From f76c8ecabe22930c273c123bb1e5d1893d35fea8 Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Mar 05 2009 12:57:02 +0000 Subject: Updated to latest upstream version: 1.1.5 --- diff --git a/.cvsignore b/.cvsignore index e852eba..fcb926e 100644 --- a/.cvsignore +++ b/.cvsignore @@ -14,3 +14,4 @@ nfs-utils-1.1.1.tar.bz2 nfs-utils-1.1.2.tar.bz2 nfs-utils-1.1.3.tar.bz2 nfs-utils-1.1.4.tar.bz2 +nfs-utils-1.1.5.tar.bz2 diff --git a/nfs-utils-1.1.4-configure-tirpc.patch b/nfs-utils-1.1.4-configure-tirpc.patch deleted file mode 100644 index 5158256..0000000 --- a/nfs-utils-1.1.4-configure-tirpc.patch +++ /dev/null @@ -1,142 +0,0 @@ -commit aee8b1ab778f8e07b30305f10d4f9427023e314d -Author: Chuck Lever -Date: Wed Jan 7 12:06:14 2009 -0500 - - configure: Remove inet_ntop(3) check from configure.ac - - nfs-utils no longer uses inet_ntop(3) so remove checks for it from - configure.ac. - -commit ba05418f589c2d01f4e7e44c70d4844f43511927 -Author: Chuck Lever -Date: Wed Jan 7 12:18:11 2009 -0500 - - configure: Add new build option "--enable-tirpc" - - Allow easier testing of nfs-utils in legacy environments by providing - a "configure" option to force the build not to use libtirpc, even if - it's present on the build system. This can also be tried as a - fallback if problems are found with the new TI-RPC-based nfs-utils - code. - - The new option is: - - --enable-tirpc enable use of TI-RPC [default=no] - - Build option matrix: - - --disable-tirpc --disable-ipv6 Default; IPv4 only, glibc RPC - --disable-tirpc --enable-ipv6 'configure' will fail - --enable-tirpc --disable-ipv6 IPv4 only, TI-RPC - --enable-tirpc --enable-ipv6 IPv4 and IPv6, TI-RPC - -commit 29ac873f9024c8fcbca38ab09ba54cda3765b746 -Author: Chuck Lever -Date: Wed Jan 7 12:33:09 2009 -0500 - - showmount command: Quiesce warning when TI-RPC is disabled - - Make sure nfs_sm_pgmtbl is not compiled if TI-RPC functions are not - available. This quiesces the following compiler warning: - - showmount.c:53: warning: nfs_sm_pgmtbl defined but not used - -diff -up nfs-utils-1.1.4/configure.ac.save nfs-utils-1.1.4/configure.ac ---- nfs-utils-1.1.4/configure.ac.save 2009-01-07 12:52:29.000000000 -0500 -+++ nfs-utils-1.1.4/configure.ac 2009-01-07 12:52:50.000000000 -0500 -@@ -131,6 +131,14 @@ AC_ARG_ENABLE(ipv6, - AC_SUBST(enable_ipv6) - AM_CONDITIONAL(CONFIG_IPV6, [test "$enable_ipv6" = "yes"]) - -+AC_ARG_ENABLE(tirpc, -+ [AC_HELP_STRING([--enable-tirpc], -+ [enable use of TI-RPC @<:@default=no@:>@])], -+ enable_tirpc=$enableval, -+ enable_tirpc=no) -+ AC_SUBST(enable_tirpc) -+ AM_CONDITIONAL(CONFIG_TIRPC, [test "$enable_tirpc" = "yes"]) -+ - # Check whether user wants TCP wrappers support - AC_TCP_WRAPPERS - -@@ -251,15 +259,22 @@ AC_CHECK_DECL([AI_ADDRCONFIG], - [Define this to 1 if AI_ADDRCONFIG macro is defined]), , - [ #include ] ) - -+if test "$enable_tirpc" = yes; then -+ AC_CHECK_LIB(tirpc, clnt_tli_create, , -+ AC_MSG_ERROR([libtirpc not found.])) -+ AC_CHECK_HEADERS(tirpc/netconfig.h, , -+ AC_MSG_ERROR([libtirpc headers not found.])) -+ AC_CHECK_FUNCS([bindresvport_sa getnetconfig \ -+ clnt_create clnt_create_timed \ -+ clnt_vc_create clnt_dg_create xdr_rpcb]) -+fi -+ - if test "$enable_ipv6" = yes; then -- AC_CHECK_FUNC(inet_ntop, , , -- AC_MSG_ERROR(Function 'inet_ntop' not found.)) -+ if test "$enable_tirpc" = no; then -+ AC_MSG_ERROR('--enable-ipv6' requires '--enable-tirpc'.) -+ fi - AC_CHECK_FUNC(getnameinfo, , , - AC_MSG_ERROR(Function 'getnameinfo' not found.)) -- AC_CHECK_LIB(tirpc, clnt_tli_create, , -- AC_MSG_ERROR([libtirpc needed for IPv6 support])) -- AC_CHECK_HEADERS(tirpc/netconfig.h, , -- AC_MSG_ERROR([libtirpc headers needed for IPv6 support])) - AC_CHECK_DECL([AI_ADDRCONFIG], , - AC_MSG_ERROR([full getaddrinfo(3) implementation needed for IPv6 support]), - [ #include ] ) -@@ -273,7 +288,7 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h li - stdlib.h string.h sys/file.h sys/ioctl.h sys/mount.h \ - sys/param.h sys/socket.h sys/time.h sys/vfs.h \ - syslog.h unistd.h com_err.h et/com_err.h \ -- ifaddrs.h tirpc/netconfig.h]) -+ ifaddrs.h]) - - dnl ************************************************************* - dnl Checks for typedefs, structures, and compiler characteristics -@@ -309,10 +324,7 @@ AC_FUNC_STAT - AC_FUNC_VPRINTF - AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \ - gethostbyaddr gethostbyname gethostname getmntent \ -- inet_ntop getnameinfo getrpcbyname \ -- bindresvport_sa getnetconfig \ -- clnt_create clnt_create_timed \ -- clnt_tli_create clnt_vc_create clnt_dg_create xdr_rpcb \ -+ getnameinfo getrpcbyname \ - gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \ - realpath rmdir select socket strcasecmp strchr strdup \ - strerror strrchr strtol strtoul sigprocmask]) -diff -up nfs-utils-1.1.4/utils/showmount/showmount.c.save nfs-utils-1.1.4/utils/showmount/showmount.c ---- nfs-utils-1.1.4/utils/showmount/showmount.c.save 2009-01-07 12:53:26.000000000 -0500 -+++ nfs-utils-1.1.4/utils/showmount/showmount.c 2009-01-07 12:53:37.000000000 -0500 -@@ -50,13 +50,6 @@ static int aflag = 0; - static int dflag = 0; - static int eflag = 0; - --static const char *nfs_sm_pgmtbl[] = { -- "showmount", -- "mount", -- "mountd", -- NULL, --}; -- - static struct option longopts[] = - { - { "all", 0, 0, 'a' }, -@@ -87,6 +80,13 @@ static void usage(FILE *fp, int n) - - #ifdef HAVE_CLNT_CREATE - -+static const char *nfs_sm_pgmtbl[] = { -+ "showmount", -+ "mount", -+ "mountd", -+ NULL, -+}; -+ - /* - * Generate an RPC client handle connected to the mountd service - * at @hostname, or die trying. diff --git a/nfs-utils-1.1.4-configure-uuid.patch b/nfs-utils-1.1.4-configure-uuid.patch deleted file mode 100644 index d15cc2e..0000000 --- a/nfs-utils-1.1.4-configure-uuid.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- nfs-utils-1.1.4/configure.ac.orig 2009-01-06 12:27:23.944023000 -0500 -+++ nfs-utils-1.1.4/configure.ac 2009-01-06 12:29:43.128014000 -0500 -@@ -109,7 +109,7 @@ AC_ARG_WITH(rpcgen, - AC_SUBST(RPCGEN_PATH) - AM_CONDITIONAL(CONFIG_RPCGEN, [test "$RPCGEN_PATH" == ""]) - AC_ARG_ENABLE(uuid, -- [AC_HELP_STRING([--without-uuid], [Exclude uuid support and so avoid possibly buggy libblkid])], -+ [AC_HELP_STRING([--disable-uuid], [Exclude uuid support to avoid buggy libblkid])], - if test "$enableval" = "yes" ; then choose_blkid=yes; else choose_blkid=no; fi, - choose_blkid=default) - AC_ARG_ENABLE(mount, diff --git a/nfs-utils-1.1.4-configure.patch b/nfs-utils-1.1.4-configure.patch deleted file mode 100644 index 23ba4a2..0000000 --- a/nfs-utils-1.1.4-configure.patch +++ /dev/null @@ -1,64 +0,0 @@ -commit 38667906c89d6944faaced7fbcda027643dc10ad -Author: Chuck Lever -Date: Wed Mar 4 15:54:39 2009 -0500 - - configure: fix AC_CACHE_VAL warnings on Fedora 10 - - Autoconf 2.63 (and maybe earlier releases) complains about the cache - variable name used in aclocal/libblkid.m4: - - configure.ac:217: warning: AC_CACHE_VAL(libblkid_is_recent, ...): - suspicious cache-id, must contain _cv_ to be cached - ../../lib/autoconf/general.m4:1974: AC_CACHE_VAL is expanded from... - aclocal/libblkid.m4:2: AC_BLKID_VERS is expanded from... - configure.ac:217: the top level - - This addresses - https://bugzilla.redhat.com/attachment.cgi?bugid=481386 . - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -diff --git a/aclocal/libblkid.m4 b/aclocal/libblkid.m4 -index d751a8c..10824e9 100644 ---- a/aclocal/libblkid.m4 -+++ b/aclocal/libblkid.m4 -@@ -1,7 +1,7 @@ - dnl *************************** libblkid needs version 1.40 or later *********************** - AC_DEFUN([AC_BLKID_VERS], [ - AC_MSG_CHECKING(for suitable libblkid version) -- AC_CACHE_VAL(libblkid_is_recent, -+ AC_CACHE_VAL([libblkid_cv_is_recent], - [ - saved_LIBS="$LIBS" - LIBS=-lblkid -@@ -12,9 +12,8 @@ AC_DEFUN([AC_BLKID_VERS], [ - int vers = blkid_get_library_version(0, 0); - return vers >= 140 ? 0 : 1; - } -- ], libblkid_is_recent=yes, libblkid_is_recent=no, -- libblkid_is_recent=unknown) -- LIBS="$saved_LIBS" -- ])dnl -- AC_MSG_RESULT($libblkid_is_recent) -+ ], [libblkid_cv_is_recent=yes], [libblkid_cv_is_recent=no], -+ [libblkid_cv_is_recent=unknown]) -+ LIBS="$saved_LIBS"]) -+ AC_MSG_RESULT($libblkid_cv_is_recent) - ])dnl -diff --git a/configure.ac b/configure.ac -index c8508f1..4fd111f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -219,9 +219,9 @@ if test "$choose_blkid" != no; then - AC_BLKID_VERS - if test $choose_blkid = yes; then - use_blkid=1 -- test $libblkid_is_recent = no && AC_MSG_WARN([libblkid is old and may cause mountd to leak memory]) -+ test $libblkid_cv_is_recent = no && AC_MSG_WARN([libblkid is old and may cause mountd to leak memory]) - else -- if test $libblkid_is_recent = yes -+ if test $libblkid_cv_is_recent = yes - then use_blkid=1 - else use_blkid=0 - AC_MSG_WARN([uuid support disabled as libblkid is too old]) diff --git a/nfs-utils-1.1.4-export-hash.patch b/nfs-utils-1.1.4-export-hash.patch deleted file mode 100644 index 7e5373e..0000000 --- a/nfs-utils-1.1.4-export-hash.patch +++ /dev/null @@ -1,357 +0,0 @@ -commit 4cacc965afc4fb03a465ffcc6cb3078aeadc3818 -Author: Tomas Richter -Date: Wed Feb 18 13:33:27 2009 -0500 - - Exportfs and rpc.mountd optimalization - - There were some problems with exportfs and rpc.mountd for long export - lists - see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=76643 - I do optimalization as my bachelors thesis (Facuulty of informatics, - Masaryk's university Brno, Czech Republic), under lead of Yenya - Kasprzak. - - Both exportfs and rpc.mount build linked list of exports (shared - functions in export.c). Every time they are inserting new export into - list, they search for same export in list. - I replaced linked list by hash table and functions export_add and - export_lookup by functions hash_export_add and hash_export_lookup - (export.c). - - Because some other functions required exportlist as linked list, hash - table has some implementation modification im comparison with ordinary - hash table. It also keeps exports in linked list and has pointer to - head of the list. So there's no need of implementation function - . - - Signed-off-by: Tomas Richter - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/support/export/export.c.orig nfs-utils-1.1.4/support/export/export.c ---- nfs-utils-1.1.4/support/export/export.c.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/support/export/export.c 2009-02-18 19:42:13.000000000 -0500 -@@ -19,7 +19,8 @@ - #include "nfslib.h" - #include "exportfs.h" - --nfs_export *exportlist[MCL_MAXTYPES] = { NULL, }; -+exp_hash_table exportlist[MCL_MAXTYPES] = {{NULL, {{NULL,NULL}, }}, }; -+static int export_hash(char *); - - static void export_init(nfs_export *exp, nfs_client *clp, - struct exportent *nep); -@@ -125,22 +126,35 @@ export_dup(nfs_export *exp, struct hoste - - return new; - } -- --void -+/* -+ * Add export entry to hash table -+ */ -+void - export_add(nfs_export *exp) - { -- nfs_export **epp; -- int type = exp->m_client->m_type; -- int slen = strlen(exp->m_export.e_path); -- -- if (type < 0 || type >= MCL_MAXTYPES) -- xlog(L_FATAL, "unknown client type in export_add"); -- -- epp = exportlist + type; -- while (*epp && slen <= strlen((*epp)->m_export.e_path)) -- epp = &((*epp)->m_next); -- exp->m_next = *epp; -- *epp = exp; -+ exp_hash_table *p_tbl; -+ exp_hash_entry *p_hen; -+ nfs_export *p_next; -+ -+ int type = exp->m_client->m_type; -+ int pos; -+ -+ pos = export_hash(exp->m_export.e_path); -+ p_tbl = &(exportlist[type]); /* pointer to hash table */ -+ p_hen = &(p_tbl->entries[pos]); /* pointer to hash table entry */ -+ -+ if (!(p_hen->p_first)) { /* hash table entry is empty */ -+ p_hen->p_first = exp; -+ p_hen->p_last = exp; -+ -+ exp->m_next = p_tbl->p_head; -+ p_tbl->p_head = exp; -+ } else { /* hash table entry is NOT empty */ -+ p_next = p_hen->p_last->m_next; -+ p_hen->p_last->m_next = exp; -+ exp->m_next = p_next; -+ p_hen->p_last = exp; -+ } - } - - nfs_export * -@@ -150,7 +164,7 @@ export_find(struct hostent *hp, char *pa - int i; - - for (i = 0; i < MCL_MAXTYPES; i++) { -- for (exp = exportlist[i]; exp; exp = exp->m_next) { -+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { - if (!export_check(exp, hp, path)) - continue; - if (exp->m_client->m_type == MCL_FQDN) -@@ -169,7 +183,7 @@ export_allowed_internal (struct hostent - int i; - - for (i = 0; i < MCL_MAXTYPES; i++) { -- for (exp = exportlist[i]; exp; exp = exp->m_next) { -+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { - if (!exp->m_mayexport || - !export_check(exp, hp, path)) - continue; -@@ -207,17 +221,30 @@ export_allowed(struct hostent *hp, char - return NULL; - } - -+/* -+ * Search hash table for export entry. -+ */ - nfs_export * --export_lookup(char *hname, char *path, int canonical) -+export_lookup(char *hname, char *path, int canonical) - { -- nfs_client *clp; -- nfs_export *exp; -+ nfs_client *clp; -+ nfs_export *exp; -+ exp_hash_entry *p_hen; -+ -+ int pos; - -- if (!(clp = client_lookup(hname, canonical))) -+ clp = client_lookup(hname, canonical); -+ if(clp == NULL) - return NULL; -- for (exp = exportlist[clp->m_type]; exp; exp = exp->m_next) -- if (exp->m_client == clp && !strcmp(exp->m_export.e_path, path)) -- return exp; -+ -+ pos = export_hash(path); -+ p_hen = &(exportlist[clp->m_type].entries[pos]); -+ for(exp = p_hen->p_first; exp && (exp != p_hen->p_last->m_next); -+ exp = exp->m_next) { -+ if (exp->m_client == clp && !strcmp(exp->m_export.e_path, path)) { -+ return exp; -+ } -+ } - return NULL; - } - -@@ -234,10 +261,10 @@ void - export_freeall(void) - { - nfs_export *exp, *nxt; -- int i; -+ int i, j; - - for (i = 0; i < MCL_MAXTYPES; i++) { -- for (exp = exportlist[i]; exp; exp = nxt) { -+ for (exp = exportlist[i].p_head; exp; exp = nxt) { - nxt = exp->m_next; - client_release(exp->m_client); - if (exp->m_export.e_squids) -@@ -251,7 +278,40 @@ export_freeall(void) - xfree(exp->m_export.e_hostname); - xfree(exp); - } -- exportlist[i] = NULL; -+ for(j = 0; j < HASH_TABLE_SIZE; j++) { -+ exportlist[i].entries[j].p_first = NULL; -+ exportlist[i].entries[j].p_last = NULL; -+ } -+ exportlist[i].p_head = NULL; - } - client_freeall(); - } -+ -+/* -+ * Compute and returns integer from string. -+ * Note: Its understood the smae integers can be same for -+ * different strings, but it should not matter. -+ */ -+static unsigned int -+strtoint(char *str) -+{ -+ int i = 0; -+ unsigned int n = 0; -+ -+ while ( str[i] != '\0') { -+ n+=((int)str[i])*i; -+ i++; -+ } -+ return n; -+} -+ -+/* -+ * Hash function -+ */ -+static int -+export_hash(char *str) -+{ -+ int num = strtoint(str); -+ -+ return num % HASH_TABLE_SIZE; -+} -diff -up nfs-utils-1.1.4/support/export/xtab.c.orig nfs-utils-1.1.4/support/export/xtab.c ---- nfs-utils-1.1.4/support/export/xtab.c.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/support/export/xtab.c 2009-02-18 19:42:13.000000000 -0500 -@@ -100,7 +100,7 @@ xtab_write(char *xtab, char *xtabtmp, in - setexportent(xtabtmp, "w"); - - for (i = 0; i < MCL_MAXTYPES; i++) { -- for (exp = exportlist[i]; exp; exp = exp->m_next) { -+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { - if (is_export && !exp->m_xtabent) - continue; - if (!is_export && ! exp->m_exported) -diff -up nfs-utils-1.1.4/support/include/exportfs.h.orig nfs-utils-1.1.4/support/include/exportfs.h ---- nfs-utils-1.1.4/support/include/exportfs.h.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/support/include/exportfs.h 2009-02-18 19:42:13.000000000 -0500 -@@ -52,8 +52,21 @@ typedef struct mexport { - * matching one client */ - } nfs_export; - -+#define HASH_TABLE_SIZE 1021 -+ -+typedef struct _exp_hash_entry { -+ nfs_export * p_first; -+ nfs_export * p_last; -+} exp_hash_entry; -+ -+typedef struct _exp_hash_table { -+ nfs_export * p_head; -+ exp_hash_entry entries[HASH_TABLE_SIZE]; -+} exp_hash_table; -+ -+extern exp_hash_table exportlist[MCL_MAXTYPES]; -+ - extern nfs_client * clientlist[MCL_MAXTYPES]; --extern nfs_export * exportlist[MCL_MAXTYPES]; - - nfs_client * client_lookup(char *hname, int canonical); - nfs_client * client_find(struct hostent *); -@@ -69,7 +82,7 @@ struct hostent * client_resolve(struct - int client_member(char *client, char *name); - - int export_read(char *fname); --void export_add(nfs_export *); -+void export_add(nfs_export *); - void export_reset(nfs_export *); - nfs_export * export_lookup(char *hname, char *path, int caconical); - nfs_export * export_find(struct hostent *, char *path); -diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c ---- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-02-17 16:45:04.000000000 -0500 -+++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-02-18 19:42:13.000000000 -0500 -@@ -91,7 +91,7 @@ inline unsigned int strtoint(char *str) - - return n; - } --inline int hashint(unsigned int num) -+static inline int hashint(unsigned int num) - { - return num % HASH_TABLE_SIZE; - } -diff -up nfs-utils-1.1.4/utils/exportfs/exportfs.c.orig nfs-utils-1.1.4/utils/exportfs/exportfs.c ---- nfs-utils-1.1.4/utils/exportfs/exportfs.c.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/utils/exportfs/exportfs.c 2009-02-18 19:42:13.000000000 -0500 -@@ -111,7 +111,6 @@ main(int argc, char **argv) - return 0; - } - } -- - if (f_export && ! f_ignore) - export_read(_PATH_EXPORTS); - if (f_export) { -@@ -193,10 +192,10 @@ exports_update(int verbose) - { - nfs_export *exp; - -- for (exp = exportlist[MCL_FQDN]; exp; exp=exp->m_next) { -+ for (exp = exportlist[MCL_FQDN].p_head; exp; exp=exp->m_next) { - exports_update_one(exp, verbose); - } -- for (exp = exportlist[MCL_GSS]; exp; exp=exp->m_next) { -+ for (exp = exportlist[MCL_GSS].p_head; exp; exp=exp->m_next) { - exports_update_one(exp, verbose); - } - } -@@ -212,7 +211,7 @@ export_all(int verbose) - int i; - - for (i = 0; i < MCL_MAXTYPES; i++) { -- for (exp = exportlist[i]; exp; exp = exp->m_next) { -+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { - if (verbose) - printf("exporting %s:%s\n", - exp->m_client->m_hostname, -@@ -308,7 +307,7 @@ unexportfs(char *arg, int verbose) - } - } - -- for (exp = exportlist[htype]; exp; exp = exp->m_next) { -+ for (exp = exportlist[htype].p_head; exp; exp = exp->m_next) { - if (path && strcmp(path, exp->m_export.e_path)) - continue; - if (htype != exp->m_client->m_type) -@@ -453,7 +452,7 @@ dump(int verbose) - char *hname, c; - - for (htype = 0; htype < MCL_MAXTYPES; htype++) { -- for (exp = exportlist[htype]; exp; exp = exp->m_next) { -+ for (exp = exportlist[htype].p_head; exp; exp = exp->m_next) { - ep = &exp->m_export; - if (!exp->m_xtabent) - continue; /* neilb */ -diff -up nfs-utils-1.1.4/utils/mountd/auth.c.orig nfs-utils-1.1.4/utils/mountd/auth.c ---- nfs-utils-1.1.4/utils/mountd/auth.c.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/utils/mountd/auth.c 2009-02-18 19:42:13.000000000 -0500 -@@ -142,7 +142,7 @@ auth_authenticate_internal(char *what, s - - exp = NULL; - for (i = 0; !exp && i < MCL_MAXTYPES; i++) -- for (exp = exportlist[i]; exp; exp = exp->m_next) { -+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { - if (strcmp(path, exp->m_export.e_path)) - continue; - if (!use_ipaddr && !client_member(my_client.m_hostname, exp->m_client->m_hostname)) -diff -up nfs-utils-1.1.4/utils/mountd/cache.c.orig nfs-utils-1.1.4/utils/mountd/cache.c ---- nfs-utils-1.1.4/utils/mountd/cache.c.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/utils/mountd/cache.c 2009-02-18 19:42:13.000000000 -0500 -@@ -394,7 +394,7 @@ void nfsd_fh(FILE *f) - /* Now determine export point for this fsid/domain */ - for (i=0 ; i < MCL_MAXTYPES; i++) { - nfs_export *next_exp; -- for (exp = exportlist[i]; exp; exp = next_exp) { -+ for (exp = exportlist[i].p_head; exp; exp = next_exp) { - struct stat stb; - char u[16]; - char *path; -@@ -654,7 +654,7 @@ void nfsd_export(FILE *f) - - /* now find flags for this export point in this domain */ - for (i=0 ; i < MCL_MAXTYPES; i++) { -- for (exp = exportlist[i]; exp; exp = exp->m_next) { -+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { - if (!use_ipaddr && !client_member(dom, exp->m_client->m_hostname)) - continue; - if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) { -diff -up nfs-utils-1.1.4/utils/mountd/mountd.c.orig nfs-utils-1.1.4/utils/mountd/mountd.c ---- nfs-utils-1.1.4/utils/mountd/mountd.c.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/utils/mountd/mountd.c 2009-02-18 19:42:13.000000000 -0500 -@@ -521,7 +521,7 @@ get_exportlist(void) - elist = NULL; - - for (i = 0; i < MCL_MAXTYPES; i++) { -- for (exp = exportlist[i]; exp; exp = exp->m_next) { -+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { - for (e = elist; e != NULL; e = e->ex_next) { - if (!strcmp(exp->m_export.e_path, e->ex_dir)) - break; diff --git a/nfs-utils-1.1.4-gssd-dnotify.patch b/nfs-utils-1.1.4-gssd-dnotify.patch deleted file mode 100644 index 84962d1..0000000 --- a/nfs-utils-1.1.4-gssd-dnotify.patch +++ /dev/null @@ -1,48 +0,0 @@ -commit 068ea89e7d335d381276a2fff73d5abbb2b0a04d -Author: Neil Brown -Date: Wed Nov 26 08:48:03 2008 -0500 - - gssd: unblock DNOTIFY_SIGNAL in case it was blocked. - - I have a situation where rpc.gssd appears to not be working. - Mount attempts which need to communicate with it block. - - I've narrowed down the problem to that fact that all realtime signals - have been blocked. This means that DNOTIFY_SIGNAL (which is a - realtime signal) is never delivered, so gssd never rescans the - rpc_pipe/nfs directory. - - It seems start_kde (or whatever it is called) and all descendants have - these - signals blocked. xfce seems to do the same thing. gnome doesn't. - - So if you start rpc.gssd from a terminal window while logged in via - KDE, it doesn't behave as expected. - - Signed-off-by: Neil Brown - Signed-off-by: Steve Dickson - -diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c -index 84f04e9..b9f3a06 100644 ---- a/utils/gssd/gssd_main_loop.c -+++ b/utils/gssd/gssd_main_loop.c -@@ -99,6 +99,7 @@ gssd_run() - int ret; - struct sigaction dn_act; - int fd; -+ sigset_t set; - - /* Taken from linux/Documentation/dnotify.txt: */ - dn_act.sa_sigaction = dir_notify_handler; -@@ -106,6 +107,11 @@ gssd_run() - dn_act.sa_flags = SA_SIGINFO; - sigaction(DNOTIFY_SIGNAL, &dn_act, NULL); - -+ /* just in case the signal is blocked... */ -+ sigemptyset(&set); -+ sigaddset(&set, DNOTIFY_SIGNAL); -+ sigprocmask(SIG_UNBLOCK, &set, NULL); -+ - if ((fd = open(pipefs_nfsdir, O_RDONLY)) == -1) { - printerr(0, "ERROR: failed to open %s: %s\n", - pipefs_nfsdir, strerror(errno)); diff --git a/nfs-utils-1.1.4-gssd-verbosity.patch b/nfs-utils-1.1.4-gssd-verbosity.patch deleted file mode 100644 index 32ec518..0000000 --- a/nfs-utils-1.1.4-gssd-verbosity.patch +++ /dev/null @@ -1,136 +0,0 @@ -commit 09c7ad1cd9c5ca2fc46631a0057d47309abc8706 -Author: Kevin Coffman -Date: Mon Jan 5 14:07:05 2009 -0500 - - gssd: By default, don't spam syslog when users' credentials expire - - Change the priority of "common" log messages so that syslog doesn't get - slammed/spammed when users' credentials expire, or there is another - common - problem which would cause error messages for all context creation - requests. - - Note that this will now require that gssd or svcgssd option "-v" is used - to - debug these common cases. - - Original patch from Andrew Pollock . - - Signed-off-by: Kevin Coffman - Signed-off-by: Steve Dickson - CC: Andrew Pollock - -diff --git a/utils/gssd/gss_util.c b/utils/gssd/gss_util.c -index 8a7bcaa..2d66be9 100644 ---- a/utils/gssd/gss_util.c -+++ b/utils/gssd/gss_util.c -@@ -216,7 +216,7 @@ gssd_acquire_cred(char *server_name) - ignore_maj_stat = gss_display_name(&ignore_min_stat, - target_name, &pbuf, NULL); - if (ignore_maj_stat == GSS_S_COMPLETE) { -- printerr(0, "Unable to obtain credentials for '%.*s'\n", -+ printerr(1, "Unable to obtain credentials for '%.*s'\n", - pbuf.length, pbuf.value); - ignore_maj_stat = gss_release_buffer(&ignore_min_stat, - &pbuf); -diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c -index cb14d45..91fc8d2 100644 ---- a/utils/gssd/gssd_proc.c -+++ b/utils/gssd/gssd_proc.c -@@ -448,7 +448,7 @@ do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd, - return 0; - out_err: - if (buf) free(buf); -- printerr(0, "Failed to write downcall!\n"); -+ printerr(1, "Failed to write downcall!\n"); - return -1; - } - -@@ -741,14 +741,14 @@ handle_krb5_upcall(struct clnt_info *clp) - } - gssd_free_krb5_machine_cred_list(credlist); - if (!success) { -- printerr(0, "WARNING: Failed to create krb5 context " -+ printerr(1, "WARNING: Failed to create krb5 context " - "for user with uid %d with any " - "credentials cache for server %s\n", - uid, clp->servername); - goto out_return_error; - } - } else { -- printerr(0, "WARNING: Failed to create krb5 context " -+ printerr(1, "WARNING: Failed to create krb5 context " - "for user with uid %d for server %s\n", - uid, clp->servername); - goto out_return_error; -@@ -756,7 +756,7 @@ handle_krb5_upcall(struct clnt_info *clp) - } - - if (!authgss_get_private_data(auth, &pd)) { -- printerr(0, "WARNING: Failed to obtain authentication " -+ printerr(1, "WARNING: Failed to obtain authentication " - "data for user with uid %d for server %s\n", - uid, clp->servername); - goto out_return_error; -diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c -index 77814bc..d4ee631 100644 ---- a/utils/gssd/krb5_util.c -+++ b/utils/gssd/krb5_util.c -@@ -399,7 +399,7 @@ gssd_get_single_krb5_cred(krb5_context context, - goto out; - } - if (krb5_get_init_creds_opt_set_addressless(context, init_opts, 1)) -- printerr(0, "WARNING: Unable to set option for addressless " -+ printerr(1, "WARNING: Unable to set option for addressless " - "tickets. May have problems behind a NAT.\n"); - #ifdef TEST_SHORT_LIFETIME - /* set a short lifetime (for debugging only!) */ -@@ -422,7 +422,7 @@ gssd_get_single_krb5_cred(krb5_context context, - - if ((code = krb5_get_init_creds_keytab(context, &my_creds, ple->princ, - kt, 0, NULL, opts))) { -- printerr(0, "WARNING: %s while getting initial ticket for " -+ printerr(1, "WARNING: %s while getting initial ticket for " - "principal '%s' using keytab '%s'\n", - gssd_k5_err_msg(context, code), - pname ? pname : "", kt_name); -@@ -632,7 +632,7 @@ get_full_hostname(const char *inhost, char *outhost, int outhostlen) - /* Get full target hostname */ - retval = getaddrinfo(inhost, NULL, &hints, &addrs); - if (retval) { -- printerr(0, "%s while getting full hostname for '%s'\n", -+ printerr(1, "%s while getting full hostname for '%s'\n", - gai_strerror(retval), inhost); - goto out; - } -diff --git a/utils/gssd/svcgssd_proc.c b/utils/gssd/svcgssd_proc.c -index f162152..1d13532 100644 ---- a/utils/gssd/svcgssd_proc.c -+++ b/utils/gssd/svcgssd_proc.c -@@ -108,7 +108,7 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred, - fclose(f); - return err; - out_err: -- printerr(0, "WARNING: downcall failed\n"); -+ printerr(1, "WARNING: downcall failed\n"); - return -1; - } - -@@ -247,7 +247,7 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred) - res = 0; - goto out_free; - } -- printerr(0, "WARNING: get_ids: failed to map name '%s' " -+ printerr(1, "WARNING: get_ids: failed to map name '%s' " - "to uid/gid: %s\n", sname, strerror(-res)); - goto out_free; - } -@@ -380,7 +380,7 @@ handle_nullreq(FILE *f) { - goto continue_needed; - } - else if (maj_stat != GSS_S_COMPLETE) { -- printerr(0, "WARNING: gss_accept_sec_context failed\n"); -+ printerr(1, "WARNING: gss_accept_sec_context failed\n"); - pgsserr("handle_nullreq: gss_accept_sec_context", - maj_stat, min_stat, mech); - goto out_err; diff --git a/nfs-utils-1.1.4-inet6-capable-api.patch b/nfs-utils-1.1.4-inet6-capable-api.patch deleted file mode 100644 index 122a26f..0000000 --- a/nfs-utils-1.1.4-inet6-capable-api.patch +++ /dev/null @@ -1,646 +0,0 @@ -commit 162cbdd19830abaf6a3fd64a22839023ce99185d -Author: Chuck Lever -Date: Mon Nov 17 16:08:03 2008 -0500 - - Add AF_INET6-capable API to acquire an RPC CLIENT * - - Provide a simple interface that any component of nfs-utils can use to acquire - an RPC CLIENT *. This is an AF_INET6-enabled API, and can also handle - PF_LOCAL sockets if libtirpc is present on the system. - - When libtirpc is not available, legacy RPC services will be used instead, - and an attempt to connect to an AF_INET6 address will fail. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - ---- nfs-utils-1.1.4/support/nfs/Makefile.am.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/support/nfs/Makefile.am 2008-11-18 14:59:08.894659000 -0500 -@@ -3,7 +3,7 @@ - noinst_LIBRARIES = libnfs.a - libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \ - xlog.c xcommon.c wildmat.c nfssvc.c nfsclient.c \ -- nfsexport.c getfh.c nfsctl.c \ -+ nfsexport.c getfh.c nfsctl.c rpc_socket.c \ - svc_socket.c cacheio.c closeall.c nfs_mntent.c - - MAINTAINERCLEANFILES = Makefile.in ---- /dev/null 2008-11-18 08:07:41.940431098 -0500 -+++ nfs-utils-1.1.4/support/nfs/rpc_socket.c 2008-11-18 14:59:08.904660000 -0500 -@@ -0,0 +1,528 @@ -+/* -+ * Generic RPC client socket-level APIs for nfs-utils -+ * -+ * Copyright (C) 2008 Oracle Corporation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 021110-1307, USA. -+ * -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "nfsrpc.h" -+ -+#ifdef HAVE_TIRPC_NETCONFIG_H -+ -+/* -+ * Most of the headers under /usr/include/tirpc are currently -+ * unusable for various reasons. We statically define the bits -+ * we need here until the official headers are fixed. -+ * -+ * The commonly used RPC calls such as CLNT_CALL and CLNT_DESTROY -+ * are actually virtual functions in both the legacy and TI-RPC -+ * implementations. The proper _CALL or _DESTROY will be invoked -+ * no matter if we used a legacy clnt_create() or clnt_tli_create() -+ * from libtirpc. -+ */ -+ -+#include -+#include -+ -+/* definitions from tirpc/rpc/types.h */ -+ -+/* -+ * The netbuf structure is used for transport-independent address storage. -+ */ -+struct netbuf { -+ unsigned int maxlen; -+ unsigned int len; -+ void *buf; -+}; -+ -+/* definitions from tirpc/rpc/clnt.h */ -+ -+/* -+ * Low level clnt create routine for connectionless transports, e.g. udp. -+ */ -+extern CLIENT *clnt_dg_create(const int, const struct netbuf *, -+ const rpcprog_t, const rpcvers_t, -+ const u_int, const u_int); -+ -+/* -+ * Low level clnt create routine for connectionful transports, e.g. tcp. -+ */ -+extern CLIENT *clnt_vc_create(const int, const struct netbuf *, -+ const rpcprog_t, const rpcvers_t, -+ u_int, u_int); -+ -+#endif /* HAVE_TIRPC_NETCONFIG_H */ -+ -+/* -+ * If "-1" is specified in the tv_sec field, use these defaults instead. -+ */ -+#define NFSRPC_TIMEOUT_UDP (3) -+#define NFSRPC_TIMEOUT_TCP (10) -+ -+/* -+ * Set up an RPC client for communicating via a AF_LOCAL socket. -+ * -+ * @timeout is initialized upon return -+ * -+ * Returns a pointer to a prepared RPC client if successful; caller -+ * must destroy a non-NULL returned RPC client. Otherwise NULL, and -+ * rpc_createerr.cf_stat is set to reflect the error. -+ */ -+static CLIENT *nfs_get_localclient(const struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ struct timeval *timeout) -+{ -+#ifdef HAVE_CLNT_VC_CREATE -+ struct sockaddr_storage address; -+ const struct netbuf nbuf = { -+ .maxlen = sizeof(struct sockaddr_un), -+ .len = (size_t)salen, -+ .buf = &address, -+ }; -+#endif /* HAVE_CLNT_VC_CREATE */ -+ CLIENT *client; -+ int sock; -+ -+ sock = socket(AF_LOCAL, SOCK_STREAM, 0); -+ if (sock == -1) { -+ rpc_createerr.cf_stat = RPC_SYSTEMERROR; -+ rpc_createerr.cf_error.re_errno = errno; -+ return NULL; -+ } -+ -+ if (timeout->tv_sec == -1) -+ timeout->tv_sec = NFSRPC_TIMEOUT_TCP; -+ -+#ifdef HAVE_CLNT_VC_CREATE -+ memcpy(nbuf.buf, sap, (size_t)salen); -+ client = clnt_vc_create(sock, &nbuf, program, version, 0, 0); -+#else /* HAVE_CLNT_VC_CREATE */ -+ client = clntunix_create((struct sockaddr_un *)sap, -+ program, version, &sock, 0, 0); -+#endif /* HAVE_CLNT_VC_CREATE */ -+ if (client != NULL) -+ CLNT_CONTROL(client, CLSET_FD_CLOSE, NULL); -+ else -+ (void)close(sock); -+ -+ return client; -+} -+ -+/* -+ * Bind a socket using an unused ephemeral source port. -+ * -+ * Returns zero on success, or returns -1 on error. errno is -+ * set to reflect the nature of the error. -+ */ -+static int nfs_bind(const int sock, const sa_family_t family) -+{ -+ struct sockaddr_in sin = { -+ .sin_family = AF_INET, -+ .sin_addr.s_addr = htonl(INADDR_ANY), -+ }; -+ struct sockaddr_in6 sin6 = { -+ .sin6_family = AF_INET6, -+ .sin6_addr = IN6ADDR_ANY_INIT, -+ }; -+ -+ switch (family) { -+ case AF_INET: -+ return bind(sock, (struct sockaddr *)&sin, -+ (socklen_t)sizeof(sin)); -+ case AF_INET6: -+ return bind(sock, (struct sockaddr *)&sin6, -+ (socklen_t)sizeof(sin6)); -+ } -+ -+ errno = EAFNOSUPPORT; -+ return -1; -+} -+ -+/* -+ * Perform a non-blocking connect on the socket fd. -+ * -+ * @timeout is modified to contain the time remaining (i.e. time provided -+ * minus time elasped). -+ * -+ * Returns zero on success, or returns -1 on error. errno is -+ * set to reflect the nature of the error. -+ */ -+static int nfs_connect_nb(const int fd, const struct sockaddr *sap, -+ const socklen_t salen, struct timeval *timeout) -+{ -+ int flags, ret; -+ fd_set rset; -+ -+ flags = fcntl(fd, F_GETFL, 0); -+ if (flags < 0) -+ return -1; -+ -+ ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); -+ if (ret < 0) -+ return -1; -+ -+ /* -+ * From here on subsequent sys calls could change errno so -+ * we set ret = -errno to capture it in case we decide to -+ * use it later. -+ */ -+ ret = connect(fd, sap, salen); -+ if (ret < 0 && errno != EINPROGRESS) { -+ ret = -1; -+ goto done; -+ } -+ -+ if (ret == 0) -+ goto done; -+ -+ /* now wait */ -+ FD_ZERO(&rset); -+ FD_SET(fd, &rset); -+ -+ ret = select(fd + 1, NULL, &rset, NULL, timeout); -+ if (ret <= 0) { -+ if (ret == 0) -+ errno = ETIMEDOUT; -+ ret = -1; -+ goto done; -+ } -+ -+ if (FD_ISSET(fd, &rset)) { -+ int status; -+ socklen_t len = (socklen_t)sizeof(ret); -+ -+ status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &len); -+ if (status < 0) { -+ ret = -1; -+ goto done; -+ } -+ -+ /* Oops - something wrong with connect */ -+ if (ret != 0) { -+ errno = ret; -+ ret = -1; -+ } -+ } -+ -+done: -+ (void)fcntl(fd, F_SETFL, flags); -+ return ret; -+} -+ -+/* -+ * Set up an RPC client for communicating via a datagram socket. -+ * A connected UDP socket is used to detect a missing remote -+ * listener as quickly as possible. -+ * -+ * @timeout is initialized upon return -+ * -+ * Returns a pointer to a prepared RPC client if successful; caller -+ * must destroy a non-NULL returned RPC client. Otherwise NULL, and -+ * rpc_createerr.cf_stat is set to reflect the error. -+ */ -+static CLIENT *nfs_get_udpclient(const struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ struct timeval *timeout) -+{ -+#ifdef HAVE_CLNT_DG_CREATE -+ struct sockaddr_storage address; -+ const struct netbuf nbuf = { -+ .maxlen = salen, -+ .len = salen, -+ .buf = &address, -+ }; -+#endif /* HAVE_CLNT_DG_CREATE */ -+ CLIENT *client; -+ int ret, sock; -+ -+#ifndef HAVE_CLNT_DG_CREATE -+ if (sap->sa_family != AF_INET) { -+ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; -+ return NULL; -+ } -+#endif /* !HAVE_CLNT_DG_CREATE */ -+ -+ sock = socket((int)sap->sa_family, SOCK_DGRAM, IPPROTO_UDP); -+ if (sock == -1) { -+ rpc_createerr.cf_stat = RPC_SYSTEMERROR; -+ rpc_createerr.cf_error.re_errno = errno; -+ return NULL; -+ } -+ -+ ret = nfs_bind(sock, sap->sa_family); -+ if (ret < 0) { -+ rpc_createerr.cf_stat = RPC_SYSTEMERROR; -+ rpc_createerr.cf_error.re_errno = errno; -+ (void)close(sock); -+ return NULL; -+ } -+ -+ if (timeout->tv_sec == -1) -+ timeout->tv_sec = NFSRPC_TIMEOUT_UDP; -+ -+ ret = nfs_connect_nb(sock, sap, salen, timeout); -+ if (ret != 0) { -+ rpc_createerr.cf_stat = RPC_SYSTEMERROR; -+ rpc_createerr.cf_error.re_errno = errno; -+ (void)close(sock); -+ return NULL; -+ } -+ -+#ifdef HAVE_CLNT_DG_CREATE -+ memcpy(nbuf.buf, sap, (size_t)salen); -+ client = clnt_dg_create(sock, &nbuf, program, version, 0, 0); -+#else /* HAVE_CLNT_DG_CREATE */ -+ client = clntudp_create((struct sockaddr_in *)sap, program, -+ version, *timeout, &sock); -+#endif /* HAVE_CLNT_DG_CREATE */ -+ if (client != NULL) { -+ CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)timeout); -+ CLNT_CONTROL(client, CLSET_FD_CLOSE, NULL); -+ } else -+ (void)close(sock); -+ -+ return client; -+} -+ -+/* -+ * Set up and connect an RPC client for communicating via a stream socket. -+ * -+ * @timeout is initialized upon return -+ * -+ * Returns a pointer to a prepared and connected RPC client if -+ * successful; caller must destroy a non-NULL returned RPC client. -+ * Otherwise NULL, and rpc_createerr.cf_stat is set to reflect the -+ * error. -+ */ -+static CLIENT *nfs_get_tcpclient(const struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ struct timeval *timeout) -+{ -+#ifdef HAVE_CLNT_VC_CREATE -+ struct sockaddr_storage address; -+ const struct netbuf nbuf = { -+ .maxlen = salen, -+ .len = salen, -+ .buf = &address, -+ }; -+#endif /* HAVE_CLNT_VC_CREATE */ -+ CLIENT *client; -+ int ret, sock; -+ -+#ifndef HAVE_CLNT_VC_CREATE -+ if (sap->sa_family != AF_INET) { -+ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; -+ return NULL; -+ } -+#endif /* !HAVE_CLNT_VC_CREATE */ -+ -+ sock = socket((int)sap->sa_family, SOCK_STREAM, IPPROTO_TCP); -+ if (sock == -1) { -+ rpc_createerr.cf_stat = RPC_SYSTEMERROR; -+ rpc_createerr.cf_error.re_errno = errno; -+ return NULL; -+ } -+ -+ ret = nfs_bind(sock, sap->sa_family); -+ if (ret < 0) { -+ rpc_createerr.cf_stat = RPC_SYSTEMERROR; -+ rpc_createerr.cf_error.re_errno = errno; -+ (void)close(sock); -+ return NULL; -+ } -+ -+ if (timeout->tv_sec == -1) -+ timeout->tv_sec = NFSRPC_TIMEOUT_TCP; -+ -+ ret = nfs_connect_nb(sock, sap, salen, timeout); -+ if (ret != 0) { -+ rpc_createerr.cf_stat = RPC_SYSTEMERROR; -+ rpc_createerr.cf_error.re_errno = errno; -+ (void)close(sock); -+ return NULL; -+ } -+ -+#ifdef HAVE_CLNT_VC_CREATE -+ memcpy(nbuf.buf, sap, (size_t)salen); -+ client = clnt_vc_create(sock, &nbuf, program, version, 0, 0); -+#else /* HAVE_CLNT_VC_CREATE */ -+ client = clnttcp_create((struct sockaddr_in *)sap, -+ program, version, &sock, 0, 0); -+#endif /* HAVE_CLNT_VC_CREATE */ -+ if (client != NULL) -+ CLNT_CONTROL(client, CLSET_FD_CLOSE, NULL); -+ else -+ (void)close(sock); -+ -+ return client; -+} -+ -+/** -+ * nfs_get_rpcclient - acquire an RPC client -+ * @sap: pointer to socket address of RPC server -+ * @salen: length of socket address -+ * @transport: IPPROTO_ value of transport protocol to use -+ * @program: RPC program number -+ * @version: RPC version number -+ * @timeout: pointer to request timeout (must not be NULL) -+ * -+ * Set up an RPC client for communicating with an RPC program @program -+ * and @version on the server @sap over @transport. -+ * -+ * Returns a pointer to a prepared RPC client if successful, and -+ * @timeout is initialized; caller must destroy a non-NULL returned RPC -+ * client. Otherwise returns NULL, and rpc_createerr.cf_stat is set to -+ * reflect the error. -+ */ -+CLIENT *nfs_get_rpcclient(const struct sockaddr *sap, -+ const socklen_t salen, -+ const unsigned short transport, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ struct timeval *timeout) -+{ -+ struct sockaddr_in *sin = (struct sockaddr_in *)sap; -+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; -+ -+ switch (sap->sa_family) { -+ case AF_LOCAL: -+ return nfs_get_localclient(sap, salen, program, -+ version, timeout); -+ case AF_INET: -+ if (sin->sin_port == 0) { -+ rpc_createerr.cf_stat = RPC_UNKNOWNADDR; -+ return NULL; -+ } -+ break; -+ case AF_INET6: -+ if (sin6->sin6_port == 0) { -+ rpc_createerr.cf_stat = RPC_UNKNOWNADDR; -+ return NULL; -+ } -+ break; -+ default: -+ rpc_createerr.cf_stat = RPC_UNKNOWNHOST; -+ return NULL; -+ } -+ -+ switch (transport) { -+ case IPPROTO_TCP: -+ return nfs_get_tcpclient(sap, salen, program, version, timeout); -+ case 0: -+ case IPPROTO_UDP: -+ return nfs_get_udpclient(sap, salen, program, version, timeout); -+ } -+ -+ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; -+ return NULL; -+} -+ -+/** -+ * nfs_getrpcbyname - convert an RPC program name to a rpcprog_t -+ * @program: default program number to use if names not found in db -+ * @table: pointer to table of 'char *' names to try to find -+ * -+ * Returns program number of first name to be successfully looked -+ * up, or the default program number if all lookups fail. -+ */ -+rpcprog_t nfs_getrpcbyname(const rpcprog_t program, const char *table[]) -+{ -+#ifdef HAVE_GETRPCBYNAME -+ struct rpcent *entry; -+ unsigned int i; -+ -+ if (table != NULL) -+ for (i = 0; table[i] != NULL; i++) { -+ entry = getrpcbyname(table[i]); -+ if (entry) -+ return (rpcprog_t)entry->r_number; -+ } -+#endif /* HAVE_GETRPCBYNAME */ -+ -+ return program; -+} -+ -+static unsigned short nfs_tryportbyname(const char *name, -+ const char *protocol) -+{ -+ struct servent *servp = NULL; -+ -+ servp = getservbyname(name, protocol); -+ if (servp != NULL) -+ return (unsigned short)ntohl((uint32_t)servp->s_port); -+ return 0; -+} -+ -+/** -+ * nfs_getportbynumber - convert an RPC program number to a port -+ * @program: RPC program number to look up -+ * @transport: IPPROTO_ value of transport protocol to use -+ * -+ * Returns a non-zero port number, in host byte order, on success; -+ * otherwise zero if some problem occurred. -+ */ -+unsigned short nfs_getportbynumber(const rpcprog_t program, -+ const unsigned short transport) -+{ -+ char *protocol = (transport == IPPROTO_TCP) ? "tcp" : "udp"; -+ struct rpcent *rpcp; -+ unsigned short port = 0; -+ -+ rpcp = getrpcbynumber((int)program); -+ if (rpcp == NULL) -+ return port; -+ -+ port = nfs_tryportbyname(rpcp->r_name, protocol); -+ if (port != 0) -+ return port; -+ -+ if (rpcp->r_aliases) { -+ int i; -+ for (i = 0; rpcp->r_aliases[i] != NULL; i++) { -+ port = nfs_tryportbyname(rpcp->r_aliases[i], protocol); -+ if (port != 0) -+ break; -+ } -+ } -+ -+ return port; -+} ---- /dev/null 2008-11-18 08:07:41.940431098 -0500 -+++ nfs-utils-1.1.4/support/include/nfsrpc.h 2008-11-18 14:59:08.888662000 -0500 -@@ -0,0 +1,70 @@ -+/* -+ * nfsrpc.h -- RPC client APIs provided by support/nfs -+ * -+ * Copyright (C) 2008 Oracle Corporation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 021110-1307, USA. -+ * -+ */ -+ -+#ifndef __NFS_UTILS_NFSRPC_H -+#define __NFS_UTILS_NFSRPC_H -+ -+#include -+ -+/* -+ * Conventional RPC program numbers -+ */ -+#ifndef RPCBPROG -+#define RPCBPROG ((rpcprog_t)100000) -+#endif -+#ifndef PMAPPROG -+#define PMAPPROG ((rpcprog_t)100000) -+#endif -+ -+#ifndef NFSPROG -+#define NFSPROG ((rpcprog_t)100003) -+#endif -+#ifndef MOUNTPROG -+#define MOUNTPROG ((rpcprog_t)100005) -+#endif -+#ifndef NLMPROG -+#define NLMPROG ((rpcprog_t)100021) -+#endif -+#ifndef NSMPROG -+#define NSMPROG ((rpcprog_t)100024) -+#endif -+ -+/* -+ * Look up an RPC program name in /etc/rpc -+ */ -+extern rpcprog_t nfs_getrpcbyname(const rpcprog_t, const char *table[]); -+ -+/* -+ * Look up a port number in /etc/services for an RPC program -+ */ -+extern unsigned short nfs_getportbynumber(const rpcprog_t program, -+ const unsigned short transport); -+ -+/* -+ * Acquire an RPC CLIENT * -+ */ -+extern CLIENT *nfs_get_rpcclient(const struct sockaddr *, -+ const socklen_t, const unsigned short, -+ const rpcprog_t, const rpcvers_t, -+ struct timeval *); -+ -+#endif /* __NFS_UTILS_NFSRPC_H */ ---- nfs-utils-1.1.4/configure.ac.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/configure.ac 2008-11-18 14:59:08.884659000 -0500 -@@ -178,6 +178,12 @@ AC_CHECK_FUNC(connect, , - AC_CHECK_FUNC(getaddrinfo, , , - AC_MSG_ERROR(Function 'getaddrinfo' not found.)) - -+AC_CHECK_FUNC(getrpcbynumber, , , -+ AC_MSG_ERROR(Function 'getrpcbynumber' not found.)) -+ -+AC_CHECK_FUNC(getservbyname, , , -+ AC_MSG_ERROR(Function 'getservbyname' not found.)) -+ - AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"]) - if test "$enable_nfsv4" = yes; then - AC_CHECK_LIB(event, event_dispatch, [libevent=1], AC_MSG_ERROR([libevent needed for nfsv4 support])) diff --git a/nfs-utils-1.1.4-inet6-rpcbind-util-funcs.patch b/nfs-utils-1.1.4-inet6-rpcbind-util-funcs.patch deleted file mode 100644 index 2371162..0000000 --- a/nfs-utils-1.1.4-inet6-rpcbind-util-funcs.patch +++ /dev/null @@ -1,1102 +0,0 @@ -commit 541bf913ec64dee719b34d2a6850fcfee550e6c0 -Author: Chuck Lever -Date: Mon Nov 17 16:13:48 2008 -0500 - - Introduce rpcbind client utility functions - - It turns out that at least the mount command and the showmount command - need to query a server's rpcbind daemon. They need to query over - AF_INET6 as well as AF_INET. - - libtirpc provides an rpcbind query capability with the rpcb_getaddr(3) - interface, but it takes a hostname and netconfig entry rather than a - sockaddr and a protocol type, and always uses a lengthy timeout. The - former is important to the mount command because it sometimes must - operate using a specific port and IP address rather than depending on - rpcbind and DNS to convert a [hostname, RPC program, netconfig] tuple - to a [socket address, port number, transport protocol] tuple. - - The rpcb_getaddr(3) API also always uses a privileged port (at least - for setuid root executables like mount.nfs), which is not required for - an rpcbind query. This can exhaust the local system's reserved port - space quickly. - - This patch provides a reserved-port-friendly AF_INET6-capable rpcbind - query C API that can be shared among commands and tools in nfs-utils, - and allows a query to a specified socket address and port rather than - a hostname. - - In addition to an rpcbind query interface, this patch also provides a - facility to ping the remote RPC service to ensure that it is operating - as advertised by rpcbind. It's useful to combine an RPC ping with an - rpcbind query because in many cases, components of nfs-utils already - ping an RPC service immediately after receiving a successful GETPORT - result. - - There are also a handful of utility routines provided, such as a - functions that can map between [sockaddr, port] and a universal - address. - - I've made an attempt to make these new functions build and operate on - systems that do not have libtirpc. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - ---- nfs-utils-1.1.4/support/nfs/Makefile.am.orig 2008-11-18 15:06:29.115299000 -0500 -+++ nfs-utils-1.1.4/support/nfs/Makefile.am 2008-11-18 15:08:43.272905000 -0500 -@@ -3,7 +3,7 @@ - noinst_LIBRARIES = libnfs.a - libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \ - xlog.c xcommon.c wildmat.c nfssvc.c nfsclient.c \ -- nfsexport.c getfh.c nfsctl.c rpc_socket.c \ -+ nfsexport.c getfh.c nfsctl.c rpc_socket.c getport.c \ - svc_socket.c cacheio.c closeall.c nfs_mntent.c - - MAINTAINERCLEANFILES = Makefile.in ---- /dev/null 2008-11-18 08:07:41.940431098 -0500 -+++ nfs-utils-1.1.4/support/nfs/getport.c 2008-11-18 15:08:58.025493000 -0500 -@@ -0,0 +1,965 @@ -+/* -+ * Provide a variety of APIs that query an rpcbind daemon to -+ * discover RPC service ports and allowed protocol version -+ * numbers. -+ * -+ * Copyright (C) 2008 Oracle Corporation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 021110-1307, USA. -+ * -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#ifdef HAVE_TIRPC_NETCONFIG_H -+#include -+#include -+#endif -+ -+#include "nfsrpc.h" -+ -+/* -+ * Try a local socket first to access the local rpcbind daemon -+ * -+ * Rpcbind's local socket service does not seem to be working. -+ * Disable this logic for now. -+ */ -+#ifdef HAVE_XDR_RPCB -+#undef NFS_GP_LOCAL -+#else /* HAVE_XDR_RPCB */ -+#undef NFS_GP_LOCAL -+#endif /* HAVE_XDR_RPCB */ -+ -+#ifdef HAVE_XDR_RPCB -+const static rpcvers_t default_rpcb_version = RPCBVERS_4; -+#else -+const static rpcvers_t default_rpcb_version = PMAPVERS; -+#endif -+ -+static const char *nfs_gp_rpcb_pgmtbl[] = { -+ "rpcbind", -+ "portmap", -+ "portmapper", -+ "sunrpc", -+ NULL, -+}; -+ -+/* -+ * Discover the port number that should be used to contact an -+ * rpcbind service. This will detect if the port has a local -+ * value that may have been set in /etc/services. -+ * -+ * NB: s_port is already in network byte order. -+ * -+ * Returns network byte-order port number of rpcbind service -+ * on this system. -+ */ -+static in_port_t nfs_gp_get_rpcb_port(const unsigned short protocol) -+{ -+ struct protoent *proto; -+ -+ proto = getprotobynumber((int)protocol); -+ if (proto != NULL) { -+ struct servent *entry; -+ -+ entry = getservbyname("rpcbind", proto->p_name); -+ if (entry != NULL) -+ return (in_port_t)entry->s_port; -+ -+ entry = getservbyname("portmapper", proto->p_name); -+ if (entry != NULL) -+ return (in_port_t)entry->s_port; -+ -+ entry = getservbyname("sunrpc", proto->p_name); -+ if (entry != NULL) -+ return (in_port_t)entry->s_port; -+ } -+ return htons((uint16_t)PMAPPORT); -+} -+ -+/* -+ * Plant port number in @sap. @port is already in network byte order. -+ */ -+static void nfs_gp_set_port(struct sockaddr *sap, const in_port_t port) -+{ -+ struct sockaddr_in *sin = (struct sockaddr_in *)sap; -+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; -+ -+ switch (sap->sa_family) { -+ case AF_INET: -+ sin->sin_port = port; -+ break; -+ case AF_INET6: -+ sin6->sin6_port = port; -+ break; -+ default: -+ fprintf(stderr, "%s: unrecognized address family\n", -+ __func__); -+ } -+} -+ -+/* -+ * Set up an RPC client for communicating with an rpcbind daemon at -+ * @sap over @transport with protocol version @version. -+ * -+ * Returns a pointer to a prepared RPC client if successful, and -+ * @timeout is initialized; caller must destroy a non-NULL returned RPC -+ * client. Otherwise returns NULL, and rpc_createerr.cf_stat is set to -+ * reflect the error. -+ */ -+static CLIENT *nfs_gp_get_rpcbclient(const struct sockaddr *sap, -+ const socklen_t salen, -+ const unsigned short transport, -+ const rpcvers_t version, -+ struct timeval *timeout) -+{ -+ struct sockaddr_storage address; -+ struct sockaddr *saddr = (struct sockaddr *)&address; -+ rpcprog_t rpcb_prog = nfs_getrpcbyname(RPCBPROG, nfs_gp_rpcb_pgmtbl); -+ -+ memcpy(saddr, sap, (size_t)salen); -+ nfs_gp_set_port(saddr, nfs_gp_get_rpcb_port(transport)); -+ -+ return nfs_get_rpcclient(saddr, salen, transport, rpcb_prog, -+ version, timeout); -+} -+ -+/* -+ * One of the arguments passed when querying remote rpcbind services -+ * via rpcbind v3 or v4 is a netid string. This replaces the pm_prot -+ * field used in legacy PMAP_GETPORT calls. -+ * -+ * RFC 1833 says netids are not standard but rather defined on the local -+ * host. There are, however, standard definitions for nc_protofmly and -+ * nc_proto that can be used to derive a netid string on the local host, -+ * based on the contents of /etc/netconfig. -+ * -+ * Walk through the local netconfig database and grab the netid of the -+ * first entry that matches @family and @protocol and whose netid string -+ * fits in the provided buffer. -+ * -+ * Returns a '\0'-terminated string if successful; otherwise NULL. -+ * rpc_createerr.cf_stat is set to reflect the error. -+ */ -+#ifdef HAVE_XDR_RPCB -+ -+static char *nfs_gp_get_netid(const sa_family_t family, -+ const unsigned short protocol) -+{ -+ char *nc_protofmly, *nc_proto, *nc_netid; -+ struct netconfig *nconf; -+ struct protoent *proto; -+ void *handle; -+ -+ switch (family) { -+ case AF_LOCAL: -+ case AF_INET: -+ nc_protofmly = NC_INET; -+ break; -+ case AF_INET6: -+ nc_protofmly = NC_INET6; -+ break; -+ default: -+ goto out; -+ } -+ -+ proto = getprotobynumber(protocol); -+ if (proto == NULL) -+ goto out; -+ nc_proto = proto->p_name; -+ -+ handle = setnetconfig(); -+ while ((nconf = getnetconfig(handle)) != NULL) { -+ -+ if (nconf->nc_protofmly != NULL && -+ strcmp(nconf->nc_protofmly, nc_protofmly) != 0) -+ continue; -+ if (nconf->nc_proto != NULL && -+ strcmp(nconf->nc_proto, nc_proto) != 0) -+ continue; -+ -+ nc_netid = strdup(nconf->nc_netid); -+ endnetconfig(handle); -+ return nc_netid; -+ } -+ endnetconfig(handle); -+ -+out: -+ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; -+ return NULL; -+} -+ -+#endif /* HAVE_XDR_RPCB */ -+ -+/* -+ * Extract a port number from a universal address, and terminate the -+ * string in @addrstr just after the address part. -+ * -+ * Returns -1 if unsuccesful; otherwise a decoded port number (possibly 0) -+ * is returned. -+ */ -+static int nfs_gp_universal_porthelper(char *addrstr) -+{ -+ char *p, *endptr; -+ unsigned long portlo, porthi; -+ int port = -1; -+ -+ p = strrchr(addrstr, '.'); -+ if (p == NULL) -+ goto out; -+ portlo = strtoul(p + 1, &endptr, 10); -+ if (*endptr != '\0' || portlo > 255) -+ goto out; -+ *p = '\0'; -+ -+ p = strrchr(addrstr, '.'); -+ if (p == NULL) -+ goto out; -+ porthi = strtoul(p + 1, &endptr, 10); -+ if (*endptr != '\0' || porthi > 255) -+ goto out; -+ *p = '\0'; -+ port = (porthi << 8) | portlo; -+ -+out: -+ return port; -+} -+ -+/** -+ * nfs_universal2port - extract port number from a "universal address" -+ * @uaddr: '\0'-terminated C string containing a universal address -+ * -+ * Universal addresses (defined in RFC 1833) are used when calling an -+ * rpcbind daemon via protocol versions 3 or 4.. -+ * -+ * Returns -1 if unsuccesful; otherwise a decoded port number (possibly 0) -+ * is returned. -+ */ -+int nfs_universal2port(const char *uaddr) -+{ -+ char *addrstr; -+ int port = -1; -+ -+ addrstr = strdup(uaddr); -+ if (addrstr != NULL) { -+ port = nfs_gp_universal_porthelper(addrstr); -+ free(addrstr); -+ } -+ return port; -+} -+ -+/** -+ * nfs_sockaddr2universal - convert a sockaddr to a "universal address" -+ * @sap: pointer to a socket address -+ * @salen: length of socket address -+ * -+ * Universal addresses (defined in RFC 1833) are used when calling an -+ * rpcbind daemon via protocol versions 3 or 4.. -+ * -+ * Returns a '\0'-terminated string if successful; caller must free -+ * the returned string. Otherwise NULL is returned and -+ * rpc_createerr.cf_stat is set to reflect the error. -+ * -+ */ -+#ifdef HAVE_GETNAMEINFO -+ -+char *nfs_sockaddr2universal(const struct sockaddr *sap, -+ const socklen_t salen) -+{ -+ struct sockaddr_un *sun = (struct sockaddr_un *)sap; -+ char buf[NI_MAXHOST]; -+ uint16_t port; -+ -+ switch (sap->sa_family) { -+ case AF_LOCAL: -+ return strndup(sun->sun_path, sizeof(sun->sun_path)); -+ case AF_INET: -+ if (getnameinfo(sap, salen, buf, (socklen_t)sizeof(buf), -+ NULL, 0, NI_NUMERICHOST) != 0) -+ goto out_err; -+ port = ntohs(((struct sockaddr_in *)sap)->sin_port); -+ break; -+ case AF_INET6: -+ if (getnameinfo(sap, salen, buf, (socklen_t)sizeof(buf), -+ NULL, 0, NI_NUMERICHOST) != 0) -+ goto out_err; -+ port = ntohs(((struct sockaddr_in6 *)sap)->sin6_port); -+ break; -+ default: -+ goto out_err; -+ } -+ -+ (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ".%u.%u", -+ (unsigned)(port >> 8), (unsigned)(port & 0xff)); -+ -+ return strdup(buf); -+ -+out_err: -+ rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; -+ return NULL; -+} -+ -+#else /* HAVE_GETNAMEINFO */ -+ -+char *nfs_sockaddr2universal(const struct sockaddr *sap, -+ const socklen_t salen) -+{ -+ struct sockaddr_un *sun = (struct sockaddr_un *)sap; -+ char buf[NI_MAXHOST]; -+ uint16_t port; -+ char *addr; -+ -+ switch (sap->sa_family) { -+ case AF_LOCAL: -+ return strndup(sun->sun_path, sizeof(sun->sun_path)); -+ case AF_INET: -+ addr = inet_ntoa(((struct sockaddr_in *)sap)->sin_addr); -+ if (addr != NULL && strlen(addr) > sizeof(buf)) -+ goto out_err; -+ strcpy(buf, addr); -+ port = ntohs(((struct sockaddr_in *)sap)->sin_port); -+ break; -+ default: -+ goto out_err; -+ } -+ -+ (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ".%u.%u", -+ (unsigned)(port >> 8), (unsigned)(port & 0xff)); -+ -+ return strdup(buf); -+ -+out_err: -+ rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; -+ return NULL; -+} -+ -+#endif /* HAVE_GETNAMEINFO */ -+ -+/* -+ * Send a NULL request to the indicated RPC service. -+ * -+ * Returns 1 if the service responded; otherwise 0; -+ */ -+static int nfs_gp_ping(CLIENT *client, struct timeval timeout) -+{ -+ enum clnt_stat status; -+ -+ status = CLNT_CALL(client, NULLPROC, -+ (xdrproc_t)xdr_void, NULL, -+ (xdrproc_t)xdr_void, NULL, -+ timeout); -+ -+ return (int)(status == RPC_SUCCESS); -+} -+ -+#ifdef HAVE_XDR_RPCB -+ -+/* -+ * Initialize the rpcb argument for a GETADDR request. -+ * -+ * The rpcbind daemon ignores the parms.r_owner field in GETADDR -+ * requests, but we plant an eye-catcher to help distinguish these -+ * requests in network traces. -+ * -+ * Returns 1 if successful, and caller must free strings pointed -+ * to by r_netid and r_addr; otherwise 0. -+ */ -+static int nfs_gp_init_rpcb_parms(const struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol, -+ struct rpcb *parms) -+{ -+ char *netid, *addr; -+ -+ netid = nfs_gp_get_netid(sap->sa_family, protocol); -+ if (netid == NULL) -+ return 0; -+ -+ addr = nfs_sockaddr2universal(sap, salen); -+ if (addr == NULL) { -+ free(netid); -+ return 0; -+ } -+ -+ memset(parms, 0, sizeof(*parms)); -+ parms->r_prog = program; -+ parms->r_vers = version; -+ parms->r_netid = netid; -+ parms->r_addr = addr; -+ parms->r_owner = "nfs-utils"; /* eye-catcher */ -+ -+ return 1; -+} -+ -+static void nfs_gp_free_rpcb_parms(struct rpcb *parms) -+{ -+ free(parms->r_netid); -+ free(parms->r_addr); -+} -+ -+/* -+ * Try rpcbind GETADDR via version 4. If that fails, try same -+ * request via version 3. -+ * -+ * Returns non-zero port number on success; otherwise returns -+ * zero. rpccreateerr is set to reflect the nature of the error. -+ */ -+static unsigned short nfs_gp_rpcb_getaddr(CLIENT *client, -+ struct rpcb *parms, -+ struct timeval timeout) -+{ -+ rpcvers_t rpcb_version; -+ struct rpc_err rpcerr; -+ int port = 0; -+ -+ for (rpcb_version = RPCBVERS_4; -+ rpcb_version >= RPCBVERS_3; -+ rpcb_version--) { -+ enum clnt_stat status; -+ char *uaddr = NULL; -+ -+ CLNT_CONTROL(client, CLSET_VERS, (void *)&rpcb_version); -+ status = CLNT_CALL(client, (rpcproc_t)RPCBPROC_GETADDR, -+ (xdrproc_t)xdr_rpcb, (void *)parms, -+ (xdrproc_t)xdr_wrapstring, (void *)&uaddr, -+ timeout); -+ -+ switch (status) { -+ case RPC_SUCCESS: -+ if ((uaddr == NULL) || (uaddr[0] == '\0')) { -+ rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; -+ continue; -+ } -+ -+ port = nfs_universal2port(uaddr); -+ xdr_free((xdrproc_t)xdr_wrapstring, (char *)&uaddr); -+ if (port == -1) { -+ rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; -+ return 0; -+ } -+ return (unsigned short)port; -+ case RPC_PROGVERSMISMATCH: -+ clnt_geterr(client, &rpcerr); -+ if (rpcerr.re_vers.low > RPCBVERS4) -+ return 0; -+ continue; -+ case RPC_PROCUNAVAIL: -+ case RPC_PROGUNAVAIL: -+ continue; -+ default: -+ /* Most likely RPC_TIMEDOUT or RPC_CANTRECV */ -+ rpc_createerr.cf_stat = status; -+ clnt_geterr(client, &rpc_createerr.cf_error); -+ return 0; -+ } -+ -+ } -+ -+ if (port == 0) { -+ rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; -+ clnt_geterr(client, &rpc_createerr.cf_error); -+ } -+ return port; -+} -+ -+#endif /* HAVE_XDR_RPCB */ -+ -+/* -+ * Try GETPORT request via rpcbind version 2. -+ * -+ * Returns non-zero port number on success; otherwise returns -+ * zero. rpccreateerr is set to reflect the nature of the error. -+ */ -+static unsigned long nfs_gp_pmap_getport(CLIENT *client, -+ struct pmap *parms, -+ struct timeval timeout) -+{ -+ enum clnt_stat status; -+ unsigned long port; -+ -+ status = CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT, -+ (xdrproc_t)xdr_pmap, (void *)parms, -+ (xdrproc_t)xdr_u_long, (void *)&port, -+ timeout); -+ -+ if (status != RPC_SUCCESS) { -+ rpc_createerr.cf_stat = status; -+ clnt_geterr(client, &rpc_createerr.cf_error); -+ port = 0; -+ } else if (port == 0) -+ rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; -+ -+ return port; -+} -+ -+#ifdef HAVE_XDR_RPCB -+ -+static unsigned short nfs_gp_getport_rpcb(CLIENT *client, -+ const struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol, -+ struct timeval timeout) -+{ -+ unsigned short port = 0; -+ struct rpcb parms; -+ -+ if (nfs_gp_init_rpcb_parms(sap, salen, program, -+ version, protocol, &parms) != 0) { -+ port = nfs_gp_rpcb_getaddr(client, &parms, timeout); -+ nfs_gp_free_rpcb_parms(&parms); -+ } -+ -+ return port; -+} -+ -+#endif /* HAVE_XDR_RPCB */ -+ -+static unsigned long nfs_gp_getport_pmap(CLIENT *client, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol, -+ struct timeval timeout) -+{ -+ struct pmap parms = { -+ .pm_prog = program, -+ .pm_vers = version, -+ .pm_prot = protocol, -+ }; -+ rpcvers_t pmap_version = PMAPVERS; -+ -+ CLNT_CONTROL(client, CLSET_VERS, (void *)&pmap_version); -+ return nfs_gp_pmap_getport(client, &parms, timeout); -+} -+ -+/* -+ * Try an AF_INET6 request via rpcbind v4/v3; try an AF_INET -+ * request via rpcbind v2. -+ * -+ * Returns non-zero port number on success; otherwise returns -+ * zero. rpccreateerr is set to reflect the nature of the error. -+ */ -+static unsigned short nfs_gp_getport(CLIENT *client, -+ const struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol, -+ struct timeval timeout) -+{ -+ switch (sap->sa_family) { -+#ifdef HAVE_XDR_RPCB -+ case AF_INET6: -+ return nfs_gp_getport_rpcb(client, sap, salen, program, -+ version, protocol, timeout); -+#endif /* HAVE_XDR_RPCB */ -+ case AF_INET: -+ return nfs_gp_getport_pmap(client, program, version, -+ protocol, timeout); -+ } -+ -+ rpc_createerr.cf_stat = RPC_UNKNOWNADDR; -+ return 0; -+} -+ -+/** -+ * nfs_rcp_ping - Determine if RPC service is responding to requests -+ * @sap: pointer to address of server to query (port is already filled in) -+ * @salen: length of server address -+ * @program: requested RPC program number -+ * @version: requested RPC version number -+ * @protocol: requested IPPROTO_ value of transport protocol -+ * @timeout: pointer to request timeout (NULL means use default timeout) -+ * -+ * Returns 1 if the remote service responded without an error; otherwise -+ * zero. -+ */ -+int nfs_rpc_ping(const struct sockaddr *sap, const socklen_t salen, -+ const rpcprog_t program, const rpcvers_t version, -+ const unsigned short protocol, const struct timeval *timeout) -+{ -+ CLIENT *client; -+ struct timeval tout = { -1, 0 }; -+ int result = 0; -+ -+ if (timeout != NULL) -+ tout = *timeout; -+ -+ client = nfs_get_rpcclient(sap, salen, protocol, program, version, &tout); -+ if (client != NULL) { -+ result = nfs_gp_ping(client, tout); -+ CLNT_DESTROY(client); -+ } -+ -+ return result; -+} -+ -+/** -+ * nfs_getport - query server's rpcbind to get port number for an RPC service -+ * @sap: pointer to address of server to query -+ * @salen: length of server's address -+ * @program: requested RPC program number -+ * @version: requested RPC version number -+ * @protocol: IPPROTO_ value of requested transport protocol -+ * -+ * Uses any acceptable rpcbind version to discover the port number for the -+ * RPC service described by the given [program, version, transport] tuple. -+ * Uses a quick timeout and an ephemeral source port. Supports AF_INET and -+ * AF_INET6 server addresses. -+ * -+ * Returns a positive integer representing the port number of the RPC -+ * service advertised by the server (in host byte order), or zero if the -+ * service is not advertised or there was some problem querying the server's -+ * rpcbind daemon. rpccreateerr is set to reflect the underlying cause of -+ * the error. -+ * -+ * There are a variety of ways to choose which transport and rpcbind versions -+ * to use. We chose to conserve local resources and try to avoid incurring -+ * timeouts. -+ * -+ * Transport -+ * To provide rudimentary support for traversing firewalls, query the remote -+ * using the same transport as the requested service. This provides some -+ * guarantee that the requested transport is available between this client -+ * and the server, and if the caller specifically requests TCP, for example, -+ * this may be becuase a firewall is in place that blocks UDP traffic. We -+ * could try both, but that could involve a lengthy timeout in several cases, -+ * and would often consume an extra ephemeral port. -+ * -+ * Rpcbind version -+ * To avoid using up too many ephemeral ports, AF_INET queries use tried-and- -+ * true rpcbindv2, and don't try the newer versions; and AF_INET6 queries use -+ * rpcbindv4, then rpcbindv3 on the same socket. The newer rpcbind protocol -+ * versions can adequately detect if a remote RPC service does not support -+ * AF_INET6 at all. The rpcbind socket is re-used in an attempt to keep the -+ * overall number of consumed ephemeral ports low. -+ */ -+unsigned short nfs_getport(const struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol) -+{ -+ struct timeval timeout = { -1, 0 }; -+ unsigned short port = 0; -+ CLIENT *client; -+ -+ client = nfs_gp_get_rpcbclient(sap, salen, protocol, -+ default_rpcb_version, &timeout); -+ if (client != NULL) { -+ port = nfs_gp_getport(client, sap, salen, program, -+ version, protocol, timeout); -+ CLNT_DESTROY(client); -+ } -+ -+ return port; -+} -+ -+/** -+ * nfs_getport_ping - query server's rpcbind and do RPC ping to verify result -+ * @sap: IN: pointer to address of server to query; -+ * OUT: pointer to updated address -+ * @salen: length of server's address -+ * @program: requested RPC program number -+ * @version: requested RPC version number -+ * @protocol: IPPROTO_ value of requested transport protocol -+ * -+ * Uses any acceptable rpcbind version to discover the port number for the -+ * RPC service described by the given [program, version, transport] tuple. -+ * Uses a quick timeout and an ephemeral source port. Supports AF_INET and -+ * AF_INET6 server addresses. -+ * -+ * Returns a 1 and sets the port number in the passed-in server address -+ * if both the query and the ping were successful; otherwise zero. -+ * rpccreateerr is set to reflect the underlying cause of the error. -+ */ -+int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen, -+ const rpcprog_t program, const rpcvers_t version, -+ const unsigned short protocol) -+{ -+ struct timeval timeout = { -1, 0 }; -+ unsigned short port = 0; -+ CLIENT *client; -+ int result = 0; -+ -+ client = nfs_gp_get_rpcbclient(sap, salen, protocol, -+ default_rpcb_version, &timeout); -+ if (client != NULL) { -+ port = nfs_gp_getport(client, sap, salen, program, -+ version, protocol, timeout); -+ CLNT_DESTROY(client); -+ client = NULL; -+ } -+ -+ if (port != 0) { -+ struct sockaddr_storage address; -+ struct sockaddr *saddr = (struct sockaddr *)&address; -+ -+ memcpy(saddr, sap, (size_t)salen); -+ nfs_gp_set_port(saddr, htons(port)); -+ -+ client = nfs_get_rpcclient(saddr, salen, protocol, -+ program, version, &timeout); -+ if (client != NULL) { -+ result = nfs_gp_ping(client, timeout); -+ CLNT_DESTROY(client); -+ } -+ } -+ -+ if (result) -+ nfs_gp_set_port(sap, htons(port)); -+ -+ return result; -+} -+ -+/** -+ * nfs_getlocalport - query local rpcbind to get port number for an RPC service -+ * @program: requested RPC program number -+ * @version: requested RPC version number -+ * @protocol: IPPROTO_ value of requested transport protocol -+ * -+ * Uses any acceptable rpcbind version to discover the port number for the -+ * RPC service described by the given [program, version, transport] tuple. -+ * Uses a quick timeout and an ephemeral source port. Supports AF_INET and -+ * AF_INET6 local addresses. -+ * -+ * Returns a positive integer representing the port number of the RPC -+ * service advertised by the server (in host byte order), or zero if the -+ * service is not advertised or there was some problem querying the server's -+ * rpcbind daemon. rpccreateerr is set to reflect the underlying cause of -+ * the error. -+ * -+ * Try an AF_LOCAL connection first. The rpcbind daemon implementation should -+ * listen on AF_LOCAL. -+ * -+ * If that doesn't work (for example, if portmapper is running, or rpcbind -+ * isn't listening on /var/run/rpcbind.sock), send a query via UDP to localhost -+ * (UDP doesn't leave a socket in TIME_WAIT, and the timeout is a relatively -+ * short 3 seconds). -+ * -+ * getaddrinfo(3) generates a usable loopback address. RFC 3484 requires that -+ * the results are sorted so that the first result has the best likelihood of -+ * working, so we try just that first result. If IPv6 is all that is -+ * available, we are sure to generate an AF_INET6 loopback address and use -+ * rpcbindv4/v3 GETADDR. AF_INET6 requests go via rpcbind v4/3 in order to -+ * detect if the requested RPC service supports AF_INET6 or not. -+ */ -+unsigned short nfs_getlocalport(const rpcprot_t program, -+ const rpcvers_t version, -+ const unsigned short protocol) -+{ -+ struct addrinfo *gai_results; -+ struct addrinfo gai_hint = { -+ .ai_flags = AI_ADDRCONFIG, -+ }; -+ unsigned short port = 0; -+ int error; -+ -+#ifdef NFS_GP_LOCAL -+ const struct sockaddr_un sun = { -+ .sun_family = AF_LOCAL, -+ .sun_path = _PATH_RPCBINDSOCK, -+ }; -+ const struct sockaddr *sap = (struct sockaddr *)&sun; -+ const socklen_t salen = SUN_LEN(&sun); -+ CLIENT *client; -+ struct timeval timeout = { -1, 0 }; -+ -+ client = nfs_gp_get_rpcbclient(sap, salen, 0, RPCBVERS_4, &timeout); -+ if (client != NULL) { -+ struct rpcb parms; -+ -+ if (nfs_gp_init_rpcb_parms(sap, salen, program, version, -+ protocol, &parms) != 0) { -+ port = nfs_gp_rpcb_getaddr(client, &parms, timeout); -+ nfs_gp_free_rpcb_parms(&parms); -+ } -+ CLNT_DESTROY(client); -+ } -+#endif /* NFS_GP_LOCAL */ -+ -+ if (port == 0) { -+ error = getaddrinfo(NULL, "sunrpc", &gai_hint, &gai_results); -+ if (error == 0) { -+ port = nfs_getport(gai_results->ai_addr, -+ gai_results->ai_addrlen, -+ program, version, protocol); -+ freeaddrinfo(gai_results); -+ } else -+ rpc_createerr.cf_stat = RPC_UNKNOWNADDR; -+ } -+ -+ return port; -+} -+ -+/** -+ * nfs_rpcb_getaddr - query rpcbind via rpcbind versions 4 and 3 -+ * @sap: pointer to address of server to query -+ * @salen: length of server address -+ * @transport: transport protocol to use for the query -+ * @addr: pointer to r_addr address -+ * @addrlen: length of address -+ * @program: requested RPC program number -+ * @version: requested RPC version number -+ * @protocol: requested IPPROTO_ value of transport protocol -+ * @timeout: pointer to request timeout (NULL means use default timeout) -+ * -+ * Returns a positive integer representing the port number of the RPC -+ * service advertised by the server (in host byte order), or zero if the -+ * service is not advertised or there was some problem querying the -+ * server's rpcbind daemon. rpccreateerr is set to reflect the -+ * underlying cause of the error. -+ * -+ * This function provides similar functionality to nfs_pmap_getport(), -+ * but performs the rpcbind lookup via rpcbind version 4. If the server -+ * doesn't support rpcbind version 4, it will retry with version 3. -+ * The GETADDR procedure is exactly the same in these two versions of -+ * the rpcbind protocol, so the socket, RPC client, and arguments are -+ * re-used when retrying, saving ephemeral port space. -+ * -+ * These RPC procedures take a universal address as an argument, so the -+ * query will fail if the remote rpcbind daemon doesn't find an entry -+ * with a matching address. A matching address includes an ANYADDR -+ * address of the same address family. In this way an RPC server can -+ * advertise via rpcbind that it does not support AF_INET6. -+ */ -+#ifdef HAVE_XDR_RPCB -+ -+unsigned short nfs_rpcb_getaddr(const struct sockaddr *sap, -+ const socklen_t salen, -+ const unsigned short transport, -+ const struct sockaddr *addr, -+ const socklen_t addrlen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol, -+ const struct timeval *timeout) -+{ -+ CLIENT *client; -+ struct rpcb parms; -+ struct timeval tout = { -1, 0 }; -+ unsigned short port = 0; -+ -+ if (timeout != NULL) -+ tout = *timeout; -+ -+ client = nfs_gp_get_rpcbclient(sap, salen, transport, RPCBVERS_4, &tout); -+ if (client != NULL) { -+ if (nfs_gp_init_rpcb_parms(addr, addrlen, program, version, -+ protocol, &parms) != 0) { -+ port = nfs_gp_rpcb_getaddr(client, &parms, tout); -+ nfs_gp_free_rpcb_parms(&parms); -+ } -+ CLNT_DESTROY(client); -+ } -+ -+ return port; -+} -+ -+#else /* HAVE_XDR_RPCB */ -+ -+unsigned short nfs_rpcb_getaddr(const struct sockaddr *sap, -+ const socklen_t salen, -+ const unsigned short transport, -+ const struct sockaddr *addr, -+ const socklen_t addrlen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol, -+ const struct timeval *timeout) -+{ -+ rpc_createerr.cf_stat = RPC_UNKNOWNADDR; -+ return 0; -+} -+ -+#endif /* HAVE_XDR_RPCB */ -+ -+/** -+ * nfs_pmap_getport - query rpcbind via the portmap protocol (rpcbindv2) -+ * @sin: pointer to AF_INET address of server to query -+ * @transport: transport protocol to use for the query -+ * @program: requested RPC program number -+ * @version: requested RPC version number -+ * @protocol: requested IPPROTO_ value of transport protocol -+ * @timeout: pointer to request timeout (NULL means use default timeout) -+ * -+ * Returns a positive integer representing the port number of the RPC service -+ * advertised by the server (in host byte order), or zero if the service is -+ * not advertised or there was some problem querying the server's rpcbind -+ * daemon. rpccreateerr is set to reflect the underlying cause of the error. -+ * -+ * nfs_pmap_getport() is very similar to pmap_getport(), except that: -+ * -+ * 1. This version always tries to use an ephemeral port, since reserved -+ * ports are not needed for GETPORT queries. This conserves the very -+ * limited reserved port space, helping reduce failed socket binds -+ * during mount storms. -+ * -+ * 2. This version times out quickly by default. It time-limits the -+ * connect process as well as the actual RPC call, and even allows the -+ * caller to specify the timeout. -+ * -+ * 3. This version shares code with the rpcbindv3 and rpcbindv4 query -+ * functions. It can use a TI-RPC generated CLIENT. -+ */ -+unsigned long nfs_pmap_getport(const struct sockaddr_in *sin, -+ const unsigned short transport, -+ const unsigned long program, -+ const unsigned long version, -+ const unsigned long protocol, -+ const struct timeval *timeout) -+{ -+ CLIENT *client; -+ struct pmap parms = { -+ .pm_prog = program, -+ .pm_vers = version, -+ .pm_prot = protocol, -+ }; -+ struct timeval tout = { -1, 0 }; -+ unsigned long port = 0; -+ -+ if (timeout != NULL) -+ tout = *timeout; -+ -+ client = nfs_gp_get_rpcbclient((struct sockaddr *)sin, -+ (socklen_t)sizeof(*sin), -+ transport, PMAPVERS, &tout); -+ if (client != NULL) { -+ port = nfs_gp_pmap_getport(client, &parms, tout); -+ CLNT_DESTROY(client); -+ } -+ -+ return port; -+} ---- nfs-utils-1.1.4/support/include/nfsrpc.h.orig 2008-11-18 15:06:29.121302000 -0500 -+++ nfs-utils-1.1.4/support/include/nfsrpc.h 2008-11-18 15:08:43.267903000 -0500 -@@ -67,4 +67,75 @@ extern CLIENT *nfs_get_rpcclient(const - const rpcprog_t, const rpcvers_t, - struct timeval *); - -+/* -+ * Convert a socket address to a universal address -+ */ -+extern char *nfs_sockaddr2universal(const struct sockaddr *, -+ const socklen_t); -+ -+/* -+ * Extract port number from a universal address -+ */ -+extern int nfs_universal2port(const char *); -+ -+/* -+ * Generic function that maps an RPC service tuple to an IP port -+ * number of the service on a remote post, and sends a NULL -+ * request to determine if the service is responding to requests -+ */ -+extern int nfs_getport_ping(struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol); -+ -+/* -+ * Generic function that maps an RPC service tuple to an IP port -+ * number of the service on a remote host -+ */ -+extern unsigned short nfs_getport(const struct sockaddr *, -+ const socklen_t, const rpcprog_t, -+ const rpcvers_t, const unsigned short); -+ -+/* -+ * Generic function that maps an RPC service tuple to an IP port -+ * number of the service on the local host -+ */ -+extern unsigned short nfs_getlocalport(const rpcprot_t, -+ const rpcvers_t, const unsigned short); -+ -+/* -+ * Function to invoke an rpcbind v3/v4 GETADDR request -+ */ -+extern unsigned short nfs_rpcb_getaddr(const struct sockaddr *, -+ const socklen_t, -+ const unsigned short, -+ const struct sockaddr *, -+ const socklen_t, -+ const rpcprog_t, -+ const rpcvers_t, -+ const unsigned short, -+ const struct timeval *); -+ -+/* -+ * Function to invoke a portmap GETPORT request -+ */ -+extern unsigned long nfs_pmap_getport(const struct sockaddr_in *, -+ const unsigned short, -+ const unsigned long, -+ const unsigned long, -+ const unsigned long, -+ const struct timeval *); -+ -+/* -+ * Contact a remote RPC service to discover whether it is responding -+ * to requests. -+ */ -+extern int nfs_rpc_ping(const struct sockaddr *sap, -+ const socklen_t salen, -+ const rpcprog_t program, -+ const rpcvers_t version, -+ const unsigned short protocol, -+ const struct timeval *timeout); -+ - #endif /* __NFS_UTILS_NFSRPC_H */ diff --git a/nfs-utils-1.1.4-mount-addrconfig.patch b/nfs-utils-1.1.4-mount-addrconfig.patch deleted file mode 100644 index 96945e5..0000000 --- a/nfs-utils-1.1.4-mount-addrconfig.patch +++ /dev/null @@ -1,227 +0,0 @@ ---- nfs-utils-1.1.4/support/nfs/getport.c.save 2009-01-06 12:22:33.100864000 -0500 -+++ nfs-utils-1.1.4/support/nfs/getport.c 2009-01-06 12:23:04.885428000 -0500 -@@ -73,6 +73,60 @@ static const char *nfs_gp_rpcb_pgmtbl[] - NULL, - }; - -+#ifdef HAVE_DECL_AI_ADDRCONFIG -+/* -+ * getaddrinfo(3) generates a usable loopback address based on how the -+ * local network interfaces are configured. RFC 3484 requires that the -+ * results are sorted so that the first result has the best likelihood -+ * of working, so we try just that first result. -+ * -+ * Returns TRUE on success. -+ */ -+static int nfs_gp_loopback_address(struct sockaddr *sap, socklen_t *salen) -+{ -+ struct addrinfo *gai_results; -+ struct addrinfo gai_hint = { -+ .ai_flags = AI_ADDRCONFIG, -+ }; -+ socklen_t len = *salen; -+ int ret = 0; -+ -+ if (getaddrinfo(NULL, "sunrpc", &gai_hint, &gai_results)) -+ return 0; -+ -+ switch (gai_results->ai_addr->sa_family) { -+ case AF_INET: -+ case AF_INET6: -+ if (len >= gai_results->ai_addrlen) { -+ memcpy(sap, gai_results->ai_addr, -+ gai_results->ai_addrlen); -+ *salen = gai_results->ai_addrlen; -+ ret = 1; -+ } -+ } -+ -+ freeaddrinfo(gai_results); -+ return ret; -+} -+#else -+/* -+ * Old versions of getaddrinfo(3) don't support AI_ADDRCONFIG, so we -+ * have a fallback for building on legacy systems. -+ */ -+static int nfs_gp_loopback_address(struct sockaddr *sap, socklen_t *salen) -+{ -+ struct sockaddr_in *sin = (struct sockaddr_in *)sap; -+ -+ memset(sin, 0, sizeof(*sin)); -+ -+ sin->sin_family = AF_INET; -+ sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); -+ *salen = sizeof(*sin); -+ -+ return 1; -+} -+#endif -+ - /* - * Discover the port number that should be used to contact an - * rpcbind service. This will detect if the port has a local -@@ -780,12 +834,10 @@ unsigned short nfs_getlocalport(const rp - const rpcvers_t version, - const unsigned short protocol) - { -- struct addrinfo *gai_results; -- struct addrinfo gai_hint = { -- .ai_flags = AI_ADDRCONFIG, -- }; -+ struct sockaddr_storage address; -+ struct sockaddr *lb_addr = (struct sockaddr *)&address; -+ socklen_t lb_len = sizeof(lb_addr); - unsigned short port = 0; -- int error; - - #ifdef NFS_GP_LOCAL - const struct sockaddr_un sun = { -@@ -811,12 +863,9 @@ unsigned short nfs_getlocalport(const rp - #endif /* NFS_GP_LOCAL */ - - if (port == 0) { -- error = getaddrinfo(NULL, "sunrpc", &gai_hint, &gai_results); -- if (error == 0) { -- port = nfs_getport(gai_results->ai_addr, -- gai_results->ai_addrlen, -+ if (nfs_gp_loopback_address(lb_addr, &lb_len)) { -+ port = nfs_getport(lb_addr, lb_len, - program, version, protocol); -- freeaddrinfo(gai_results); - } else - rpc_createerr.cf_stat = RPC_UNKNOWNADDR; - } ---- nfs-utils-1.1.4/utils/mount/network.c.save 2009-01-06 12:22:12.950764000 -0500 -+++ nfs-utils-1.1.4/utils/mount/network.c 2009-01-06 12:23:10.432801000 -0500 -@@ -50,24 +50,6 @@ - #include "nfsrpc.h" - #include "network.h" - --/* -- * Earlier versions of glibc's /usr/include/netdb.h exclude these -- * definitions because it was thought they were not part of a stable -- * POSIX standard. However, they are defined by RFC 2553 and 3493 -- * and in POSIX 1003.1-2001, so these definitions were added in later -- * versions of netdb.h. -- */ --#ifndef AI_V4MAPPED --#define AI_V4MAPPED 0x0008 /* IPv4-mapped addresses are acceptable. */ --#endif /* AI_V4MAPPED */ --#ifndef AI_ALL --#define AI_ALL 0x0010 /* Return both IPv4 and IPv6 addresses. */ --#endif /* AI_ALL */ --#ifndef AI_ADDRCONFIG --#define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose \ -- returned address type. */ --#endif /* AI_ADDRCONFIG */ -- - #define PMAP_TIMEOUT (10) - #define CONNECT_TIMEOUT (20) - #define MOUNT_TIMEOUT (30) -@@ -175,9 +157,11 @@ static void nfs_set_port(struct sockaddr - } - } - -+#ifdef HAVE_DECL_AI_ADDRCONFIG - /** - * nfs_name_to_address - resolve hostname to an IPv4 or IPv6 socket address - * @hostname: pointer to C string containing DNS hostname to resolve -+ * @af_hint: hint to restrict resolution to one address family - * @sap: pointer to buffer to fill with socket address - * @len: IN: size of buffer to fill; OUT: size of socket address - * -@@ -228,11 +212,66 @@ int nfs_name_to_address(const char *host - freeaddrinfo(gai_results); - return ret; - } -+#else /* HAVE_DECL_AI_ADDRCONFIG */ -+/** -+ * nfs_name_to_address - resolve hostname to an IPv4 socket address -+ * @hostname: pointer to C string containing DNS hostname to resolve -+ * @af_hint: hint to restrict resolution to one address family -+ * @sap: pointer to buffer to fill with socket address -+ * @len: IN: size of buffer to fill; OUT: size of socket address -+ * -+ * Returns 1 and places a socket address at @sap if successful; -+ * otherwise zero. -+ * -+ * Some older getaddrinfo(3) implementations don't support -+ * AI_ADDRCONFIG or AI_V4MAPPED properly. For those cases, a DNS -+ * resolver based on the traditional gethostbyname(3) is provided. -+ */ -+int nfs_name_to_address(const char *hostname, -+ const sa_family_t af_hint, -+ struct sockaddr *sap, socklen_t *salen) -+{ -+ struct sockaddr_in *sin = (struct sockaddr_in *)sap; -+ socklen_t len = *salen; -+ struct hostent *hp; -+ -+ *salen = 0; -+ -+ if (af_hint != AF_INET) { -+ nfs_error(_("%s: address family not supported by DNS resolver\n"), -+ progname, hostname); -+ return 0; -+ } -+ -+ sin->sin_family = AF_INET; -+ if (inet_aton(hostname, &sin->sin_addr)) { -+ *salen = sizeof(*sin); -+ return 1; -+ } -+ -+ hp = gethostbyname(hostname); -+ if (hp == NULL) { -+ nfs_error(_("%s: DNS resolution failed for %s: %s"), -+ progname, hostname, hstrerror(h_errno)); -+ return 0; -+ } -+ -+ if (hp->h_length > len) { -+ nfs_error(_("%s: DNS resolution results too long for buffer\n"), -+ progname); -+ return 0; -+ } -+ -+ memcpy(&sin->sin_addr, hp->h_addr, hp->h_length); -+ *salen = hp->h_length; -+ return 1; -+} -+#endif /* HAVE_DECL_AI_ADDRCONFIG */ - - /** - * nfs_gethostbyname - resolve a hostname to an IPv4 address - * @hostname: pointer to a C string containing a DNS hostname -- * @saddr: returns an IPv4 address -+ * @sin: returns an IPv4 address - * - * Returns 1 if successful, otherwise zero. - */ ---- nfs-utils-1.1.4/configure.ac.save 2009-01-06 12:22:41.437331000 -0500 -+++ nfs-utils-1.1.4/configure.ac 2009-01-06 12:23:10.424809000 -0500 -@@ -246,6 +246,11 @@ if test "$enable_gss" = yes; then - - fi - -+AC_CHECK_DECL([AI_ADDRCONFIG], -+ AC_DEFINE([HAVE_DECL_AI_ADDRCONFIG], 1, -+ [Define this to 1 if AI_ADDRCONFIG macro is defined]), , -+ [ #include ] ) -+ - if test "$enable_ipv6" = yes; then - AC_CHECK_FUNC(inet_ntop, , , - AC_MSG_ERROR(Function 'inet_ntop' not found.)) -@@ -254,7 +259,10 @@ if test "$enable_ipv6" = yes; then - AC_CHECK_LIB(tirpc, clnt_tli_create, , - AC_MSG_ERROR([libtirpc needed for IPv6 support])) - AC_CHECK_HEADERS(tirpc/netconfig.h, , -- AC_MSG_ERROR([libtirpc-devel needed for IPv6 support])) -+ AC_MSG_ERROR([libtirpc headers needed for IPv6 support])) -+ AC_CHECK_DECL([AI_ADDRCONFIG], , -+ AC_MSG_ERROR([full getaddrinfo(3) implementation needed for IPv6 support]), -+ [ #include ] ) - fi - - dnl ************************************************************* diff --git a/nfs-utils-1.1.4-mount-inet6-support.patch b/nfs-utils-1.1.4-mount-inet6-support.patch deleted file mode 100644 index 165df19..0000000 --- a/nfs-utils-1.1.4-mount-inet6-support.patch +++ /dev/null @@ -1,407 +0,0 @@ -commit 71433fbcb0e3142e2b555727197f480d24761d7e -Author: Chuck Lever -Date: Thu Dec 11 10:27:34 2008 -0500 - - mount command: full support for AF_INET6 addresses in probe_port() - - Now that probe_port() uses an AF_INET6-capable rpcbind query and RPC ping, - finish updating probe_port() to support AF_INET6 addresses fully. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit 299a990de1b16ff769201fa0ed38249853254497 -Author: Chuck Lever -Date: Thu Dec 11 10:28:57 2008 -0500 - - mount command: support AF_INET6 in probe_nfsport() and probe_mntport() - - Flesh out support for AF_INET6 in the intermediate helper functions - probe_nfsport() and probe_mntport(). - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit 8a5ef964599438ea45f849a0cd1431a0c26bf054 -Author: Chuck Lever -Date: Thu Dec 11 10:30:20 2008 -0500 - - mount command: AF_INET6 support for probe_bothports() - - Introduce an AF_INET6 capable probe_bothports() API. This means replacing - "struct sockaddr_in *" arguments with a "struct sockaddr *" and a socklen_t - arguments. - - These functions often combine a "struct sockaddr_in" and a "struct pmap" into - a single "clnt_addr_t" argument. Instead of modifying "clnt_addr_t" and all - the legacy code that uses it, I'm going to create a new probe_bothports() API - for the text-based mount command that takes a "struct sockaddr *" and - sockaddr length, and leave the existing probe_bothports() interface, which - takes "clnt_addr_t" arguments, for legacy use. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -diff --git a/utils/mount/network.c b/utils/mount/network.c -index 0c68993..e50bc28 100644 ---- a/utils/mount/network.c -+++ b/utils/mount/network.c -@@ -160,6 +160,21 @@ static const unsigned long probe_mnt3_first[] = { - 0, - }; - -+static void nfs_set_port(struct sockaddr *sap, const unsigned short port) -+{ -+ switch (sap->sa_family) { -+ case AF_INET: -+ ((struct sockaddr_in *)sap)->sin_port = htons(port); -+ break; -+ case AF_INET6: -+ ((struct sockaddr_in6 *)sap)->sin6_port = htons(port); -+ break; -+ default: -+ nfs_error(_("%s: unrecognized address family in %s"), -+ progname, __func__); -+ } -+} -+ - /** - * nfs_name_to_address - resolve hostname to an IPv4 or IPv6 socket address - * @hostname: pointer to C string containing DNS hostname to resolve -@@ -474,27 +489,38 @@ static void nfs_pp_debug(const struct sockaddr *sap, const socklen_t salen, - * Use the portmapper to discover whether or not the service we want is - * available. The lists 'versions' and 'protos' define ordered sequences - * of service versions and udp/tcp protocols to probe for. -+ * -+ * Returns 1 if the requested service port is unambiguous and pingable; -+ * @pmap is filled in with the version, port, and transport protocol used -+ * during the successful ping. Note that if a port is already specified -+ * in @pmap and it matches the rpcbind query result, nfs_probe_port() does -+ * not perform an RPC ping. -+ * -+ * If an error occurs or the requested service isn't available, zero is -+ * returned; rpccreateerr.cf_stat is set to reflect the nature of the error. - */ --static int probe_port(clnt_addr_t *server, const unsigned long *versions, -- const unsigned int *protos) -+static int nfs_probe_port(const struct sockaddr *sap, const socklen_t salen, -+ struct pmap *pmap, const unsigned long *versions, -+ const unsigned int *protos) - { -- const struct sockaddr *saddr = (struct sockaddr *)&server->saddr; -- const socklen_t salen = sizeof(server->saddr); -- struct pmap *pmap = &server->pmap; -+ struct sockaddr_storage address; -+ struct sockaddr *saddr = (struct sockaddr *)&address; - const unsigned long prog = pmap->pm_prog, *p_vers; - const unsigned int prot = (u_int)pmap->pm_prot, *p_prot; - const u_short port = (u_short) pmap->pm_port; - unsigned long vers = pmap->pm_vers; - unsigned short p_port; - -+ memcpy(saddr, sap, salen); - p_prot = prot ? &prot : protos; - p_vers = vers ? &vers : versions; - rpc_createerr.cf_stat = 0; -+ - for (;;) { - p_port = nfs_getport(saddr, salen, prog, *p_vers, *p_prot); - if (p_port) { - if (!port || port == p_port) { -- server->saddr.sin_port = htons(p_port); -+ nfs_set_port(saddr, p_port); - nfs_pp_debug(saddr, salen, prog, *p_vers, - *p_prot, p_port); - if (nfs_rpc_ping(saddr, salen, prog, -@@ -537,28 +563,36 @@ out_ok: - - static int probe_nfsport(clnt_addr_t *nfs_server) - { -+ struct sockaddr *sap = (struct sockaddr *)&nfs_server->saddr; -+ socklen_t salen = sizeof(nfs_server->saddr); - struct pmap *pmap = &nfs_server->pmap; - - if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port) - return 1; - - if (nfs_mount_data_version >= 4) -- return probe_port(nfs_server, probe_nfs3_first, probe_tcp_first); -+ return nfs_probe_port(sap, salen, pmap, -+ probe_nfs3_first, probe_tcp_first); - else -- return probe_port(nfs_server, probe_nfs2_only, probe_udp_only); -+ return nfs_probe_port(sap, salen, pmap, -+ probe_nfs2_only, probe_udp_only); - } - - static int probe_mntport(clnt_addr_t *mnt_server) - { -+ struct sockaddr *sap = (struct sockaddr *)&mnt_server->saddr; -+ socklen_t salen = sizeof(mnt_server->saddr); - struct pmap *pmap = &mnt_server->pmap; - - if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port) - return 1; - - if (nfs_mount_data_version >= 4) -- return probe_port(mnt_server, probe_mnt3_first, probe_udp_first); -+ return nfs_probe_port(sap, salen, pmap, -+ probe_mnt3_first, probe_udp_first); - else -- return probe_port(mnt_server, probe_mnt1_first, probe_udp_only); -+ return nfs_probe_port(sap, salen, pmap, -+ probe_mnt1_first, probe_udp_only); - } - - /** -diff --git a/utils/mount/network.c b/utils/mount/network.c -index e50bc28..55b2cab 100644 ---- a/utils/mount/network.c -+++ b/utils/mount/network.c -@@ -561,12 +561,22 @@ out_ok: - return 1; - } - --static int probe_nfsport(clnt_addr_t *nfs_server) -+/* -+ * Probe a server's NFS service to determine which versions and -+ * transport protocols are supported. -+ * -+ * Returns 1 if the requested service port is unambiguous and pingable; -+ * @pmap is filled in with the version, port, and transport protocol used -+ * during the successful ping. If all three are already specified, simply -+ * return success without an rpcbind query or RPC ping (we may be trying -+ * to mount an NFS service that is not advertised via rpcbind). -+ * -+ * If an error occurs or the requested service isn't available, zero is -+ * returned; rpccreateerr.cf_stat is set to reflect the nature of the error. -+ */ -+static int nfs_probe_nfsport(const struct sockaddr *sap, const socklen_t salen, -+ struct pmap *pmap) - { -- struct sockaddr *sap = (struct sockaddr *)&nfs_server->saddr; -- socklen_t salen = sizeof(nfs_server->saddr); -- struct pmap *pmap = &nfs_server->pmap; -- - if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port) - return 1; - -@@ -578,12 +588,22 @@ static int probe_nfsport(clnt_addr_t *nfs_server) - probe_nfs2_only, probe_udp_only); - } - --static int probe_mntport(clnt_addr_t *mnt_server) -+/* -+ * Probe a server's mountd service to determine which versions and -+ * transport protocols are supported. -+ * -+ * Returns 1 if the requested service port is unambiguous and pingable; -+ * @pmap is filled in with the version, port, and transport protocol used -+ * during the successful ping. If all three are already specified, simply -+ * return success without an rpcbind query or RPC ping (we may be trying -+ * to mount an NFS service that is not advertised via rpcbind). -+ * -+ * If an error occurs or the requested service isn't available, zero is -+ * returned; rpccreateerr.cf_stat is set to reflect the nature of the error. -+ */ -+static int nfs_probe_mntport(const struct sockaddr *sap, const socklen_t salen, -+ struct pmap *pmap) - { -- struct sockaddr *sap = (struct sockaddr *)&mnt_server->saddr; -- socklen_t salen = sizeof(mnt_server->saddr); -- struct pmap *pmap = &mnt_server->pmap; -- - if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port) - return 1; - -@@ -607,10 +627,13 @@ static int probe_mntport(clnt_addr_t *mnt_server) - */ - int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server) - { -+ struct sockaddr *nfs_saddr = (struct sockaddr *)&nfs_server->saddr; -+ socklen_t nfs_salen = sizeof(nfs_server->saddr); -+ struct sockaddr *mnt_saddr = (struct sockaddr *)&mnt_server->saddr; -+ socklen_t mnt_salen = sizeof(mnt_server->saddr); - struct pmap *nfs_pmap = &nfs_server->pmap; - struct pmap *mnt_pmap = &mnt_server->pmap; - struct pmap save_nfs, save_mnt; -- int res; - const unsigned long *probe_vers; - - if (mnt_pmap->pm_vers && !nfs_pmap->pm_vers) -@@ -627,9 +650,9 @@ int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server) - - for (; *probe_vers; probe_vers++) { - nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers); -- if ((res = probe_nfsport(nfs_server) != 0)) { -+ if (nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap) != 0) { - mnt_pmap->pm_vers = *probe_vers; -- if ((res = probe_mntport(mnt_server)) != 0) -+ if (nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap) != 0) - return 1; - memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap)); - } -@@ -647,9 +670,9 @@ out_bad: - return 0; - - version_fixed: -- if (!probe_nfsport(nfs_server)) -+ if (!nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap)) - goto out_bad; -- return probe_mntport(mnt_server); -+ return nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap); - } - - static int nfs_probe_statd(void) -@@ -716,11 +739,14 @@ int start_statd(void) - */ - int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp) - { -+ struct sockaddr *sap = (struct sockaddr *)&mnt_server->saddr; -+ socklen_t salen = sizeof(mnt_server->saddr); -+ struct pmap *pmap = &mnt_server->pmap; - CLIENT *clnt; - enum clnt_stat res = 0; - int msock; - -- if (!probe_mntport(mnt_server)) -+ if (!nfs_probe_mntport(sap, salen, pmap)) - return 0; - clnt = mnt_openclnt(mnt_server, &msock); - if (!clnt) -diff --git a/utils/mount/network.c b/utils/mount/network.c -index 55b2cab..6a9a41a 100644 ---- a/utils/mount/network.c -+++ b/utils/mount/network.c -@@ -615,24 +615,49 @@ static int nfs_probe_mntport(const struct sockaddr *sap, const socklen_t salen, - probe_mnt1_first, probe_udp_only); - } - --/** -- * probe_bothports - discover the RPC endpoints of mountd and NFS server -- * @mnt_server: pointer to address and pmap argument for mountd results -- * @nfs_server: pointer to address and pmap argument for NFS server -+/* -+ * Probe a server's mountd service to determine which versions and -+ * transport protocols are supported. Invoked when the protocol -+ * version is already known for both the NFS and mountd service. - * -- * Returns 1 if successful, otherwise zero if some error occurred. -- * Note that the arguments are both input and output arguments. -+ * Returns 1 and fills in both @pmap structs if the requested service -+ * ports are unambiguous and pingable. Otherwise zero is returned; -+ * rpccreateerr.cf_stat is set to reflect the nature of the error. -+ */ -+static int nfs_probe_version_fixed(const struct sockaddr *mnt_saddr, -+ const socklen_t mnt_salen, -+ struct pmap *mnt_pmap, -+ const struct sockaddr *nfs_saddr, -+ const socklen_t nfs_salen, -+ struct pmap *nfs_pmap) -+{ -+ if (!nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap)) -+ return 0; -+ return nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap); -+} -+ -+/** -+ * nfs_probe_bothports - discover the RPC endpoints of mountd and NFS server -+ * @mnt_saddr: pointer to socket address of mountd server -+ * @mnt_salen: length of mountd server's address -+ * @mnt_pmap: IN: partially filled-in mountd RPC service tuple; -+ * OUT: fully filled-in mountd RPC service tuple -+ * @nfs_saddr: pointer to socket address of NFS server -+ * @nfs_salen: length of NFS server's address -+ * @nfs_pmap: IN: partially filled-in NFS RPC service tuple; -+ * OUT: fully filled-in NFS RPC service tuple - * -- * A side effect of calling this function is that rpccreateerr is set. -+ * Returns 1 and fills in both @pmap structs if the requested service -+ * ports are unambiguous and pingable. Otherwise zero is returned; -+ * rpccreateerr.cf_stat is set to reflect the nature of the error. - */ --int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server) -+int nfs_probe_bothports(const struct sockaddr *mnt_saddr, -+ const socklen_t mnt_salen, -+ struct pmap *mnt_pmap, -+ const struct sockaddr *nfs_saddr, -+ const socklen_t nfs_salen, -+ struct pmap *nfs_pmap) - { -- struct sockaddr *nfs_saddr = (struct sockaddr *)&nfs_server->saddr; -- socklen_t nfs_salen = sizeof(nfs_server->saddr); -- struct sockaddr *mnt_saddr = (struct sockaddr *)&mnt_server->saddr; -- socklen_t mnt_salen = sizeof(mnt_server->saddr); -- struct pmap *nfs_pmap = &nfs_server->pmap; -- struct pmap *mnt_pmap = &mnt_server->pmap; - struct pmap save_nfs, save_mnt; - const unsigned long *probe_vers; - -@@ -640,8 +665,10 @@ int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server) - nfs_pmap->pm_vers = mntvers_to_nfs(mnt_pmap->pm_vers); - else if (nfs_pmap->pm_vers && !mnt_pmap->pm_vers) - mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers); -+ - if (nfs_pmap->pm_vers) -- goto version_fixed; -+ return nfs_probe_version_fixed(mnt_saddr, mnt_salen, mnt_pmap, -+ nfs_saddr, nfs_salen, nfs_pmap); - - memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs)); - memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt)); -@@ -661,18 +688,35 @@ int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server) - case RPC_PROGNOTREGISTERED: - break; - default: -- goto out_bad; -+ return 0; - } - memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap)); - } - --out_bad: - return 0; -+} - --version_fixed: -- if (!nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap)) -- goto out_bad; -- return nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap); -+/** -+ * probe_bothports - discover the RPC endpoints of mountd and NFS server -+ * @mnt_server: pointer to address and pmap argument for mountd results -+ * @nfs_server: pointer to address and pmap argument for NFS server -+ * -+ * This is the legacy API that takes "clnt_addr_t" for both servers, -+ * but supports only AF_INET addresses. -+ * -+ * Returns 1 and fills in the pmap field in both clnt_addr_t structs -+ * if the requested service ports are unambiguous and pingable. -+ * Otherwise zero is returned; rpccreateerr.cf_stat is set to reflect -+ * the nature of the error. -+ */ -+int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server) -+{ -+ return nfs_probe_bothports((struct sockaddr *)&mnt_server->saddr, -+ sizeof(mnt_server->saddr), -+ &mnt_server->pmap, -+ (struct sockaddr *)&nfs_server->saddr, -+ sizeof(nfs_server->saddr), -+ &nfs_server->pmap); - } - - static int nfs_probe_statd(void) -diff --git a/utils/mount/network.h b/utils/mount/network.h -index a4dba1b..075093d 100644 ---- a/utils/mount/network.h -+++ b/utils/mount/network.h -@@ -40,6 +40,9 @@ static const struct timeval TIMEOUT = { 20, 0 }; - static const struct timeval RETRY_TIMEOUT = { 3, 0 }; - - int probe_bothports(clnt_addr_t *, clnt_addr_t *); -+int nfs_probe_bothports(const struct sockaddr *, const socklen_t, -+ struct pmap *, const struct sockaddr *, -+ const socklen_t, struct pmap *); - int nfs_gethostbyname(const char *, struct sockaddr_in *); - int nfs_name_to_address(const char *, const sa_family_t, - struct sockaddr *, socklen_t *); diff --git a/nfs-utils-1.1.4-mount-nfs_getport.patch b/nfs-utils-1.1.4-mount-nfs_getport.patch deleted file mode 100644 index 00e7692..0000000 --- a/nfs-utils-1.1.4-mount-nfs_getport.patch +++ /dev/null @@ -1,276 +0,0 @@ -commit b8711a0665b9ecff9d59ee36d756f50823242f64 -Author: Chuck Lever -Date: Tue Dec 2 07:43:54 2008 -0500 - - mount command: remove local getport() implementation - - Eliminate local getport() implementation from utils/mount/network.c, as - it is no longer used. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit cc58ba0c98b2f687810a5af9e6185bcc5e855fb0 -Author: Chuck Lever -Date: Tue Dec 2 07:43:01 2008 -0500 - - mount command: Replace clnt_ping() and getport() calls in probe_port() - - Update the mount command's probe_port() function to call the new shared - rpcbind query and RPC ping functions. This provides immediate support - for - rpcbind v3/v4 queries, and paves the way for supporting AF_INET6 in the - probe_bothports() path. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit 14b0dae49afae3fcf05c19ae84829aeef2f6876e -Author: Chuck Lever -Date: Tue Dec 2 07:40:16 2008 -0500 - - mount command: Use nfs_error() instead of perror() - - So we can ensure that error output is directed appropriately, use - nfs_error() instead of perror() in start_statd(). - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit ea0473feffd8071216c96217df3202a8deed2c65 -Author: Chuck Lever -Date: Tue Dec 2 07:39:06 2008 -0500 - - mount command: Use nfs_pmap_getport() in probe_statd() - - Repace the getport() and clnt_ping() calls in probe_statd() with their - new shared equivalents. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/utils/mount/network.c.orig nfs-utils-1.1.4/utils/mount/network.c ---- nfs-utils-1.1.4/utils/mount/network.c.orig 2008-12-01 09:14:24.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/network.c 2008-12-02 08:32:00.000000000 -0500 -@@ -47,6 +47,7 @@ - #include "nls.h" - #include "nfs_mount.h" - #include "mount_constants.h" -+#include "nfsrpc.h" - #include "network.h" - - /* -@@ -79,6 +80,11 @@ extern int nfs_mount_data_version; - extern char *progname; - extern int verbose; - -+static const char *nfs_ns_pgmtbl[] = { -+ "status", -+ NULL, -+}; -+ - static const unsigned long nfs_to_mnt[] = { - 0, - 0, -@@ -443,76 +449,25 @@ err_connect: - return RPC_ANYSOCK; - } - --/* -- * getport() is very similar to pmap_getport() with the exception that -- * this version tries to use an ephemeral port, since reserved ports are -- * not needed for GETPORT queries. This conserves the very limited -- * reserved port space, which helps reduce failed socket binds -- * during mount storms. -- * -- * A side effect of calling this function is that rpccreateerr is set. -- */ --static unsigned short getport(struct sockaddr_in *saddr, -- unsigned long program, -- unsigned long version, -- unsigned int proto) --{ -- struct sockaddr_in bind_saddr; -- unsigned short port = 0; -- int socket; -- CLIENT *clnt = NULL; -- enum clnt_stat stat; -- -- bind_saddr = *saddr; -- bind_saddr.sin_port = htons(PMAPPORT); -- -- 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) -- rpc_createerr.cf_stat = RPC_TIMEDOUT; -- return 0; -- } -+static void nfs_pp_debug(const struct sockaddr *sap, const socklen_t salen, -+ const rpcprog_t program, const rpcvers_t version, -+ const unsigned short protocol, -+ const unsigned short port) -+{ -+ char buf[NI_MAXHOST]; - -- switch (proto) { -- case IPPROTO_UDP: -- clnt = clntudp_bufcreate(&bind_saddr, -- PMAPPROG, PMAPVERS, -- RETRY_TIMEOUT, &socket, -- RPCSMALLMSGSIZE, -- RPCSMALLMSGSIZE); -- break; -- case IPPROTO_TCP: -- clnt = clnttcp_create(&bind_saddr, -- PMAPPROG, PMAPVERS, -- &socket, -- RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); -- break; -- } -- if (clnt != NULL) { -- struct pmap parms = { -- .pm_prog = program, -- .pm_vers = version, -- .pm_prot = proto, -- }; -- -- stat = clnt_call(clnt, PMAPPROC_GETPORT, -- (xdrproc_t)xdr_pmap, (caddr_t)&parms, -- (xdrproc_t)xdr_u_short, (caddr_t)&port, -- TIMEOUT); -- if (stat) { -- clnt_geterr(clnt, &rpc_createerr.cf_error); -- rpc_createerr.cf_stat = stat; -- } -- clnt_destroy(clnt); -- if (stat != RPC_SUCCESS) -- port = 0; -- else if (port == 0) -- rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; -+ if (!verbose) -+ return; -+ -+ if (nfs_present_sockaddr(sap, salen, buf, sizeof(buf)) == 0) { -+ buf[0] = '\0'; -+ strcat(buf, "unknown host"); - } -- close(socket); - -- return port; -+ fprintf(stderr, _("%s: trying %s prog %ld vers %ld prot %s port %d\n"), -+ progname, buf, program, version, -+ (protocol == IPPROTO_UDP ? _("UDP") : _("TCP")), -+ port); - } - - /* -@@ -523,7 +478,8 @@ static unsigned short getport(struct soc - static int probe_port(clnt_addr_t *server, const unsigned long *versions, - const unsigned int *protos) - { -- struct sockaddr_in *saddr = &server->saddr; -+ const struct sockaddr *saddr = (struct sockaddr *)&server->saddr; -+ const socklen_t salen = sizeof(server->saddr); - struct pmap *pmap = &server->pmap; - const unsigned long prog = pmap->pm_prog, *p_vers; - const unsigned int prot = (u_int)pmap->pm_prot, *p_prot; -@@ -535,21 +491,14 @@ static int probe_port(clnt_addr_t *serve - p_vers = vers ? &vers : versions; - rpc_createerr.cf_stat = 0; - for (;;) { -- p_port = getport(saddr, prog, *p_vers, *p_prot); -+ p_port = nfs_getport(saddr, salen, prog, *p_vers, *p_prot); - if (p_port) { - if (!port || port == p_port) { -- saddr->sin_port = htons(p_port); -- if (verbose) { -- printf(_("%s: trying %s prog %ld vers " -- "%ld prot %s port %d\n"), -- progname, -- inet_ntoa(saddr->sin_addr), -- prog, *p_vers, -- *p_prot == IPPROTO_UDP ? -- _("UDP") : _("TCP"), -- p_port); -- } -- if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL)) -+ server->saddr.sin_port = htons(p_port); -+ nfs_pp_debug(saddr, salen, prog, *p_vers, -+ *p_prot, p_port); -+ if (nfs_rpc_ping(saddr, salen, prog, -+ *p_vers, *p_prot, NULL)) - goto out_ok; - } - } -@@ -669,24 +618,16 @@ version_fixed: - return probe_mntport(mnt_server); - } - --static int probe_statd(void) -+static int nfs_probe_statd(void) - { -- struct sockaddr_in addr; -- unsigned short port; -- -- memset(&addr, 0, sizeof(addr)); -- addr.sin_family = AF_INET; -- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); -- port = getport(&addr, 100024, 1, IPPROTO_UDP); -- -- if (port == 0) -- return 0; -- addr.sin_port = htons(port); -- -- if (clnt_ping(&addr, 100024, 1, IPPROTO_UDP, NULL) <= 0) -- return 0; -+ struct sockaddr_in addr = { -+ .sin_family = AF_INET, -+ .sin_addr.s_addr = htonl(INADDR_LOOPBACK), -+ }; -+ rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl); - -- return 1; -+ return nfs_getport_ping((struct sockaddr *)&addr, sizeof(addr), -+ program, (rpcvers_t)1, IPPROTO_UDP); - } - - /** -@@ -700,7 +641,7 @@ int start_statd(void) - struct stat stb; - #endif - -- if (probe_statd()) -+ if (nfs_probe_statd()) - return 1; - - #ifdef START_STATD -@@ -712,13 +653,14 @@ int start_statd(void) - execl(START_STATD, START_STATD, NULL); - exit(1); - case -1: /* error */ -- perror("Fork failed"); -+ nfs_error(_("fork failed: %s"), -+ strerror(errno)); - break; - default: /* parent */ - waitpid(pid, NULL,0); - break; - } -- if (probe_statd()) -+ if (nfs_probe_statd()) - return 1; - } - } -@@ -829,9 +771,9 @@ void mnt_closeclnt(CLIENT *clnt, int mso - * @prot: target RPC protocol - * @caddr: filled in with our network address - * -- * Sigh... getport() doesn't actually check the version number. -+ * Sigh... GETPORT queries don't actually check the version number. - * In order to make sure that the server actually supports the service -- * we're requesting, we open and RPC client, and fire off a NULL -+ * we're requesting, we open an RPC client, and fire off a NULL - * RPC call. - * - * caddr is the network address that the server will use to call us back. diff --git a/nfs-utils-1.1.4-mount-nolock.patch b/nfs-utils-1.1.4-mount-nolock.patch deleted file mode 100644 index 5c0da19..0000000 --- a/nfs-utils-1.1.4-mount-nolock.patch +++ /dev/null @@ -1,139 +0,0 @@ -commit e7ec5e745e851ad10c56d579463ee7e1b85c9c21 -Author: Chuck Lever -Date: Tue Feb 17 15:19:58 2009 -0500 - - text-based mount command: fix return value from po_rightmost() - - Recently commit 0dcb83a8 changed the po_rightmost() function to - distinguish among several possible mount options by taking a table - containing the alternatives, and returning the table index of the - entry which is rightmost in the mount option string. - - If it didn't find any mount option that matches an entry from the - passed-in table, it returned zero. This was the same behavior it had - before, when it only checked for two options at a time. It returned - PO_NEITHER_FOUND, which was zero. - - Since this is C, however, zero also happens to be a valid index into - the passed-in array of options. - - Modify the po_rightmost() function to return -1 if the entry wasn't - found, and fix up the callers to look for a C-style array index that - starts at zero. - - Thanks to Steve Dickson for troubleshooting the problem. His solution - was merely to bump the return value, as callers already expected an - ordinal index instead of a C-style index. - - I prefer this equivalent but slightly more extensive change because it - makes the behavior of po_rightmost() more closely match how humans - understand C arrays to work. Let's address some of the confusion that - caused this bug, as well as fixing the run-time behavior. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/utils/mount/network.c.orig nfs-utils-1.1.4/utils/mount/network.c ---- nfs-utils-1.1.4/utils/mount/network.c.orig 2009-02-17 15:51:27.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/network.c 2009-02-17 15:52:13.000000000 -0500 -@@ -1168,16 +1168,16 @@ static rpcvers_t nfs_nfs_version(struct - long tmp; - - switch (po_rightmost(options, nfs_version_opttbl)) { -- case 1: /* v2 */ -+ case 0: /* v2 */ - return 2; -- case 2: /* v3 */ -+ case 1: /* v3 */ - return 3; -- case 3: /* vers */ -+ case 2: /* vers */ - if (po_get_numeric(options, "vers", &tmp) == PO_FOUND) - if (tmp >= 2 && tmp <= 3) - return tmp; - break; -- case 4: /* nfsvers */ -+ case 3: /* nfsvers */ - if (po_get_numeric(options, "nfsvers", &tmp) == PO_FOUND) - if (tmp >= 2 && tmp <= 3) - return tmp; -@@ -1198,11 +1198,9 @@ static unsigned short nfs_nfs_protocol(s - char *option; - - switch (po_rightmost(options, nfs_transport_opttbl)) { -- case 1: /* udp */ -- return IPPROTO_UDP; -- case 2: /* tcp */ -+ case 1: /* tcp */ - return IPPROTO_TCP; -- case 3: /* proto */ -+ case 2: /* proto */ - option = po_get(options, "proto"); - if (option) { - if (strcmp(option, "tcp") == 0) -@@ -1211,6 +1209,7 @@ static unsigned short nfs_nfs_protocol(s - return IPPROTO_UDP; - } - } -+ - return IPPROTO_UDP; - } - -diff -up nfs-utils-1.1.4/utils/mount/parse_opt.c.orig nfs-utils-1.1.4/utils/mount/parse_opt.c ---- nfs-utils-1.1.4/utils/mount/parse_opt.c.orig 2009-02-17 15:51:27.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/parse_opt.c 2009-02-17 15:52:13.000000000 -0500 -@@ -437,9 +437,10 @@ po_found_t po_get_numeric(struct mount_o - * as "proto=," "udp" and "tcp." - * - * Returns the index into @keys of the option that is rightmost. -- * If none of the options are present, returns zero. -+ * If none of the options listed in @keys is present in @options, or -+ * if @options is NULL, returns -1. - */ --unsigned int po_rightmost(struct mount_options *options, const char *keys[]) -+int po_rightmost(struct mount_options *options, const char *keys[]) - { - struct mount_option *option; - unsigned int i; -@@ -452,7 +453,7 @@ unsigned int po_rightmost(struct mount_o - } - } - -- return 0; -+ return -1; - } - - /** -diff -up nfs-utils-1.1.4/utils/mount/parse_opt.h.orig nfs-utils-1.1.4/utils/mount/parse_opt.h ---- nfs-utils-1.1.4/utils/mount/parse_opt.h.orig 2009-02-17 15:51:27.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/parse_opt.h 2009-02-17 15:52:13.000000000 -0500 -@@ -47,7 +47,7 @@ po_found_t po_contains(struct mount_opt - char * po_get(struct mount_options *, char *); - po_found_t po_get_numeric(struct mount_options *, - char *, long *); --unsigned int po_rightmost(struct mount_options *, -+int po_rightmost(struct mount_options *, - const char *keys[]); - po_found_t po_remove_all(struct mount_options *, char *); - void po_destroy(struct mount_options *); -diff -up nfs-utils-1.1.4/utils/mount/stropts.c.orig nfs-utils-1.1.4/utils/mount/stropts.c ---- nfs-utils-1.1.4/utils/mount/stropts.c.orig 2009-02-17 15:51:27.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/stropts.c 2009-02-17 15:52:13.000000000 -0500 -@@ -232,7 +232,7 @@ static const char *nfs_lock_opttbl[] = { - - static int nfs_verify_lock_option(struct mount_options *options) - { -- if (po_rightmost(options, nfs_lock_opttbl) == 1) -+ if (po_rightmost(options, nfs_lock_opttbl) == 0) - return 1; - - if (!start_statd()) { -@@ -756,7 +756,7 @@ static int nfsmount_start(struct nfsmoun - if (!nfs_validate_options(mi)) - return EX_FAIL; - -- if (po_rightmost(mi->options, nfs_background_opttbl) == 1) -+ if (po_rightmost(mi->options, nfs_background_opttbl) == 0) - return nfsmount_bg(mi); - else - return nfsmount_fg(mi); diff --git a/nfs-utils-1.1.4-mount-po_get_numeric.patch b/nfs-utils-1.1.4-mount-po_get_numeric.patch deleted file mode 100644 index 35b99a7..0000000 --- a/nfs-utils-1.1.4-mount-po_get_numeric.patch +++ /dev/null @@ -1,153 +0,0 @@ -commit b5009d23525181846777349f2fc0e4a72b89d24d -Author: Chuck Lever -Date: Wed Dec 17 14:21:10 2008 -0500 - - text-based mount command: add function to parse numeric mount options - - Introduce a function that is especially for parsing keyword mount options - that take a numeric value. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -diff --git a/utils/mount/parse_opt.c b/utils/mount/parse_opt.c -index cb398bd..f61d0dd 100644 ---- a/utils/mount/parse_opt.c -+++ b/utils/mount/parse_opt.c -@@ -36,6 +36,10 @@ - */ - - -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ - #include - #include - #include -@@ -366,6 +370,57 @@ char *po_get(struct mount_options *options, char *keyword) - } - - /** -+ * po_get_numeric - return numeric value of rightmost instance of keyword option -+ * @options: pointer to mount options -+ * @keyword: pointer to a C string containing option keyword for which to search -+ * @value: OUT: set to the value of the keyword -+ * -+ * This is specifically for parsing keyword options that take only a numeric -+ * value. If multiple instances of the same option are present in a mount -+ * option list, the rightmost instance is always the effective one. -+ * -+ * Returns: -+ * * PO_FOUND if the keyword was found and the value is numeric; @value is -+ * set to the keyword's value -+ * * PO_NOT_FOUND if the keyword was not found -+ * * PO_BAD_VALUE if the keyword was found, but the value is not numeric -+ * -+ * These last two are separate in case the caller wants to warn about bad mount -+ * options instead of silently using a default. -+ */ -+#ifdef HAVE_STRTOL -+po_found_t po_get_numeric(struct mount_options *options, char *keyword, long *value) -+{ -+ char *option, *endptr; -+ long tmp; -+ -+ option = po_get(options, keyword); -+ if (option == NULL) -+ return PO_NOT_FOUND; -+ -+ errno = 0; -+ tmp = strtol(option, &endptr, 10); -+ if (errno == 0 && endptr != option) { -+ *value = tmp; -+ return PO_FOUND; -+ } -+ return PO_BAD_VALUE; -+} -+#else /* HAVE_STRTOL */ -+po_found_t po_get_numeric(struct mount_options *options, char *keyword, long *value) -+{ -+ char *option; -+ -+ option = po_get(options, keyword); -+ if (option == NULL) -+ return PO_NOT_FOUND; -+ -+ *value = atoi(option); -+ return PO_FOUND; -+} -+#endif /* HAVE_STRTOL */ -+ -+/** - * po_rightmost - determine the relative position of two options - * @options: pointer to mount options - * @key1: pointer to a C string containing an option keyword -diff --git a/utils/mount/parse_opt.h b/utils/mount/parse_opt.h -index fb003c3..199630f 100644 ---- a/utils/mount/parse_opt.h -+++ b/utils/mount/parse_opt.h -@@ -32,6 +32,7 @@ typedef enum { - typedef enum { - PO_NOT_FOUND = 0, - PO_FOUND = 1, -+ PO_BAD_VALUE = 2, - } po_found_t; - - typedef enum { -@@ -50,6 +51,8 @@ po_return_t po_join(struct mount_options *, char **); - po_return_t po_append(struct mount_options *, char *); - po_found_t po_contains(struct mount_options *, char *); - char * po_get(struct mount_options *, char *); -+po_found_t po_get_numeric(struct mount_options *, -+ char *, long *); - po_rightmost_t po_rightmost(struct mount_options *, char *, char *); - po_found_t po_remove_all(struct mount_options *, char *); - void po_destroy(struct mount_options *); -commit 3f23f712477df48fd1d57376b65c44bb2a19ec16 -Author: Chuck Lever -Date: Wed Dec 17 14:23:43 2008 -0500 - - text-based mount command: use po_get_numeric() for handling retry - - Replace the logic in nfs_parse_retry_option() with a call to the new - po_get_numeric() function. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index 09fca86..43791e6 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -99,19 +99,21 @@ struct nfsmount_info { - static time_t nfs_parse_retry_option(struct mount_options *options, - unsigned int timeout_minutes) - { -- char *retry_option, *endptr; -+ long tmp; - -- retry_option = po_get(options, "retry"); -- if (retry_option) { -- long tmp; -- -- errno = 0; -- tmp = strtol(retry_option, &endptr, 10); -- if (errno == 0 && endptr != retry_option && tmp >= 0) -+ switch (po_get_numeric(options, "retry", &tmp)) { -+ case PO_NOT_FOUND: -+ break; -+ case PO_FOUND: -+ if (tmp >= 0) { - timeout_minutes = tmp; -- else if (verbose) -+ break; -+ } -+ case PO_BAD_VALUE: -+ if (verbose) - nfs_error(_("%s: invalid retry timeout was specified; " - "using default timeout"), progname); -+ break; - } - - return time(NULL) + (time_t)(timeout_minutes * 60); diff --git a/nfs-utils-1.1.4-mount-textbased.patch b/nfs-utils-1.1.4-mount-textbased.patch deleted file mode 100644 index d941ce8..0000000 --- a/nfs-utils-1.1.4-mount-textbased.patch +++ /dev/null @@ -1,821 +0,0 @@ -text-based mount command: make po_rightmost() work for N options - -Sometimes we need to choose the rightmost option among multiple -different mount options. For example, we want to find the rightmost -of "proto," "tcp," and "udp". Or, the rightmost of "vers," "nfsvers," -"v2," and "v3". - -Update po_rightmost() to choose among N options instead of just two. - -Signed-off-by: Chuck Lever ---- - - utils/mount/parse_opt.c | 28 ++++++++++++++++------------ - utils/mount/parse_opt.h | 9 ++------- - utils/mount/stropts.c | 28 +++++++++++++++++++++++----- - 3 files changed, 41 insertions(+), 24 deletions(-) - -diff --git a/utils/mount/parse_opt.c b/utils/mount/parse_opt.c -index f61d0dd..4934508 100644 ---- a/utils/mount/parse_opt.c -+++ b/utils/mount/parse_opt.c -@@ -421,34 +421,38 @@ po_found_t po_get_numeric(struct mount_options *options, char *keyword, long *va - #endif /* HAVE_STRTOL */ - - /** -- * po_rightmost - determine the relative position of two options -+ * po_rightmost - determine the relative position of several options - * @options: pointer to mount options -- * @key1: pointer to a C string containing an option keyword -- * @key2: pointer to a C string containing another option keyword -+ * @keys: pointer to an array of C strings containing option keywords -+ * -+ * This function can be used to determine which of several similar -+ * options will be the one to take effect. - * - * The kernel parses the mount option string from left to right. - * If an option is specified more than once (for example, "intr" - * and "nointr", the rightmost option is the last to be parsed, - * and it therefore takes precedence over previous similar options. - * -- * This function can be used to determine which of two similar -- * options will be the one to take effect. -+ * This can also distinguish among multiple synonymous options, such -+ * as "proto=," "udp" and "tcp." -+ * -+ * Returns the index into @keys of the option that is rightmost. -+ * If none of the options are present, returns zero. - */ --po_rightmost_t po_rightmost(struct mount_options *options, -- char *key1, char *key2) -+unsigned int po_rightmost(struct mount_options *options, const char *keys[]) - { - struct mount_option *option; -+ unsigned int i; - - if (options) { - for (option = options->tail; option; option = option->prev) { -- if (key2 && strcmp(option->keyword, key2) == 0) -- return PO_KEY2_RIGHTMOST; -- if (key1 && strcmp(option->keyword, key1) == 0) -- return PO_KEY1_RIGHTMOST; -+ for (i = 0; keys[i] != NULL; i++) -+ if (strcmp(option->keyword, keys[i]) == 0) -+ return i; - } - } - -- return PO_NEITHER_FOUND; -+ return 0; - } - - /** -diff --git a/utils/mount/parse_opt.h b/utils/mount/parse_opt.h -index 199630f..e132b1c 100644 ---- a/utils/mount/parse_opt.h -+++ b/utils/mount/parse_opt.h -@@ -35,12 +35,6 @@ typedef enum { - PO_BAD_VALUE = 2, - } po_found_t; - --typedef enum { -- PO_KEY1_RIGHTMOST = -1, -- PO_NEITHER_FOUND = 0, -- PO_KEY2_RIGHTMOST = 1, --} po_rightmost_t; -- - struct mount_options; - - struct mount_options * po_split(char *); -@@ -53,7 +47,8 @@ po_found_t po_contains(struct mount_options *, char *); - char * po_get(struct mount_options *, char *); - po_found_t po_get_numeric(struct mount_options *, - char *, long *); --po_rightmost_t po_rightmost(struct mount_options *, char *, char *); -+unsigned int po_rightmost(struct mount_options *, -+ const char *keys[]); - po_found_t po_remove_all(struct mount_options *, char *); - void po_destroy(struct mount_options *); - -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index 43791e6..bd127ab 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -224,9 +224,15 @@ static int nfs_fix_mounthost_option(const sa_family_t family, - * Returns zero if the "lock" option is in effect, but statd - * can't be started. Otherwise, returns 1. - */ -+static const char *nfs_lock_opttbl[] = { -+ "nolock", -+ "lock", -+ NULL, -+}; -+ - static int nfs_verify_lock_option(struct mount_options *options) - { -- if (po_rightmost(options, "nolock", "lock") == PO_KEY1_RIGHTMOST) -+ if (po_rightmost(options, nfs_lock_opttbl) == 1) - return 1; - - if (!start_statd()) { -@@ -316,6 +322,12 @@ static int nfs_is_permanent_error(int error) - * Returns a new group of mount options if successful; otherwise - * NULL is returned if some failure occurred. - */ -+static const char *nfs_transport_opttbl[] = { -+ "udp", -+ "tcp", -+ NULL, -+}; -+ - static struct mount_options *nfs_rewrite_mount_options(char *str) - { - struct mount_options *options; -@@ -395,12 +407,12 @@ static struct mount_options *nfs_rewrite_mount_options(char *str) - po_remove_all(options, "proto"); - } - } -- p = po_rightmost(options, "tcp", "udp"); -+ p = po_rightmost(options, nfs_transport_opttbl); - switch (p) { -- case PO_KEY2_RIGHTMOST: -+ case 1: - nfs_server.pmap.pm_prot = IPPROTO_UDP; - break; -- case PO_KEY1_RIGHTMOST: -+ case 2: - nfs_server.pmap.pm_prot = IPPROTO_TCP; - break; - } -@@ -722,12 +734,18 @@ static int nfsmount_bg(struct nfsmount_info *mi) - * - * Returns a valid mount command exit code. - */ -+static const char *nfs_background_opttbl[] = { -+ "bg", -+ "fg", -+ NULL, -+}; -+ - static int nfsmount_start(struct nfsmount_info *mi) - { - if (!nfs_validate_options(mi)) - return EX_FAIL; - -- if (po_rightmost(mi->options, "bg", "fg") == PO_KEY1_RIGHTMOST) -+ if (po_rightmost(mi->options, nfs_background_opttbl) == 1) - return nfsmount_bg(mi); - else - return nfsmount_fg(mi); - -text-based mount command: Function to stuff "struct pmap" from mount options - -Both the text-based mount.nfs command and the umount.nfs command need -to fill in a pmap structure based on string mount options. Introduce -a shared function that can do this. - -Signed-off-by: Chuck Lever ---- - - utils/mount/network.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++ - utils/mount/network.h | 5 + - 2 files changed, 219 insertions(+), 0 deletions(-) - -diff --git a/utils/mount/network.c b/utils/mount/network.c -index d262e94..91a005c 100644 ---- a/utils/mount/network.c -+++ b/utils/mount/network.c -@@ -48,6 +48,7 @@ - #include "nfs_mount.h" - #include "mount_constants.h" - #include "nfsrpc.h" -+#include "parse_opt.h" - #include "network.h" - - #define PMAP_TIMEOUT (10) -@@ -67,6 +68,33 @@ static const char *nfs_ns_pgmtbl[] = { - NULL, - }; - -+static const char *nfs_mnt_pgmtbl[] = { -+ "mount", -+ "mountd", -+ NULL, -+}; -+ -+static const char *nfs_nfs_pgmtbl[] = { -+ "nfs", -+ "nfsprog", -+ NULL, -+}; -+ -+static const char *nfs_transport_opttbl[] = { -+ "udp", -+ "tcp", -+ "proto", -+ NULL, -+}; -+ -+static const char *nfs_version_opttbl[] = { -+ "v2", -+ "v3", -+ "vers", -+ "nfsvers", -+ NULL, -+}; -+ - static const unsigned long nfs_to_mnt[] = { - 0, - 0, -@@ -1111,3 +1139,189 @@ out_failed: - return 0; - - } -+ -+/* -+ * "nfsprog" is only supported by the legacy mount command. The -+ * kernel mount client does not support this option. -+ * -+ * Returns the value set by the nfsprog= option, the value of -+ * the RPC NFS program specified in /etc/rpc, or a baked-in -+ * default program number, if all fails. -+ */ -+static rpcprog_t nfs_nfs_program(struct mount_options *options) -+{ -+ long tmp; -+ -+ if (po_get_numeric(options, "nfsprog", &tmp) == PO_FOUND) -+ if (tmp >= 0) -+ return tmp; -+ return nfs_getrpcbyname(NFSPROG, nfs_nfs_pgmtbl); -+} -+ -+ -+/* -+ * Returns the RPC version number specified by the given mount -+ * options for the NFS service, or zero if all fails. -+ */ -+static rpcvers_t nfs_nfs_version(struct mount_options *options) -+{ -+ long tmp; -+ -+ switch (po_rightmost(options, nfs_version_opttbl)) { -+ case 1: /* v2 */ -+ return 2; -+ case 2: /* v3 */ -+ return 3; -+ case 3: /* vers */ -+ if (po_get_numeric(options, "vers", &tmp) == PO_FOUND) -+ if (tmp >= 2 && tmp <= 3) -+ return tmp; -+ break; -+ case 4: /* nfsvers */ -+ if (po_get_numeric(options, "nfsvers", &tmp) == PO_FOUND) -+ if (tmp >= 2 && tmp <= 3) -+ return tmp; -+ break; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Returns the NFS transport protocol specified by the given mount options -+ * -+ * Returns the IPPROTO_ value specified by the given mount options, or -+ * IPPROTO_UDP if all fails. -+ */ -+static unsigned short nfs_nfs_protocol(struct mount_options *options) -+{ -+ char *option; -+ -+ switch (po_rightmost(options, nfs_transport_opttbl)) { -+ case 1: /* udp */ -+ return IPPROTO_UDP; -+ case 2: /* tcp */ -+ return IPPROTO_TCP; -+ case 3: /* proto */ -+ option = po_get(options, "proto"); -+ if (option) { -+ if (strcmp(option, "tcp") == 0) -+ return IPPROTO_TCP; -+ if (strcmp(option, "udp") == 0) -+ return IPPROTO_UDP; -+ } -+ } -+ return IPPROTO_UDP; -+} -+ -+/* -+ * Returns the NFS server's port number specified by the given -+ * mount options, or zero if all fails. Zero results in a portmap -+ * query to discover the server's mountd service port. -+ * -+ * port=0 will guarantee an rpcbind request precedes the first -+ * NFS RPC so the client can determine the server's port number. -+ */ -+static unsigned short nfs_nfs_port(struct mount_options *options) -+{ -+ long tmp; -+ -+ if (po_get_numeric(options, "port", &tmp) == PO_FOUND) -+ if (tmp >= 0 && tmp <= 65535) -+ return tmp; -+ return 0; -+} -+ -+/* -+ * "mountprog" is only supported by the legacy mount command. The -+ * kernel mount client does not support this option. -+ * -+ * Returns the value set by the mountprog= option, the value of -+ * the RPC mount program specified in /etc/rpc, or a baked-in -+ * default program number, if all fails. -+ */ -+static rpcprog_t nfs_mount_program(struct mount_options *options) -+{ -+ long tmp; -+ -+ if (po_get_numeric(options, "mountprog", &tmp) == PO_FOUND) -+ if (tmp >= 0) -+ return tmp; -+ return nfs_getrpcbyname(MOUNTPROG, nfs_mnt_pgmtbl); -+} -+ -+/* -+ * Returns the RPC version number specified by the given mount options, -+ * or the version "3" if all fails. -+ */ -+static rpcvers_t nfs_mount_version(struct mount_options *options) -+{ -+ long tmp; -+ -+ if (po_get_numeric(options, "mountvers", &tmp) == PO_FOUND) -+ if (tmp >= 1 && tmp <= 4) -+ return tmp; -+ -+ return nfsvers_to_mnt(nfs_nfs_version(options)); -+} -+ -+/* -+ * Returns the transport protocol to use for the mount service -+ * -+ * Returns the IPPROTO_ value specified by the mountproto option, or -+ * if that doesn't exist, the IPPROTO_ value specified for NFS -+ * itself. -+ */ -+static unsigned short nfs_mount_protocol(struct mount_options *options) -+{ -+ char *option; -+ -+ option = po_get(options, "mountproto"); -+ if (option) { -+ if (strcmp(option, "tcp") == 0) -+ return IPPROTO_TCP; -+ if (strcmp(option, "udp") == 0) -+ return IPPROTO_UDP; -+ } -+ -+ return nfs_nfs_version(options); -+} -+ -+/* -+ * Returns the mountd server's port number specified by the given -+ * mount options, or zero if all fails. Zero results in a portmap -+ * query to discover the server's mountd service port. -+ * -+ * port=0 will guarantee an rpcbind request precedes the mount -+ * RPC so the client can determine the server's port number. -+ */ -+static unsigned short nfs_mount_port(struct mount_options *options) -+{ -+ long tmp; -+ -+ if (po_get_numeric(options, "mountport", &tmp) == PO_FOUND) -+ if (tmp >= 0 && tmp <= 65535) -+ return tmp; -+ return 0; -+} -+ -+/** -+ * nfs_options2pmap - set up pmap structs based on mount options -+ * @options: pointer to mount options -+ * @nfs_pmap: OUT: pointer to pmap arguments for NFS server -+ * @mnt_pmap: OUT: pointer to pmap arguments for mountd server -+ * -+ */ -+void nfs_options2pmap(struct mount_options *options, -+ struct pmap *nfs_pmap, struct pmap *mnt_pmap) -+{ -+ nfs_pmap->pm_prog = nfs_nfs_program(options); -+ nfs_pmap->pm_vers = nfs_nfs_version(options); -+ nfs_pmap->pm_prot = nfs_nfs_protocol(options); -+ nfs_pmap->pm_port = nfs_nfs_port(options); -+ -+ mnt_pmap->pm_prog = nfs_mount_program(options); -+ mnt_pmap->pm_vers = nfs_mount_version(options); -+ mnt_pmap->pm_prot = nfs_mount_protocol(options); -+ mnt_pmap->pm_port = nfs_mount_port(options); -+} -diff --git a/utils/mount/network.h b/utils/mount/network.h -index 075093d..25060ab 100644 ---- a/utils/mount/network.h -+++ b/utils/mount/network.h -@@ -57,6 +57,11 @@ int clnt_ping(struct sockaddr_in *, const unsigned long, - const unsigned long, const unsigned int, - struct sockaddr_in *); - -+struct mount_options; -+ -+void nfs_options2pmap(struct mount_options *, -+ struct pmap *, struct pmap *); -+ - int start_statd(void); - - unsigned long nfsvers_to_mnt(const unsigned long); - -text-based mount options: Use new pmap stuffer when rewriting mount options - -all nfs_options2pmap() in nfs_rewrite_mount_options() instead of -open-coding the logic to convert mount options to a pmap struct. -The new nfs_options2pmap() function is more careful about avoiding -invalid mount option values, and handles multiply-specified transport -protocol options correctly. - -Signed-off-by: Chuck Lever ---- - - utils/mount/stropts.c | 68 ++++--------------------------------------------- - 1 files changed, 5 insertions(+), 63 deletions(-) - -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index bd127ab..99be0f3 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -322,19 +322,12 @@ static int nfs_is_permanent_error(int error) - * Returns a new group of mount options if successful; otherwise - * NULL is returned if some failure occurred. - */ --static const char *nfs_transport_opttbl[] = { -- "udp", -- "tcp", -- NULL, --}; -- - static struct mount_options *nfs_rewrite_mount_options(char *str) - { - struct mount_options *options; - char *option, new_option[64]; - clnt_addr_t mnt_server = { }; - clnt_addr_t nfs_server = { }; -- int p; - - options = po_split(str); - if (!options) { -@@ -360,64 +353,13 @@ static struct mount_options *nfs_rewrite_mount_options(char *str) - memcpy(&mnt_server.saddr, &nfs_server.saddr, - sizeof(mnt_server.saddr)); - -- option = po_get(options, "mountport"); -- if (option) -- mnt_server.pmap.pm_port = atoi(option); -- mnt_server.pmap.pm_prog = MOUNTPROG; -- option = po_get(options, "mountvers"); -- if (option) -- mnt_server.pmap.pm_vers = atoi(option); -- option = po_get(options, "mountproto"); -- if (option) { -- if (strcmp(option, "tcp") == 0) { -- mnt_server.pmap.pm_prot = IPPROTO_TCP; -- po_remove_all(options, "mountproto"); -- } -- if (strcmp(option, "udp") == 0) { -- mnt_server.pmap.pm_prot = IPPROTO_UDP; -- po_remove_all(options, "mountproto"); -- } -- } -+ nfs_options2pmap(options, &nfs_server.pmap, &mnt_server.pmap); - -- option = po_get(options, "port"); -- if (option) { -- nfs_server.pmap.pm_port = atoi(option); -- po_remove_all(options, "port"); -- } -+ /* The kernel NFS client doesn't support changing the RPC program -+ * number for these services, so reset these fields before probing -+ * the server's ports. */ - nfs_server.pmap.pm_prog = NFS_PROGRAM; -- -- option = po_get(options, "nfsvers"); -- if (option) { -- nfs_server.pmap.pm_vers = atoi(option); -- po_remove_all(options, "nfsvers"); -- } -- option = po_get(options, "vers"); -- if (option) { -- nfs_server.pmap.pm_vers = atoi(option); -- po_remove_all(options, "vers"); -- } -- option = po_get(options, "proto"); -- if (option) { -- if (strcmp(option, "tcp") == 0) { -- nfs_server.pmap.pm_prot = IPPROTO_TCP; -- po_remove_all(options, "proto"); -- } -- if (strcmp(option, "udp") == 0) { -- nfs_server.pmap.pm_prot = IPPROTO_UDP; -- po_remove_all(options, "proto"); -- } -- } -- p = po_rightmost(options, nfs_transport_opttbl); -- switch (p) { -- case 1: -- nfs_server.pmap.pm_prot = IPPROTO_UDP; -- break; -- case 2: -- nfs_server.pmap.pm_prot = IPPROTO_TCP; -- break; -- } -- po_remove_all(options, "tcp"); -- po_remove_all(options, "udp"); -+ mnt_server.pmap.pm_prog = MOUNTPROG; - - if (!probe_bothports(&mnt_server, &nfs_server)) { - errno = ESPIPE; - -text-based mount command: fix mount option rewriting logic - -Fix a bunch of corner cases in the text-based mount option rewriting logic. - -Signed-off-by: Chuck Lever ---- - - utils/mount/stropts.c | 113 ++++++++++++++++++++++++++++++++++--------------- - 1 files changed, 79 insertions(+), 34 deletions(-) - -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index 99be0f3..319be71 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -309,6 +309,81 @@ static int nfs_is_permanent_error(int error) - } - } - -+static int nfs_construct_new_options(struct mount_options *options, -+ struct pmap *nfs_pmap, -+ struct pmap *mnt_pmap) -+{ -+ char new_option[64]; -+ -+ po_remove_all(options, "nfsprog"); -+ po_remove_all(options, "mountprog"); -+ -+ po_remove_all(options, "v2"); -+ po_remove_all(options, "v3"); -+ po_remove_all(options, "vers"); -+ po_remove_all(options, "nfsvers"); -+ snprintf(new_option, sizeof(new_option) - 1, -+ "vers=%lu", nfs_pmap->pm_vers); -+ if (po_append(options, new_option) == PO_FAILED) -+ return 0; -+ -+ po_remove_all(options, "proto"); -+ po_remove_all(options, "udp"); -+ po_remove_all(options, "tcp"); -+ switch (nfs_pmap->pm_prot) { -+ case IPPROTO_TCP: -+ snprintf(new_option, sizeof(new_option) - 1, -+ "proto=tcp"); -+ if (po_append(options, new_option) == PO_FAILED) -+ return 0; -+ break; -+ case IPPROTO_UDP: -+ snprintf(new_option, sizeof(new_option) - 1, -+ "proto=udp"); -+ if (po_append(options, new_option) == PO_FAILED) -+ return 0; -+ break; -+ } -+ -+ po_remove_all(options, "port"); -+ if (nfs_pmap->pm_port != NFS_PORT) { -+ snprintf(new_option, sizeof(new_option) - 1, -+ "port=%lu", nfs_pmap->pm_port); -+ if (po_append(options, new_option) == PO_FAILED) -+ return 0; -+ } -+ -+ po_remove_all(options, "mountvers"); -+ snprintf(new_option, sizeof(new_option) - 1, -+ "mountvers=%lu", mnt_pmap->pm_vers); -+ if (po_append(options, new_option) == PO_FAILED) -+ return 0; -+ -+ po_remove_all(options, "mountproto"); -+ switch (mnt_pmap->pm_prot) { -+ case IPPROTO_TCP: -+ snprintf(new_option, sizeof(new_option) - 1, -+ "mountproto=tcp"); -+ if (po_append(options, new_option) == PO_FAILED) -+ return 0; -+ break; -+ case IPPROTO_UDP: -+ snprintf(new_option, sizeof(new_option) - 1, -+ "mountproto=udp"); -+ if (po_append(options, new_option) == PO_FAILED) -+ return 0; -+ break; -+ } -+ -+ po_remove_all(options, "mountport"); -+ snprintf(new_option, sizeof(new_option) - 1, -+ "mountport=%lu", mnt_pmap->pm_port); -+ if (po_append(options, new_option) == PO_FAILED) -+ return 0; -+ -+ return 1; -+} -+ - /* - * Reconstruct the mount option string based on a portmapper probe - * of the server. Returns one if the server's portmapper returned -@@ -325,7 +400,7 @@ static int nfs_is_permanent_error(int error) - static struct mount_options *nfs_rewrite_mount_options(char *str) - { - struct mount_options *options; -- char *option, new_option[64]; -+ char *option; - clnt_addr_t mnt_server = { }; - clnt_addr_t nfs_server = { }; - -@@ -366,42 +441,12 @@ static struct mount_options *nfs_rewrite_mount_options(char *str) - goto err; - } - -- snprintf(new_option, sizeof(new_option) - 1, -- "nfsvers=%lu", nfs_server.pmap.pm_vers); -- if (po_append(options, new_option) == PO_FAILED) -+ if (!nfs_construct_new_options(options, -+ &nfs_server.pmap, &mnt_server.pmap)) { -+ errno = EINVAL; - goto err; -- -- if (nfs_server.pmap.pm_prot == IPPROTO_TCP) -- snprintf(new_option, sizeof(new_option) - 1, -- "proto=tcp"); -- else -- snprintf(new_option, sizeof(new_option) - 1, -- "proto=udp"); -- if (po_append(options, new_option) == PO_FAILED) -- goto err; -- -- if (nfs_server.pmap.pm_port != NFS_PORT) { -- snprintf(new_option, sizeof(new_option) - 1, -- "port=%lu", nfs_server.pmap.pm_port); -- if (po_append(options, new_option) == PO_FAILED) -- goto err; -- - } - -- if (mnt_server.pmap.pm_prot == IPPROTO_TCP) -- snprintf(new_option, sizeof(new_option) - 1, -- "mountproto=tcp"); -- else -- snprintf(new_option, sizeof(new_option) - 1, -- "mountproto=udp"); -- if (po_append(options, new_option) == PO_FAILED) -- goto err; -- -- snprintf(new_option, sizeof(new_option) - 1, -- "mountport=%lu", mnt_server.pmap.pm_port); -- if (po_append(options, new_option) == PO_FAILED) -- goto err; -- - errno = 0; - return options; - - -text-based mount command: support AF_INET6 in rewrite_mount_options() - -Now that we have an AF_INET6-capable probe_bothports(), we can support -AF_INET6 when rewriting text-based NFS mount options. This should be -adequate to support NFS transport protocol and version negotiation with -AF_INET6 NFS servers. - -Signed-off-by: Chuck Lever ---- - - utils/mount/stropts.c | 74 ++++++++++++++++++++++++++++++++----------------- - 1 files changed, 49 insertions(+), 25 deletions(-) - -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index 319be71..6d44bb7 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -309,6 +309,37 @@ static int nfs_is_permanent_error(int error) - } - } - -+/* -+ * Get NFS/mnt server addresses from mount options -+ * -+ * Returns 1 and fills in @nfs_saddr, @nfs_salen, @mnt_saddr, and @mnt_salen -+ * if all goes well; otherwise zero. -+ */ -+static int nfs_extract_server_addresses(struct mount_options *options, -+ struct sockaddr *nfs_saddr, -+ socklen_t *nfs_salen, -+ struct sockaddr *mnt_saddr, -+ socklen_t *mnt_salen) -+{ -+ char *option; -+ -+ option = po_get(options, "addr"); -+ if (option == NULL) -+ return 0; -+ if (!nfs_string_to_sockaddr(option, strlen(option), -+ nfs_saddr, nfs_salen)) -+ return 0; -+ -+ option = po_get(options, "mountaddr"); -+ if (option == NULL) -+ memcpy(mnt_saddr, nfs_saddr, *nfs_salen); -+ else if (!nfs_string_to_sockaddr(option, strlen(option), -+ mnt_saddr, mnt_salen)) -+ return 0; -+ -+ return 1; -+} -+ - static int nfs_construct_new_options(struct mount_options *options, - struct pmap *nfs_pmap, - struct pmap *mnt_pmap) -@@ -400,9 +431,14 @@ static int nfs_construct_new_options(struct mount_options *options, - static struct mount_options *nfs_rewrite_mount_options(char *str) - { - struct mount_options *options; -- char *option; -- clnt_addr_t mnt_server = { }; -- clnt_addr_t nfs_server = { }; -+ struct sockaddr_storage nfs_address; -+ struct sockaddr *nfs_saddr = (struct sockaddr *)&nfs_address; -+ socklen_t nfs_salen; -+ struct pmap nfs_pmap; -+ struct sockaddr_storage mnt_address; -+ struct sockaddr *mnt_saddr = (struct sockaddr *)&mnt_address; -+ socklen_t mnt_salen; -+ struct pmap mnt_pmap; - - options = po_split(str); - if (!options) { -@@ -410,39 +446,27 @@ static struct mount_options *nfs_rewrite_mount_options(char *str) - return NULL; - } - -- errno = EINVAL; -- option = po_get(options, "addr"); -- if (option) { -- nfs_server.saddr.sin_family = AF_INET; -- if (!inet_aton((const char *)option, &nfs_server.saddr.sin_addr)) -- goto err; -- } else -+ if (!nfs_extract_server_addresses(options, nfs_saddr, &nfs_salen, -+ mnt_saddr, &mnt_salen)) { -+ errno = EINVAL; - goto err; -+ } - -- option = po_get(options, "mountaddr"); -- if (option) { -- mnt_server.saddr.sin_family = AF_INET; -- if (!inet_aton((const char *)option, &mnt_server.saddr.sin_addr)) -- goto err; -- } else -- memcpy(&mnt_server.saddr, &nfs_server.saddr, -- sizeof(mnt_server.saddr)); -- -- nfs_options2pmap(options, &nfs_server.pmap, &mnt_server.pmap); -+ nfs_options2pmap(options, &nfs_pmap, &mnt_pmap); - - /* The kernel NFS client doesn't support changing the RPC program - * number for these services, so reset these fields before probing - * the server's ports. */ -- nfs_server.pmap.pm_prog = NFS_PROGRAM; -- mnt_server.pmap.pm_prog = MOUNTPROG; -+ nfs_pmap.pm_prog = NFS_PROGRAM; -+ mnt_pmap.pm_prog = MOUNTPROG; - -- if (!probe_bothports(&mnt_server, &nfs_server)) { -+ if (!nfs_probe_bothports(mnt_saddr, mnt_salen, &mnt_pmap, -+ nfs_saddr, nfs_salen, &nfs_pmap)) { - errno = ESPIPE; - goto err; - } - -- if (!nfs_construct_new_options(options, -- &nfs_server.pmap, &mnt_server.pmap)) { -+ if (!nfs_construct_new_options(options, &nfs_pmap, &mnt_pmap)) { - errno = EINVAL; - goto err; - } - diff --git a/nfs-utils-1.1.4-mount-udponly.patch b/nfs-utils-1.1.4-mount-udponly.patch deleted file mode 100644 index cd2115e..0000000 --- a/nfs-utils-1.1.4-mount-udponly.patch +++ /dev/null @@ -1,27 +0,0 @@ -commit 52ec1b5fceece8f63b97afc6d6b78bfabff12669 -Author: Steve Dickson -Date: Tue Feb 17 15:33:58 2009 -0500 - - The mount sockaddr len (mnt_salen) is not be set in - nfs_extract_server_addresses() which causes the mount.nfs - command to segmentation fault when a NFS server only - supports UDP mounts. - - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/utils/mount/stropts.c.orig nfs-utils-1.1.4/utils/mount/stropts.c ---- nfs-utils-1.1.4/utils/mount/stropts.c.orig 2009-02-17 15:55:53.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/stropts.c 2009-02-17 15:58:15.000000000 -0500 -@@ -331,9 +331,10 @@ static int nfs_extract_server_addresses( - return 0; - - option = po_get(options, "mountaddr"); -- if (option == NULL) -+ if (option == NULL) { - memcpy(mnt_saddr, nfs_saddr, *nfs_salen); -- else if (!nfs_string_to_sockaddr(option, strlen(option), -+ *mnt_salen = *nfs_salen; -+ } else if (!nfs_string_to_sockaddr(option, strlen(option), - mnt_saddr, mnt_salen)) - return 0; - diff --git a/nfs-utils-1.1.4-showmount-rpcbind.patch b/nfs-utils-1.1.4-showmount-rpcbind.patch deleted file mode 100644 index 2a6c455..0000000 --- a/nfs-utils-1.1.4-showmount-rpcbind.patch +++ /dev/null @@ -1,349 +0,0 @@ -commit bb3e50bd5c4f6bf94221ef69d4dc87e73d0e474b -Author: Chuck Lever -Date: Tue Nov 25 08:15:51 2008 -0500 - - showmount command: call nfs_getport instead of local getport - - Have the showmount command invoke the shared nfs_getport() function - instead of its own local version. This gives the showmount command - immediate support for querying via rpcbindv3/v4 in addition to - portmapper, and sets the stage for AF_INET6 support in showmount. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit e358039c9ffa8a4ead342e8a0cf0ff51a3a21af4 -Author: Chuck Lever -Date: Tue Nov 25 08:35:10 2008 -0500 - - showmount command: Remove unused local getport() implementation - - Clean up: remove showmount.c's local getport() implementation, now that - the showmount command uses the shared one. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit 1c96846ba3adeb59a61e0cf33cf4c94c0678853f -Author: Chuck Lever -Date: Tue Nov 25 08:38:01 2008 -0500 - - showmount command: move logic to acquire RPC client handle out of main() - - In preparation to support IPv6 in the showmount command, extract the - logic that parses/acquires the target hostname and converts it into an RPC - client handle to contact the remote mountd service, and move it into its - own function. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit f7020bd5d3ffca280690c6beba5fecdeb4d305f7 -Author: Chuck Lever -Date: Tue Nov 25 08:39:47 2008 -0500 - - showmount command: support querying IPv6 servers - - Introduce a version of nfs_get_mount_client() that supports AF_INET6 and - AF_INET server addresses. If the TI-RPC library is not available when - the showmount command is built, fall back to the legacy RPC user-space - API. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/utils/showmount/showmount.c.save nfs-utils-1.1.4/utils/showmount/showmount.c ---- nfs-utils-1.1.4/utils/showmount/showmount.c.save 2008-11-25 11:16:03.000000000 -0500 -+++ nfs-utils-1.1.4/utils/showmount/showmount.c 2008-11-25 11:16:28.000000000 -0500 -@@ -37,8 +37,9 @@ - #include - #include - -+#include "nfsrpc.h" -+ - #define TIMEOUT_UDP 3 --#define TIMEOUT_TCP 10 - #define TOTAL_TIMEOUT 20 - - static char * version = "showmount for " VERSION; -@@ -49,6 +50,13 @@ static int aflag = 0; - static int dflag = 0; - static int eflag = 0; - -+static const char *nfs_sm_pgmtbl[] = { -+ "showmount", -+ "mount", -+ "mountd", -+ NULL, -+}; -+ - static struct option longopts[] = - { - { "all", 0, 0, 'a' }, -@@ -77,6 +85,33 @@ static void usage(FILE *fp, int n) - exit(n); - } - -+#ifdef HAVE_CLNT_CREATE -+ -+/* -+ * Generate an RPC client handle connected to the mountd service -+ * at @hostname, or die trying. -+ * -+ * Supports both AF_INET and AF_INET6 server addresses. -+ */ -+static CLIENT *nfs_get_mount_client(const char *hostname) -+{ -+ rpcprog_t program = nfs_getrpcbyname(MOUNTPROG, nfs_sm_pgmtbl); -+ CLIENT *client; -+ -+ client = clnt_create(hostname, program, MOUNTVERS, "tcp"); -+ if (client) -+ return client; -+ -+ client = clnt_create(hostname, program, MOUNTVERS, "udp"); -+ if (client) -+ return client; -+ -+ clnt_pcreateerror("clnt_create"); -+ exit(1); -+} -+ -+#else /* HAVE_CLNT_CREATE */ -+ - /* - * Perform a non-blocking connect on the socket fd. - * -@@ -149,120 +184,77 @@ done: - return ret; - } - --static unsigned short getport(struct sockaddr_in *addr, -- unsigned long prog, unsigned long vers, int prot) -+/* -+ * Generate an RPC client handle connected to the mountd service -+ * at @hostname, or die trying. -+ * -+ * Supports only AF_INET server addresses. -+ */ -+static CLIENT *nfs_get_mount_client(const char *hostname) - { -- CLIENT *client; -- enum clnt_stat status; -- struct pmap parms; -- int ret, sock; -- struct sockaddr_in laddr, saddr; -- struct timeval tout = {0, 0}; -- socklen_t len; -- unsigned int send_sz = 0; -- unsigned int recv_sz = 0; -- unsigned short port; -- -- memset(&laddr, 0, sizeof(laddr)); -- memset(&saddr, 0, sizeof(saddr)); -- memset(&parms, 0, sizeof(parms)); -- -- memcpy(&saddr, addr, sizeof(saddr)); -- saddr.sin_port = htons(PMAPPORT); -+ struct hostent *hp; -+ struct sockaddr_in server_addr; -+ struct timeval pertry_timeout; -+ CLIENT *mclient = NULL; -+ int ret, msock; - -- if (prot == IPPROTO_TCP) { -- sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); -- if (sock == -1) { -- rpc_createerr.cf_stat = RPC_SYSTEMERROR; -- rpc_createerr.cf_error.re_errno = errno; -- return 0; -+ if (inet_aton(hostname, &server_addr.sin_addr)) { -+ server_addr.sin_family = AF_INET; -+ } -+ else { -+ if ((hp = gethostbyname(hostname)) == NULL) { -+ fprintf(stderr, "%s: can't get address for %s\n", -+ program_name, hostname); -+ exit(1); - } -+ server_addr.sin_family = AF_INET; -+ memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length); -+ } - -- tout.tv_sec = TIMEOUT_TCP; -- -- ret = connect_nb(sock, &saddr, &tout); -- if (ret != 0) { -- rpc_createerr.cf_stat = RPC_SYSTEMERROR; -- rpc_createerr.cf_error.re_errno = errno; -- close(sock); -- return 0; -- } -- client = clnttcp_create(&saddr, -- PMAPPROG, PMAPVERS, &sock, -- 0, 0); -- } else { -- /* -- * bind to any unused port. If we left this up to the rpc -- * layer, it would bind to a reserved port, which has been shown -- * to exhaust the reserved port range in some situations. -- */ -- sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); -- if (sock == -1) { -- rpc_createerr.cf_stat = RPC_SYSTEMERROR; -- rpc_createerr.cf_error.re_errno = errno; -- return 0; -- } -- -- laddr.sin_family = AF_INET; -- laddr.sin_port = 0; -- laddr.sin_addr.s_addr = htonl(INADDR_ANY); -- -- tout.tv_sec = TIMEOUT_UDP; -- -- send_sz = RPCSMALLMSGSIZE; -- recv_sz = RPCSMALLMSGSIZE; -- -- len = sizeof(struct sockaddr_in); -- if (bind(sock, (struct sockaddr *)&laddr, len) < 0) { -- close(sock); -- sock = RPC_ANYSOCK; -- /* FALLTHROUGH */ -- } -- client = clntudp_bufcreate(&saddr, PMAPPROG, PMAPVERS, -- tout, &sock, send_sz, recv_sz); -- } -- -- if (!client) { -- close(sock); -- rpc_createerr.cf_stat = RPC_RPCBFAILURE; -- return 0; -- } -- -- clnt_control(client, CLSET_FD_CLOSE, NULL); -- -- parms.pm_prog = prog; -- parms.pm_vers = vers; -- parms.pm_prot = prot; -- -- status = clnt_call(client, PMAPPROC_GETPORT, -- (xdrproc_t) xdr_pmap, (caddr_t) &parms, -- (xdrproc_t) xdr_u_short, (caddr_t) &port, -- tout); -- -- if (status != RPC_SUCCESS) { -- clnt_geterr(client, &rpc_createerr.cf_error); -- rpc_createerr.cf_stat = status; -- clnt_destroy(client); -- return 0; -- } else if (port == 0) { -- rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; -+ msock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); -+ if (msock != -1) { -+ if (nfs_getport_ping((struct sockaddr *)&server_addr, -+ sizeof(server_addr), MOUNTPROG, -+ MOUNTVERS, IPPROTO_TCP)) { -+ ret = connect_nb(msock, &server_addr, 0); -+ if (ret == 0) -+ mclient = clnttcp_create(&server_addr, -+ MOUNTPROG, MOUNTVERS, &msock, -+ 0, 0); -+ else -+ close(msock); -+ } else -+ close(msock); - } - -- clnt_destroy(client); -+ if (!mclient) { -+ if (nfs_getport_ping((struct sockaddr *)&server_addr, -+ sizeof(server_addr), MOUNTPROG, -+ MOUNTVERS, IPPROTO_UDP)) { -+ clnt_pcreateerror("showmount"); -+ exit(1); -+ } -+ msock = RPC_ANYSOCK; -+ pertry_timeout.tv_sec = TIMEOUT_UDP; -+ pertry_timeout.tv_usec = 0; -+ if ((mclient = clntudp_create(&server_addr, -+ MOUNTPROG, MOUNTVERS, pertry_timeout, &msock)) == NULL) { -+ clnt_pcreateerror("mount clntudp_create"); -+ exit(1); -+ } -+ } - -- return htons(port); -+ return mclient; - } - -+#endif /* HAVE_CLNT_CREATE */ -+ - int main(int argc, char **argv) - { - char hostname_buf[MAXHOSTLEN]; - char *hostname; - enum clnt_stat clnt_stat; -- struct hostent *hp; -- struct sockaddr_in server_addr; -- int ret, msock; - struct timeval total_timeout; -- struct timeval pertry_timeout; - int c; - CLIENT *mclient; - groups grouplist; -@@ -334,54 +326,7 @@ int main(int argc, char **argv) - break; - } - -- if (inet_aton(hostname, &server_addr.sin_addr)) { -- server_addr.sin_family = AF_INET; -- } -- else { -- if ((hp = gethostbyname(hostname)) == NULL) { -- fprintf(stderr, "%s: can't get address for %s\n", -- program_name, hostname); -- exit(1); -- } -- server_addr.sin_family = AF_INET; -- memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length); -- } -- -- /* create mount deamon client */ -- -- mclient = NULL; -- msock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); -- if (msock != -1) { -- server_addr.sin_port = getport(&server_addr, -- MOUNTPROG, MOUNTVERS, IPPROTO_TCP); -- if (server_addr.sin_port) { -- ret = connect_nb(msock, &server_addr, 0); -- if (ret == 0) /* success */ -- mclient = clnttcp_create(&server_addr, -- MOUNTPROG, MOUNTVERS, &msock, -- 0, 0); -- else -- close(msock); -- } else -- close(msock); -- } -- -- if (!mclient) { -- server_addr.sin_port = getport(&server_addr, -- MOUNTPROG, MOUNTVERS, IPPROTO_UDP); -- if (!server_addr.sin_port) { -- clnt_pcreateerror("showmount"); -- exit(1); -- } -- msock = RPC_ANYSOCK; -- pertry_timeout.tv_sec = TIMEOUT_UDP; -- pertry_timeout.tv_usec = 0; -- if ((mclient = clntudp_create(&server_addr, -- MOUNTPROG, MOUNTVERS, pertry_timeout, &msock)) == NULL) { -- clnt_pcreateerror("mount clntudp_create"); -- exit(1); -- } -- } -+ mclient = nfs_get_mount_client(hostname); - mclient->cl_auth = authunix_create_default(); - total_timeout.tv_sec = TOTAL_TIMEOUT; - total_timeout.tv_usec = 0; diff --git a/nfs-utils-1.1.4-sm-notify-freeaddrinfo.patch b/nfs-utils-1.1.4-sm-notify-freeaddrinfo.patch deleted file mode 100644 index acd2d0e..0000000 --- a/nfs-utils-1.1.4-sm-notify-freeaddrinfo.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff -up nfs-utils-1.1.4/utils/statd/sm-notify.c.orig nfs-utils-1.1.4/utils/statd/sm-notify.c ---- nfs-utils-1.1.4/utils/statd/sm-notify.c.orig 2008-12-17 15:09:13.000000000 -0500 -+++ nfs-utils-1.1.4/utils/statd/sm-notify.c 2008-12-17 15:11:07.000000000 -0500 -@@ -133,6 +133,17 @@ static struct addrinfo *smn_lookup(const - return ai; - } - -+static void smn_forget_host(struct nsm_host *host) -+{ -+ unlink(host->path); -+ free(host->path); -+ free(host->name); -+ if (host->ai) -+ freeaddrinfo(host->ai); -+ -+ free(host); -+} -+ - int - main(int argc, char **argv) - { -@@ -342,13 +353,8 @@ notify(void) - hp = hosts; - hosts = hp->next; - -- if (notify_host(sock, hp)){ -- unlink(hp->path); -- free(hp->name); -- free(hp->path); -- free(hp); -+ if (notify_host(sock, hp)) - continue; -- } - - /* Set the timeout for this call, using an - exponential timeout strategy */ -@@ -403,6 +409,7 @@ notify_host(int sock, struct nsm_host *h - nsm_log(LOG_WARNING, - "%s doesn't seem to be a valid address," - " skipped", host->name); -+ smn_forget_host(host); - return 1; - } - } -@@ -547,11 +554,7 @@ recv_reply(int sock) - if (p <= end) { - nsm_log(LOG_DEBUG, "Host %s notified successfully", - hp->name); -- unlink(hp->path); -- free(hp->name); -- free(hp->path); -- free(hp); -- freeaddrinfo(hp->ai); -+ smn_forget_host(hp); - return; - } - } diff --git a/nfs-utils-1.1.4-sm-notify-typo.patch b/nfs-utils-1.1.4-sm-notify-typo.patch deleted file mode 100644 index 213faae..0000000 --- a/nfs-utils-1.1.4-sm-notify-typo.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit 5d8b800b8438222a55c4698c86b558b15717aa21 -Author: Steve Dickson -Date: Sat Dec 6 08:31:29 2008 -0500 - - sm-notify: always exiting without any notification - - Added curly brackets around the record_pid() check which - stop sm-notify from exiting when a pid file does not - exist. - - Signed-off-by: Steve Dickson - -diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c -index 7a7ae1a..d8e2c01 100644 ---- a/utils/statd/sm-notify.c -+++ b/utils/statd/sm-notify.c -@@ -193,10 +193,11 @@ usage: fprintf(stderr, - openlog("sm-notify", LOG_PID, LOG_DAEMON); - - if (strcmp(_SM_BASE_PATH, BASEDIR) == 0) { -- if (record_pid() == 0 && force == 0 && opt_update_state == 1) -+ if (record_pid() == 0 && force == 0 && opt_update_state == 1) { - /* already run, don't try again */ - nsm_log(LOG_NOTICE, "Already notifying clients; Exiting!"); - exit(0); -+ } - } - - if (opt_srcaddr) { diff --git a/nfs-utils-1.1.4-statd-setuid.patch b/nfs-utils-1.1.4-statd-setuid.patch deleted file mode 100644 index 80689f1..0000000 --- a/nfs-utils-1.1.4-statd-setuid.patch +++ /dev/null @@ -1,72 +0,0 @@ -commit 33bbeabb40d11a59266e0702adaa6a2e0acb6382 -Author: Neil Brown -Date: Wed Nov 26 12:01:06 2008 -0500 - - Ensure statd gets started if required when non-root - user mounts an NFS filesystem. - - The first time an NFS filesystem is mounted, we start statd from - /sbin/mount.nfs. If this first time is a non-root user doing the - mount, (thanks to e.g. the 'users' option in /etc/fstab) - then we need to be sure that the 'setuid' status from mount.nfs - is inherited through to rpc.statd so that it runs as root. - - There are two places where we loose our setuid status due to the shell - (/bin/sh) discarding. - - 1/ mount.nfs uses "system" to run /usr/sbin/start-statd. This runs a - shell which is likely to drop privileges. So change that code to use - 'fork' and 'execl' explicitly. - 2/ start-statd is a shell script. To convince the shell to allow the - program to run in privileged mode, we need to add a "-p" flag. - - We could just call setuid(getuid()) at some appropriate time, and it - might be worth doing that as well, however I think that getting - rid of 'system()' is a good idea and once that is done, the - adding of '-p' is trivial and sufficient. - - Signed-off-by: Neil Brown - Signed-off-by: Steve Dickson - -diff --git a/utils/mount/network.c b/utils/mount/network.c -index 2db694d..806344c 100644 ---- a/utils/mount/network.c -+++ b/utils/mount/network.c -@@ -36,6 +36,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -705,7 +706,18 @@ int start_statd(void) - #ifdef START_STATD - if (stat(START_STATD, &stb) == 0) { - if (S_ISREG(stb.st_mode) && (stb.st_mode & S_IXUSR)) { -- system(START_STATD); -+ pid_t pid = fork(); -+ switch (pid) { -+ case 0: /* child */ -+ execl(START_STATD, START_STATD, NULL); -+ exit(1); -+ case -1: /* error */ -+ perror("Fork failed"); -+ break; -+ default: /* parent */ -+ waitpid(pid, NULL,0); -+ break; -+ } - if (probe_statd()) - return 1; - } -diff --git a/utils/statd/start-statd b/utils/statd/start-statd -index 6e7ea04..c7805ee 100644 ---- a/utils/statd/start-statd -+++ b/utils/statd/start-statd -@@ -1,4 +1,4 @@ --#!/bin/sh -+#!/bin/sh -p - # nfsmount calls this script when mounting a filesystem with locking - # enabled, but when statd does not seem to be running (based on - # /var/run/rpc.statd.pid). diff --git a/nfs-utils-1.1.4-statd-xunlink.patch b/nfs-utils-1.1.4-statd-xunlink.patch deleted file mode 100644 index 26d19c2..0000000 --- a/nfs-utils-1.1.4-statd-xunlink.patch +++ /dev/null @@ -1,98 +0,0 @@ -commit bc870150cc2116584aee288d15ac2b9a2f825ff5 -Author: Steve Dickson -Date: Wed Dec 17 16:41:35 2008 -0500 - - statd: not unlinking host files - - Statd is not unlinking host files during SM_UNMON and - SM_UNMON_ALL calls because the given host is still on the run-time - notify list (rtnl) and the check flag is set when xunlink() is - called. But the next thing the caller of xunlink() does is - remove the host from the rtnl list which means the - unlink will never happen. - - So this patch removes the check flag from xunlink() since - its not needed and correctly allocates and frees memory - used by xunlink(). - - Signed-off-by: Steve Dickson - -diff --git a/utils/statd/misc.c b/utils/statd/misc.c -index fd201b4..7256291 100644 ---- a/utils/statd/misc.c -+++ b/utils/statd/misc.c -@@ -53,23 +53,25 @@ xstrdup (const char *string) - - - /* -- * Call with check=1 to verify that this host is not still on the rtnl -- * before unlinking file. -+ * Unlinking a file. - */ - void --xunlink (char *path, char *host, short int check) -+xunlink (char *path, char *host) - { -- char *tozap; -+ char *tozap; - -- tozap=alloca (strlen(path)+strlen(host)+2); -- sprintf (tozap, "%s/%s", path, host); -+ tozap = malloc(strlen(path)+strlen(host)+2); -+ if (tozap == NULL) { -+ note(N_ERROR, "xunlink: malloc failed: errno %d (%s)", -+ errno, strerror(errno)); -+ return; -+ } -+ sprintf (tozap, "%s/%s", path, host); - -- if (!check || !nlist_gethost(rtnl, host, 0)) { -- if (unlink (tozap) == -1) -- note (N_ERROR, "unlink (%s): %s", tozap, strerror (errno)); -- else -- dprintf (N_DEBUG, "Unlinked %s", tozap); -- } -- else -- dprintf (N_DEBUG, "Not unlinking %s--host still monitored.", tozap); -+ if (unlink (tozap) == -1) -+ note(N_ERROR, "unlink (%s): %s", tozap, strerror (errno)); -+ else -+ dprintf (N_DEBUG, "Unlinked %s", tozap); -+ -+ free(tozap); - } -diff --git a/utils/statd/monitor.c b/utils/statd/monitor.c -index a6a1d9c..24c2531 100644 ---- a/utils/statd/monitor.c -+++ b/utils/statd/monitor.c -@@ -352,7 +352,7 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp) - /* PRC: do the HA callout: */ - ha_callout("del-client", mon_name, my_name, -1); - -- xunlink(SM_DIR, clnt->dns_name, 1); -+ xunlink(SM_DIR, clnt->dns_name); - nlist_free(&rtnl, clnt); - - return (&result); -@@ -404,7 +404,7 @@ sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp) - temp = NL_NEXT(clnt); - /* PRC: do the HA callout: */ - ha_callout("del-client", mon_name, my_name, -1); -- xunlink(SM_DIR, clnt->dns_name, 1); -+ xunlink(SM_DIR, clnt->dns_name); - nlist_free(&rtnl, clnt); - ++count; - clnt = temp; -diff --git a/utils/statd/statd.h b/utils/statd/statd.h -index 5a6e289..88ba208 100644 ---- a/utils/statd/statd.h -+++ b/utils/statd/statd.h -@@ -53,7 +53,7 @@ extern int process_notify_list(void); - extern int process_reply(FD_SET_TYPE *); - extern char * xstrdup(const char *); - extern void * xmalloc(size_t); --extern void xunlink (char *, char *, short int); -+extern void xunlink (char *, char *); - extern void load_state(void); - - /* diff --git a/nfs-utils-1.1.4-svcgssd-expiration.patch b/nfs-utils-1.1.4-svcgssd-expiration.patch deleted file mode 100644 index ac704c5..0000000 --- a/nfs-utils-1.1.4-svcgssd-expiration.patch +++ /dev/null @@ -1,304 +0,0 @@ -commit a4f1386224310b6797f083826fc4b6751e91f9b6 -Author: Kevin Coffman -Date: Thu Dec 11 11:39:38 2008 -0500 - - gssd/svcgssd: add support to retrieve actual context expiration - - Add some plumbing so that the context expiration can be returned while - serializing the information. Later patch(es) will actually get the - expiration and pass it down to the kernel. - - Signed-off-by: Kevin Coffman - Signed-off-by: Steve Dickson - -diff --git a/utils/gssd/context.c b/utils/gssd/context.c -index 4bab3e7..0ca7079 100644 ---- a/utils/gssd/context.c -+++ b/utils/gssd/context.c -@@ -43,13 +43,14 @@ - int - serialize_context_for_kernel(gss_ctx_id_t ctx, - gss_buffer_desc *buf, -- gss_OID mech) -+ gss_OID mech, -+ int32_t *endtime) - { - if (g_OID_equal(&krb5oid, mech)) -- return serialize_krb5_ctx(ctx, buf); -+ return serialize_krb5_ctx(ctx, buf, endtime); - #ifdef HAVE_SPKM3_H - else if (g_OID_equal(&spkm3oid, mech)) -- return serialize_spkm3_ctx(ctx, buf); -+ return serialize_spkm3_ctx(ctx, buf, endtime); - #endif - else { - printerr(0, "ERROR: attempting to serialize context with " -diff --git a/utils/gssd/context.h b/utils/gssd/context.h -index 67ed3bb..be47f9c 100644 ---- a/utils/gssd/context.h -+++ b/utils/gssd/context.h -@@ -38,8 +38,10 @@ - - - int serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf, -- gss_OID mech); --int serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf); --int serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf); -+ gss_OID mech, int32_t *endtime); -+int serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, -+ int32_t *endtime); -+int serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, -+ int32_t *endtime); - - #endif /* _CONTEXT_H_ */ -diff --git a/utils/gssd/context_heimdal.c b/utils/gssd/context_heimdal.c -index 6fb8fbd..fc241e3 100644 ---- a/utils/gssd/context_heimdal.c -+++ b/utils/gssd/context_heimdal.c -@@ -198,7 +198,7 @@ int write_heimdal_seq_key(char **p, char *end, gss_ctx_id_t ctx) - */ - - int --serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) -+serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, int32_t *endtime) - { - - char *p, *end; -@@ -239,6 +239,9 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) - /* endtime */ - if (WRITE_BYTES(&p, end, ctx->lifetime)) goto out_err; - -+ if (endtime) -+ *endtime = ctx->lifetime; -+ - /* seq_send */ - if (WRITE_BYTES(&p, end, ctx->auth_context->local_seqnumber)) - goto out_err; -diff --git a/utils/gssd/context_lucid.c b/utils/gssd/context_lucid.c -index 3550762..94403af 100644 ---- a/utils/gssd/context_lucid.c -+++ b/utils/gssd/context_lucid.c -@@ -66,7 +66,7 @@ write_lucid_keyblock(char **p, char *end, gss_krb5_lucid_key_t *key) - - static int - prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx, -- gss_buffer_desc *buf) -+ gss_buffer_desc *buf, int32_t *endtime) - { - char *p, *end; - static int constant_zero = 0; -@@ -101,6 +101,8 @@ prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx, - if (WRITE_BYTES(&p, end, lctx->rfc1964_kd.sign_alg)) goto out_err; - if (WRITE_BYTES(&p, end, lctx->rfc1964_kd.seal_alg)) goto out_err; - if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err; -+ if (endtime) -+ *endtime = lctx->endtime; - word_send_seq = lctx->send_seq; /* XXX send_seq is 64-bit */ - if (WRITE_BYTES(&p, end, word_send_seq)) goto out_err; - if (write_oid(&p, end, &krb5oid)) goto out_err; -@@ -154,7 +156,7 @@ out_err: - - static int - prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx, -- gss_buffer_desc *buf) -+ gss_buffer_desc *buf, int32_t *endtime) - { - printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n"); - return -1; -@@ -162,7 +164,7 @@ prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx, - - - int --serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) -+serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, int32_t *endtime) - { - OM_uint32 maj_stat, min_stat; - void *return_ctx = 0; -@@ -194,9 +196,9 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) - - /* Now lctx points to a lucid context that we can send down to kernel */ - if (lctx->protocol == 0) -- retcode = prepare_krb5_rfc1964_buffer(lctx, buf); -+ retcode = prepare_krb5_rfc1964_buffer(lctx, buf, endtime); - else -- retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf); -+ retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf, endtime); - - maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx); - if (maj_stat != GSS_S_COMPLETE) { -diff --git a/utils/gssd/context_mit.c b/utils/gssd/context_mit.c -index 94b2266..e76a8b1 100644 ---- a/utils/gssd/context_mit.c -+++ b/utils/gssd/context_mit.c -@@ -150,7 +150,7 @@ typedef struct gss_union_ctx_id_t { - } gss_union_ctx_id_desc, *gss_union_ctx_id_t; - - int --serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) -+serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, int32_t *endtime) - { - krb5_gss_ctx_id_t kctx = ((gss_union_ctx_id_t)ctx)->internal_ctx_id; - char *p, *end; -@@ -180,6 +180,8 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) - if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err; - if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err; - if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err; -+ if (endtime) -+ *endtime = kctx->endtime; - word_seq_send = kctx->seq_send; - if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err; - if (write_oid(&p, end, kctx->mech_used)) goto out_err; -diff --git a/utils/gssd/context_spkm3.c b/utils/gssd/context_spkm3.c -index 4f41ee3..5b387bd 100644 ---- a/utils/gssd/context_spkm3.c -+++ b/utils/gssd/context_spkm3.c -@@ -139,7 +139,7 @@ out_err: - * and only export those fields to the kernel. - */ - int --serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) -+serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, int32_t *endtime) - { - OM_uint32 vers, ret, maj_stat, min_stat; - void *ret_ctx = 0; -@@ -162,6 +162,9 @@ serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) - } - ret = prepare_spkm3_ctx_buffer(lctx, buf); - -+ if (endtime) -+ *endtime = lctx->endtime; -+ - maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, ret_ctx); - - if (maj_stat != GSS_S_COMPLETE) -diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c -index f415a10..cb14d45 100644 ---- a/utils/gssd/gssd_proc.c -+++ b/utils/gssd/gssd_proc.c -@@ -762,7 +762,7 @@ handle_krb5_upcall(struct clnt_info *clp) - goto out_return_error; - } - -- if (serialize_context_for_kernel(pd.pd_ctx, &token, &krb5oid)) { -+ if (serialize_context_for_kernel(pd.pd_ctx, &token, &krb5oid, NULL)) { - printerr(0, "WARNING: Failed to serialize krb5 context for " - "user with uid %d for server %s\n", - uid, clp->servername); -@@ -824,7 +824,7 @@ handle_spkm3_upcall(struct clnt_info *clp) - goto out_return_error; - } - -- if (serialize_context_for_kernel(pd.pd_ctx, &token, &spkm3oid)) { -+ if (serialize_context_for_kernel(pd.pd_ctx, &token, &spkm3oid, NULL)) { - printerr(0, "WARNING: Failed to serialize spkm3 context for " - "user with uid %d for server\n", - uid, clp->servername); -diff --git a/utils/gssd/svcgssd_proc.c b/utils/gssd/svcgssd_proc.c -index 794c2f4..d021d49 100644 ---- a/utils/gssd/svcgssd_proc.c -+++ b/utils/gssd/svcgssd_proc.c -@@ -396,7 +396,7 @@ handle_nullreq(FILE *f) { - - /* kernel needs ctx to calculate verifier on null response, so - * must give it context before doing null call: */ -- if (serialize_context_for_kernel(ctx, &ctx_token, mech)) { -+ if (serialize_context_for_kernel(ctx, &ctx_token, mech, NULL)) { - printerr(0, "WARNING: handle_nullreq: " - "serialize_context_for_kernel failed\n"); - maj_stat = GSS_S_FAILURE; -commit eb3a145789b9eedd39b56e1d76f412435abaa747 -Author: Kevin Coffman -Date: Thu Dec 11 11:43:31 2008 -0500 - - svcgssd: use the actual context expiration for cache - - Instead of sending down an infinite expiration value for the rsi(init) and - rsc(context) cache entries, use a reasonable value for the rsi cache, and - the actual context expiration value for the rsc cache. - - Prompted by a proposal from Neil Brown as a result of a complaint of a - server running out of kernel memory when under heavy load of rpcsec_gss - traffic. Neil's original patch used one minute for the init cache and one - hour for the context cache. Using the actual expiration time prevents - unnecessary context re-negotiation. - - Signed-off-by: Kevin Coffman - Signed-off-by: Steve Dickson - -diff --git a/utils/gssd/svcgssd_proc.c b/utils/gssd/svcgssd_proc.c -index d021d49..f162152 100644 ---- a/utils/gssd/svcgssd_proc.c -+++ b/utils/gssd/svcgssd_proc.c -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - - #include "svcgssd.h" - #include "gss_util.h" -@@ -67,7 +68,8 @@ struct svc_cred { - - static int - do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred, -- gss_OID mech, gss_buffer_desc *context_token) -+ gss_OID mech, gss_buffer_desc *context_token, -+ int32_t endtime) - { - FILE *f; - int i; -@@ -86,13 +88,15 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred, - } - qword_printhex(f, out_handle->value, out_handle->length); - /* XXX are types OK for the rest of this? */ -- qword_printint(f, 0x7fffffff); /*XXX need a better timeout */ -+ /* For context cache, use the actual context endtime */ -+ qword_printint(f, endtime); - qword_printint(f, cred->cr_uid); - qword_printint(f, cred->cr_gid); - qword_printint(f, cred->cr_ngroups); -- printerr(2, "mech: %s, hndl len: %d, ctx len %d, timeout: %d, " -+ printerr(2, "mech: %s, hndl len: %d, ctx len %d, timeout: %d (%d from now), " - "uid: %d, gid: %d, num aux grps: %d:\n", -- fname, out_handle->length, context_token->length, 0x7fffffff, -+ fname, out_handle->length, context_token->length, -+ endtime, endtime - time(0), - cred->cr_uid, cred->cr_gid, cred->cr_ngroups); - for (i=0; i < cred->cr_ngroups; i++) { - qword_printint(f, cred->cr_groups[i]); -@@ -130,7 +134,8 @@ send_response(FILE *f, gss_buffer_desc *in_handle, gss_buffer_desc *in_token, - - qword_addhex(&bp, &blen, in_handle->value, in_handle->length); - qword_addhex(&bp, &blen, in_token->value, in_token->length); -- qword_addint(&bp, &blen, 0x7fffffff); /*XXX need a better timeout */ -+ /* For init cache, only needed for a short time */ -+ qword_addint(&bp, &blen, time(0) + 60); - qword_adduint(&bp, &blen, maj_stat); - qword_adduint(&bp, &blen, min_stat); - qword_addhex(&bp, &blen, out_handle->value, out_handle->length); -@@ -320,6 +325,7 @@ handle_nullreq(FILE *f) { - static char *lbuf = NULL; - static int lbuflen = 0; - static char *cp; -+ int32_t ctx_endtime; - - printerr(1, "handling null request\n"); - -@@ -396,7 +402,7 @@ handle_nullreq(FILE *f) { - - /* kernel needs ctx to calculate verifier on null response, so - * must give it context before doing null call: */ -- if (serialize_context_for_kernel(ctx, &ctx_token, mech, NULL)) { -+ if (serialize_context_for_kernel(ctx, &ctx_token, mech, &ctx_endtime)) { - printerr(0, "WARNING: handle_nullreq: " - "serialize_context_for_kernel failed\n"); - maj_stat = GSS_S_FAILURE; -@@ -405,7 +411,7 @@ handle_nullreq(FILE *f) { - /* We no longer need the gss context */ - gss_delete_sec_context(&ignore_min_stat, &ctx, &ignore_out_tok); - -- do_svc_downcall(&out_handle, &cred, mech, &ctx_token); -+ do_svc_downcall(&out_handle, &cred, mech, &ctx_token, ctx_endtime); - continue_needed: - send_response(f, &in_handle, &in_tok, maj_stat, min_stat, - &out_handle, &out_tok); diff --git a/nfs-utils-1.1.4-tcpwrap-cleanup.patch b/nfs-utils-1.1.4-tcpwrap-cleanup.patch deleted file mode 100644 index 187da42..0000000 --- a/nfs-utils-1.1.4-tcpwrap-cleanup.patch +++ /dev/null @@ -1,194 +0,0 @@ -Author: Steve Dickson -Date: Sat Jan 31 06:17:18 2009 -0500 - - General clean up. Removed unused routines. Reworked syslog - message to (hopefully) make it more sensible. Move - "#ifdef HAVE_LIBWRAP" around so nothing will be defined - when tcp wrapper is not configured. - - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c ---- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-01-31 06:27:54.000000000 -0500 -+++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-01-31 06:31:32.000000000 -0500 -@@ -34,6 +34,7 @@ - #ifdef HAVE_CONFIG_H - #include - #endif -+#ifdef HAVE_LIBWRAP - #include - #include - #include -@@ -57,40 +58,10 @@ - - static void logit(int severity, struct sockaddr_in *addr, - u_long procnum, u_long prognum, char *text); --static void toggle_verboselog(int sig); --int verboselog = 0; --int allow_severity = LOG_INFO; --int deny_severity = LOG_WARNING; -- --/* A handful of macros for "readability". */ -- --#ifdef HAVE_LIBWRAP --/* coming from libwrap.a (tcp_wrappers) */ --extern int hosts_ctl(char *daemon, char *name, char *addr, char *user); --#else --int hosts_ctl(char *daemon, char *name, char *addr, char *user) --{ -- return 0; --} --#endif -- --#define legal_port(a,p) \ -- (ntohs((a)->sin_port) < IPPORT_RESERVED || (p) >= IPPORT_RESERVED) -- --#define log_bad_port(addr, proc, prog) \ -- logit(deny_severity, addr, proc, prog, ": request from unprivileged port") -+static int check_files(void); - - #define log_bad_host(addr, proc, prog) \ -- logit(deny_severity, addr, proc, prog, ": request from unauthorized host") -- --#define log_bad_owner(addr, proc, prog) \ -- logit(deny_severity, addr, proc, prog, ": request from non-local host") -- --#define log_no_forward(addr, proc, prog) \ -- logit(deny_severity, addr, proc, prog, ": request not forwarded") -- --#define log_client(addr, proc, prog) \ -- logit(allow_severity, addr, proc, prog, "") -+ logit(LOG_WARNING, addr, proc, prog, "request from unauthorized host") - - #define ALLOW 1 - #define DENY 0 -@@ -180,46 +151,9 @@ struct sockaddr_in *addr; - return DENY; - } - --/* check_startup - additional startup code */ -- --void check_startup(void) --{ -- -- /* -- * Give up root privileges so that we can never allocate a privileged -- * port when forwarding an rpc request. -- * -- * Fix 8/3/00 Philipp Knirsch: First lookup our rpc user. If we find it, -- * switch to that uid, otherwise simply resue the old bin user and print -- * out a warning in syslog. -- */ -- -- struct passwd *pwent; -- -- pwent = getpwnam("rpc"); -- if (pwent == NULL) { -- syslog(LOG_WARNING, "user rpc not found, reverting to user bin"); -- if (setuid(1) == -1) { -- syslog(LOG_ERR, "setuid(1) failed: %m"); -- exit(1); -- } -- } -- else { -- if (setuid(pwent->pw_uid) == -1) { -- syslog(LOG_WARNING, "setuid() to rpc user failed: %m"); -- if (setuid(1) == -1) { -- syslog(LOG_ERR, "setuid(1) failed: %m"); -- exit(1); -- } -- } -- } -- -- (void) signal(SIGINT, toggle_verboselog); --} -- - /* check_files - check to see if either access files have changed */ - --int check_files() -+static int check_files() - { - static time_t allow_mtime, deny_mtime; - struct stat astat, dstat; -@@ -268,78 +202,21 @@ u_long prog; - haccess_add(addr, prog, FALSE); - return (FALSE); - } -- if (verboselog) -- log_client(addr, proc, prog); - - if (acc) - acc->access = TRUE; - else - haccess_add(addr, prog, TRUE); -- return (TRUE); --} - --/* check_privileged_port - additional checks for privileged-port updates */ --int --check_privileged_port(struct sockaddr_in *addr, -- u_long proc, u_long prog, u_long port) --{ --#ifdef CHECK_PORT -- if (!legal_port(addr, port)) { -- log_bad_port(addr, proc, prog); -- return (FALSE); -- } --#endif - return (TRUE); - } - --/* toggle_verboselog - toggle verbose logging flag */ -- --static void toggle_verboselog(int sig) --{ -- (void) signal(sig, toggle_verboselog); -- verboselog = !verboselog; --} -- - /* logit - report events of interest via the syslog daemon */ - - static void logit(int severity, struct sockaddr_in *addr, - u_long procnum, u_long prognum, char *text) - { -- char *procname; -- char procbuf[16 + 4 * sizeof(u_long)]; -- char *progname; -- char progbuf[16 + 4 * sizeof(u_long)]; -- struct rpcent *rpc; -- -- /* -- * Fork off a process or the portmap daemon might hang while -- * getrpcbynumber() or syslog() does its thing. -- * -- * Don't forget to wait for the children, too... -- */ -- -- if (fork() == 0) { -- -- /* Try to map program number to name. */ -- -- if (prognum == 0) { -- progname = ""; -- } else if ((rpc = getrpcbynumber((int) prognum))) { -- progname = rpc->r_name; -- } else { -- snprintf(progname = progbuf, sizeof (progbuf), -- "prog (%lu)", prognum); -- } -- -- /* Try to map procedure number to name. */ -- -- snprintf(procname = procbuf, sizeof (procbuf), -- "proc (%lu)", (u_long) procnum); -- -- /* Write syslog record. */ -- -- syslog(severity, "connect from %s to %s in %s%s", -- inet_ntoa(addr->sin_addr), procname, progname, text); -- exit(0); -- } -+ syslog(severity, "connect from %s denied: %s", -+ inet_ntoa(addr->sin_addr), text); - } -+#endif diff --git a/nfs-utils-1.1.4-tcpwrap-hash.patch b/nfs-utils-1.1.4-tcpwrap-hash.patch deleted file mode 100644 index fd6abb5..0000000 --- a/nfs-utils-1.1.4-tcpwrap-hash.patch +++ /dev/null @@ -1,89 +0,0 @@ -Author: Steve Dickson -Date: Sat Jan 31 05:30:13 2009 -0500 - - Only hash on IP address and Program number. Including the Procedure - number only creates needles extra hash entries. - - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c ---- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-01-31 06:22:35.000000000 -0500 -+++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-01-31 06:23:22.000000000 -0500 -@@ -106,8 +106,8 @@ typedef struct _hash_head { - TAILQ_HEAD(host_list, _haccess_t) h_head; - } hash_head; - hash_head haccess_tbl[HASH_TABLE_SIZE]; --static haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long, u_long); --static void haccess_add(struct sockaddr_in *addr, u_long, u_long, int); -+static haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long); -+static void haccess_add(struct sockaddr_in *addr, u_long, int); - - inline unsigned int strtoint(char *str) - { -@@ -124,11 +124,10 @@ inline int hashint(unsigned int num) - { - return num % HASH_TABLE_SIZE; - } --#define HASH(_addr, _proc, _prog) \ -- hashint((strtoint((_addr))+(_proc)+(_prog))) -+#define HASH(_addr, _prog) \ -+ hashint((strtoint((_addr))+(_prog))) - --void haccess_add(struct sockaddr_in *addr, u_long proc, -- u_long prog, int access) -+void haccess_add(struct sockaddr_in *addr, u_long prog, int access) - { - hash_head *head; - haccess_t *hptr; -@@ -138,7 +137,7 @@ void haccess_add(struct sockaddr_in *add - if (hptr == NULL) - return; - -- hash = HASH(inet_ntoa(addr->sin_addr), proc, prog); -+ hash = HASH(inet_ntoa(addr->sin_addr), prog); - head = &(haccess_tbl[hash]); - - hptr->access = access; -@@ -149,13 +148,13 @@ void haccess_add(struct sockaddr_in *add - else - TAILQ_INSERT_TAIL(&head->h_head, hptr, list); - } --haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long proc, u_long prog) -+haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long prog) - { - hash_head *head; - haccess_t *hptr; - int hash; - -- hash = HASH(inet_ntoa(addr->sin_addr), proc, prog); -+ hash = HASH(inet_ntoa(addr->sin_addr), prog); - head = &(haccess_tbl[hash]); - - TAILQ_FOREACH(hptr, &head->h_head, list) { -@@ -300,7 +299,7 @@ u_long prog; - haccess_t *acc = NULL; - int changed = check_files(); - -- acc = haccess_lookup(addr, proc, prog); -+ acc = haccess_lookup(addr, prog); - if (acc && changed == 0) - return (acc->access); - -@@ -309,7 +308,7 @@ u_long prog; - if (acc) - acc->access = FALSE; - else -- haccess_add(addr, proc, prog, FALSE); -+ haccess_add(addr, prog, FALSE); - return (FALSE); - } - if (verboselog) -@@ -318,7 +317,7 @@ u_long prog; - if (acc) - acc->access = TRUE; - else -- haccess_add(addr, proc, prog, TRUE); -+ haccess_add(addr, prog, TRUE); - return (TRUE); - } - diff --git a/nfs-utils-1.1.4-tcpwrap-newrules.patch b/nfs-utils-1.1.4-tcpwrap-newrules.patch deleted file mode 100644 index 41de945..0000000 --- a/nfs-utils-1.1.4-tcpwrap-newrules.patch +++ /dev/null @@ -1,106 +0,0 @@ -Author: Steve Dickson -Date: Sat Jan 31 05:50:51 2009 -0500 - - Converted good_client() to correctly use the tcp wrapper - interface and added a note to the mountd man page saying - hostnames will be ignored when they can not be looked up. - - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c ---- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-01-31 06:25:16.000000000 -0500 -+++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-01-31 06:26:27.000000000 -0500 -@@ -46,7 +46,7 @@ - #include - #include - #include --#include -+#include - - #include "xlog.h" - -@@ -169,58 +169,15 @@ good_client(daemon, addr) - char *daemon; - struct sockaddr_in *addr; - { -- struct hostent *hp; -- char **sp; -- char *tmpname; -- -- /* First check the address. */ -- if (hosts_ctl(daemon, "", inet_ntoa(addr->sin_addr), "") == DENY) -- return DENY; -- -- /* Now do the hostname lookup */ -- hp = gethostbyaddr ((const char *) &(addr->sin_addr), -- sizeof (addr->sin_addr), AF_INET); -- if (!hp) { -- xlog(L_WARNING, -- "Warning: Client IP address '%s' not found in host lookup", -- inet_ntoa(addr->sin_addr)); -- return DENY; /* never heard of it. misconfigured DNS? */ -- } -- -- /* Make sure the hostent is authorative. */ -- tmpname = strdup(hp->h_name); -- if (!tmpname) { -- xlog(L_WARNING, "Warning: No memory for Host access check"); -- return DENY; -- } -- hp = gethostbyname(tmpname); -- if (!hp) { -- xlog(L_WARNING, -- "Warning: Client hostname '%s' not found in host lookup", tmpname); -- free(tmpname); -- return DENY; /* never heard of it. misconfigured DNS? */ -- } -- free(tmpname); -+ struct request_info req; - -- /* Now make sure the address is on the list */ -- for (sp = hp->h_addr_list ; *sp ; sp++) { -- if (memcmp(*sp, &(addr->sin_addr), hp->h_length) == 0) -- break; -- } -- if (!*sp) -- return DENY; /* it was a FAKE. */ -+ request_init(&req, RQ_DAEMON, daemon, RQ_CLIENT_SIN, addr, 0); -+ sock_methods(&req); - -- /* Check the official name and address. */ -- if (hosts_ctl(daemon, hp->h_name, inet_ntoa(addr->sin_addr), "") == DENY) -- return DENY; -- -- /* Now check aliases. */ -- for (sp = hp->h_aliases; *sp ; sp++) { -- if (hosts_ctl(daemon, *sp, inet_ntoa(addr->sin_addr), "") == DENY) -- return DENY; -- } -+ if (hosts_access(&req)) -+ return ALLOW; - -- return ALLOW; -+ return DENY; - } - - /* check_startup - additional startup code */ -diff -up nfs-utils-1.1.4/utils/mountd/mountd.man.orig nfs-utils-1.1.4/utils/mountd/mountd.man ---- nfs-utils-1.1.4/utils/mountd/mountd.man.orig 2008-10-17 10:20:09.000000000 -0400 -+++ nfs-utils-1.1.4/utils/mountd/mountd.man 2009-01-31 06:26:27.000000000 -0500 -@@ -181,13 +181,15 @@ mountd: .bar.com - You have to use the daemon name - .B mountd - for the daemon name (even if the binary has a different name). -+.B Note: -+hostnames used in either access file will be ignored when -+they can not be resolved into IP addresses. - - For further information please have a look at the - .BR tcpd (8) - and - .BR hosts_access (5) - manual pages. -- - .SH SEE ALSO - .BR rpc.nfsd (8), - .BR exportfs (8), diff --git a/nfs-utils-1.1.4-tcpwrap-warn.patch b/nfs-utils-1.1.4-tcpwrap-warn.patch deleted file mode 100644 index 5c8914e..0000000 --- a/nfs-utils-1.1.4-tcpwrap-warn.patch +++ /dev/null @@ -1,55 +0,0 @@ -commit 6e3f696e788a56f30b5b3f8250647fe4cd63c884 -Author: Steve Dickson -Date: Sat Jan 3 14:08:25 2009 -0500 - - Now that the TCP wrapper actually works, mounts will - be denied with misconfigured DNS configurations. Warnings - will be logged when these types of configurations are - detected. - - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c ---- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-01-03 13:02:15.000000000 -0500 -+++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-01-03 14:05:42.000000000 -0500 -@@ -48,6 +48,8 @@ - #include - #include - -+#include "xlog.h" -+ - #ifdef SYSV40 - #include - #include -@@ -179,17 +181,27 @@ struct sockaddr_in *addr; - /* Now do the hostname lookup */ - hp = gethostbyaddr ((const char *) &(addr->sin_addr), - sizeof (addr->sin_addr), AF_INET); -- if (!hp) -+ if (!hp) { -+ xlog(L_WARNING, -+ "Warning: Client IP address '%s' not found in host lookup", -+ inet_ntoa(addr->sin_addr)); - return DENY; /* never heard of it. misconfigured DNS? */ -+ } - - /* Make sure the hostent is authorative. */ - tmpname = strdup(hp->h_name); -- if (!tmpname) -+ if (!tmpname) { -+ xlog(L_WARNING, "Warning: No memory for Host access check"); - return DENY; -+ } - hp = gethostbyname(tmpname); -- free(tmpname); -- if (!hp) -+ if (!hp) { -+ xlog(L_WARNING, -+ "Warning: Client hostname '%s' not found in host lookup", tmpname); -+ free(tmpname); - return DENY; /* never heard of it. misconfigured DNS? */ -+ } -+ free(tmpname); - - /* Now make sure the address is on the list */ - for (sp = hp->h_addr_list ; *sp ; sp++) { diff --git a/nfs-utils-1.1.4-tcpwrapper-update.patch b/nfs-utils-1.1.4-tcpwrapper-update.patch deleted file mode 100644 index 307184f..0000000 --- a/nfs-utils-1.1.4-tcpwrapper-update.patch +++ /dev/null @@ -1,280 +0,0 @@ -commit 71f9f61517bf301f723b79651d53590ef97c3556 -Author: Steve Dickson -Date: Fri Dec 19 14:20:14 2008 -0500 - - To ensure the hash table of clients has valid - access rights, check the modification times on - both access files. If one of them have change, - update the hash entry instead of creating a - new entry. - - Signed-off-by: Steve Dickson - -commit 58e0a308fec476361dd21f7d3856faceb6e308ee -Author: Steve Dickson -Date: Fri Dec 19 14:11:09 2008 -0500 - - Clients IP address and host names are check on - every RPC request, to both mountd and statd - when TCP wrappers are enabled. To help this - process scale better the access rights are stored - in a hash table, which are hashed per IP address, - RPC program and procudure numbers. - - Signed-off-by: Steve Dickson - -commit e47da19d63ea50a4e15f6ab491535d54097744de -Author: Steve Dickson -Date: Fri Dec 19 14:09:59 2008 -0500 - - When clients are define as IP addresses in /etc/hosts.deny, - access is allow due to misinterpreting the return value of - hosts_ctl(). This patch reworks that logic which closes - that hole. - - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.save nfs-utils-1.1.4/support/misc/tcpwrapper.c ---- nfs-utils-1.1.4/support/misc/tcpwrapper.c.save 2008-12-19 15:44:05.000000000 -0500 -+++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2008-12-19 15:46:15.000000000 -0500 -@@ -44,6 +44,10 @@ - #include - #include - #include -+#include -+#include -+#include -+ - #ifdef SYSV40 - #include - #include -@@ -86,6 +90,79 @@ int hosts_ctl(char *daemon, char *name, - #define log_client(addr, proc, prog) \ - logit(allow_severity, addr, proc, prog, "") - -+#define ALLOW 1 -+#define DENY 0 -+ -+typedef struct _haccess_t { -+ TAILQ_ENTRY(_haccess_t) list; -+ int access; -+ struct in_addr addr; -+} haccess_t; -+ -+#define HASH_TABLE_SIZE 1021 -+typedef struct _hash_head { -+ TAILQ_HEAD(host_list, _haccess_t) h_head; -+} hash_head; -+hash_head haccess_tbl[HASH_TABLE_SIZE]; -+static haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long, u_long); -+static void haccess_add(struct sockaddr_in *addr, u_long, u_long, int); -+ -+inline unsigned int strtoint(char *str) -+{ -+ unsigned int n = 0; -+ int len = strlen(str); -+ int i; -+ -+ for (i=0; i < len; i++) -+ n+=((int)str[i])*i; -+ -+ return n; -+} -+inline int hashint(unsigned int num) -+{ -+ return num % HASH_TABLE_SIZE; -+} -+#define HASH(_addr, _proc, _prog) \ -+ hashint((strtoint((_addr))+(_proc)+(_prog))) -+ -+void haccess_add(struct sockaddr_in *addr, u_long proc, -+ u_long prog, int access) -+{ -+ hash_head *head; -+ haccess_t *hptr; -+ int hash; -+ -+ hptr = (haccess_t *)malloc(sizeof(haccess_t)); -+ if (hptr == NULL) -+ return; -+ -+ hash = HASH(inet_ntoa(addr->sin_addr), proc, prog); -+ head = &(haccess_tbl[hash]); -+ -+ hptr->access = access; -+ hptr->addr.s_addr = addr->sin_addr.s_addr; -+ -+ if (TAILQ_EMPTY(&head->h_head)) -+ TAILQ_INSERT_HEAD(&head->h_head, hptr, list); -+ else -+ TAILQ_INSERT_TAIL(&head->h_head, hptr, list); -+} -+haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long proc, u_long prog) -+{ -+ hash_head *head; -+ haccess_t *hptr; -+ int hash; -+ -+ hash = HASH(inet_ntoa(addr->sin_addr), proc, prog); -+ head = &(haccess_tbl[hash]); -+ -+ TAILQ_FOREACH(hptr, &head->h_head, list) { -+ if (hptr->addr.s_addr == addr->sin_addr.s_addr) -+ return hptr; -+ } -+ return NULL; -+} -+ - int - good_client(daemon, addr) - char *daemon; -@@ -95,47 +172,44 @@ struct sockaddr_in *addr; - char **sp; - char *tmpname; - -- /* Check the IP address first. */ -- if (hosts_ctl(daemon, "", inet_ntoa(addr->sin_addr), "")) -- return 1; -- -- /* Check the hostname. */ -- hp = gethostbyaddr ((const char *) &(addr->sin_addr), -- sizeof (addr->sin_addr), AF_INET); -+ /* First check the address. */ -+ if (hosts_ctl(daemon, "", inet_ntoa(addr->sin_addr), "") == DENY) -+ return DENY; -+ -+ /* Now do the hostname lookup */ -+ hp = gethostbyaddr ((const char *) &(addr->sin_addr), -+ sizeof (addr->sin_addr), AF_INET); -+ if (!hp) -+ return DENY; /* never heard of it. misconfigured DNS? */ -+ -+ /* Make sure the hostent is authorative. */ -+ tmpname = strdup(hp->h_name); -+ if (!tmpname) -+ return DENY; -+ hp = gethostbyname(tmpname); -+ free(tmpname); -+ if (!hp) -+ return DENY; /* never heard of it. misconfigured DNS? */ - -- if (!hp) -- return 0; -- -- /* must make sure the hostent is authorative. */ -- tmpname = alloca (strlen (hp->h_name) + 1); -- strcpy (tmpname, hp->h_name); -- hp = gethostbyname(tmpname); -- if (hp) { -- /* now make sure the "addr->sin_addr" is on the list */ -+ /* Now make sure the address is on the list */ - for (sp = hp->h_addr_list ; *sp ; sp++) { -- if (memcmp(*sp, &(addr->sin_addr), hp->h_length)==0) -- break; -+ if (memcmp(*sp, &(addr->sin_addr), hp->h_length) == 0) -+ break; - } - if (!*sp) -- /* it was a FAKE. */ -- return 0; -- } -- else -- /* never heard of it. misconfigured DNS? */ -- return 0; -- -- /* Check the official name first. */ -- if (hosts_ctl(daemon, hp->h_name, "", "")) -- return 1; -- -- /* Check aliases. */ -- for (sp = hp->h_aliases; *sp ; sp++) { -- if (hosts_ctl(daemon, *sp, "", "")) -- return 1; -- } -+ return DENY; /* it was a FAKE. */ -+ -+ /* Check the official name and address. */ -+ if (hosts_ctl(daemon, hp->h_name, inet_ntoa(addr->sin_addr), "") == DENY) -+ return DENY; -+ -+ /* Now check aliases. */ -+ for (sp = hp->h_aliases; *sp ; sp++) { -+ if (hosts_ctl(daemon, *sp, inet_ntoa(addr->sin_addr), "") == DENY) -+ return DENY; -+ } - -- /* No match */ -- return 0; -+ return ALLOW; - } - - /* check_startup - additional startup code */ -@@ -175,6 +249,33 @@ void check_startup(void) - (void) signal(SIGINT, toggle_verboselog); - } - -+/* check_files - check to see if either access files have changed */ -+ -+int check_files() -+{ -+ static time_t allow_mtime, deny_mtime; -+ struct stat astat, dstat; -+ int changed = 0; -+ -+ if (stat("/etc/hosts.allow", &astat) < 0) -+ astat.st_mtime = 0; -+ if (stat("/etc/hosts.deny", &dstat) < 0) -+ dstat.st_mtime = 0; -+ -+ if(!astat.st_mtime || !dstat.st_mtime) -+ return changed; -+ -+ if (astat.st_mtime != allow_mtime) -+ changed = 1; -+ else if (dstat.st_mtime != deny_mtime) -+ changed = 1; -+ -+ allow_mtime = astat.st_mtime; -+ deny_mtime = dstat.st_mtime; -+ -+ return changed; -+} -+ - /* check_default - additional checks for NULL, DUMP, GETPORT and unknown */ - - int -@@ -184,12 +285,28 @@ struct sockaddr_in *addr; - u_long proc; - u_long prog; - { -- if (!(from_local(addr) || good_client(daemon, addr))) { -- log_bad_host(addr, proc, prog); -- return (FALSE); -- } -- if (verboselog) -- log_client(addr, proc, prog); -+ haccess_t *acc = NULL; -+ int changed = check_files(); -+ -+ acc = haccess_lookup(addr, proc, prog); -+ if (acc && changed == 0) -+ return (acc->access); -+ -+ if (!(from_local(addr) || good_client(daemon, addr))) { -+ log_bad_host(addr, proc, prog); -+ if (acc) -+ acc->access = FALSE; -+ else -+ haccess_add(addr, proc, prog, FALSE); -+ return (FALSE); -+ } -+ if (verboselog) -+ log_client(addr, proc, prog); -+ -+ if (acc) -+ acc->access = TRUE; -+ else -+ haccess_add(addr, proc, prog, TRUE); - return (TRUE); - } - diff --git a/nfs-utils-1.1.4-umount-ipv6.patch b/nfs-utils-1.1.4-umount-ipv6.patch deleted file mode 100644 index 3c3e965..0000000 --- a/nfs-utils-1.1.4-umount-ipv6.patch +++ /dev/null @@ -1,343 +0,0 @@ -Author: Chuck Lever -Date: Tue Feb 17 16:27:43 2009 -0500 - - umount command: remove do_nfs_umount23 function - - Remove do_nfs_umount23() now that it is unused. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit c735a8331b082038a0e83ec4187c2656b0804eea -Author: Chuck Lever -Date: Tue Feb 17 16:26:31 2009 -0500 - - umount.nfs command: Support AF_INET6 server addresses - - Replace existing mount option parser in nfsumount.c with the new pmap - stuffer - function nfs_options2pmap(). Mount option parsing for umount.nfs now - works - the same as it does for mount option rewriting in the text-based - mount.nfs - command. - - This adds a number of new features: - - 1. The new logic supports resolving AF_INET6 server addresses - 2. Support is added for the recently introduced "mountaddr" option. - 3. Parsing numeric option values is much more careful - 4. Option parsing no longer uses xmalloc/xstrdup, so it won't fail - silently if memory can't be allocated - 5. Mount program number set in /etc/rpc is respected - 6. Mount doesn't exit with EX_USAGE if the hostname lookup fails - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -commit 97de03f8c866b9d3e790d64f4e9ac24011aaa5b1 -Author: Chuck Lever -Date: Tue Feb 17 16:25:27 2009 -0500 - - umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount() - - We need an AF_INET6-capable version of nfs_call_unmount() to allow the - umount.nfs command to support unmounting NFS servers over IPv6. The - legacy - mount.nfs command still likes to use nfs_call_umount(), so we leave it - in - place and introduce a new API that can take a "struct sockaddr *". - - The umount.nfs command will invoke this new API, but we'll leave the - legacy - mount.nfs command and the umount.nfs4 command alone. The umount.nfs4 - command does not need this support because NFSv4 unmount operations are - entirely local. - - Signed-off-by: Chuck Lever - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/utils/mount/network.c.save nfs-utils-1.1.4/utils/mount/network.c ---- nfs-utils-1.1.4/utils/mount/network.c.save 2009-02-17 16:37:18.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/network.c 2009-02-17 16:38:10.000000000 -0500 -@@ -838,6 +838,59 @@ int start_statd(void) - } - - /** -+ * nfs_advise_umount - ask the server to remove a share from it's rmtab -+ * @sap: pointer to IP address of server to call -+ * @salen: length of server address -+ * @pmap: partially filled-in mountd RPC service tuple -+ * @argp: directory path of share to "unmount" -+ * -+ * Returns one if the unmount call succeeded; zero if the unmount -+ * failed for any reason; rpccreateerr.cf_stat is set to reflect -+ * the nature of the error. -+ * -+ * We use a fast timeout since this call is advisory only. -+ */ -+int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen, -+ const struct pmap *pmap, const dirpath *argp) -+{ -+ struct sockaddr_storage address; -+ struct sockaddr *saddr = (struct sockaddr *)&address; -+ struct pmap mnt_pmap = *pmap; -+ struct timeval timeout = { -+ .tv_sec = MOUNT_TIMEOUT >> 3, -+ }; -+ CLIENT *client; -+ enum clnt_stat res = 0; -+ -+ if (nfs_probe_mntport(sap, salen, &mnt_pmap) == 0) -+ return 0; -+ -+ memcpy(saddr, sap, salen); -+ nfs_set_port(saddr, mnt_pmap.pm_port); -+ -+ client = nfs_get_rpcclient(saddr, salen, mnt_pmap.pm_prot, -+ mnt_pmap.pm_prog, mnt_pmap.pm_vers, -+ &timeout); -+ if (client == NULL) -+ return 0; -+ -+ client->cl_auth = authunix_create_default(); -+ -+ res = CLNT_CALL(client, MOUNTPROC_UMNT, -+ (xdrproc_t)xdr_dirpath, (caddr_t)argp, -+ (xdrproc_t)xdr_void, NULL, -+ timeout); -+ -+ auth_destroy(client->cl_auth); -+ CLNT_DESTROY(client); -+ -+ if (res != RPC_SUCCESS) -+ return 0; -+ -+ return 1; -+} -+ -+/** - * nfs_call_umount - ask the server to remove a share from it's rmtab - * @mnt_server: address of RPC MNT program server - * @argp: directory path of share to "unmount" -diff -up nfs-utils-1.1.4/utils/mount/network.h.save nfs-utils-1.1.4/utils/mount/network.h ---- nfs-utils-1.1.4/utils/mount/network.h.save 2009-02-17 16:37:26.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/network.h 2009-02-17 16:38:10.000000000 -0500 -@@ -52,7 +52,6 @@ int nfs_present_sockaddr(const struct so - const socklen_t, char *, const size_t); - int nfs_callback_address(const struct sockaddr *, const socklen_t, - struct sockaddr *, socklen_t *); --int nfs_call_umount(clnt_addr_t *, dirpath *); - int clnt_ping(struct sockaddr_in *, const unsigned long, - const unsigned long, const unsigned int, - struct sockaddr_in *); -@@ -66,6 +65,9 @@ int start_statd(void); - - unsigned long nfsvers_to_mnt(const unsigned long); - -+int nfs_call_umount(clnt_addr_t *, dirpath *); -+int nfs_advise_umount(const struct sockaddr *, const socklen_t, -+ const struct pmap *, const dirpath *); - CLIENT *mnt_openclnt(clnt_addr_t *, int *); - void mnt_closeclnt(CLIENT *, int); - -diff -up nfs-utils-1.1.4/utils/mount/nfsumount.c.save nfs-utils-1.1.4/utils/mount/nfsumount.c ---- nfs-utils-1.1.4/utils/mount/nfsumount.c.save 2009-02-17 16:37:42.000000000 -0500 -+++ nfs-utils-1.1.4/utils/mount/nfsumount.c 2009-02-17 16:38:29.000000000 -0500 -@@ -34,6 +34,7 @@ - #include "mount.h" - #include "error.h" - #include "network.h" -+#include "parse_opt.h" - #include "parse_dev.h" - - #if !defined(MNT_FORCE) -@@ -134,6 +135,64 @@ static int del_mtab(const char *spec, co - } - - /* -+ * Discover mount server's hostname/address by examining mount options -+ * -+ * Returns a pointer to a string that the caller must free, on -+ * success; otherwise NULL is returned. -+ */ -+static char *nfs_umount_hostname(struct mount_options *options, -+ char *hostname) -+{ -+ char *option; -+ -+ option = po_get(options, "mountaddr"); -+ if (option) -+ goto out; -+ option = po_get(options, "mounthost"); -+ if (option) -+ goto out; -+ option = po_get(options, "addr"); -+ if (option) -+ goto out; -+ -+ return hostname; -+ -+out: -+ free(hostname); -+ return strdup(option); -+} -+ -+/* -+ * Returns EX_SUCCESS if mount options and device name have been -+ * parsed successfully; otherwise EX_FAIL. -+ */ -+static int nfs_umount_do_umnt(struct mount_options *options, -+ char **hostname, char **dirname) -+{ -+ struct sockaddr_storage address; -+ struct sockaddr *sap = (struct sockaddr *)&address; -+ socklen_t salen = sizeof(address); -+ struct pmap nfs_pmap, mnt_pmap; -+ -+ nfs_options2pmap(options, &nfs_pmap, &mnt_pmap); -+ -+ *hostname = nfs_umount_hostname(options, *hostname); -+ if (!*hostname) { -+ nfs_error(_("%s: out of memory"), progname); -+ return EX_FAIL; -+ } -+ -+ if (nfs_name_to_address(*hostname, AF_UNSPEC, sap, &salen)) { -+ if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) != 0) -+ return EX_SUCCESS; -+ else -+ nfs_error(_("%s: Server failed to unmount '%s:%s'"), -+ progname, *hostname, *dirname); -+ } -+ return EX_FAIL; -+} -+ -+/* - * Pick up certain mount options used during the original mount - * from /etc/mtab. The basics include the server's IP address and - * the server pathname of the share to unregister. -@@ -142,85 +201,28 @@ static int del_mtab(const char *spec, co - * version, and transport protocol used to punch through a firewall. - * We will need this information to get through the firewall again - * to do the umount. -+ * -+ * Note that option parsing failures won't necessarily cause the -+ * umount request to fail. Those values will be left zero in the -+ * pmap tuple. If the GETPORT call later fails to disambiguate them, -+ * then we fail. - */ --static int do_nfs_umount23(const char *spec, char *opts) -+static int nfs_umount23(const char *devname, char *string) - { -- char *hostname; -- char *dirname; -- clnt_addr_t mnt_server = { &hostname, }; -- struct mntent mnt = { .mnt_opts = opts }; -- struct pmap *pmap = &mnt_server.pmap; -- char *p; -- int result = EX_USAGE; -- -- if (!nfs_parse_devname(spec, &hostname, &dirname)) -- return result; -- --#ifdef NFS_MOUNT_DEBUG -- printf(_("host: %s, directory: %s\n"), hostname, dirname); --#endif -- -- if (opts && (p = strstr(opts, "addr="))) { -- char *q; -+ char *hostname, *dirname; -+ struct mount_options *options; -+ int result = EX_FAIL; - -- free(hostname); -- p += 5; -- q = p; -- while (*q && *q != ',') q++; -- hostname = xstrndup(p,q-p); -- } -- -- if (opts && (p = strstr(opts, "mounthost="))) { -- char *q; -- -- free(hostname); -- p += 10; -- q = p; -- while (*q && *q != ',') q++; -- hostname = xstrndup(p,q-p); -- } -- -- pmap->pm_prog = MOUNTPROG; -- pmap->pm_vers = 0; /* unknown */ -- if (opts && (p = strstr(opts, "mountprog=")) && isdigit(*(p+10))) -- pmap->pm_prog = atoi(p+10); -- if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10))) -- pmap->pm_port = atoi(p+10); -- if (opts && hasmntopt(&mnt, "v2")) -- pmap->pm_vers = nfsvers_to_mnt(2); -- if (opts && hasmntopt(&mnt, "v3")) -- pmap->pm_vers = nfsvers_to_mnt(3); -- if (opts && (p = strstr(opts, "vers=")) && isdigit(*(p+5))) -- pmap->pm_vers = nfsvers_to_mnt(atoi(p+5)); -- if (opts && (p = strstr(opts, "mountvers=")) && isdigit(*(p+10))) -- pmap->pm_vers = atoi(p+10); -- if (opts && (hasmntopt(&mnt, "udp") -- || hasmntopt(&mnt, "proto=udp") -- || hasmntopt(&mnt, "mountproto=udp") -- )) -- pmap->pm_prot = IPPROTO_UDP; -- if (opts && (hasmntopt(&mnt, "tcp") -- || hasmntopt(&mnt, "proto=tcp") -- || hasmntopt(&mnt, "mountproto=tcp") -- )) -- pmap->pm_prot = IPPROTO_TCP; -- -- if (!nfs_gethostbyname(hostname, &mnt_server.saddr)) { -- nfs_error(_("%s: DNS resolution of '%s' failed"), -- progname, hostname); -- goto out; -- } -- -- if (!nfs_call_umount(&mnt_server, &dirname)) { -- nfs_error(_("%s: Server failed to unmount '%s'"), -- progname, spec); -- result = EX_FAIL; -- goto out; -- } -+ if (!nfs_parse_devname(devname, &hostname, &dirname)) -+ return EX_USAGE; - -- result = EX_SUCCESS; -+ options = po_split(string); -+ if (options) { -+ result = nfs_umount_do_umnt(options, &hostname, &dirname); -+ po_destroy(options); -+ } else -+ nfs_error(_("%s: option parsing error"), progname); - --out: - free(hostname); - free(dirname); - return result; -@@ -350,16 +352,16 @@ int nfsumount(int argc, char *argv[]) - ret = 0; - if (mc) { - if (!lazy && strcmp(mc->m.mnt_type, "nfs4") != 0) -- /* We ignore the error from do_nfs_umount23. -+ /* We ignore the error from nfs_umount23. - * If the actual umount succeeds (in del_mtab), - * we don't want to signal an error, as that - * could cause /sbin/mount to retry! - */ -- do_nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts); -- ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir); -+ nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts); -+ ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir) ?: ret; - } else if (*spec != '/') { - if (!lazy) -- ret = do_nfs_umount23(spec, "tcp,v3"); -+ ret = nfs_umount23(spec, "tcp,v3"); - } else - ret = del_mtab(NULL, spec); - diff --git a/nfs-utils.spec b/nfs-utils.spec index f263944..da81dce 100644 --- a/nfs-utils.spec +++ b/nfs-utils.spec @@ -1,8 +1,8 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS server Name: nfs-utils URL: http://sourceforge.net/projects/nfs -Version: 1.1.4 -Release: 21%{?dist} +Version: 1.1.5 +Release: 1%{?dist} Epoch: 1 # group all 32bit related archs @@ -26,34 +26,6 @@ Patch00: nfs-utils-1.0.5-statdpath.patch Patch01: nfs-utils-1.1.0-smnotify-path.patch Patch02: nfs-utils-1.1.0-exp-subtree-warn-off.patch -Patch100: nfs-utils-1.1.4-inet6-capable-api.patch -Patch101: nfs-utils-1.1.4-inet6-rpcbind-util-funcs.patch -Patch102: nfs-utils-1.1.4-showmount-rpcbind.patch -Patch103: nfs-utils-1.1.4-gssd-dnotify.patch -Patch104: nfs-utils-1.1.4-statd-setuid.patch -Patch105: nfs-utils-1.1.4-mount-nfs_getport.patch -Patch106: nfs-utils-1.1.4-sm-notify-typo.patch -Patch107: nfs-utils-1.1.4-mount-inet6-support.patch -Patch108: nfs-utils-1.1.4-svcgssd-expiration.patch -Patch109: nfs-utils-1.1.4-mount-po_get_numeric.patch -Patch110: nfs-utils-1.1.4-sm-notify-freeaddrinfo.patch -Patch111: nfs-utils-1.1.4-statd-xunlink.patch -Patch112: nfs-utils-1.1.4-tcpwrapper-update.patch -Patch113: nfs-utils-1.1.4-tcpwrap-warn.patch -Patch114: nfs-utils-1.1.4-gssd-verbosity.patch -Patch115: nfs-utils-1.1.4-mount-addrconfig.patch -Patch116: nfs-utils-1.1.4-configure-uuid.patch -Patch117: nfs-utils-1.1.4-configure-tirpc.patch -Patch118: nfs-utils-1.1.4-tcpwrap-hash.patch -Patch119: nfs-utils-1.1.4-tcpwrap-newrules.patch -Patch120: nfs-utils-1.1.4-tcpwrap-cleanup.patch -Patch121: nfs-utils-1.1.4-mount-textbased.patch -Patch122: nfs-utils-1.1.4-mount-nolock.patch -Patch123: nfs-utils-1.1.4-mount-udponly.patch -Patch124: nfs-utils-1.1.4-umount-ipv6.patch -Patch125: nfs-utils-1.1.4-export-hash.patch -Patch126: nfs-utils-1.1.4-configure.patch - %if %{enablefscache} Patch90: nfs-utils-1.1.0-mount-fsc.patch %endif @@ -107,34 +79,6 @@ This package also contains the mount.nfs and umount.nfs program. %patch01 -p1 %patch02 -p1 -%patch100 -p1 -%patch101 -p1 -%patch102 -p1 -%patch103 -p1 -%patch104 -p1 -%patch105 -p1 -%patch106 -p1 -%patch107 -p1 -%patch108 -p1 -%patch109 -p1 -%patch110 -p1 -%patch111 -p1 -%patch112 -p1 -%patch113 -p1 -%patch114 -p1 -%patch115 -p1 -%patch116 -p1 -%patch117 -p1 -%patch118 -p1 -%patch119 -p1 -%patch120 -p1 -%patch121 -p1 -%patch122 -p1 -%patch123 -p1 -%patch124 -p1 -%patch125 -p1 -%patch126 -p1 - %if %{enablefscache} %patch90 -p1 %endif @@ -297,6 +241,9 @@ fi %attr(4755,root,root) /sbin/umount.nfs4 %changelog +* Thu Mar 5 2009 Steve Dickson 1.1.5-1 +- Updated to latest upstream version: 1.1.5 + * Wed Mar 4 2009 Steve Dickson 1.1.4-21 - configure: fix AC_CACHE_VAL warnings diff --git a/sources b/sources index dc4e3fb..fdb67d2 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ ae7db9c61c5ad04f83bb99e5caed73da nfs.doc.tar.gz -3ed5b9cb73fd1c9b358c7bfa7a6ae150 nfs-utils-1.1.4.tar.bz2 +2848072a5e53840b9bc520fbb6782b57 nfs-utils-1.1.5.tar.bz2