Deleted Added
full compact
hlfsd.c (131706) hlfsd.c (174313)
1/*
1/*
2 * Copyright (c) 1997-2004 Erez Zadok
2 * Copyright (c) 1997-2006 Erez Zadok
3 * Copyright (c) 1989 Jan-Simon Pendry
4 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
10 *

--- 20 unchanged lines hidden (view full) ---

31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
3 * Copyright (c) 1989 Jan-Simon Pendry
4 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
10 *

--- 20 unchanged lines hidden (view full) ---

31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * %W% (Berkeley) %G%
40 *
39 *
41 * $Id: hlfsd.c,v 1.7.2.9 2004/01/19 00:25:55 ezk Exp $
42 * $FreeBSD: head/contrib/amd/hlfsd/hlfsd.c 131706 2004-07-06 13:16:49Z mbr $
40 * File: am-utils/hlfsd/hlfsd.c
43 *
44 * HLFSD was written at Columbia University Computer Science Department, by
45 * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
46 * It is being distributed under the same terms and conditions as amd does.
47 */
48
49#ifdef HAVE_CONFIG_H
50# include <config.h>

--- 30 unchanged lines hidden (view full) ---

81 */
82SVCXPRT *nfsxprt;
83char *alt_spooldir = ALT_SPOOLDIR;
84char *home_subdir = HOME_SUBDIR;
85char *logfile = DEFAULT_LOGFILE;
86char *passwdfile = NULL; /* alternate passwd file to use */
87char *slinkname = 0;
88char hostname[MAXHOSTNAMELEN + 1] = "localhost";
41 *
42 * HLFSD was written at Columbia University Computer Science Department, by
43 * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
44 * It is being distributed under the same terms and conditions as amd does.
45 */
46
47#ifdef HAVE_CONFIG_H
48# include <config.h>

--- 30 unchanged lines hidden (view full) ---

79 */
80SVCXPRT *nfsxprt;
81char *alt_spooldir = ALT_SPOOLDIR;
82char *home_subdir = HOME_SUBDIR;
83char *logfile = DEFAULT_LOGFILE;
84char *passwdfile = NULL; /* alternate passwd file to use */
85char *slinkname = 0;
86char hostname[MAXHOSTNAMELEN + 1] = "localhost";
89int cache_interval = DEFAULT_CACHE_INTERVAL;
87u_int cache_interval = DEFAULT_CACHE_INTERVAL;
90gid_t hlfs_gid = (gid_t) INVALIDID;
91int masterpid = 0;
92int noverify = 0;
93int orig_umask = 022;
94int serverpid = 0;
95nfstime startup;
96u_short nfs_port;
97

--- 19 unchanged lines hidden (view full) ---

117#ifdef DEBUG
118 show_opts('D', dbg_opt);
119#endif /* DEBUG */
120 fprintf(stderr, "\t[dir_name [subdir]]\n");
121 exit(2);
122}
123
124
88gid_t hlfs_gid = (gid_t) INVALIDID;
89int masterpid = 0;
90int noverify = 0;
91int orig_umask = 022;
92int serverpid = 0;
93nfstime startup;
94u_short nfs_port;
95

--- 19 unchanged lines hidden (view full) ---

115#ifdef DEBUG
116 show_opts('D', dbg_opt);
117#endif /* DEBUG */
118 fprintf(stderr, "\t[dir_name [subdir]]\n");
119 exit(2);
120}
121
122
123void
124fatalerror(char *str)
125{
126#define ERRM ": %m"
127 size_t l = strlen(str) + sizeof(ERRM) - 1;
128 char *tmp = strnsave(str, l);
129 xstrlcat(tmp, ERRM, l);
130 fatal(tmp);
131}
132
133
125int
126main(int argc, char *argv[])
127{
128 char *dot;
129 char *mntopts = (char *) NULL;
130 char hostpid_fs[MAXHOSTNAMELEN + 1 + 16]; /* room for ":(pid###)" */
131 char progpid_fs[PROGNAMESZ + 1 + 11]; /* room for ":pid" */
132 char preopts[128];

--- 171 unchanged lines hidden (view full) ---

304
305 /* get hostname for logging and open log before we reset umask */
306 gethostname(hostname, sizeof(hostname));
307 hostname[sizeof(hostname) - 1] = '\0';
308 if ((dot = strchr(hostname, '.')) != NULL)
309 *dot = '\0';
310 orig_umask = umask(0);
311 if (logfile)
134int
135main(int argc, char *argv[])
136{
137 char *dot;
138 char *mntopts = (char *) NULL;
139 char hostpid_fs[MAXHOSTNAMELEN + 1 + 16]; /* room for ":(pid###)" */
140 char progpid_fs[PROGNAMESZ + 1 + 11]; /* room for ":pid" */
141 char preopts[128];

--- 171 unchanged lines hidden (view full) ---

313
314 /* get hostname for logging and open log before we reset umask */
315 gethostname(hostname, sizeof(hostname));
316 hostname[sizeof(hostname) - 1] = '\0';
317 if ((dot = strchr(hostname, '.')) != NULL)
318 *dot = '\0';
319 orig_umask = umask(0);
320 if (logfile)
312 switch_to_logfile(logfile, orig_umask);
321 switch_to_logfile(logfile, orig_umask, 0);
313
322
314#if defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE)
315 if (debug_flags & D_MTAB)
323#ifndef MOUNT_TABLE_ON_FILE
324 if (amuDebug(D_MTAB))
316 dlog("-D mtab option ignored");
325 dlog("-D mtab option ignored");
317#endif /* defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE) */
326#endif /* not MOUNT_TABLE_ON_FILE */
318
319 /* avoid hanging on other NFS servers if started elsewhere */
320 if (chdir("/") < 0)
321 fatal("cannot chdir to /: %m");
322
323 if (geteuid() != 0)
324 fatal("must be root to mount filesystems");
325

--- 7 unchanged lines hidden (view full) ---

333 (dir_name[0] == '\0' || slinkname[0] == '\0'))) {
334 if (slinkname)
335 *--slinkname = '/';
336 printf("%s: invalid mount directory/link %s\n",
337 am_get_progname(), dir_name);
338 exit(3);
339 }
340
327
328 /* avoid hanging on other NFS servers if started elsewhere */
329 if (chdir("/") < 0)
330 fatal("cannot chdir to /: %m");
331
332 if (geteuid() != 0)
333 fatal("must be root to mount filesystems");
334

--- 7 unchanged lines hidden (view full) ---

342 (dir_name[0] == '\0' || slinkname[0] == '\0'))) {
343 if (slinkname)
344 *--slinkname = '/';
345 printf("%s: invalid mount directory/link %s\n",
346 am_get_progname(), dir_name);
347 exit(3);
348 }
349
341 clock_valid = 0; /* invalidate logging clock */
342
343 if (!forcefast) {
344 /* make sure mount point exists and is at least mode 555 */
345 if (stat(dir_name, &stmodes) < 0)
346 if (errno != ENOENT || mkdirs(dir_name, 0555) < 0
347 || stat(dir_name, &stmodes) < 0)
348 fatalerror(dir_name);
349
350 if ((stmodes.st_mode & 0555) != 0555) {

--- 28 unchanged lines hidden (view full) ---

379 am_get_progname());
380 perror(alt_spooldir);
381 plog(XLOG_ERROR, "cannot create alternate dir %s: %m",
382 alt_spooldir);
383 }
384 chmod(alt_spooldir, OPEN_SPOOLMODE);
385
386 /* create failsafe link to alternate spool directory */
350 if (!forcefast) {
351 /* make sure mount point exists and is at least mode 555 */
352 if (stat(dir_name, &stmodes) < 0)
353 if (errno != ENOENT || mkdirs(dir_name, 0555) < 0
354 || stat(dir_name, &stmodes) < 0)
355 fatalerror(dir_name);
356
357 if ((stmodes.st_mode & 0555) != 0555) {

--- 28 unchanged lines hidden (view full) ---

386 am_get_progname());
387 perror(alt_spooldir);
388 plog(XLOG_ERROR, "cannot create alternate dir %s: %m",
389 alt_spooldir);
390 }
391 chmod(alt_spooldir, OPEN_SPOOLMODE);
392
393 /* create failsafe link to alternate spool directory */
387 slinkname[-1] = '/'; /* unsplit dir_name to include link */
394 *(slinkname-1) = '/'; /* unsplit dir_name to include link */
388 if (lstat(dir_name, &stmodes) == 0 &&
389 (stmodes.st_mode & S_IFMT) != S_IFLNK) {
390 fprintf(stderr, "%s: failsafe %s not a symlink\n",
391 am_get_progname(), dir_name);
392 plog(XLOG_WARNING, "failsafe %s not a symlink\n",
393 dir_name);
394 } else {
395 unlink(dir_name);

--- 4 unchanged lines hidden (view full) ---

400 am_get_progname(), dir_name);
401 perror(alt_spooldir);
402 plog(XLOG_WARNING,
403 "cannot create failsafe symlink %s -> %s: %m",
404 dir_name, alt_spooldir);
405 }
406 }
407
395 if (lstat(dir_name, &stmodes) == 0 &&
396 (stmodes.st_mode & S_IFMT) != S_IFLNK) {
397 fprintf(stderr, "%s: failsafe %s not a symlink\n",
398 am_get_progname(), dir_name);
399 plog(XLOG_WARNING, "failsafe %s not a symlink\n",
400 dir_name);
401 } else {
402 unlink(dir_name);

--- 4 unchanged lines hidden (view full) ---

407 am_get_progname(), dir_name);
408 perror(alt_spooldir);
409 plog(XLOG_WARNING,
410 "cannot create failsafe symlink %s -> %s: %m",
411 dir_name, alt_spooldir);
412 }
413 }
414
408 slinkname[-1] = '\0'; /* resplit dir_name */
415 *(slinkname-1) = '\0'; /* resplit dir_name */
409 } /* end of "if (!forcefast) {" */
410
411 /*
412 * Register hlfsd as an nfs service with the portmapper.
413 */
414#ifdef HAVE_TRANSPORT_TYPE_TLI
415 ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
416#else /* not HAVE_TRANSPORT_TYPE_TLI */
417 ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
418#endif /* not HAVE_TRANSPORT_TYPE_TLI */
419 if (ret != 0)
420 fatal("cannot create NFS service");
421
422#ifdef HAVE_SIGACTION
423 sa.sa_handler = proceed;
416 } /* end of "if (!forcefast) {" */
417
418 /*
419 * Register hlfsd as an nfs service with the portmapper.
420 */
421#ifdef HAVE_TRANSPORT_TYPE_TLI
422 ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
423#else /* not HAVE_TRANSPORT_TYPE_TLI */
424 ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
425#endif /* not HAVE_TRANSPORT_TYPE_TLI */
426 if (ret != 0)
427 fatal("cannot create NFS service");
428
429#ifdef HAVE_SIGACTION
430 sa.sa_handler = proceed;
424 sa.sa_flags = SA_RESTART;
431 sa.sa_flags = 0;
425 sigemptyset(&(sa.sa_mask));
426 sigaddset(&(sa.sa_mask), SIGUSR2);
427 sigaction(SIGUSR2, &sa, NULL);
428#else /* not HAVE_SIGACTION */
429 signal(SIGUSR2, proceed);
430#endif /* not HAVE_SIGACTION */
431
432 plog(XLOG_INFO, "Initializing hlfsd...");
433 hlfsd_init(); /* start up child (forking) to run svc_run */
434
435#ifdef HAVE_SIGACTION
436 sa.sa_handler = reaper;
432 sigemptyset(&(sa.sa_mask));
433 sigaddset(&(sa.sa_mask), SIGUSR2);
434 sigaction(SIGUSR2, &sa, NULL);
435#else /* not HAVE_SIGACTION */
436 signal(SIGUSR2, proceed);
437#endif /* not HAVE_SIGACTION */
438
439 plog(XLOG_INFO, "Initializing hlfsd...");
440 hlfsd_init(); /* start up child (forking) to run svc_run */
441
442#ifdef HAVE_SIGACTION
443 sa.sa_handler = reaper;
437 sa.sa_flags = SA_RESTART;
444 sa.sa_flags = 0;
438 sigemptyset(&(sa.sa_mask));
439 sigaddset(&(sa.sa_mask), SIGCHLD);
440 sigaction(SIGCHLD, &sa, NULL);
441#else /* not HAVE_SIGACTION */
442 signal(SIGCHLD, reaper);
443#endif /* not HAVE_SIGACTION */
444
445 sigemptyset(&(sa.sa_mask));
446 sigaddset(&(sa.sa_mask), SIGCHLD);
447 sigaction(SIGCHLD, &sa, NULL);
448#else /* not HAVE_SIGACTION */
449 signal(SIGCHLD, reaper);
450#endif /* not HAVE_SIGACTION */
451
445#ifdef DEBUG
446 /*
452 /*
447 * In the parent, if -D nodaemon (or -D daemon) , we don't need to
453 * In the parent, if -D daemon, we don't need to
448 * set this signal handler.
449 */
454 * set this signal handler.
455 */
450 amuDebug(D_DAEMON) {
451#endif /* DEBUG */
452 /* XXX: port to use pure svr4 signals */
456 if (!amuDebug(D_DAEMON)) {
453 s = -99;
454 while (stoplight != SIGUSR2) {
455 plog(XLOG_INFO, "parent waits for child to setup (stoplight=%d)", stoplight);
457 s = -99;
458 while (stoplight != SIGUSR2) {
459 plog(XLOG_INFO, "parent waits for child to setup (stoplight=%d)", stoplight);
460#ifdef HAVE_SIGSUSPEND
461 {
462 sigset_t mask;
463 sigemptyset(&mask);
464 s = sigsuspend(&mask); /* wait for child to set up */
465 }
466#else /* not HAVE_SIGSUSPEND */
456 s = sigpause(0); /* wait for child to set up */
467 s = sigpause(0); /* wait for child to set up */
468#endif /* not HAVE_SIGSUSPEND */
457 sleep(1);
458 }
469 sleep(1);
470 }
459#ifdef DEBUG
460 }
471 }
461#endif /* DEBUG */
462
463 /*
464 * setup options to mount table (/etc/{mtab,mnttab}) entry
465 */
472
473 /*
474 * setup options to mount table (/etc/{mtab,mnttab}) entry
475 */
466 sprintf(hostpid_fs, "%s:(pid%d)", hostname, masterpid);
476 xsnprintf(hostpid_fs, sizeof(hostpid_fs),
477 "%s:(pid%d)", hostname, masterpid);
467 memset((char *) &mnt, 0, sizeof(mnt));
468 mnt.mnt_dir = dir_name; /* i.e., "/mail" */
469 mnt.mnt_fsname = hostpid_fs;
470 if (mntopts) {
471 mnt.mnt_opts = mntopts;
472 } else {
478 memset((char *) &mnt, 0, sizeof(mnt));
479 mnt.mnt_dir = dir_name; /* i.e., "/mail" */
480 mnt.mnt_fsname = hostpid_fs;
481 if (mntopts) {
482 mnt.mnt_opts = mntopts;
483 } else {
473 strcpy(preopts, default_mntopts);
484 xstrlcpy(preopts, default_mntopts, sizeof(preopts));
474 /*
475 * Turn off all kinds of attribute and symlink caches as
476 * much as possible. Also make sure that mount does not
477 * show up to df.
478 */
479#ifdef MNTTAB_OPT_INTR
485 /*
486 * Turn off all kinds of attribute and symlink caches as
487 * much as possible. Also make sure that mount does not
488 * show up to df.
489 */
490#ifdef MNTTAB_OPT_INTR
480 strcat(preopts, ",");
481 strcat(preopts, MNTTAB_OPT_INTR);
491 xstrlcat(preopts, ",", sizeof(preopts));
492 xstrlcat(preopts, MNTTAB_OPT_INTR, sizeof(preopts));
482#endif /* MNTTAB_OPT_INTR */
483#ifdef MNTTAB_OPT_IGNORE
493#endif /* MNTTAB_OPT_INTR */
494#ifdef MNTTAB_OPT_IGNORE
484 strcat(preopts, ",");
485 strcat(preopts, MNTTAB_OPT_IGNORE);
495 xstrlcat(preopts, ",", sizeof(preopts));
496 xstrlcat(preopts, MNTTAB_OPT_IGNORE, sizeof(preopts));
486#endif /* MNTTAB_OPT_IGNORE */
487#ifdef MNT2_GEN_OPT_CACHE
497#endif /* MNTTAB_OPT_IGNORE */
498#ifdef MNT2_GEN_OPT_CACHE
488 strcat(preopts, ",nocache");
499 xstrlcat(preopts, ",nocache", sizeof(preopts));
489#endif /* MNT2_GEN_OPT_CACHE */
490#ifdef MNT2_NFS_OPT_SYMTTL
500#endif /* MNT2_GEN_OPT_CACHE */
501#ifdef MNT2_NFS_OPT_SYMTTL
491 strcat(preopts, ",symttl=0");
502 xstrlcat(preopts, ",symttl=0", sizeof(preopts));
492#endif /* MNT2_NFS_OPT_SYMTTL */
493 mnt.mnt_opts = preopts;
494 }
495
496 /*
497 * Make sure that amd's top-level NFS mounts are hidden by default
498 * from df.
499 * If they don't appear to support the either the "ignore" mnttab
500 * option entry, or the "auto" one, set the mount type to "nfs".
501 */
503#endif /* MNT2_NFS_OPT_SYMTTL */
504 mnt.mnt_opts = preopts;
505 }
506
507 /*
508 * Make sure that amd's top-level NFS mounts are hidden by default
509 * from df.
510 * If they don't appear to support the either the "ignore" mnttab
511 * option entry, or the "auto" one, set the mount type to "nfs".
512 */
513#ifdef HIDE_MOUNT_TYPE
502 mnt.mnt_type = HIDE_MOUNT_TYPE;
514 mnt.mnt_type = HIDE_MOUNT_TYPE;
515#else /* not HIDE_MOUNT_TYPE */
516 mnt.mnt_type = "nfs";
517#endif /* not HIDE_MOUNT_TYPE */
503 /* some systems don't have a mount type, but a mount flag */
504
505#ifndef HAVE_TRANSPORT_TYPE_TLI
518 /* some systems don't have a mount type, but a mount flag */
519
520#ifndef HAVE_TRANSPORT_TYPE_TLI
506 amu_get_myaddress(&localsocket.sin_addr);
521 amu_get_myaddress(&localsocket.sin_addr, NULL);
507 localsocket.sin_family = AF_INET;
508 localsocket.sin_port = htons(nfsxprt->xp_port);
509#endif /* not HAVE_TRANSPORT_TYPE_TLI */
510
511 /*
512 * Update hostname field.
513 * Make some name prog:pid (i.e., hlfsd:174) for hostname
514 */
522 localsocket.sin_family = AF_INET;
523 localsocket.sin_port = htons(nfsxprt->xp_port);
524#endif /* not HAVE_TRANSPORT_TYPE_TLI */
525
526 /*
527 * Update hostname field.
528 * Make some name prog:pid (i.e., hlfsd:174) for hostname
529 */
515 sprintf(progpid_fs, "%s:%d", am_get_progname(), masterpid);
530 xsnprintf(progpid_fs, sizeof(progpid_fs),
531 "%s:%d", am_get_progname(), masterpid);
516
517 /* Most kernels have a name length restriction. */
518 if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN)
532
533 /* Most kernels have a name length restriction. */
534 if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN)
519 strcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..");
535 xstrlcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..",
536 sizeof(progpid_fs) - MAXHOSTNAMELEN + 3);
520
521 genflags = compute_mount_flags(&mnt);
522
523 retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
524 if (retry <= 0)
525 retry = 1; /* XXX */
526
537
538 genflags = compute_mount_flags(&mnt);
539
540 retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
541 if (retry <= 0)
542 retry = 1; /* XXX */
543
527 memmove(&anh.v2.fhs_fh, root_fhp, sizeof(*root_fhp));
544 memmove(&anh.v2, root_fhp, sizeof(*root_fhp));
528#ifdef HAVE_TRANSPORT_TYPE_TLI
529 compute_nfs_args(&nfs_args,
530 &mnt,
531 genflags,
532 nfsncp,
533 NULL, /* remote host IP addr is set below */
534 NFS_VERSION, /* version 2 */
535 "udp", /* XXX: shouldn't this be "udp"? */

--- 9 unchanged lines hidden (view full) ---

545 * because they define a special macro HOST_SELF which is DIFFERENT
546 * than localhost (127.0.0.1)!
547 */
548 nfs_args.addr = &nfsxprt->xp_ltaddr;
549#else /* not HAVE_TRANSPORT_TYPE_TLI */
550 compute_nfs_args(&nfs_args,
551 &mnt,
552 genflags,
545#ifdef HAVE_TRANSPORT_TYPE_TLI
546 compute_nfs_args(&nfs_args,
547 &mnt,
548 genflags,
549 nfsncp,
550 NULL, /* remote host IP addr is set below */
551 NFS_VERSION, /* version 2 */
552 "udp", /* XXX: shouldn't this be "udp"? */

--- 9 unchanged lines hidden (view full) ---

562 * because they define a special macro HOST_SELF which is DIFFERENT
563 * than localhost (127.0.0.1)!
564 */
565 nfs_args.addr = &nfsxprt->xp_ltaddr;
566#else /* not HAVE_TRANSPORT_TYPE_TLI */
567 compute_nfs_args(&nfs_args,
568 &mnt,
569 genflags,
570 NULL,
553 &localsocket,
554 NFS_VERSION, /* version 2 */
555 "udp", /* XXX: shouldn't this be "udp"? */
556 &anh,
557 progpid_fs, /* host name for kernel */
558 hostpid_fs); /* filesystem name for kernel */
559#endif /* not HAVE_TRANSPORT_TYPE_TLI */
560
561 /*************************************************************************
562 * NOTE: while compute_nfs_args() works ok for regular NFS mounts *
563 * the toplvl one is not, and so some options must be corrected by hand *
564 * more carefully, *after* compute_nfs_args() runs. *
565 *************************************************************************/
566 compute_automounter_nfs_args(&nfs_args, &mnt);
567
571 &localsocket,
572 NFS_VERSION, /* version 2 */
573 "udp", /* XXX: shouldn't this be "udp"? */
574 &anh,
575 progpid_fs, /* host name for kernel */
576 hostpid_fs); /* filesystem name for kernel */
577#endif /* not HAVE_TRANSPORT_TYPE_TLI */
578
579 /*************************************************************************
580 * NOTE: while compute_nfs_args() works ok for regular NFS mounts *
581 * the toplvl one is not, and so some options must be corrected by hand *
582 * more carefully, *after* compute_nfs_args() runs. *
583 *************************************************************************/
584 compute_automounter_nfs_args(&nfs_args, &mnt);
585
568 clock_valid = 0; /* invalidate logging clock */
569
570/*
586/*
571 * The following code could be cleverly ifdef-ed, but I duplicated the
572 * mount_fs call three times for simplicity and readability.
573 */
574#ifdef DEBUG
575/*
576 * For some reason, this mount may have to be done in the background, if I am
587 * For some reason, this mount may have to be done in the background, if I am
577 * using -D nodebug. I suspect that the actual act of mounting requires
588 * using -D daemon. I suspect that the actual act of mounting requires
578 * calling to hlfsd itself to invoke one or more of its nfs calls, to stat
589 * calling to hlfsd itself to invoke one or more of its nfs calls, to stat
579 * /mail. That means that even if you say -D nodaemon, at least the mount
590 * /mail. That means that even if you say -D daemon, at least the mount
580 * of hlfsd itself on top of /mail will be done in the background.
581 * The other alternative I have is to run svc_run, but set a special
582 * signal handler to perform the mount in N seconds via some alarm.
583 * -Erez Zadok.
584 */
591 * of hlfsd itself on top of /mail will be done in the background.
592 * The other alternative I have is to run svc_run, but set a special
593 * signal handler to perform the mount in N seconds via some alarm.
594 * -Erez Zadok.
595 */
585 if (debug_flags & D_DAEMON) { /* asked for -D daemon */
586 plog(XLOG_INFO, "parent NFS mounting hlfsd service points");
587 if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0)
596 if (!amuDebug(D_DAEMON)) { /* Normal case */
597 plog(XLOG_INFO, "normal NFS mounting hlfsd service points");
598 if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, 0) < 0)
588 fatal("nfsmount: %m");
599 fatal("nfsmount: %m");
589 } else { /* asked for -D nodaemon */
600 } else { /* asked for -D daemon */
590 if (fork() == 0) { /* child runs mount */
591 am_set_mypid();
592 foreground = 0;
593 plog(XLOG_INFO, "child NFS mounting hlfsd service points");
601 if (fork() == 0) { /* child runs mount */
602 am_set_mypid();
603 foreground = 0;
604 plog(XLOG_INFO, "child NFS mounting hlfsd service points");
594 if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0) {
605 if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, 0) < 0) {
595 fatal("nfsmount: %m");
596 }
597 exit(0); /* all went well */
598 } else { /* fork failed or parent running */
599 plog(XLOG_INFO, "parent waiting 1sec for mount...");
600 }
601 }
606 fatal("nfsmount: %m");
607 }
608 exit(0); /* all went well */
609 } else { /* fork failed or parent running */
610 plog(XLOG_INFO, "parent waiting 1sec for mount...");
611 }
612 }
602#else /* not DEBUG */
603 plog(XLOG_INFO, "normal NFS mounting hlfsd service points");
604 if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 2, "udp", mnttab_file_name) < 0)
605 fatal("nfsmount: %m");
606#endif /* not DEBUG */
607
608#ifdef HAVE_TRANSPORT_TYPE_TLI
609 /*
610 * XXX: this free_knetconfig() was not done for hlfsd before,
611 * and apparently there was a reason for it, but why? -Erez
612 */
613 free_knetconfig(nfs_args.knconf);
614 /*
615 * local automounter mounts do not allocate a special address, so
616 * no need to XFREE(nfs_args.addr) under TLI.
617 */
618#endif /* HAVE_TRANSPORT_TYPE_TLI */
619
620 if (printpid)
621 printf("%d\n", masterpid);
622
623 plog(XLOG_INFO, "hlfsd ready to serve");
613
614#ifdef HAVE_TRANSPORT_TYPE_TLI
615 /*
616 * XXX: this free_knetconfig() was not done for hlfsd before,
617 * and apparently there was a reason for it, but why? -Erez
618 */
619 free_knetconfig(nfs_args.knconf);
620 /*
621 * local automounter mounts do not allocate a special address, so
622 * no need to XFREE(nfs_args.addr) under TLI.
623 */
624#endif /* HAVE_TRANSPORT_TYPE_TLI */
625
626 if (printpid)
627 printf("%d\n", masterpid);
628
629 plog(XLOG_INFO, "hlfsd ready to serve");
624#ifdef DEBUG
625 /*
630 /*
626 * If asked not to fork a daemon (-D nodaemon), then hlfsd_init()
631 * If asked not to fork a daemon (-D daemon), then hlfsd_init()
627 * will not run svc_run. We must start svc_run here.
628 */
632 * will not run svc_run. We must start svc_run here.
633 */
629 dlog("starting no-daemon debugging svc_run");
630 amuDebugNo(D_DAEMON)
634 if (amuDebug(D_DAEMON)) {
635 plog(XLOG_DEBUG, "starting no-daemon debugging svc_run");
631 svc_run();
636 svc_run();
632#endif /* DEBUG */
637 }
633
634 cleanup(0); /* should never happen here */
635 return (0); /* everything went fine? */
636}
637
638
639static void
640hlfsd_init(void)
641{
642 int child = 0;
643#ifdef HAVE_SIGACTION
644 struct sigaction sa;
645#endif /* HAVE_SIGACTION */
646
638
639 cleanup(0); /* should never happen here */
640 return (0); /* everything went fine? */
641}
642
643
644static void
645hlfsd_init(void)
646{
647 int child = 0;
648#ifdef HAVE_SIGACTION
649 struct sigaction sa;
650#endif /* HAVE_SIGACTION */
651
647 clock_valid = 0; /* invalidate logging clock */
648
649 /*
650 * Initialize file handles.
651 */
652 plog(XLOG_INFO, "initializing hlfsd file handles");
653 hlfsd_init_filehandles();
654
652 /*
653 * Initialize file handles.
654 */
655 plog(XLOG_INFO, "initializing hlfsd file handles");
656 hlfsd_init_filehandles();
657
655#ifdef DEBUG
656 /*
658 /*
657 * If -D daemon then we must fork.
659 * If not -D daemon then we must fork.
658 */
660 */
659 amuDebug(D_DAEMON)
660#endif /* DEBUG */
661 if (!amuDebug(D_DAEMON))
661 child = fork();
662
663 if (child < 0)
664 fatal("fork: %m");
665
666 if (child != 0) { /* parent process - save child pid */
667 masterpid = child;
668 am_set_mypid(); /* for logging routines */

--- 12 unchanged lines hidden (view full) ---

681 masterpid = serverpid = am_set_mypid(); /* for logging routines */
682
683 /*
684 * SIGALRM/SIGHUP: reload password database if timer expired
685 * or user sent HUP signal.
686 */
687#ifdef HAVE_SIGACTION
688 sa.sa_handler = reload;
662 child = fork();
663
664 if (child < 0)
665 fatal("fork: %m");
666
667 if (child != 0) { /* parent process - save child pid */
668 masterpid = child;
669 am_set_mypid(); /* for logging routines */

--- 12 unchanged lines hidden (view full) ---

682 masterpid = serverpid = am_set_mypid(); /* for logging routines */
683
684 /*
685 * SIGALRM/SIGHUP: reload password database if timer expired
686 * or user sent HUP signal.
687 */
688#ifdef HAVE_SIGACTION
689 sa.sa_handler = reload;
689 sa.sa_flags = SA_RESTART;
690 sa.sa_flags = 0;
690 sigemptyset(&(sa.sa_mask));
691 sigaddset(&(sa.sa_mask), SIGALRM);
692 sigaddset(&(sa.sa_mask), SIGHUP);
693 sigaction(SIGALRM, &sa, NULL);
694 sigaction(SIGHUP, &sa, NULL);
695#else /* not HAVE_SIGACTION */
696 signal(SIGALRM, reload);
697 signal(SIGHUP, reload);
698#endif /* not HAVE_SIGACTION */
699
700 /*
701 * SIGTERM: cleanup and exit.
702 */
703#ifdef HAVE_SIGACTION
704 sa.sa_handler = cleanup;
691 sigemptyset(&(sa.sa_mask));
692 sigaddset(&(sa.sa_mask), SIGALRM);
693 sigaddset(&(sa.sa_mask), SIGHUP);
694 sigaction(SIGALRM, &sa, NULL);
695 sigaction(SIGHUP, &sa, NULL);
696#else /* not HAVE_SIGACTION */
697 signal(SIGALRM, reload);
698 signal(SIGHUP, reload);
699#endif /* not HAVE_SIGACTION */
700
701 /*
702 * SIGTERM: cleanup and exit.
703 */
704#ifdef HAVE_SIGACTION
705 sa.sa_handler = cleanup;
705 sa.sa_flags = SA_RESTART;
706 sa.sa_flags = 0;
706 sigemptyset(&(sa.sa_mask));
707 sigaddset(&(sa.sa_mask), SIGTERM);
708 sigaction(SIGTERM, &sa, NULL);
709#else /* not HAVE_SIGACTION */
710 signal(SIGTERM, cleanup);
711#endif /* not HAVE_SIGACTION */
712
713 /*
714 * SIGCHLD: interlock synchronization and testing
715 */
716#ifdef HAVE_SIGACTION
717 sa.sa_handler = interlock;
707 sigemptyset(&(sa.sa_mask));
708 sigaddset(&(sa.sa_mask), SIGTERM);
709 sigaction(SIGTERM, &sa, NULL);
710#else /* not HAVE_SIGACTION */
711 signal(SIGTERM, cleanup);
712#endif /* not HAVE_SIGACTION */
713
714 /*
715 * SIGCHLD: interlock synchronization and testing
716 */
717#ifdef HAVE_SIGACTION
718 sa.sa_handler = interlock;
718 sa.sa_flags = SA_RESTART;
719 sa.sa_flags = 0;
719 sigemptyset(&(sa.sa_mask));
720 sigaddset(&(sa.sa_mask), SIGCHLD);
721 sigaction(SIGCHLD, &sa, NULL);
722#else /* not HAVE_SIGACTION */
723 signal(SIGCHLD, interlock);
724#endif /* not HAVE_SIGACTION */
725
726 /*
727 * SIGUSR1: dump internal hlfsd maps/cache to file
728 */
729#ifdef HAVE_SIGACTION
730# if defined(DEBUG) || defined(DEBUG_PRINT)
731 sa.sa_handler = plt_print;
732# else /* not defined(DEBUG) || defined(DEBUG_PRINT) */
733 sa.sa_handler = SIG_IGN;
734# endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */
720 sigemptyset(&(sa.sa_mask));
721 sigaddset(&(sa.sa_mask), SIGCHLD);
722 sigaction(SIGCHLD, &sa, NULL);
723#else /* not HAVE_SIGACTION */
724 signal(SIGCHLD, interlock);
725#endif /* not HAVE_SIGACTION */
726
727 /*
728 * SIGUSR1: dump internal hlfsd maps/cache to file
729 */
730#ifdef HAVE_SIGACTION
731# if defined(DEBUG) || defined(DEBUG_PRINT)
732 sa.sa_handler = plt_print;
733# else /* not defined(DEBUG) || defined(DEBUG_PRINT) */
734 sa.sa_handler = SIG_IGN;
735# endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */
735 sa.sa_flags = SA_RESTART;
736 sa.sa_flags = 0;
736 sigemptyset(&(sa.sa_mask));
737 sigaddset(&(sa.sa_mask), SIGUSR1);
738 sigaction(SIGUSR1, &sa, NULL);
739#else /* not HAVE_SIGACTION */
740# if defined(DEBUG) || defined(DEBUG_PRINT)
741 signal(SIGUSR1, plt_print);
742# else /* not defined(DEBUG) || defined(DEBUG_PRINT) */
743 signal(SIGUSR1, SIG_IGN);
744# endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */
745#endif /* not HAVE_SIGACTION */
746
747 if (setitimer(ITIMER_REAL, &reloadinterval, (struct itimerval *) 0) < 0)
748 fatal("setitimer: %m");
749
737 sigemptyset(&(sa.sa_mask));
738 sigaddset(&(sa.sa_mask), SIGUSR1);
739 sigaction(SIGUSR1, &sa, NULL);
740#else /* not HAVE_SIGACTION */
741# if defined(DEBUG) || defined(DEBUG_PRINT)
742 signal(SIGUSR1, plt_print);
743# else /* not defined(DEBUG) || defined(DEBUG_PRINT) */
744 signal(SIGUSR1, SIG_IGN);
745# endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */
746#endif /* not HAVE_SIGACTION */
747
748 if (setitimer(ITIMER_REAL, &reloadinterval, (struct itimerval *) 0) < 0)
749 fatal("setitimer: %m");
750
750 gettimeofday((struct timeval *) ((void *)&startup), (struct timezone *) 0);
751 clocktime(&startup);
751
752
752#ifdef DEBUG
753 /*
753 /*
754 * If -D daemon, then start serving here in the child,
755 * and the parent will exit. But if -D nodaemon, then
754 * If not -D daemon, then start serving here in the child,
755 * and the parent will exit. But if -D daemon, then
756 * skip this code and make sure svc_run is entered elsewhere.
757 */
756 * skip this code and make sure svc_run is entered elsewhere.
757 */
758 amuDebug(D_DAEMON) {
759#endif /* DEBUG */
760
758 if (!amuDebug(D_DAEMON)) {
761 /*
762 * Dissociate from the controlling terminal
763 */
764 amu_release_controlling_tty();
765
766 /*
767 * signal parent we are ready. parent should
768 * mount(2) and die.
769 */
770 if (kill(getppid(), SIGUSR2) < 0)
771 fatal("kill: %m");
772 plog(XLOG_INFO, "starting svc_run");
773 svc_run();
774 cleanup(0); /* should never happen, just in case */
759 /*
760 * Dissociate from the controlling terminal
761 */
762 amu_release_controlling_tty();
763
764 /*
765 * signal parent we are ready. parent should
766 * mount(2) and die.
767 */
768 if (kill(getppid(), SIGUSR2) < 0)
769 fatal("kill: %m");
770 plog(XLOG_INFO, "starting svc_run");
771 svc_run();
772 cleanup(0); /* should never happen, just in case */
775#ifdef DEBUG
776 } /* end of code that runs iff hlfsd daemonizes */
777#endif /* DEBUG */
773 }
778
779}
780
781
782static RETSIGTYPE
783proceed(int signum)
784{
785 stoplight = signum;
786}
787
788
789static RETSIGTYPE
790reload(int signum)
791{
792 int child;
793 int status;
794
774
775}
776
777
778static RETSIGTYPE
779proceed(int signum)
780{
781 stoplight = signum;
782}
783
784
785static RETSIGTYPE
786reload(int signum)
787{
788 int child;
789 int status;
790
795 clock_valid = 0; /* invalidate logging clock */
796
797 if (getpid() != masterpid)
798 return;
799
800 /*
801 * If received a SIGHUP, close and reopen the log file (so that it
802 * can be rotated)
803 */
804 if (signum == SIGHUP && logfile)
791 if (getpid() != masterpid)
792 return;
793
794 /*
795 * If received a SIGHUP, close and reopen the log file (so that it
796 * can be rotated)
797 */
798 if (signum == SIGHUP && logfile)
805 switch_to_logfile(logfile, orig_umask);
799 switch_to_logfile(logfile, orig_umask, 0);
806
807 /*
808 * parent performs the reload, while the child continues to serve
809 * clients accessing the home dir link.
810 */
811 if ((child = fork()) > 0) {
812 serverpid = child; /* parent runs here */
813 am_set_mypid();

--- 26 unchanged lines hidden (view full) ---

840
841
842RETSIGTYPE
843cleanup(int signum)
844{
845 struct stat stbuf;
846 int umount_result;
847
800
801 /*
802 * parent performs the reload, while the child continues to serve
803 * clients accessing the home dir link.
804 */
805 if ((child = fork()) > 0) {
806 serverpid = child; /* parent runs here */
807 am_set_mypid();

--- 26 unchanged lines hidden (view full) ---

834
835
836RETSIGTYPE
837cleanup(int signum)
838{
839 struct stat stbuf;
840 int umount_result;
841
848 clock_valid = 0; /* invalidate logging clock */
849
850#ifdef DEBUG
851 amuDebug(D_DAEMON)
852#endif /* DEBUG */
842 if (!amuDebug(D_DAEMON)) {
853 if (getpid() != masterpid)
854 return;
855
843 if (getpid() != masterpid)
844 return;
845
856#ifdef DEBUG
857 amuDebug(D_DAEMON)
858#endif /* DEBUG */
859 if (fork() != 0) {
860 masterpid = 0;
861 am_set_mypid();
862 return;
863 }
846 if (fork() != 0) {
847 masterpid = 0;
848 am_set_mypid();
849 return;
850 }
851 }
864 am_set_mypid();
865
866 for (;;) {
852 am_set_mypid();
853
854 for (;;) {
867 while ((umount_result = UMOUNT_FS(dir_name, mnttab_file_name)) == EBUSY) {
868#ifdef DEBUG
855 while ((umount_result = UMOUNT_FS(dir_name, mnttab_file_name, 0)) == EBUSY) {
869 dlog("cleanup(): umount delaying for 10 seconds");
856 dlog("cleanup(): umount delaying for 10 seconds");
870#endif /* DEBUG */
871 sleep(10);
872 }
873 if (stat(dir_name, &stbuf) == 0 && stbuf.st_ino == ROOTID) {
874 plog(XLOG_ERROR, "unable to unmount %s", dir_name);
875 plog(XLOG_ERROR, "suspending, unmount before terminating");
876 kill(am_mypid, SIGSTOP);
877 continue; /* retry unmount */
878 }
879 break;
880 }
881
857 sleep(10);
858 }
859 if (stat(dir_name, &stbuf) == 0 && stbuf.st_ino == ROOTID) {
860 plog(XLOG_ERROR, "unable to unmount %s", dir_name);
861 plog(XLOG_ERROR, "suspending, unmount before terminating");
862 kill(am_mypid, SIGSTOP);
863 continue; /* retry unmount */
864 }
865 break;
866 }
867
882#ifdef DEBUG
883 dlog("cleanup(): killing processes and terminating");
884 amuDebug(D_DAEMON)
885#endif /* DEBUG */
868 if (!amuDebug(D_DAEMON)) {
869 plog(XLOG_INFO, "cleanup(): killing processes and terminating");
886 kill(masterpid, SIGKILL);
870 kill(masterpid, SIGKILL);
887
888#ifdef DEBUG
889 amuDebug(D_DAEMON)
890#endif /* DEBUG */
891 kill(serverpid, SIGKILL);
871 kill(serverpid, SIGKILL);
872 }
892
893 plog(XLOG_INFO, "hlfsd terminating with status 0\n");
873
874 plog(XLOG_INFO, "hlfsd terminating with status 0\n");
894 exit(0);
875 _exit(0);
895}
896
897
898static RETSIGTYPE
899reaper(int signum)
900{
901 int result;
902
903 if (wait(&result) == masterpid) {
876}
877
878
879static RETSIGTYPE
880reaper(int signum)
881{
882 int result;
883
884 if (wait(&result) == masterpid) {
904 exit(4);
885 _exit(4);
905 }
906}
907
908
909void
910hlfsd_going_down(int rc)
911{
912 int mypid = getpid(); /* XXX: should this be the global am_mypid */

--- 14 unchanged lines hidden (view full) ---

927 char lessmess[128];
928 int messlen;
929
930 messlen = strlen(mess);
931
932 if (!STREQ(&mess[messlen + 1 - sizeof(ERRM)], ERRM))
933 fprintf(stderr, "%s: %s\n", am_get_progname(), mess);
934 else {
886 }
887}
888
889
890void
891hlfsd_going_down(int rc)
892{
893 int mypid = getpid(); /* XXX: should this be the global am_mypid */

--- 14 unchanged lines hidden (view full) ---

908 char lessmess[128];
909 int messlen;
910
911 messlen = strlen(mess);
912
913 if (!STREQ(&mess[messlen + 1 - sizeof(ERRM)], ERRM))
914 fprintf(stderr, "%s: %s\n", am_get_progname(), mess);
915 else {
935 strcpy(lessmess, mess);
916 xstrlcpy(lessmess, mess, sizeof(lessmess));
936 lessmess[messlen - 4] = '\0';
937
938 fprintf(stderr, "%s: %s: %s\n",
939 am_get_progname(), lessmess, strerror(errno));
940 }
941 }
942 plog(XLOG_FATAL, "%s", mess);
943
944 hlfsd_going_down(1);
945}
917 lessmess[messlen - 4] = '\0';
918
919 fprintf(stderr, "%s: %s: %s\n",
920 am_get_progname(), lessmess, strerror(errno));
921 }
922 }
923 plog(XLOG_FATAL, "%s", mess);
924
925 hlfsd_going_down(1);
926}