Date: Thu, 21 May 2009 11:51:09 -0400 (EDT) From: Rick Macklem <rmacklem@uoguelph.ca> To: freebsd-current@freebsd.org Subject: review of changes to nfsd.c to add experimental server support Message-ID: <Pine.GSO.4.63.0905211147310.6233@muncher.cs.uoguelph.ca>
next in thread | raw e-mail | index | archive | help
In case anyone is interested in reviewing them, here are the changes I've proposed to src/usr.sbin/nfsd.c so that it supports the experimental server which handles nfsv4 as well as nfsv2,3 along with the regular server. It uses the experimental server if it is the only one loaded into the kernel or the "-4" option is specified on the command line. Thanks in advance for any comments, rick --- diff -u nfsd.c --- --- freebsd-svn/usr-src/usr.sbin/nfsd/nfsd.c 2009-05-17 15:59:55.000000000 -0400 +++ usr-src/usr.sbin/nfsd/nfsd.c 2009-05-21 11:33:32.000000000 -0400 @@ -48,6 +48,7 @@ #include <sys/syslog.h> #include <sys/wait.h> #include <sys/mount.h> +#include <sys/fcntl.h> #include <sys/linker.h> #include <sys/module.h> @@ -59,6 +60,7 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsserver/nfs.h> +#include <nfs/nfssvc.h> #include <err.h> #include <errno.h> @@ -77,11 +79,14 @@ int debug = 0; #endif +#define NFSD_STABLERESTART "/var/db/stablerestart" #define MAXNFSDCNT 256 #define DEFNFSDCNT 4 pid_t children[MAXNFSDCNT]; /* PIDs of children */ int nfsdcnt; /* number of children */ int new_syscall; +int run_v4server = 0; /* Force running of nfsv4 server */ +int nfssvc_nfsd; /* Set to correct NFSSVC_xxx flag */ void cleanup(int); void child_cleanup(int); @@ -112,6 +117,7 @@ * -d - unregister with rpcbind * -t - support tcp nfs clients * -u - support udp nfs clients + * -4 - forces it to run a server that supports nfsv4 * followed by "n" which is the number of nfsds' to fork off */ int @@ -131,20 +137,15 @@ int tcp6sock, ip6flag, tcpflag, tcpsock; int udpflag, ecode, s, srvcnt; int bindhostc, bindanyflag, rpcbreg, rpcbregcnt; + int stablefd, nfssvc_addsock; char **bindhost = NULL; pid_t pid; - if (modfind("nfsserver") < 0) { - /* Not present in kernel, try loading it */ - if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0) - errx(1, "NFS server is not available"); - } - nfsdcnt = DEFNFSDCNT; unregister = reregister = tcpflag = maxsock = 0; bindanyflag = udpflag = connect_type_cnt = bindhostc = 0; -#define GETOPT "ah:n:rdtu" -#define USAGE "[-ardtu] [-n num_servers] [-h bindip]" +#define GETOPT "ah:n:rdtu4" +#define USAGE "[-ardtu4] [-n num_servers] [-h bindip]" while ((ch = getopt(argc, argv, GETOPT)) != -1) switch (ch) { case 'a': @@ -179,6 +180,9 @@ case 'u': udpflag = 1; break; + case '4': + run_v4server = 1; + break; default: case '?': usage(); @@ -203,6 +207,25 @@ } } + /* + * If the "-4" option was specified OR only the nfsd module is + * found in the server, run "nfsd". + * Otherwise, try and run "nfsserver". + */ + if (run_v4server > 0) { + if (modfind("nfsd") < 0) { + /* Not present in kernel, try loading it */ + if (kldload("nfsd") < 0 || modfind("nfsd") < 0) + errx(1, "NFS server is not available"); + } + } else if (modfind("nfsserver") < 0 && modfind("nfsd") >= 0) { + run_v4server = 1; + } else if (modfind("nfsserver") < 0) { + /* Not present in kernel, try loading it */ + if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0) + errx(1, "NFS server is not available"); + } + ip6flag = 1; s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (s == -1) { @@ -328,15 +351,47 @@ openlog("nfsd", LOG_PID, LOG_DAEMON); /* - * Figure out if the kernel supports the new-style - * NFSSVC_NFSD. Old kernels will return ENXIO because they - * don't recognise the flag value, new ones will return EINVAL - * because argp is NULL. + * For V4, we open the stablerestart file and call nfssvc() + * to get it loaded. This is done before the daemons do the + * regular nfssvc() call to service NFS requests. + * (This way the file remains open until the last nfsd is killed + * off.) + * Note that this file is not created by this daemon and can + * only be relocated by recompiling the daemon, in order to + * minimize accidentally starting up with the wrong file. + * If should be created as an empty file Read and Write for + * root before the first time you run NFS v4 and should never + * be re-initialized if at all possible. It should live on a + * local, non-volatile storage device that does not do hardware + * level write-back caching. (See SCSI doc for more information + * on how to prevent write-back caching on SCSI disks.) */ - new_syscall = FALSE; - if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL) + if (run_v4server > 0) { + stablefd = open(NFSD_STABLERESTART, O_RDWR, 0); + if (stablefd < 0) { + syslog(LOG_ERR, "Can't open %s\n", NFSD_STABLERESTART); + exit(1); + } + if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) { + syslog(LOG_ERR, "Can't read stable storage file\n"); + exit(1); + } + nfssvc_addsock = NFSSVC_NFSDADDSOCK; + nfssvc_nfsd = NFSSVC_NFSDNFSD; new_syscall = TRUE; - new_syscall = FALSE; + } else { + nfssvc_addsock = NFSSVC_ADDSOCK; + nfssvc_nfsd = NFSSVC_NFSD; + /* + * Figure out if the kernel supports the new-style + * NFSSVC_NFSD. Old kernels will return ENXIO because they + * don't recognise the flag value, new ones will return EINVAL + * because argp is NULL. + */ + new_syscall = FALSE; + if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL) + new_syscall = TRUE; + } if (!new_syscall) { /* If we use UDP only, we start the last server below. */ @@ -413,7 +468,7 @@ addsockargs.sock = sock; addsockargs.name = NULL; addsockargs.namelen = 0; - if (nfssvc(NFSSVC_ADDSOCK, &addsockargs) < 0) { + if (nfssvc(nfssvc_addsock, &addsockargs) < 0) { syslog(LOG_ERR, "can't Add UDP socket"); nfsd_exit(1); } @@ -481,7 +536,7 @@ addsockargs.sock = sock; addsockargs.name = NULL; addsockargs.namelen = 0; - if (nfssvc(NFSSVC_ADDSOCK, &addsockargs) < 0) { + if (nfssvc(nfssvc_addsock, &addsockargs) < 0) { syslog(LOG_ERR, "can't add UDP6 socket"); nfsd_exit(1); @@ -711,7 +766,7 @@ addsockargs.sock = msgsock; addsockargs.name = (caddr_t)&inetpeer; addsockargs.namelen = len; - nfssvc(NFSSVC_ADDSOCK, &addsockargs); + nfssvc(nfssvc_addsock, &addsockargs); (void)close(msgsock); } else if (FD_ISSET(tcpsock, &v6bits)) { len = sizeof(inet6peer); @@ -733,7 +788,7 @@ addsockargs.sock = msgsock; addsockargs.name = (caddr_t)&inet6peer; addsockargs.namelen = len; - nfssvc(NFSSVC_ADDSOCK, &addsockargs); + nfssvc(nfssvc_addsock, &addsockargs); (void)close(msgsock); } } @@ -861,19 +916,47 @@ void start_server(int master) { - char principal[128]; - char hostname[128]; + char principal[MAXHOSTNAMELEN + 5]; struct nfsd_nfsd_args nfsdargs; - int status; + int status, error; + char hostname[MAXHOSTNAMELEN + 1], *cp; + struct addrinfo *aip, hints; status = 0; if (new_syscall) { - gethostname(hostname, sizeof(hostname)); - snprintf(principal, sizeof(principal), "nfs@%s", hostname); + gethostname(hostname, sizeof (hostname)); + snprintf(principal, sizeof (principal), "nfs@%s", hostname); + if ((cp = strchr(hostname, '.')) == NULL || + *(cp + 1) == '\0') { + /* If not fully qualified, try getaddrinfo() */ + memset((void *)&hints, 0, sizeof (hints)); + hints.ai_flags = AI_CANONNAME; + error = getaddrinfo(hostname, NULL, &hints, &aip); + if (error == 0) { + if (aip->ai_canonname != NULL && + (cp = strchr(aip->ai_canonname, '.')) != + NULL && *(cp + 1) != '\0') + snprintf(principal, sizeof (principal), + "nfs@%s", aip->ai_canonname); + freeaddrinfo(aip); + } + } nfsdargs.principal = principal; nfsdargs.minthreads = nfsdcnt; nfsdargs.maxthreads = nfsdcnt; - if (nfssvc(NFSSVC_NFSD, &nfsdargs) < 0) { + error = nfssvc(nfssvc_nfsd, &nfsdargs); + if (error < 0 && errno == EAUTH) { + /* + * This indicates that it could not register the + * rpcsec_gss credentials, usually because the + * gssd daemon isn't running. + * (only the experimental server with nfsv4) + */ + syslog(LOG_ERR, "No gssd, using AUTH_SYS only"); + principal[0] = '\0'; + error = nfssvc(nfssvc_nfsd, &nfsdargs); + } + if (error < 0) { syslog(LOG_ERR, "nfssvc: %m"); status = 1; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.63.0905211147310.6233>