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>
22 #include <afs/afsutil.h>
29 #include <sys/types.h>
38 #ifdef HAVE_SYS_PARAM_H
39 #include <sys/param.h>
42 #ifdef HAVE_SYS_FS_TYPES_H
43 #include <sys/fs_types.h>
46 #ifdef HAVE_SYS_MOUNT_H
47 #include <sys/mount.h>
50 #ifdef HAVE_SYS_FCNTL_H
51 #include <sys/fcntl.h>
54 #ifdef HAVE_SYS_MNTTAB_H
55 #include <sys/mnttab.h>
58 #ifdef HAVE_SYS_MNTENT_H
59 #include <sys/mntent.h>
66 #ifdef HAVE_SYS_MOUNT_H
67 #include <sys/mount.h>
74 #ifdef HAVE_SYS_FSTYP_H
75 #include <sys/fstyp.h>
86 #include <netinet/in.h>
87 #include <afs/afs_args.h>
88 #include <afs/cellconfig.h>
90 #include <afs/afssyscalls.h>
91 #include <afs/afsutil.h>
94 #ifdef AFS_DARWIN80_ENV
95 #include <sys/ioctl.h>
96 #include <sys/xattr.h>
98 #include <mach/mach.h>
99 #ifndef AFS_DARWIN100_ENV
100 /* Symbols from the DiskArbitration framework */
101 kern_return_t DiskArbStart(mach_port_t *);
102 kern_return_t DiskArbDiskAppearedWithMountpointPing_auto(char *, unsigned int,
104 #define DISK_ARB_NETWORK_DISK_FLAG 8
106 #include <mach/mach_port.h>
107 #include <mach/mach_interface.h>
108 #include <mach/mach_init.h>
109 #endif /* AFS_DARWIN_ENV */
112 #define MOUNT_AFS AFS_MOUNT_AFS
113 #endif /* MOUNT_AFS */
117 # define SET_RTPRI(P) { \
118 struct sched_param sp; \
119 sp.sched_priority = P; \
120 if (sched_setscheduler(0, SCHED_RR, &sp)<0) { \
121 perror("sched_setscheduler"); \
124 # define SET_AFSD_RTPRI() SET_RTPRI(68)
125 # define SET_RX_RTPRI() SET_RTPRI(199)
127 # ifdef AFS_LINUX20_ENV
128 # define SET_AFSD_RTPRI()
129 # define SET_RX_RTPRI() do { \
130 if (setpriority(PRIO_PROCESS, 0, -10) < 0) \
131 perror("setting rx priority"); \
134 # define SET_AFSD_RTPRI()
135 # define SET_RX_RTPRI()
140 afsd_set_rx_rtpri(void)
146 afsd_set_afsd_rtpri(void)
151 #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
154 afsd_call_syscall(long param1, long param2, long param3, long param4, long param5,
155 long param6, long param7)
158 # ifdef AFS_LINUX20_ENV
160 struct afsprocdata syscall_data;
161 int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
163 fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
169 param4 = (long)eparm;
171 syscall_data.syscall = AFSCALL_CALL;
172 syscall_data.param1 = param1;
173 syscall_data.param2 = param2;
174 syscall_data.param3 = param3;
175 syscall_data.param4 = param4;
177 error = ioctl(fd, VIOC_SYSCALL, &syscall_data);
180 # endif /* AFS_LINUX20_ENV */
181 # ifdef AFS_DARWIN80_ENV
182 struct afssysargs syscall_data;
184 int fd = open(SYSCALL_DEV_FNAME,O_RDWR);
186 #ifdef AFS_DARWIN100_ENV
188 struct afssysargs64 syscall64_data;
189 if (sizeof(param1) == 8) {
190 syscallnum = VIOC_SYSCALL64;
192 ioctldata = &syscall64_data;
193 syscall64_data.syscall = (int)AFSCALL_CALL;
194 syscall64_data.param1 = param1;
195 syscall64_data.param2 = param2;
196 syscall64_data.param3 = param3;
197 syscall64_data.param4 = param4;
198 syscall64_data.param5 = param5;
199 syscall64_data.param6 = param6;
202 syscallnum = VIOC_SYSCALL;
203 ioctldata = &syscall_data;
204 syscall_data.syscall = AFSCALL_CALL;
205 syscall_data.param1 = param1;
206 syscall_data.param2 = param2;
207 syscall_data.param3 = param3;
208 syscall_data.param4 = param4;
209 syscall_data.param5 = param5;
210 syscall_data.param6 = param6;
211 #ifdef AFS_DARWIN100_ENV
215 error = ioctl(fd, syscallnum, ioctldata);
221 #ifdef AFS_DARWIN100_ENV
223 error=syscall64_data.retval;
226 error=syscall_data.retval;
228 # elif defined(AFS_SUN511_ENV)
231 rval = ioctl_sun_afs_syscall(AFSCALL_CALL, param1, param2, param3,
232 param4, param5, param6, &error);
237 # else /* AFS_DARWIN80_ENV */
239 syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4,
240 param5, param6, param7);
241 # endif /* !AFS_DARWIN80_ENV */
244 #ifdef AFS_NBSD40_ENV
245 char *s = strerror(errno);
246 printf("SScall(%d, %d, %d)=%d (%d, %s)\n", AFS_SYSCALL, AFSCALL_CALL,
247 param1, error, errno, s);
249 printf("SScall(%d, %d, %ld)=%d ", AFS_SYSCALL, AFSCALL_CALL, param1,
256 #else /* !AFS_SGI_ENV && !AFS_AIX32_ENV */
257 # if defined(AFS_SGI_ENV)
259 afsd_call_syscall(call, parm0, parm1, parm2, parm3, parm4)
264 error = afs_syscall(call, parm0, parm1, parm2, parm3, parm4);
266 printf("SScall(%d, %d)=%d ", call, parm0, error);
270 # else /* AFS_SGI_ENV */
272 afsd_call_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, parm6)
275 return syscall(AFSCALL_CALL, call, parm0, parm1, parm2, parm3, parm4,
278 # endif /* !AFS_SGI_ENV */
279 #endif /* AFS_SGI_ENV || AFS_AIX32_ENV */
283 /* Special handling for AIX's afs mount operation since they require much more
284 * miscl. information before making the vmount(2) syscall */
287 #define ROUNDUP(x) (((x) + 3) & ~3)
289 aix_vmount(const char *cacheMountDir)
291 struct vmount *vmountp;
294 size = sizeof(struct vmount) + ROUNDUP(strlen(cacheMountDir) + 1) + 5 * 4;
295 /* Malloc the vmount structure */
296 if ((vmountp = (struct vmount *)malloc(size)) == (struct vmount *)NULL) {
297 printf("Can't allocate space for the vmount structure (AIX)\n");
301 /* zero out the vmount structure */
302 memset(vmountp, '\0', size);
304 /* transfer info into the vmount structure */
305 vmountp->vmt_revision = VMT_REVISION;
306 vmountp->vmt_length = size;
307 vmountp->vmt_fsid.fsid_dev = 0;
308 vmountp->vmt_fsid.fsid_type = AFS_MOUNT_AFS;
309 vmountp->vmt_vfsnumber = 0;
310 vmountp->vmt_time = 0; /* We'll put the time soon! */
311 vmountp->vmt_flags = VFS_DEVMOUNT; /* read/write permission */
312 vmountp->vmt_gfstype = AFS_MOUNT_AFS;
313 vmountdata(vmountp, "AFS", cacheMountDir, "", "", "", "rw");
315 /* Do the actual mount system call */
316 error = vmount(vmountp, size);
321 vmountdata(struct vmount * vmtp, char *obj, char *stub, char *host,
322 char *hostsname, char *info, char *args)
330 vdp = (struct data *)vmtp->vmt_data;
331 vdp->vmt_off = sizeof(struct vmount);
332 size = ROUNDUP(strlen(obj) + 1);
333 vdp->vmt_size = size;
334 strcpy(vmt2dataptr(vmtp, VMT_OBJECT), obj);
338 vdp->vmt_off = vdprev->vmt_off + size;
339 size = ROUNDUP(strlen(stub) + 1);
340 vdp->vmt_size = size;
341 strcpy(vmt2dataptr(vmtp, VMT_STUB), stub);
345 vdp->vmt_off = vdprev->vmt_off + size;
346 size = ROUNDUP(strlen(host) + 1);
347 vdp->vmt_size = size;
348 strcpy(vmt2dataptr(vmtp, VMT_HOST), host);
352 vdp->vmt_off = vdprev->vmt_off + size;
353 size = ROUNDUP(strlen(hostsname) + 1);
354 vdp->vmt_size = size;
355 strcpy(vmt2dataptr(vmtp, VMT_HOSTNAME), hostsname);
360 vdp->vmt_off = vdprev->vmt_off + size;
361 size = ROUNDUP(strlen(info) + 1);
362 vdp->vmt_size = size;
363 strcpy(vmt2dataptr(vmtp, VMT_INFO), info);
367 vdp->vmt_off = vdprev->vmt_off + size;
368 size = ROUNDUP(strlen(args) + 1);
369 vdp->vmt_size = size;
370 strcpy(vmt2dataptr(vmtp, VMT_ARGS), args);
372 #endif /* AFS_AIX_ENV */
375 #define MOUNTED_TABLE MNT_MNTTAB
378 #define MOUNTED_TABLE MNTTAB
380 #define MOUNTED_TABLE MOUNTED
385 HandleMTab(char *cacheMountDir)
387 #if (defined (AFS_SUN_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)) && !defined(AFS_SUN58_ENV)
391 struct mnttab tmntent;
393 memset(&tmntent, '\0', sizeof(struct mnttab));
394 if (!(tfilep = fopen(MOUNTED_TABLE, "a+"))) {
395 printf("Can't open %s\n", MOUNTED_TABLE);
399 tmntent.mnt_special = "AFS";
400 tmntent.mnt_mountp = cacheMountDir;
401 tmntent.mnt_fstype = "xx";
402 tmntent.mnt_mntopts = "rw";
403 sprintf(tbuf, "%ld", (long)time((time_t *) 0));
404 tmntent.mnt_time = tbuf;
405 putmntent(tfilep, &tmntent);
408 #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
409 struct mntent tmntent;
410 char *dir = strdup(cacheMountDir);
413 /* trim trailing slashes; don't look at dir[0] in case we are somehow
415 for (i = strlen(dir)-1; i > 0; i--) {
423 tfilep = setmntent("/etc/mtab", "a+");
424 tmntent.mnt_fsname = "AFS";
425 tmntent.mnt_dir = dir;
426 tmntent.mnt_type = "afs";
427 tmntent.mnt_opts = "rw";
428 tmntent.mnt_freq = 1;
429 tmntent.mnt_passno = 3;
430 addmntent(tfilep, &tmntent);
436 struct mntent tmntent;
438 memset(&tmntent, '\0', sizeof(struct mntent));
439 tfilep = setmntent(MOUNTED_TABLE, "a+");
441 printf("Can't open %s for write; Not adding afs entry to it\n",
445 tmntent.mnt_fsname = "AFS";
446 tmntent.mnt_dir = cacheMountDir;
447 tmntent.mnt_type = "xx";
448 tmntent.mnt_opts = "rw";
449 tmntent.mnt_freq = 1;
450 tmntent.mnt_passno = 3;
452 tmntent.mnt_type = "afs";
453 tmntent.mnt_time = time(0);
454 tmntent.mnt_cnode = 0;
456 addmntent(tfilep, &tmntent);
458 #endif /* AFS_SGI_ENV */
459 #endif /* AFS_SUN5_ENV */
460 #endif /* unreasonable systems */
461 #ifdef AFS_DARWIN_ENV
462 #ifndef AFS_DARWIN100_ENV
463 mach_port_t diskarb_port;
464 kern_return_t status;
466 status = DiskArbStart(&diskarb_port);
467 if (status == KERN_SUCCESS) {
469 DiskArbDiskAppearedWithMountpointPing_auto("AFS",
470 DISK_ARB_NETWORK_DISK_FLAG,
476 #endif /* AFS_DARWIN_ENV */
481 afsd_mount_afs(const char *rn, const char *cacheMountDir)
483 int mountFlags; /*Flags passed to mount() */
484 char *mountDir; /* For HandleMTab() */
486 mountFlags = 0; /* Read/write file system, can do setuid() */
487 #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
489 mountFlags |= MS_DATA;
491 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... */
495 #if defined(AFS_HPUX100_ENV)
496 mountFlags |= MS_DATA;
500 printf("%s: Mounting the AFS root on '%s', flags: %d.\n", rn,
501 cacheMountDir, mountFlags);
502 #if defined(AFS_FBSD60_ENV)
503 /* data must be non-NULL but is otherwise ignored */
504 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, rn)) < 0) {
505 #elif defined(AFS_FBSD_ENV)
506 if ((mount("AFS", cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
507 #elif defined(AFS_AIX_ENV)
508 if (aix_vmount(cacheMountDir)) {
509 #elif defined(AFS_HPUX100_ENV)
510 if ((mount("", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
511 #elif defined(AFS_SUN5_ENV)
512 if ((mount("AFS", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
513 #elif defined(AFS_SGI_ENV)
515 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) MOUNT_AFS))
517 #elif defined(AFS_LINUX20_ENV)
518 if ((mount("AFS", cacheMountDir, MOUNT_AFS, 0, NULL)) < 0) {
519 #elif defined(AFS_NBSD50_ENV)
520 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, NULL, 0)) < 0) {
522 /* This is the standard mount used by the suns and rts */
523 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
525 printf("%s: Can't mount AFS on %s(%d)\n", rn, cacheMountDir,
530 mountDir = strdup(cacheMountDir);
531 HandleMTab(mountDir);
536 afsd_fork(int wait, afsd_callback_func cb, void *rock)
546 assert(waitpid(code, NULL, 0) != -1);
553 afsd_daemon(int nochdir, int noclose)
555 return daemon(nochdir, noclose);
559 afsd_check_mount(const char *rn, const char *mountdir)
563 if (stat(mountdir, &statbuf)) {
564 printf("%s: Mountpoint %s missing.\n", rn, mountdir);
566 } else if (!S_ISDIR(statbuf.st_mode)) {
567 printf("%s: Mountpoint %s is not a directory.\n", rn, mountdir);
574 main(int argc, char **argv)
580 code = afsd_parse(argc, argv);