138494Sobrien/* 2174298Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1989 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1989 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2042633Sobrien * must display the following acknowledgment: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * 40131706Smbr * $Id: amd.c,v 1.8.2.6 2004/01/06 03:15:16 ezk Exp $ 41174298Sobrien * File: am-utils/amd/amd.c 4238494Sobrien * 4338494Sobrien */ 4438494Sobrien 45174298Sobrien#include <sys/cdefs.h> 46174298Sobrien__FBSDID("$FreeBSD$"); 47174298Sobrien 4838494Sobrien/* 4938494Sobrien * Automounter 5038494Sobrien */ 5138494Sobrien 5238494Sobrien#ifdef HAVE_CONFIG_H 5338494Sobrien# include <config.h> 5438494Sobrien#endif /* HAVE_CONFIG_H */ 5538494Sobrien#include <am_defs.h> 5638494Sobrien#include <amd.h> 5738494Sobrien 5838494Sobrienstruct amu_global_options gopt; /* where global options are stored */ 5938494Sobrien 60174298Sobrienchar pid_fsname[SIZEOF_PID_FSNAME]; /* "kiska.southseas.nz:(pid%d)" */ 6138494Sobrienchar *hostdomain = "unknown.domain"; 62174298Sobrien#define SIZEOF_HOSTD (2 * MAXHOSTNAMELEN + 1) /* Host+domain */ 63174298Sobrienchar hostd[SIZEOF_HOSTD]; /* Host+domain */ 6438494Sobrienchar *endian = ARCH_ENDIAN; /* Big or Little endian */ 6538494Sobrienchar *cpu = HOST_CPU; /* CPU type */ 6638494Sobrienchar *PrimNetName; /* name of primary network */ 6738494Sobrienchar *PrimNetNum; /* number of primary network */ 6838494Sobrien 6938494Sobrienint immediate_abort; /* Should close-down unmounts be retried */ 7042633Sobrienint orig_umask = 022; 7138494Sobrienint select_intr_valid; 7238494Sobrien 7338494Sobrienjmp_buf select_intr; 7438494Sobrienstruct amd_stats amd_stats; /* Server statistics */ 7538494Sobrienstruct in_addr myipaddr; /* (An) IP address of this host */ 7638494Sobrientime_t do_mapc_reload = 0; /* mapc_reload() call required? */ 7738494Sobrien 78174298Sobrien#ifdef HAVE_FS_AUTOFS 79174298Sobrienint amd_use_autofs = 0; 80174298Sobrien#endif /* HAVE_FS_AUTOFS */ 81174298Sobrien 8238494Sobrien#ifdef HAVE_SIGACTION 8338494Sobriensigset_t masked_sigs; 8438494Sobrien#endif /* HAVE_SIGACTION */ 8538494Sobrien 8638494Sobrien 8738494Sobrien/* 8838494Sobrien * Signal handler: 8938494Sobrien * SIGINT - tells amd to do a full shutdown, including unmounting all 9038494Sobrien * filesystem. 9138494Sobrien * SIGTERM - tells amd to shutdown now. Just unmounts the automount nodes. 9238494Sobrien */ 9338494Sobrienstatic RETSIGTYPE 9438494Sobriensigterm(int sig) 9538494Sobrien{ 9638494Sobrien#ifdef REINSTALL_SIGNAL_HANDLER 9738494Sobrien signal(sig, sigterm); 9838494Sobrien#endif /* REINSTALL_SIGNAL_HANDLER */ 9938494Sobrien 10038494Sobrien switch (sig) { 10138494Sobrien case SIGINT: 10238494Sobrien immediate_abort = 15; 10338494Sobrien break; 10438494Sobrien 10538494Sobrien case SIGTERM: 10638494Sobrien immediate_abort = -1; 10738494Sobrien /* fall through... */ 10838494Sobrien 10938494Sobrien default: 11038494Sobrien plog(XLOG_WARNING, "WARNING: automounter going down on signal %d", sig); 11138494Sobrien break; 11238494Sobrien } 11338494Sobrien if (select_intr_valid) 11438494Sobrien longjmp(select_intr, sig); 11538494Sobrien} 11638494Sobrien 11738494Sobrien 11838494Sobrien/* 11938494Sobrien * Hook for cache reload. 12038494Sobrien * When a SIGHUP arrives it schedules a call to mapc_reload 12138494Sobrien */ 12238494Sobrienstatic RETSIGTYPE 12338494Sobriensighup(int sig) 12438494Sobrien{ 12538494Sobrien#ifdef REINSTALL_SIGNAL_HANDLER 12638494Sobrien signal(sig, sighup); 12738494Sobrien#endif /* REINSTALL_SIGNAL_HANDLER */ 12838494Sobrien 12938494Sobrien if (sig != SIGHUP) 13038494Sobrien dlog("spurious call to sighup"); 13138494Sobrien /* 13238494Sobrien * Force a reload by zero'ing the timer 13338494Sobrien */ 13438494Sobrien if (amd_state == Run) 13538494Sobrien do_mapc_reload = 0; 13638494Sobrien} 13738494Sobrien 13838494Sobrien 13938494Sobrienstatic RETSIGTYPE 14038494Sobrienparent_exit(int sig) 14138494Sobrien{ 142174298Sobrien /* 143174298Sobrien * This signal handler is called during Amd initialization. The parent 144174298Sobrien * forks a child to do all the hard automounting work, and waits for a 145174298Sobrien * SIGQUIT signal from the child. When the parent gets the signal it's 146174298Sobrien * supposed to call this handler and exit(3), thus completing the 147174298Sobrien * daemonizing process. Alas, on some systems, especially Linux 2.4/2.6 148174298Sobrien * with Glibc, exit(3) doesn't always terminate the parent process. 149174298Sobrien * Worse, the parent process now refuses to accept any more SIGQUIT 150174298Sobrien * signals -- they are blocked. What's really annoying is that this 151174298Sobrien * doesn't happen all the time, suggesting a race condition somewhere. 152174298Sobrien * (This happens even if I change the logic to use another signal.) I 153174298Sobrien * traced this to something which exit(3) does in addition to exiting the 154174298Sobrien * process, probably some atexit() stuff or other side-effects related to 155174298Sobrien * signal handling. Either way, since at this stage the parent process 156174298Sobrien * just needs to terminate, I'm simply calling _exit(2). Note also that 157174298Sobrien * the OpenGroup doesn't list exit(3) as a recommended "Base Interface" 158174298Sobrien * but they do list _exit(2) as one. This fix seems to work reliably all 159174298Sobrien * the time. -Erez (2/27/2005) 160174298Sobrien */ 161174298Sobrien _exit(0); 16238494Sobrien} 16338494Sobrien 16438494Sobrien 16538494Sobrienstatic int 16638494Sobriendaemon_mode(void) 16738494Sobrien{ 16838494Sobrien int bgpid; 16938494Sobrien 17038494Sobrien#ifdef HAVE_SIGACTION 17138494Sobrien struct sigaction sa, osa; 17238494Sobrien 173174298Sobrien memset(&sa, 0, sizeof(sa)); 17438494Sobrien sa.sa_handler = parent_exit; 17538494Sobrien sa.sa_flags = 0; 17638494Sobrien sigemptyset(&(sa.sa_mask)); 17738494Sobrien sigaddset(&(sa.sa_mask), SIGQUIT); 17838494Sobrien sigaction(SIGQUIT, &sa, &osa); 17938494Sobrien#else /* not HAVE_SIGACTION */ 18038494Sobrien signal(SIGQUIT, parent_exit); 18138494Sobrien#endif /* not HAVE_SIGACTION */ 18238494Sobrien 18338494Sobrien bgpid = background(); 18438494Sobrien 18538494Sobrien if (bgpid != 0) { 18638494Sobrien /* 18738494Sobrien * Now wait for the automount points to 18838494Sobrien * complete. 18938494Sobrien */ 19038494Sobrien for (;;) 19138494Sobrien pause(); 19242633Sobrien /* should never reach here */ 19338494Sobrien } 19438494Sobrien#ifdef HAVE_SIGACTION 19538494Sobrien sigaction(SIGQUIT, &osa, NULL); 19638494Sobrien#else /* not HAVE_SIGACTION */ 19738494Sobrien signal(SIGQUIT, SIG_DFL); 19838494Sobrien#endif /* not HAVE_SIGACTION */ 19938494Sobrien 20038494Sobrien /* 20138494Sobrien * Record our pid to make it easier to kill the correct amd. 20238494Sobrien */ 20338494Sobrien if (gopt.flags & CFM_PRINT_PID) { 20438494Sobrien if (STREQ(gopt.pid_file, "/dev/stdout")) { 20542633Sobrien printf("%ld\n", (long) am_mypid); 20682797Sobrien /* flush stdout, just in case */ 20738494Sobrien fflush(stdout); 20838494Sobrien } else { 20938494Sobrien FILE *f; 21038494Sobrien mode_t prev_umask = umask(0022); /* set secure temporary umask */ 21138494Sobrien 21238494Sobrien f = fopen(gopt.pid_file, "w"); 21338494Sobrien if (f) { 21442633Sobrien fprintf(f, "%ld\n", (long) am_mypid); 21538494Sobrien (void) fclose(f); 21638494Sobrien } else { 21738494Sobrien fprintf(stderr, "cannot open %s (errno=%d)\n", gopt.pid_file, errno); 21838494Sobrien } 21938494Sobrien umask(prev_umask); /* restore umask */ 22038494Sobrien } 22138494Sobrien } 22238494Sobrien 22338494Sobrien /* 22438494Sobrien * Pretend we are in the foreground again 22538494Sobrien */ 22638494Sobrien foreground = 1; 22738494Sobrien 22838494Sobrien /* 22938494Sobrien * Dissociate from the controlling terminal 23038494Sobrien */ 23138494Sobrien amu_release_controlling_tty(); 23238494Sobrien 23338494Sobrien return getppid(); 23438494Sobrien} 23538494Sobrien 23638494Sobrien 23738494Sobrien/* 23838494Sobrien * Initialize global options structure. 23938494Sobrien */ 24038494Sobrienstatic void 24138494Sobrieninit_global_options(void) 24238494Sobrien{ 24338494Sobrien#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) 24438494Sobrien static struct utsname un; 24538494Sobrien#endif /* defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) */ 246174298Sobrien int i; 24738494Sobrien 24838494Sobrien memset(&gopt, 0, sizeof(struct amu_global_options)); 24938494Sobrien 25038494Sobrien /* name of current architecture */ 25138494Sobrien gopt.arch = HOST_ARCH; 25238494Sobrien 25338494Sobrien /* automounter temp dir */ 25465308Sobrien gopt.auto_dir = "/.amd_mnt"; 25538494Sobrien 256174298Sobrien /* toplevel attribute cache timeout */ 257174298Sobrien gopt.auto_attrcache = 0; 258174298Sobrien 25938494Sobrien /* cluster name */ 26038494Sobrien gopt.cluster = NULL; 26138494Sobrien 262174298Sobrien /* executable map timeout */ 263174298Sobrien gopt.exec_map_timeout = AMFS_EXEC_MAP_TIMEOUT; 264174298Sobrien 26538494Sobrien /* 26638494Sobrien * kernel architecture: this you must get from uname() if possible. 26738494Sobrien */ 26838494Sobrien#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) 26938494Sobrien if (uname(&un) >= 0) 27038494Sobrien gopt.karch = un.machine; 27138494Sobrien else 27238494Sobrien#endif /* defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) */ 27338494Sobrien gopt.karch = HOST_ARCH; 27438494Sobrien 27538494Sobrien /* amd log file */ 27638494Sobrien gopt.logfile = NULL; 27738494Sobrien 27838494Sobrien /* operating system name */ 27938494Sobrien gopt.op_sys = HOST_OS_NAME; 28038494Sobrien 28138494Sobrien /* OS version */ 28238494Sobrien gopt.op_sys_ver = HOST_OS_VERSION; 28338494Sobrien 28452897Sobrien /* full OS name and version */ 28552897Sobrien gopt.op_sys_full = HOST_OS; 28652897Sobrien 28752897Sobrien /* OS version */ 28852897Sobrien gopt.op_sys_vendor = HOST_VENDOR; 28952897Sobrien 29038494Sobrien /* pid file */ 29138494Sobrien gopt.pid_file = "/dev/stdout"; 29238494Sobrien 29338494Sobrien /* local domain */ 29438494Sobrien gopt.sub_domain = NULL; 29538494Sobrien 296174298Sobrien /* reset NFS (and toplvl) retransmit counter and retry interval */ 297174298Sobrien for (i=0; i<AMU_TYPE_MAX; ++i) { 298174298Sobrien gopt.amfs_auto_retrans[i] = -1; /* -1 means "never set before" */ 299174298Sobrien gopt.amfs_auto_timeo[i] = -1; /* -1 means "never set before" */ 300174298Sobrien } 30138494Sobrien 30238494Sobrien /* cache duration */ 30338494Sobrien gopt.am_timeo = AM_TTL; 30438494Sobrien 30538494Sobrien /* dismount interval */ 30638494Sobrien gopt.am_timeo_w = AM_TTL_W; 30738494Sobrien 308174298Sobrien /* map reload intervl */ 309174298Sobrien gopt.map_reload_interval = ONE_HOUR; 310174298Sobrien 31138494Sobrien /* 312174298Sobrien * various CFM_* flags that are on by default. 31338494Sobrien */ 314174298Sobrien gopt.flags = CFM_DEFAULT_FLAGS; 31538494Sobrien 31638494Sobrien#ifdef HAVE_MAP_HESIOD 31738494Sobrien /* Hesiod rhs zone */ 31838494Sobrien gopt.hesiod_base = "automount"; 31938494Sobrien#endif /* HAVE_MAP_HESIOD */ 32038494Sobrien 32138494Sobrien#ifdef HAVE_MAP_LDAP 32238494Sobrien /* LDAP base */ 32338494Sobrien gopt.ldap_base = NULL; 32438494Sobrien 32538494Sobrien /* LDAP host ports */ 32638494Sobrien gopt.ldap_hostports = NULL; 32738494Sobrien 32838494Sobrien /* LDAP cache */ 32938494Sobrien gopt.ldap_cache_seconds = 0; 33038494Sobrien gopt.ldap_cache_maxmem = 131072; 331174298Sobrien 332174298Sobrien /* LDAP protocol version */ 333174298Sobrien gopt.ldap_proto_version = 2; 33438494Sobrien#endif /* HAVE_MAP_LDAP */ 33538494Sobrien 33638494Sobrien#ifdef HAVE_MAP_NIS 33738494Sobrien /* YP domain name */ 33838494Sobrien gopt.nis_domain = NULL; 33938494Sobrien#endif /* HAVE_MAP_NIS */ 34038494Sobrien} 34138494Sobrien 34238494Sobrien 343174298Sobrien/* 344174298Sobrien * Lock process text and data segment in memory (after forking the daemon) 345174298Sobrien */ 346174298Sobrienstatic void 347174298Sobriendo_memory_locking(void) 348174298Sobrien{ 349174298Sobrien#if defined(HAVE_PLOCK) || defined(HAVE_MLOCKALL) 350174298Sobrien int locked_ok = 0; 351174298Sobrien#else /* not HAVE_PLOCK and not HAVE_MLOCKALL */ 352174298Sobrien plog(XLOG_WARNING, "Process memory locking not supported by the OS"); 353174298Sobrien#endif /* not HAVE_PLOCK and not HAVE_MLOCKALL */ 354174298Sobrien#ifdef HAVE_PLOCK 355174298Sobrien# ifdef _AIX 356174298Sobrien /* 357174298Sobrien * On AIX you must lower the stack size using ulimit() before calling 358174298Sobrien * plock. Otherwise plock will reserve a lot of memory space based on 359174298Sobrien * your maximum stack size limit. Since it is not easily possible to 360174298Sobrien * tell what should the limit be, I print a warning before calling 361174298Sobrien * plock(). See the manual pages for ulimit(1,3,4) on your AIX system. 362174298Sobrien */ 363174298Sobrien plog(XLOG_WARNING, "AIX: may need to lower stack size using ulimit(3) before calling plock"); 364174298Sobrien# endif /* _AIX */ 365174298Sobrien if (!locked_ok && plock(PROCLOCK) != 0) 366174298Sobrien plog(XLOG_WARNING, "Couldn't lock process pages in memory using plock(): %m"); 367174298Sobrien else 368174298Sobrien locked_ok = 1; 369174298Sobrien#endif /* HAVE_PLOCK */ 370174298Sobrien#ifdef HAVE_MLOCKALL 371174298Sobrien if (!locked_ok && mlockall(MCL_CURRENT|MCL_FUTURE) != 0) 372174298Sobrien plog(XLOG_WARNING, "Couldn't lock process pages in memory using mlockall(): %m"); 373174298Sobrien else 374174298Sobrien locked_ok = 1; 375174298Sobrien#endif /* HAVE_MLOCKALL */ 376174298Sobrien#if defined(HAVE_PLOCK) || defined(HAVE_MLOCKALL) 377174298Sobrien if (locked_ok) 378174298Sobrien plog(XLOG_INFO, "Locked process pages in memory"); 379174298Sobrien#endif /* HAVE_PLOCK || HAVE_MLOCKALL */ 380174298Sobrien 381174298Sobrien#if defined(HAVE_MADVISE) && defined(MADV_PROTECT) 382174298Sobrien madvise(0, 0, MADV_PROTECT); /* may be redundant of the above worked out */ 383174298Sobrien#endif /* defined(HAVE_MADVISE) && defined(MADV_PROTECT) */ 384174298Sobrien} 385174298Sobrien 386174298Sobrien 38738494Sobrienint 38838494Sobrienmain(int argc, char *argv[]) 38938494Sobrien{ 390174298Sobrien char *domdot, *verstr, *vertmp; 39138494Sobrien int ppid = 0; 39238494Sobrien int error; 39342633Sobrien char *progname = NULL; /* "amd" */ 39442633Sobrien char hostname[MAXHOSTNAMELEN + 1] = "localhost"; /* Hostname */ 39538494Sobrien 39638494Sobrien /* 39738494Sobrien * Make sure some built-in assumptions are true before we start 39838494Sobrien */ 39938494Sobrien assert(sizeof(nfscookie) >= sizeof(u_int)); 40038494Sobrien assert(sizeof(int) >= 4); 40138494Sobrien 40238494Sobrien /* 40338494Sobrien * Set processing status. 40438494Sobrien */ 40538494Sobrien amd_state = Start; 40638494Sobrien 40738494Sobrien /* 40838494Sobrien * Determine program name 40938494Sobrien */ 41038494Sobrien if (argv[0]) { 41138494Sobrien progname = strrchr(argv[0], '/'); 41238494Sobrien if (progname && progname[1]) 41338494Sobrien progname++; 41438494Sobrien else 41538494Sobrien progname = argv[0]; 41638494Sobrien } 41738494Sobrien if (!progname) 41838494Sobrien progname = "amd"; 41942633Sobrien am_set_progname(progname); 42038494Sobrien 42138494Sobrien /* 42242633Sobrien * Initialize process id. This is kept 42338494Sobrien * cached since it is used for generating 42438494Sobrien * and using file handles. 42538494Sobrien */ 42642633Sobrien am_set_mypid(); 42738494Sobrien 42838494Sobrien /* 42938494Sobrien * Get local machine name 43038494Sobrien */ 43138494Sobrien if (gethostname(hostname, sizeof(hostname)) < 0) { 43238494Sobrien plog(XLOG_FATAL, "gethostname: %m"); 43338494Sobrien going_down(1); 43438494Sobrien } 43538500Sobrien hostname[sizeof(hostname) - 1] = '\0'; 43638494Sobrien 43738494Sobrien /* 43838494Sobrien * Check it makes sense 43938494Sobrien */ 44038494Sobrien if (!*hostname) { 44138494Sobrien plog(XLOG_FATAL, "host name is not set"); 44238494Sobrien going_down(1); 44338494Sobrien } 44438494Sobrien 44538494Sobrien /* 44638494Sobrien * Initialize global options structure. 44738494Sobrien */ 44838494Sobrien init_global_options(); 44938494Sobrien 45038494Sobrien /* 45142633Sobrien * Partially initialize hostd[]. This 45238494Sobrien * is completed in get_args(). 45338494Sobrien */ 45438494Sobrien if ((domdot = strchr(hostname, '.'))) { 45538494Sobrien /* 45638494Sobrien * Hostname already contains domainname. 45738494Sobrien * Split out hostname and domainname 45838494Sobrien * components 45938494Sobrien */ 46038494Sobrien *domdot++ = '\0'; 46138494Sobrien hostdomain = domdot; 46238494Sobrien } 463174298Sobrien xstrlcpy(hostd, hostname, sizeof(hostd)); 46442633Sobrien am_set_hostname(hostname); 46538494Sobrien 46638494Sobrien /* 467174298Sobrien * Setup signal handlers 46838494Sobrien */ 469174298Sobrien /* SIGINT: trap interrupts for shutdowns */ 470174298Sobrien setup_sighandler(SIGINT, sigterm); 471174298Sobrien /* SIGTERM: trap terminate so we can shutdown cleanly (some chance) */ 472174298Sobrien setup_sighandler(SIGTERM, sigterm); 473174298Sobrien /* SIGHUP: hangups tell us to reload the cache */ 474174298Sobrien setup_sighandler(SIGHUP, sighup); 47538494Sobrien /* 476174298Sobrien * SIGCHLD: trap Death-of-a-child. These allow us to pick up the exit 477174298Sobrien * status of backgrounded mounts. See "sched.c". 47838494Sobrien */ 479174298Sobrien setup_sighandler(SIGCHLD, sigchld); 48038494Sobrien#ifdef HAVE_SIGACTION 481174298Sobrien /* construct global "masked_sigs" used in nfs_start.c */ 48238494Sobrien sigemptyset(&masked_sigs); 483174298Sobrien sigaddset(&masked_sigs, SIGINT); 484174298Sobrien sigaddset(&masked_sigs, SIGTERM); 48538494Sobrien sigaddset(&masked_sigs, SIGHUP); 48638494Sobrien sigaddset(&masked_sigs, SIGCHLD); 487174298Sobrien#endif /* HAVE_SIGACTION */ 48838494Sobrien 48938494Sobrien /* 49038494Sobrien * Fix-up any umask problems. Most systems default 49138494Sobrien * to 002 which is not too convenient for our purposes 49238494Sobrien */ 49338494Sobrien orig_umask = umask(0); 49438494Sobrien 49538494Sobrien /* 49638494Sobrien * Figure out primary network name 49738494Sobrien */ 49838494Sobrien getwire(&PrimNetName, &PrimNetNum); 49938494Sobrien 50038494Sobrien /* 50138494Sobrien * Determine command-line arguments 50238494Sobrien */ 50338494Sobrien get_args(argc, argv); 50438494Sobrien 50538494Sobrien /* 50638494Sobrien * Log version information. 50738494Sobrien */ 508174298Sobrien vertmp = get_version_string(); 509174298Sobrien verstr = strtok(vertmp, "\n"); 51038494Sobrien plog(XLOG_INFO, "AM-UTILS VERSION INFORMATION:"); 51138494Sobrien while (verstr) { 51282797Sobrien plog(XLOG_INFO, "%s", verstr); 51338494Sobrien verstr = strtok(NULL, "\n"); 51438494Sobrien } 515174298Sobrien XFREE(vertmp); 51638494Sobrien 51738494Sobrien /* 518174298Sobrien * Get our own IP address so that we can mount the automounter. We pass 519174298Sobrien * localhost_address which could be used as the default localhost 520174298Sobrien * name/address in amu_get_myaddress(). 52138494Sobrien */ 522174298Sobrien amu_get_myaddress(&myipaddr, gopt.localhost_address); 52351300Sobrien plog(XLOG_INFO, "My ip addr is %s", inet_ntoa(myipaddr)); 52438494Sobrien 52538494Sobrien /* avoid hanging on other NFS servers if started elsewhere */ 52638494Sobrien if (chdir("/") < 0) 52738494Sobrien plog(XLOG_INFO, "cannot chdir to /: %m"); 52838494Sobrien 52938494Sobrien /* 53038494Sobrien * Now check we are root. 53138494Sobrien */ 53238494Sobrien if (geteuid() != 0) { 53351300Sobrien plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %ld)", (long) geteuid()); 53438494Sobrien going_down(1); 53538494Sobrien } 53638494Sobrien 53738494Sobrien#ifdef HAVE_MAP_NIS 53838494Sobrien /* 53938494Sobrien * If the domain was specified then bind it here 54038494Sobrien * to circumvent any default bindings that may 54138494Sobrien * be done in the C library. 54238494Sobrien */ 54338494Sobrien if (gopt.nis_domain && yp_bind(gopt.nis_domain)) { 54438494Sobrien plog(XLOG_FATAL, "Can't bind to NIS domain \"%s\"", gopt.nis_domain); 54538494Sobrien going_down(1); 54638494Sobrien } 54738494Sobrien#endif /* HAVE_MAP_NIS */ 54838494Sobrien 549174298Sobrien if (!amuDebug(D_DAEMON)) 55038494Sobrien ppid = daemon_mode(); 55138494Sobrien 552174298Sobrien /* 553174298Sobrien * Lock process text and data segment in memory. 554174298Sobrien */ 555174298Sobrien if (gopt.flags & CFM_PROCESS_LOCK) { 556174298Sobrien do_memory_locking(); 557174298Sobrien } 55838494Sobrien 559174298Sobrien do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval; 56038494Sobrien 56138494Sobrien /* 56238494Sobrien * Register automounter with system. 56338494Sobrien */ 56438494Sobrien error = mount_automounter(ppid); 56538494Sobrien if (error && ppid) 56642633Sobrien kill(ppid, SIGALRM); 567174298Sobrien 568174298Sobrien#ifdef HAVE_FS_AUTOFS 569174298Sobrien /* 570174298Sobrien * XXX this should be part of going_down(), but I can't move it there 571174298Sobrien * because it would be calling non-library code from the library... ugh 572174298Sobrien */ 573174298Sobrien if (amd_use_autofs) 574174298Sobrien destroy_autofs_service(); 575174298Sobrien#endif /* HAVE_FS_AUTOFS */ 576174298Sobrien 57738494Sobrien going_down(error); 57838494Sobrien 57938494Sobrien abort(); 58038494Sobrien return 1; /* should never get here */ 58138494Sobrien} 582