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 */
100 #define MOUNT_AFS AFS_MOUNT_AFS
101 #endif /* MOUNT_AFS */
105 # define SET_RTPRI(P) { \
106 struct sched_param sp; \
107 sp.sched_priority = P; \
108 if (sched_setscheduler(0, SCHED_RR, &sp)<0) { \
109 perror("sched_setscheduler"); \
112 # define SET_AFSD_RTPRI() SET_RTPRI(68)
113 # define SET_RX_RTPRI() SET_RTPRI(199)
115 # ifdef AFS_LINUX20_ENV
116 # define SET_AFSD_RTPRI()
117 # define SET_RX_RTPRI() do { \
118 if (setpriority(PRIO_PROCESS, 0, -10) < 0) \
119 perror("setting rx priority"); \
122 # define SET_AFSD_RTPRI()
123 # define SET_RX_RTPRI()
128 afsd_set_rx_rtpri(void)
134 afsd_set_afsd_rtpri(void)
139 #if defined(AFS_LINUX20_ENV)
141 os_syscall(struct afsd_syscall_args *args)
144 struct afsprocdata syscall_data;
146 int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
148 fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
153 syscall_data.syscall = AFSCALL_CALL;
154 syscall_data.param1 = args->syscall;
155 syscall_data.param2 = args->params[0];
156 syscall_data.param3 = args->params[1];
157 syscall_data.param4 = (long) &args->params[2];
159 error = ioctl(fd, VIOC_SYSCALL, &syscall_data);
164 #elif defined(AFS_DARWIN80_ENV)
166 # if defined(AFS_DARWIN100_ENV)
168 os_syscall64(struct afsd_syscall_args *args)
171 struct afssysargs64 syscall64_data;
172 int fd = open(SYSCALL_DEV_FNAME, O_RDWR);
177 syscall64_data.syscall = (int)AFSCALL_CALL;
178 syscall64_data.param1 = args->syscall;
179 syscall64_data.param2 = args->params[0];
180 syscall64_data.param3 = args->params[1];
181 syscall64_data.param4 = args->params[2];
182 syscall64_data.param5 = args->params[3];
183 syscall64_data.param6 = args->params[4];
185 error = ioctl(fd, VIOC_SYSCALL64, &syscall64_data);
191 return syscall64_data.retval;
196 os_syscall(struct afsd_syscall_args *args)
199 struct afssysargs syscall_data;
202 # ifdef AFS_DARWIN100_ENV
203 if (sizeof(long) == 8)
204 return os_syscall64(args);
207 fd = open(SYSCALL_DEV_FNAME, O_RDWR);
211 syscall_data.syscall = AFSCALL_CALL;
212 syscall_data.param1 = (unsigned int)(uintptr_t)args->syscall;
213 syscall_data.param2 = (unsigned int)(uintptr_t)args->params[0];
214 syscall_data.param3 = (unsigned int)(uintptr_t)args->params[1];
215 syscall_data.param4 = (unsigned int)(uintptr_t)args->params[2];
216 syscall_data.param5 = (unsigned int)(uintptr_t)args->params[3];
217 syscall_data.param6 = (unsigned int)(uintptr_t)args->params[4];
219 error = ioctl(fd, VIOC_SYSCALL, syscall_data);
225 return syscall_data.retval;
228 #elif defined(AFS_SUN511_ENV)
230 os_syscall(struct afsd_syscall_args *args)
234 error = ioctl_sun_afs_syscall(AFSCALL_CALL, args->syscall,
235 args->params[0], args->params[1],
236 args->params[2], args->params[3],
237 args->params[4], &retval);
243 #elif defined(AFS_SGI_ENV)
245 os_syscall(struct afsd_syscall_args *args)
247 return afs_syscall(args->syscall, args->params[0], args->params[1],
248 args->params[2], args->params[3], args->params[4]);
250 #elif defined(AFS_AIX32_ENV)
252 os_syscall(struct afsd_syscall_args *args)
254 return syscall(AFSCALL_CALL, args->syscall,
255 args->params[0], args->params[1], args->params[2],
256 args->params[3], args->params[4], args->params[5],
261 os_syscall(struct afsd_syscall_args *args)
263 return syscall(AFS_SYSCALL, AFSCALL_CALL, args->syscall,
264 args->params[0], args->params[1], args->params[2],
265 args->params[3], args->params[4], args->params[5]);
270 afsd_call_syscall(struct afsd_syscall_args *args)
274 error = os_syscall(args);
277 #ifdef AFS_NBSD40_ENV
278 char *s = strerror(errno);
279 printf("SScall(%d, %d, %d)=%d (%d, %s)\n", AFS_SYSCALL, AFSCALL_CALL,
280 (int)args->params[0], error, errno, s);
282 printf("SScall(%d, %d, %d)=%d ", AFS_SYSCALL, AFSCALL_CALL,
283 (int)args->params[0], error);
291 /* Special handling for AIX's afs mount operation since they require much more
292 * miscl. information before making the vmount(2) syscall */
295 #define ROUNDUP(x) (((x) + 3) & ~3)
297 aix_vmount(const char *cacheMountDir)
299 struct vmount *vmountp;
302 size = sizeof(struct vmount) + ROUNDUP(strlen(cacheMountDir) + 1) + 5 * 4;
303 /* Malloc and zero the vmount structure */
304 if ((vmountp = calloc(1, size)) == NULL) {
305 printf("Can't allocate space for the vmount structure (AIX)\n");
309 /* transfer info into the vmount structure */
310 vmountp->vmt_revision = VMT_REVISION;
311 vmountp->vmt_length = size;
312 vmountp->vmt_fsid.fsid_dev = 0;
313 vmountp->vmt_fsid.fsid_type = AFS_MOUNT_AFS;
314 vmountp->vmt_vfsnumber = 0;
315 vmountp->vmt_time = 0; /* We'll put the time soon! */
316 vmountp->vmt_flags = VFS_DEVMOUNT; /* read/write permission */
317 vmountp->vmt_gfstype = AFS_MOUNT_AFS;
318 vmountdata(vmountp, "AFS", cacheMountDir, "", "", "", "rw");
320 /* Do the actual mount system call */
321 error = vmount(vmountp, size);
326 vmountdata(struct vmount * vmtp, char *obj, char *stub, char *host,
327 char *hostsname, char *info, char *args)
335 vdp = (struct data *)vmtp->vmt_data;
336 vdp->vmt_off = sizeof(struct vmount);
337 size = ROUNDUP(strlen(obj) + 1);
338 vdp->vmt_size = size;
339 strcpy(vmt2dataptr(vmtp, VMT_OBJECT), obj);
343 vdp->vmt_off = vdprev->vmt_off + size;
344 size = ROUNDUP(strlen(stub) + 1);
345 vdp->vmt_size = size;
346 strcpy(vmt2dataptr(vmtp, VMT_STUB), stub);
350 vdp->vmt_off = vdprev->vmt_off + size;
351 size = ROUNDUP(strlen(host) + 1);
352 vdp->vmt_size = size;
353 strcpy(vmt2dataptr(vmtp, VMT_HOST), host);
357 vdp->vmt_off = vdprev->vmt_off + size;
358 size = ROUNDUP(strlen(hostsname) + 1);
359 vdp->vmt_size = size;
360 strcpy(vmt2dataptr(vmtp, VMT_HOSTNAME), hostsname);
365 vdp->vmt_off = vdprev->vmt_off + size;
366 size = ROUNDUP(strlen(info) + 1);
367 vdp->vmt_size = size;
368 strcpy(vmt2dataptr(vmtp, VMT_INFO), info);
372 vdp->vmt_off = vdprev->vmt_off + size;
373 size = ROUNDUP(strlen(args) + 1);
374 vdp->vmt_size = size;
375 strcpy(vmt2dataptr(vmtp, VMT_ARGS), args);
377 #endif /* AFS_AIX_ENV */
380 #define MOUNTED_TABLE MNT_MNTTAB
382 #define MOUNTED_TABLE MOUNTED
386 HandleMTab(char *cacheMountDir)
388 #if (defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV))
390 #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
391 struct mntent tmntent;
395 tfilep = setmntent("/etc/mtab", "a+");
397 printf("Can't open /etc/mtab for writing (errno %d); not adding "
398 "an entry for AFS\n", errno);
402 dir = strdup(cacheMountDir);
404 /* trim trailing slashes; don't look at dir[0] in case we are somehow
406 for (i = strlen(dir)-1; i > 0; i--) {
414 tmntent.mnt_fsname = "AFS";
415 tmntent.mnt_dir = dir;
416 tmntent.mnt_type = "afs";
417 tmntent.mnt_opts = "rw";
418 tmntent.mnt_freq = 1;
419 tmntent.mnt_passno = 3;
420 addmntent(tfilep, &tmntent);
426 struct mntent tmntent;
428 memset(&tmntent, '\0', sizeof(struct mntent));
429 tfilep = setmntent(MOUNTED_TABLE, "a+");
431 printf("Can't open %s for write; Not adding afs entry to it\n",
435 tmntent.mnt_fsname = "AFS";
436 tmntent.mnt_dir = cacheMountDir;
437 tmntent.mnt_type = "xx";
438 tmntent.mnt_opts = "rw";
439 tmntent.mnt_freq = 1;
440 tmntent.mnt_passno = 3;
442 tmntent.mnt_type = "afs";
443 tmntent.mnt_time = time(0);
444 tmntent.mnt_cnode = 0;
446 addmntent(tfilep, &tmntent);
448 #endif /* AFS_SGI_ENV */
449 #endif /* unreasonable systems */
450 #ifdef AFS_DARWIN_ENV
451 #ifndef AFS_DARWIN100_ENV
452 mach_port_t diskarb_port;
453 kern_return_t status;
455 status = DiskArbStart(&diskarb_port);
456 if (status == KERN_SUCCESS) {
458 DiskArbDiskAppearedWithMountpointPing_auto("AFS",
459 DISK_ARB_NETWORK_DISK_FLAG,
465 #endif /* AFS_DARWIN_ENV */
470 afsd_mount_afs(const char *rn, const char *cacheMountDir)
472 int mountFlags; /*Flags passed to mount() */
473 char *mountDir; /* For HandleMTab() */
475 mountFlags = 0; /* Read/write file system, can do setuid() */
476 #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
478 mountFlags |= MS_DATA;
480 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... */
484 #if defined(AFS_HPUX100_ENV)
485 mountFlags |= MS_DATA;
489 printf("%s: Mounting the AFS root on '%s', flags: %d.\n", rn,
490 cacheMountDir, mountFlags);
491 #if defined(AFS_FBSD60_ENV)
492 /* data must be non-const non-NULL but is otherwise ignored */
493 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, &mountFlags)) < 0) {
494 #elif defined(AFS_FBSD_ENV)
495 if ((mount("AFS", cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
496 #elif defined(AFS_AIX_ENV)
497 if (aix_vmount(cacheMountDir)) {
498 #elif defined(AFS_HPUX100_ENV)
499 if ((mount("", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
500 #elif defined(AFS_SUN5_ENV)
501 if ((mount("AFS", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
502 #elif defined(AFS_SGI_ENV)
504 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) MOUNT_AFS))
506 #elif defined(AFS_LINUX20_ENV)
507 if ((mount("AFS", cacheMountDir, MOUNT_AFS, 0, NULL)) < 0) {
508 #elif defined(AFS_NBSD50_ENV)
509 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, NULL, 0)) < 0) {
511 /* This is the standard mount used by the suns and rts */
512 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
514 printf("%s: Can't mount AFS on %s(%d)\n", rn, cacheMountDir,
519 mountDir = strdup(cacheMountDir);
520 HandleMTab(mountDir);
525 afsd_fork(int wait, afsd_callback_func cb, void *rock)
535 opr_Verify(waitpid(code, NULL, 0) != -1);
542 afsd_daemon(int nochdir, int noclose)
544 return daemon(nochdir, noclose);
548 afsd_check_mount(const char *rn, const char *mountdir)
552 if (stat(mountdir, &statbuf)) {
553 printf("%s: Mountpoint %s missing.\n", rn, mountdir);
555 } else if (!S_ISDIR(statbuf.st_mode)) {
556 printf("%s: Mountpoint %s is not a directory.\n", rn, mountdir);
558 } else if (mountdir[0] != '/') {
559 printf("%s: Mountpoint %s is not an absolute path.\n", rn, mountdir);
566 main(int argc, char **argv)
572 code = afsd_parse(argc, argv);
573 if (code == CMD_HELP) {
574 return 0; /* Displaying help is not an error. */