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 _at__at_ -48,6 +48,7 _at__at_ #include <sys/syslog.h> #include <sys/wait.h> #include <sys/mount.h> +#include <sys/fcntl.h> #include <sys/linker.h> #include <sys/module.h> _at__at_ -59,6 +60,7 _at__at_ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsserver/nfs.h> +#include <nfs/nfssvc.h> #include <err.h> #include <errno.h> _at__at_ -77,11 +79,14 _at__at_ 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); _at__at_ -112,6 +117,7 _at__at_ * -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 _at__at_ -131,20 +137,15 _at__at_ 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': _at__at_ -179,6 +180,9 _at__at_ case 'u': udpflag = 1; break; + case '4': + run_v4server = 1; + break; default: case '?': usage(); _at__at_ -203,6 +207,25 _at__at_ } } + /* + * 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) { _at__at_ -328,15 +351,47 _at__at_ 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. */ _at__at_ -413,7 +468,7 _at__at_ 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); } _at__at_ -481,7 +536,7 _at__at_ 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); _at__at_ -711,7 +766,7 _at__at_ 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); _at__at_ -733,7 +788,7 _at__at_ addsockargs.sock = msgsock; addsockargs.name = (caddr_t)&inet6peer; addsockargs.namelen = len; - nfssvc(NFSSVC_ADDSOCK, &addsockargs); + nfssvc(nfssvc_addsock, &addsockargs); (void)close(msgsock); } } _at__at_ -861,19 +916,47 _at__at_ 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_at_%s", hostname); + gethostname(hostname, sizeof (hostname)); + snprintf(principal, sizeof (principal), "nfs_at_%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_at_%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; }Received on Thu May 21 2009 - 14:19:32 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:48 UTC