]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
Add support for suppressing different NFS versions.
authorSteve Dickson <SteveD@redhat.com>
Mon, 26 Jun 2006 05:23:19 +0000 (15:23 +1000)
committerNeil Brown <neilb@suse.de>
Mon, 26 Jun 2006 05:23:19 +0000 (15:23 +1000)
e.g.  -N 2
means that NFSv2 won't be supported, just v3 and v4 (if the kernel
supports them).

support/include/nfs/nfs.h
support/include/nfslib.h
support/nfs/nfssvc.c
utils/nfsd/nfsd.c
utils/nfsd/nfsd.man

index c7fc42cb8be55f6d1106d3449fed7d3b1f21477d..2cf6857ba5ef8729a9da5486ebd588e8051bb0c3 100644 (file)
@@ -10,6 +10,9 @@
 #define        NFS3_FHSIZE     64
 #define        NFS_FHSIZE      32
 
 #define        NFS3_FHSIZE     64
 #define        NFS_FHSIZE      32
 
+#define NFSD_MINVERS 2
+#define NFSD_MAXVERS 4
+
 struct nfs_fh_len {
        int             fh_size;
        u_int8_t        fh_handle[NFS3_FHSIZE];
 struct nfs_fh_len {
        int             fh_size;
        u_int8_t        fh_handle[NFS3_FHSIZE];
@@ -40,7 +43,11 @@ struct nfs_fh_old {
 #define NFSCTL_LOCKD           0x10000
 #define LOCKDCTL_SVC           NFSCTL_LOCKD
 
 #define NFSCTL_LOCKD           0x10000
 #define LOCKDCTL_SVC           NFSCTL_LOCKD
 
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) 
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1))) 
 
 
+#define NFSCTL_ALLBITS (~0)
 
 /* SVC */
 struct nfsctl_svc {
 
 /* SVC */
 struct nfsctl_svc {
index 8c832622dd052dce0f98a03d04c01aa0884cd19a..50892e22b0d3fe0874887df1b8606c284d34cedd 100644 (file)
@@ -120,7 +120,7 @@ int                 wildmat(char *text, char *pattern);
  * nfsd library functions.
  */
 int                    nfsctl(int, struct nfsctl_arg *, union nfsctl_res *);
  * nfsd library functions.
  */
 int                    nfsctl(int, struct nfsctl_arg *, union nfsctl_res *);
-int                    nfssvc(int port, int nrservs);
+int                    nfssvc(int port, int nrservs, unsigned int versbits);
 int                    nfsaddclient(struct nfsctl_client *clp);
 int                    nfsdelclient(struct nfsctl_client *clp);
 int                    nfsexport(struct nfsctl_export *exp);
 int                    nfsaddclient(struct nfsctl_client *clp);
 int                    nfsdelclient(struct nfsctl_client *clp);
 int                    nfsexport(struct nfsctl_export *exp);
index 38240a020f190ffbe12c5591752929e1c6baed30..c51ace18ea078c223aa597afb4637b9fbd1663a1 100644 (file)
 
 #include <unistd.h>
 #include <fcntl.h>
 
 #include <unistd.h>
 #include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
 
 #include "nfslib.h"
 
 
 #include "nfslib.h"
 
+static void
+nfssvc_versbits(unsigned int ctlbits)
+{
+       int fd, n, off;
+       char buf[BUFSIZ], *ptr;
+
+       ptr = buf;
+       off = 0;
+       fd = open("/proc/fs/nfsd/versions", O_WRONLY);
+       if (fd < 0)
+               return;
+
+       for (n = NFSD_MINVERS; n <= NFSD_MAXVERS; n++) {
+               if (NFSCTL_VERISSET(ctlbits, n))
+                   off += snprintf(ptr+off, BUFSIZ - off, "+%d ", n);
+               else
+                   off += snprintf(ptr+off, BUFSIZ - off, "-%d ", n);
+       }
+       snprintf(ptr+off, BUFSIZ - off, "\n");
+       if (write(fd, buf, strlen(buf)) != strlen(buf)) {
+               syslog(LOG_ERR, "nfssvc: Setting version failed: errno %d (%s)", 
+                       errno, strerror(errno));
+       }
+       close(fd);
+
+       return;
+}
 int
 int
-nfssvc(int port, int nrservs)
+nfssvc(int port, int nrservs, unsigned int versbits)
 {
        struct nfsctl_arg       arg;
        int fd;
 
 {
        struct nfsctl_arg       arg;
        int fd;
 
+       nfssvc_versbits(versbits);
+
        fd = open("/proc/fs/nfsd/threads", O_WRONLY);
        if (fd < 0)
                fd = open("/proc/fs/nfs/threads", O_WRONLY);
        fd = open("/proc/fs/nfsd/threads", O_WRONLY);
        if (fd < 0)
                fd = open("/proc/fs/nfs/threads", O_WRONLY);
index 05506ee4ae6c2900fbd2fb4b62749f0789424959..fa6ee71fdd6443245511a4b105df891017106905 100644 (file)
 
 static void    usage(const char *);
 
 
 static void    usage(const char *);
 
+static struct option longopts[] =
+{
+       { "help", 0, 0, 'h' },
+       { "no-nfs-version", 1, 0, 'N' },
+       { NULL, 0, 0, 0 }
+};
+unsigned int versbits = NFSCTL_ALLBITS;
+
 int
 main(int argc, char **argv)
 {
 int
 main(int argc, char **argv)
 {
-       int     count = 1, c, error, port, fd;
+       int     count = 1, c, error, port, fd, found_one;
        struct servent *ent;
 
        ent = getservbyname ("nfs", "udp");
        struct servent *ent;
 
        ent = getservbyname ("nfs", "udp");
@@ -36,7 +44,7 @@ main(int argc, char **argv)
        else
                port = 2049;
 
        else
                port = 2049;
 
-       while ((c = getopt(argc, argv, "hp:P:")) != EOF) {
+       while ((c = getopt_long(argc, argv, "hN:p:P:", longopts, NULL)) != EOF) {
                switch(c) {
                case 'P':       /* XXX for nfs-server compatibility */
                case 'p':
                switch(c) {
                case 'P':       /* XXX for nfs-server compatibility */
                case 'p':
@@ -47,12 +55,36 @@ main(int argc, char **argv)
                                usage(argv [0]);
                        }
                        break;
                                usage(argv [0]);
                        }
                        break;
+               case 'N':
+                       switch((c = atoi(optarg))) {
+                       case 2:
+                       case 3:
+                       case 4:
+                               NFSCTL_VERUNSET(versbits, c);
+                               break;
+                       default:
+                               fprintf(stderr, "%c: Unsupported version\n", c);
+                               exit(1);
+                       }
                        break;
                        break;
-               case 'h':
                default:
                default:
+                       fprintf(stderr, "Invalid argument: '%c'\n", c);
+               case 'h':
                        usage(argv[0]);
                }
        }
                        usage(argv[0]);
                }
        }
+       /*
+        * Do some sanity checking, if the ctlbits are set
+        */
+       found_one = 0;
+       for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) {
+               if (NFSCTL_VERISSET(versbits, c))
+                       found_one = 1;
+       }
+       if (!found_one) {
+               fprintf(stderr, "no version specified\n");
+               exit(1);
+       }                       
 
        if (chdir(NFS_STATEDIR)) {
                fprintf(stderr, "%s: chdir(%s) failed: %s\n",
 
        if (chdir(NFS_STATEDIR)) {
                fprintf(stderr, "%s: chdir(%s) failed: %s\n",
@@ -69,7 +101,6 @@ main(int argc, char **argv)
                        count = 1;
                }
        }
                        count = 1;
                }
        }
-
        /* KLUDGE ALERT:
           Some kernels let nfsd kernel threads inherit open files
           from the program that spawns them (i.e. us).  So close
        /* KLUDGE ALERT:
           Some kernels let nfsd kernel threads inherit open files
           from the program that spawns them (i.e. us).  So close
@@ -84,9 +115,9 @@ main(int argc, char **argv)
        }
        closeall(3);
 
        }
        closeall(3);
 
-       if ((error = nfssvc(port, count)) < 0) {
+       openlog("nfsd", LOG_PID, LOG_DAEMON);
+       if ((error = nfssvc(port, count, versbits)) < 0) {
                int e = errno;
                int e = errno;
-               openlog("nfsd", LOG_PID, LOG_DAEMON);
                syslog(LOG_ERR, "nfssvc: %s", strerror(e));
                closelog();
        }
                syslog(LOG_ERR, "nfssvc: %s", strerror(e));
                closelog();
        }
@@ -97,7 +128,8 @@ main(int argc, char **argv)
 static void
 usage(const char *prog)
 {
 static void
 usage(const char *prog)
 {
-       fprintf(stderr, "usage:\n"
-                       "%s nrservs\n", prog);
+       fprintf(stderr, "Usage:\n"
+               "%s [-p|-P|--port port] [-N|--no-nfs-version version ] nrservs\n", 
+               prog);
        exit(2);
 }
        exit(2);
 }
index a890ea6df12c8f8d8e830dcdc73b2d7df64f6370..d175d11677b8a39795e168da1ee72db0fa31e008 100644 (file)
@@ -6,7 +6,7 @@
 .SH NAME
 rpc.nfsd \- NFS server process
 .SH SYNOPSIS
 .SH NAME
 rpc.nfsd \- NFS server process
 .SH SYNOPSIS
-.BI "/usr/sbin/rpc.nfsd [-p " port "] " nproc
+.BI "/usr/sbin/rpc.nfsd [" options "]" " "nproc
 .SH DESCRIPTION
 The
 .B rpc.nfsd
 .SH DESCRIPTION
 The
 .B rpc.nfsd
@@ -22,11 +22,18 @@ server provides an ancillary service needed to satisfy mount requests
 by NFS clients.
 .SH OPTIONS
 .TP
 by NFS clients.
 .SH OPTIONS
 .TP
-.BI \-p " port"
+.B \-p " or " \-\-port  port
 specify a diferent port to listen on for NFS requests. By default,
 .B rpc.nfsd
 will listen on port 2049.
 .TP
 specify a diferent port to listen on for NFS requests. By default,
 .B rpc.nfsd
 will listen on port 2049.
 .TP
+.B \-N " or " \-\-no-nfs-version vers
+This option can be used to request that 
+.B rpc.nfsd
+does not offer certain versions of NFS. The current version of
+.B rpc.nfsd
+can support both NFS version 2,3 and the newer version 4.
+.TP
 .I nproc
 specify the number of NFS server threads. By default, just one
 thread is started. However, for optimum performance several threads
 .I nproc
 specify the number of NFS server threads. By default, just one
 thread is started. However, for optimum performance several threads