2 * Copyright (c) 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
34 static const char copyright[] =
35 "@(#) Copyright (c) 1989, 1993, 1994\n\
36 The Regents of the University of California. All rights reserved.\n";
41 static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95";
43 static const char rcsid[] =
47 #include <sys/param.h>
48 #include <sys/syslog.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>
56 #include <sys/ucred.h>
59 #include <rpc/pmap_clnt.h>
60 #include <rpcsvc/nfs_prot.h>
63 #include <arpa/inet.h>
64 #include <nfsserver/nfs.h>
65 #include <nfs/nfssvc.h>
77 #define syslog(e, s...) fprintf(stderr,s)
83 #define NFSD_STABLERESTART "/var/db/nfs-stablerestart"
84 #define NFSD_STABLEBACKUP "/var/db/nfs-stablerestart.bak"
85 #define MAXNFSDCNT 256
87 pid_t children[MAXNFSDCNT]; /* PIDs of children */
88 int nfsdcnt; /* number of children */
90 int run_v4server = 1; /* Force running of nfsv4 server */
91 int nfssvc_nfsd; /* Set to correct NFSSVC_xxx flag */
92 int stablefd = -1; /* Fd for the stable restart file */
93 int backupfd; /* Fd for the backup stable restart file */
96 void child_cleanup(int);
97 void killchildren(void);
101 int setbindhost(struct addrinfo **ia, const char *bindhost,
102 struct addrinfo hints);
103 void start_server(int);
104 void unregistration(void);
106 void open_stable(int *, int *);
107 void copy_stable(int, int);
108 void backup_stable(int);
111 * Nfs server daemon mostly just a user context for nfssvc()
113 * 1 - do file descriptor and signal cleanup
114 * 2 - fork the nfsd(s)
115 * 3 - create server socket(s)
116 * 4 - register socket with rpcbind
118 * For connectionless protocols, just pass the socket into the kernel via.
120 * For connection based sockets, loop doing accepts. When you get a new
121 * socket from accept, pass the msgsock into the kernel via. nfssvc().
123 * -r - reregister with rpcbind
124 * -d - unregister with rpcbind
125 * -t - support tcp nfs clients
126 * -u - support udp nfs clients
127 * -e - forces it to run a server that supports nfsv4
128 * followed by "n" which is the number of nfsds' to fork off
131 main(int argc, char **argv)
133 struct nfsd_addsock_args addsockargs;
134 struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
135 struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
136 struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
137 struct sockaddr_in inetpeer;
138 struct sockaddr_in6 inet6peer;
139 fd_set ready, sockbits;
140 fd_set v4bits, v6bits;
141 int ch, connect_type_cnt, i, maxsock, msgsock;
143 int on = 1, unregister, reregister, sock;
144 int tcp6sock, ip6flag, tcpflag, tcpsock;
145 int udpflag, ecode, error, s, srvcnt;
146 int bindhostc, bindanyflag, rpcbreg, rpcbregcnt;
148 char **bindhost = NULL;
151 nfsdcnt = DEFNFSDCNT;
152 unregister = reregister = tcpflag = maxsock = 0;
153 bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
154 #define GETOPT "ah:n:rdtueo"
155 #define USAGE "[-ardtueo] [-n num_servers] [-h bindip]"
156 while ((ch = getopt(argc, argv, GETOPT)) != -1)
162 nfsdcnt = atoi(optarg);
163 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
164 warnx("nfsd count %d; reset to %d", nfsdcnt,
166 nfsdcnt = DEFNFSDCNT;
171 bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
172 if (bindhost == NULL)
173 errx(1, "Out of memory");
174 bindhost[bindhostc-1] = strdup(optarg);
175 if (bindhost[bindhostc-1] == NULL)
176 errx(1, "Out of memory");
191 /* now a no-op, since this is the default */
200 if (!tcpflag && !udpflag)
207 * Backward compatibility, trailing number is the count of daemons.
212 nfsdcnt = atoi(argv[0]);
213 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
214 warnx("nfsd count %d; reset to %d", nfsdcnt,
216 nfsdcnt = DEFNFSDCNT;
221 * Unless the "-o" option was specified, try and run "nfsd".
222 * If "-o" was specified, try and run "nfsserver".
224 if (run_v4server > 0) {
225 if (modfind("nfsd") < 0) {
226 /* Not present in kernel, try loading it */
227 if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
228 errx(1, "NFS server is not available");
230 } else if (modfind("nfsserver") < 0) {
231 /* Not present in kernel, try loading it */
232 if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0)
233 errx(1, "NFS server is not available");
237 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
239 if (errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT)
242 } else if (getnetconfigent("udp6") == NULL ||
243 getnetconfigent("tcp6") == NULL) {
249 if (bindhostc == 0 || bindanyflag) {
251 bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
252 if (bindhost == NULL)
253 errx(1, "Out of memory");
254 bindhost[bindhostc-1] = strdup("*");
255 if (bindhost[bindhostc-1] == NULL)
256 errx(1, "Out of memory");
265 memset(&hints, 0, sizeof hints);
266 hints.ai_flags = AI_PASSIVE;
267 hints.ai_family = AF_INET;
268 hints.ai_socktype = SOCK_DGRAM;
269 hints.ai_protocol = IPPROTO_UDP;
270 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
272 err(1, "getaddrinfo udp: %s", gai_strerror(ecode));
273 nconf_udp = getnetconfigent("udp");
274 if (nconf_udp == NULL)
275 err(1, "getnetconfigent udp failed");
276 nb_udp.buf = ai_udp->ai_addr;
277 nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
278 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp, &nb_udp)) ||
279 (!rpcb_set(NFS_PROGRAM, 3, nconf_udp, &nb_udp)))
280 err(1, "rpcb_set udp failed");
281 freeaddrinfo(ai_udp);
283 if (udpflag && ip6flag) {
284 memset(&hints, 0, sizeof hints);
285 hints.ai_flags = AI_PASSIVE;
286 hints.ai_family = AF_INET6;
287 hints.ai_socktype = SOCK_DGRAM;
288 hints.ai_protocol = IPPROTO_UDP;
289 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
291 err(1, "getaddrinfo udp6: %s", gai_strerror(ecode));
292 nconf_udp6 = getnetconfigent("udp6");
293 if (nconf_udp6 == NULL)
294 err(1, "getnetconfigent udp6 failed");
295 nb_udp6.buf = ai_udp6->ai_addr;
296 nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
297 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp6, &nb_udp6)) ||
298 (!rpcb_set(NFS_PROGRAM, 3, nconf_udp6, &nb_udp6)))
299 err(1, "rpcb_set udp6 failed");
300 freeaddrinfo(ai_udp6);
303 memset(&hints, 0, sizeof hints);
304 hints.ai_flags = AI_PASSIVE;
305 hints.ai_family = AF_INET;
306 hints.ai_socktype = SOCK_STREAM;
307 hints.ai_protocol = IPPROTO_TCP;
308 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
310 err(1, "getaddrinfo tcp: %s", gai_strerror(ecode));
311 nconf_tcp = getnetconfigent("tcp");
312 if (nconf_tcp == NULL)
313 err(1, "getnetconfigent tcp failed");
314 nb_tcp.buf = ai_tcp->ai_addr;
315 nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
316 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp, &nb_tcp)) ||
317 (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp, &nb_tcp)))
318 err(1, "rpcb_set tcp failed");
319 freeaddrinfo(ai_tcp);
321 if (tcpflag && ip6flag) {
322 memset(&hints, 0, sizeof hints);
323 hints.ai_flags = AI_PASSIVE;
324 hints.ai_family = AF_INET6;
325 hints.ai_socktype = SOCK_STREAM;
326 hints.ai_protocol = IPPROTO_TCP;
327 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
329 err(1, "getaddrinfo tcp6: %s", gai_strerror(ecode));
330 nconf_tcp6 = getnetconfigent("tcp6");
331 if (nconf_tcp6 == NULL)
332 err(1, "getnetconfigent tcp6 failed");
333 nb_tcp6.buf = ai_tcp6->ai_addr;
334 nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
335 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp6, &nb_tcp6)) ||
336 (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp6, &nb_tcp6)))
337 err(1, "rpcb_set tcp6 failed");
338 freeaddrinfo(ai_tcp6);
344 (void)signal(SIGHUP, SIG_IGN);
345 (void)signal(SIGINT, SIG_IGN);
347 * nfsd sits in the kernel most of the time. It needs
348 * to ignore SIGTERM/SIGQUIT in order to stay alive as long
349 * as possible during a shutdown, otherwise loopback
350 * mounts will not be able to unmount.
352 (void)signal(SIGTERM, SIG_IGN);
353 (void)signal(SIGQUIT, SIG_IGN);
355 (void)signal(SIGSYS, nonfs);
356 (void)signal(SIGCHLD, reapchild);
357 (void)signal(SIGUSR2, backup_stable);
359 openlog("nfsd", LOG_PID, LOG_DAEMON);
362 * For V4, we open the stablerestart file and call nfssvc()
363 * to get it loaded. This is done before the daemons do the
364 * regular nfssvc() call to service NFS requests.
365 * (This way the file remains open until the last nfsd is killed
367 * It and the backup copy will be created as empty files
368 * the first time this nfsd is started and should never be
369 * deleted/replaced if at all possible. It should live on a
370 * local, non-volatile storage device that does not do hardware
371 * level write-back caching. (See SCSI doc for more information
372 * on how to prevent write-back caching on SCSI disks.)
374 if (run_v4server > 0) {
375 open_stable(&stablefd, &backupfd);
377 syslog(LOG_ERR, "Can't open %s\n", NFSD_STABLERESTART);
380 /* This system call will fail for old kernels, but that's ok. */
381 nfssvc(NFSSVC_BACKUPSTABLE, NULL);
382 if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) {
383 syslog(LOG_ERR, "Can't read stable storage file\n");
386 nfssvc_addsock = NFSSVC_NFSDADDSOCK;
387 nfssvc_nfsd = NFSSVC_NFSDNFSD;
390 nfssvc_addsock = NFSSVC_ADDSOCK;
391 nfssvc_nfsd = NFSSVC_NFSD;
393 * Figure out if the kernel supports the new-style
394 * NFSSVC_NFSD. Old kernels will return ENXIO because they
395 * don't recognise the flag value, new ones will return EINVAL
396 * because argp is NULL.
399 if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL)
404 /* If we use UDP only, we start the last server below. */
405 srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1;
406 for (i = 0; i < srvcnt; i++) {
407 switch ((pid = fork())) {
409 syslog(LOG_ERR, "fork: %m");
417 (void)signal(SIGUSR1, child_cleanup);
418 setproctitle("server");
422 } else if (tcpflag) {
424 * For TCP mode, we fork once to start the first
425 * kernel nfsd thread. The kernel will add more
430 syslog(LOG_ERR, "fork: %m");
436 (void)signal(SIGUSR1, child_cleanup);
437 setproctitle("server");
442 (void)signal(SIGUSR1, cleanup);
448 /* Set up the socket for udp and rpcb register it. */
451 for (i = 0; i < bindhostc; i++) {
452 memset(&hints, 0, sizeof hints);
453 hints.ai_flags = AI_PASSIVE;
454 hints.ai_family = AF_INET;
455 hints.ai_socktype = SOCK_DGRAM;
456 hints.ai_protocol = IPPROTO_UDP;
457 if (setbindhost(&ai_udp, bindhost[i], hints) == 0) {
460 if ((sock = socket(ai_udp->ai_family,
462 ai_udp->ai_protocol)) < 0) {
464 "can't create udp socket");
467 if (bind(sock, ai_udp->ai_addr,
468 ai_udp->ai_addrlen) < 0) {
470 "can't bind udp addr %s: %m",
474 freeaddrinfo(ai_udp);
475 addsockargs.sock = sock;
476 addsockargs.name = NULL;
477 addsockargs.namelen = 0;
478 if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
479 syslog(LOG_ERR, "can't Add UDP socket");
486 memset(&hints, 0, sizeof hints);
487 hints.ai_flags = AI_PASSIVE;
488 hints.ai_family = AF_INET;
489 hints.ai_socktype = SOCK_DGRAM;
490 hints.ai_protocol = IPPROTO_UDP;
491 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
493 syslog(LOG_ERR, "getaddrinfo udp: %s",
494 gai_strerror(ecode));
497 nconf_udp = getnetconfigent("udp");
498 if (nconf_udp == NULL)
499 err(1, "getnetconfigent udp failed");
500 nb_udp.buf = ai_udp->ai_addr;
501 nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
502 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp, &nb_udp)) ||
503 (!rpcb_set(NFS_PROGRAM, 3, nconf_udp, &nb_udp)))
504 err(1, "rpcb_set udp failed");
505 freeaddrinfo(ai_udp);
509 /* Set up the socket for udp6 and rpcb register it. */
510 if (udpflag && ip6flag) {
512 for (i = 0; i < bindhostc; i++) {
513 memset(&hints, 0, sizeof hints);
514 hints.ai_flags = AI_PASSIVE;
515 hints.ai_family = AF_INET6;
516 hints.ai_socktype = SOCK_DGRAM;
517 hints.ai_protocol = IPPROTO_UDP;
518 if (setbindhost(&ai_udp6, bindhost[i], hints) == 0) {
521 if ((sock = socket(ai_udp6->ai_family,
522 ai_udp6->ai_socktype,
523 ai_udp6->ai_protocol)) < 0) {
525 "can't create udp6 socket");
528 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
529 &on, sizeof on) < 0) {
531 "can't set v6-only binding for "
535 if (bind(sock, ai_udp6->ai_addr,
536 ai_udp6->ai_addrlen) < 0) {
538 "can't bind udp6 addr %s: %m",
542 freeaddrinfo(ai_udp6);
543 addsockargs.sock = sock;
544 addsockargs.name = NULL;
545 addsockargs.namelen = 0;
546 if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
548 "can't add UDP6 socket");
555 memset(&hints, 0, sizeof hints);
556 hints.ai_flags = AI_PASSIVE;
557 hints.ai_family = AF_INET6;
558 hints.ai_socktype = SOCK_DGRAM;
559 hints.ai_protocol = IPPROTO_UDP;
560 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
562 syslog(LOG_ERR, "getaddrinfo udp6: %s",
563 gai_strerror(ecode));
566 nconf_udp6 = getnetconfigent("udp6");
567 if (nconf_udp6 == NULL)
568 err(1, "getnetconfigent udp6 failed");
569 nb_udp6.buf = ai_udp6->ai_addr;
570 nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
571 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp6, &nb_udp6)) ||
572 (!rpcb_set(NFS_PROGRAM, 3, nconf_udp6, &nb_udp6)))
573 err(1, "rpcb_set udp6 failed");
574 freeaddrinfo(ai_udp6);
578 /* Set up the socket for tcp and rpcb register it. */
581 for (i = 0; i < bindhostc; i++) {
582 memset(&hints, 0, sizeof hints);
583 hints.ai_flags = AI_PASSIVE;
584 hints.ai_family = AF_INET;
585 hints.ai_socktype = SOCK_STREAM;
586 hints.ai_protocol = IPPROTO_TCP;
587 if (setbindhost(&ai_tcp, bindhost[i], hints) == 0) {
590 if ((tcpsock = socket(AF_INET, SOCK_STREAM,
593 "can't create tcp socket");
596 if (setsockopt(tcpsock, SOL_SOCKET,
598 (char *)&on, sizeof(on)) < 0)
600 "setsockopt SO_REUSEADDR: %m");
601 if (bind(tcpsock, ai_tcp->ai_addr,
602 ai_tcp->ai_addrlen) < 0) {
604 "can't bind tcp addr %s: %m",
608 if (listen(tcpsock, -1) < 0) {
609 syslog(LOG_ERR, "listen failed");
612 freeaddrinfo(ai_tcp);
613 FD_SET(tcpsock, &sockbits);
614 FD_SET(tcpsock, &v4bits);
620 memset(&hints, 0, sizeof hints);
621 hints.ai_flags = AI_PASSIVE;
622 hints.ai_family = AF_INET;
623 hints.ai_socktype = SOCK_STREAM;
624 hints.ai_protocol = IPPROTO_TCP;
625 ecode = getaddrinfo(NULL, "nfs", &hints,
628 syslog(LOG_ERR, "getaddrinfo tcp: %s",
629 gai_strerror(ecode));
632 nconf_tcp = getnetconfigent("tcp");
633 if (nconf_tcp == NULL)
634 err(1, "getnetconfigent tcp failed");
635 nb_tcp.buf = ai_tcp->ai_addr;
636 nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
637 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp,
638 &nb_tcp)) || (!rpcb_set(NFS_PROGRAM, 3,
639 nconf_tcp, &nb_tcp)))
640 err(1, "rpcb_set tcp failed");
641 freeaddrinfo(ai_tcp);
645 /* Set up the socket for tcp6 and rpcb register it. */
646 if (tcpflag && ip6flag) {
648 for (i = 0; i < bindhostc; i++) {
649 memset(&hints, 0, sizeof hints);
650 hints.ai_flags = AI_PASSIVE;
651 hints.ai_family = AF_INET6;
652 hints.ai_socktype = SOCK_STREAM;
653 hints.ai_protocol = IPPROTO_TCP;
654 if (setbindhost(&ai_tcp6, bindhost[i], hints) == 0) {
657 if ((tcp6sock = socket(ai_tcp6->ai_family,
658 ai_tcp6->ai_socktype,
659 ai_tcp6->ai_protocol)) < 0) {
661 "can't create tcp6 socket");
664 if (setsockopt(tcp6sock, SOL_SOCKET,
666 (char *)&on, sizeof(on)) < 0)
668 "setsockopt SO_REUSEADDR: %m");
669 if (setsockopt(tcp6sock, IPPROTO_IPV6,
670 IPV6_V6ONLY, &on, sizeof on) < 0) {
672 "can't set v6-only binding for tcp6 "
676 if (bind(tcp6sock, ai_tcp6->ai_addr,
677 ai_tcp6->ai_addrlen) < 0) {
679 "can't bind tcp6 addr %s: %m",
683 if (listen(tcp6sock, -1) < 0) {
684 syslog(LOG_ERR, "listen failed");
687 freeaddrinfo(ai_tcp6);
688 FD_SET(tcp6sock, &sockbits);
689 FD_SET(tcp6sock, &v6bits);
690 if (maxsock < tcp6sock)
696 memset(&hints, 0, sizeof hints);
697 hints.ai_flags = AI_PASSIVE;
698 hints.ai_family = AF_INET6;
699 hints.ai_socktype = SOCK_STREAM;
700 hints.ai_protocol = IPPROTO_TCP;
701 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
703 syslog(LOG_ERR, "getaddrinfo tcp6: %s",
704 gai_strerror(ecode));
707 nconf_tcp6 = getnetconfigent("tcp6");
708 if (nconf_tcp6 == NULL)
709 err(1, "getnetconfigent tcp6 failed");
710 nb_tcp6.buf = ai_tcp6->ai_addr;
711 nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
712 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp6, &nb_tcp6)) ||
713 (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp6, &nb_tcp6)))
714 err(1, "rpcb_set tcp6 failed");
715 freeaddrinfo(ai_tcp6);
719 if (rpcbregcnt == 0) {
720 syslog(LOG_ERR, "rpcb_set() failed, nothing to do: %m");
724 if (tcpflag && connect_type_cnt == 0) {
725 syslog(LOG_ERR, "tcp connects == 0, nothing to do: %m");
729 setproctitle("master");
731 * We always want a master to have a clean way to to shut nfsd down
732 * (with unregistration): if the master is killed, it unregisters and
733 * kills all children. If we run for UDP only (and so do not have to
734 * loop waiting waiting for accept), we instead make the parent
735 * a "server" too. start_server will not return.
741 * Loop forever accepting connections and passing the sockets
742 * into the kernel for the mounts.
746 if (connect_type_cnt > 1) {
747 if (select(maxsock + 1,
748 &ready, NULL, NULL, NULL) < 1) {
752 syslog(LOG_ERR, "select failed: %m");
756 for (tcpsock = 0; tcpsock <= maxsock; tcpsock++) {
757 if (FD_ISSET(tcpsock, &ready)) {
758 if (FD_ISSET(tcpsock, &v4bits)) {
759 len = sizeof(inetpeer);
760 if ((msgsock = accept(tcpsock,
761 (struct sockaddr *)&inetpeer, &len)) < 0) {
763 syslog(LOG_ERR, "accept failed: %m");
764 if (error == ECONNABORTED ||
769 memset(inetpeer.sin_zero, 0,
770 sizeof(inetpeer.sin_zero));
771 if (setsockopt(msgsock, SOL_SOCKET,
772 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
774 "setsockopt SO_KEEPALIVE: %m");
775 addsockargs.sock = msgsock;
776 addsockargs.name = (caddr_t)&inetpeer;
777 addsockargs.namelen = len;
778 nfssvc(nfssvc_addsock, &addsockargs);
779 (void)close(msgsock);
780 } else if (FD_ISSET(tcpsock, &v6bits)) {
781 len = sizeof(inet6peer);
782 if ((msgsock = accept(tcpsock,
783 (struct sockaddr *)&inet6peer,
787 "accept failed: %m");
788 if (error == ECONNABORTED ||
793 if (setsockopt(msgsock, SOL_SOCKET,
794 SO_KEEPALIVE, (char *)&on,
796 syslog(LOG_ERR, "setsockopt "
798 addsockargs.sock = msgsock;
799 addsockargs.name = (caddr_t)&inet6peer;
800 addsockargs.namelen = len;
801 nfssvc(nfssvc_addsock, &addsockargs);
802 (void)close(msgsock);
810 setbindhost(struct addrinfo **ai, const char *bindhost, struct addrinfo hints)
813 u_int32_t host_addr[4]; /* IPv4 or IPv6 */
816 if (bindhost == NULL || strcmp("*", bindhost) == 0)
821 if (hostptr != NULL) {
822 switch (hints.ai_family) {
824 if (inet_pton(AF_INET, hostptr, host_addr) == 1) {
825 hints.ai_flags = AI_NUMERICHOST;
827 if (inet_pton(AF_INET6, hostptr,
833 if (inet_pton(AF_INET6, hostptr, host_addr) == 1) {
834 hints.ai_flags = AI_NUMERICHOST;
836 if (inet_pton(AF_INET, hostptr,
846 ecode = getaddrinfo(hostptr, "nfs", &hints, ai);
848 syslog(LOG_ERR, "getaddrinfo %s: %s", bindhost,
849 gai_strerror(ecode));
858 (void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
863 nonfs(__unused int signo)
865 syslog(LOG_ERR, "missing system call: NFS not available");
869 reapchild(__unused int signo)
874 while ((pid = wait3(NULL, WNOHANG, NULL)) > 0) {
875 for (i = 0; i < nfsdcnt; i++)
876 if (pid == children[i])
884 if ((!rpcb_unset(NFS_PROGRAM, 2, NULL)) ||
885 (!rpcb_unset(NFS_PROGRAM, 3, NULL)))
886 syslog(LOG_ERR, "rpcb_unset failed");
894 for (i = 0; i < nfsdcnt; i++) {
896 kill(children[i], SIGKILL);
901 * Cleanup master after SIGUSR1.
904 cleanup(__unused int signo)
910 * Cleanup child after SIGUSR1.
913 child_cleanup(__unused int signo)
919 nfsd_exit(int status)
927 start_server(int master)
929 char principal[MAXHOSTNAMELEN + 5];
930 struct nfsd_nfsd_args nfsdargs;
932 char hostname[MAXHOSTNAMELEN + 1], *cp;
933 struct addrinfo *aip, hints;
937 gethostname(hostname, sizeof (hostname));
938 snprintf(principal, sizeof (principal), "nfs@%s", hostname);
939 if ((cp = strchr(hostname, '.')) == NULL ||
941 /* If not fully qualified, try getaddrinfo() */
942 memset((void *)&hints, 0, sizeof (hints));
943 hints.ai_flags = AI_CANONNAME;
944 error = getaddrinfo(hostname, NULL, &hints, &aip);
946 if (aip->ai_canonname != NULL &&
947 (cp = strchr(aip->ai_canonname, '.')) !=
948 NULL && *(cp + 1) != '\0')
949 snprintf(principal, sizeof (principal),
950 "nfs@%s", aip->ai_canonname);
954 nfsdargs.principal = principal;
955 nfsdargs.minthreads = nfsdcnt;
956 nfsdargs.maxthreads = nfsdcnt;
957 error = nfssvc(nfssvc_nfsd, &nfsdargs);
958 if (error < 0 && errno == EAUTH) {
960 * This indicates that it could not register the
961 * rpcsec_gss credentials, usually because the
962 * gssd daemon isn't running.
963 * (only the experimental server with nfsv4)
965 syslog(LOG_ERR, "No gssd, using AUTH_SYS only");
967 error = nfssvc(nfssvc_nfsd, &nfsdargs);
970 syslog(LOG_ERR, "nfssvc: %m");
974 if (nfssvc(NFSSVC_OLDNFSD, NULL) < 0) {
975 syslog(LOG_ERR, "nfssvc: %m");
986 * Open the stable restart file and return the file descriptor for it.
989 open_stable(int *stable_fdp, int *backup_fdp)
991 int stable_fd, backup_fd = -1, ret;
992 struct stat st, backup_st;
994 /* Open and stat the stable restart file. */
995 stable_fd = open(NFSD_STABLERESTART, O_RDWR, 0);
997 stable_fd = open(NFSD_STABLERESTART, O_RDWR | O_CREAT, 0600);
998 if (stable_fd >= 0) {
999 ret = fstat(stable_fd, &st);
1006 /* Open and stat the backup stable restart file. */
1007 if (stable_fd >= 0) {
1008 backup_fd = open(NFSD_STABLEBACKUP, O_RDWR, 0);
1010 backup_fd = open(NFSD_STABLEBACKUP, O_RDWR | O_CREAT,
1012 if (backup_fd >= 0) {
1013 ret = fstat(backup_fd, &backup_st);
1019 if (backup_fd < 0) {
1025 *stable_fdp = stable_fd;
1026 *backup_fdp = backup_fd;
1030 /* Sync up the 2 files, as required. */
1032 copy_stable(stable_fd, backup_fd);
1033 else if (backup_st.st_size > 0)
1034 copy_stable(backup_fd, stable_fd);
1038 * Copy the stable restart file to the backup or vice versa.
1041 copy_stable(int from_fd, int to_fd)
1044 static char buf[1024];
1046 ret = lseek(from_fd, (off_t)0, SEEK_SET);
1048 ret = lseek(to_fd, (off_t)0, SEEK_SET);
1050 ret = ftruncate(to_fd, (off_t)0);
1053 cnt = read(from_fd, buf, 1024);
1055 ret = write(to_fd, buf, cnt);
1058 } while (cnt > 0 && ret >= 0);
1062 syslog(LOG_ERR, "stable restart copy failure: %m");
1066 * Back up the stable restart file when indicated by the kernel.
1069 backup_stable(__unused int signo)
1073 copy_stable(stablefd, backupfd);