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>
78 #define syslog(e, s...) fprintf(stderr,s)
84 #define NFSD_STABLERESTART "/var/db/nfs-stablerestart"
85 #define NFSD_STABLEBACKUP "/var/db/nfs-stablerestart.bak"
86 #define MAXNFSDCNT 256
88 pid_t children[MAXNFSDCNT]; /* PIDs of children */
89 int nfsdcnt; /* number of children */
91 int run_v4server = 0; /* 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 */
97 void child_cleanup(int);
98 void killchildren(void);
102 int setbindhost(struct addrinfo **ia, const char *bindhost,
103 struct addrinfo hints);
104 void start_server(int);
105 void unregistration(void);
107 void open_stable(int *, int *);
108 void copy_stable(int, int);
109 void backup_stable(int);
112 * Nfs server daemon mostly just a user context for nfssvc()
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
119 * For connectionless protocols, just pass the socket into the kernel via.
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().
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
132 main(int argc, char **argv)
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;
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;
149 char **bindhost = NULL;
152 nfsdcnt = DEFNFSDCNT;
153 unregister = reregister = tcpflag = maxsock = 0;
154 bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
155 #define GETOPT "ah:n:rdtue"
156 #define USAGE "[-ardtue] [-n num_servers] [-h bindip]"
157 while ((ch = getopt(argc, argv, GETOPT)) != -1)
163 nfsdcnt = atoi(optarg);
164 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
165 warnx("nfsd count %d; reset to %d", nfsdcnt,
167 nfsdcnt = DEFNFSDCNT;
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");
198 if (!tcpflag && !udpflag)
205 * Backward compatibility, trailing number is the count of daemons.
210 nfsdcnt = atoi(argv[0]);
211 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
212 warnx("nfsd count %d; reset to %d", nfsdcnt,
214 nfsdcnt = DEFNFSDCNT;
219 * If the "-e" option was specified OR only the nfsd module is
220 * found in the server, run "nfsd".
221 * Otherwise, try and run "nfsserver".
223 if (run_v4server > 0) {
224 if (modfind("nfsd") < 0) {
225 /* Not present in kernel, try loading it */
226 if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
227 errx(1, "NFS server is not available");
229 } else if (modfind("nfsserver") < 0 && modfind("nfsd") >= 0) {
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");
238 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
240 if (errno != EPROTONOSUPPORT)
243 } else if (getnetconfigent("udp6") == NULL ||
244 getnetconfigent("tcp6") == NULL) {
250 if (bindhostc == 0 || bindanyflag) {
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");
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);
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);
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);
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);
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);
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);
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);
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);
345 (void)signal(SIGHUP, SIG_IGN);
346 (void)signal(SIGINT, SIG_IGN);
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.
353 (void)signal(SIGTERM, SIG_IGN);
354 (void)signal(SIGQUIT, SIG_IGN);
356 (void)signal(SIGSYS, nonfs);
357 (void)signal(SIGCHLD, reapchild);
358 (void)signal(SIGUSR2, backup_stable);
360 openlog("nfsd", LOG_PID, LOG_DAEMON);
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
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.)
375 if (run_v4server > 0) {
376 open_stable(&stablefd, &backupfd);
378 syslog(LOG_ERR, "Can't open %s\n", NFSD_STABLERESTART);
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");
387 nfssvc_addsock = NFSSVC_NFSDADDSOCK;
388 nfssvc_nfsd = NFSSVC_NFSDNFSD;
391 nfssvc_addsock = NFSSVC_ADDSOCK;
392 nfssvc_nfsd = NFSSVC_NFSD;
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.
400 if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL)
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())) {
410 syslog(LOG_ERR, "fork: %m");
418 (void)signal(SIGUSR1, child_cleanup);
419 setproctitle("server");
423 } else if (tcpflag) {
425 * For TCP mode, we fork once to start the first
426 * kernel nfsd thread. The kernel will add more
431 syslog(LOG_ERR, "fork: %m");
437 (void)signal(SIGUSR1, child_cleanup);
438 setproctitle("server");
443 (void)signal(SIGUSR1, cleanup);
449 /* Set up the socket for udp and rpcb register it. */
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) {
461 if ((sock = socket(ai_udp->ai_family,
463 ai_udp->ai_protocol)) < 0) {
465 "can't create udp socket");
468 if (bind(sock, ai_udp->ai_addr,
469 ai_udp->ai_addrlen) < 0) {
471 "can't bind udp addr %s: %m",
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");
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);
494 syslog(LOG_ERR, "getaddrinfo udp: %s",
495 gai_strerror(ecode));
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);
510 /* Set up the socket for udp6 and rpcb register it. */
511 if (udpflag && ip6flag) {
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) {
522 if ((sock = socket(ai_udp6->ai_family,
523 ai_udp6->ai_socktype,
524 ai_udp6->ai_protocol)) < 0) {
526 "can't create udp6 socket");
529 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
530 &on, sizeof on) < 0) {
532 "can't set v6-only binding for "
536 if (bind(sock, ai_udp6->ai_addr,
537 ai_udp6->ai_addrlen) < 0) {
539 "can't bind udp6 addr %s: %m",
543 freeaddrinfo(ai_udp6);
544 addsockargs.sock = sock;
545 addsockargs.name = NULL;
546 addsockargs.namelen = 0;
547 if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
549 "can't add UDP6 socket");
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);
563 syslog(LOG_ERR, "getaddrinfo udp6: %s",
564 gai_strerror(ecode));
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);
579 /* Set up the socket for tcp and rpcb register it. */
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) {
591 if ((tcpsock = socket(AF_INET, SOCK_STREAM,
594 "can't create tcp socket");
597 if (setsockopt(tcpsock, SOL_SOCKET,
599 (char *)&on, sizeof(on)) < 0)
601 "setsockopt SO_REUSEADDR: %m");
602 if (bind(tcpsock, ai_tcp->ai_addr,
603 ai_tcp->ai_addrlen) < 0) {
605 "can't bind tcp addr %s: %m",
609 if (listen(tcpsock, 5) < 0) {
610 syslog(LOG_ERR, "listen failed");
613 freeaddrinfo(ai_tcp);
614 FD_SET(tcpsock, &sockbits);
615 FD_SET(tcpsock, &v4bits);
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,
629 syslog(LOG_ERR, "getaddrinfo tcp: %s",
630 gai_strerror(ecode));
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);
646 /* Set up the socket for tcp6 and rpcb register it. */
647 if (tcpflag && ip6flag) {
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) {
658 if ((tcp6sock = socket(ai_tcp6->ai_family,
659 ai_tcp6->ai_socktype,
660 ai_tcp6->ai_protocol)) < 0) {
662 "can't create tcp6 socket");
665 if (setsockopt(tcp6sock, SOL_SOCKET,
667 (char *)&on, sizeof(on)) < 0)
669 "setsockopt SO_REUSEADDR: %m");
670 if (setsockopt(tcp6sock, IPPROTO_IPV6,
671 IPV6_V6ONLY, &on, sizeof on) < 0) {
673 "can't set v6-only binding for tcp6 "
677 if (bind(tcp6sock, ai_tcp6->ai_addr,
678 ai_tcp6->ai_addrlen) < 0) {
680 "can't bind tcp6 addr %s: %m",
684 if (listen(tcp6sock, 5) < 0) {
685 syslog(LOG_ERR, "listen failed");
688 freeaddrinfo(ai_tcp6);
689 FD_SET(tcp6sock, &sockbits);
690 FD_SET(tcp6sock, &v6bits);
691 if (maxsock < tcp6sock)
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);
704 syslog(LOG_ERR, "getaddrinfo tcp6: %s",
705 gai_strerror(ecode));
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);
720 if (rpcbregcnt == 0) {
721 syslog(LOG_ERR, "rpcb_set() failed, nothing to do: %m");
725 if (tcpflag && connect_type_cnt == 0) {
726 syslog(LOG_ERR, "tcp connects == 0, nothing to do: %m");
730 setproctitle("master");
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.
742 * Loop forever accepting connections and passing the sockets
743 * into the kernel for the mounts.
747 if (connect_type_cnt > 1) {
748 if (select(maxsock + 1,
749 &ready, NULL, NULL, NULL) < 1) {
753 syslog(LOG_ERR, "select failed: %m");
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) {
764 syslog(LOG_ERR, "accept failed: %m");
765 if (error == ECONNABORTED ||
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)
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,
788 "accept failed: %m");
789 if (error == ECONNABORTED ||
794 if (setsockopt(msgsock, SOL_SOCKET,
795 SO_KEEPALIVE, (char *)&on,
797 syslog(LOG_ERR, "setsockopt "
799 addsockargs.sock = msgsock;
800 addsockargs.name = (caddr_t)&inet6peer;
801 addsockargs.namelen = len;
802 nfssvc(nfssvc_addsock, &addsockargs);
803 (void)close(msgsock);
811 setbindhost(struct addrinfo **ai, const char *bindhost, struct addrinfo hints)
814 u_int32_t host_addr[4]; /* IPv4 or IPv6 */
817 if (bindhost == NULL || strcmp("*", bindhost) == 0)
822 if (hostptr != NULL) {
823 switch (hints.ai_family) {
825 if (inet_pton(AF_INET, hostptr, host_addr) == 1) {
826 hints.ai_flags = AI_NUMERICHOST;
828 if (inet_pton(AF_INET6, hostptr,
834 if (inet_pton(AF_INET6, hostptr, host_addr) == 1) {
835 hints.ai_flags = AI_NUMERICHOST;
837 if (inet_pton(AF_INET, hostptr,
847 ecode = getaddrinfo(hostptr, "nfs", &hints, ai);
849 syslog(LOG_ERR, "getaddrinfo %s: %s", bindhost,
850 gai_strerror(ecode));
859 (void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
864 nonfs(__unused int signo)
866 syslog(LOG_ERR, "missing system call: NFS not available");
870 reapchild(__unused int signo)
875 while ((pid = wait3(NULL, WNOHANG, NULL)) > 0) {
876 for (i = 0; i < nfsdcnt; i++)
877 if (pid == children[i])
885 if ((!rpcb_unset(NFS_PROGRAM, 2, NULL)) ||
886 (!rpcb_unset(NFS_PROGRAM, 3, NULL)))
887 syslog(LOG_ERR, "rpcb_unset failed");
895 for (i = 0; i < nfsdcnt; i++) {
897 kill(children[i], SIGKILL);
902 * Cleanup master after SIGUSR1.
905 cleanup(__unused int signo)
911 * Cleanup child after SIGUSR1.
914 child_cleanup(__unused int signo)
920 nfsd_exit(int status)
928 start_server(int master)
930 char principal[MAXHOSTNAMELEN + 5];
931 struct nfsd_nfsd_args nfsdargs;
933 char hostname[MAXHOSTNAMELEN + 1], *cp;
934 struct addrinfo *aip, hints;
938 gethostname(hostname, sizeof (hostname));
939 snprintf(principal, sizeof (principal), "nfs@%s", hostname);
940 if ((cp = strchr(hostname, '.')) == NULL ||
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);
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);
955 nfsdargs.principal = principal;
956 nfsdargs.minthreads = nfsdcnt;
957 nfsdargs.maxthreads = nfsdcnt;
958 error = nfssvc(nfssvc_nfsd, &nfsdargs);
959 if (error < 0 && errno == EAUTH) {
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)
966 syslog(LOG_ERR, "No gssd, using AUTH_SYS only");
968 error = nfssvc(nfssvc_nfsd, &nfsdargs);
971 syslog(LOG_ERR, "nfssvc: %m");
975 if (nfssvc(NFSSVC_OLDNFSD, NULL) < 0) {
976 syslog(LOG_ERR, "nfssvc: %m");
987 * Open the stable restart file and return the file descriptor for it.
990 open_stable(int *stable_fdp, int *backup_fdp)
992 int stable_fd, backup_fd = -1, ret;
993 struct stat st, backup_st;
995 /* Open and stat the stable restart file. */
996 stable_fd = open(NFSD_STABLERESTART, O_RDWR, 0);
998 stable_fd = open(NFSD_STABLERESTART, O_RDWR | O_CREAT, 0600);
999 if (stable_fd >= 0) {
1000 ret = fstat(stable_fd, &st);
1007 /* Open and stat the backup stable restart file. */
1008 if (stable_fd >= 0) {
1009 backup_fd = open(NFSD_STABLEBACKUP, O_RDWR, 0);
1011 backup_fd = open(NFSD_STABLEBACKUP, O_RDWR | O_CREAT,
1013 if (backup_fd >= 0) {
1014 ret = fstat(backup_fd, &backup_st);
1020 if (backup_fd < 0) {
1026 *stable_fdp = stable_fd;
1027 *backup_fdp = backup_fd;
1031 /* Sync up the 2 files, as required. */
1033 copy_stable(stable_fd, backup_fd);
1034 else if (backup_st.st_size > 0)
1035 copy_stable(backup_fd, stable_fd);
1039 * Copy the stable restart file to the backup or vice versa.
1042 copy_stable(int from_fd, int to_fd)
1045 static char buf[1024];
1047 ret = lseek(from_fd, (off_t)0, SEEK_SET);
1049 ret = lseek(to_fd, (off_t)0, SEEK_SET);
1051 ret = ftruncate(to_fd, (off_t)0);
1054 cnt = read(from_fd, buf, 1024);
1056 ret = write(to_fd, buf, cnt);
1059 } while (cnt > 0 && ret >= 0);
1063 syslog(LOG_ERR, "stable restart copy failure: %m");
1067 * Back up the stable restart file when indicated by the kernel.
1070 backup_stable(__unused int signo)
1074 copy_stable(stablefd, backupfd);