diff --git a/nfs-utils-1.2.0-proots-rel5.patch b/nfs-utils-1.2.0-proots-rel5.patch deleted file mode 100644 index 2539d89..0000000 --- a/nfs-utils-1.2.0-proots-rel5.patch +++ /dev/null @@ -1,694 +0,0 @@ -diff -up nfs-utils-1.2.0/support/export/xtab.c.orig nfs-utils-1.2.0/support/export/xtab.c ---- nfs-utils-1.2.0/support/export/xtab.c.orig 2009-06-02 10:43:05.000000000 -0400 -+++ nfs-utils-1.2.0/support/export/xtab.c 2009-08-17 07:33:13.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.orig nfs-utils-1.2.0/support/include/exportfs.h ---- nfs-utils-1.2.0/support/include/exportfs.h.orig 2009-06-02 10:43:05.000000000 -0400 -+++ nfs-utils-1.2.0/support/include/exportfs.h 2009-08-17 07:33:13.000000000 -0400 -@@ -12,6 +12,17 @@ - #include - #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.orig nfs-utils-1.2.0/support/include/nfs/export.h ---- nfs-utils-1.2.0/support/include/nfs/export.h.orig 2009-06-02 10:43:05.000000000 -0400 -+++ nfs-utils-1.2.0/support/include/nfs/export.h 2009-08-17 07:33:13.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.orig nfs-utils-1.2.0/support/include/nfslib.h ---- nfs-utils-1.2.0/support/include/nfslib.h.orig 2009-08-17 07:31:52.000000000 -0400 -+++ nfs-utils-1.2.0/support/include/nfslib.h 2009-08-17 07:33:13.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-08-13 17:25:29.612003011 -0400 -+++ nfs-utils-1.2.0/support/include/v4root.h 2009-08-17 07:33:13.000000000 -0400 -@@ -0,0 +1,20 @@ -+/* -+ * Copyright (C) 2009 Red Hat -+ * 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_create(char *, nfs_export *, int); -+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.orig nfs-utils-1.2.0/utils/mountd/auth.c ---- nfs-utils-1.2.0/utils/mountd/auth.c.orig 2009-06-02 10:43:05.000000000 -0400 -+++ nfs-utils-1.2.0/utils/mountd/auth.c 2009-08-17 07:33:13.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.orig nfs-utils-1.2.0/utils/mountd/cache.c ---- nfs-utils-1.2.0/utils/mountd/cache.c.orig 2009-08-17 07:31:52.000000000 -0400 -+++ nfs-utils-1.2.0/utils/mountd/cache.c 2009-08-17 07:33:13.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_create(path, exp, TRUE); - 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_create(path, exp, TRUE); - 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.orig nfs-utils-1.2.0/utils/mountd/Makefile.am ---- nfs-utils-1.2.0/utils/mountd/Makefile.am.orig 2009-06-02 10:43:05.000000000 -0400 -+++ nfs-utils-1.2.0/utils/mountd/Makefile.am 2009-08-17 07:33:13.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-08-13 17:25:29.612003011 -0400 -+++ nfs-utils-1.2.0/utils/mountd/v4root.c 2009-08-17 07:33:13.000000000 -0400 -@@ -0,0 +1,409 @@ -+/* -+ * Copyright (C) 2009 Red Hat -+ * -+ * support/export/v4root.c -+ * -+ * Routines used to support NFSv4 pseudo roots -+ * -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#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); -+ -+typedef struct _exports_t { -+ TAILQ_ENTRY(_exports_t) list; -+ char *path; -+ void *head; -+ char uuid_len; -+ char uuid[sizeof(uuid_t)]; -+ struct exportent p_export; -+} exports_t; -+ -+#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]; -+ -+ -+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); -+ -+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 psuedo 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 -+ * not exported, will be come pseudo exports allow 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, slcnt; -+ char *e_path, *path, *ptr, *comp; -+ 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; -+ e_path = exp->m_export.e_path; -+ hostname = exp->m_export.e_hostname; -+ -+ if ((slcnt = slash_count(e_path)) < 2) -+ continue; -+ slcnt--; /* knock off the leanding '/' */ -+ -+ path = strdup(e_path); -+ if ((ptr = strrchr(path, '/')) != NULL) -+ *ptr = '\0'; -+ -+ /* -+ * Run through each component of the path to -+ * see if a pseudo export should be create. -+ */ -+ comp = path+1; -+ do { -+ if ((ptr = strchr(comp, '/')) != NULL) -+ *ptr = '\0'; -+ -+ if (export_lookup(hostname, path, 0) == NULL) -+ v4root_create(path, exp, FALSE); -+ -+ if (ptr) { -+ *ptr = '/'; -+ comp = ptr+1; -+ } -+ } while (--slcnt > 0); -+ } -+ } -+} -+ -+/* -+ * 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) -+{ -+ struct exportent *p_export = NULL; -+ -+ if (pseudo_root == NULL) -+ return NULL; -+ -+ switch(fsidtype) { -+ case FSID_NUM: -+ if (fsidnum == _PSEUDO_ROOT_FSID) { -+ p_export = &pseudo_root->m_export; -+ strncpy(p_export->e_path, _PATH_PSEUDO_ROOT, -+ NFS_MAXPATHLEN); -+ } -+ break; -+ } -+ -+ return p_export; -+} -+ -+/* -+ * Create a psuedo export, if one does not -+ * already exist. -+ */ -+struct exportent * -+v4root_create(char *path, nfs_export *exp, int docheck) -+{ -+ static struct exportent *p_export = NULL; -+ exports_t *pexp; -+ char *epath = exp->m_export.e_path; -+ char *hostname = exp->m_export.e_hostname; -+ int elen, plen, i; -+ char uuid_len = sizeof(uuid_t); -+ char uuid[sizeof(uuid_t)]; -+ -+ if (pseudo_root == NULL) -+ return NULL; -+ -+ if (docheck) { -+ -+ /* Path needs to be an subset of e_path */ -+ elen = strlen(epath); -+ plen = strlen(path); -+ if (plen >= elen) -+ return NULL; -+ -+ for (i=0; i < plen; i++) { -+ if (path[i] != epath[i]) -+ 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 psuedo export"); -+ return NULL; -+ } -+ p_export = &pexp->p_export; -+ pexp->path = strdup(path); -+ -+ pexp->uuid_len = uuid_len; -+ memcpy(pexp->uuid, uuid, uuid_len); -+ -+ memcpy(&pexp->p_export, &pr_export.m_export, -+ sizeof(struct exportent)); -+ 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; -+} -+ -+/* -+ * Free a psuedo 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 psuedo 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 psuedo 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 psuedo 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 psuedo 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); -+ } -+} diff --git a/nfs-utils-1.2.0-v4root-bz538609.patch b/nfs-utils-1.2.0-v4root-bz538609.patch deleted file mode 100644 index 9e29e08..0000000 --- a/nfs-utils-1.2.0-v4root-bz538609.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 3c473bf19432cd7c17c7be7595d46e7c2d6a7efe -Author: Steve Dickson -Date: Fri Nov 20 08:51:34 2009 -0500 - - Fixed a bug introduced by commit 5d27b4 that was stopping - exports that existed on the pseudo root (i.e. '/') from - being exported. The result of this bug was client mounts - were failing with ESTALE. - - Signed-off-by: Steve Dickson - -diff --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c -index a1e0eb2..a5a1a75 100644 ---- a/utils/mountd/v4root.c -+++ b/utils/mountd/v4root.c -@@ -275,8 +275,10 @@ v4root_create(char *path, nfs_export *exp) - - /* 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; -+ if ((p_export = v4root_export(uuid, uuid_len)) != NULL) { -+ if (strcmp(path, p_export->e_path) == 0) -+ return p_export; -+ } - - pexp = (exports_t *)malloc(sizeof(exports_t)); - if (pexp == NULL) { diff --git a/nfs-utils-1.2.0-v4root-rel6.patch b/nfs-utils-1.2.0-v4root-rel6.patch deleted file mode 100644 index 20856bc..0000000 --- a/nfs-utils-1.2.0-v4root-rel6.patch +++ /dev/null @@ -1,716 +0,0 @@ -diff --git a/support/export/xtab.c b/support/export/xtab.c -index 3b1dcce..2a43193 100644 ---- a/support/export/xtab.c -+++ b/support/export/xtab.c -@@ -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 is_export) - 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 is_export) - 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 --git a/support/include/exportfs.h b/support/include/exportfs.h -index a5cf482..1ad41e2 100644 ---- a/support/include/exportfs.h -+++ b/support/include/exportfs.h -@@ -12,6 +12,17 @@ - #include - #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 --git a/support/include/nfs/export.h b/support/include/nfs/export.h -index f7a99ba..76953ac 100644 ---- a/support/include/nfs/export.h -+++ b/support/include/nfs/export.h -@@ -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 --git a/support/include/nfslib.h b/support/include/nfslib.h -index 537a31e..e4777dd 100644 ---- a/support/include/nfslib.h -+++ b/support/include/nfslib.h -@@ -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 --git a/support/include/v4root.h b/support/include/v4root.h -new file mode 100644 -index 0000000..43b1d2e ---- /dev/null -+++ b/support/include/v4root.h -@@ -0,0 +1,20 @@ -+/* -+ * Copyright (C) 2009 Red Hat -+ * 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_create(char *, nfs_export *, int); -+extern void v4root_free(struct exportent *); -+extern void v4root_unset(void), v4root_set(void); -+ -+#endif /* V4ROOT_H */ -diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am -index 1e76cf8..eba81fc 100644 ---- a/utils/mountd/Makefile.am -+++ b/utils/mountd/Makefile.am -@@ -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 --git a/utils/mountd/auth.c b/utils/mountd/auth.c -index 575f207..041a745 100644 ---- a/utils/mountd/auth.c -+++ b/utils/mountd/auth.c -@@ -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 --git a/utils/mountd/cache.c b/utils/mountd/cache.c -index e4e2f22..d631570 100644 ---- a/utils/mountd/cache.c -+++ b/utils/mountd/cache.c -@@ -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_create(path, exp, TRUE); - 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_create(path, exp, TRUE); - 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 --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c -new file mode 100644 -index 0000000..8de2ab6 ---- /dev/null -+++ b/utils/mountd/v4root.c -@@ -0,0 +1,420 @@ -+/* -+ * Copyright (C) 2009 Red Hat -+ * -+ * support/export/v4root.c -+ * -+ * Routines used to support NFSv4 pseudo roots -+ * -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#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); -+ -+typedef struct _exports_t { -+ TAILQ_ENTRY(_exports_t) list; -+ char *path; -+ void *head; -+ char uuid_len; -+ char uuid[sizeof(uuid_t)]; -+ struct exportent p_export; -+} exports_t; -+ -+#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]; -+ -+ -+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); -+ -+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, slcnt; -+ char *e_path, *path, *ptr, *comp; -+ 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; -+ e_path = exp->m_export.e_path; -+ hostname = exp->m_export.e_hostname; -+ -+ slcnt = slash_count(e_path); -+ if (slcnt == 1) -+ continue; -+ slcnt--; /* knock off the leanding '/' */ -+ -+ path = strdup(e_path); -+ if (path == NULL) { -+ xlog(L_WARNING, "v4root_set: No memory for pseudo export"); -+ return; -+ } -+ -+ /* -+ * Run through each component of the path to -+ * see if a pseudo export should be created. -+ */ -+ comp = path+1; -+ do { -+ if ((ptr = strchr(comp, '/')) != NULL) -+ *ptr = '\0'; -+ -+ if (export_lookup(hostname, path, 0) == NULL) -+ if (v4root_create(path, exp, FALSE) == NULL) { -+ xlog(L_WARNING, -+ "v4root_set: Unable to create pseudo export" -+ "for '%s'", path); -+ break; -+ } -+ -+ if (ptr) { -+ *ptr = '/'; -+ comp = ptr+1; -+ } -+ } while (--slcnt > 0); -+ 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) -+{ -+ struct exportent *p_export = NULL; -+ -+ if (pseudo_root == NULL) -+ return NULL; -+ -+ switch(fsidtype) { -+ case FSID_NUM: -+ if (fsidnum == _PSEUDO_ROOT_FSID) { -+ p_export = &pseudo_root->m_export; -+ strncpy(p_export->e_path, _PATH_PSEUDO_ROOT, -+ NFS_MAXPATHLEN); -+ } -+ break; -+ } -+ -+ return p_export; -+} -+ -+/* -+ * Create a pseudo export, if one does not -+ * already exist. -+ */ -+struct exportent * -+v4root_create(char *path, nfs_export *exp, int docheck) -+{ -+ static struct exportent *p_export = NULL; -+ exports_t *pexp; -+ 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; -+ -+ if (docheck) { -+ -+ /* 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; -+ } -+ -+ /* 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; -+} -+ -+/* -+ * 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); -+ } -+} diff --git a/nfs-utils-1.2.0-v4root-rel8.patch b/nfs-utils-1.2.0-v4root-rel8.patch deleted file mode 100644 index bd73165..0000000 --- a/nfs-utils-1.2.0-v4root-rel8.patch +++ /dev/null @@ -1,717 +0,0 @@ -diff -up nfs-utils-1.2.1/support/export/xtab.c.orig nfs-utils-1.2.1/support/export/xtab.c ---- nfs-utils-1.2.1/support/export/xtab.c.orig 2009-11-04 06:13:56.000000000 -0500 -+++ nfs-utils-1.2.1/support/export/xtab.c 2009-11-11 14:01:56.370963000 -0500 -@@ -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.1/support/include/exportfs.h.orig nfs-utils-1.2.1/support/include/exportfs.h ---- nfs-utils-1.2.1/support/include/exportfs.h.orig 2009-11-04 06:13:56.000000000 -0500 -+++ nfs-utils-1.2.1/support/include/exportfs.h 2009-11-11 14:01:56.377960000 -0500 -@@ -12,6 +12,17 @@ - #include - #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.1/support/include/nfs/export.h.orig nfs-utils-1.2.1/support/include/nfs/export.h ---- nfs-utils-1.2.1/support/include/nfs/export.h.orig 2009-11-04 06:13:56.000000000 -0500 -+++ nfs-utils-1.2.1/support/include/nfs/export.h 2009-11-11 14:01:56.383967000 -0500 -@@ -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.1/support/include/nfslib.h.orig nfs-utils-1.2.1/support/include/nfslib.h ---- nfs-utils-1.2.1/support/include/nfslib.h.orig 2009-11-04 06:13:56.000000000 -0500 -+++ nfs-utils-1.2.1/support/include/nfslib.h 2009-11-11 14:01:56.390963000 -0500 -@@ -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.1/support/include/v4root.h ---- /dev/null 2009-11-11 11:00:17.075766506 -0500 -+++ nfs-utils-1.2.1/support/include/v4root.h 2009-11-11 14:01:56.399965000 -0500 -@@ -0,0 +1,20 @@ -+/* -+ * Copyright (C) 2009 Red Hat -+ * 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.1/utils/mountd/auth.c.orig nfs-utils-1.2.1/utils/mountd/auth.c ---- nfs-utils-1.2.1/utils/mountd/auth.c.orig 2009-11-04 06:13:56.000000000 -0500 -+++ nfs-utils-1.2.1/utils/mountd/auth.c 2009-11-11 14:01:56.405963000 -0500 -@@ -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.1/utils/mountd/cache.c.orig nfs-utils-1.2.1/utils/mountd/cache.c ---- nfs-utils-1.2.1/utils/mountd/cache.c.orig 2009-11-04 06:13:56.000000000 -0500 -+++ nfs-utils-1.2.1/utils/mountd/cache.c 2009-11-11 14:01:56.414960000 -0500 -@@ -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.1/utils/mountd/Makefile.am.orig nfs-utils-1.2.1/utils/mountd/Makefile.am ---- nfs-utils-1.2.1/utils/mountd/Makefile.am.orig 2009-11-04 06:13:56.000000000 -0500 -+++ nfs-utils-1.2.1/utils/mountd/Makefile.am 2009-11-11 14:01:56.421960000 -0500 -@@ -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.1/utils/mountd/v4root.c ---- /dev/null 2009-11-11 11:00:17.075766506 -0500 -+++ nfs-utils-1.2.1/utils/mountd/v4root.c 2009-11-11 14:02:39.699100000 -0500 -@@ -0,0 +1,432 @@ -+/* -+ * Copyright (C) 2009 Red Hat -+ * -+ * support/export/v4root.c -+ * -+ * Routines used to support NFSv4 pseudo roots -+ * -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#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; -+ struct exportent *proot; -+ int i, insecure = 0; -+ char *path, *ptr; -+ char *hostname; -+ -+ if (!v4root_needed) -+ return; -+ -+ if (!v4root_support()) -+ return; -+ -+ pseudo_root = &pr_export; -+ if ((proot = v4root_create(_PATH_PSEUDO_ROOT, pseudo_root)) == NULL) { -+ xlog(L_WARNING, "v4root_set: Unable to create" -+ "pseudo export for '%s'", _PATH_PSEUDO_ROOT); -+ pseudo_root = NULL; -+ return; -+ } -+ -+ 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++; -+ } -+ /* Make note of insecure exports */ -+ if (!insecure) -+ insecure = (exp->m_export.e_flags & NFSEXP_INSECURE_PORT); -+ -+ free(path); -+ } -+ } -+ /* -+ * If there are any insecure exports, the pseudo root -+ * also has to be insecure -+ */ -+ if (insecure) { -+ pseudo_root->m_export.e_flags |= NFSEXP_INSECURE_PORT; -+ proot->e_flags |= NFSEXP_INSECURE_PORT; -+ } -+} -+ -+/* -+ * 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); -+ } -+} diff --git a/nfs-utils-1.2.0-v4root-rel9.patch b/nfs-utils-1.2.0-v4root-rel9.patch new file mode 100644 index 0000000..002ef1c --- /dev/null +++ b/nfs-utils-1.2.0-v4root-rel9.patch @@ -0,0 +1,406 @@ +diff --git a/support/export/xtab.c b/support/export/xtab.c +index 3b1dcce..2a43193 100644 +--- a/support/export/xtab.c ++++ b/support/export/xtab.c +@@ -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 is_export) + 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 is_export) + 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 --git a/support/include/nfs/export.h b/support/include/nfs/export.h +index f7a99ba..76953ac 100644 +--- a/support/include/nfs/export.h ++++ b/support/include/nfs/export.h +@@ -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 --git a/support/include/pseudoflavors.h b/support/include/pseudoflavors.h +index c21087b..c7ba8a2 100644 +--- a/support/include/pseudoflavors.h ++++ b/support/include/pseudoflavors.h +@@ -15,3 +15,4 @@ struct flav_info { + + extern struct flav_info flav_map[]; + extern const int flav_map_size; ++extern unsigned int flavors_setall(struct exportent *ep); +diff --git a/support/include/v4root.h b/support/include/v4root.h +new file mode 100644 +index 0000000..706c15c +--- /dev/null ++++ b/support/include/v4root.h +@@ -0,0 +1,15 @@ ++/* ++ * Copyright (C) 2009 Red Hat ++ * support/include/v4root.h ++ * ++ * Support routines for dynamic pseudo roots. ++ * ++ */ ++ ++#ifndef V4ROOT_H ++#define V4ROOT_H ++ ++extern int v4root_needed; ++extern void v4root_set(void); ++ ++#endif /* V4ROOT_H */ +diff --git a/support/nfs/exports.c b/support/nfs/exports.c +index 1aaebf4..fe9ed3a 100644 +--- a/support/nfs/exports.c ++++ b/support/nfs/exports.c +@@ -39,16 +39,18 @@ struct flav_info flav_map[] = { + { "krb5", RPC_AUTH_GSS_KRB5 }, + { "krb5i", RPC_AUTH_GSS_KRB5I }, + { "krb5p", RPC_AUTH_GSS_KRB5P }, ++ { "unix", AUTH_UNIX }, ++ { "sys", AUTH_SYS }, ++ { "null", AUTH_NULL }, ++ { "none", AUTH_NONE }, ++#ifdef NOLONGERSUPPORTED + { "lipkey", RPC_AUTH_GSS_LKEY }, + { "lipkey-i", RPC_AUTH_GSS_LKEYI }, + { "lipkey-p", RPC_AUTH_GSS_LKEYP }, + { "spkm3", RPC_AUTH_GSS_SPKM }, + { "spkm3i", RPC_AUTH_GSS_SPKMI }, + { "spkm3p", RPC_AUTH_GSS_SPKMP }, +- { "unix", AUTH_UNIX }, +- { "sys", AUTH_SYS }, +- { "null", AUTH_NULL }, +- { "none", AUTH_NONE }, ++#endif + }; + + const int flav_map_size = sizeof(flav_map)/sizeof(flav_map[0]); +@@ -436,6 +438,20 @@ static unsigned int parse_flavors(char *str, struct exportent *ep) + } + return out; + } ++unsigned int flavors_setall(struct exportent *ep) ++{ ++ struct flav_info *flav; ++ unsigned int out=0; ++ int bit; ++ ++ for (flav = flav_map; flav < flav_map + flav_map_size; flav++) { ++ bit = secinfo_addflavor(flav, ep); ++ if (bit < 0) ++ return 0; ++ out |= 1<m_next) { ++ /* Don't show pseudo exports */ ++ if (exp->m_export.e_flags & NFSEXP_V4ROOT) ++ continue; ++ + for (e = elist; e != NULL; e = e->ex_next) { + if (!strcmp(exp->m_export.e_path, e->ex_dir)) + break; +diff --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c +new file mode 100644 +index 0000000..817dfb4 +--- /dev/null ++++ b/utils/mountd/v4root.c +@@ -0,0 +1,228 @@ ++/* ++ * Copyright (C) 2009 Red Hat ++ * ++ * support/export/v4root.c ++ * ++ * Routines used to support NFSv4 pseudo roots ++ * ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "xlog.h" ++#include "exportfs.h" ++#include "nfslib.h" ++#include "misc.h" ++#include "pseudoflavors.h" ++#include "v4root.h" ++ ++#ifndef _PATH_PSEUDO_ROOT ++#define _PATH_PSEUDO_ROOT "/" ++#endif ++ ++#ifndef _PSEUDO_ROOT_FSID ++#define _PSEUDO_ROOT_FSID 0 ++#endif ++ ++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 pseudo_root = { ++ .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, ++ .e_secinfo[0].flav = NULL, ++ }, ++ .m_exported = 0, ++ .m_xtabent = 1, ++ .m_mayexport = 1, ++ .m_changed = 0, ++ .m_warned = 0, ++}; ++ ++/* ++ * Create a pseudo export ++ */ ++static struct exportent * ++v4root_create(char *path, nfs_export *export) ++{ ++ nfs_export *exp; ++ struct exportent eep; ++ struct exportent *curexp = &export->m_export; ++ ++ dupexportent(&eep, curexp); ++ eep.e_hostname = strdup(curexp->e_hostname); ++ strncpy(eep.e_path, path, sizeof(eep.e_path)); ++ exp = export_create(&eep, 0); ++ if (exp == NULL) ++ return NULL; ++ ++ exp->m_export.e_flags |= NFSEXP_V4ROOT; ++ if (strcmp(path, _PATH_PSEUDO_ROOT) != 0) ++ exp->m_export.e_flags &= ~NFSEXP_FSID; ++ ++ xlog(D_CALL, "v4root_create: path '%s'", exp->m_export.e_path); ++ ++ return &exp->m_export; ++} ++ ++/* ++ * 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; ++} ++ ++/* ++ * Create 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; ++ struct exportent *proot; ++ int i, insecure = 0, secflavors = 0; ++ char *path, *ptr; ++ char *hostname; ++ ++ if (!v4root_needed) ++ return; ++ ++ if (!v4root_support()) ++ return; ++ ++ proot = v4root_create(_PATH_PSEUDO_ROOT, &pseudo_root); ++ if (proot == NULL) { ++ xlog(L_WARNING, "v4root_set: Unable to create " ++ "pseudo export for '%s'", _PATH_PSEUDO_ROOT); ++ return; ++ } ++ ++ 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++; ++ } ++ /* Make note of insecure exports */ ++ if (!insecure) ++ insecure = (exp->m_export.e_flags & NFSEXP_INSECURE_PORT); ++ ++ /* Make note of security flavors being set */ ++ if (!secflavors) ++ secflavors = (exp->m_export.e_secinfo[0].flav != NULL); ++ ++ free(path); ++ } ++ } ++ ++ if (insecure && secflavors) { ++ xlog(L_WARNING, "WARNING: The 'sec=' and 'insecure' export options " ++ "are incompatible, causing the security flavors set by " ++ "'sec=' to be ignored on V4 exports"); ++ } ++ ++ /* ++ * If there are any insecure exports, the pseudo root ++ * also has to be insecure ++ */ ++ if (insecure) { ++ proot->e_flags |= NFSEXP_INSECURE_PORT; ++ } ++ ++ /* ++ * Make sure the pseudo root is accessible from all ++ * security flavors unless the insecure port is set, ++ * which cause the kernel to silently fail v4 mounts ++ * with security flavors set. ++ */ ++ if (secflavors && !insecure) { ++ if (!flavors_setall(proot)) { ++ xlog(L_WARNING, "v4root_set: Unable to set security " ++ "flavors on pseudo root"); ++ } ++ } ++} ++ ++ diff --git a/nfs-utils-1.2.1-mount-eperm.patch b/nfs-utils-1.2.1-mount-eperm.patch new file mode 100644 index 0000000..616768f --- /dev/null +++ b/nfs-utils-1.2.1-mount-eperm.patch @@ -0,0 +1,30 @@ +commit 26a14b65991b79d317638f78dc6b4e5ac1ef712e +Author: Neil Brown +Date: Mon Dec 7 17:23:48 2009 -0500 + + mount.nfs: Retry v4 mounts with v3 on ENOENT errors + + Retry v4 mounts with a v3 mount when the version + is not explicitly specified and the mount fails + with ENOENT. The will help deal with Linux servers + that do not automatically export a pseudo root + + Signed-off-by: Steve Dickson + +diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c +index a0b9e7f..4007150 100644 +--- a/utils/mount/stropts.c ++++ b/utils/mount/stropts.c +@@ -668,9 +668,10 @@ static int nfs_try_mount(struct nfsmount_info *mi) + /* + * To deal with legacy Linux servers that don't + * automatically export a pseudo root, retry +- * ENOENT errors using version 3 ++ * ENOENT errors using version 3. And for ++ * Linux servers prior to 2.6.25, retry EPERM + */ +- if (errno != ENOENT) ++ if (errno != ENOENT && errno != EPERM) + break; + } + } diff --git a/nfs-utils.spec b/nfs-utils.spec index 5a1dcef..384e72a 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.1 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 1 # group all 32bit related archs @@ -25,8 +25,8 @@ Patch02: nfs-utils-1.1.0-exp-subtree-warn-off.patch Patch200: nfs-utils-1.2.0-mount-default.patch Patch201: nfs-utils-1.2.1-nfsd-bootfail.patch -Patch300: nfs-utils-1.2.0-v4root-rel8.patch -Patch301: nfs-utils-1.2.0-v4root-bz538609.patch +Patch300: nfs-utils-1.2.0-v4root-rel9.patch +Patch301: nfs-utils-1.2.1-mount-eperm.patch Group: System Environment/Daemons Provides: exportfs = %{epoch}:%{version}-%{release} @@ -82,7 +82,6 @@ This package also contains the mount.nfs and umount.nfs program. %patch201 -p1 %patch300 -p1 -%patch301 -p1 # Remove .orig files find . -name "*.orig" | xargs rm -f @@ -254,6 +253,10 @@ fi %attr(4755,root,root) /sbin/umount.nfs4 %changelog +* Mon Dec 7 2009 Steve Dickson 1.2.1-3 +- Updated to the latest pseudo root release (rel8). +- mount.nfs: Retry v4 mounts with v3 on ENOENT error + * Fri Nov 20 2009 Steve Dickson 1.2.1-2 - Fixed a bug in v4root code that was causing ESTALE mounts (bz 538609)