xref: /freebsd/usr.sbin/nfsd/nfsd.c (revision 6f9c8e5b074419423648ffb89b83fd2f257e90b7)
1 /*
2  * Copyright (c) 1989, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rick Macklem at The University of Guelph.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #ifndef lint
34 static const char copyright[] =
35 "@(#) Copyright (c) 1989, 1993, 1994\n\
36 	The Regents of the University of California.  All rights reserved.\n";
37 #endif /* not lint */
38 
39 #ifndef lint
40 #if 0
41 static char sccsid[] = "@(#)nfsd.c	8.9 (Berkeley) 3/29/95";
42 #endif
43 static const char rcsid[] =
44   "$FreeBSD$";
45 #endif /* not lint */
46 
47 #include <sys/param.h>
48 #include <sys/syslog.h>
49 #include <sys/wait.h>
50 #include <sys/mount.h>
51 #include <sys/fcntl.h>
52 #include <sys/linker.h>
53 #include <sys/module.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <sys/ucred.h>
57 
58 #include <rpc/rpc.h>
59 #include <rpc/pmap_clnt.h>
60 #include <rpcsvc/nfs_prot.h>
61 
62 #include <netdb.h>
63 #include <arpa/inet.h>
64 #include <nfsserver/nfs.h>
65 #include <nfs/nfssvc.h>
66 
67 #include <err.h>
68 #include <errno.h>
69 #include <signal.h>
70 #include <stdio.h>
71 #include <stdlib.h>
72 #include <string.h>
73 #include <unistd.h>
74 #include <netdb.h>
75 
76 /* Global defs */
77 #ifdef DEBUG
78 #define	syslog(e, s...)	fprintf(stderr,s)
79 int	debug = 1;
80 #else
81 int	debug = 0;
82 #endif
83 
84 #define	NFSD_STABLERESTART	"/var/db/nfs-stablerestart"
85 #define	NFSD_STABLEBACKUP	"/var/db/nfs-stablerestart.bak"
86 #define	MAXNFSDCNT	256
87 #define	DEFNFSDCNT	 4
88 pid_t	children[MAXNFSDCNT];	/* PIDs of children */
89 int	nfsdcnt;		/* number of children */
90 int	new_syscall;
91 int	run_v4server = 1;	/* Force running of nfsv4 server */
92 int	nfssvc_nfsd;		/* Set to correct NFSSVC_xxx flag */
93 int	stablefd = -1;		/* Fd for the stable restart file */
94 int	backupfd;		/* Fd for the backup stable restart file */
95 
96 void	cleanup(int);
97 void	child_cleanup(int);
98 void	killchildren(void);
99 void	nfsd_exit(int);
100 void	nonfs(int);
101 void	reapchild(int);
102 int	setbindhost(struct addrinfo **ia, const char *bindhost,
103 	    struct addrinfo hints);
104 void	start_server(int);
105 void	unregistration(void);
106 void	usage(void);
107 void	open_stable(int *, int *);
108 void	copy_stable(int, int);
109 void	backup_stable(int);
110 
111 /*
112  * Nfs server daemon mostly just a user context for nfssvc()
113  *
114  * 1 - do file descriptor and signal cleanup
115  * 2 - fork the nfsd(s)
116  * 3 - create server socket(s)
117  * 4 - register socket with rpcbind
118  *
119  * For connectionless protocols, just pass the socket into the kernel via.
120  * nfssvc().
121  * For connection based sockets, loop doing accepts. When you get a new
122  * socket from accept, pass the msgsock into the kernel via. nfssvc().
123  * The arguments are:
124  *	-r - reregister with rpcbind
125  *	-d - unregister with rpcbind
126  *	-t - support tcp nfs clients
127  *	-u - support udp nfs clients
128  *	-e - forces it to run a server that supports nfsv4
129  * followed by "n" which is the number of nfsds' to fork off
130  */
131 int
132 main(int argc, char **argv)
133 {
134 	struct nfsd_addsock_args addsockargs;
135 	struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
136 	struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
137 	struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
138 	struct sockaddr_in inetpeer;
139 	struct sockaddr_in6 inet6peer;
140 	fd_set ready, sockbits;
141 	fd_set v4bits, v6bits;
142 	int ch, connect_type_cnt, i, maxsock, msgsock;
143 	socklen_t len;
144 	int on = 1, unregister, reregister, sock;
145 	int tcp6sock, ip6flag, tcpflag, tcpsock;
146 	int udpflag, ecode, error, s, srvcnt;
147 	int bindhostc, bindanyflag, rpcbreg, rpcbregcnt;
148 	int nfssvc_addsock;
149 	char **bindhost = NULL;
150 	pid_t pid;
151 
152 	nfsdcnt = DEFNFSDCNT;
153 	unregister = reregister = tcpflag = maxsock = 0;
154 	bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
155 #define	GETOPT	"ah:n:rdtueo"
156 #define	USAGE	"[-ardtueo] [-n num_servers] [-h bindip]"
157 	while ((ch = getopt(argc, argv, GETOPT)) != -1)
158 		switch (ch) {
159 		case 'a':
160 			bindanyflag = 1;
161 			break;
162 		case 'n':
163 			nfsdcnt = atoi(optarg);
164 			if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
165 				warnx("nfsd count %d; reset to %d", nfsdcnt,
166 				    DEFNFSDCNT);
167 				nfsdcnt = DEFNFSDCNT;
168 			}
169 			break;
170 		case 'h':
171 			bindhostc++;
172 			bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
173 			if (bindhost == NULL)
174 				errx(1, "Out of memory");
175 			bindhost[bindhostc-1] = strdup(optarg);
176 			if (bindhost[bindhostc-1] == NULL)
177 				errx(1, "Out of memory");
178 			break;
179 		case 'r':
180 			reregister = 1;
181 			break;
182 		case 'd':
183 			unregister = 1;
184 			break;
185 		case 't':
186 			tcpflag = 1;
187 			break;
188 		case 'u':
189 			udpflag = 1;
190 			break;
191 		case 'e':
192 			/* now a no-op, since this is the default */
193 			break;
194 		case 'o':
195 			run_v4server = 0;
196 			break;
197 		default:
198 		case '?':
199 			usage();
200 		};
201 	if (!tcpflag && !udpflag)
202 		udpflag = 1;
203 	argv += optind;
204 	argc -= optind;
205 
206 	/*
207 	 * XXX
208 	 * Backward compatibility, trailing number is the count of daemons.
209 	 */
210 	if (argc > 1)
211 		usage();
212 	if (argc == 1) {
213 		nfsdcnt = atoi(argv[0]);
214 		if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
215 			warnx("nfsd count %d; reset to %d", nfsdcnt,
216 			    DEFNFSDCNT);
217 			nfsdcnt = DEFNFSDCNT;
218 		}
219 	}
220 
221 	/*
222 	 * Unless the "-o" option was specified, try and run "nfsd".
223 	 * If "-o" was specified, try and run "nfsserver".
224 	 */
225 	if (run_v4server > 0) {
226 		if (modfind("nfsd") < 0) {
227 			/* Not present in kernel, try loading it */
228 			if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
229 				errx(1, "NFS server is not available");
230 		}
231 	} else if (modfind("nfsserver") < 0) {
232 		/* Not present in kernel, try loading it */
233 		if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0)
234 			errx(1, "NFS server is not available");
235 	}
236 
237 	ip6flag = 1;
238 	s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
239 	if (s == -1) {
240 		if (errno != EPROTONOSUPPORT)
241 			err(1, "socket");
242 		ip6flag = 0;
243 	} else if (getnetconfigent("udp6") == NULL ||
244 		getnetconfigent("tcp6") == NULL) {
245 		ip6flag = 0;
246 	}
247 	if (s != -1)
248 		close(s);
249 
250 	if (bindhostc == 0 || bindanyflag) {
251 		bindhostc++;
252 		bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
253 		if (bindhost == NULL)
254 			errx(1, "Out of memory");
255 		bindhost[bindhostc-1] = strdup("*");
256 		if (bindhost[bindhostc-1] == NULL)
257 			errx(1, "Out of memory");
258 	}
259 
260 	if (unregister) {
261 		unregistration();
262 		exit (0);
263 	}
264 	if (reregister) {
265 		if (udpflag) {
266 			memset(&hints, 0, sizeof hints);
267 			hints.ai_flags = AI_PASSIVE;
268 			hints.ai_family = AF_INET;
269 			hints.ai_socktype = SOCK_DGRAM;
270 			hints.ai_protocol = IPPROTO_UDP;
271 			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
272 			if (ecode != 0)
273 				err(1, "getaddrinfo udp: %s", gai_strerror(ecode));
274 			nconf_udp = getnetconfigent("udp");
275 			if (nconf_udp == NULL)
276 				err(1, "getnetconfigent udp failed");
277 			nb_udp.buf = ai_udp->ai_addr;
278 			nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
279 			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp, &nb_udp)) ||
280 			    (!rpcb_set(NFS_PROGRAM, 3, nconf_udp, &nb_udp)))
281 				err(1, "rpcb_set udp failed");
282 			freeaddrinfo(ai_udp);
283 		}
284 		if (udpflag && ip6flag) {
285 			memset(&hints, 0, sizeof hints);
286 			hints.ai_flags = AI_PASSIVE;
287 			hints.ai_family = AF_INET6;
288 			hints.ai_socktype = SOCK_DGRAM;
289 			hints.ai_protocol = IPPROTO_UDP;
290 			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
291 			if (ecode != 0)
292 				err(1, "getaddrinfo udp6: %s", gai_strerror(ecode));
293 			nconf_udp6 = getnetconfigent("udp6");
294 			if (nconf_udp6 == NULL)
295 				err(1, "getnetconfigent udp6 failed");
296 			nb_udp6.buf = ai_udp6->ai_addr;
297 			nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
298 			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp6, &nb_udp6)) ||
299 			    (!rpcb_set(NFS_PROGRAM, 3, nconf_udp6, &nb_udp6)))
300 				err(1, "rpcb_set udp6 failed");
301 			freeaddrinfo(ai_udp6);
302 		}
303 		if (tcpflag) {
304 			memset(&hints, 0, sizeof hints);
305 			hints.ai_flags = AI_PASSIVE;
306 			hints.ai_family = AF_INET;
307 			hints.ai_socktype = SOCK_STREAM;
308 			hints.ai_protocol = IPPROTO_TCP;
309 			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
310 			if (ecode != 0)
311 				err(1, "getaddrinfo tcp: %s", gai_strerror(ecode));
312 			nconf_tcp = getnetconfigent("tcp");
313 			if (nconf_tcp == NULL)
314 				err(1, "getnetconfigent tcp failed");
315 			nb_tcp.buf = ai_tcp->ai_addr;
316 			nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
317 			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp, &nb_tcp)) ||
318 			    (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp, &nb_tcp)))
319 				err(1, "rpcb_set tcp failed");
320 			freeaddrinfo(ai_tcp);
321 		}
322 		if (tcpflag && ip6flag) {
323 			memset(&hints, 0, sizeof hints);
324 			hints.ai_flags = AI_PASSIVE;
325 			hints.ai_family = AF_INET6;
326 			hints.ai_socktype = SOCK_STREAM;
327 			hints.ai_protocol = IPPROTO_TCP;
328 			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
329 			if (ecode != 0)
330 				err(1, "getaddrinfo tcp6: %s", gai_strerror(ecode));
331 			nconf_tcp6 = getnetconfigent("tcp6");
332 			if (nconf_tcp6 == NULL)
333 				err(1, "getnetconfigent tcp6 failed");
334 			nb_tcp6.buf = ai_tcp6->ai_addr;
335 			nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
336 			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp6, &nb_tcp6)) ||
337 			    (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp6, &nb_tcp6)))
338 				err(1, "rpcb_set tcp6 failed");
339 			freeaddrinfo(ai_tcp6);
340 		}
341 		exit (0);
342 	}
343 	if (debug == 0) {
344 		daemon(0, 0);
345 		(void)signal(SIGHUP, SIG_IGN);
346 		(void)signal(SIGINT, SIG_IGN);
347 		/*
348 		 * nfsd sits in the kernel most of the time.  It needs
349 		 * to ignore SIGTERM/SIGQUIT in order to stay alive as long
350 		 * as possible during a shutdown, otherwise loopback
351 		 * mounts will not be able to unmount.
352 		 */
353 		(void)signal(SIGTERM, SIG_IGN);
354 		(void)signal(SIGQUIT, SIG_IGN);
355 	}
356 	(void)signal(SIGSYS, nonfs);
357 	(void)signal(SIGCHLD, reapchild);
358 	(void)signal(SIGUSR2, backup_stable);
359 
360 	openlog("nfsd", LOG_PID, LOG_DAEMON);
361 
362 	/*
363 	 * For V4, we open the stablerestart file and call nfssvc()
364 	 * to get it loaded. This is done before the daemons do the
365 	 * regular nfssvc() call to service NFS requests.
366 	 * (This way the file remains open until the last nfsd is killed
367 	 *  off.)
368 	 * It and the backup copy will be created as empty files
369 	 * the first time this nfsd is started and should never be
370 	 * deleted/replaced if at all possible. It should live on a
371 	 * local, non-volatile storage device that does not do hardware
372 	 * level write-back caching. (See SCSI doc for more information
373 	 * on how to prevent write-back caching on SCSI disks.)
374 	 */
375 	if (run_v4server > 0) {
376 		open_stable(&stablefd, &backupfd);
377 		if (stablefd < 0) {
378 			syslog(LOG_ERR, "Can't open %s\n", NFSD_STABLERESTART);
379 			exit(1);
380 		}
381 		/* This system call will fail for old kernels, but that's ok. */
382 		nfssvc(NFSSVC_BACKUPSTABLE, NULL);
383 		if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) {
384 			syslog(LOG_ERR, "Can't read stable storage file\n");
385 			exit(1);
386 		}
387 		nfssvc_addsock = NFSSVC_NFSDADDSOCK;
388 		nfssvc_nfsd = NFSSVC_NFSDNFSD;
389 		new_syscall = TRUE;
390 	} else {
391 		nfssvc_addsock = NFSSVC_ADDSOCK;
392 		nfssvc_nfsd = NFSSVC_NFSD;
393 		/*
394 		 * Figure out if the kernel supports the new-style
395 		 * NFSSVC_NFSD. Old kernels will return ENXIO because they
396 		 * don't recognise the flag value, new ones will return EINVAL
397 		 * because argp is NULL.
398 		 */
399 		new_syscall = FALSE;
400 		if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL)
401 			new_syscall = TRUE;
402 	}
403 
404 	if (!new_syscall) {
405 		/* If we use UDP only, we start the last server below. */
406 		srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1;
407 		for (i = 0; i < srvcnt; i++) {
408 			switch ((pid = fork())) {
409 			case -1:
410 				syslog(LOG_ERR, "fork: %m");
411 				nfsd_exit(1);
412 			case 0:
413 				break;
414 			default:
415 				children[i] = pid;
416 				continue;
417 			}
418 			(void)signal(SIGUSR1, child_cleanup);
419 			setproctitle("server");
420 
421 			start_server(0);
422 		}
423 	} else if (tcpflag) {
424 		/*
425 		 * For TCP mode, we fork once to start the first
426 		 * kernel nfsd thread. The kernel will add more
427 		 * threads as needed.
428 		 */
429 		pid = fork();
430 		if (pid == -1) {
431 			syslog(LOG_ERR, "fork: %m");
432 			nfsd_exit(1);
433 		}
434 		if (pid) {
435 			children[0] = pid;
436 		} else {
437 			(void)signal(SIGUSR1, child_cleanup);
438 			setproctitle("server");
439 			start_server(0);
440 		}
441 	}
442 
443 	(void)signal(SIGUSR1, cleanup);
444 	FD_ZERO(&v4bits);
445 	FD_ZERO(&v6bits);
446 	FD_ZERO(&sockbits);
447 
448 	rpcbregcnt = 0;
449 	/* Set up the socket for udp and rpcb register it. */
450 	if (udpflag) {
451 		rpcbreg = 0;
452 		for (i = 0; i < bindhostc; i++) {
453 			memset(&hints, 0, sizeof hints);
454 			hints.ai_flags = AI_PASSIVE;
455 			hints.ai_family = AF_INET;
456 			hints.ai_socktype = SOCK_DGRAM;
457 			hints.ai_protocol = IPPROTO_UDP;
458 			if (setbindhost(&ai_udp, bindhost[i], hints) == 0) {
459 				rpcbreg = 1;
460 				rpcbregcnt++;
461 				if ((sock = socket(ai_udp->ai_family,
462 				    ai_udp->ai_socktype,
463 				    ai_udp->ai_protocol)) < 0) {
464 					syslog(LOG_ERR,
465 					    "can't create udp socket");
466 					nfsd_exit(1);
467 				}
468 				if (bind(sock, ai_udp->ai_addr,
469 				    ai_udp->ai_addrlen) < 0) {
470 					syslog(LOG_ERR,
471 					    "can't bind udp addr %s: %m",
472 					    bindhost[i]);
473 					nfsd_exit(1);
474 				}
475 				freeaddrinfo(ai_udp);
476 				addsockargs.sock = sock;
477 				addsockargs.name = NULL;
478 				addsockargs.namelen = 0;
479 				if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
480 					syslog(LOG_ERR, "can't Add UDP socket");
481 					nfsd_exit(1);
482 				}
483 				(void)close(sock);
484 			}
485 		}
486 		if (rpcbreg == 1) {
487 			memset(&hints, 0, sizeof hints);
488 			hints.ai_flags = AI_PASSIVE;
489 			hints.ai_family = AF_INET;
490 			hints.ai_socktype = SOCK_DGRAM;
491 			hints.ai_protocol = IPPROTO_UDP;
492 			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
493 			if (ecode != 0) {
494 				syslog(LOG_ERR, "getaddrinfo udp: %s",
495 				   gai_strerror(ecode));
496 				nfsd_exit(1);
497 			}
498 			nconf_udp = getnetconfigent("udp");
499 			if (nconf_udp == NULL)
500 				err(1, "getnetconfigent udp failed");
501 			nb_udp.buf = ai_udp->ai_addr;
502 			nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
503 			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp, &nb_udp)) ||
504 			    (!rpcb_set(NFS_PROGRAM, 3, nconf_udp, &nb_udp)))
505 				err(1, "rpcb_set udp failed");
506 			freeaddrinfo(ai_udp);
507 		}
508 	}
509 
510 	/* Set up the socket for udp6 and rpcb register it. */
511 	if (udpflag && ip6flag) {
512 		rpcbreg = 0;
513 		for (i = 0; i < bindhostc; i++) {
514 			memset(&hints, 0, sizeof hints);
515 			hints.ai_flags = AI_PASSIVE;
516 			hints.ai_family = AF_INET6;
517 			hints.ai_socktype = SOCK_DGRAM;
518 			hints.ai_protocol = IPPROTO_UDP;
519 			if (setbindhost(&ai_udp6, bindhost[i], hints) == 0) {
520 				rpcbreg = 1;
521 				rpcbregcnt++;
522 				if ((sock = socket(ai_udp6->ai_family,
523 				    ai_udp6->ai_socktype,
524 				    ai_udp6->ai_protocol)) < 0) {
525 					syslog(LOG_ERR,
526 						"can't create udp6 socket");
527 					nfsd_exit(1);
528 				}
529 				if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
530 				    &on, sizeof on) < 0) {
531 					syslog(LOG_ERR,
532 					    "can't set v6-only binding for "
533 					    "udp6 socket: %m");
534 					nfsd_exit(1);
535 				}
536 				if (bind(sock, ai_udp6->ai_addr,
537 				    ai_udp6->ai_addrlen) < 0) {
538 					syslog(LOG_ERR,
539 					    "can't bind udp6 addr %s: %m",
540 					    bindhost[i]);
541 					nfsd_exit(1);
542 				}
543 				freeaddrinfo(ai_udp6);
544 				addsockargs.sock = sock;
545 				addsockargs.name = NULL;
546 				addsockargs.namelen = 0;
547 				if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
548 					syslog(LOG_ERR,
549 					    "can't add UDP6 socket");
550 					nfsd_exit(1);
551 				}
552 				(void)close(sock);
553 			}
554 		}
555 		if (rpcbreg == 1) {
556 			memset(&hints, 0, sizeof hints);
557 			hints.ai_flags = AI_PASSIVE;
558 			hints.ai_family = AF_INET6;
559 			hints.ai_socktype = SOCK_DGRAM;
560 			hints.ai_protocol = IPPROTO_UDP;
561 			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
562 			if (ecode != 0) {
563 				syslog(LOG_ERR, "getaddrinfo udp6: %s",
564 				   gai_strerror(ecode));
565 				nfsd_exit(1);
566 			}
567 			nconf_udp6 = getnetconfigent("udp6");
568 			if (nconf_udp6 == NULL)
569 				err(1, "getnetconfigent udp6 failed");
570 			nb_udp6.buf = ai_udp6->ai_addr;
571 			nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
572 			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp6, &nb_udp6)) ||
573 			    (!rpcb_set(NFS_PROGRAM, 3, nconf_udp6, &nb_udp6)))
574 				err(1, "rpcb_set udp6 failed");
575 			freeaddrinfo(ai_udp6);
576 		}
577 	}
578 
579 	/* Set up the socket for tcp and rpcb register it. */
580 	if (tcpflag) {
581 		rpcbreg = 0;
582 		for (i = 0; i < bindhostc; i++) {
583 			memset(&hints, 0, sizeof hints);
584 			hints.ai_flags = AI_PASSIVE;
585 			hints.ai_family = AF_INET;
586 			hints.ai_socktype = SOCK_STREAM;
587 			hints.ai_protocol = IPPROTO_TCP;
588 			if (setbindhost(&ai_tcp, bindhost[i], hints) == 0) {
589 				rpcbreg = 1;
590 				rpcbregcnt++;
591 				if ((tcpsock = socket(AF_INET, SOCK_STREAM,
592 				    0)) < 0) {
593 					syslog(LOG_ERR,
594 					    "can't create tpc socket");
595 					nfsd_exit(1);
596 				}
597 				if (setsockopt(tcpsock, SOL_SOCKET,
598 				    SO_REUSEADDR,
599 				    (char *)&on, sizeof(on)) < 0)
600 					syslog(LOG_ERR,
601 					     "setsockopt SO_REUSEADDR: %m");
602 				if (bind(tcpsock, ai_tcp->ai_addr,
603 				    ai_tcp->ai_addrlen) < 0) {
604 					syslog(LOG_ERR,
605 					    "can't bind tcp addr %s: %m",
606 					    bindhost[i]);
607 					nfsd_exit(1);
608 				}
609 				if (listen(tcpsock, 5) < 0) {
610 					syslog(LOG_ERR, "listen failed");
611 					nfsd_exit(1);
612 				}
613 				freeaddrinfo(ai_tcp);
614 				FD_SET(tcpsock, &sockbits);
615 				FD_SET(tcpsock, &v4bits);
616 				maxsock = tcpsock;
617 				connect_type_cnt++;
618 			}
619 		}
620 		if (rpcbreg == 1) {
621 			memset(&hints, 0, sizeof hints);
622 			hints.ai_flags = AI_PASSIVE;
623 			hints.ai_family = AF_INET;
624 			hints.ai_socktype = SOCK_STREAM;
625 			hints.ai_protocol = IPPROTO_TCP;
626 			ecode = getaddrinfo(NULL, "nfs", &hints,
627 			     &ai_tcp);
628 			if (ecode != 0) {
629 				syslog(LOG_ERR, "getaddrinfo tcp: %s",
630 				   gai_strerror(ecode));
631 				nfsd_exit(1);
632 			}
633 			nconf_tcp = getnetconfigent("tcp");
634 			if (nconf_tcp == NULL)
635 				err(1, "getnetconfigent tcp failed");
636 			nb_tcp.buf = ai_tcp->ai_addr;
637 			nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
638 			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp,
639 			    &nb_tcp)) || (!rpcb_set(NFS_PROGRAM, 3,
640 			    nconf_tcp, &nb_tcp)))
641 				err(1, "rpcb_set tcp failed");
642 			freeaddrinfo(ai_tcp);
643 		}
644 	}
645 
646 	/* Set up the socket for tcp6 and rpcb register it. */
647 	if (tcpflag && ip6flag) {
648 		rpcbreg = 0;
649 		for (i = 0; i < bindhostc; i++) {
650 			memset(&hints, 0, sizeof hints);
651 			hints.ai_flags = AI_PASSIVE;
652 			hints.ai_family = AF_INET6;
653 			hints.ai_socktype = SOCK_STREAM;
654 			hints.ai_protocol = IPPROTO_TCP;
655 			if (setbindhost(&ai_tcp6, bindhost[i], hints) == 0) {
656 				rpcbreg = 1;
657 				rpcbregcnt++;
658 				if ((tcp6sock = socket(ai_tcp6->ai_family,
659 				    ai_tcp6->ai_socktype,
660 				    ai_tcp6->ai_protocol)) < 0) {
661 					syslog(LOG_ERR,
662 					    "can't create tcp6 socket");
663 					nfsd_exit(1);
664 				}
665 				if (setsockopt(tcp6sock, SOL_SOCKET,
666 				    SO_REUSEADDR,
667 				    (char *)&on, sizeof(on)) < 0)
668 					syslog(LOG_ERR,
669 					    "setsockopt SO_REUSEADDR: %m");
670 				if (setsockopt(tcp6sock, IPPROTO_IPV6,
671 				    IPV6_V6ONLY, &on, sizeof on) < 0) {
672 					syslog(LOG_ERR,
673 					"can't set v6-only binding for tcp6 "
674 					    "socket: %m");
675 					nfsd_exit(1);
676 				}
677 				if (bind(tcp6sock, ai_tcp6->ai_addr,
678 				    ai_tcp6->ai_addrlen) < 0) {
679 					syslog(LOG_ERR,
680 					    "can't bind tcp6 addr %s: %m",
681 					    bindhost[i]);
682 					nfsd_exit(1);
683 				}
684 				if (listen(tcp6sock, 5) < 0) {
685 					syslog(LOG_ERR, "listen failed");
686 					nfsd_exit(1);
687 				}
688 				freeaddrinfo(ai_tcp6);
689 				FD_SET(tcp6sock, &sockbits);
690 				FD_SET(tcp6sock, &v6bits);
691 				if (maxsock < tcp6sock)
692 					maxsock = tcp6sock;
693 				connect_type_cnt++;
694 			}
695 		}
696 		if (rpcbreg == 1) {
697 			memset(&hints, 0, sizeof hints);
698 			hints.ai_flags = AI_PASSIVE;
699 			hints.ai_family = AF_INET6;
700 			hints.ai_socktype = SOCK_STREAM;
701 			hints.ai_protocol = IPPROTO_TCP;
702 			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
703 			if (ecode != 0) {
704 				syslog(LOG_ERR, "getaddrinfo tcp6: %s",
705 				   gai_strerror(ecode));
706 				nfsd_exit(1);
707 			}
708 			nconf_tcp6 = getnetconfigent("tcp6");
709 			if (nconf_tcp6 == NULL)
710 				err(1, "getnetconfigent tcp6 failed");
711 			nb_tcp6.buf = ai_tcp6->ai_addr;
712 			nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
713 			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp6, &nb_tcp6)) ||
714 			    (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp6, &nb_tcp6)))
715 				err(1, "rpcb_set tcp6 failed");
716 			freeaddrinfo(ai_tcp6);
717 		}
718 	}
719 
720 	if (rpcbregcnt == 0) {
721 		syslog(LOG_ERR, "rpcb_set() failed, nothing to do: %m");
722 		nfsd_exit(1);
723 	}
724 
725 	if (tcpflag && connect_type_cnt == 0) {
726 		syslog(LOG_ERR, "tcp connects == 0, nothing to do: %m");
727 		nfsd_exit(1);
728 	}
729 
730 	setproctitle("master");
731 	/*
732 	 * We always want a master to have a clean way to to shut nfsd down
733 	 * (with unregistration): if the master is killed, it unregisters and
734 	 * kills all children. If we run for UDP only (and so do not have to
735 	 * loop waiting waiting for accept), we instead make the parent
736 	 * a "server" too. start_server will not return.
737 	 */
738 	if (!tcpflag)
739 		start_server(1);
740 
741 	/*
742 	 * Loop forever accepting connections and passing the sockets
743 	 * into the kernel for the mounts.
744 	 */
745 	for (;;) {
746 		ready = sockbits;
747 		if (connect_type_cnt > 1) {
748 			if (select(maxsock + 1,
749 			    &ready, NULL, NULL, NULL) < 1) {
750 				error = errno;
751 				if (error == EINTR)
752 					continue;
753 				syslog(LOG_ERR, "select failed: %m");
754 				nfsd_exit(1);
755 			}
756 		}
757 		for (tcpsock = 0; tcpsock <= maxsock; tcpsock++) {
758 			if (FD_ISSET(tcpsock, &ready)) {
759 				if (FD_ISSET(tcpsock, &v4bits)) {
760 					len = sizeof(inetpeer);
761 					if ((msgsock = accept(tcpsock,
762 					    (struct sockaddr *)&inetpeer, &len)) < 0) {
763 						error = errno;
764 						syslog(LOG_ERR, "accept failed: %m");
765 						if (error == ECONNABORTED ||
766 						    error == EINTR)
767 							continue;
768 						nfsd_exit(1);
769 					}
770 					memset(inetpeer.sin_zero, 0,
771 						sizeof(inetpeer.sin_zero));
772 					if (setsockopt(msgsock, SOL_SOCKET,
773 					    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
774 						syslog(LOG_ERR,
775 						    "setsockopt SO_KEEPALIVE: %m");
776 					addsockargs.sock = msgsock;
777 					addsockargs.name = (caddr_t)&inetpeer;
778 					addsockargs.namelen = len;
779 					nfssvc(nfssvc_addsock, &addsockargs);
780 					(void)close(msgsock);
781 				} else if (FD_ISSET(tcpsock, &v6bits)) {
782 					len = sizeof(inet6peer);
783 					if ((msgsock = accept(tcpsock,
784 					    (struct sockaddr *)&inet6peer,
785 					    &len)) < 0) {
786 						error = errno;
787 						syslog(LOG_ERR,
788 						     "accept failed: %m");
789 						if (error == ECONNABORTED ||
790 						    error == EINTR)
791 							continue;
792 						nfsd_exit(1);
793 					}
794 					if (setsockopt(msgsock, SOL_SOCKET,
795 					    SO_KEEPALIVE, (char *)&on,
796 					    sizeof(on)) < 0)
797 						syslog(LOG_ERR, "setsockopt "
798 						    "SO_KEEPALIVE: %m");
799 					addsockargs.sock = msgsock;
800 					addsockargs.name = (caddr_t)&inet6peer;
801 					addsockargs.namelen = len;
802 					nfssvc(nfssvc_addsock, &addsockargs);
803 					(void)close(msgsock);
804 				}
805 			}
806 		}
807 	}
808 }
809 
810 int
811 setbindhost(struct addrinfo **ai, const char *bindhost, struct addrinfo hints)
812 {
813 	int ecode;
814 	u_int32_t host_addr[4];  /* IPv4 or IPv6 */
815 	const char *hostptr;
816 
817 	if (bindhost == NULL || strcmp("*", bindhost) == 0)
818 		hostptr = NULL;
819 	else
820 		hostptr = bindhost;
821 
822 	if (hostptr != NULL) {
823 		switch (hints.ai_family) {
824 		case AF_INET:
825 			if (inet_pton(AF_INET, hostptr, host_addr) == 1) {
826 				hints.ai_flags = AI_NUMERICHOST;
827 			} else {
828 				if (inet_pton(AF_INET6, hostptr,
829 				    host_addr) == 1)
830 					return (1);
831 			}
832 			break;
833 		case AF_INET6:
834 			if (inet_pton(AF_INET6, hostptr, host_addr) == 1) {
835 				hints.ai_flags = AI_NUMERICHOST;
836 			} else {
837 				if (inet_pton(AF_INET, hostptr,
838 				    host_addr) == 1)
839 					return (1);
840 			}
841 			break;
842 		default:
843 			break;
844 		}
845 	}
846 
847 	ecode = getaddrinfo(hostptr, "nfs", &hints, ai);
848 	if (ecode != 0) {
849 		syslog(LOG_ERR, "getaddrinfo %s: %s", bindhost,
850 		    gai_strerror(ecode));
851 		return (1);
852 	}
853 	return (0);
854 }
855 
856 void
857 usage(void)
858 {
859 	(void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
860 	exit(1);
861 }
862 
863 void
864 nonfs(__unused int signo)
865 {
866 	syslog(LOG_ERR, "missing system call: NFS not available");
867 }
868 
869 void
870 reapchild(__unused int signo)
871 {
872 	pid_t pid;
873 	int i;
874 
875 	while ((pid = wait3(NULL, WNOHANG, NULL)) > 0) {
876 		for (i = 0; i < nfsdcnt; i++)
877 			if (pid == children[i])
878 				children[i] = -1;
879 	}
880 }
881 
882 void
883 unregistration(void)
884 {
885 	if ((!rpcb_unset(NFS_PROGRAM, 2, NULL)) ||
886 	    (!rpcb_unset(NFS_PROGRAM, 3, NULL)))
887 		syslog(LOG_ERR, "rpcb_unset failed");
888 }
889 
890 void
891 killchildren(void)
892 {
893 	int i;
894 
895 	for (i = 0; i < nfsdcnt; i++) {
896 		if (children[i] > 0)
897 			kill(children[i], SIGKILL);
898 	}
899 }
900 
901 /*
902  * Cleanup master after SIGUSR1.
903  */
904 void
905 cleanup(__unused int signo)
906 {
907 	nfsd_exit(0);
908 }
909 
910 /*
911  * Cleanup child after SIGUSR1.
912  */
913 void
914 child_cleanup(__unused int signo)
915 {
916 	exit(0);
917 }
918 
919 void
920 nfsd_exit(int status)
921 {
922 	killchildren();
923 	unregistration();
924 	exit(status);
925 }
926 
927 void
928 start_server(int master)
929 {
930 	char principal[MAXHOSTNAMELEN + 5];
931 	struct nfsd_nfsd_args nfsdargs;
932 	int status, error;
933 	char hostname[MAXHOSTNAMELEN + 1], *cp;
934 	struct addrinfo *aip, hints;
935 
936 	status = 0;
937 	if (new_syscall) {
938 		gethostname(hostname, sizeof (hostname));
939 		snprintf(principal, sizeof (principal), "nfs@%s", hostname);
940 		if ((cp = strchr(hostname, '.')) == NULL ||
941 		    *(cp + 1) == '\0') {
942 			/* If not fully qualified, try getaddrinfo() */
943 			memset((void *)&hints, 0, sizeof (hints));
944 			hints.ai_flags = AI_CANONNAME;
945 			error = getaddrinfo(hostname, NULL, &hints, &aip);
946 			if (error == 0) {
947 				if (aip->ai_canonname != NULL &&
948 				    (cp = strchr(aip->ai_canonname, '.')) !=
949 				    NULL && *(cp + 1) != '\0')
950 					snprintf(principal, sizeof (principal),
951 					    "nfs@%s", aip->ai_canonname);
952 				freeaddrinfo(aip);
953 			}
954 		}
955 		nfsdargs.principal = principal;
956 		nfsdargs.minthreads = nfsdcnt;
957 		nfsdargs.maxthreads = nfsdcnt;
958 		error = nfssvc(nfssvc_nfsd, &nfsdargs);
959 		if (error < 0 && errno == EAUTH) {
960 			/*
961 			 * This indicates that it could not register the
962 			 * rpcsec_gss credentials, usually because the
963 			 * gssd daemon isn't running.
964 			 * (only the experimental server with nfsv4)
965 			 */
966 			syslog(LOG_ERR, "No gssd, using AUTH_SYS only");
967 			principal[0] = '\0';
968 			error = nfssvc(nfssvc_nfsd, &nfsdargs);
969 		}
970 		if (error < 0) {
971 			syslog(LOG_ERR, "nfssvc: %m");
972 			status = 1;
973 		}
974 	} else {
975 		if (nfssvc(NFSSVC_OLDNFSD, NULL) < 0) {
976 			syslog(LOG_ERR, "nfssvc: %m");
977 			status = 1;
978 		}
979 	}
980 	if (master)
981 		nfsd_exit(status);
982 	else
983 		exit(status);
984 }
985 
986 /*
987  * Open the stable restart file and return the file descriptor for it.
988  */
989 void
990 open_stable(int *stable_fdp, int *backup_fdp)
991 {
992 	int stable_fd, backup_fd = -1, ret;
993 	struct stat st, backup_st;
994 
995 	/* Open and stat the stable restart file. */
996 	stable_fd = open(NFSD_STABLERESTART, O_RDWR, 0);
997 	if (stable_fd < 0)
998 		stable_fd = open(NFSD_STABLERESTART, O_RDWR | O_CREAT, 0600);
999 	if (stable_fd >= 0) {
1000 		ret = fstat(stable_fd, &st);
1001 		if (ret < 0) {
1002 			close(stable_fd);
1003 			stable_fd = -1;
1004 		}
1005 	}
1006 
1007 	/* Open and stat the backup stable restart file. */
1008 	if (stable_fd >= 0) {
1009 		backup_fd = open(NFSD_STABLEBACKUP, O_RDWR, 0);
1010 		if (backup_fd < 0)
1011 			backup_fd = open(NFSD_STABLEBACKUP, O_RDWR | O_CREAT,
1012 			    0600);
1013 		if (backup_fd >= 0) {
1014 			ret = fstat(backup_fd, &backup_st);
1015 			if (ret < 0) {
1016 				close(backup_fd);
1017 				backup_fd = -1;
1018 			}
1019 		}
1020 		if (backup_fd < 0) {
1021 			close(stable_fd);
1022 			stable_fd = -1;
1023 		}
1024 	}
1025 
1026 	*stable_fdp = stable_fd;
1027 	*backup_fdp = backup_fd;
1028 	if (stable_fd < 0)
1029 		return;
1030 
1031 	/* Sync up the 2 files, as required. */
1032 	if (st.st_size > 0)
1033 		copy_stable(stable_fd, backup_fd);
1034 	else if (backup_st.st_size > 0)
1035 		copy_stable(backup_fd, stable_fd);
1036 }
1037 
1038 /*
1039  * Copy the stable restart file to the backup or vice versa.
1040  */
1041 void
1042 copy_stable(int from_fd, int to_fd)
1043 {
1044 	int cnt, ret;
1045 	static char buf[1024];
1046 
1047 	ret = lseek(from_fd, (off_t)0, SEEK_SET);
1048 	if (ret >= 0)
1049 		ret = lseek(to_fd, (off_t)0, SEEK_SET);
1050 	if (ret >= 0)
1051 		ret = ftruncate(to_fd, (off_t)0);
1052 	if (ret >= 0)
1053 		do {
1054 			cnt = read(from_fd, buf, 1024);
1055 			if (cnt > 0)
1056 				ret = write(to_fd, buf, cnt);
1057 			else if (cnt < 0)
1058 				ret = cnt;
1059 		} while (cnt > 0 && ret >= 0);
1060 	if (ret >= 0)
1061 		ret = fsync(to_fd);
1062 	if (ret < 0)
1063 		syslog(LOG_ERR, "stable restart copy failure: %m");
1064 }
1065 
1066 /*
1067  * Back up the stable restart file when indicated by the kernel.
1068  */
1069 void
1070 backup_stable(__unused int signo)
1071 {
1072 
1073 	if (stablefd >= 0)
1074 		copy_stable(stablefd, backupfd);
1075 }
1076 
1077