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 const char *syscall_str
;
278 #if defined(AFS_SYSCALL)
279 syscall_str
= AFS_STRINGIZE(AFS_SYSCALL
);
281 syscall_str
= "[AFS_SYSCALL]";
284 char *s
= strerror(errno
);
285 printf("SScall(%s, %d, %d)=%d (%d, %s)\n", syscall_str
, AFSCALL_CALL
,
286 (int)args
->params
[0], error
, errno
, s
);
288 printf("SScall(%s, %d, %d)=%d\n", syscall_str
, AFSCALL_CALL
,
289 (int)args
->params
[0], error
);
297 /* Special handling for AIX's afs mount operation since they require much more
298 * miscl. information before making the vmount(2) syscall */
301 #define ROUNDUP(x) (((x) + 3) & ~3)
303 aix_vmount(const char *cacheMountDir
)
305 struct vmount
*vmountp
;
308 size
= sizeof(struct vmount
) + ROUNDUP(strlen(cacheMountDir
) + 1) + 5 * 4;
309 /* Malloc and zero the vmount structure */
310 if ((vmountp
= calloc(1, size
)) == NULL
) {
311 printf("Can't allocate space for the vmount structure (AIX)\n");
315 /* transfer info into the vmount structure */
316 vmountp
->vmt_revision
= VMT_REVISION
;
317 vmountp
->vmt_length
= size
;
318 vmountp
->vmt_fsid
.fsid_dev
= 0;
319 vmountp
->vmt_fsid
.fsid_type
= AFS_MOUNT_AFS
;
320 vmountp
->vmt_vfsnumber
= 0;
321 vmountp
->vmt_time
= 0; /* We'll put the time soon! */
322 vmountp
->vmt_flags
= VFS_DEVMOUNT
; /* read/write permission */
323 vmountp
->vmt_gfstype
= AFS_MOUNT_AFS
;
324 vmountdata(vmountp
, "AFS", cacheMountDir
, "", "", "", "rw");
326 /* Do the actual mount system call */
327 error
= vmount(vmountp
, size
);
332 vmountdata(struct vmount
* vmtp
, char *obj
, char *stub
, char *host
,
333 char *hostsname
, char *info
, char *args
)
341 vdp
= (struct data
*)vmtp
->vmt_data
;
342 vdp
->vmt_off
= sizeof(struct vmount
);
343 size
= ROUNDUP(strlen(obj
) + 1);
344 vdp
->vmt_size
= size
;
345 strcpy(vmt2dataptr(vmtp
, VMT_OBJECT
), obj
);
349 vdp
->vmt_off
= vdprev
->vmt_off
+ size
;
350 size
= ROUNDUP(strlen(stub
) + 1);
351 vdp
->vmt_size
= size
;
352 strcpy(vmt2dataptr(vmtp
, VMT_STUB
), stub
);
356 vdp
->vmt_off
= vdprev
->vmt_off
+ size
;
357 size
= ROUNDUP(strlen(host
) + 1);
358 vdp
->vmt_size
= size
;
359 strcpy(vmt2dataptr(vmtp
, VMT_HOST
), host
);
363 vdp
->vmt_off
= vdprev
->vmt_off
+ size
;
364 size
= ROUNDUP(strlen(hostsname
) + 1);
365 vdp
->vmt_size
= size
;
366 strcpy(vmt2dataptr(vmtp
, VMT_HOSTNAME
), hostsname
);
371 vdp
->vmt_off
= vdprev
->vmt_off
+ size
;
372 size
= ROUNDUP(strlen(info
) + 1);
373 vdp
->vmt_size
= size
;
374 strcpy(vmt2dataptr(vmtp
, VMT_INFO
), info
);
378 vdp
->vmt_off
= vdprev
->vmt_off
+ size
;
379 size
= ROUNDUP(strlen(args
) + 1);
380 vdp
->vmt_size
= size
;
381 strcpy(vmt2dataptr(vmtp
, VMT_ARGS
), args
);
383 #endif /* AFS_AIX_ENV */
386 #define MOUNTED_TABLE MNT_MNTTAB
388 #define MOUNTED_TABLE MOUNTED
392 HandleMTab(char *cacheMountDir
)
394 #if (defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV))
396 #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
397 struct mntent tmntent
;
401 tfilep
= setmntent("/etc/mtab", "a+");
403 printf("Can't open /etc/mtab for writing (errno %d); not adding "
404 "an entry for AFS\n", errno
);
408 dir
= strdup(cacheMountDir
);
410 /* trim trailing slashes; don't look at dir[0] in case we are somehow
412 for (i
= strlen(dir
)-1; i
> 0; i
--) {
420 tmntent
.mnt_fsname
= "AFS";
421 tmntent
.mnt_dir
= dir
;
422 tmntent
.mnt_type
= "afs";
423 tmntent
.mnt_opts
= "rw";
424 tmntent
.mnt_freq
= 1;
425 tmntent
.mnt_passno
= 3;
426 addmntent(tfilep
, &tmntent
);
432 struct mntent tmntent
;
434 memset(&tmntent
, '\0', sizeof(struct mntent
));
435 tfilep
= setmntent(MOUNTED_TABLE
, "a+");
437 printf("Can't open %s for write; Not adding afs entry to it\n",
441 tmntent
.mnt_fsname
= "AFS";
442 tmntent
.mnt_dir
= cacheMountDir
;
443 tmntent
.mnt_type
= "xx";
444 tmntent
.mnt_opts
= "rw";
445 tmntent
.mnt_freq
= 1;
446 tmntent
.mnt_passno
= 3;
448 tmntent
.mnt_type
= "afs";
449 tmntent
.mnt_time
= time(0);
450 tmntent
.mnt_cnode
= 0;
452 addmntent(tfilep
, &tmntent
);
454 #endif /* AFS_SGI_ENV */
455 #endif /* unreasonable systems */
456 #ifdef AFS_DARWIN_ENV
457 #ifndef AFS_DARWIN100_ENV
458 mach_port_t diskarb_port
;
459 kern_return_t status
;
461 status
= DiskArbStart(&diskarb_port
);
462 if (status
== KERN_SUCCESS
) {
464 DiskArbDiskAppearedWithMountpointPing_auto("AFS",
465 DISK_ARB_NETWORK_DISK_FLAG
,
471 #endif /* AFS_DARWIN_ENV */
476 afsd_mount_afs(const char *rn
, const char *cacheMountDir
)
478 int mountFlags
; /*Flags passed to mount() */
479 char *mountDir
; /* For HandleMTab() */
481 mountFlags
= 0; /* Read/write file system, can do setuid() */
482 #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
484 mountFlags
|= MS_DATA
;
486 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... */
490 #if defined(AFS_HPUX100_ENV)
491 mountFlags
|= MS_DATA
;
495 printf("%s: Mounting the AFS root on '%s', flags: %d.\n", rn
,
496 cacheMountDir
, mountFlags
);
497 #if defined(AFS_FBSD60_ENV)
498 /* data must be non-const non-NULL but is otherwise ignored */
499 if ((mount(MOUNT_AFS
, cacheMountDir
, mountFlags
, &mountFlags
)) < 0) {
500 #elif defined(AFS_FBSD_ENV)
501 if ((mount("AFS", cacheMountDir
, mountFlags
, (caddr_t
) 0)) < 0) {
502 #elif defined(AFS_AIX_ENV)
503 if (aix_vmount(cacheMountDir
)) {
504 #elif defined(AFS_HPUX100_ENV)
505 if ((mount("", cacheMountDir
, mountFlags
, "afs", NULL
, 0)) < 0) {
506 #elif defined(AFS_SUN5_ENV)
507 if ((mount("AFS", cacheMountDir
, mountFlags
, "afs", NULL
, 0)) < 0) {
508 #elif defined(AFS_SGI_ENV)
510 if ((mount(MOUNT_AFS
, cacheMountDir
, mountFlags
, (caddr_t
) MOUNT_AFS
))
512 #elif defined(AFS_LINUX20_ENV)
513 if ((mount("AFS", cacheMountDir
, MOUNT_AFS
, 0, NULL
)) < 0) {
514 #elif defined(AFS_NBSD50_ENV)
515 if ((mount(MOUNT_AFS
, cacheMountDir
, mountFlags
, NULL
, 0)) < 0) {
517 /* This is the standard mount used by the suns and rts */
518 if ((mount(MOUNT_AFS
, cacheMountDir
, mountFlags
, (caddr_t
) 0)) < 0) {
520 printf("%s: Can't mount AFS on %s(%d)\n", rn
, cacheMountDir
,
525 mountDir
= strdup(cacheMountDir
);
526 HandleMTab(mountDir
);
531 afsd_fork(int wait
, afsd_callback_func cb
, void *rock
)
541 opr_Verify(waitpid(code
, NULL
, 0) != -1);
548 afsd_daemon(int nochdir
, int noclose
)
550 return daemon(nochdir
, noclose
);
554 afsd_check_mount(const char *rn
, const char *mountdir
)
558 if (stat(mountdir
, &statbuf
)) {
559 printf("%s: Mountpoint %s missing.\n", rn
, mountdir
);
561 } else if (!S_ISDIR(statbuf
.st_mode
)) {
562 printf("%s: Mountpoint %s is not a directory.\n", rn
, mountdir
);
564 } else if (mountdir
[0] != '/') {
565 printf("%s: Mountpoint %s is not an absolute path.\n", rn
, mountdir
);
572 main(int argc
, char **argv
)
578 code
= afsd_parse(argc
, argv
);
579 if (code
== CMD_HELP
) {
580 return 0; /* Displaying help is not an error. */