1*8bae5d40Schristos /* $NetBSD: amd.c,v 1.1.1.3 2015/01/17 16:34:15 christos Exp $ */
2a53f50b9Schristos
3a53f50b9Schristos /*
4*8bae5d40Schristos * Copyright (c) 1997-2014 Erez Zadok
5a53f50b9Schristos * Copyright (c) 1989 Jan-Simon Pendry
6a53f50b9Schristos * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
7a53f50b9Schristos * Copyright (c) 1989 The Regents of the University of California.
8a53f50b9Schristos * All rights reserved.
9a53f50b9Schristos *
10a53f50b9Schristos * This code is derived from software contributed to Berkeley by
11a53f50b9Schristos * Jan-Simon Pendry at Imperial College, London.
12a53f50b9Schristos *
13a53f50b9Schristos * Redistribution and use in source and binary forms, with or without
14a53f50b9Schristos * modification, are permitted provided that the following conditions
15a53f50b9Schristos * are met:
16a53f50b9Schristos * 1. Redistributions of source code must retain the above copyright
17a53f50b9Schristos * notice, this list of conditions and the following disclaimer.
18a53f50b9Schristos * 2. Redistributions in binary form must reproduce the above copyright
19a53f50b9Schristos * notice, this list of conditions and the following disclaimer in the
20a53f50b9Schristos * documentation and/or other materials provided with the distribution.
21*8bae5d40Schristos * 3. Neither the name of the University nor the names of its contributors
22a53f50b9Schristos * may be used to endorse or promote products derived from this software
23a53f50b9Schristos * without specific prior written permission.
24a53f50b9Schristos *
25a53f50b9Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26a53f50b9Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27a53f50b9Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28a53f50b9Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29a53f50b9Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30a53f50b9Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31a53f50b9Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32a53f50b9Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33a53f50b9Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34a53f50b9Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35a53f50b9Schristos * SUCH DAMAGE.
36a53f50b9Schristos *
37a53f50b9Schristos *
38a53f50b9Schristos * File: am-utils/amd/amd.c
39a53f50b9Schristos *
40a53f50b9Schristos */
41a53f50b9Schristos
42a53f50b9Schristos /*
43a53f50b9Schristos * Automounter
44a53f50b9Schristos */
45a53f50b9Schristos
46a53f50b9Schristos #ifdef HAVE_CONFIG_H
47a53f50b9Schristos # include <config.h>
48a53f50b9Schristos #endif /* HAVE_CONFIG_H */
49a53f50b9Schristos #include <am_defs.h>
50a53f50b9Schristos #include <amd.h>
51a53f50b9Schristos
52a53f50b9Schristos struct amu_global_options gopt; /* where global options are stored */
53a53f50b9Schristos
54a53f50b9Schristos char pid_fsname[SIZEOF_PID_FSNAME]; /* "kiska.southseas.nz:(pid%d)" */
55a53f50b9Schristos char *hostdomain = "unknown.domain";
56a53f50b9Schristos #define SIZEOF_HOSTD (2 * MAXHOSTNAMELEN + 1) /* Host+domain */
57a53f50b9Schristos char hostd[SIZEOF_HOSTD]; /* Host+domain */
58a53f50b9Schristos char *endian = ARCH_ENDIAN; /* Big or Little endian */
59a53f50b9Schristos char *cpu = HOST_CPU; /* CPU type */
60a53f50b9Schristos char *PrimNetName; /* name of primary network */
61a53f50b9Schristos char *PrimNetNum; /* number of primary network */
62a53f50b9Schristos
63a53f50b9Schristos int immediate_abort; /* Should close-down unmounts be retried */
64a53f50b9Schristos int orig_umask = 022;
65a53f50b9Schristos int select_intr_valid;
66a53f50b9Schristos
67a53f50b9Schristos jmp_buf select_intr;
68a53f50b9Schristos struct amd_stats amd_stats; /* Server statistics */
69a53f50b9Schristos struct in_addr myipaddr; /* (An) IP address of this host */
70a53f50b9Schristos time_t do_mapc_reload = 0; /* mapc_reload() call required? */
71a53f50b9Schristos
72a53f50b9Schristos #ifdef HAVE_FS_AUTOFS
73a53f50b9Schristos int amd_use_autofs = 0;
74a53f50b9Schristos #endif /* HAVE_FS_AUTOFS */
75a53f50b9Schristos
76a53f50b9Schristos #ifdef HAVE_SIGACTION
77a53f50b9Schristos sigset_t masked_sigs;
78a53f50b9Schristos #endif /* HAVE_SIGACTION */
79a53f50b9Schristos
80a53f50b9Schristos
81a53f50b9Schristos /*
82a53f50b9Schristos * Signal handler:
83a53f50b9Schristos * SIGINT - tells amd to do a full shutdown, including unmounting all
84a53f50b9Schristos * filesystem.
85a53f50b9Schristos * SIGTERM - tells amd to shutdown now. Just unmounts the automount nodes.
86a53f50b9Schristos */
87a53f50b9Schristos static RETSIGTYPE
sigterm(int sig)88a53f50b9Schristos sigterm(int sig)
89a53f50b9Schristos {
90a53f50b9Schristos #ifdef REINSTALL_SIGNAL_HANDLER
91a53f50b9Schristos signal(sig, sigterm);
92a53f50b9Schristos #endif /* REINSTALL_SIGNAL_HANDLER */
93a53f50b9Schristos
94a53f50b9Schristos switch (sig) {
95a53f50b9Schristos case SIGINT:
96a53f50b9Schristos immediate_abort = 15;
97a53f50b9Schristos break;
98a53f50b9Schristos
99a53f50b9Schristos case SIGTERM:
100a53f50b9Schristos immediate_abort = -1;
101a53f50b9Schristos /* fall through... */
102a53f50b9Schristos
103a53f50b9Schristos default:
104a53f50b9Schristos plog(XLOG_WARNING, "WARNING: automounter going down on signal %d", sig);
105a53f50b9Schristos break;
106a53f50b9Schristos }
107a53f50b9Schristos if (select_intr_valid)
108a53f50b9Schristos longjmp(select_intr, sig);
109a53f50b9Schristos }
110a53f50b9Schristos
111a53f50b9Schristos
112a53f50b9Schristos /*
113a53f50b9Schristos * Hook for cache reload.
114a53f50b9Schristos * When a SIGHUP arrives it schedules a call to mapc_reload
115a53f50b9Schristos */
116a53f50b9Schristos static RETSIGTYPE
sighup(int sig)117a53f50b9Schristos sighup(int sig)
118a53f50b9Schristos {
119a53f50b9Schristos #ifdef REINSTALL_SIGNAL_HANDLER
120a53f50b9Schristos signal(sig, sighup);
121a53f50b9Schristos #endif /* REINSTALL_SIGNAL_HANDLER */
122a53f50b9Schristos
123a53f50b9Schristos if (sig != SIGHUP)
124a53f50b9Schristos dlog("spurious call to sighup");
125a53f50b9Schristos /*
126a53f50b9Schristos * Force a reload by zero'ing the timer
127a53f50b9Schristos */
128a53f50b9Schristos if (amd_state == Run)
129a53f50b9Schristos do_mapc_reload = 0;
130a53f50b9Schristos }
131a53f50b9Schristos
132a53f50b9Schristos
133a53f50b9Schristos static RETSIGTYPE
parent_exit(int sig)134a53f50b9Schristos parent_exit(int sig)
135a53f50b9Schristos {
136a53f50b9Schristos /*
137a53f50b9Schristos * This signal handler is called during Amd initialization. The parent
138a53f50b9Schristos * forks a child to do all the hard automounting work, and waits for a
139a53f50b9Schristos * SIGQUIT signal from the child. When the parent gets the signal it's
140a53f50b9Schristos * supposed to call this handler and exit(3), thus completing the
141a53f50b9Schristos * daemonizing process. Alas, on some systems, especially Linux 2.4/2.6
142a53f50b9Schristos * with Glibc, exit(3) doesn't always terminate the parent process.
143a53f50b9Schristos * Worse, the parent process now refuses to accept any more SIGQUIT
144a53f50b9Schristos * signals -- they are blocked. What's really annoying is that this
145a53f50b9Schristos * doesn't happen all the time, suggesting a race condition somewhere.
146a53f50b9Schristos * (This happens even if I change the logic to use another signal.) I
147a53f50b9Schristos * traced this to something which exit(3) does in addition to exiting the
148a53f50b9Schristos * process, probably some atexit() stuff or other side-effects related to
149a53f50b9Schristos * signal handling. Either way, since at this stage the parent process
150a53f50b9Schristos * just needs to terminate, I'm simply calling _exit(2). Note also that
151a53f50b9Schristos * the OpenGroup doesn't list exit(3) as a recommended "Base Interface"
152a53f50b9Schristos * but they do list _exit(2) as one. This fix seems to work reliably all
153a53f50b9Schristos * the time. -Erez (2/27/2005)
154a53f50b9Schristos */
155a53f50b9Schristos _exit(0);
156a53f50b9Schristos }
157a53f50b9Schristos
158a53f50b9Schristos
159a53f50b9Schristos static int
daemon_mode(void)160a53f50b9Schristos daemon_mode(void)
161a53f50b9Schristos {
162a53f50b9Schristos int bgpid;
163a53f50b9Schristos
164a53f50b9Schristos #ifdef HAVE_SIGACTION
165a53f50b9Schristos struct sigaction sa, osa;
166a53f50b9Schristos
167a53f50b9Schristos memset(&sa, 0, sizeof(sa));
168a53f50b9Schristos sa.sa_handler = parent_exit;
169a53f50b9Schristos sa.sa_flags = 0;
170a53f50b9Schristos sigemptyset(&(sa.sa_mask));
171a53f50b9Schristos sigaddset(&(sa.sa_mask), SIGQUIT);
172a53f50b9Schristos sigaction(SIGQUIT, &sa, &osa);
173a53f50b9Schristos #else /* not HAVE_SIGACTION */
174a53f50b9Schristos signal(SIGQUIT, parent_exit);
175a53f50b9Schristos #endif /* not HAVE_SIGACTION */
176a53f50b9Schristos
177a53f50b9Schristos bgpid = background();
178a53f50b9Schristos
179a53f50b9Schristos if (bgpid != 0) {
180a53f50b9Schristos /*
181a53f50b9Schristos * Now wait for the automount points to
182a53f50b9Schristos * complete.
183a53f50b9Schristos */
184a53f50b9Schristos for (;;)
185a53f50b9Schristos pause();
186a53f50b9Schristos /* should never reach here */
187a53f50b9Schristos }
188a53f50b9Schristos #ifdef HAVE_SIGACTION
189a53f50b9Schristos sigaction(SIGQUIT, &osa, NULL);
190a53f50b9Schristos #else /* not HAVE_SIGACTION */
191a53f50b9Schristos signal(SIGQUIT, SIG_DFL);
192a53f50b9Schristos #endif /* not HAVE_SIGACTION */
193a53f50b9Schristos
194a53f50b9Schristos /*
195a53f50b9Schristos * Record our pid to make it easier to kill the correct amd.
196a53f50b9Schristos */
197a53f50b9Schristos if (gopt.flags & CFM_PRINT_PID) {
198a53f50b9Schristos if (STREQ(gopt.pid_file, "/dev/stdout")) {
199a53f50b9Schristos printf("%ld\n", (long) am_mypid);
200a53f50b9Schristos /* flush stdout, just in case */
201a53f50b9Schristos fflush(stdout);
202a53f50b9Schristos } else {
203a53f50b9Schristos FILE *f;
204a53f50b9Schristos mode_t prev_umask = umask(0022); /* set secure temporary umask */
205a53f50b9Schristos
206a53f50b9Schristos f = fopen(gopt.pid_file, "w");
207a53f50b9Schristos if (f) {
208a53f50b9Schristos fprintf(f, "%ld\n", (long) am_mypid);
209a53f50b9Schristos (void) fclose(f);
210a53f50b9Schristos } else {
211a53f50b9Schristos fprintf(stderr, "cannot open %s (errno=%d)\n", gopt.pid_file, errno);
212a53f50b9Schristos }
213a53f50b9Schristos umask(prev_umask); /* restore umask */
214a53f50b9Schristos }
215a53f50b9Schristos }
216a53f50b9Schristos
217a53f50b9Schristos /*
218a53f50b9Schristos * Pretend we are in the foreground again
219a53f50b9Schristos */
220a53f50b9Schristos foreground = 1;
221a53f50b9Schristos
222a53f50b9Schristos /*
223a53f50b9Schristos * Dissociate from the controlling terminal
224a53f50b9Schristos */
225a53f50b9Schristos amu_release_controlling_tty();
226a53f50b9Schristos
227a53f50b9Schristos return getppid();
228a53f50b9Schristos }
229a53f50b9Schristos
230a53f50b9Schristos
231a53f50b9Schristos /*
232a53f50b9Schristos * Initialize global options structure.
233a53f50b9Schristos */
234a53f50b9Schristos static void
init_global_options(void)235a53f50b9Schristos init_global_options(void)
236a53f50b9Schristos {
237a53f50b9Schristos #if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
238a53f50b9Schristos static struct utsname un;
239a53f50b9Schristos #endif /* defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) */
240a53f50b9Schristos int i;
241a53f50b9Schristos
242a53f50b9Schristos memset(&gopt, 0, sizeof(struct amu_global_options));
243a53f50b9Schristos
244a53f50b9Schristos /* name of current architecture */
245a53f50b9Schristos gopt.arch = HOST_ARCH;
246a53f50b9Schristos
247a53f50b9Schristos /* automounter temp dir */
248a53f50b9Schristos gopt.auto_dir = "/a";
249a53f50b9Schristos
250a53f50b9Schristos /* toplevel attribute cache timeout */
251a53f50b9Schristos gopt.auto_attrcache = 0;
252a53f50b9Schristos
253a53f50b9Schristos /* cluster name */
254a53f50b9Schristos gopt.cluster = NULL;
255a53f50b9Schristos
256a53f50b9Schristos /* executable map timeout */
257a53f50b9Schristos gopt.exec_map_timeout = AMFS_EXEC_MAP_TIMEOUT;
258a53f50b9Schristos
259a53f50b9Schristos /*
260a53f50b9Schristos * kernel architecture: this you must get from uname() if possible.
261a53f50b9Schristos */
262a53f50b9Schristos #if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
263a53f50b9Schristos if (uname(&un) >= 0)
264a53f50b9Schristos gopt.karch = un.machine;
265a53f50b9Schristos else
266a53f50b9Schristos #endif /* defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) */
267a53f50b9Schristos gopt.karch = HOST_ARCH;
268a53f50b9Schristos
269a53f50b9Schristos /* amd log file */
270a53f50b9Schristos gopt.logfile = NULL;
271a53f50b9Schristos
272a53f50b9Schristos /* operating system name */
273a53f50b9Schristos gopt.op_sys = HOST_OS_NAME;
274a53f50b9Schristos
275a53f50b9Schristos /* OS version */
276a53f50b9Schristos gopt.op_sys_ver = HOST_OS_VERSION;
277a53f50b9Schristos
278a53f50b9Schristos /* full OS name and version */
279a53f50b9Schristos gopt.op_sys_full = HOST_OS;
280a53f50b9Schristos
281a53f50b9Schristos /* OS version */
282a53f50b9Schristos gopt.op_sys_vendor = HOST_VENDOR;
283a53f50b9Schristos
284a53f50b9Schristos /* pid file */
285a53f50b9Schristos gopt.pid_file = "/dev/stdout";
286a53f50b9Schristos
287a53f50b9Schristos /* local domain */
288a53f50b9Schristos gopt.sub_domain = NULL;
289a53f50b9Schristos
290a53f50b9Schristos /* reset NFS (and toplvl) retransmit counter and retry interval */
291a53f50b9Schristos for (i=0; i<AMU_TYPE_MAX; ++i) {
292a53f50b9Schristos gopt.amfs_auto_retrans[i] = -1; /* -1 means "never set before" */
293a53f50b9Schristos gopt.amfs_auto_timeo[i] = -1; /* -1 means "never set before" */
294a53f50b9Schristos }
295a53f50b9Schristos
296a53f50b9Schristos /* cache duration */
297a53f50b9Schristos gopt.am_timeo = AM_TTL;
298a53f50b9Schristos
299a53f50b9Schristos /* dismount interval */
300a53f50b9Schristos gopt.am_timeo_w = AM_TTL_W;
301a53f50b9Schristos
302a53f50b9Schristos /* map reload intervl */
303a53f50b9Schristos gopt.map_reload_interval = ONE_HOUR;
304a53f50b9Schristos
305a53f50b9Schristos /*
306a53f50b9Schristos * various CFM_* flags that are on by default.
307a53f50b9Schristos */
308a53f50b9Schristos gopt.flags = CFM_DEFAULT_FLAGS;
309a53f50b9Schristos
310a53f50b9Schristos #ifdef HAVE_MAP_HESIOD
311a53f50b9Schristos /* Hesiod rhs zone */
312a53f50b9Schristos gopt.hesiod_base = "automount";
313a53f50b9Schristos #endif /* HAVE_MAP_HESIOD */
314a53f50b9Schristos
315a53f50b9Schristos #ifdef HAVE_MAP_LDAP
316a53f50b9Schristos /* LDAP base */
317a53f50b9Schristos gopt.ldap_base = NULL;
318a53f50b9Schristos
319a53f50b9Schristos /* LDAP host ports */
320a53f50b9Schristos gopt.ldap_hostports = NULL;
321a53f50b9Schristos
322a53f50b9Schristos /* LDAP cache */
323a53f50b9Schristos gopt.ldap_cache_seconds = 0;
324a53f50b9Schristos gopt.ldap_cache_maxmem = 131072;
325a53f50b9Schristos
326a53f50b9Schristos /* LDAP protocol version */
327a53f50b9Schristos gopt.ldap_proto_version = 2;
328a53f50b9Schristos #endif /* HAVE_MAP_LDAP */
329a53f50b9Schristos
330a53f50b9Schristos #ifdef HAVE_MAP_NIS
331a53f50b9Schristos /* YP domain name */
332a53f50b9Schristos gopt.nis_domain = NULL;
333a53f50b9Schristos #endif /* HAVE_MAP_NIS */
334a53f50b9Schristos }
335a53f50b9Schristos
336a53f50b9Schristos
337a53f50b9Schristos /*
338a53f50b9Schristos * Lock process text and data segment in memory (after forking the daemon)
339a53f50b9Schristos */
340a53f50b9Schristos static void
do_memory_locking(void)341a53f50b9Schristos do_memory_locking(void)
342a53f50b9Schristos {
343a53f50b9Schristos #if defined(HAVE_PLOCK) || defined(HAVE_MLOCKALL)
344a53f50b9Schristos int locked_ok = 0;
345a53f50b9Schristos #else /* not HAVE_PLOCK and not HAVE_MLOCKALL */
346a53f50b9Schristos plog(XLOG_WARNING, "Process memory locking not supported by the OS");
347a53f50b9Schristos #endif /* not HAVE_PLOCK and not HAVE_MLOCKALL */
348a53f50b9Schristos #ifdef HAVE_PLOCK
349a53f50b9Schristos # ifdef _AIX
350a53f50b9Schristos /*
351a53f50b9Schristos * On AIX you must lower the stack size using ulimit() before calling
352a53f50b9Schristos * plock. Otherwise plock will reserve a lot of memory space based on
353a53f50b9Schristos * your maximum stack size limit. Since it is not easily possible to
354a53f50b9Schristos * tell what should the limit be, I print a warning before calling
355a53f50b9Schristos * plock(). See the manual pages for ulimit(1,3,4) on your AIX system.
356a53f50b9Schristos */
357a53f50b9Schristos plog(XLOG_WARNING, "AIX: may need to lower stack size using ulimit(3) before calling plock");
358a53f50b9Schristos # endif /* _AIX */
359a53f50b9Schristos if (!locked_ok && plock(PROCLOCK) != 0)
360a53f50b9Schristos plog(XLOG_WARNING, "Couldn't lock process pages in memory using plock(): %m");
361a53f50b9Schristos else
362a53f50b9Schristos locked_ok = 1;
363a53f50b9Schristos #endif /* HAVE_PLOCK */
364a53f50b9Schristos #ifdef HAVE_MLOCKALL
365a53f50b9Schristos if (!locked_ok && mlockall(MCL_CURRENT|MCL_FUTURE) != 0)
366a53f50b9Schristos plog(XLOG_WARNING, "Couldn't lock process pages in memory using mlockall(): %m");
367a53f50b9Schristos else
368a53f50b9Schristos locked_ok = 1;
369a53f50b9Schristos #endif /* HAVE_MLOCKALL */
370a53f50b9Schristos #if defined(HAVE_PLOCK) || defined(HAVE_MLOCKALL)
371a53f50b9Schristos if (locked_ok)
372a53f50b9Schristos plog(XLOG_INFO, "Locked process pages in memory");
373a53f50b9Schristos #endif /* HAVE_PLOCK || HAVE_MLOCKALL */
374a53f50b9Schristos
375a53f50b9Schristos #if defined(HAVE_MADVISE) && defined(MADV_PROTECT)
376a53f50b9Schristos madvise(NULL, 0, MADV_PROTECT); /* may be redundant of the above worked out */
377a53f50b9Schristos #endif /* defined(HAVE_MADVISE) && defined(MADV_PROTECT) */
378a53f50b9Schristos }
379a53f50b9Schristos
380a53f50b9Schristos
381a53f50b9Schristos int
main(int argc,char * argv[])382a53f50b9Schristos main(int argc, char *argv[])
383a53f50b9Schristos {
384a53f50b9Schristos char *domdot, *verstr, *vertmp;
385a53f50b9Schristos int ppid = 0;
386a53f50b9Schristos int error;
387a53f50b9Schristos char *progname = NULL; /* "amd" */
388a53f50b9Schristos char hostname[MAXHOSTNAMELEN + 1] = "localhost"; /* Hostname */
389a53f50b9Schristos
390a53f50b9Schristos /*
391a53f50b9Schristos * Make sure some built-in assumptions are true before we start
392a53f50b9Schristos */
393a53f50b9Schristos assert(sizeof(nfscookie) >= sizeof(u_int));
394a53f50b9Schristos assert(sizeof(int) >= 4);
395a53f50b9Schristos
396a53f50b9Schristos /*
397a53f50b9Schristos * Set processing status.
398a53f50b9Schristos */
399a53f50b9Schristos amd_state = Start;
400a53f50b9Schristos
401a53f50b9Schristos /*
402a53f50b9Schristos * Determine program name
403a53f50b9Schristos */
404a53f50b9Schristos if (argv[0]) {
405a53f50b9Schristos progname = strrchr(argv[0], '/');
406a53f50b9Schristos if (progname && progname[1])
407a53f50b9Schristos progname++;
408a53f50b9Schristos else
409a53f50b9Schristos progname = argv[0];
410a53f50b9Schristos }
411a53f50b9Schristos if (!progname)
412a53f50b9Schristos progname = "amd";
413a53f50b9Schristos am_set_progname(progname);
414a53f50b9Schristos
415a53f50b9Schristos /*
416a53f50b9Schristos * Initialize process id. This is kept
417a53f50b9Schristos * cached since it is used for generating
418a53f50b9Schristos * and using file handles.
419a53f50b9Schristos */
420a53f50b9Schristos am_set_mypid();
421a53f50b9Schristos
422a53f50b9Schristos /*
423a53f50b9Schristos * Get local machine name
424a53f50b9Schristos */
425a53f50b9Schristos if (gethostname(hostname, sizeof(hostname)) < 0) {
426a53f50b9Schristos plog(XLOG_FATAL, "gethostname: %m");
427a53f50b9Schristos going_down(1);
428*8bae5d40Schristos return 1;
429a53f50b9Schristos }
430a53f50b9Schristos hostname[sizeof(hostname) - 1] = '\0';
431a53f50b9Schristos
432a53f50b9Schristos /*
433a53f50b9Schristos * Check it makes sense
434a53f50b9Schristos */
435a53f50b9Schristos if (!*hostname) {
436a53f50b9Schristos plog(XLOG_FATAL, "host name is not set");
437a53f50b9Schristos going_down(1);
438*8bae5d40Schristos return 1;
439a53f50b9Schristos }
440a53f50b9Schristos
441a53f50b9Schristos /*
442a53f50b9Schristos * Initialize global options structure.
443a53f50b9Schristos */
444a53f50b9Schristos init_global_options();
445a53f50b9Schristos
446a53f50b9Schristos /*
447a53f50b9Schristos * Partially initialize hostd[]. This
448a53f50b9Schristos * is completed in get_args().
449a53f50b9Schristos */
450a53f50b9Schristos if ((domdot = strchr(hostname, '.'))) {
451a53f50b9Schristos /*
452a53f50b9Schristos * Hostname already contains domainname.
453a53f50b9Schristos * Split out hostname and domainname
454a53f50b9Schristos * components
455a53f50b9Schristos */
456a53f50b9Schristos *domdot++ = '\0';
457a53f50b9Schristos hostdomain = domdot;
458a53f50b9Schristos }
459a53f50b9Schristos xstrlcpy(hostd, hostname, sizeof(hostd));
460a53f50b9Schristos am_set_hostname(hostname);
461a53f50b9Schristos
462a53f50b9Schristos /*
463a53f50b9Schristos * Setup signal handlers
464a53f50b9Schristos */
465a53f50b9Schristos /* SIGINT: trap interrupts for shutdowns */
466a53f50b9Schristos setup_sighandler(SIGINT, sigterm);
467a53f50b9Schristos /* SIGTERM: trap terminate so we can shutdown cleanly (some chance) */
468a53f50b9Schristos setup_sighandler(SIGTERM, sigterm);
469a53f50b9Schristos /* SIGHUP: hangups tell us to reload the cache */
470a53f50b9Schristos setup_sighandler(SIGHUP, sighup);
471a53f50b9Schristos /*
472a53f50b9Schristos * SIGCHLD: trap Death-of-a-child. These allow us to pick up the exit
473a53f50b9Schristos * status of backgrounded mounts. See "sched.c".
474a53f50b9Schristos */
475a53f50b9Schristos setup_sighandler(SIGCHLD, sigchld);
476a53f50b9Schristos #ifdef HAVE_SIGACTION
477a53f50b9Schristos /* construct global "masked_sigs" used in nfs_start.c */
478a53f50b9Schristos sigemptyset(&masked_sigs);
479a53f50b9Schristos sigaddset(&masked_sigs, SIGINT);
480a53f50b9Schristos sigaddset(&masked_sigs, SIGTERM);
481a53f50b9Schristos sigaddset(&masked_sigs, SIGHUP);
482a53f50b9Schristos sigaddset(&masked_sigs, SIGCHLD);
483a53f50b9Schristos #endif /* HAVE_SIGACTION */
484a53f50b9Schristos
485a53f50b9Schristos /*
486a53f50b9Schristos * Fix-up any umask problems. Most systems default
487a53f50b9Schristos * to 002 which is not too convenient for our purposes
488a53f50b9Schristos */
489a53f50b9Schristos orig_umask = umask(0);
490a53f50b9Schristos
491a53f50b9Schristos /*
492a53f50b9Schristos * Figure out primary network name
493a53f50b9Schristos */
494a53f50b9Schristos getwire(&PrimNetName, &PrimNetNum);
495a53f50b9Schristos
496a53f50b9Schristos /*
497a53f50b9Schristos * Determine command-line arguments.
498a53f50b9Schristos * (Also initialize amd.conf parameters, maps, and more.)
499a53f50b9Schristos */
500a53f50b9Schristos get_args(argc, argv);
501a53f50b9Schristos
502a53f50b9Schristos /*
503a53f50b9Schristos * Log version information.
504a53f50b9Schristos */
505a53f50b9Schristos vertmp = get_version_string();
506a53f50b9Schristos verstr = strtok(vertmp, "\n");
507a53f50b9Schristos plog(XLOG_INFO, "AM-UTILS VERSION INFORMATION:");
508a53f50b9Schristos while (verstr) {
509a53f50b9Schristos plog(XLOG_INFO, "%s", verstr);
510a53f50b9Schristos verstr = strtok(NULL, "\n");
511a53f50b9Schristos }
512a53f50b9Schristos XFREE(vertmp);
513a53f50b9Schristos
514a53f50b9Schristos /*
515a53f50b9Schristos * Get our own IP address so that we can mount the automounter. We pass
516a53f50b9Schristos * localhost_address which could be used as the default localhost
517a53f50b9Schristos * name/address in amu_get_myaddress().
518a53f50b9Schristos */
519a53f50b9Schristos amu_get_myaddress(&myipaddr, gopt.localhost_address);
520a53f50b9Schristos plog(XLOG_INFO, "My ip addr is %s", inet_ntoa(myipaddr));
521a53f50b9Schristos
522a53f50b9Schristos /* avoid hanging on other NFS servers if started elsewhere */
523a53f50b9Schristos if (chdir("/") < 0)
524a53f50b9Schristos plog(XLOG_INFO, "cannot chdir to /: %m");
525a53f50b9Schristos
526a53f50b9Schristos /*
527a53f50b9Schristos * Now check we are root.
528a53f50b9Schristos */
529a53f50b9Schristos if (geteuid() != 0) {
530a53f50b9Schristos plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %ld)", (long) geteuid());
531a53f50b9Schristos going_down(1);
532*8bae5d40Schristos return 1;
533a53f50b9Schristos }
534a53f50b9Schristos
535a53f50b9Schristos #ifdef HAVE_MAP_NIS
536a53f50b9Schristos /*
537a53f50b9Schristos * If the domain was specified then bind it here
538a53f50b9Schristos * to circumvent any default bindings that may
539a53f50b9Schristos * be done in the C library.
540a53f50b9Schristos */
541a53f50b9Schristos if (gopt.nis_domain && yp_bind(gopt.nis_domain)) {
542a53f50b9Schristos plog(XLOG_FATAL, "Can't bind to NIS domain \"%s\"", gopt.nis_domain);
543a53f50b9Schristos going_down(1);
544*8bae5d40Schristos return 1;
545a53f50b9Schristos }
546a53f50b9Schristos #endif /* HAVE_MAP_NIS */
547a53f50b9Schristos
548a53f50b9Schristos if (amuDebug(D_DAEMON))
549a53f50b9Schristos ppid = daemon_mode();
550a53f50b9Schristos
551a53f50b9Schristos /*
552a53f50b9Schristos * Lock process text and data segment in memory.
553a53f50b9Schristos */
554a53f50b9Schristos if (gopt.flags & CFM_PROCESS_LOCK) {
555a53f50b9Schristos do_memory_locking();
556a53f50b9Schristos }
557a53f50b9Schristos
558a53f50b9Schristos do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval;
559a53f50b9Schristos
560a53f50b9Schristos /*
561a53f50b9Schristos * Register automounter with system.
562a53f50b9Schristos */
563a53f50b9Schristos error = mount_automounter(ppid);
564a53f50b9Schristos if (error && ppid)
565a53f50b9Schristos kill(ppid, SIGALRM);
566a53f50b9Schristos
567a53f50b9Schristos #ifdef HAVE_FS_AUTOFS
568a53f50b9Schristos /*
569a53f50b9Schristos * XXX this should be part of going_down(), but I can't move it there
570a53f50b9Schristos * because it would be calling non-library code from the library... ugh
571a53f50b9Schristos */
572a53f50b9Schristos if (amd_use_autofs)
573a53f50b9Schristos destroy_autofs_service();
574a53f50b9Schristos #endif /* HAVE_FS_AUTOFS */
575a53f50b9Schristos
576a53f50b9Schristos going_down(error);
577a53f50b9Schristos
578a53f50b9Schristos abort();
579a53f50b9Schristos return 1; /* should never get here */
580a53f50b9Schristos }
581