From 1e5327b6dd1aac76855e91e7e75d7ad029fc3cad Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Wed, 30 Sep 2009 00:52:00 +0000 Subject: [PATCH] - Added upstream 1.2.1-rc5 patch - mount.nfs: Support negotiation between v4, v3, and v2 - mount.nfs: Keep server's address in nfsmount_info - mount.nfs: Sandbox each mount attempt - mount.nfs: Support negotiation between v4, v3, and v2 --- nfs-utils-1.2.0-mount-vers4.patch | 31 +++ nfs-utils-1.2.1-rc6.patch | 307 ++++++++++++++++++++++++++++++ nfs-utils.spec | 13 +- 3 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 nfs-utils-1.2.0-mount-vers4.patch create mode 100644 nfs-utils-1.2.1-rc6.patch diff --git a/nfs-utils-1.2.0-mount-vers4.patch b/nfs-utils-1.2.0-mount-vers4.patch new file mode 100644 index 0000000..61bf5d5 --- /dev/null +++ b/nfs-utils-1.2.0-mount-vers4.patch @@ -0,0 +1,31 @@ +diff -up nfs-utils-1.2.0/utils/mount/nfsmount.conf.orig nfs-utils-1.2.0/utils/mount/nfsmount.conf +--- nfs-utils-1.2.0/utils/mount/nfsmount.conf.orig 2009-09-29 18:48:47.000000000 -0400 ++++ nfs-utils-1.2.0/utils/mount/nfsmount.conf 2009-09-29 19:02:06.000000000 -0400 +@@ -24,12 +24,12 @@ + # All reads and writes to the 'nfsserver.foo.com' server + # will be done with 32k (32768 bytes) block sizes. + # +-#[ NFSMount_Global_Options ] ++[ NFSMount_Global_Options ] + # This statically named section defines global mount + # options that can be applied on all NFS mount. + # +-# Protocol Version [2,3] +-# Nfsvers=3 ++# Protocol Version [2,3,4] ++#Nfsvers=3 + # Network Transport [Udp,Tcp,Rdma] + # Proto=Tcp + # +diff -up nfs-utils-1.2.0/utils/mount/stropts.c.orig nfs-utils-1.2.0/utils/mount/stropts.c +--- nfs-utils-1.2.0/utils/mount/stropts.c.orig 2009-09-29 18:48:47.000000000 -0400 ++++ nfs-utils-1.2.0/utils/mount/stropts.c 2009-09-29 19:01:10.000000000 -0400 +@@ -601,7 +601,7 @@ static int nfs_try_mount(struct nfsmount + + switch (mi->version) { + case 0: +- if (linux_version_code() > MAKE_VERSION(2, 6, 31)) { ++ if (linux_version_code() >= MAKE_VERSION(2, 6, 31)) { + errno = 0; + result = nfs_try_mount_v4(mi); + if (errno != EPROTONOSUPPORT) diff --git a/nfs-utils-1.2.1-rc6.patch b/nfs-utils-1.2.1-rc6.patch new file mode 100644 index 0000000..d8c8a3d --- /dev/null +++ b/nfs-utils-1.2.1-rc6.patch @@ -0,0 +1,307 @@ +diff --git a/utils/mount/parse_opt.c b/utils/mount/parse_opt.c +index 1dfee8a..f0918f7 100644 +--- a/utils/mount/parse_opt.c ++++ b/utils/mount/parse_opt.c +@@ -101,6 +101,37 @@ fail: + return NULL; + } + ++static struct mount_option *option_dup(const struct mount_option *option) ++{ ++ struct mount_option *new; ++ ++ new = malloc(sizeof(*new)); ++ if (!new) ++ return NULL; ++ ++ new->next = NULL; ++ new->prev = NULL; ++ ++ new->keyword = strdup(option->keyword); ++ if (!new->keyword) ++ goto fail; ++ ++ new->value = NULL; ++ if (option->value) { ++ new->value = strdup(option->value); ++ if (!new->value) { ++ free(new->keyword); ++ goto fail; ++ } ++ } ++ ++ return new; ++ ++fail: ++ free(new); ++ return NULL; ++} ++ + static void option_destroy(struct mount_option *option) + { + free(option->keyword); +@@ -229,6 +260,40 @@ fail: + } + + /** ++ * po_dup - duplicate an existing list of options ++ * @options: pointer to mount options ++ * ++ */ ++struct mount_options *po_dup(struct mount_options *source) ++{ ++ struct mount_options *target; ++ struct mount_option *current; ++ ++ if (!source) ++ return NULL; ++ ++ target = options_create(); ++ if (options_empty(source) || target == NULL) ++ return target; ++ ++ current = source->head; ++ while (target->count < source->count) { ++ struct mount_option *option; ++ ++ option = option_dup(current); ++ if (!option) { ++ po_destroy(target); ++ return NULL; ++ } ++ ++ options_tail_insert(target, option); ++ current = current->next; ++ } ++ ++ return target; ++} ++ ++/** + * po_replace - replace mount options in one mount_options object with another + * @target: pointer to previously instantiated object to replace + * @source: pointer to object containing source mount options +diff --git a/utils/mount/parse_opt.h b/utils/mount/parse_opt.h +index f9243c3..2c0b5f4 100644 +--- a/utils/mount/parse_opt.h ++++ b/utils/mount/parse_opt.h +@@ -38,6 +38,7 @@ typedef enum { + struct mount_options; + + struct mount_options * po_split(char *); ++struct mount_options * po_dup(struct mount_options *); + void po_replace(struct mount_options *, + struct mount_options *); + po_return_t po_join(struct mount_options *, char **); +diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c +index 3eb661e..069bdc1 100644 +--- a/utils/mount/stropts.c ++++ b/utils/mount/stropts.c +@@ -80,6 +80,8 @@ struct nfsmount_info { + *node, /* mounted-on dir */ + *type; /* "nfs" or "nfs4" */ + char *hostname; /* server's hostname */ ++ struct sockaddr_storage address; /* server's address */ ++ socklen_t salen; /* size of server's address */ + + struct mount_options *options; /* parsed mount options */ + char **extra_opts; /* string for /etc/mtab */ +@@ -257,47 +259,35 @@ static int nfs_append_sloppy_option(struct mount_options *options) + } + + /* +- * Set up mandatory NFS mount options. ++ * Set up mandatory non-version specific NFS mount options. + * + * Returns 1 if successful; otherwise zero. + */ + static int nfs_validate_options(struct nfsmount_info *mi) + { +- struct sockaddr_storage dummy; +- struct sockaddr *sap = (struct sockaddr *)&dummy; +- socklen_t salen = sizeof(dummy); ++ struct sockaddr *sap = (struct sockaddr *)&mi->address; + + if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL)) + return 0; + +- if (!nfs_name_to_address(mi->hostname, sap, &salen)) ++ mi->salen = sizeof(mi->address); ++ if (!nfs_name_to_address(mi->hostname, sap, &mi->salen)) + return 0; + + if (!nfs_nfs_version(mi->options, &mi->version)) + return 0; + if (strncmp(mi->type, "nfs4", 4) == 0) + mi->version = 4; +- +- if (mi->version == 4) { +- if (!nfs_append_clientaddr_option(sap, salen, mi->options)) +- return 0; +- } else { +- if (!nfs_fix_mounthost_option(mi->options)) +- return 0; +- if (!mi->fake && !nfs_verify_lock_option(mi->options)) +- return 0; ++ else { ++ char *option = po_get(mi->options, "proto"); ++ if (option && strcmp(option, "rdma") == 0) ++ mi->version = 3; + } + + if (!nfs_append_sloppy_option(mi->options)) + return 0; + +- if (!nfs_append_addr_option(sap, salen, mi->options)) +- return 0; +- +- /* +- * Update option string to be recorded in /etc/mnttab +- */ +- if (po_join(mi->options, mi->extra_opts) == PO_FAILED) ++ if (!nfs_append_addr_option(sap, mi->salen, mi->options)) + return 0; + + return 1; +@@ -489,17 +479,12 @@ out: + * Returns TRUE if successful, otherwise FALSE. + * "errno" is set to reflect the individual error. + */ +-static int nfs_try_mount(struct nfsmount_info *mi) ++static int nfs_sys_mount(struct nfsmount_info *mi, struct mount_options *opts) + { + char *options = NULL; + int result; + +- if (mi->version != 4) { +- if (!nfs_rewrite_pmap_mount_options(mi->options)) +- return 0; +- } +- +- if (po_join(mi->options, &options) == PO_FAILED) { ++ if (po_join(opts, &options) == PO_FAILED) { + errno = EIO; + return 0; + } +@@ -522,6 +507,121 @@ static int nfs_try_mount(struct nfsmount_info *mi) + } + + /* ++ * For "-t nfs vers=2" or "-t nfs vers=3" mounts. ++ */ ++static int nfs_try_mount_v3v2(struct nfsmount_info *mi) ++{ ++ struct mount_options *options = po_dup(mi->options); ++ int result = 0; ++ ++ if (!options) { ++ errno = ENOMEM; ++ return result; ++ } ++ ++ if (!nfs_fix_mounthost_option(options)) { ++ errno = EINVAL; ++ goto out_fail; ++ } ++ if (!mi->fake && !nfs_verify_lock_option(options)) { ++ errno = EINVAL; ++ goto out_fail; ++ } ++ ++ /* ++ * Options we negotiate below may be stale by the time this ++ * file system is unmounted. In order to force umount.nfs ++ * to renegotiate with the server, only write the user- ++ * specified options, and not negotiated options, to /etc/mtab. ++ */ ++ if (po_join(options, mi->extra_opts) == PO_FAILED) { ++ errno = ENOMEM; ++ goto out_fail; ++ } ++ ++ if (!nfs_rewrite_pmap_mount_options(options)) ++ goto out_fail; ++ ++ result = nfs_sys_mount(mi, options); ++ ++out_fail: ++ po_destroy(options); ++ return result; ++} ++ ++/* ++ * For "-t nfs -o vers=4" or "-t nfs4" mounts. ++ */ ++static int nfs_try_mount_v4(struct nfsmount_info *mi) ++{ ++ struct sockaddr *sap = (struct sockaddr *)&mi->address; ++ struct mount_options *options = po_dup(mi->options); ++ int result = 0; ++ ++ if (!options) { ++ errno = ENOMEM; ++ return result; ++ } ++ ++ if (mi->version == 0) { ++ if (po_append(options, "vers=4") == PO_FAILED) { ++ errno = EINVAL; ++ goto out_fail; ++ } ++ } ++ ++ if (!nfs_append_clientaddr_option(sap, mi->salen, options)) { ++ errno = EINVAL; ++ goto out_fail; ++ } ++ /* ++ * Update option string to be recorded in /etc/mtab. ++ */ ++ if (po_join(options, mi->extra_opts) == PO_FAILED) { ++ errno = ENOMEM; ++ return 0; ++ } ++ ++ result = nfs_sys_mount(mi, options); ++ ++out_fail: ++ po_destroy(options); ++ return result; ++} ++ ++/* ++ * This is a single pass through the fg/bg loop. ++ * ++ * Returns TRUE if successful, otherwise FALSE. ++ * "errno" is set to reflect the individual error. ++ */ ++static int nfs_try_mount(struct nfsmount_info *mi) ++{ ++ int result = 0; ++ ++ switch (mi->version) { ++ case 0: ++ if (linux_version_code() > MAKE_VERSION(2, 6, 31)) { ++ errno = 0; ++ result = nfs_try_mount_v4(mi); ++ if (errno != EPROTONOSUPPORT) ++ break; ++ } ++ case 2: ++ case 3: ++ result = nfs_try_mount_v3v2(mi); ++ break; ++ case 4: ++ result = nfs_try_mount_v4(mi); ++ break; ++ default: ++ errno = EIO; ++ } ++ ++ return result; ++} ++ ++/* + * Distinguish between permanent and temporary errors. + * + * Basically, we retry if communication with the server has diff --git a/nfs-utils.spec b/nfs-utils.spec index db50685..2019024 100644 --- a/nfs-utils.spec +++ b/nfs-utils.spec @@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser Name: nfs-utils URL: http://sourceforge.net/projects/nfs Version: 1.2.0 -Release: 12%{?dist} +Release: 13%{?dist} Epoch: 1 # group all 32bit related archs @@ -27,6 +27,8 @@ Patch101: nfs-utils-1.2.1-rc2.patch Patch102: nfs-utils-1.2.1-rc3.patch Patch103: nfs-utils-1.2.1-rc4.patch Patch104: nfs-utils-1.2.1-rc5.patch +Patch105: nfs-utils-1.2.1-rc6.patch +Patch106: nfs-utils-1.2.0-mount-vers4.patch Patch200: nfs-utils-1.2.0-v4root-rel6.patch @@ -85,6 +87,8 @@ This package also contains the mount.nfs and umount.nfs program. %patch102 -p1 %patch103 -p1 %patch104 -p1 +%patch105 -p1 +%patch106 -p1 %patch200 -p1 @@ -258,6 +262,13 @@ fi %attr(4755,root,root) /sbin/umount.nfs4 %changelog +* Tue Sep 29 2009 Steve Dickson 1.2.0-13 +- Added upstream 1.2.1-rc5 patch + - mount.nfs: Support negotiation between v4, v3, and v2 + - mount.nfs: Keep server's address in nfsmount_info + - mount.nfs: Sandbox each mount attempt + - mount.nfs: Support negotiation between v4, v3, and v2 + * Wed Sep 23 2009 Steve Dickson 1.2.0-12 - Updated to the latest pseudo root release (rel6).