rpms/nfs-utils/devel nfs-utils-1.2.0-v4root-rel7.patch, NONE, 1.1 nfs-utils-1.2.1-rc7.patch, NONE, 1.1 nfs-utils.spec, 1.246, 1.247 nfs-utils-1.2.0-mntconf-negation.patch, 1.1, NONE nfs-utils-1.2.0-mntconf-vers.patch, 1.2, NONE nfs-utils-1.2.0-mount-vers4.patch, 1.2, NONE nfs-utils-1.2.0-v4root-rel6.patch, 1.1, NONE

Steve Dickson steved at fedoraproject.org
Mon Oct 26 13:26:04 UTC 2009


Author: steved

Update of /cvs/pkgs/rpms/nfs-utils/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv5172

Modified Files:
	nfs-utils.spec 
Added Files:
	nfs-utils-1.2.0-v4root-rel7.patch nfs-utils-1.2.1-rc7.patch 
Removed Files:
	nfs-utils-1.2.0-mntconf-negation.patch 
	nfs-utils-1.2.0-mntconf-vers.patch 
	nfs-utils-1.2.0-mount-vers4.patch 
	nfs-utils-1.2.0-v4root-rel6.patch 
Log Message:
- Updated to the latest pseudo root release (rel7).
- Added upstream 1.2.1-rc7 patch which fixes:
  - Stop ignoring the -o v4 option (bz 529407)
  - Allow network protocol roll backs when proto is set
    in the config file (bz 529864)


nfs-utils-1.2.0-v4root-rel7.patch:
 support/export/xtab.c        |    6 
 support/include/exportfs.h   |   11 +
 support/include/nfs/export.h |    3 
 support/include/nfslib.h     |    1 
 support/include/v4root.h     |   20 ++
 utils/mountd/Makefile.am     |    2 
 utils/mountd/auth.c          |    4 
 utils/mountd/cache.c         |   69 +++++--
 utils/mountd/v4root.c        |  414 +++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 511 insertions(+), 19 deletions(-)

--- NEW FILE nfs-utils-1.2.0-v4root-rel7.patch ---
diff -up nfs-utils-1.2.0/support/export/xtab.c.save nfs-utils-1.2.0/support/export/xtab.c
--- nfs-utils-1.2.0/support/export/xtab.c.save	2009-10-20 08:46:50.000000000 -0400
+++ nfs-utils-1.2.0/support/export/xtab.c	2009-10-20 08:47:26.000000000 -0400
@@ -19,7 +19,9 @@
 #include "exportfs.h"
 #include "xio.h"
 #include "xlog.h"
+#include "v4root.h"
 
+int v4root_needed;
 static void cond_rename(char *newfile, char *oldfile);
 
 static int
@@ -36,6 +38,8 @@ xtab_read(char *xtab, char *lockfn, int 
 	if ((lockid = xflock(lockfn, "r")) < 0)
 		return 0;
 	setexportent(xtab, "r");
+	if (is_export == 1)
+		v4root_needed = 1;
 	while ((xp = getexportent(is_export==0, 0)) != NULL) {
 		if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
 		    !(exp = export_create(xp, is_export!=1))) {
@@ -48,6 +52,8 @@ xtab_read(char *xtab, char *lockfn, int 
 		case 1:
 			exp->m_xtabent = 1;
 			exp->m_mayexport = 1;
+			if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0)
+				v4root_needed = 0;
 			break;
 		case 2:
 			exp->m_exported = -1;/* may be exported */
diff -up nfs-utils-1.2.0/support/include/exportfs.h.save nfs-utils-1.2.0/support/include/exportfs.h
--- nfs-utils-1.2.0/support/include/exportfs.h.save	2009-10-20 08:46:50.000000000 -0400
+++ nfs-utils-1.2.0/support/include/exportfs.h	2009-10-20 08:47:07.000000000 -0400
@@ -12,6 +12,17 @@
 #include <netdb.h>
 #include "nfslib.h"
 
+enum nfsd_fsid {
+	FSID_DEV = 0,
+	FSID_NUM,
+	FSID_MAJOR_MINOR,
+	FSID_ENCODE_DEV,
+	FSID_UUID4_INUM,
+	FSID_UUID8,
+	FSID_UUID16,
+	FSID_UUID16_INUM,
+};
+
 enum {
 	MCL_FQDN = 0,
 	MCL_SUBNETWORK,
diff -up nfs-utils-1.2.0/support/include/nfs/export.h.save nfs-utils-1.2.0/support/include/nfs/export.h
--- nfs-utils-1.2.0/support/include/nfs/export.h.save	2009-10-20 08:46:50.000000000 -0400
+++ nfs-utils-1.2.0/support/include/nfs/export.h	2009-10-20 08:47:07.000000000 -0400
@@ -24,6 +24,7 @@
 #define NFSEXP_FSID		0x2000
 #define	NFSEXP_CROSSMOUNT	0x4000
 #define NFSEXP_NOACL		0x8000 /* reserved for possible ACL related use */
-#define NFSEXP_ALLFLAGS		0xFFFF
+#define NFSEXP_V4ROOT       0x10000
+#define NFSEXP_ALLFLAGS		0x1FFFF
 
 #endif /* _NSF_EXPORT_H */
diff -up nfs-utils-1.2.0/support/include/nfslib.h.save nfs-utils-1.2.0/support/include/nfslib.h
--- nfs-utils-1.2.0/support/include/nfslib.h.save	2009-10-20 08:46:50.000000000 -0400
+++ nfs-utils-1.2.0/support/include/nfslib.h	2009-10-20 08:47:07.000000000 -0400
@@ -88,6 +88,7 @@ struct exportent {
 	int             e_fslocmethod;
 	char *          e_fslocdata;
 	char *		e_uuid;
+	void *		e_v4root;
 	struct sec_entry e_secinfo[SECFLAVOR_COUNT+1];
 };
 
diff -up /dev/null nfs-utils-1.2.0/support/include/v4root.h
--- /dev/null	2009-10-15 16:13:05.251004788 -0400
+++ nfs-utils-1.2.0/support/include/v4root.h	2009-10-20 08:47:16.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2009 Red Hat <nfs at redhat.com>
+ * support/include/v4root.h
+ *
+ * Support routines for dynamic pseudo roots.
+ *
+ */
+
+#ifndef V4ROOT_H
+#define V4ROOT_H
+
+extern int v4root_needed;
+
+extern struct exportent *v4root_chkroot(int , unsigned int , char *);
+extern struct exportent *v4root_export(char *, int);
+extern struct exportent *v4root_lookup(char *, nfs_export *);
+extern void v4root_free(struct exportent *);
+extern void v4root_unset(void), v4root_set(void);
+
+#endif /* V4ROOT_H */
diff -up nfs-utils-1.2.0/utils/mountd/auth.c.save nfs-utils-1.2.0/utils/mountd/auth.c
--- nfs-utils-1.2.0/utils/mountd/auth.c.save	2009-10-20 08:46:50.000000000 -0400
+++ nfs-utils-1.2.0/utils/mountd/auth.c	2009-10-20 08:47:26.000000000 -0400
@@ -20,6 +20,7 @@
 #include "exportfs.h"
 #include "mountd.h"
 #include "xmalloc.h"
+#include "v4root.h"
 
 enum auth_error
 {
@@ -98,10 +99,13 @@ auth_reload()
 		last_inode = stb.st_ino;
 	}
 
+	v4root_unset();
 	export_freeall();
 	memset(&my_client, 0, sizeof(my_client));
 	xtab_export_read();
 	check_useipaddr();
+	v4root_set();
+
 	++counter;
 
 	return counter;
diff -up nfs-utils-1.2.0/utils/mountd/cache.c.save nfs-utils-1.2.0/utils/mountd/cache.c
--- nfs-utils-1.2.0/utils/mountd/cache.c.save	2009-10-20 08:46:50.000000000 -0400
+++ nfs-utils-1.2.0/utils/mountd/cache.c	2009-10-20 08:47:21.000000000 -0400
@@ -32,23 +32,12 @@
 #include "xmalloc.h"
 #include "fsloc.h"
 #include "pseudoflavors.h"
+#include "v4root.h"
 
 #ifdef USE_BLKID
 #include "blkid/blkid.h"
 #endif
 
-
-enum nfsd_fsid {
-	FSID_DEV = 0,
-	FSID_NUM,
-	FSID_MAJOR_MINOR,
-	FSID_ENCODE_DEV,
-	FSID_UUID4_INUM,
-	FSID_UUID8,
-	FSID_UUID16,
-	FSID_UUID16_INUM,
-};
-
 /*
  * Support routines for text-based upcalls.
  * Fields are separated by spaces.
@@ -135,6 +124,8 @@ void auth_unix_gid(FILE *f)
 	if (readline(fileno(f), &lbuf, &lbuflen) != 1)
 		return;
 
+	xlog(D_CALL, "auth_unix_gid: '%s'", lbuf);
+
 	cp = lbuf;
 	if (qword_get_int(&cp, &uid) != 0)
 		return;
@@ -391,6 +382,12 @@ void nfsd_fh(FILE *f)
 
 	auth_reload();
 
+	/* Check to see if the kenel is looking for the pseudo root */
+	if ((found = v4root_chkroot(fsidtype, fsidnum, fhuuid))) {
+		found_path = strdup(found->e_path);
+		goto found;
+	}
+
 	/* Now determine export point for this fsid/domain */
 	for (i=0 ; i < MCL_MAXTYPES; i++) {
 		nfs_export *next_exp;
@@ -511,7 +508,23 @@ void nfsd_fh(FILE *f)
 		 */
 		goto out;
 	}
+	if (!found) {
+		/*
+		 * See if this is a pesudo export
+		 */
+		switch(fsidtype) {
+		case FSID_UUID4_INUM:
+		case FSID_UUID8:
+		case FSID_UUID16:
+		case FSID_UUID16_INUM:
+			found = v4root_export(fhuuid, uuidlen);
+			break;
+		}
+		if (found)
+			found_path = strdup(found->e_path);
+	}
 
+found:
 	if (found)
 		if (cache_export_ent(dom, found, found_path) < 0)
 			found = 0;
@@ -629,6 +642,7 @@ void nfsd_export(FILE *f)
 	int found_type = 0;
 	struct in_addr addr;
 	struct hostent *he = NULL;
+	struct exportent *v4root = NULL;
 
 
 	if (readline(fileno(f), &lbuf, &lbuflen) != 1)
@@ -663,10 +677,18 @@ void nfsd_export(FILE *f)
 				     path[l] == '/' &&
 				     is_mountpoint(path)))
 					/* ok */;
-				else
+				else {
+					/* See if the path is part of the psuedo root */
+					if (v4root_needed && !v4root) 
+						v4root = v4root_lookup(path, exp); 
 					continue;
-			} else if (strcmp(path, exp->m_export.e_path) != 0)
+				}
+			} else if (strcmp(path, exp->m_export.e_path) != 0) {
+				/* See if the path is part of the psuedo root */
+				if (v4root_needed && !v4root) 
+					v4root = v4root_lookup(path, exp); 
 				continue;
+			}
 			if (use_ipaddr) {
 				if (he == NULL) {
 					if (!inet_aton(dom, &addr))
@@ -705,17 +727,28 @@ void nfsd_export(FILE *f)
 	}
 
 	if (found) {
+		xlog(D_CALL, "nfsd_export: found: path %s", path);
 		if (dump_to_cache(f, dom, path, &found->m_export) < 0) {
 			xlog(L_WARNING,
 			     "Cannot export %s, possibly unsupported filesystem"
 			     " or fsid= required", path);
 			dump_to_cache(f, dom, path, NULL);
 		}
-	} else {
+	} else if (v4root) {
+		xlog(D_CALL, "nfsd_export: vroot: path %s", path);
+		dump_to_cache(f, dom, path, v4root);
+		found = (nfs_export *)v4root;
+	} else { 
 		dump_to_cache(f, dom, path, NULL);
 	}
  out:
-	xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);
+	/*
+	 * If a psuedo export was create and its not needed
+	 * free it up.
+	 */
+	if (v4root && found != (nfs_export *)v4root)
+		v4root_free(v4root);
+
 	if (dom) free(dom);
 	if (path) free(path);
 	if (he) free(he);
@@ -743,7 +776,9 @@ void cache_open(void) 
 		if (!manage_gids && cachelist[i].cache_handle == auth_unix_gid)
 			continue;
 		sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name);
-		cachelist[i].f = fopen(path, "r+");
+		if ((cachelist[i].f = fopen(path, "r+")) == NULL)
+			xlog(L_ERROR, "cache_open: Unable to open '%s': errno %d (%s)", 
+				path, errno, strerror(errno));
 	}
 }
 
diff -up nfs-utils-1.2.0/utils/mountd/Makefile.am.save nfs-utils-1.2.0/utils/mountd/Makefile.am
--- nfs-utils-1.2.0/utils/mountd/Makefile.am.save	2009-10-20 08:46:50.000000000 -0400
+++ nfs-utils-1.2.0/utils/mountd/Makefile.am	2009-10-20 08:47:16.000000000 -0400
@@ -8,7 +8,7 @@ KPREFIX		= @kprefix@
 sbin_PROGRAMS	= mountd
 
 mountd_SOURCES = mountd.c mount_dispatch.c auth.c rmtab.c cache.c \
-		 svc_run.c fsloc.c mountd.h
+		 svc_run.c fsloc.c v4root.c mountd.h
 mountd_LDADD = ../../support/export/libexport.a \
 	       ../../support/nfs/libnfs.a \
 	       ../../support/misc/libmisc.a \
diff -up /dev/null nfs-utils-1.2.0/utils/mountd/v4root.c
--- /dev/null	2009-10-15 16:13:05.251004788 -0400
+++ nfs-utils-1.2.0/utils/mountd/v4root.c	2009-10-20 08:47:33.000000000 -0400
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2009 Red Hat <nfs at redhat.com>
+ *
+ * support/export/v4root.c
+ *
+ * Routines used to support NFSv4 pseudo roots
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/queue.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <uuid/uuid.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "xlog.h"
+#include "exportfs.h"
+#include "nfslib.h"
+#include "misc.h"
+#include "v4root.h"
+
+#ifndef _PATH_PSEUDO_ROOT
+#define _PATH_PSEUDO_ROOT		"/"
+#endif
+
+#ifndef _PSEUDO_ROOT_FSID
+#define _PSEUDO_ROOT_FSID	0
+#endif
+
+extern int get_uuid(char *path, char *uuid, int uuidlen, char *u);
+
+#define HASH_TABLE_SIZE 1021
+typedef struct _hash_head {
+	TAILQ_HEAD(export_list, _exports_t) h_head;
+} hash_head;
+hash_head exports_tbl[HASH_TABLE_SIZE];
+
+typedef struct _exports_t {
+	TAILQ_ENTRY(_exports_t) list;
+	char *path;
+	hash_head *head;
+	char uuid_len;
+	char uuid[sizeof(uuid_t)];
+	struct exportent p_export;
+} exports_t;
+
+
+
+static exports_t *hash_export_lookup(char *, unsigned int);
+static void hash_export_add(struct _exports_t *, int);
+static void hash_mount_free(void);
+
+static inline unsigned int strtoint(char *str, int len)
+{
+	unsigned int n = 0;
+	int i;
+
+	for (i=0; i < len; i++)
+		n+=((int)str[i])*i;
+	return n;
+}
+static inline int hashint(unsigned int num)
+{
+	return num % HASH_TABLE_SIZE;
+}
+#define HASH(_s, _l) hashint(strtoint((_s), (_l)))
+void v4root_set(void);
+void v4root_unset(void);
+static int v4root_support(void);
+
+static struct exportent *v4root_create(char *, nfs_export *);
+
+int v4root_needed;
+
+static nfs_export pr_export = {
+	.m_next = NULL,
+	.m_client = NULL,
+	.m_export = {
+		.e_hostname = "*",
+		.e_path = _PATH_PSEUDO_ROOT,
+		.e_flags = NFSEXP_READONLY | NFSEXP_ROOTSQUASH
+				| NFSEXP_NOSUBTREECHECK | NFSEXP_FSID
+				| NFSEXP_CROSSMOUNT | NFSEXP_V4ROOT,
+		.e_anonuid = 65534,
+		.e_anongid = 65534,
+		.e_squids = NULL,
+		.e_nsquids = 0,
+		.e_sqgids = NULL,
+		.e_nsqgids = 0,
+		.e_fsid = 0,
+		.e_mountpoint = NULL,
+	},
+	.m_exported = 0,
+	.m_xtabent = 1,
+	.m_mayexport = 1,
+	.m_changed = 0,
+	.m_warned = 0,
+};
+static nfs_export *pseudo_root;
+
+/*
+ * Return the number '/' in the path
+ */
+inline static int slash_count(char *path)
+{
+	int i, slashs=0;
+
+	for (i=0; i < strlen(path); i++) {
+			if (path[i] == '/')
+				slashs++;
+	}
+	return slashs;
+}
+/*
+ * Make sure the kernel has pseudo root support.
+ */
+static int
+v4root_support()
+{
+	static int kernel_support = -1;
+	char *ptr, version[64];
+	int major, minor;
+	FILE *fp;
+
+	if (kernel_support != -1)
+		return kernel_support;
+
+	kernel_support = 0;
+	fp = fopen("/proc/fs/nfsd/exports", "r");
+	if (fp == NULL)
+		goto out;
+
+	ptr = fgets(version, 64, fp);
+	fclose(fp);
+	if (ptr == NULL)
+		goto out;
+
+	while(*ptr && isdigit(*ptr) == 0)
+		ptr++;
+	if (*ptr == '\0')
+		goto out;
+
+	major = minor = 0;
+	sscanf(ptr, " %d.%d",&major, &minor);
+	if (major >= 1 && minor >= 2)
+		kernel_support = 1;
+out:
+	if (!kernel_support) {
+		xlog(L_WARNING, "Kernel does not have pseudo root support.");
+		xlog(L_WARNING, "NFS v4 mounts will be disabled unless fsid=0");
+		xlog(L_WARNING, "is specfied in /etc/exports file.");
+	}
+
+	return kernel_support;
+}
+/*
+ * Build a table of pseudo exports by running through
+ * the real export looking at the components of the path
+ * that make up the export. Those path components, if
+ * not exported, will become pseudo exports allowing them 
+ * to be found when the kernel does an upcall looking for 
+ * components of the v4 mount.
+ */
+void
+v4root_set()
+{
+	nfs_export	*exp, *nxt;
+	int	i;
+	char *path, *ptr;
+	char *hostname;
+
+	if (!v4root_needed)
+		return;
+
+	if (!v4root_support())
+		return;
+
+	pseudo_root = &pr_export;
+
+	for (i = 0; i < MCL_MAXTYPES; i++) {
+		for (exp = exportlist[i].p_head; exp; exp = nxt) {
+			nxt = exp->m_next;
+			hostname = exp->m_export.e_hostname;
+
+			path = strdup(exp->m_export.e_path);
+			ptr = path + 1;
+			while ((ptr = strchr(ptr, '/')) != NULL) {
+				*ptr = '\0';
+				if (export_lookup(hostname, path, 0) == NULL)
+					if (v4root_create(path, exp) == NULL) {
+						xlog(L_WARNING, "v4root_set: Unable to create"
+							"pseudo export for '%s'", path);
+						break;
+					}
+				*ptr = '/';
+				ptr++;
+			}
+
+			free(path);
+		}
+	}
+}
+
+/*
+ * Unset the pseudo root export
+ */
+void
+v4root_unset()
+{
+	pseudo_root = NULL;
+	hash_mount_free();
+}
+
+/*
+ * The kernel will do an upcall looking for the pseudo
+ * root via its fsid. When the wanted fsid equals 
+ * PSEUDO_ROOT_FSID return the pseudo root export.
+ */
+struct exportent *
+v4root_chkroot(int fsidtype, unsigned int fsidnum, char *fhuuid)
+{
+	if (pseudo_root == NULL)
+		return NULL;
+
+	if (fsidtype != FSID_NUM)
+		return NULL;
+
+	if (fsidnum != _PSEUDO_ROOT_FSID)
+		return NULL;
+
+	return &pseudo_root->m_export;
+}
+
+/*
+ * Create a pseudo export, if one does not 
+ * already exist.
+ */
+static struct exportent *
+v4root_create(char *path, nfs_export *exp)
+{
+	static struct exportent *p_export = NULL;
+	exports_t *pexp;
+	char uuid_len = sizeof(uuid_t);
+	char uuid[sizeof(uuid_t)];
+
+	if (pseudo_root == NULL)
+		return NULL;
+
+	/* Check to see if the export already exists */
+	get_uuid(path, NULL, uuid_len, uuid);
+	if ((p_export = v4root_export(uuid, uuid_len)) != NULL)
+		return p_export;
+
+	pexp = (exports_t *)malloc(sizeof(exports_t));
+	if (pexp == NULL) {
+		xlog(L_WARNING, "v4root_create: No memory for pseudo export");
+		return NULL;
+	}
+	p_export = &pexp->p_export;
+	pexp->path = strdup(path);
+	if (pexp->path == 0) {
+		xlog(L_WARNING, "v4root_create: No memory for pseudo path");
+		free(pexp);
+		return NULL;
+	}
+	pexp->uuid_len = uuid_len;
+	memcpy(pexp->uuid, uuid, uuid_len);
+
+	dupexportent(&pexp->p_export, &pr_export.m_export);
+	strcpy(p_export->e_path, path);
+	p_export->e_flags &= ~NFSEXP_FSID;
+	p_export->e_v4root = (void *)pexp;
+
+	hash_export_add(pexp, HASH(pexp->uuid, sizeof(uuid_t)));
+
+	xlog(D_CALL, "v4root_create: path '%s'", p_export->e_path);
+
+	return p_export;
+}
+
+/*
+ * See if the  pseudo export exists
+ */
+struct exportent *
+v4root_lookup(char *path, nfs_export *exp)
+{
+	static struct exportent *p_export = NULL;
+	char *epath = exp->m_export.e_path;
+	int elen, plen;
+	char uuid_len = sizeof(uuid_t);
+	char uuid[sizeof(uuid_t)];
+
+	if (pseudo_root == NULL)
+		return NULL;
+
+	/* Path needs to be a subset of e_path */
+	elen = strlen(epath);
+	plen = strlen(path);
+	if (plen >= elen)
+		return NULL;
+
+	if (memcmp(path, epath, plen) != 0)
+		return NULL;
+
+	/* Now to see if the export exists */
+	get_uuid(path, NULL, uuid_len, uuid);
+	p_export = v4root_export(uuid, uuid_len);
+
+	return p_export;
+}
+
+/*
+ * Free a pseudo export
+ */
+void
+v4root_free(struct exportent *p_export)
+{
+	exports_t *pexp = (exports_t *)p_export->e_v4root;
+	hash_head *head = (hash_head *)pexp->head;
+
+	free(pexp->path);
+	TAILQ_REMOVE(&head->h_head, pexp, list);
+}
+
+/*
+ * Return a pseudo export that match the given uuid
+ */
+struct exportent *
+v4root_export(char *fhuuid, int uuidlen)
+{
+	struct exportent *p_export = NULL;
+	exports_t *pexp;
+	int len = MIN(uuidlen, sizeof(uuid_t));
+
+	if (pseudo_root == NULL)
+		return NULL;
+
+	pexp = hash_export_lookup(fhuuid, len);
+	if (pexp) {
+		p_export = &pexp->p_export;
+		xlog(D_CALL, "v4root_export: path %s", p_export->e_path);
+	}
+	return p_export;
+}
+
+/*
+ * Add pseudo export to export table
+ */
+static void hash_export_add(struct _exports_t *exp, int hash)
+{
+	hash_head *head;
+
+	head = &(exports_tbl[hash]);
+	exp->head = head;
+
+	if (TAILQ_EMPTY(&head->h_head))
+		TAILQ_INSERT_HEAD(&head->h_head, exp, list);
+	else
+		TAILQ_INSERT_TAIL(&head->h_head, exp, list);
+}
+
+/*
+ * Lookup a pseudo export using the uuid and inode number
+ */
+static exports_t *
+hash_export_lookup(char *uuid, unsigned int uuidlen)
+{
+	exports_t *pexp;
+	hash_head *head;
+	int hash = HASH(uuid, uuidlen);
+
+	head = &(exports_tbl[hash]);
+
+	TAILQ_FOREACH(pexp, &head->h_head, list) {
+		if (memcmp(pexp->uuid, uuid, uuidlen) == 0)
+			return pexp;
+	}
+	return NULL;
+
+}
+
+/*
+ * Free up pseudo export table
+ */
+static void hash_mount_free()
+{
+	hash_head *head;
+	exports_t *e1, *e2;
+	int hash;
+
+	for (hash=0; hash < HASH_TABLE_SIZE; hash++) {
+		head = &(exports_tbl[hash]);
+		if (head == NULL)
+			continue;
+		e1 = TAILQ_FIRST(&head->h_head);
+		while (e1 != NULL) {
+			free(e1->path);
+			e2 =  TAILQ_NEXT(e1, list);
+			TAILQ_REMOVE(&head->h_head, e1, list);
+			free(e1);
+			e1 = e2;
+		}
+		TAILQ_INIT(&head->h_head);
+	}
+}

nfs-utils-1.2.1-rc7.patch:
 support/include/conffile.h |    7 ++++
 utils/mount/configfile.c   |   75 ++++++++++++++++++++++++++++++++++++++++++++-
 utils/mount/network.c      |   18 ++++++++--
 utils/mount/network.h      |    2 +
 utils/mount/nfsmount.conf  |   25 ++++++++++++---
 utils/mount/stropts.c      |    9 +++++
 6 files changed, 126 insertions(+), 10 deletions(-)

--- NEW FILE nfs-utils-1.2.1-rc7.patch ---
diff --git a/support/include/conffile.h b/support/include/conffile.h
index 672020a..fe23ec2 100644
--- a/support/include/conffile.h
+++ b/support/include/conffile.h
@@ -75,4 +75,11 @@ static inline void upper2lower(char *str)
 	while ((c = tolower(*str)))
 		*str++ = c;
 }
+
+/*
+ * Default Mount options
+ */
+extern unsigned long config_default_vers;
+extern unsigned long config_default_proto;
+
 #endif				/* _CONFFILE_H_ */
diff --git a/utils/mount/configfile.c b/utils/mount/configfile.c
index e347b0e..28b722c 100644
--- a/utils/mount/configfile.c
+++ b/utils/mount/configfile.c
@@ -20,13 +20,19 @@
 #include <config.h>
 #endif
 #include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <errno.h>
 
 #include "xlog.h"
+#include "mount.h"
+#include "parse_opt.h"
+#include "network.h"
 #include "conffile.h"
 
 #define KBYTES(x)     ((x) * (1024))
@@ -185,6 +191,63 @@ void free_all(void)
 		free(entry);
 	}
 }
+static char *versions[] = {"v2", "v3", "v4", "vers", "nfsvers", NULL};
+int inline check_vers(char *mopt, char *field)
+{
+	int i;
+
+	if (strncmp("mountvers", field, strlen("mountvers")) != 0) {
+		for (i=0; versions[i]; i++) 
+			if (strcasestr(mopt, versions[i]) != NULL)
+				return 1;
+	}
+	return 0;
+}
+
+unsigned long config_default_vers;
+unsigned long config_default_proto;
+/*
+ * Check to see if a default value is being set.
+ * If so, set the appropriate global value which will 
+ * be used as the initial value in the server negation.
+ */
+int inline default_value(char *mopt)
+{
+	struct mount_options *options = NULL;
+	int dftlen = strlen("default");
+	char *field;
+
+	if (strncasecmp(mopt, "default", dftlen) != 0)
+		return 0;
+
+	field = mopt + dftlen;
+	if (strncasecmp(field, "proto", strlen("proto")) == 0) {
+		if ((options = po_split(field)) != NULL) {
+			if (!nfs_nfs_protocol(options, &config_default_proto)) {
+				xlog_warn("Unable to set default protocol : %s", 
+					strerror(errno));
+			}
+		} else {
+			xlog_warn("Unable to alloc memory for default protocol");
+		}
+	} else if (strncasecmp(field, "vers", strlen("vers")) == 0) {
+		if ((options = po_split(field)) != NULL) {
+			if (!nfs_nfs_version(options, &config_default_vers)) {
+				xlog_warn("Unable to set default version: %s", 
+					strerror(errno));
+				
+			}
+		} else {
+			xlog_warn("Unable to alloc memory for default version");
+		}
+	} else 
+		xlog_warn("Invalid default setting: '%s'", mopt);
+
+	if (options)
+		po_destroy(options);
+
+	return 1;
+}
 /*
  * Parse the given section of the configuration 
  * file to if there are any mount options set.
@@ -207,6 +270,12 @@ conf_parse_mntopts(char *section, char *arg, char *opts)
 		snprintf(buf, BUFSIZ, "%s=", node->field);
 		if (opts && strcasestr(opts, buf) != NULL)
 			continue;
+		/* 
+		 * Protocol verions can be set in a number of ways
+		 */
+		if (opts && check_vers(opts, node->field))
+			continue;
+
 		if (lookup_entry(node->field) != NULL)
 			continue;
 		buf[0] = '\0';
@@ -302,15 +371,19 @@ char *conf_get_mntopts(char *spec, char *mount_point,
 		free_all();
 		return mount_opts;
 	}
+
 	if (mount_opts) {
 		strcpy(config_opts, mount_opts);
 		strcat(config_opts, ",");
 	}
 	SLIST_FOREACH(entry, &head, entries) {
+		if (default_value(entry->opt))
+			continue;
 		strcat(config_opts, entry->opt);
 		strcat(config_opts, ",");
 	}
-	*(strrchr(config_opts, ',')) = '\0';
+	if ((ptr = strrchr(config_opts, ',')) != NULL)
+		*ptr = '\0';
 
 	free_all();
 	if (mount_opts)
diff --git a/utils/mount/network.c b/utils/mount/network.c
index bd621be..e651167 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -50,6 +50,7 @@
 #include "nfsrpc.h"
 #include "parse_opt.h"
 #include "network.h"
+#include "conffile.h"
 
 #define PMAP_TIMEOUT	(10)
 #define CONNECT_TIMEOUT	(20)
@@ -609,10 +610,19 @@ static int nfs_probe_nfsport(const struct sockaddr *sap, const socklen_t salen,
 	if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
 		return 1;
 
-	if (nfs_mount_data_version >= 4)
+	if (nfs_mount_data_version >= 4) {
+		const unsigned int *probe_proto = probe_tcp_first;
+
+		/*
+		 * If the default proto has been set and 
+		 * its not TCP, start with UDP
+		 */
+		if (config_default_proto && config_default_proto != IPPROTO_TCP)
+			probe_proto =  probe_udp_first;
+
 		return nfs_probe_port(sap, salen, pmap,
-					probe_nfs3_first, probe_tcp_first);
-	else
+					probe_nfs3_first, probe_proto);
+	} else
 		return nfs_probe_port(sap, salen, pmap,
 					probe_nfs2_only, probe_udp_only);
 }
@@ -1261,7 +1271,7 @@ nfs_nfs_version(struct mount_options *options, unsigned long *version)
  * Returns TRUE if @protocol contains a valid value for this option,
  * or FALSE if the option was specified with an invalid value.
  */
-static int
+int
 nfs_nfs_protocol(struct mount_options *options, unsigned long *protocol)
 {
 	char *option;
diff --git a/utils/mount/network.h b/utils/mount/network.h
index 402e0a5..7eb89b0 100644
--- a/utils/mount/network.h
+++ b/utils/mount/network.h
@@ -57,6 +57,8 @@ int clnt_ping(struct sockaddr_in *, const unsigned long,
 struct mount_options;
 
 int nfs_nfs_version(struct mount_options *options, unsigned long *version);
+int  nfs_nfs_protocol(struct mount_options *options, unsigned long *protocol);
+
 int nfs_options2pmap(struct mount_options *,
 		      struct pmap *, struct pmap *);
 
diff --git a/utils/mount/nfsmount.conf b/utils/mount/nfsmount.conf
index f9fcfcb..9b8ff4a 100644
--- a/utils/mount/nfsmount.conf
+++ b/utils/mount/nfsmount.conf
@@ -24,14 +24,29 @@
 # 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
-# Network Transport [Udp,Tcp,Rdma]
-# Proto=Tcp
+# Protocol Version [2,3,4]
+# This defines the default protocol version which will
+# be used to start the negotiation with the server.
+# Defaultvers=4
+#
+# Setting this option makes it mandatory the server supports the
+# given version. The mount will fail if the given version is 
+# not support by the server. 
+# Nfsvers=4
+#
+# Network Protocol [udp,tcp,rdma] (Note: values are case sensitive)
+# This defines the default network protocol which will
+# be used to start the negotiation with the server.
+# Defaultproto=tcp
+#
+# Setting this option makes it mandatory the server supports the
+# given network protocol. The mount will fail if the given network
+# protocol is not supported by the server.
+# Proto=tcp
 #
 # The number of times a request will be retired before 
 # generating a timeout 
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 069bdc1..ceefdb0 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -45,6 +45,7 @@
 #include "parse_opt.h"
 #include "version.h"
 #include "parse_dev.h"
+#include "conffile.h"
 
 #ifndef NFS_PROGRAM
 #define NFS_PROGRAM	(100003)
@@ -283,6 +284,14 @@ static int nfs_validate_options(struct nfsmount_info *mi)
 		if (option && strcmp(option, "rdma") == 0)
 			mi->version = 3;
 	}
+	/*
+	 * Use the default value set in the config file when
+	 * the version has not been explicitly set.
+	 */
+	if (mi->version == 0 && config_default_vers) {
+		if (config_default_vers < 4)
+			mi->version = config_default_vers;
+	}
 
 	if (!nfs_append_sloppy_option(mi->options))
 		return 0;


Index: nfs-utils.spec
===================================================================
RCS file: /cvs/pkgs/rpms/nfs-utils/devel/nfs-utils.spec,v
retrieving revision 1.246
retrieving revision 1.247
diff -u -p -r1.246 -r1.247
--- nfs-utils.spec	6 Oct 2009 10:50:48 -0000	1.246
+++ nfs-utils.spec	26 Oct 2009 13:26:04 -0000	1.247
@@ -2,7 +2,7 @@ Summary: NFS utilities and supporting cl
 Name: nfs-utils
 URL: http://sourceforge.net/projects/nfs
 Version: 1.2.0
-Release: 16%{?dist}
+Release: 17%{?dist}
 Epoch: 1
 
 # group all 32bit related archs
@@ -28,12 +28,9 @@ 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
+Patch106: nfs-utils-1.2.1-rc7.patch
 
-Patch200: nfs-utils-1.2.0-v4root-rel6.patch
-
-Patch300: nfs-utils-1.2.0-mntconf-vers.patch
-Patch301: nfs-utils-1.2.0-mntconf-negation.patch
+Patch200: nfs-utils-1.2.0-v4root-rel7.patch
 
 Group: System Environment/Daemons
 Provides: exportfs    = %{epoch}:%{version}-%{release}
@@ -95,9 +92,6 @@ This package also contains the mount.nfs
 
 %patch200 -p1
 
-%patch300 -p1
-%patch301 -p1
-
 # Remove .orig files
 find . -name "*.orig" | xargs rm -f
 
@@ -268,6 +262,13 @@ fi
 %attr(4755,root,root)   /sbin/umount.nfs4
 
 %changelog
+* Mon Oct 26 09:23:45 EDT 2009
+- Updated to the latest pseudo root release (rel7).
+- Added upstream 1.2.1-rc7 patch which fixes:
+  - Stop ignoring the -o v4 option (bz 529407)
+  - Allow network protocol roll backs when proto is set
+    in the config file (bz 529864)
+
 * Mon Oct  5 2009 Steve Dickson <steved at redhat.com> 1.2.0-16
 - Fixed a whole where '-o v4' was not overriding the
   version in the conf file.


--- nfs-utils-1.2.0-mntconf-negation.patch DELETED ---


--- nfs-utils-1.2.0-mntconf-vers.patch DELETED ---


--- nfs-utils-1.2.0-mount-vers4.patch DELETED ---


--- nfs-utils-1.2.0-v4root-rel6.patch DELETED ---




More information about the fedora-extras-commits mailing list