2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
15 #ifdef IGNORE_SOME_GCC_WARNINGS
17 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
19 # pragma GCC diagnostic warning "-Wdeprecated-declarations"
30 #include <afs/afsutil.h>
34 #if defined(AFS_LINUX20_ENV)
35 #include <sys/resource.h>
38 #ifdef HAVE_SYS_FS_TYPES_H
39 #include <sys/fs_types.h>
42 #ifdef HAVE_SYS_MOUNT_H
43 #include <sys/mount.h>
46 #ifdef HAVE_SYS_FCNTL_H
47 #include <sys/fcntl.h>
50 #ifdef HAVE_SYS_MNTTAB_H
51 #include <sys/mnttab.h>
54 #ifdef HAVE_SYS_MNTENT_H
55 #include <sys/mntent.h>
62 #ifdef HAVE_SYS_MOUNT_H
63 #include <sys/mount.h>
70 #ifdef HAVE_SYS_FSTYP_H
71 #include <sys/fstyp.h>
77 #include <afs/afs_args.h>
78 #include <afs/cellconfig.h>
79 #include <afs/afssyscalls.h>
80 #include <afs/afsutil.h>
83 #ifdef AFS_DARWIN80_ENV
84 #include <sys/xattr.h>
86 #include <mach/mach.h>
87 #ifndef AFS_DARWIN100_ENV
88 /* Symbols from the DiskArbitration framework */
89 kern_return_t DiskArbStart(mach_port_t *);
90 kern_return_t DiskArbDiskAppearedWithMountpointPing_auto(char *, unsigned int,
92 #define DISK_ARB_NETWORK_DISK_FLAG 8
94 #include <mach/mach_port.h>
95 #include <mach/mach_interface.h>
96 #include <mach/mach_init.h>
97 #endif /* AFS_DARWIN_ENV */
99 #define AFS_MOUNT_STR "afs"
101 #define MOUNT_AFS AFS_MOUNT_STR
102 #endif /* MOUNT_AFS */
106 # define SET_RTPRI(P) { \
107 struct sched_param sp; \
108 sp.sched_priority = P; \
109 if (sched_setscheduler(0, SCHED_RR, &sp)<0) { \
110 perror("sched_setscheduler"); \
113 # define SET_AFSD_RTPRI() SET_RTPRI(68)
114 # define SET_RX_RTPRI() SET_RTPRI(199)
116 # ifdef AFS_LINUX20_ENV
117 # define SET_AFSD_RTPRI()
118 # define SET_RX_RTPRI() do { \
119 if (setpriority(PRIO_PROCESS, 0, -10) < 0) \
120 perror("setting rx priority"); \
123 # define SET_AFSD_RTPRI()
124 # define SET_RX_RTPRI()
128 static char *afsd_syscalls[AFSOP_MAX_OPCODE + 1]; /* For syscall tracing. */
131 afsd_init_syscall_opcodes(void)
133 #define add_opcode(x) afsd_syscalls[x] = #x
134 add_opcode(AFSOP_START_RXCALLBACK);
135 add_opcode(AFSOP_START_AFS);
136 add_opcode(AFSOP_START_BKG);
137 add_opcode(AFSOP_START_TRUNCDAEMON);
138 add_opcode(AFSOP_START_CS);
139 add_opcode(AFSOP_ADDCELL);
140 add_opcode(AFSOP_CACHEINIT);
141 add_opcode(AFSOP_CACHEINFO);
142 add_opcode(AFSOP_VOLUMEINFO);
143 add_opcode(AFSOP_CACHEFILE);
144 add_opcode(AFSOP_CACHEINODE);
145 add_opcode(AFSOP_AFSLOG);
146 add_opcode(AFSOP_ROOTVOLUME);
147 add_opcode(AFSOP_STARTLOG);
148 add_opcode(AFSOP_ENDLOG);
149 add_opcode(AFSOP_AFS_VFSMOUNT);
150 add_opcode(AFSOP_ADVISEADDR);
151 add_opcode(AFSOP_CLOSEWAIT);
152 add_opcode(AFSOP_RXEVENT_DAEMON);
153 add_opcode(AFSOP_GETMTU);
154 add_opcode(AFSOP_GETIFADDRS);
155 add_opcode(AFSOP_ADDCELL2);
156 add_opcode(AFSOP_AFSDB_HANDLER);
157 add_opcode(AFSOP_SET_DYNROOT);
158 add_opcode(AFSOP_ADDCELLALIAS);
159 add_opcode(AFSOP_SET_FAKESTAT);
160 add_opcode(AFSOP_CELLINFO);
161 add_opcode(AFSOP_SET_THISCELL);
162 add_opcode(AFSOP_BASIC_INIT);
163 add_opcode(AFSOP_SET_BACKUPTREE);
164 add_opcode(AFSOP_SET_RXPCK);
165 add_opcode(AFSOP_BUCKETPCT);
166 add_opcode(AFSOP_SET_RXMAXMTU);
167 add_opcode(AFSOP_BKG_HANDLER);
168 add_opcode(AFSOP_GETMASK);
169 add_opcode(AFSOP_SET_RXMAXFRAGS);
170 add_opcode(AFSOP_SET_RMTSYS_FLAG);
171 add_opcode(AFSOP_SEED_ENTROPY);
172 add_opcode(AFSOP_SET_INUMCALC);
173 add_opcode(AFSOP_RXLISTENER_DAEMON);
174 add_opcode(AFSOP_CACHEBASEDIR);
175 add_opcode(AFSOP_CACHEDIRS);
176 add_opcode(AFSOP_CACHEFILES);
177 add_opcode(AFSOP_SETINT);
178 add_opcode(AFSOP_GO);
179 add_opcode(AFSOP_CHECKLOCKS);
180 add_opcode(AFSOP_SHUTDOWN);
181 add_opcode(AFSOP_STOP_RXCALLBACK);
182 add_opcode(AFSOP_STOP_AFS);
183 add_opcode(AFSOP_STOP_BKG);
184 add_opcode(AFSOP_STOP_TRUNCDAEMON);
185 /* AFSOP_STOP_RXEVENT -- not a syscall opcode */
186 /* AFSOP_STOP_COMPLETE -- not a syscall opcode */
187 add_opcode(AFSOP_STOP_CS);
188 /* AFSOP_STOP_RXK_LISTENER -- not a syscall opcode */
189 add_opcode(AFSOP_STOP_AFSDB);
190 add_opcode(AFSOP_STOP_NETIF);
195 afsd_set_rx_rtpri(void)
201 afsd_set_afsd_rtpri(void)
206 #if defined(AFS_LINUX20_ENV)
208 os_syscall(struct afsd_syscall_args *args)
211 struct afsprocdata syscall_data;
213 int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
215 fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
220 syscall_data.syscall = AFSCALL_CALL;
221 syscall_data.param1 = args->syscall;
222 syscall_data.param2 = args->params[0];
223 syscall_data.param3 = args->params[1];
224 syscall_data.param4 = (long) &args->params[2];
226 error = ioctl(fd, VIOC_SYSCALL, &syscall_data);
231 #elif defined(AFS_DARWIN80_ENV)
233 # if defined(AFS_DARWIN100_ENV)
235 os_syscall64(struct afsd_syscall_args *args)
238 struct afssysargs64 syscall64_data;
239 int fd = open(SYSCALL_DEV_FNAME, O_RDWR);
244 syscall64_data.syscall = (int)AFSCALL_CALL;
245 syscall64_data.param1 = args->syscall;
246 syscall64_data.param2 = args->params[0];
247 syscall64_data.param3 = args->params[1];
248 syscall64_data.param4 = args->params[2];
249 syscall64_data.param5 = args->params[3];
250 syscall64_data.param6 = args->params[4];
252 error = ioctl(fd, VIOC_SYSCALL64, &syscall64_data);
258 return syscall64_data.retval;
263 os_syscall(struct afsd_syscall_args *args)
266 struct afssysargs syscall_data;
269 # ifdef AFS_DARWIN100_ENV
270 if (sizeof(long) == 8)
271 return os_syscall64(args);
274 fd = open(SYSCALL_DEV_FNAME, O_RDWR);
278 syscall_data.syscall = AFSCALL_CALL;
279 syscall_data.param1 = (unsigned int)(uintptr_t)args->syscall;
280 syscall_data.param2 = (unsigned int)(uintptr_t)args->params[0];
281 syscall_data.param3 = (unsigned int)(uintptr_t)args->params[1];
282 syscall_data.param4 = (unsigned int)(uintptr_t)args->params[2];
283 syscall_data.param5 = (unsigned int)(uintptr_t)args->params[3];
284 syscall_data.param6 = (unsigned int)(uintptr_t)args->params[4];
286 error = ioctl(fd, VIOC_SYSCALL, syscall_data);
292 return syscall_data.retval;
295 #elif defined(AFS_SUN511_ENV)
297 os_syscall(struct afsd_syscall_args *args)
301 error = ioctl_sun_afs_syscall(AFSCALL_CALL, args->syscall,
302 args->params[0], args->params[1],
303 args->params[2], args->params[3],
304 args->params[4], &retval);
310 #elif defined(AFS_SGI_ENV)
312 os_syscall(struct afsd_syscall_args *args)
314 return afs_syscall(args->syscall, args->params[0], args->params[1],
315 args->params[2], args->params[3], args->params[4]);
317 #elif defined(AFS_AIX32_ENV)
319 os_syscall(struct afsd_syscall_args *args)
321 return syscall(AFSCALL_CALL, args->syscall,
322 args->params[0], args->params[1], args->params[2],
323 args->params[3], args->params[4], args->params[5],
328 os_syscall(struct afsd_syscall_args *args)
330 return syscall(AFS_SYSCALL, AFSCALL_CALL, args->syscall,
331 args->params[0], args->params[1], args->params[2],
332 args->params[3], args->params[4], args->params[5]);
337 afsd_call_syscall(struct afsd_syscall_args *args)
341 error = os_syscall(args);
346 const char *syscall_str;
348 #if defined(AFS_SYSCALL)
349 syscall_str = AFS_STRINGIZE(AFS_SYSCALL);
351 syscall_str = "[AFS_SYSCALL]";
354 if ((args->syscall < 0) ||
355 (args->syscall >= (sizeof(afsd_syscalls) / sizeof(*afsd_syscalls))))
358 opcode = afsd_syscalls[args->syscall];
360 if (opcode == NULL) {
361 snprintf(buffer, sizeof(buffer), "unknown (%d)", args->syscall);
366 char *s = strerror(errno);
367 printf("os_syscall(%s, %d, %s, 0x%lx)=%d (%d, %s)\n",
368 syscall_str, AFSCALL_CALL, opcode,
369 (long)args->params[0], error, errno, s);
371 printf("os_syscall(%s %d %s, 0x%lx)=%d\n",
372 syscall_str, AFSCALL_CALL, opcode,
373 (long)args->params[0], error);
381 /* Special handling for AIX's afs mount operation since they require much more
382 * miscl. information before making the vmount(2) syscall */
385 #define ROUNDUP(x) (((x) + 3) & ~3)
387 aix_vmount(const char *cacheMountDir)
389 struct vmount *vmountp;
392 size = sizeof(struct vmount) + ROUNDUP(strlen(cacheMountDir) + 1) + 5 * 4;
393 /* Malloc and zero the vmount structure */
394 if ((vmountp = calloc(1, size)) == NULL) {
395 printf("Can't allocate space for the vmount structure (AIX)\n");
399 /* transfer info into the vmount structure */
400 vmountp->vmt_revision = VMT_REVISION;
401 vmountp->vmt_length = size;
402 vmountp->vmt_fsid.fsid_dev = 0;
403 vmountp->vmt_fsid.fsid_type = AFS_FSNO;
404 vmountp->vmt_vfsnumber = 0;
405 vmountp->vmt_time = 0; /* We'll put the time soon! */
406 vmountp->vmt_flags = VFS_DEVMOUNT; /* read/write permission */
407 vmountp->vmt_gfstype = AFS_FSNO;
408 vmountdata(vmountp, "AFS", cacheMountDir, "", "", "", "rw");
410 /* Do the actual mount system call */
411 error = vmount(vmountp, size);
416 vmountdata(struct vmount * vmtp, char *obj, char *stub, char *host,
417 char *hostsname, char *info, char *args)
425 vdp = (struct data *)vmtp->vmt_data;
426 vdp->vmt_off = sizeof(struct vmount);
427 size = ROUNDUP(strlen(obj) + 1);
428 vdp->vmt_size = size;
429 strcpy(vmt2dataptr(vmtp, VMT_OBJECT), obj);
433 vdp->vmt_off = vdprev->vmt_off + size;
434 size = ROUNDUP(strlen(stub) + 1);
435 vdp->vmt_size = size;
436 strcpy(vmt2dataptr(vmtp, VMT_STUB), stub);
440 vdp->vmt_off = vdprev->vmt_off + size;
441 size = ROUNDUP(strlen(host) + 1);
442 vdp->vmt_size = size;
443 strcpy(vmt2dataptr(vmtp, VMT_HOST), host);
447 vdp->vmt_off = vdprev->vmt_off + size;
448 size = ROUNDUP(strlen(hostsname) + 1);
449 vdp->vmt_size = size;
450 strcpy(vmt2dataptr(vmtp, VMT_HOSTNAME), hostsname);
455 vdp->vmt_off = vdprev->vmt_off + size;
456 size = ROUNDUP(strlen(info) + 1);
457 vdp->vmt_size = size;
458 strcpy(vmt2dataptr(vmtp, VMT_INFO), info);
462 vdp->vmt_off = vdprev->vmt_off + size;
463 size = ROUNDUP(strlen(args) + 1);
464 vdp->vmt_size = size;
465 strcpy(vmt2dataptr(vmtp, VMT_ARGS), args);
467 #endif /* AFS_AIX_ENV */
470 #define MOUNTED_TABLE MNT_MNTTAB
472 #define MOUNTED_TABLE MOUNTED
476 HandleMTab(char *cacheMountDir)
478 #if (defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV))
480 #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
481 struct mntent tmntent;
485 tfilep = setmntent("/etc/mtab", "a+");
487 printf("Can't open /etc/mtab for writing (errno %d); not adding "
488 "an entry for AFS\n", errno);
492 dir = strdup(cacheMountDir);
494 /* trim trailing slashes; don't look at dir[0] in case we are somehow
496 for (i = strlen(dir)-1; i > 0; i--) {
504 tmntent.mnt_fsname = "AFS";
505 tmntent.mnt_dir = dir;
506 tmntent.mnt_type = "afs";
507 tmntent.mnt_opts = "rw";
508 tmntent.mnt_freq = 1;
509 tmntent.mnt_passno = 3;
510 addmntent(tfilep, &tmntent);
516 struct mntent tmntent;
518 memset(&tmntent, '\0', sizeof(struct mntent));
519 tfilep = setmntent(MOUNTED_TABLE, "a+");
521 printf("Can't open %s for write; Not adding afs entry to it\n",
525 tmntent.mnt_fsname = "AFS";
526 tmntent.mnt_dir = cacheMountDir;
527 tmntent.mnt_type = "xx";
528 tmntent.mnt_opts = "rw";
529 tmntent.mnt_freq = 1;
530 tmntent.mnt_passno = 3;
532 tmntent.mnt_type = "afs";
533 tmntent.mnt_time = time(0);
534 tmntent.mnt_cnode = 0;
536 addmntent(tfilep, &tmntent);
538 #endif /* AFS_SGI_ENV */
539 #endif /* unreasonable systems */
540 #ifdef AFS_DARWIN_ENV
541 #ifndef AFS_DARWIN100_ENV
542 mach_port_t diskarb_port;
543 kern_return_t status;
545 status = DiskArbStart(&diskarb_port);
546 if (status == KERN_SUCCESS) {
548 DiskArbDiskAppearedWithMountpointPing_auto("AFS",
549 DISK_ARB_NETWORK_DISK_FLAG,
555 #endif /* AFS_DARWIN_ENV */
560 afsd_mount_afs(const char *rn, const char *cacheMountDir)
562 int mountFlags; /*Flags passed to mount() */
563 char *mountDir; /* For HandleMTab() */
565 mountFlags = 0; /* Read/write file system, can do setuid() */
566 #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
568 mountFlags |= MS_DATA;
570 mountFlags |= M_NEWTYPE; /* This searches by name in vfs_conf.c so don't need to recompile vfs.c because MOUNT_MAXTYPE has changed; it seems that Sun fixed this at last... */
574 #if defined(AFS_HPUX100_ENV)
575 mountFlags |= MS_DATA;
579 printf("%s: Mounting the AFS root on '%s', flags: %d.\n", rn,
580 cacheMountDir, mountFlags);
581 #if defined(AFS_FBSD_ENV)
582 /* data must be non-const non-NULL but is otherwise ignored */
583 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, &mountFlags)) < 0) {
584 #elif defined(AFS_AIX_ENV)
585 if (aix_vmount(cacheMountDir)) {
586 #elif defined(AFS_HPUX100_ENV)
587 if ((mount("", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
588 #elif defined(AFS_SUN5_ENV)
589 if ((mount("AFS", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
590 #elif defined(AFS_SGI_ENV)
592 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) MOUNT_AFS))
594 #elif defined(AFS_LINUX20_ENV)
595 if ((mount("AFS", cacheMountDir, MOUNT_AFS, 0, NULL)) < 0) {
596 #elif defined(AFS_NBSD50_ENV)
597 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, NULL, 0)) < 0) {
599 /* This is the standard mount used by the suns and rts */
600 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
602 printf("%s: Can't mount AFS on %s(%d)\n", rn, cacheMountDir,
607 mountDir = strdup(cacheMountDir);
608 HandleMTab(mountDir);
613 afsd_fork(int wait, afsd_callback_func cb, void *rock)
623 opr_Verify(waitpid(code, NULL, 0) != -1);
630 afsd_daemon(int nochdir, int noclose)
632 return daemon(nochdir, noclose);
636 afsd_check_mount(const char *rn, const char *mountdir)
640 if (stat(mountdir, &statbuf)) {
641 printf("%s: Mountpoint %s missing.\n", rn, mountdir);
643 } else if (!S_ISDIR(statbuf.st_mode)) {
644 printf("%s: Mountpoint %s is not a directory.\n", rn, mountdir);
646 } else if (mountdir[0] != '/') {
647 printf("%s: Mountpoint %s is not an absolute path.\n", rn, mountdir);
654 main(int argc, char **argv)
658 afsd_init_syscall_opcodes();
661 code = afsd_parse(argc, argv);
662 if (code == CMD_HELP) {
663 return 0; /* Displaying help is not an error. */