From f5b3ef36df758bf503da16dbd6cf85e288065f30 Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Aug 28 2008 17:31:27 +0000 Subject: Added in a number of up upstream patches (101 thru 110). --- diff --git a/nfs-utils-1.1.3-exportfs-uuid-nowarn.patch b/nfs-utils-1.1.3-exportfs-uuid-nowarn.patch new file mode 100644 index 0000000..4756fbd --- /dev/null +++ b/nfs-utils-1.1.3-exportfs-uuid-nowarn.patch @@ -0,0 +1,44 @@ +commit ec16220910f0bf1bf2b8e1d50e78df7da11d8b1e +Author: David Woodhouse +Date: Thu Aug 28 11:07:53 2008 -0400 + + Stop exportfs warning about needing fsid, when we actually have one + + Signed-off-by: David Woodhouse + Signed-off-by: Steve Dickson + +diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c +index 18dfe5a..fec2571 100644 +--- a/utils/exportfs/exportfs.c ++++ b/utils/exportfs/exportfs.c +@@ -12,6 +12,7 @@ + #include + #endif + ++#include + #include + #include + #include +@@ -388,6 +389,8 @@ validate_export(nfs_export *exp) + */ + struct stat stb; + char *path = exp->m_export.e_path; ++ struct statfs64 stf; ++ int fs_has_fsid = 0; + + if (stat(path, &stb) < 0) { + fprintf(stderr, "exportfs: Warning: %s does not exist\n", +@@ -403,7 +406,12 @@ validate_export(nfs_export *exp) + if (!can_test()) + return; + +- if ((exp->m_export.e_flags & NFSEXP_FSID) || exp->m_export.e_uuid) { ++ if (!statfs64(path, &stf) && ++ (stf.f_fsid.__val[0] || stf.f_fsid.__val[1])) ++ fs_has_fsid = 1; ++ ++ if ((exp->m_export.e_flags & NFSEXP_FSID) || exp->m_export.e_uuid || ++ fs_has_fsid) { + if ( !test_export(path, 1)) { + fprintf(stderr, "exportfs: Warning: %s does not " + "support NFS export.\n", diff --git a/nfs-utils-1.1.3-idmapd-rm-idmapconf.patch b/nfs-utils-1.1.3-idmapd-rm-idmapconf.patch new file mode 100644 index 0000000..4668d44 --- /dev/null +++ b/nfs-utils-1.1.3-idmapd-rm-idmapconf.patch @@ -0,0 +1,28 @@ +commit 83a8da644b553680e9d578843a6fa0fc9347af0e +Author: J. Bruce Fields +Date: Thu Aug 28 11:25:29 2008 -0400 + + Remove idmapd.conf + + The example idmapd.conf file is kept in libnfsidmap now, which is what's + responsible for parsing it anyway. + + Signed-off-by: J. Bruce Fields + Signed-off-by: Steve Dickson + +diff --git a/utils/idmapd/idmapd.conf b/utils/idmapd/idmapd.conf +deleted file mode 100644 +index acafd4b..0000000 +--- a/utils/idmapd/idmapd.conf ++++ /dev/null +@@ -1,10 +0,0 @@ +-[General] +- +-Verbosity = 0 +-Pipefs-Directory = /var/lib/nfs/rpc_pipefs +-Domain = localdomain +- +-[Mapping] +- +-Nobody-User = nobody +-Nobody-Group = nobody diff --git a/nfs-utils-1.1.3-mountd-cleanup.patch b/nfs-utils-1.1.3-mountd-cleanup.patch new file mode 100644 index 0000000..4cb8c46 --- /dev/null +++ b/nfs-utils-1.1.3-mountd-cleanup.patch @@ -0,0 +1,192 @@ +commit 60107345a32982bb0ff9eb8a17f8f0edf0276a98 +Author: J. Bruce Fields +Date: Thu Aug 28 11:20:58 2008 -0400 + + Minor mountd.c cleanup + + I find it more readable to have the normal (non-error) case unindented, + and to keep conditionals relatively simple, as is the usual kernel + style. Fix some inconsistent indentation while we're there. + + Signed-off-by: J. Bruce Fields + Signed-off-by: Steve Dickson + +diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c +index 0facf89..d5b8c0d 100644 +--- a/utils/mountd/mountd.c ++++ b/utils/mountd/mountd.c +@@ -175,9 +175,9 @@ killer (int sig) + static void + sig_hup (int sig) + { +- /* don't exit on SIGHUP */ +- xlog (L_NOTICE, "Received SIGHUP... Ignoring.\n", sig); +- return; ++ /* don't exit on SIGHUP */ ++ xlog (L_NOTICE, "Received SIGHUP... Ignoring.\n", sig); ++ return; + } + + bool_t +@@ -192,7 +192,8 @@ mount_mnt_1_svc(struct svc_req *rqstp, dirpath *path, fhstatus *res) + struct nfs_fh_len *fh; + + xlog(D_CALL, "MNT1(%s) called", *path); +- if ((fh = get_rootfh(rqstp, path, &res->fhs_status, 0)) != NULL) ++ fh = get_rootfh(rqstp, path, &res->fhs_status, 0); ++ if (fh) + memcpy(&res->fhstatus_u.fhs_fhandle, fh->fh_handle, 32); + return 1; + } +@@ -304,7 +305,8 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res) + } + + /* Now authenticate the intruder... */ +- if (!(exp = auth_authenticate("pathconf", sin, p))) { ++ exp = auth_authenticate("pathconf", sin, p); ++ if (!exp) { + return 1; + } else if (stat(p, &stb) < 0) { + xlog(L_WARNING, "can't stat exported dir %s: %s", +@@ -344,18 +346,18 @@ mount_mnt_3_svc(struct svc_req *rqstp, dirpath *path, mountres3 *res) + * issue with older Linux clients, who inspect the list in reversed + * order. + */ ++ struct mountres3_ok *ok = &res->mountres3_u.mountinfo; + struct nfs_fh_len *fh; + + xlog(D_CALL, "MNT3(%s) called", *path); +- if ((fh = get_rootfh(rqstp, path, &res->fhs_status, 1)) != NULL) { +- struct mountres3_ok *ok = &res->mountres3_u.mountinfo; +- +- ok->fhandle.fhandle3_len = fh->fh_size; +- ok->fhandle.fhandle3_val = (char *)fh->fh_handle; +- ok->auth_flavors.auth_flavors_len +- = sizeof(flavors)/sizeof(flavors[0]); +- ok->auth_flavors.auth_flavors_val = flavors; +- } ++ fh = get_rootfh(rqstp, path, &res->fhs_status, 1); ++ if (!fh) ++ return 1; ++ ++ ok->fhandle.fhandle3_len = fh->fh_size; ++ ok->fhandle.fhandle3_val = (char *)fh->fh_handle; ++ ok->auth_flavors.auth_flavors_len = sizeof(flavors)/sizeof(flavors[0]); ++ ok->auth_flavors.auth_flavors_val = flavors; + return 1; + } + +@@ -366,6 +368,7 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3) + (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); + struct stat stb, estb; + nfs_export *exp; ++ struct nfs_fh_len *fh; + char rpath[MAXPATHLEN+1]; + char *p = *path; + +@@ -382,57 +385,65 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3) + } + + /* Now authenticate the intruder... */ +- if (!(exp = auth_authenticate("mount", sin, p))) { ++ exp = auth_authenticate("mount", sin, p); ++ if (!exp) { + *error = NFSERR_ACCES; +- } else if (stat(p, &stb) < 0) { ++ return NULL; ++ } ++ if (stat(p, &stb) < 0) { + xlog(L_WARNING, "can't stat exported dir %s: %s", + p, strerror(errno)); + if (errno == ENOENT) + *error = NFSERR_NOENT; + else + *error = NFSERR_ACCES; +- } else if (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) { ++ return NULL; ++ } ++ if (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) { + xlog(L_WARNING, "%s is not a directory or regular file", p); + *error = NFSERR_NOTDIR; +- } else if (stat(exp->m_export.e_path, &estb) < 0) { ++ return NULL; ++ } ++ if (stat(exp->m_export.e_path, &estb) < 0) { + xlog(L_WARNING, "can't stat export point %s: %s", + p, strerror(errno)); + *error = NFSERR_NOENT; +- } else if (estb.st_dev != stb.st_dev +- && (!new_cache || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT)) +- ) { ++ return NULL; ++ } ++ if (estb.st_dev != stb.st_dev ++ && (!new_cache ++ || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT))) { + xlog(L_WARNING, "request to export directory %s below nearest filesystem %s", + p, exp->m_export.e_path); + *error = NFSERR_ACCES; +- } else if (exp->m_export.e_mountpoint && ++ return NULL; ++ } ++ if (exp->m_export.e_mountpoint && + !is_mountpoint(exp->m_export.e_mountpoint[0]? + exp->m_export.e_mountpoint: + exp->m_export.e_path)) { + xlog(L_WARNING, "request to export an unmounted filesystem: %s", + p); + *error = NFSERR_NOENT; +- } else if (new_cache) { ++ return NULL; ++ } ++ ++ if (new_cache) { + /* This will be a static private nfs_export with just one + * address. We feed it to kernel then extract the filehandle, + * + */ +- struct nfs_fh_len *fh; + + if (cache_export(exp, p)) { + *error = NFSERR_ACCES; + return NULL; + } + fh = cache_get_filehandle(exp, v3?64:32, p); +- if (fh == NULL) ++ if (fh == NULL) { + *error = NFSERR_ACCES; +- else { +- *error = NFS_OK; +- mountlist_add(inet_ntoa(sin->sin_addr), p); ++ return NULL; + } +- return fh; + } else { +- struct nfs_fh_len *fh; +- + if (exp->m_exported<1) + export_export(exp); + if (!exp->m_xtabent) +@@ -448,15 +459,15 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3) + fh = getfh_old ((struct sockaddr *) sin, + stb.st_dev, stb.st_ino); + } +- if (fh != NULL) { +- mountlist_add(inet_ntoa(sin->sin_addr), p); +- *error = NFS_OK; +- return fh; ++ if (fh == NULL) { ++ xlog(L_WARNING, "getfh failed: %s", strerror(errno)); ++ *error = NFSERR_ACCES; ++ return NULL; + } +- xlog(L_WARNING, "getfh failed: %s", strerror(errno)); +- *error = NFSERR_ACCES; + } +- return NULL; ++ *error = NFS_OK; ++ mountlist_add(inet_ntoa(sin->sin_addr), p); ++ return fh; + } + + static exports diff --git a/nfs-utils-1.1.3-mountd-gids.patch b/nfs-utils-1.1.3-mountd-gids.patch new file mode 100644 index 0000000..63ecc94 --- /dev/null +++ b/nfs-utils-1.1.3-mountd-gids.patch @@ -0,0 +1,29 @@ +commit 86c3a79a108091fe08869a887438cc2d4e1126ed +Author: Neil Brown +Date: Wed Aug 27 16:30:19 2008 -0400 + + mount issue with Mac OSX and --manage-gids, client hangs + + Make sure are zero len group list is sent down to the + kernel when the gids do not exist on the server. + + Tested-by: Alex Samad + Signed-off-by: Neil Brown + Signed-off-by: Steve Dickson + +diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c +index f555dcc..609c6e3 100644 +--- a/utils/mountd/cache.c ++++ b/utils/mountd/cache.c +@@ -158,8 +158,10 @@ void auth_unix_gid(FILE *f) + qword_printint(f, ngroups); + for (i=0; i +Date: Thu Aug 28 11:23:05 2008 -0400 + + Determine supported pseudoflavors from export + + Instead of using a static list of supported flavors, we should be taking + the list from the export. + + Signed-off-by: J. Bruce Fields + Signed-off-by: Steve Dickson + +diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c +index d5b8c0d..6adb68f 100644 +--- a/utils/mountd/mountd.c ++++ b/utils/mountd/mountd.c +@@ -26,6 +26,7 @@ + #include "misc.h" + #include "mountd.h" + #include "rpcmisc.h" ++#include "pseudoflavors.h" + + extern void cache_open(void); + extern struct nfs_fh_len *cache_get_filehandle(nfs_export *exp, int len, char *p); +@@ -35,7 +36,7 @@ extern void my_svc_run(void); + + static void usage(const char *, int exitcode); + static exports get_exportlist(void); +-static struct nfs_fh_len *get_rootfh(struct svc_req *, dirpath *, mountstat3 *, int v3); ++static struct nfs_fh_len *get_rootfh(struct svc_req *, dirpath *, nfs_export **, mountstat3 *, int v3); + + int reverse_resolve = 0; + int new_cache = 0; +@@ -192,7 +193,7 @@ mount_mnt_1_svc(struct svc_req *rqstp, dirpath *path, fhstatus *res) + struct nfs_fh_len *fh; + + xlog(D_CALL, "MNT1(%s) called", *path); +- fh = get_rootfh(rqstp, path, &res->fhs_status, 0); ++ fh = get_rootfh(rqstp, path, NULL, &res->fhs_status, 0); + if (fh) + memcpy(&res->fhstatus_u.fhs_fhandle, fh->fh_handle, 32); + return 1; +@@ -330,39 +331,57 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res) + } + + /* ++ * We should advertise the preferred flavours first. (See RFC 2623 ++ * section 2.7.) We leave that to the administrator, by advertising ++ * flavours in the order they were listed in /etc/exports. AUTH_NULL is ++ * dropped from the list to avoid backward compatibility issue with ++ * older Linux clients, who inspect the list in reversed order. ++ * ++ * XXX: It might be more helpful to rearrange these so that flavors ++ * giving more access (as determined from readonly and id-squashing ++ * options) come first. (If we decide to do that we should probably do ++ * that when reading the exports rather than here.) ++ */ ++static void set_authflavors(struct mountres3_ok *ok, nfs_export *exp) ++{ ++ struct sec_entry *s; ++ static int flavors[SECFLAVOR_COUNT]; ++ int i = 0; ++ ++ for (s = exp->m_export.e_secinfo; s->flav; s++) { ++ if (s->flav->fnum == AUTH_NULL) ++ continue; ++ flavors[i] = s->flav->fnum; ++ i++; ++ } ++ ok->auth_flavors.auth_flavors_val = flavors; ++ ok->auth_flavors.auth_flavors_len = i; ++} ++ ++/* + * NFSv3 MOUNT procedure + */ + bool_t + mount_mnt_3_svc(struct svc_req *rqstp, dirpath *path, mountres3 *res) + { +-#define AUTH_GSS_KRB5 390003 +-#define AUTH_GSS_KRB5I 390004 +-#define AUTH_GSS_KRB5P 390005 +- static int flavors[] = { AUTH_UNIX, AUTH_GSS_KRB5, AUTH_GSS_KRB5I, AUTH_GSS_KRB5P}; +- /* +- * We should advertise the preferred flavours first. (See RFC 2623 +- * section 2.7.) AUTH_UNIX is arbitrarily ranked over the GSS's. +- * AUTH_NULL is dropped from the list to avoid backward compatibility +- * issue with older Linux clients, who inspect the list in reversed +- * order. +- */ + struct mountres3_ok *ok = &res->mountres3_u.mountinfo; ++ nfs_export *exp; + struct nfs_fh_len *fh; + + xlog(D_CALL, "MNT3(%s) called", *path); +- fh = get_rootfh(rqstp, path, &res->fhs_status, 1); ++ fh = get_rootfh(rqstp, path, &exp, &res->fhs_status, 1); + if (!fh) + return 1; + + ok->fhandle.fhandle3_len = fh->fh_size; + ok->fhandle.fhandle3_val = (char *)fh->fh_handle; +- ok->auth_flavors.auth_flavors_len = sizeof(flavors)/sizeof(flavors[0]); +- ok->auth_flavors.auth_flavors_val = flavors; ++ set_authflavors(ok, exp); + return 1; + } + + static struct nfs_fh_len * +-get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3) ++get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret, ++ mountstat3 *error, int v3) + { + struct sockaddr_in *sin = + (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); +@@ -467,6 +486,8 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3) + } + *error = NFS_OK; + mountlist_add(inet_ntoa(sin->sin_addr), p); ++ if (expret) ++ *expret = exp; + return fh; + } + diff --git a/nfs-utils-1.1.3-mountd-rm-m_path.patch b/nfs-utils-1.1.3-mountd-rm-m_path.patch new file mode 100644 index 0000000..cea8141 --- /dev/null +++ b/nfs-utils-1.1.3-mountd-rm-m_path.patch @@ -0,0 +1,184 @@ +commit 124b74413e943ab9c02cdff2832d1d81dc9fda87 +Author: J. Bruce Fields +Date: Thu Aug 28 11:17:34 2008 -0400 + + Remove redundant m_path field + + Contrary to the comment above its definition, the field m_path always + has the same value as e_path: the *only* modifications of m_path are all + of the form: + + strncpy(exp->m_export.m_path, exp->m_export.e_path, + sizeof (exp->m_export.m_path) - 1); + exp->m_export.m_path[sizeof (exp->m_export.m_path) - 1] = '\0'; + + So m_path is always just a copy of e_path. In places where we need to + store a path to a submount of a CROSSMNT-exported filesystem, as in + cache.c, we just use a local variable. + + Signed-off-by: J. Bruce Fields + Signed-off-by: Steve Dickson + +diff --git a/support/export/export.c b/support/export/export.c +index 93c58b6..14af112 100644 +--- a/support/export/export.c ++++ b/support/export/export.c +@@ -255,15 +255,3 @@ export_freeall(void) + } + client_freeall(); + } +- +-void +-export_reset(nfs_export *exp) +-{ +- if (!exp) +- return; +- +- /* Restore m_path. */ +- strncpy(exp->m_export.m_path, exp->m_export.e_path, +- sizeof (exp->m_export.m_path) - 1); +- exp->m_export.m_path[sizeof (exp->m_export.m_path) - 1] = '\0'; +-} +diff --git a/support/export/nfsctl.c b/support/export/nfsctl.c +index 32d92bd..e2877b9 100644 +--- a/support/export/nfsctl.c ++++ b/support/export/nfsctl.c +@@ -89,11 +89,11 @@ expsetup(struct nfsctl_export *exparg, nfs_export *exp, int unexport) + nfs_client *clp = exp->m_client; + struct stat stb; + +- if (stat(exp->m_export.m_path, &stb) < 0) ++ if (stat(exp->m_export.e_path, &stb) < 0) + return 0; + + memset(exparg, 0, sizeof(*exparg)); +- strncpy(exparg->ex_path, exp->m_export.m_path, ++ strncpy(exparg->ex_path, exp->m_export.e_path, + sizeof (exparg->ex_path) - 1); + strncpy(exparg->ex_client, clp->m_hostname, + sizeof (exparg->ex_client) - 1); +diff --git a/support/include/nfslib.h b/support/include/nfslib.h +index 422b012..a51d79d 100644 +--- a/support/include/nfslib.h ++++ b/support/include/nfslib.h +@@ -67,11 +67,6 @@ struct sec_entry { + struct exportent { + char * e_hostname; + char e_path[NFS_MAXPATHLEN+1]; +- /* The mount path may be different from the exported path due +- to submount. It may change for every mount. The idea is we +- set m_path every time when we process a mount. We should not +- use it for anything else. */ +- char m_path[NFS_MAXPATHLEN+1]; + int e_flags; + int e_anonuid; + int e_anongid; +diff --git a/support/nfs/exports.c b/support/nfs/exports.c +index 334c08e..1aaebf4 100644 +--- a/support/nfs/exports.c ++++ b/support/nfs/exports.c +@@ -127,8 +127,6 @@ getexportent(int fromkernel, int fromexports) + if (ok <= 0) + return NULL; + +- strncpy (def_ee.m_path, def_ee.e_path, sizeof (def_ee.m_path) - 1); +- def_ee.m_path [sizeof (def_ee.m_path) - 1] = '\0'; + ok = getexport(exp, sizeof(exp)); + } + if (ok < 0) { +@@ -187,8 +185,6 @@ getexportent(int fromkernel, int fromexports) + rpath[sizeof (rpath) - 1] = '\0'; + strncpy(ee.e_path, rpath, sizeof (ee.e_path) - 1); + ee.e_path[sizeof (ee.e_path) - 1] = '\0'; +- strncpy (ee.m_path, ee.e_path, sizeof (ee.m_path) - 1); +- ee.m_path [sizeof (ee.m_path) - 1] = '\0'; + } + + return ⅇ +@@ -360,8 +356,6 @@ mkexportent(char *hname, char *path, char *options) + } + strncpy(ee.e_path, path, sizeof (ee.e_path)); + ee.e_path[sizeof (ee.e_path) - 1] = '\0'; +- strncpy (ee.m_path, ee.e_path, sizeof (ee.m_path) - 1); +- ee.m_path [sizeof (ee.m_path) - 1] = '\0'; + if (parseopts(options, &ee, 0, NULL) < 0) + return NULL; + return ⅇ +diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c +index 8137f7f..0facf89 100644 +--- a/utils/mountd/mountd.c ++++ b/utils/mountd/mountd.c +@@ -230,9 +230,6 @@ mount_umnt_1_svc(struct svc_req *rqstp, dirpath *argp, void *resp) + return 1; + } + +- if (!new_cache) +- export_reset (exp); +- + mountlist_del(inet_ntoa(sin->sin_addr), p); + return 1; + } +@@ -312,7 +309,6 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res) + } else if (stat(p, &stb) < 0) { + xlog(L_WARNING, "can't stat exported dir %s: %s", + p, strerror(errno)); +- export_reset (exp); + return 1; + } + +@@ -328,8 +324,6 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res) + res->pc_mask[0] = 0; + res->pc_mask[1] = 0; + +- export_reset (exp); +- + return 1; + } + +@@ -457,13 +451,11 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3) + if (fh != NULL) { + mountlist_add(inet_ntoa(sin->sin_addr), p); + *error = NFS_OK; +- export_reset (exp); + return fh; + } + xlog(L_WARNING, "getfh failed: %s", strerror(errno)); + *error = NFSERR_ACCES; + } +- export_reset (exp); + return NULL; + } + +@@ -499,14 +491,14 @@ get_exportlist(void) + for (i = 0; i < MCL_MAXTYPES; i++) { + for (exp = exportlist[i]; exp; exp = exp->m_next) { + for (e = elist; e != NULL; e = e->ex_next) { +- if (!strcmp(exp->m_export.m_path, e->ex_dir)) ++ if (!strcmp(exp->m_export.e_path, e->ex_dir)) + break; + } + if (!e) { + e = (struct exportnode *) xmalloc(sizeof(*e)); + e->ex_next = elist; + e->ex_groups = NULL; +- e->ex_dir = xstrdup(exp->m_export.m_path); ++ e->ex_dir = xstrdup(exp->m_export.e_path); + elist = e; + } + +diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c +index e8aff5a..5787ed6 100644 +--- a/utils/mountd/rmtab.c ++++ b/utils/mountd/rmtab.c +@@ -162,10 +162,8 @@ mountlist_del_all(struct sockaddr_in *sin) + } + while ((rep = getrmtabent(1, NULL)) != NULL) { + if (strcmp(rep->r_client, hp->h_name) == 0 && +- (exp = auth_authenticate("umountall", sin, rep->r_path))) { +- export_reset(exp); ++ (exp = auth_authenticate("umountall", sin, rep->r_path))) + continue; +- } + fputrmtabent(fp, rep, NULL); + } + if (slink_safe_rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) { diff --git a/nfs-utils-1.1.3-mountd-uuid-explicit.patch b/nfs-utils-1.1.3-mountd-uuid-explicit.patch new file mode 100644 index 0000000..1decc02 --- /dev/null +++ b/nfs-utils-1.1.3-mountd-uuid-explicit.patch @@ -0,0 +1,44 @@ +commit 0ae97c5b87a56870e74a74ae50aeb2ae0e496907 +Author: David Woodhouse +Date: Thu Aug 28 10:29:54 2008 -0400 + + Fix handling of explicit uuid + + Fix a couple of bugs which show up if you try to explicitly set a + 16-byte UUID when exporting a file system. First, exportfs cuts the + first two bytes off the UUID and writes something invalid to etab. + Second, mountd writes the _ascii_ form of the UUID to the kernel, + instead of converting it to hex. + + Signed-off-by: David Woodhouse + Signed-off-by: Steve Dickson + +diff --git a/support/nfs/exports.c b/support/nfs/exports.c +index 525e5b1..334c08e 100644 +--- a/support/nfs/exports.c ++++ b/support/nfs/exports.c +@@ -595,7 +595,7 @@ bad_option: + if (opt[5]!='\0' && *oe == '\0') + ep->e_flags |= NFSEXP_FSID; + else if (valid_uuid(opt+5)) +- ep->e_uuid = strdup(opt+7); ++ ep->e_uuid = strdup(opt+5); + else { + xlog(L_ERROR, "%s: %d: bad fsid \"%s\"\n", + flname, flline, opt); +diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c +index 609c6e3..2ebdd45 100644 +--- a/utils/mountd/cache.c ++++ b/utils/mountd/cache.c +@@ -592,8 +592,10 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex + qword_printhex(f, u, 16); + } + } else { ++ char u[16]; ++ get_uuid(NULL, exp->e_uuid, 16, u); + qword_print(f, "uuid"); +- qword_printhex(f, exp->e_uuid, 16); ++ qword_printhex(f, u, 16); + } + #endif + } diff --git a/nfs-utils-1.1.3-mountd-uuid-noblkid.patch b/nfs-utils-1.1.3-mountd-uuid-noblkid.patch new file mode 100644 index 0000000..6b8b95a --- /dev/null +++ b/nfs-utils-1.1.3-mountd-uuid-noblkid.patch @@ -0,0 +1,149 @@ +commit 8d52fc2691783dc9ef5bd9d9a1fa4c0ec33b20bc +Author: David Woodhouse +Date: Thu Aug 28 10:56:57 2008 -0400 + + Explicit UUID handling doesn't require blkid; factor out get_uuid_blkdev() + + Signed-off-by: David Woodhouse + Signed-off-by: Steve Dickson + +diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c +index 2ebdd45..23e2344 100644 +--- a/utils/mountd/cache.c ++++ b/utils/mountd/cache.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -167,6 +168,41 @@ void auth_unix_gid(FILE *f) + } + + #if USE_BLKID ++static const char *get_uuid_blkdev(char *path) ++{ ++ static blkid_cache cache = NULL; ++ struct stat stb; ++ char *devname; ++ blkid_tag_iterate iter; ++ blkid_dev dev; ++ const char *type; ++ const char *val = NULL; ++ ++ if (cache == NULL) ++ blkid_get_cache(&cache, NULL); ++ ++ if (stat(path, &stb) != 0) ++ return NULL; ++ devname = blkid_devno_to_devname(stb.st_dev); ++ if (!devname) ++ return NULL; ++ dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL); ++ free(devname); ++ if (!dev) ++ return NULL; ++ iter = blkid_tag_iterate_begin(dev); ++ if (!iter) ++ return NULL; ++ while (blkid_tag_next(iter, &type, &val) == 0) ++ if (strcmp(type, "UUID") == 0) ++ break; ++ blkid_tag_iterate_end(iter); ++ return val; ++} ++#else ++#define get_uuid_blkdev(path) (NULL) ++#endif ++ + int get_uuid(char *path, char *uuid, int uuidlen, char *u) + { + /* extract hex digits from uuidstr and compose a uuid +@@ -174,35 +210,12 @@ int get_uuid(char *path, char *uuid, int uuidlen, char *u) + * a smaller uuid. Then compare with uuid + */ + int i = 0; +- const char *val; ++ const char *val = NULL; ++ char fsid_val[17]; + + if (path) { +- static blkid_cache cache = NULL; +- struct stat stb; +- char *devname; +- blkid_tag_iterate iter; +- blkid_dev dev; +- const char *type; +- if (cache == NULL) +- blkid_get_cache(&cache, NULL); +- +- if (stat(path, &stb) != 0) +- return 0; +- devname = blkid_devno_to_devname(stb.st_dev); +- if (!devname) +- return 0; +- dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL); +- free(devname); +- if (!dev) +- return 0; +- iter = blkid_tag_iterate_begin(dev); +- if (!iter) +- return 0; +- while (blkid_tag_next(iter, &type, &val) == 0) +- if (strcmp(type, "UUID") == 0) +- break; +- blkid_tag_iterate_end(iter); +- if (!type) ++ val = get_uuid_blkdev(path); ++ if (!val) + return 0; + } else { + val = uuid; +@@ -229,7 +242,6 @@ int get_uuid(char *path, char *uuid, int uuidlen, char *u) + } + return 1; + } +-#endif + + /* Iterate through /etc/mtab, finding mountpoints + * at or below a given path +@@ -439,20 +451,15 @@ void nfsd_fh(FILE *f) + if (!is_mountpoint(path)) + continue; + check_uuid: +-#if USE_BLKID + if (exp->m_export.e_uuid) + get_uuid(NULL, exp->m_export.e_uuid, + uuidlen, u); +- else if (get_uuid(path, NULL, +- uuidlen, u) == 0) ++ else if (get_uuid(path, NULL, uuidlen, u) == 0) + continue; + + if (memcmp(u, fhuuid, uuidlen) != 0) + continue; + break; +-#else +- continue; +-#endif + } + if (use_ipaddr) { + if (he == NULL) { +@@ -584,7 +591,6 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex + qword_printint(f, exp->e_fsid); + write_fsloc(f, exp, path); + write_secinfo(f, exp); +-#if USE_BLKID + if (exp->e_uuid == NULL || different_fs) { + char u[16]; + if (get_uuid(path, NULL, 16, u)) { +@@ -597,7 +603,6 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex + qword_print(f, "uuid"); + qword_printhex(f, u, 16); + } +-#endif + } + return qword_eol(f); + } diff --git a/nfs-utils-1.1.3-mountd-uuid-stat.patch b/nfs-utils-1.1.3-mountd-uuid-stat.patch new file mode 100644 index 0000000..8548937 --- /dev/null +++ b/nfs-utils-1.1.3-mountd-uuid-stat.patch @@ -0,0 +1,33 @@ +commit 3a340251597a5b0c579c31d8caf9aa3b53a77016 +Author: David Woodhouse +Date: Thu Aug 28 11:05:17 2008 -0400 + + Use fsid from statfs for UUID if blkid can't cope (or not used) + + Signed-off-by: David Woodhouse + Signed-off-by: Steve Dickson + +diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c +index 23e2344..fa15472 100644 +--- a/utils/mountd/cache.c ++++ b/utils/mountd/cache.c +@@ -215,8 +215,17 @@ int get_uuid(char *path, char *uuid, int uuidlen, char *u) + + if (path) { + val = get_uuid_blkdev(path); +- if (!val) +- return 0; ++ if (!val) { ++ struct statfs64 st; ++ ++ if (statfs64(path, &st)) ++ return 0; ++ if (!st.f_fsid.__val[0] && !st.f_fsid.__val[1]) ++ return 0; ++ snprintf(fsid_val, 17, "%08x%08x", ++ st.f_fsid.__val[0], st.f_fsid.__val[1]); ++ val = fsid_val; ++ } + } else { + val = uuid; + } diff --git a/nfs-utils-1.1.3-network-conn-udp-ports.patch b/nfs-utils-1.1.3-network-conn-udp-ports.patch new file mode 100644 index 0000000..aeb2bf4 --- /dev/null +++ b/nfs-utils-1.1.3-network-conn-udp-ports.patch @@ -0,0 +1,45 @@ +commit 92e4d5c342f15940362fc2b2df19df0893f0dd13 +Author: Neil Brown +Date: Thu Aug 28 11:32:33 2008 -0400 + + mount: enable retry for nfs23 to set the correct protocol for mount. + + Use a connected port when talking to portmap via UDP. + + This allows us to get ICMP errors reported back so we can avoid + timeouts. Also catch the error (RPC_CANTRECV) properly in getport. + + Signed-off-by: NeilBrown + Signed-off-by: Steve Dickson + +diff --git a/utils/mount/network.c b/utils/mount/network.c +index 0023769..2db694d 100644 +--- a/utils/mount/network.c ++++ b/utils/mount/network.c +@@ -465,7 +465,7 @@ static unsigned short getport(struct sockaddr_in *saddr, + bind_saddr = *saddr; + bind_saddr.sin_port = htons(PMAPPORT); + +- socket = get_socket(&bind_saddr, proto, PMAP_TIMEOUT, FALSE, FALSE); ++ socket = get_socket(&bind_saddr, proto, PMAP_TIMEOUT, FALSE, TRUE); + if (socket == RPC_ANYSOCK) { + if (proto == IPPROTO_TCP && + rpc_createerr.cf_error.re_errno == ETIMEDOUT) +@@ -554,6 +554,7 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions, + } + if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED && + rpc_createerr.cf_stat != RPC_TIMEDOUT && ++ rpc_createerr.cf_stat != RPC_CANTRECV && + rpc_createerr.cf_stat != RPC_PROGVERSMISMATCH) + goto out_bad; + +@@ -562,7 +563,8 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions, + continue; + p_prot = protos; + } +- if (rpc_createerr.cf_stat == RPC_TIMEDOUT) ++ if (rpc_createerr.cf_stat == RPC_TIMEDOUT || ++ rpc_createerr.cf_stat == RPC_CANTRECV) + goto out_bad; + + if (vers || !*++p_vers) diff --git a/nfs-utils.spec b/nfs-utils.spec index 064d646..6c477f0 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.1.3 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 1 # group all 32bit related archs @@ -31,6 +31,16 @@ Patch90: nfs-utils-1.1.0-mount-fsc.patch %endif Patch100: nfs-utils-1.1.3-glibc22.patch +Patch101: nfs-utils-1.1.3-mountd-gids.patch +Patch102: nfs-utils-1.1.3-mountd-uuid-explicit.patch +Patch103: nfs-utils-1.1.3-mountd-uuid-noblkid.patch +Patch104: nfs-utils-1.1.3-mountd-uuid-stat.patch +Patch105: nfs-utils-1.1.3-exportfs-uuid-nowarn.patch +Patch106: nfs-utils-1.1.3-mountd-rm-m_path.patch +Patch107: nfs-utils-1.1.3-mountd-cleanup.patch +Patch108: nfs-utils-1.1.3-mountd-pseudoflavor-support.patch +Patch109: nfs-utils-1.1.3-idmapd-rm-idmapconf.patch +Patch110: nfs-utils-1.1.3-network-conn-udp-ports.patch Group: System Environment/Daemons Provides: exportfs = %{epoch}:%{version}-%{release} @@ -86,6 +96,16 @@ This package also contains the mount.nfs and umount.nfs program. %endif %patch100 -p1 +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch104 -p1 +%patch105 -p1 +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 +%patch109 -p1 +%patch110 -p1 # Remove .orig files find . -name "*.orig" | xargs rm -f @@ -245,6 +265,9 @@ fi %attr(4755,root,root) /sbin/umount.nfs4 %changelog +* Thu Aug 28 2008 Steve Dickson 1.1.3-4 +- Added in a number of up upstream patches (101 thru 110). + * Mon Aug 11 2008 Tom "spot" Callaway 1.1.3-3 - fix license tag