X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fnfsd%2Fnfssvc.c;h=683008e291c6bff1016b365789d3401b5380604c;hp=34c67ca11b927ff6201e2d6b61a2e9c8c605ae7b;hb=014e00dfaea0efc92150e2aedc5ca43aa337545e;hpb=b594ee2b2a1b9c0c5823a7af279488f113f91be4 diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c index 34c67ca..683008e 100644 --- a/utils/nfsd/nfssvc.c +++ b/utils/nfsd/nfssvc.c @@ -15,25 +15,22 @@ #include #include #include +#include #include #include #include +#include #include "nfslib.h" #include "xlog.h" -/* - * IPv6 support for nfsd was finished before some of the other daemons (mountd - * and statd in particular). That could be a problem in the future if someone - * were to boot a kernel that supports IPv6 serving with an older nfs-utils. For - * now, hardcode the IPv6 switch into the off position until the other daemons - * are functional. - */ -#undef IPV6_SUPPORTED +#ifndef NFSD_FS_DIR +#define NFSD_FS_DIR "/proc/fs/nfsd" +#endif -#define NFSD_PORTS_FILE "/proc/fs/nfsd/portlist" -#define NFSD_VERS_FILE "/proc/fs/nfsd/versions" -#define NFSD_THREAD_FILE "/proc/fs/nfsd/threads" +#define NFSD_PORTS_FILE NFSD_FS_DIR "/portlist" +#define NFSD_VERS_FILE NFSD_FS_DIR "/versions" +#define NFSD_THREAD_FILE NFSD_FS_DIR "/threads" /* * declaring a common static scratch buffer here keeps us from having to @@ -43,6 +40,46 @@ */ char buf[128]; +/* + * Using the "new" interfaces for nfsd requires that /proc/fs/nfsd is + * actually mounted. Make an attempt to mount it here if it doesn't appear + * to be. If the mount attempt fails, no big deal -- fall back to using nfsctl + * instead. + */ +void +nfssvc_mount_nfsdfs(char *progname) +{ + int err; + struct stat statbuf; + + err = stat(NFSD_THREAD_FILE, &statbuf); + if (err == 0) + return; + + if (errno != ENOENT) { + xlog(L_ERROR, "Unable to stat %s: errno %d (%m)", + NFSD_THREAD_FILE, errno); + return; + } + + /* + * this call can return an error if modprobe is set up to automatically + * mount nfsdfs when nfsd.ko is plugged in. So, ignore the return + * code from it and just check for the "threads" file afterward. + */ + system("/bin/mount -t nfsd nfsd " NFSD_FS_DIR " >/dev/null 2>&1"); + + err = stat(NFSD_THREAD_FILE, &statbuf); + if (err == 0) + return; + + xlog(L_WARNING, "Unable to access " NFSD_FS_DIR " errno %d (%m)." + "\nPlease try, as root, 'mount -t nfsd nfsd " NFSD_FS_DIR + "' and then restart %s to correct the problem", errno, progname); + + return; +} + /* * Are there already sockets configured? If not, then it is safe to try to * open some and pass them through. @@ -137,8 +174,13 @@ nfssvc_setfds(const struct addrinfo *hints, const char *node, const char *port) sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (sockfd < 0) { - xlog(L_ERROR, "unable to create %s %s socket: " - "errno %d (%m)", family, proto, errno); + if (errno == EAFNOSUPPORT) + xlog(L_NOTICE, "address family %s not " + "supported by protocol %s", + family, proto); + else + xlog(L_ERROR, "unable to create %s %s socket: " + "errno %d (%m)", family, proto, errno); rc = errno; goto error; } @@ -227,7 +269,7 @@ nfssvc_set_sockets(const int family, const unsigned int protobits, } void -nfssvc_setvers(unsigned int ctlbits, int minorvers4) +nfssvc_setvers(unsigned int ctlbits, int minorvers41) { int fd, n, off; char *ptr; @@ -238,11 +280,9 @@ nfssvc_setvers(unsigned int ctlbits, int minorvers4) if (fd < 0) return; - n = minorvers4 >= 0 ? minorvers4 : -minorvers4; - if (n >= NFSD_MINMINORVERS4 && n <= NFSD_MAXMINORVERS4) - off += snprintf(ptr+off, sizeof(buf) - off, "%c4.%d ", - minorvers4 > 0 ? '+' : '-', - n); + if (minorvers41) + off += snprintf(ptr+off, sizeof(buf) - off, "%c4.1", + minorvers41 > 0 ? '+' : '-'); for (n = NFSD_MINVERS; n <= NFSD_MAXVERS; n++) { if (NFSCTL_VERISSET(ctlbits, n)) off += snprintf(ptr+off, sizeof(buf) - off, "+%d ", n);