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>
26 #if defined(AFS_LINUX20_ENV)
27 #include <sys/resource.h>
30 #ifdef HAVE_SYS_FS_TYPES_H
31 #include <sys/fs_types.h>
34 #ifdef HAVE_SYS_MOUNT_H
35 #include <sys/mount.h>
38 #ifdef HAVE_SYS_FCNTL_H
39 #include <sys/fcntl.h>
42 #ifdef HAVE_SYS_MNTTAB_H
43 #include <sys/mnttab.h>
46 #ifdef HAVE_SYS_MNTENT_H
47 #include <sys/mntent.h>
54 #ifdef HAVE_SYS_MOUNT_H
55 #include <sys/mount.h>
62 #ifdef HAVE_SYS_FSTYP_H
63 #include <sys/fstyp.h>
69 #include <afs/afs_args.h>
70 #include <afs/cellconfig.h>
71 #include <afs/afssyscalls.h>
72 #include <afs/afsutil.h>
75 #ifdef AFS_DARWIN80_ENV
76 #include <sys/xattr.h>
78 #include <mach/mach.h>
79 #ifndef AFS_DARWIN100_ENV
80 /* Symbols from the DiskArbitration framework */
81 kern_return_t DiskArbStart(mach_port_t *);
82 kern_return_t DiskArbDiskAppearedWithMountpointPing_auto(char *, unsigned int,
84 #define DISK_ARB_NETWORK_DISK_FLAG 8
86 #include <mach/mach_port.h>
87 #include <mach/mach_interface.h>
88 #include <mach/mach_init.h>
89 #endif /* AFS_DARWIN_ENV */
92 #define MOUNT_AFS AFS_MOUNT_AFS
93 #endif /* MOUNT_AFS */
97 # define SET_RTPRI(P) { \
98 struct sched_param sp; \
99 sp.sched_priority = P; \
100 if (sched_setscheduler(0, SCHED_RR, &sp)<0) { \
101 perror("sched_setscheduler"); \
104 # define SET_AFSD_RTPRI() SET_RTPRI(68)
105 # define SET_RX_RTPRI() SET_RTPRI(199)
107 # ifdef AFS_LINUX20_ENV
108 # define SET_AFSD_RTPRI()
109 # define SET_RX_RTPRI() do { \
110 if (setpriority(PRIO_PROCESS, 0, -10) < 0) \
111 perror("setting rx priority"); \
114 # define SET_AFSD_RTPRI()
115 # define SET_RX_RTPRI()
120 afsd_set_rx_rtpri(void)
126 afsd_set_afsd_rtpri(void)
131 #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
134 afsd_call_syscall(long param1, long param2, long param3, long param4, long param5,
135 long param6, long param7)
138 # ifdef AFS_LINUX20_ENV
140 struct afsprocdata syscall_data;
141 int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
143 fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
149 param4 = (long)eparm;
151 syscall_data.syscall = AFSCALL_CALL;
152 syscall_data.param1 = param1;
153 syscall_data.param2 = param2;
154 syscall_data.param3 = param3;
155 syscall_data.param4 = param4;
157 error = ioctl(fd, VIOC_SYSCALL, &syscall_data);
160 # endif /* AFS_LINUX20_ENV */
161 # ifdef AFS_DARWIN80_ENV
162 struct afssysargs syscall_data;
164 int fd = open(SYSCALL_DEV_FNAME,O_RDWR);
166 #ifdef AFS_DARWIN100_ENV
168 struct afssysargs64 syscall64_data;
169 if (sizeof(param1) == 8) {
170 syscallnum = VIOC_SYSCALL64;
172 ioctldata = &syscall64_data;
173 syscall64_data.syscall = (int)AFSCALL_CALL;
174 syscall64_data.param1 = param1;
175 syscall64_data.param2 = param2;
176 syscall64_data.param3 = param3;
177 syscall64_data.param4 = param4;
178 syscall64_data.param5 = param5;
179 syscall64_data.param6 = param6;
182 syscallnum = VIOC_SYSCALL;
183 ioctldata = &syscall_data;
184 syscall_data.syscall = AFSCALL_CALL;
185 syscall_data.param1 = param1;
186 syscall_data.param2 = param2;
187 syscall_data.param3 = param3;
188 syscall_data.param4 = param4;
189 syscall_data.param5 = param5;
190 syscall_data.param6 = param6;
191 #ifdef AFS_DARWIN100_ENV
195 error = ioctl(fd, syscallnum, ioctldata);
201 #ifdef AFS_DARWIN100_ENV
203 error=syscall64_data.retval;
206 error=syscall_data.retval;
208 # elif defined(AFS_SUN511_ENV)
211 rval = ioctl_sun_afs_syscall(AFSCALL_CALL, param1, param2, param3,
212 param4, param5, param6, &error);
217 # else /* AFS_DARWIN80_ENV */
219 syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4,
220 param5, param6, param7);
221 # endif /* !AFS_DARWIN80_ENV */
224 #ifdef AFS_NBSD40_ENV
225 char *s = strerror(errno);
226 printf("SScall(%d, %d, %d)=%d (%d, %s)\n", AFS_SYSCALL, AFSCALL_CALL,
227 param1, error, errno, s);
229 printf("SScall(%d, %d, %ld)=%d ", AFS_SYSCALL, AFSCALL_CALL, param1,
236 #else /* !AFS_SGI_ENV && !AFS_AIX32_ENV */
237 # if defined(AFS_SGI_ENV)
239 afsd_call_syscall(call, parm0, parm1, parm2, parm3, parm4)
244 error = afs_syscall(call, parm0, parm1, parm2, parm3, parm4);
246 printf("SScall(%d, %d)=%d ", call, parm0, error);
250 # else /* AFS_SGI_ENV */
252 afsd_call_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, parm6)
255 return syscall(AFSCALL_CALL, call, parm0, parm1, parm2, parm3, parm4,
258 # endif /* !AFS_SGI_ENV */
259 #endif /* AFS_SGI_ENV || AFS_AIX32_ENV */
263 /* Special handling for AIX's afs mount operation since they require much more
264 * miscl. information before making the vmount(2) syscall */
267 #define ROUNDUP(x) (((x) + 3) & ~3)
269 aix_vmount(const char *cacheMountDir)
271 struct vmount *vmountp;
274 size = sizeof(struct vmount) + ROUNDUP(strlen(cacheMountDir) + 1) + 5 * 4;
275 /* Malloc and zero the vmount structure */
276 if ((vmountp = calloc(1, size)) == NULL) {
277 printf("Can't allocate space for the vmount structure (AIX)\n");
281 /* transfer info into the vmount structure */
282 vmountp->vmt_revision = VMT_REVISION;
283 vmountp->vmt_length = size;
284 vmountp->vmt_fsid.fsid_dev = 0;
285 vmountp->vmt_fsid.fsid_type = AFS_MOUNT_AFS;
286 vmountp->vmt_vfsnumber = 0;
287 vmountp->vmt_time = 0; /* We'll put the time soon! */
288 vmountp->vmt_flags = VFS_DEVMOUNT; /* read/write permission */
289 vmountp->vmt_gfstype = AFS_MOUNT_AFS;
290 vmountdata(vmountp, "AFS", cacheMountDir, "", "", "", "rw");
292 /* Do the actual mount system call */
293 error = vmount(vmountp, size);
298 vmountdata(struct vmount * vmtp, char *obj, char *stub, char *host,
299 char *hostsname, char *info, char *args)
307 vdp = (struct data *)vmtp->vmt_data;
308 vdp->vmt_off = sizeof(struct vmount);
309 size = ROUNDUP(strlen(obj) + 1);
310 vdp->vmt_size = size;
311 strcpy(vmt2dataptr(vmtp, VMT_OBJECT), obj);
315 vdp->vmt_off = vdprev->vmt_off + size;
316 size = ROUNDUP(strlen(stub) + 1);
317 vdp->vmt_size = size;
318 strcpy(vmt2dataptr(vmtp, VMT_STUB), stub);
322 vdp->vmt_off = vdprev->vmt_off + size;
323 size = ROUNDUP(strlen(host) + 1);
324 vdp->vmt_size = size;
325 strcpy(vmt2dataptr(vmtp, VMT_HOST), host);
329 vdp->vmt_off = vdprev->vmt_off + size;
330 size = ROUNDUP(strlen(hostsname) + 1);
331 vdp->vmt_size = size;
332 strcpy(vmt2dataptr(vmtp, VMT_HOSTNAME), hostsname);
337 vdp->vmt_off = vdprev->vmt_off + size;
338 size = ROUNDUP(strlen(info) + 1);
339 vdp->vmt_size = size;
340 strcpy(vmt2dataptr(vmtp, VMT_INFO), info);
344 vdp->vmt_off = vdprev->vmt_off + size;
345 size = ROUNDUP(strlen(args) + 1);
346 vdp->vmt_size = size;
347 strcpy(vmt2dataptr(vmtp, VMT_ARGS), args);
349 #endif /* AFS_AIX_ENV */
352 #define MOUNTED_TABLE MNT_MNTTAB
354 #define MOUNTED_TABLE MOUNTED
358 HandleMTab(char *cacheMountDir)
360 #if (defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV))
362 #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
363 struct mntent tmntent;
367 tfilep = setmntent("/etc/mtab", "a+");
369 printf("Can't open /etc/mtab for writing (errno %d); not adding "
370 "an entry for AFS\n", errno);
374 dir = strdup(cacheMountDir);
376 /* trim trailing slashes; don't look at dir[0] in case we are somehow
378 for (i = strlen(dir)-1; i > 0; i--) {
386 tmntent.mnt_fsname = "AFS";
387 tmntent.mnt_dir = dir;
388 tmntent.mnt_type = "afs";
389 tmntent.mnt_opts = "rw";
390 tmntent.mnt_freq = 1;
391 tmntent.mnt_passno = 3;
392 addmntent(tfilep, &tmntent);
398 struct mntent tmntent;
400 memset(&tmntent, '\0', sizeof(struct mntent));
401 tfilep = setmntent(MOUNTED_TABLE, "a+");
403 printf("Can't open %s for write; Not adding afs entry to it\n",
407 tmntent.mnt_fsname = "AFS";
408 tmntent.mnt_dir = cacheMountDir;
409 tmntent.mnt_type = "xx";
410 tmntent.mnt_opts = "rw";
411 tmntent.mnt_freq = 1;
412 tmntent.mnt_passno = 3;
414 tmntent.mnt_type = "afs";
415 tmntent.mnt_time = time(0);
416 tmntent.mnt_cnode = 0;
418 addmntent(tfilep, &tmntent);
420 #endif /* AFS_SGI_ENV */
421 #endif /* unreasonable systems */
422 #ifdef AFS_DARWIN_ENV
423 #ifndef AFS_DARWIN100_ENV
424 mach_port_t diskarb_port;
425 kern_return_t status;
427 status = DiskArbStart(&diskarb_port);
428 if (status == KERN_SUCCESS) {
430 DiskArbDiskAppearedWithMountpointPing_auto("AFS",
431 DISK_ARB_NETWORK_DISK_FLAG,
437 #endif /* AFS_DARWIN_ENV */
442 afsd_mount_afs(const char *rn, const char *cacheMountDir)
444 int mountFlags; /*Flags passed to mount() */
445 char *mountDir; /* For HandleMTab() */
447 mountFlags = 0; /* Read/write file system, can do setuid() */
448 #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
450 mountFlags |= MS_DATA;
452 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... */
456 #if defined(AFS_HPUX100_ENV)
457 mountFlags |= MS_DATA;
461 printf("%s: Mounting the AFS root on '%s', flags: %d.\n", rn,
462 cacheMountDir, mountFlags);
463 #if defined(AFS_FBSD60_ENV)
464 /* data must be non-NULL but is otherwise ignored */
465 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, rn)) < 0) {
466 #elif defined(AFS_FBSD_ENV)
467 if ((mount("AFS", cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
468 #elif defined(AFS_AIX_ENV)
469 if (aix_vmount(cacheMountDir)) {
470 #elif defined(AFS_HPUX100_ENV)
471 if ((mount("", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
472 #elif defined(AFS_SUN5_ENV)
473 if ((mount("AFS", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
474 #elif defined(AFS_SGI_ENV)
476 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) MOUNT_AFS))
478 #elif defined(AFS_LINUX20_ENV)
479 if ((mount("AFS", cacheMountDir, MOUNT_AFS, 0, NULL)) < 0) {
480 #elif defined(AFS_NBSD50_ENV)
481 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, NULL, 0)) < 0) {
483 /* This is the standard mount used by the suns and rts */
484 if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
486 printf("%s: Can't mount AFS on %s(%d)\n", rn, cacheMountDir,
491 mountDir = strdup(cacheMountDir);
492 HandleMTab(mountDir);
497 afsd_fork(int wait, afsd_callback_func cb, void *rock)
507 assert(waitpid(code, NULL, 0) != -1);
514 afsd_daemon(int nochdir, int noclose)
516 return daemon(nochdir, noclose);
520 afsd_check_mount(const char *rn, const char *mountdir)
524 if (stat(mountdir, &statbuf)) {
525 printf("%s: Mountpoint %s missing.\n", rn, mountdir);
527 } else if (!S_ISDIR(statbuf.st_mode)) {
528 printf("%s: Mountpoint %s is not a directory.\n", rn, mountdir);
535 main(int argc, char **argv)
541 code = afsd_parse(argc, argv);