]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
mount.nfs: Always preset nfs_mount_version
authorChuck Lever <chuck.lever@oracle.com>
Mon, 16 Jul 2007 20:28:36 +0000 (16:28 -0400)
committerNeil Brown <neilb@suse.de>
Fri, 20 Jul 2007 06:10:50 +0000 (16:10 +1000)
nfs_mount_version is a global integer that is set based on a guess
about which nfs_mount_data version is appropriate for the kernel we're
running on.

Make it always available and have the correct value before calling mount
and unmount so they don't have to worry about setting it themselves.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Neil Brown <neilb@suse.de>
utils/mount/mount.c
utils/mount/nfsmount.c
utils/mount/nfsumount.c

index 2dc0aec7ec84249460115c0997c9ab82f3d2db11..96b56973faeeb3731dcd98d74a51d216c5378fcf 100644 (file)
@@ -26,6 +26,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/mount.h>
+#include <sys/utsname.h>
 #include <getopt.h>
 #include <mntent.h>
 #include <pwd.h>
@@ -43,6 +44,7 @@
 #include "error.h"
 
 char *progname;
+int nfs_mount_data_version;
 int nomtab;
 int verbose;
 int sloppy;
@@ -128,6 +130,51 @@ static const struct opt_map opt_map[] = {
   { NULL,      0, 0, 0         }
 };
 
+#define MAKE_VERSION(p,q,r)    (65536 * (p) + 256 * (q) + (r))
+
+int linux_version_code(void)
+{
+       struct utsname my_utsname;
+       int p, q, r;
+
+       if (uname(&my_utsname) == 0) {
+               p = atoi(strtok(my_utsname.release, "."));
+               q = atoi(strtok(NULL, "."));
+               r = atoi(strtok(NULL, "."));
+               return MAKE_VERSION(p,q,r);
+       }
+       return 0;
+}
+
+/*
+ * Choose the version of the nfs_mount_data structure that is appropriate
+ * for the kernel that is doing the mount.
+ *
+ * NFS_MOUNT_VERSION:          maximum version supported by these sources
+ * nfs_mount_data_version:     maximum version supported by the running kernel
+ */
+static void discover_nfs_mount_data_version(void)
+{
+       int kernel_version = linux_version_code();
+
+       if (kernel_version) {
+               if (kernel_version < MAKE_VERSION(2, 1, 32))
+                       nfs_mount_data_version = 1;
+               else if (kernel_version < MAKE_VERSION(2, 2, 18))
+                       nfs_mount_data_version = 3;
+               else if (kernel_version < MAKE_VERSION(2, 3, 0))
+                       nfs_mount_data_version = 4;
+               else if (kernel_version < MAKE_VERSION(2, 3, 99))
+                       nfs_mount_data_version = 3;
+               else if (kernel_version < MAKE_VERSION(2, 6, 3))
+                       nfs_mount_data_version = 4;
+               else
+                       nfs_mount_data_version = 6;
+       }
+       if (nfs_mount_data_version > NFS_MOUNT_VERSION)
+               nfs_mount_data_version = NFS_MOUNT_VERSION;
+}
+
 /* Try to build a canonical options string.  */
 static char * fix_opts_string (int flags, const char *extra_opts) {
        const struct opt_map *om;
@@ -362,6 +409,8 @@ int main(int argc, char *argv[])
 
        progname = basename(argv[0]);
 
+       discover_nfs_mount_data_version();
+
        if(!strncmp(progname, "umount", strlen("umount"))) {
                if(argc < 2) {
                        umount_usage();
index 45cdcdaf1c32336c20091d09fb4a319d6fcf46d2..2747af4415e9c86755ef74b51213464795e6b25b 100644 (file)
@@ -48,7 +48,6 @@
 #include <rpc/pmap_clnt.h>
 #include <sys/socket.h>
 #include <sys/time.h>
-#include <sys/utsname.h>
 #include <sys/stat.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #define NFS_FHSIZE 32
 #endif
 
-#define MAKE_VERSION(p,q,r)    (65536*(p) + 256*(q) + (r))
-#define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
-#define MAX_MNTPROT ((nfs_mount_version >= 4) ? 3 : 2)
-#define HAVE_RELIABLE_TCP (nfs_mount_version >= 4)
+#define MAX_NFSPROT ((nfs_mount_data_version >= 4) ? 3 : 2)
+#define MAX_MNTPROT ((nfs_mount_data_version >= 4) ? 3 : 2)
+#define HAVE_RELIABLE_TCP (nfs_mount_data_version >= 4)
 
 #ifndef HAVE_INET_ATON
 #define inet_aton(a,b) (0)
@@ -93,9 +91,12 @@ typedef union {
        mnt3res_t nfsv3;
 } mntres_t;
 
+extern int nfs_mount_data_version;
 extern int verbose;
 extern int sloppy;
 
+extern int linux_version_code();
+
 /* Define the order in which to probe for UDP/TCP services */
 enum plist {
        use_tcp = 0,
@@ -144,59 +145,6 @@ mnt_probelist(const int vers)
        }
 }
 
-static int
-linux_version_code(void) {
-       struct utsname my_utsname;
-       int p, q, r;
-
-       if (uname(&my_utsname) == 0) {
-               p = atoi(strtok(my_utsname.release, "."));
-               q = atoi(strtok(NULL, "."));
-               r = atoi(strtok(NULL, "."));
-               return MAKE_VERSION(p,q,r);
-       }
-       return 0;
-}
-
-/*
- * Unfortunately, the kernel prints annoying console messages
- * in case of an unexpected nfs mount version (instead of
- * just returning some error).  Therefore we'll have to try
- * and figure out what version the kernel expects.
- *
- * Variables:
- *     NFS_MOUNT_VERSION: these nfsmount sources at compile time
- *     nfs_mount_version: version this source and running kernel can handle
- */
-int nfs_mount_version = NFS_MOUNT_VERSION;
-
-int
-find_kernel_nfs_mount_version(void) {
-       static int kernel_version = -1;
-       int mnt_version = NFS_MOUNT_VERSION;
-
-       if (kernel_version == -1)
-               kernel_version = linux_version_code();
-
-       if (kernel_version) {
-            if (kernel_version < MAKE_VERSION(2,1,32))
-                 mnt_version = 1;
-            else if (kernel_version < MAKE_VERSION(2,2,18))
-                 mnt_version = 3;
-            else if (kernel_version < MAKE_VERSION(2,3,0))
-                 mnt_version = 4; /* since 2.2.18pre9 */
-            else if (kernel_version < MAKE_VERSION(2,3,99))
-                 mnt_version = 3;
-            else if (kernel_version < MAKE_VERSION(2,6,3))
-                 mnt_version = 4;
-            else
-                 mnt_version = 6;
-       }
-       if (mnt_version > NFS_MOUNT_VERSION)
-            mnt_version = NFS_MOUNT_VERSION;
-       return mnt_version;
-}
-
 int nfs_gethostbyname(const char *, struct sockaddr_in *);
 int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
 {
@@ -554,7 +502,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                                opt = "nfsvers";
 #if NFS_MOUNT_VERSION >= 2
                        } else if (!strcmp(opt, "namlen")) {
-                               if (nfs_mount_version >= 2)
+                               if (nfs_mount_data_version >= 2)
                                        data->namlen = val;
                                else if (sloppy)
                                        continue;
@@ -578,7 +526,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
 #if NFS_MOUNT_VERSION >= 2
                                        data->flags &= ~NFS_MOUNT_TCP;
                                } else if (!strcmp(opteq+1, "tcp") &&
-                                          nfs_mount_version > 2) {
+                                          nfs_mount_data_version > 2) {
                                        nfs_pmap->pm_prot = IPPROTO_TCP;
                                        mnt_pmap->pm_prot = IPPROTO_TCP;
                                        data->flags |= NFS_MOUNT_TCP;
@@ -591,7 +539,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "sec")) {
                                char *secflavor = opteq+1;
                                /* see RFC 2623 */
-                               if (nfs_mount_version < 5) {
+                               if (nfs_mount_data_version < 5) {
                                        printf(_("Warning: ignoring sec=%s option\n"), secflavor);
                                        continue;
                                } else if (!strcmp(secflavor, "none"))
@@ -690,7 +638,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "tcp")) {
                                data->flags &= ~NFS_MOUNT_TCP;
                                if (val) {
-                                       if (nfs_mount_version < 2)
+                                       if (nfs_mount_data_version < 2)
                                                goto bad_option;
                                        nfs_pmap->pm_prot = IPPROTO_TCP;
                                        mnt_pmap->pm_prot = IPPROTO_TCP;
@@ -702,7 +650,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "udp")) {
                                data->flags &= ~NFS_MOUNT_TCP;
                                if (!val) {
-                                       if (nfs_mount_version < 2)
+                                       if (nfs_mount_data_version < 2)
                                                goto bad_option;
                                        nfs_pmap->pm_prot = IPPROTO_TCP;
                                        mnt_pmap->pm_prot = IPPROTO_TCP;
@@ -716,7 +664,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "lock")) {
                                data->flags &= ~NFS_MOUNT_NONLM;
                                if (!val) {
-                                       if (nfs_mount_version < 3)
+                                       if (nfs_mount_data_version < 3)
                                                goto bad_option;
                                        data->flags |= NFS_MOUNT_NONLM;
                                }
@@ -725,7 +673,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "broken_suid")) {
                                data->flags &= ~NFS_MOUNT_BROKEN_SUID;
                                if (val) {
-                                       if (nfs_mount_version < 4)
+                                       if (nfs_mount_data_version < 4)
                                                goto bad_option;
                                        data->flags |= NFS_MOUNT_BROKEN_SUID;
                                }
@@ -827,8 +775,6 @@ nfsmount(const char *spec, const char *node, int *flags,
        time_t prevt;
        time_t timeout;
 
-       nfs_mount_version = find_kernel_nfs_mount_version();
-
        if (strlen(spec) >= sizeof(hostdir)) {
                fprintf(stderr, _("mount: "
                                  "excessively long host:dir argument\n"));
@@ -929,7 +875,7 @@ nfsmount(const char *spec, const char *node, int *flags,
        printf("\n");
 #endif
 
-       data.version = nfs_mount_version;
+       data.version = nfs_mount_data_version;
        *mount_opts = (char *) &data;
 
        if (*flags & MS_REMOUNT)
@@ -1105,7 +1051,7 @@ noauth_flavors:
 #endif
        }
 
-       if (nfs_mount_version == 1) {
+       if (nfs_mount_data_version == 1) {
                /* create nfs socket for kernel */
                if (nfs_pmap->pm_prot == IPPROTO_TCP)
                        fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
index 81fd2640cb4e7cb695062fad5ac425f4513ea694..91d0e85627fa437c3d3d243f8b9ee3ac1a45e21e 100644 (file)
 #endif
 
 extern char *progname;
-extern int nfs_mount_version;
 extern int nomtab;
 extern int verbose;
 int force;
 int lazy;
 int remount;
 
-extern int find_kernel_nfs_mount_version(void);
 extern int probe_mntport(clnt_addr_t *);
 extern int nfs_gethostbyname(const char *, struct sockaddr_in *);
 
@@ -176,7 +174,6 @@ int _nfsumount(const char *spec, char *opts)
        struct pmap *pmap = &mnt_server.pmap;
        char *p;
 
-       nfs_mount_version = find_kernel_nfs_mount_version();
        if (spec == NULL || (p = strchr(spec,':')) == NULL)
                goto out_bad;
        hostname = xstrndup(spec, p-spec);