[nfs-utils] - Updated to latest upstream release: nfs-utils-1-2-4-rc3

Steve Dickson steved at fedoraproject.org
Mon Nov 29 20:34:35 UTC 2010


commit f6ef5e4f31385d2440ee03578f372209ddd2e411
Author: Steve Dickson <steved at redhat.com>
Date:   Mon Nov 29 11:27:06 2010 -0500

    - Updated to latest upstream release: nfs-utils-1-2-4-rc3
    
    Signed-off-by: Steve Dickson <steved at redhat.com>

 nfs-utils-1-2-3-rc4.patch                          | 4340 -------------
 nfs-utils-1-2-3-rc5.patch                          | 5668 -----------------
 nfs-utils-1-2-3-rc6.patch                          | 6521 --------------------
 ...ls-1.2.4-rc1.patch => nfs-utils-1.2.4-rc2.patch |  511 ++-
 nfs-utils-1.2.4-rc3.patch                          | 2167 +++++++
 nfs-utils.spec                                     |    9 +-
 6 files changed, 2661 insertions(+), 16555 deletions(-)
---
diff --git a/nfs-utils-1.2.4-rc1.patch b/nfs-utils-1.2.4-rc2.patch
similarity index 72%
rename from nfs-utils-1.2.4-rc1.patch
rename to nfs-utils-1.2.4-rc2.patch
index 849b533..7d1e219 100644
--- a/nfs-utils-1.2.4-rc1.patch
+++ b/nfs-utils-1.2.4-rc2.patch
@@ -1,3 +1,16 @@
+diff --git a/configure.ac b/configure.ac
+index 3058be6..5408e85 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -136,7 +136,7 @@ AC_ARG_ENABLE(tirpc,
+ 	[AC_HELP_STRING([--enable-tirpc],
+ 			[enable use of TI-RPC @<:@default=yes@:>@])],
+ 	enable_tirpc=$enableval,
+-	enable_tirpc='yes')
++	enable_tirpc='')
+ AC_ARG_ENABLE(ipv6,
+ 	[AC_HELP_STRING([--enable-ipv6],
+                         [enable support for IPv6 @<:@default=no@:>@])],
 diff --git a/support/export/client.c b/support/export/client.c
 index dbfc2b1..ba2db8f 100644
 --- a/support/export/client.c
@@ -22,6 +35,30 @@ index f528603..4fda30a 100644
  
  	xfree(exp->m_export.e_hostname);
  	xfree(exp);
+diff --git a/support/export/hostname.c b/support/export/hostname.c
+index 3c55ce7..efcb75c 100644
+--- a/support/export/hostname.c
++++ b/support/export/hostname.c
+@@ -30,10 +30,6 @@
+ #include "sockaddr.h"
+ #include "exportfs.h"
+ 
+-#ifndef HAVE_DECL_AI_ADDRCONFIG
+-#define AI_ADDRCONFIG	0
+-#endif
+-
+ /**
+  * host_ntop - generate presentation address given a sockaddr
+  * @sap: pointer to socket address
+@@ -170,7 +166,7 @@ host_addrinfo(const char *hostname)
+ #endif
+ 		/* don't return duplicates */
+ 		.ai_protocol	= (int)IPPROTO_UDP,
+-		.ai_flags	= AI_ADDRCONFIG | AI_CANONNAME,
++		.ai_flags	= AI_CANONNAME,
+ 	};
+ 	int error;
+ 
 diff --git a/support/include/nfslib.h b/support/include/nfslib.h
 index 3db5bec..53ece0e 100644
 --- a/support/include/nfslib.h
@@ -596,6 +633,55 @@ index 59ba505..b3f75ed 100644
  		void (*dispatch)(struct svc_req *, SVCXPRT *),
  		const uint16_t port)
  {
+diff --git a/tests/nsm_client/nsm_client.c b/tests/nsm_client/nsm_client.c
+index 0d1159a..0fa3422 100644
+--- a/tests/nsm_client/nsm_client.c
++++ b/tests/nsm_client/nsm_client.c
+@@ -205,7 +205,7 @@ nsm_client_get_rpcclient(const char *node)
+ {
+ 	unsigned short		port;
+ 	struct addrinfo		*ai;
+-	struct addrinfo		hints = { .ai_flags	= AI_ADDRCONFIG };
++	struct addrinfo		hints = { };
+ 	int			err;
+ 	CLIENT			*client = NULL;
+ 
+diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
+index c726dd9..4e3edc5 100644
+--- a/utils/exportfs/exports.man
++++ b/utils/exportfs/exports.man
+@@ -145,7 +145,9 @@ storage (see
+ .IR async
+ above).
+ 
+-In releases of nfs-utils up to and including 1.0.0, this option was the
++In releases of nfs-utils up to and including 1.0.0, the
++.I async 
++option was the
+ default.  In all releases after 1.0.0,
+ .I sync
+ is the default, and
+@@ -375,20 +377,6 @@ If the client asks for alternative locations for the export point, it
+ will be given this list of alternatives. (Note that actual replication
+ of the filesystem must be handled elsewhere.)
+ 
+-.TP
+-.IR refer= path at host[+host][:path at host[+host]]
+-A client referencing the export point will be directed to choose from
+-the given list an alternative location for the filesystem.
+-(Note that the server must have a mountpoint here, though a different
+-filesystem is not required; so, for example,
+-.IR "mount --bind" " /path /path"
+-is sufficient.)
+-.TP
+-.IR replicas= path at host[+host][:path at host[+host]]
+-If the client asks for alternative locations for the export point, it
+-will be given this list of alternatives. (Note that actual replication
+-of the filesystem must be handled elsewhere.)
+-
+ .SS User ID Mapping
+ .PP
+ .B nfsd
 diff --git a/utils/idmapd/Makefile.am b/utils/idmapd/Makefile.am
 index 4218048..4328e41 100644
 --- a/utils/idmapd/Makefile.am
@@ -918,7 +1004,7 @@ index 051fa38..a742e64 100644
  				close(lockfile_fd);
  				die (EX_FILEIO, _("Cannot create link %s\n"
 diff --git a/utils/mount/mount.c b/utils/mount/mount.c
-index 82b9169..b4da21f 100644
+index 82b9169..a19af53 100644
 --- a/utils/mount/mount.c
 +++ b/utils/mount/mount.c
 @@ -209,7 +209,7 @@ static char *fix_opts_string(int flags, const char *extra_opts)
@@ -930,16 +1016,62 @@ index 82b9169..b4da21f 100644
  	for (om = opt_map; om->opt != NULL; om++) {
  		if (om->skip)
  			continue;
-@@ -281,7 +281,7 @@ static int add_mtab(char *spec, char *mount_point, char *fstype,
- 	ment.mnt_fsname = spec;
- 	ment.mnt_dir = mount_point;
- 	ment.mnt_type = fstype;
+@@ -224,6 +224,20 @@ static char *fix_opts_string(int flags, const char *extra_opts)
+ 	return new_opts;
+ }
+ 
++static void
++init_mntent(struct mntent *mnt, char *fsname, char *dir, char *type,
++		int flags, char *opts)
++{
++	mnt->mnt_fsname	= fsname;
++	mnt->mnt_dir	= dir;
++	mnt->mnt_type	= type;
++	mnt->mnt_opts	= fix_opts_string(flags & ~MS_NOMTAB, opts);
++
++	/* these are always zero for NFS */
++	mnt->mnt_freq	= 0;
++	mnt->mnt_passno	= 0;
++}
++
+ /* Create mtab with a root entry.  */
+ static void
+ create_mtab (void) {
+@@ -245,11 +259,8 @@ create_mtab (void) {
+ 	if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
+ 		char *extra_opts;
+ 		parse_opts (fstab->m.mnt_opts, &flags, &extra_opts);
+-		mnt.mnt_dir = "/";
+-		mnt.mnt_fsname = xstrdup(fstab->m.mnt_fsname);
+-		mnt.mnt_type = fstab->m.mnt_type;
+-		mnt.mnt_opts = fix_opts_string (flags, extra_opts);
+-		mnt.mnt_freq = mnt.mnt_passno = 0;
++		init_mntent(&mnt, xstrdup(fstab->m.mnt_fsname), "/",
++				fstab->m.mnt_type, flags, extra_opts);
+ 		free(extra_opts);
+ 
+ 		if (nfs_addmntent (mfp, &mnt) == 1) {
+@@ -273,17 +284,12 @@ create_mtab (void) {
+ }
+ 
+ static int add_mtab(char *spec, char *mount_point, char *fstype,
+-			int flags, char *opts, int freq, int pass)
++			int flags, char *opts)
+ {
+ 	struct mntent ment;
+ 	int result = EX_SUCCESS;
+ 
+-	ment.mnt_fsname = spec;
+-	ment.mnt_dir = mount_point;
+-	ment.mnt_type = fstype;
 -	ment.mnt_opts = fix_opts_string(flags, opts);
-+	ment.mnt_opts = fix_opts_string(flags & ~MS_NOMTAB, opts);
- 	ment.mnt_freq = freq;
- 	ment.mnt_passno = pass;
+-	ment.mnt_freq = freq;
+-	ment.mnt_passno = pass;
++	init_mntent(&ment, spec, mount_point, fstype, flags, opts);
  
-@@ -321,7 +321,7 @@ static int add_mtab(char *spec, char *mount_point, char *fstype,
+ 	if (!nomtab && mtab_does_not_exist()) {
+ 		if (verbose > 1)
+@@ -321,7 +327,7 @@ static int add_mtab(char *spec, char *mount_point, char *fstype,
  	return result;
  }
  
@@ -948,7 +1080,7 @@ index 82b9169..b4da21f 100644
  {
  	printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"),
  		progname);
-@@ -337,7 +337,7 @@ void mount_usage(void)
+@@ -337,7 +343,7 @@ void mount_usage(void)
  	printf(_("\tnfsoptions\tRefer to mount.nfs(8) or nfs(5)\n\n"));
  }
  
@@ -957,7 +1089,7 @@ index 82b9169..b4da21f 100644
  {
  	const struct opt_map *om;
  
-@@ -371,7 +371,7 @@ static void parse_opts(const char *options, int *flags, char **extra_opts)
+@@ -371,7 +377,7 @@ static void parse_opts(const char *options, int *flags, char **extra_opts)
  	if (options != NULL) {
  		char *opts = xstrdup(options);
  		char *opt, *p;
@@ -966,6 +1098,17 @@ index 82b9169..b4da21f 100644
  		int open_quote = 0;
  
  		*extra_opts = xmalloc(len);
+@@ -441,9 +447,7 @@ static int try_mount(char *spec, char *mount_point, int flags,
+ 	if (!fake)
+ 		print_one(spec, mount_point, fs_type, mount_opts);
+ 
+-	ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts,
+-			0, 0 /* these are always zero for NFS */ );
+-	return ret;
++	return add_mtab(spec, mount_point, fs_type, flags, *extra_opts);
+ }
+ 
+ int main(int argc, char *argv[])
 diff --git a/utils/mount/mount_config.h b/utils/mount/mount_config.h
 index 3023306..e86b4ba 100644
 --- a/utils/mount/mount_config.h
@@ -1039,7 +1182,7 @@ index cbfb099..4d050d8 100644
 +
  #endif	/* _NFS_UTILS_MOUNT_CONSTANTS_H */
 diff --git a/utils/mount/network.c b/utils/mount/network.c
-index d612427..5b515c3 100644
+index d612427..21a7a2c 100644
 --- a/utils/mount/network.c
 +++ b/utils/mount/network.c
 @@ -59,6 +59,8 @@
@@ -1051,7 +1194,17 @@ index d612427..5b515c3 100644
  extern int nfs_mount_data_version;
  extern char *progname;
  extern int verbose;
-@@ -428,12 +430,12 @@ static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
+@@ -208,9 +210,6 @@ int nfs_lookup(const char *hostname, const sa_family_t family,
+ {
+ 	struct addrinfo *gai_results;
+ 	struct addrinfo gai_hint = {
+-#ifdef HAVE_DECL_AI_ADDRCONFIG
+-		.ai_flags	= AI_ADDRCONFIG,
+-#endif	/* HAVE_DECL_AI_ADDRCONFIG */
+ 		.ai_family	= family,
+ 	};
+ 	socklen_t len = *salen;
+@@ -428,12 +427,12 @@ static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
  		if (bindresvport(so, &laddr) < 0)
  			goto err_bindresvport;
  	} else {
@@ -1066,7 +1219,7 @@ index d612427..5b515c3 100644
  				timeout);
  		if (cc < 0)
  			goto err_connect;
-@@ -756,11 +758,12 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
+@@ -756,11 +755,12 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
   */
  int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
  {
@@ -1083,7 +1236,7 @@ index d612427..5b515c3 100644
  					&nfs_server->pmap);
  }
  
-@@ -772,7 +775,7 @@ static int nfs_probe_statd(void)
+@@ -772,7 +772,7 @@ static int nfs_probe_statd(void)
  	};
  	rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);
  
@@ -1092,7 +1245,7 @@ index d612427..5b515c3 100644
  				program, (rpcvers_t)1, IPPROTO_UDP);
  }
  
-@@ -901,7 +904,7 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
+@@ -901,7 +901,7 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
   */
  int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
  {
@@ -1101,7 +1254,7 @@ index d612427..5b515c3 100644
  	socklen_t salen = sizeof(mnt_server->saddr);
  	struct pmap *pmap = &mnt_server->pmap;
  	CLIENT *clnt;
-@@ -1011,11 +1014,11 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
+@@ -1011,11 +1011,11 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
  		struct sockaddr_in *caddr)
  {
  	CLIENT *clnt = NULL;
@@ -1115,7 +1268,7 @@ index d612427..5b515c3 100644
  	sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE);
  	if (sock == RPC_ANYSOCK) {
  		if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) {
-@@ -1058,18 +1061,18 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
+@@ -1058,18 +1058,18 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
  		return 0;
  	}
  	memset(&clnt_res, 0, sizeof(clnt_res));
@@ -1138,7 +1291,7 @@ index d612427..5b515c3 100644
  		return 1;
  	else
  		return 0;
-@@ -1103,13 +1106,13 @@ static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen,
+@@ -1103,13 +1103,13 @@ static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen,
  
  	switch (sap->sa_family) {
  	case AF_INET:
@@ -1154,7 +1307,7 @@ index d612427..5b515c3 100644
  			close(sock);
  			return 0;
  		}
-@@ -1518,7 +1521,11 @@ nfs_mount_protocol(struct mount_options *options, unsigned long *protocol)
+@@ -1518,7 +1518,11 @@ nfs_mount_protocol(struct mount_options *options, unsigned long *protocol)
  	 * set @protocol to zero.  The pmap protocol value will
  	 * be filled in later by an rpcbind query in this case.
  	 */
@@ -1168,10 +1321,36 @@ index d612427..5b515c3 100644
  
  /*
 diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
-index d2a4c5f..01bc712 100644
+index 55d4b55..be91a25 100644
 --- a/utils/mount/nfs.man
 +++ b/utils/mount/nfs.man
-@@ -619,7 +619,7 @@ in such cases.
+@@ -69,10 +69,9 @@ for details on specifying raw IPv6 addresses.
+ .P
+ The
+ .I fstype
+-field contains "nfs", for whatever version of the protocol.
+-The
+-.B nfs
+-allow several mount options, which are described below.
++field contains "nfs".  Use of the "nfs4" fstype in
++.I /etc/fstab
++is deprecated.
+ .SH "MOUNT OPTIONS"
+ Refer to
+ .BR mount (8)
+@@ -464,9 +463,9 @@ by other clients, but can impact application and server performance.
+ .IP
+ The DATA AND METADATA COHERENCE section contains a
+ detailed discussion of these trade-offs.
+-.SS "Options for versions 2 and 3 only"
++.SS "Options for NFS versions 2 and 3 only"
+ Use these options, along with the options in the above subsection,
+-for NFSv2/v3 only. They will be ignored for newer versions.
++for NFS versions 2 and 3 only.
+ .TP 1.5i
+ .BI proto= netid
+ The transport protocol name and protocol family the NFS client uses
+@@ -619,7 +618,7 @@ in such cases.
  .BI nfsvers= n
  The NFS protocol version number used to contact the server's NFS service.
  If the server does not support the requested version, the mount request fails.
@@ -1180,6 +1359,133 @@ index d2a4c5f..01bc712 100644
  the server, trying version 4 first, version 3 second, and version 2 last.
  .TP 1.5i
  .BI vers= n
+@@ -717,9 +716,53 @@ If this option is not specified, the NFS client uses READDIRPLUS requests
+ on NFS version 3 mounts to read small directories.
+ Some applications perform better if the client uses only READDIR requests
+ for all directories.
+-.SS "Options for version 4 only"
++.TP 1.5i
++.BR local_lock= mechanism
++Specifies whether to use local locking for any or both of the flock and the
++POSIX locking mechanisms.
++.I mechanism
++can be one of
++.BR all ,
++.BR flock ,
++.BR posix ,
++or
++.BR none .
++This option is supported in kernels 2.6.37 and later.
++.IP
++The Linux NFS client provides a way to make locks local. This means, the
++applications can lock files, but such locks provide exclusion only against
++other applications running on the same client. Remote applications are not
++affected by these locks.
++.IP
++If this option is not specified, or if
++.B none
++is specified, the client assumes that the locks are not local.
++.IP
++If
++.BR all
++is specified, the client assumes that both flock and POSIX locks are local.
++.IP
++If
++.BR flock
++is specified, the client assumes that only flock locks are local and uses
++NLM sideband protocol to lock files when POSIX locks are used.
++.IP
++If
++.BR posix
++is specified, the client assumes that POSIX locks are local and uses NLM
++sideband protocol to lock files when flock locks are used.
++.IP
++To support legacy flock behavior similar to that of NFS clients < 2.6.12, use
++'local_lock=flock'. This option is required when exporting NFS mounts via
++Samba as Samba maps Windows share mode locks as flock. Since NFS clients >
++2.6.12 implement flock by emulating POSIX locks, this will result in
++conflicting locks.
++.IP
++NOTE: When used together, the 'local_lock' mount option will be overridden
++by 'nolock'/'lock' mount option.
++.SS "Options for NFS version 4 only"
+ Use these options, along with the options in the first subsection above,
+-for NFSv4 only. They will be ignored with older versions.
++for NFS version 4 and newer.
+ .TP 1.5i
+ .BI proto= netid
+ The transport protocol name and protocol family the NFS client uses
+@@ -1480,32 +1523,54 @@ of Access Control Lists that are semantically richer than POSIX ACLs.
+ NFS version 4 ACLs are not fully compatible with POSIX ACLs; as such,
+ some translation between the two is required
+ in an environment that mixes POSIX ACLs and NFS version 4.
+-.SH FILES
+-.TP 1.5i
+-.I /etc/fstab
+-file system table
+-.SH BUGS
+-The generic
+-.B remount
+-option is not fully supported.
+-Generic options, such as
+-.BR rw " and " ro
+-can be modified using the
+-.B remount
+-option,
+-but NFS-specific options are not all supported.
++.SH "THE REMOUNT OPTION"
++Generic mount options such as
++.BR rw " and " sync
++can be modified on NFS mount points using the
++.BR remount
++option.
++See
++.BR mount (8)
++for more information on generic mount options.
++.P
++With few exceptions, NFS-specific options
++are not able to be modified during a remount.
+ The underlying transport or NFS version
+ cannot be changed by a remount, for example.
++.P
+ Performing a remount on an NFS file system mounted with the
+ .B noac
+ option may have unintended consequences.
+ The
+ .B noac
+-option is a mixture of a generic option,
++option is a combination of the generic option
+ .BR sync ,
+-and an NFS-specific option
++and the NFS-specific option
+ .BR actimeo=0 .
++.SS "Unmounting after a remount"
++For mount points that use NFS versions 2 or 3, the NFS umount subcommand
++depends on knowing the original set of mount options used to perform the
++MNT operation.
++These options are stored on disk by the NFS mount subcommand,
++and can be erased by a remount.
+ .P
++To ensure that the saved mount options are not erased during a remount,
++specify either the local mount directory, or the server hostname and
++export pathname, but not both, during a remount.  For example,
++.P
++.NF
++.TA 2.5i
++	mount -o remount,ro /mnt
++.FI
++.P
++merges the mount option
++.B ro
++with the mount options already saved on disk for the NFS server mounted at /mnt.
++.SH FILES
++.TP 1.5i
++.I /etc/fstab
++file system table
++.SH BUGS
+ Before 2.4.7, the Linux NFS client did not support NFS over TCP.
+ .P
+ Before 2.4.20, the Linux NFS client used a heuristic
 diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c
 index 1514340..02d40ff 100644
 --- a/utils/mount/nfsumount.c
@@ -1359,6 +1665,82 @@ index f0918f7..ab869d9 100644
  
  	if (options) {
  		for (option = options->tail; option; option = option->prev) {
+diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
+index 50a1a2a..ac81616 100644
+--- a/utils/mount/stropts.c
++++ b/utils/mount/stropts.c
+@@ -49,10 +49,6 @@
+ #include "parse_dev.h"
+ #include "conffile.h"
+ 
+-#ifndef HAVE_DECL_AI_ADDRCONFIG
+-#define AI_ADDRCONFIG	0
+-#endif
+-
+ #ifndef NFS_PROGRAM
+ #define NFS_PROGRAM	(100003)
+ #endif
+@@ -123,10 +119,12 @@ inline void nfs_default_version(struct nfsmount_info *mi) {}
+  * Returns a time_t timeout timestamp, in seconds.
+  */
+ static time_t nfs_parse_retry_option(struct mount_options *options,
+-				     unsigned int timeout_minutes)
++				     const time_t default_timeout)
+ {
++	time_t timeout_minutes;
+ 	long tmp;
+ 
++	timeout_minutes = default_timeout;
+ 	switch (po_get_numeric(options, "retry", &tmp)) {
+ 	case PO_NOT_FOUND:
+ 		break;
+@@ -135,6 +133,7 @@ static time_t nfs_parse_retry_option(struct mount_options *options,
+ 			timeout_minutes = tmp;
+ 			break;
+ 		}
++		/*FALLTHROUGH*/
+ 	case PO_BAD_VALUE:
+ 		if (verbose)
+ 			nfs_error(_("%s: invalid retry timeout was specified; "
+@@ -142,7 +141,7 @@ static time_t nfs_parse_retry_option(struct mount_options *options,
+ 		break;
+ 	}
+ 
+-	return time(NULL) + (time_t)(timeout_minutes * 60);
++	return time(NULL) + (timeout_minutes * 60);
+ }
+ 
+ /*
+@@ -343,7 +342,6 @@ static int nfs_validate_options(struct nfsmount_info *mi)
+ {
+ 	struct addrinfo hint = {
+ 		.ai_protocol	= (int)IPPROTO_UDP,
+-		.ai_flags	= AI_ADDRCONFIG,
+ 	};
+ 	sa_family_t family;
+ 	int error;
+@@ -570,16 +568,18 @@ static int nfs_sys_mount(struct nfsmount_info *mi, struct mount_options *opts)
+ 	char *options = NULL;
+ 	int result;
+ 
++	if (mi->fake)
++		return 1;
++
+ 	if (po_join(opts, &options) == PO_FAILED) {
+ 		errno = EIO;
+ 		return 0;
+ 	}
+ 
+-	if (mi->fake)
+-		return 1;
+-
+ 	result = mount(mi->spec, mi->node, mi->type,
+ 			mi->flags & ~(MS_USER|MS_USERS), options);
++	free(options);
++
+ 	if (verbose && result) {
+ 		int save = errno;
+ 		nfs_error(_("%s: mount(2): %s"), progname, strerror(save));
 diff --git a/utils/mount/version.h b/utils/mount/version.h
 index 46552a1..af61a6f 100644
 --- a/utils/mount/version.h
@@ -1376,3 +1758,88 @@ index 46552a1..af61a6f 100644
  	return MAKE_VERSION(p, q, r);
  }
  
+diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
+index d309950..035624c 100644
+--- a/utils/mountd/mountd.c
++++ b/utils/mountd/mountd.c
+@@ -99,12 +99,9 @@ static int version_any(void)
+ static void
+ unregister_services (void)
+ {
+-	if (version2()) {
+-		nfs_svc_unregister(MOUNTPROG, MOUNTVERS);
+-		nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX);
+-	}
+-	if (version3())
+-		nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3);
++	nfs_svc_unregister(MOUNTPROG, MOUNTVERS);
++	nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX);
++	nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3);
+ }
+ 
+ static void
+@@ -840,6 +837,7 @@ main(int argc, char **argv)
+ 	if (new_cache)
+ 		cache_open();
+ 
++	unregister_services();
+ 	if (version2()) {
+ 		listeners += nfs_svc_create("mountd", MOUNTPROG,
+ 					MOUNTVERS, mount_dispatch, port);
+diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man
+index 4bb96e8..016a357 100644
+--- a/utils/mountd/mountd.man
++++ b/utils/mountd/mountd.man
+@@ -106,11 +106,11 @@ This option can be used to request that
+ .B rpc.mountd
+ do not offer certain versions of NFS. The current version of
+ .B rpc.mountd
+-can support both NFS version 2 and the newer version 3. If the
+-NFS kernel module was compiled without support for NFSv3,
++can support both NFS version 2, 3 and 4. If the
++either one of these version should not be offered,
+ .B rpc.mountd
+ must be invoked with the option
+-.B "\-\-no-nfs-version 3" .
++.B "\-\-no-nfs-version <vers>" .
+ .TP
+ .B \-n " or " \-\-no-tcp
+ Don't advertise TCP for mount.
+diff --git a/utils/statd/hostname.c b/utils/statd/hostname.c
+index 38f2265..616a3cb 100644
+--- a/utils/statd/hostname.c
++++ b/utils/statd/hostname.c
+@@ -39,10 +39,6 @@
+ #include "statd.h"
+ #include "xlog.h"
+ 
+-#ifndef HAVE_DECL_AI_ADDRCONFIG
+-#define AI_ADDRCONFIG	0
+-#endif
+-
+ /**
+  * statd_present_address - convert sockaddr to presentation address
+  * @sap: pointer to socket address to convert
+diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c
+index 437e37a..b7f4371 100644
+--- a/utils/statd/sm-notify.c
++++ b/utils/statd/sm-notify.c
+@@ -34,10 +34,6 @@
+ #include "nsm.h"
+ #include "nfsrpc.h"
+ 
+-#ifndef HAVE_DECL_AI_ADDRCONFIG
+-#define AI_ADDRCONFIG	0
+-#endif
+-
+ #define NSM_TIMEOUT	2
+ #define NSM_MAX_TIMEOUT	120	/* don't make this too big */
+ 
+@@ -78,7 +74,6 @@ smn_lookup(const char *name)
+ {
+ 	struct addrinfo	*ai = NULL;
+ 	struct addrinfo hint = {
+-		.ai_flags	= AI_ADDRCONFIG,
+ 		.ai_family	= (nsm_family == AF_INET ? AF_INET: AF_UNSPEC),
+ 		.ai_protocol	= (int)IPPROTO_UDP,
+ 	};
diff --git a/nfs-utils-1.2.4-rc3.patch b/nfs-utils-1.2.4-rc3.patch
new file mode 100644
index 0000000..35046d7
--- /dev/null
+++ b/nfs-utils-1.2.4-rc3.patch
@@ -0,0 +1,2167 @@
+diff -up nfs-utils-1.2.3/aclocal/keyutils.m4.orig nfs-utils-1.2.3/aclocal/keyutils.m4
+--- nfs-utils-1.2.3/aclocal/keyutils.m4.orig	2010-11-29 11:18:44.168551958 -0500
++++ nfs-utils-1.2.3/aclocal/keyutils.m4	2010-11-29 11:18:44.168551958 -0500
+@@ -0,0 +1,11 @@
++dnl Checks for keyutils library and headers
++dnl
++AC_DEFUN([AC_KEYUTILS], [
++
++  dnl Check for libkeyutils; do not add to LIBS if found
++  AC_CHECK_LIB([keyutils], [keyctl_instantiate], [LIBKEYUTILS=-lkeyutils], ,)
++  AC_SUBST(LIBKEYUTILS)
++
++  AC_CHECK_HEADERS([keyutils.h], ,
++  		   [AC_MSG_ERROR([keyutils.h header not found.])])
++])dnl
+diff -up nfs-utils-1.2.3/aclocal/libnfsidmap.m4.orig nfs-utils-1.2.3/aclocal/libnfsidmap.m4
+--- nfs-utils-1.2.3/aclocal/libnfsidmap.m4.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/aclocal/libnfsidmap.m4	2010-11-29 11:18:44.168551958 -0500
+@@ -14,4 +14,8 @@ AC_DEFUN([AC_LIBNFSIDMAP], [
+                [AC_DEFINE([HAVE_NFS4_SET_DEBUG], 1,
+                           [Define to 1 if you have the `nfs4_set_debug' function.])])
+ 
++  dnl only enable nfsidmap when libnfsidmap supports it
++  AC_CHECK_LIB([nfsidmap], [nfs4_owner_to_uid], [enable_nfsidmap=yes],
++               [enable_nfsidmap=no])
++
+ ])dnl
+diff -up nfs-utils-1.2.3/configure.ac.orig nfs-utils-1.2.3/configure.ac
+--- nfs-utils-1.2.3/configure.ac.orig	2010-11-29 11:17:26.902868938 -0500
++++ nfs-utils-1.2.3/configure.ac	2010-11-29 11:18:44.169551941 -0500
+@@ -144,7 +144,7 @@ AC_ARG_ENABLE(tirpc,
+ 	[AC_HELP_STRING([--enable-tirpc],
+ 			[enable use of TI-RPC @<:@default=yes@:>@])],
+ 	enable_tirpc=$enableval,
+-	enable_tirpc='yes')
++	enable_tirpc='')
+ AC_ARG_ENABLE(ipv6,
+ 	[AC_HELP_STRING([--enable-ipv6],
+                         [enable support for IPv6 @<:@default=no@:>@])],
+@@ -255,6 +255,12 @@ if test "$enable_nfsv4" = yes; then
+   dnl check for nfsidmap libraries and headers
+   AC_LIBNFSIDMAP
+ 
++  dnl enable nfsidmap when its support by libnfsidmap
++  AM_CONDITIONAL(CONFIG_NFSIDMAP, [test "$enable_nfsidmap" = "yes"])
++
++  dnl check for the keyutils libraries and headers
++  AC_KEYUTILS
++
+   dnl librpcsecgss already has a dependency on libgssapi,
+   dnl but we need to make sure we get the right version
+   if test "$enable_gss" = yes; then
+@@ -446,6 +452,7 @@ AC_CONFIG_FILES([
+ 	utils/mountd/Makefile
+ 	utils/nfsd/Makefile
+ 	utils/nfsstat/Makefile
++	utils/nfsidmap/Makefile
+ 	utils/showmount/Makefile
+ 	utils/statd/Makefile
+ 	tests/Makefile
+diff -up nfs-utils-1.2.3/.gitignore.orig nfs-utils-1.2.3/.gitignore
+--- nfs-utils-1.2.3/.gitignore.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/.gitignore	2010-11-29 11:18:44.168551958 -0500
+@@ -64,6 +64,7 @@ tests/nsm_client/nlm_sm_inter.h
+ tests/nsm_client/nlm_sm_inter_clnt.c
+ tests/nsm_client/nlm_sm_inter_svc.c
+ tests/nsm_client/nlm_sm_inter_xdr.c
++utils/nfsidmap/nfsidmap
+ # cscope database files
+ cscope.*
+ # generic editor backup et al
+diff -up nfs-utils-1.2.3/support/export/client.c.orig nfs-utils-1.2.3/support/export/client.c
+--- nfs-utils-1.2.3/support/export/client.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/support/export/client.c	2010-11-29 11:18:44.170551927 -0500
+@@ -178,6 +178,7 @@ out_badprefix:
+ static int
+ init_netmask6(nfs_client *UNUSED(clp), const char *UNUSED(slash))
+ {
++	return 0;
+ }
+ #endif	/* IPV6_SUPPORTED */
+ 
+diff -up nfs-utils-1.2.3/support/export/export.c.orig nfs-utils-1.2.3/support/export/export.c
+--- nfs-utils-1.2.3/support/export/export.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/support/export/export.c	2010-11-29 11:18:44.170551927 -0500
+@@ -38,6 +38,7 @@ export_free(nfs_export *exp)
+ 	xfree(exp->m_export.e_sqgids);
+ 	free(exp->m_export.e_mountpoint);
+ 	free(exp->m_export.e_fslocdata);
++	free(exp->m_export.e_uuid);
+ 
+ 	xfree(exp->m_export.e_hostname);
+ 	xfree(exp);
+diff -up nfs-utils-1.2.3/support/export/hostname.c.orig nfs-utils-1.2.3/support/export/hostname.c
+--- nfs-utils-1.2.3/support/export/hostname.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/support/export/hostname.c	2010-11-29 11:18:44.171551914 -0500
+@@ -30,10 +30,6 @@
+ #include "sockaddr.h"
+ #include "exportfs.h"
+ 
+-#ifndef HAVE_DECL_AI_ADDRCONFIG
+-#define AI_ADDRCONFIG	0
+-#endif
+-
+ /**
+  * host_ntop - generate presentation address given a sockaddr
+  * @sap: pointer to socket address
+@@ -170,7 +166,7 @@ host_addrinfo(const char *hostname)
+ #endif
+ 		/* don't return duplicates */
+ 		.ai_protocol	= (int)IPPROTO_UDP,
+-		.ai_flags	= AI_ADDRCONFIG | AI_CANONNAME,
++		.ai_flags	= AI_CANONNAME,
+ 	};
+ 	int error;
+ 
+diff -up nfs-utils-1.2.3/support/include/nfslib.h.orig nfs-utils-1.2.3/support/include/nfslib.h
+--- nfs-utils-1.2.3/support/include/nfslib.h.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/support/include/nfslib.h	2010-11-29 11:18:44.172551902 -0500
+@@ -163,6 +163,12 @@ void closeall(int min);
+ int			svctcp_socket (u_long __number, int __reuse);
+ int			svcudp_socket (u_long __number);
+ 
++/* Misc shared code prototypes */
++size_t  strlcat(char *, const char *, size_t);
++size_t  strlcpy(char *, const char *, size_t);
++ssize_t atomicio(ssize_t (*f) (int, void*, size_t),
++		 int, void *, size_t);
++
+ 
+ #define UNUSED(x) UNUSED_ ## x __attribute__((unused))
+ 
+diff -up nfs-utils-1.2.3/support/nfs/atomicio.c.orig nfs-utils-1.2.3/support/nfs/atomicio.c
+--- nfs-utils-1.2.3/support/nfs/atomicio.c.orig	2010-11-29 11:18:44.173551890 -0500
++++ nfs-utils-1.2.3/support/nfs/atomicio.c	2010-11-29 11:18:44.173551890 -0500
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2002 Marius Aamodt Eriksen <marius at monkey.org>
++ * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <sys/types.h>
++#include <unistd.h>
++#include <errno.h>
++
++/*
++ * ensure all of data on socket comes through. f==read || f==write
++ */
++ssize_t atomicio(ssize_t(*f) (int, void *, size_t), int fd, void *_s, size_t n)
++{
++	char *s = _s;
++	ssize_t res, pos = 0;
++
++	while ((ssize_t)n > pos) {
++		res = (f) (fd, s + pos, n - pos);
++		switch (res) {
++		case -1:
++			if (errno == EINTR || errno == EAGAIN)
++				continue;
++		case 0:
++			if (pos != 0)
++				return pos;
++			return res;
++		default:
++			pos += res;
++		}
++	}
++	return pos;
++}
+diff -up nfs-utils-1.2.3/support/nfs/conffile.c.orig nfs-utils-1.2.3/support/nfs/conffile.c
+--- nfs-utils-1.2.3/support/nfs/conffile.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/support/nfs/conffile.c	2010-11-29 11:18:44.174551888 -0500
+@@ -271,9 +271,9 @@ conf_parse_line(int trans, char *line, s
+ 		if (ptr == NULL)
+ 			return;
+ 		line = ++ptr;
+-		while (*ptr && *ptr != '"')
++		while (*ptr && *ptr != '"' && *ptr != ']')
+ 			ptr++;
+-		if (*ptr == '\0') {
++		if (*ptr == '\0' || *ptr == ']') {
+ 			xlog_warn("config file error: line %d: "
+  				"non-matched '\"', ignoring until next section", ln);
+ 		}  else {
+diff -up nfs-utils-1.2.3/support/nfs/exports.c.orig nfs-utils-1.2.3/support/nfs/exports.c
+--- nfs-utils-1.2.3/support/nfs/exports.c.orig	2010-11-29 11:17:26.906868973 -0500
++++ nfs-utils-1.2.3/support/nfs/exports.c	2010-11-29 11:18:44.174551888 -0500
+@@ -332,6 +332,8 @@ dupexportent(struct exportent *dst, stru
+ 		dst->e_mountpoint = strdup(src->e_mountpoint);
+ 	if (src->e_fslocdata)
+ 		dst->e_fslocdata = strdup(src->e_fslocdata);
++	if (src->e_uuid)
++		dst->e_uuid = strdup(src->e_uuid);
+ 	dst->e_hostname = NULL;
+ }
+ 
+diff -up nfs-utils-1.2.3/support/nfs/Makefile.am.orig nfs-utils-1.2.3/support/nfs/Makefile.am
+--- nfs-utils-1.2.3/support/nfs/Makefile.am.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/support/nfs/Makefile.am	2010-11-29 11:18:44.172551902 -0500
+@@ -5,7 +5,7 @@ libnfs_a_SOURCES = exports.c rmtab.c xio
+ 		   xlog.c xcommon.c wildmat.c nfsclient.c \
+ 		   nfsexport.c getfh.c nfsctl.c rpc_socket.c getport.c \
+ 		   svc_socket.c cacheio.c closeall.c nfs_mntent.c conffile.c \
+-		   svc_create.c
++		   svc_create.c atomicio.c strlcpy.c strlcat.c
+ 
+ MAINTAINERCLEANFILES = Makefile.in
+ 
+diff -up nfs-utils-1.2.3/support/nfs/strlcat.c.orig nfs-utils-1.2.3/support/nfs/strlcat.c
+--- nfs-utils-1.2.3/support/nfs/strlcat.c.orig	2010-11-29 11:18:44.175551873 -0500
++++ nfs-utils-1.2.3/support/nfs/strlcat.c	2010-11-29 11:18:44.175551873 -0500
+@@ -0,0 +1,76 @@
++/*	$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $	*/
++
++/*
++ * Copyright (c) 1998 Todd C. Miller <Todd.Miller at courtesan.com>
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. The name of the author may not be used to endorse or promote products
++ *    derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
++ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
++ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
++ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if defined(LIBC_SCCS) && !defined(lint)
++static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $";
++#endif /* LIBC_SCCS and not lint */
++
++#include <sys/types.h>
++#include <string.h>
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif /* HAVE_CONFIG_H */
++
++/*
++ * Appends src to string dst of size siz (unlike strncat, siz is the
++ * full size of dst, not space left).  At most siz-1 characters
++ * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
++ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
++ * If retval >= siz, truncation occurred.
++ */
++size_t
++strlcat(char *dst,
++	const char *src,
++	size_t siz)
++{
++	register char *d = dst;
++	register const char *s = src;
++	register size_t n = siz;
++	size_t dlen;
++
++	/* Find the end of dst and adjust bytes left but don't go past end */
++	while (n-- != 0 && *d != '\0')
++		d++;
++	dlen = d - dst;
++	n = siz - dlen;
++
++	if (n == 0)
++		return(dlen + strlen(s));
++	while (*s != '\0') {
++		if (n != 1) {
++			*d++ = *s;
++			n--;
++		}
++		s++;
++	}
++	*d = '\0';
++
++	return(dlen + (s - src));	/* count does not include NUL */
++}
+diff -up nfs-utils-1.2.3/support/nfs/strlcpy.c.orig nfs-utils-1.2.3/support/nfs/strlcpy.c
+--- nfs-utils-1.2.3/support/nfs/strlcpy.c.orig	2010-11-29 11:18:44.175551873 -0500
++++ nfs-utils-1.2.3/support/nfs/strlcpy.c	2010-11-29 11:18:44.175551873 -0500
+@@ -0,0 +1,72 @@
++/*	$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $	*/
++
++/*
++ * Copyright (c) 1998 Todd C. Miller <Todd.Miller at courtesan.com>
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. The name of the author may not be used to endorse or promote products
++ *    derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
++ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
++ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
++ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if defined(LIBC_SCCS) && !defined(lint)
++static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $";
++#endif /* LIBC_SCCS and not lint */
++
++#include <sys/types.h>
++#include <string.h>
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif /* HAVE_CONFIG_H */
++
++/*
++ * Copy src to string dst of size siz.  At most siz-1 characters
++ * will be copied.  Always NUL terminates (unless siz == 0).
++ * Returns strlen(src); if retval >= siz, truncation occurred.
++ */
++size_t
++strlcpy(char *dst,
++	const char *src,
++	size_t siz)
++{
++	register char *d = dst;
++	register const char *s = src;
++	register size_t n = siz;
++
++	/* Copy as many bytes as will fit */
++	if (n != 0 && --n != 0) {
++		do {
++			if ((*d++ = *s++) == 0)
++				break;
++		} while (--n != 0);
++	}
++
++	/* Not enough room in dst, add NUL and traverse rest of src */
++	if (n == 0) {
++		if (siz != 0)
++			*d = '\0';		/* NUL-terminate dst */
++		while (*s++)
++			;
++	}
++
++	return(s - src - 1);	/* count does not include NUL */
++}
+diff -up nfs-utils-1.2.3/support/nfs/svc_create.c.orig nfs-utils-1.2.3/support/nfs/svc_create.c
+--- nfs-utils-1.2.3/support/nfs/svc_create.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/support/nfs/svc_create.c	2010-11-29 11:18:44.176551853 -0500
+@@ -27,6 +27,7 @@
+ #include <memory.h>
+ #include <signal.h>
+ #include <unistd.h>
++#include <errno.h>
+ #include <netdb.h>
+ 
+ #include <netinet/in.h>
+@@ -41,11 +42,68 @@
+ #include "tcpwrapper.h"
+ #endif
+ 
++#include "sockaddr.h"
+ #include "rpcmisc.h"
+ #include "xlog.h"
+ 
+ #ifdef HAVE_LIBTIRPC
+ 
++#define SVC_CREATE_XPRT_CACHE_SIZE	(8)
++static SVCXPRT *svc_create_xprt_cache[SVC_CREATE_XPRT_CACHE_SIZE] = { NULL, };
++
++/*
++ * Cache an SVC xprt, in case there are more programs or versions to
++ * register against it.
++ */
++static void
++svc_create_cache_xprt(SVCXPRT *xprt)
++{
++	unsigned int i;
++
++	/* Check if we've already got this one... */
++	for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++)
++		if (svc_create_xprt_cache[i] == xprt)
++			return;
++
++	/* No, we don't.  Cache it. */
++	for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++)
++		if (svc_create_xprt_cache[i] == NULL) {
++			svc_create_xprt_cache[i] = xprt;
++			return;
++		}
++
++	xlog(L_ERROR, "%s: Failed to cache an xprt", __func__);
++}
++
++/*
++ * Find a previously cached SVC xprt structure with the given bind address
++ * and transport semantics.
++ *
++ * Returns pointer to a cached SVC xprt.
++ *
++ * If no matching SVC XPRT can be found, NULL is returned.
++ */
++static SVCXPRT *
++svc_create_find_xprt(const struct sockaddr *bindaddr, const struct netconfig *nconf)
++{
++	unsigned int i;
++
++	for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++) {
++		SVCXPRT *xprt = svc_create_xprt_cache[i];
++		struct sockaddr *sap;
++
++		if (xprt == NULL)
++			continue;
++		if (strcmp(nconf->nc_netid, xprt->xp_netid) != 0)
++			continue;
++		sap = (struct sockaddr *)xprt->xp_ltaddr.buf;
++		if (!nfs_compare_sockaddr(bindaddr, sap))
++			continue;
++		return xprt;
++	}
++	return NULL;
++}
++
+ /*
+  * Set up an appropriate bind address, given @port and @nconf.
+  *
+@@ -98,17 +156,113 @@ svc_create_bindaddr(struct netconfig *nc
+ 	return ai;
+ }
+ 
++/*
++ * Create a listener socket on a specific bindaddr, and set
++ * special socket options to allow it to share the same port
++ * as other listeners.
++ *
++ * Returns an open, bound, and possibly listening network
++ * socket on success.
++ *
++ * Otherwise returns -1 if some error occurs.
++ */
++static int
++svc_create_sock(const struct sockaddr *sap, socklen_t salen,
++		struct netconfig *nconf)
++{
++	int fd, type, protocol;
++	int one = 1;
++
++	switch(nconf->nc_semantics) {
++	case NC_TPI_CLTS:
++		type = SOCK_DGRAM;
++		break;
++	case NC_TPI_COTS_ORD:
++		type = SOCK_STREAM;
++		break;
++	default:
++		xlog(D_GENERAL, "%s: Unrecognized bind address semantics: %u",
++			__func__, nconf->nc_semantics);
++		return -1;
++	}
++
++	if (strcmp(nconf->nc_proto, NC_UDP) == 0)
++		protocol = (int)IPPROTO_UDP;
++	else if (strcmp(nconf->nc_proto, NC_TCP) == 0)
++		protocol = (int)IPPROTO_TCP;
++	else {
++		xlog(D_GENERAL, "%s: Unrecognized bind address protocol: %s",
++			__func__, nconf->nc_proto);
++		return -1;
++	}
++
++	fd = socket((int)sap->sa_family, type, protocol);
++	if (fd == -1) {
++		xlog(L_ERROR, "Could not make a socket: (%d) %m",
++			errno);
++		return -1;
++	}
++
++#ifdef IPV6_SUPPORTED
++	if (sap->sa_family == AF_INET6) {
++		if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
++				&one, sizeof(one)) == -1) {
++			xlog(L_ERROR, "Failed to set IPV6_V6ONLY: (%d) %m",
++				errno);
++			(void)close(fd);
++			return -1;
++		}
++	}
++#endif	/* IPV6_SUPPORTED */
++
++	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
++		       &one, sizeof(one)) == -1) {
++		xlog(L_ERROR, "Failed to set SO_REUSEADDR: (%d) %m",
++			errno);
++		(void)close(fd);
++		return -1;
++	}
++
++	if (bind(fd, sap, salen) == -1) {
++		xlog(L_ERROR, "Could not bind socket: (%d) %m",
++			errno);
++		(void)close(fd);
++		return -1;
++	}
++
++	if (nconf->nc_semantics == NC_TPI_COTS_ORD)
++		if (listen(fd, SOMAXCONN) == -1) {
++			xlog(L_ERROR, "Could not listen on socket: (%d) %m",
++				errno);
++			(void)close(fd);
++			return -1;
++		}
++
++	return fd;
++}
++
++/*
++ * The simple case is allowing the TI-RPC library to create a
++ * transport itself, given just the bind address and transport
++ * semantics.
++ *
++ * Our local xprt cache is ignored in this path, since the
++ * caller is not interested in sharing listeners or ports, and
++ * the library automatically avoids ports already in use.
++ *
++ * Returns the count of started listeners (one or zero).
++ */
+ static unsigned int
+-svc_create_nconf(const char *name, const rpcprog_t program,
++svc_create_nconf_rand_port(const char *name, const rpcprog_t program,
+ 		const rpcvers_t version,
+ 		void (*dispatch)(struct svc_req *, SVCXPRT *),
+-		const uint16_t port, struct netconfig *nconf)
++		struct netconfig *nconf)
+ {
+ 	struct t_bind bindaddr;
+ 	struct addrinfo *ai;
+ 	SVCXPRT	*xprt;
+ 
+-	ai = svc_create_bindaddr(nconf, port);
++	ai = svc_create_bindaddr(nconf, 0);
+ 	if (ai == NULL)
+ 		return 0;
+ 
+@@ -119,7 +273,7 @@ svc_create_nconf(const char *name, const
+ 	freeaddrinfo(ai);
+ 	if (xprt == NULL) {
+ 		xlog(D_GENERAL, "Failed to create listener xprt "
+-				"(%s, %u, %s)", name, version, nconf->nc_netid);
++			"(%s, %u, %s)", name, version, nconf->nc_netid);
+ 		return 0;
+ 	}
+ 
+@@ -133,6 +287,93 @@ svc_create_nconf(const char *name, const
+ 	return 1;
+ }
+ 
++/*
++ * If a port is specified on the command line, that port value will be
++ * the same for all listeners created here.  Create each listener
++ * socket in advance and set SO_REUSEADDR, rather than allowing the
++ * RPC library to create the listeners for us on a randomly chosen
++ * port via svc_tli_create(RPC_ANYFD).
++ *
++ * Some callers want to listen for more than one RPC version using the
++ * same port number.  For example, mountd could want to listen for MNT
++ * version 1, 2, and 3 requests.  This means mountd must use the same
++ * set of listener sockets for multiple RPC versions, since, on one
++ * system, you can't have two listener sockets with the exact same
++ * bind address (and port) and transport protocol.
++ *
++ * To accomplish this, this function caches xprts as they are created.
++ * This cache is checked to see if a previously created xprt can be
++ * used, before creating a new xprt for this [program, version].  If
++ * there is a cached xprt with the same bindaddr and transport
++ * semantics, we simply register the new version with that xprt,
++ * rather than creating a fresh xprt for it.
++ *
++ * The xprt cache implemented here is local to a process.  Two
++ * separate RPC daemons can not share a set of listeners.
++ *
++ * Returns the count of started listeners (one or zero).
++ */
++static unsigned int
++svc_create_nconf_fixed_port(const char *name, const rpcprog_t program,
++		const rpcvers_t version,
++		void (*dispatch)(struct svc_req *, SVCXPRT *),
++		const uint16_t port, struct netconfig *nconf)
++{
++	struct addrinfo *ai;
++	SVCXPRT	*xprt;
++
++	ai = svc_create_bindaddr(nconf, port);
++	if (ai == NULL)
++		return 0;
++
++	xprt = svc_create_find_xprt(ai->ai_addr, nconf);
++	if (xprt == NULL) {
++		int fd;
++
++		fd = svc_create_sock(ai->ai_addr, ai->ai_addrlen, nconf);
++		if (fd == -1)
++			goto out_free;
++
++		xprt = svc_tli_create(fd, nconf, NULL, 0, 0);
++		if (xprt == NULL) {
++			xlog(D_GENERAL, "Failed to create listener xprt "
++				"(%s, %u, %s)", name, version, nconf->nc_netid);
++			(void)close(fd);
++			goto out_free;
++		}
++	}
++
++	if (!svc_reg(xprt, program, version, dispatch, nconf)) {
++		/* svc_reg(3) destroys @xprt in this case */
++		xlog(D_GENERAL, "Failed to register (%s, %u, %s)",
++				name, version, nconf->nc_netid);
++		goto out_free;
++	}
++
++	svc_create_cache_xprt(xprt);
++
++	freeaddrinfo(ai);
++	return 1;
++
++out_free:
++	freeaddrinfo(ai);
++	return 0;
++}
++
++static unsigned int
++svc_create_nconf(const char *name, const rpcprog_t program,
++		const rpcvers_t version,
++		void (*dispatch)(struct svc_req *, SVCXPRT *),
++		const uint16_t port, struct netconfig *nconf)
++{
++	if (port != 0)
++		return svc_create_nconf_fixed_port(name, program,
++			version, dispatch, port, nconf);
++
++	return svc_create_nconf_rand_port(name, program,
++			version, dispatch, nconf);
++}
++
+ /**
+  * nfs_svc_create - start up RPC svc listeners
+  * @name: C string containing name of new service
+@@ -145,8 +386,7 @@ svc_create_nconf(const char *name, const
+  * the RPC dispatcher.  Returns the number of started network transports.
+  */
+ unsigned int
+-nfs_svc_create(__attribute__((unused)) char *name,
+-		const rpcprog_t program, const rpcvers_t version,
++nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version,
+ 		void (*dispatch)(struct svc_req *, SVCXPRT *),
+ 		const uint16_t port)
+ {
+diff -up nfs-utils-1.2.3/tests/nsm_client/nsm_client.c.orig nfs-utils-1.2.3/tests/nsm_client/nsm_client.c
+--- nfs-utils-1.2.3/tests/nsm_client/nsm_client.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/tests/nsm_client/nsm_client.c	2010-11-29 11:18:44.177551833 -0500
+@@ -205,7 +205,7 @@ nsm_client_get_rpcclient(const char *nod
+ {
+ 	unsigned short		port;
+ 	struct addrinfo		*ai;
+-	struct addrinfo		hints = { .ai_flags	= AI_ADDRCONFIG };
++	struct addrinfo		hints = { };
+ 	int			err;
+ 	CLIENT			*client = NULL;
+ 
+diff -up nfs-utils-1.2.3/utils/exportfs/exports.man.orig nfs-utils-1.2.3/utils/exportfs/exports.man
+--- nfs-utils-1.2.3/utils/exportfs/exports.man.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/exportfs/exports.man	2010-11-29 11:18:48.351597145 -0500
+@@ -145,7 +145,9 @@ storage (see
+ .IR async
+ above).
+ 
+-In releases of nfs-utils up to and including 1.0.0, this option was the
++In releases of nfs-utils up to and including 1.0.0, the
++.I async 
++option was the
+ default.  In all releases after 1.0.0,
+ .I sync
+ is the default, and
+@@ -375,20 +377,6 @@ If the client asks for alternative locat
+ will be given this list of alternatives. (Note that actual replication
+ of the filesystem must be handled elsewhere.)
+ 
+-.TP
+-.IR refer= path at host[+host][:path at host[+host]]
+-A client referencing the export point will be directed to choose from
+-the given list an alternative location for the filesystem.
+-(Note that the server must have a mountpoint here, though a different
+-filesystem is not required; so, for example,
+-.IR "mount --bind" " /path /path"
+-is sufficient.)
+-.TP
+-.IR replicas= path at host[+host][:path at host[+host]]
+-If the client asks for alternative locations for the export point, it
+-will be given this list of alternatives. (Note that actual replication
+-of the filesystem must be handled elsewhere.)
+-
+ .SS User ID Mapping
+ .PP
+ .B nfsd
+diff -up nfs-utils-1.2.3/utils/idmapd/idmapd.c.orig nfs-utils-1.2.3/utils/idmapd/idmapd.c
+--- nfs-utils-1.2.3/utils/idmapd/idmapd.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/idmapd/idmapd.c	2010-11-29 11:18:48.353596932 -0500
+@@ -158,10 +158,6 @@ static int nfsdopenone(struct idmap_clie
+ static void nfsdreopen_one(struct idmap_client *);
+ static void nfsdreopen(void);
+ 
+-size_t  strlcat(char *, const char *, size_t);
+-size_t  strlcpy(char *, const char *, size_t);
+-ssize_t atomicio(ssize_t (*f) (int, void*, size_t),
+-		 int, void *, size_t);
+ void    mydaemon(int, int);
+ void    release_parent(void);
+ 
+diff -up nfs-utils-1.2.3/utils/idmapd/Makefile.am.orig nfs-utils-1.2.3/utils/idmapd/Makefile.am
+--- nfs-utils-1.2.3/utils/idmapd/Makefile.am.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/idmapd/Makefile.am	2010-11-29 11:18:48.352597045 -0500
+@@ -11,12 +11,8 @@ EXTRA_DIST = \
+ 	idmapd.conf
+ 
+ idmapd_SOURCES = \
+-	atomicio.c \
+ 	idmapd.c \
+-	strlcat.c \
+-	strlcpy.c \
+ 	\
+-	cfg.h \
+ 	nfs_idmap.h \
+ 	queue.h
+ 
+diff -up nfs-utils-1.2.3/utils/Makefile.am.orig nfs-utils-1.2.3/utils/Makefile.am
+--- nfs-utils-1.2.3/utils/Makefile.am.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/Makefile.am	2010-11-29 11:18:48.351597145 -0500
+@@ -4,6 +4,9 @@ OPTDIRS =
+ 
+ if CONFIG_NFSV4
+ OPTDIRS += idmapd
++if CONFIG_NFSIDMAP
++OPTDIRS += nfsidmap
++endif
+ endif
+ 
+ if CONFIG_GSS
+diff -up nfs-utils-1.2.3/utils/mountd/mountd.c.orig nfs-utils-1.2.3/utils/mountd/mountd.c
+--- nfs-utils-1.2.3/utils/mountd/mountd.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mountd/mountd.c	2010-11-29 11:18:48.362595959 -0500
+@@ -99,12 +99,9 @@ static int version_any(void)
+ static void
+ unregister_services (void)
+ {
+-	if (version2()) {
+-		nfs_svc_unregister(MOUNTPROG, MOUNTVERS);
+-		nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX);
+-	}
+-	if (version3())
+-		nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3);
++	nfs_svc_unregister(MOUNTPROG, MOUNTVERS);
++	nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX);
++	nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3);
+ }
+ 
+ static void
+@@ -840,6 +837,7 @@ main(int argc, char **argv)
+ 	if (new_cache)
+ 		cache_open();
+ 
++	unregister_services();
+ 	if (version2()) {
+ 		listeners += nfs_svc_create("mountd", MOUNTPROG,
+ 					MOUNTVERS, mount_dispatch, port);
+diff -up nfs-utils-1.2.3/utils/mountd/mountd.man.orig nfs-utils-1.2.3/utils/mountd/mountd.man
+--- nfs-utils-1.2.3/utils/mountd/mountd.man.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mountd/mountd.man	2010-11-29 11:18:48.362595959 -0500
+@@ -106,11 +106,11 @@ This option can be used to request that
+ .B rpc.mountd
+ do not offer certain versions of NFS. The current version of
+ .B rpc.mountd
+-can support both NFS version 2 and the newer version 3. If the
+-NFS kernel module was compiled without support for NFSv3,
++can support both NFS version 2, 3 and 4. If the
++either one of these version should not be offered,
+ .B rpc.mountd
+ must be invoked with the option
+-.B "\-\-no-nfs-version 3" .
++.B "\-\-no-nfs-version <vers>" .
+ .TP
+ .B \-n " or " \-\-no-tcp
+ Don't advertise TCP for mount.
+diff -up nfs-utils-1.2.3/utils/mount/fstab.c.orig nfs-utils-1.2.3/utils/mount/fstab.c
+--- nfs-utils-1.2.3/utils/mount/fstab.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/fstab.c	2010-11-29 11:18:48.354596817 -0500
+@@ -364,19 +364,22 @@ lock_mtab (void) {
+ 	/* Repeat until it was us who made the link */
+ 	while (!we_created_lockfile) {
+ 		struct flock flock;
+-		int errsv, j;
++		int j;
+ 
+ 		j = link(linktargetfile, MOUNTED_LOCK);
+-		errsv = errno;
+ 
+-		if (j == 0)
+-			we_created_lockfile = 1;
++		{
++			int errsv = errno;
+ 
+-		if (j < 0 && errsv != EEXIST) {
+-			(void) unlink(linktargetfile);
+-			die (EX_FILEIO, _("can't link lock file %s: %s "
+-			     "(use -n flag to override)"),
+-			     MOUNTED_LOCK, strerror (errsv));
++			if (j == 0)
++				we_created_lockfile = 1;
++
++			if (j < 0 && errsv != EEXIST) {
++				(void) unlink(linktargetfile);
++				die (EX_FILEIO, _("can't link lock file %s: %s "
++				     "(use -n flag to override)"),
++				     MOUNTED_LOCK, strerror (errsv));
++			}
+ 		}
+ 
+ 		lockfile_fd = open (MOUNTED_LOCK, O_WRONLY);
+@@ -414,7 +417,7 @@ lock_mtab (void) {
+ 			}
+ 			(void) unlink(linktargetfile);
+ 		} else {
+-			static int tries = 0;
++			static int retries = 0;
+ 
+ 			/* Someone else made the link. Wait. */
+ 			alarm(LOCK_TIMEOUT);
+@@ -428,10 +431,10 @@ lock_mtab (void) {
+ 			alarm(0);
+ 			/* Limit the number of iterations - maybe there
+ 			   still is some old /etc/mtab~ */
+-			++tries;
+-			if (tries % 200 == 0)
++			++retries;
++			if (retries % 200 == 0)
+ 			   usleep(30);
+-			if (tries > 100000) {
++			if (retries > 100000) {
+ 				(void) unlink(linktargetfile);
+ 				close(lockfile_fd);
+ 				die (EX_FILEIO, _("Cannot create link %s\n"
+diff -up nfs-utils-1.2.3/utils/mount/mount_config.h.orig nfs-utils-1.2.3/utils/mount/mount_config.h
+--- nfs-utils-1.2.3/utils/mount/mount_config.h.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/mount_config.h	2010-11-29 11:18:48.355596703 -0500
+@@ -1,7 +1,7 @@
+-#ifndef _LINUX_MOUNT__CONFIG_H
+-#define _LINUX_MOUNT_CONFIG__H
++#ifndef _LINUX_MOUNT_CONFIG_H
++#define _LINUX_MOUNT_CONFIG_H
+ /*
+- * mount_config.h -- mount configuration file routines 
++ * mount_config.h -- mount configuration file routines
+  * Copyright (C) 2008 Red Hat, Inc <nfs at redhat.com>
+  *
+  * This program is free software; you can redistribute it and/or modify
+@@ -16,15 +16,13 @@
+  *
+  */
+ 
+-inline void mount_config_init(char *);
+-
+ #ifdef MOUNT_CONFIG
+ #include "conffile.h"
+ #include "xlog.h"
+ 
+ extern char *conf_get_mntopts(char *, char *, char *);
+ 
+-inline void mount_config_init(char *program)
++static inline void mount_config_init(char *program)
+ {
+ 	xlog_open(program);
+ 	/*
+@@ -32,19 +30,22 @@ inline void mount_config_init(char *prog
+ 	 */
+ 	conf_init();
+ }
+-inline char *mount_config_opts(char *spec, 
++
++static inline char *mount_config_opts(char *spec,
+ 		char *mount_point, char *mount_opts)
+ {
+ 	return conf_get_mntopts(spec, mount_point, mount_opts);
+ }
++
+ #else /* MOUNT_CONFIG */
+ 
+-inline void mount_config_init(char *program) { }
++static inline void mount_config_init(char *program) { }
+ 
+-inline char *mount_config_opts(char *spec, 
++static inline char *mount_config_opts(char *spec,
+ 		char *mount_point, char *mount_opts)
+ {
+ 	return mount_opts;
+ }
+ #endif /* MOUNT_CONFIG */
+-#endif
++
++#endif	/* _LINUX_MOUNT_CONFIG_H */
+diff -up nfs-utils-1.2.3/utils/mount/mount_constants.h.orig nfs-utils-1.2.3/utils/mount/mount_constants.h
+--- nfs-utils-1.2.3/utils/mount/mount_constants.h.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/mount_constants.h	2010-11-29 11:18:48.355596703 -0500
+@@ -64,4 +64,8 @@ if we have a stack or plain mount - moun
+ #define MS_MGC_MSK 0xffff0000	/* magic flag number mask */
+ #endif
+ 
++/* Generic options that are prevented from appearing
++ * in the options field in /etc/mtab. */
++#define MS_NOMTAB	(MS_REMOUNT)
++
+ #endif	/* _NFS_UTILS_MOUNT_CONSTANTS_H */
+diff -up nfs-utils-1.2.3/utils/mount/mount.c.orig nfs-utils-1.2.3/utils/mount/mount.c
+--- nfs-utils-1.2.3/utils/mount/mount.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/mount.c	2010-11-29 11:18:48.354596817 -0500
+@@ -209,7 +209,7 @@ static char *fix_opts_string(int flags, 
+ 	}
+ 	if (flags & MS_USERS)
+ 		new_opts = xstrconcat3(new_opts, ",users", "");
+-	
++
+ 	for (om = opt_map; om->opt != NULL; om++) {
+ 		if (om->skip)
+ 			continue;
+@@ -224,6 +224,20 @@ static char *fix_opts_string(int flags, 
+ 	return new_opts;
+ }
+ 
++static void
++init_mntent(struct mntent *mnt, char *fsname, char *dir, char *type,
++		int flags, char *opts)
++{
++	mnt->mnt_fsname	= fsname;
++	mnt->mnt_dir	= dir;
++	mnt->mnt_type	= type;
++	mnt->mnt_opts	= fix_opts_string(flags & ~MS_NOMTAB, opts);
++
++	/* these are always zero for NFS */
++	mnt->mnt_freq	= 0;
++	mnt->mnt_passno	= 0;
++}
++
+ /* Create mtab with a root entry.  */
+ static void
+ create_mtab (void) {
+@@ -245,11 +259,8 @@ create_mtab (void) {
+ 	if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
+ 		char *extra_opts;
+ 		parse_opts (fstab->m.mnt_opts, &flags, &extra_opts);
+-		mnt.mnt_dir = "/";
+-		mnt.mnt_fsname = xstrdup(fstab->m.mnt_fsname);
+-		mnt.mnt_type = fstab->m.mnt_type;
+-		mnt.mnt_opts = fix_opts_string (flags, extra_opts);
+-		mnt.mnt_freq = mnt.mnt_passno = 0;
++		init_mntent(&mnt, xstrdup(fstab->m.mnt_fsname), "/",
++				fstab->m.mnt_type, flags, extra_opts);
+ 		free(extra_opts);
+ 
+ 		if (nfs_addmntent (mfp, &mnt) == 1) {
+@@ -273,17 +284,12 @@ create_mtab (void) {
+ }
+ 
+ static int add_mtab(char *spec, char *mount_point, char *fstype,
+-			int flags, char *opts, int freq, int pass)
++			int flags, char *opts)
+ {
+ 	struct mntent ment;
+ 	int result = EX_SUCCESS;
+ 
+-	ment.mnt_fsname = spec;
+-	ment.mnt_dir = mount_point;
+-	ment.mnt_type = fstype;
+-	ment.mnt_opts = fix_opts_string(flags, opts);
+-	ment.mnt_freq = freq;
+-	ment.mnt_passno = pass;
++	init_mntent(&ment, spec, mount_point, fstype, flags, opts);
+ 
+ 	if (!nomtab && mtab_does_not_exist()) {
+ 		if (verbose > 1)
+@@ -321,7 +327,7 @@ static int add_mtab(char *spec, char *mo
+ 	return result;
+ }
+ 
+-void mount_usage(void)
++static void mount_usage(void)
+ {
+ 	printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"),
+ 		progname);
+@@ -337,7 +343,7 @@ void mount_usage(void)
+ 	printf(_("\tnfsoptions\tRefer to mount.nfs(8) or nfs(5)\n\n"));
+ }
+ 
+-static void parse_opt(const char *opt, int *mask, char *extra_opts, int len)
++static void parse_opt(const char *opt, int *mask, char *extra_opts, size_t len)
+ {
+ 	const struct opt_map *om;
+ 
+@@ -371,7 +377,7 @@ static void parse_opts(const char *optio
+ 	if (options != NULL) {
+ 		char *opts = xstrdup(options);
+ 		char *opt, *p;
+-		int len = strlen(opts) + 1;	/* include room for a null */
++		size_t len = strlen(opts) + 1;	/* include room for a null */
+ 		int open_quote = 0;
+ 
+ 		*extra_opts = xmalloc(len);
+@@ -441,9 +447,7 @@ static int try_mount(char *spec, char *m
+ 	if (!fake)
+ 		print_one(spec, mount_point, fs_type, mount_opts);
+ 
+-	ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts,
+-			0, 0 /* these are always zero for NFS */ );
+-	return ret;
++	return add_mtab(spec, mount_point, fs_type, flags, *extra_opts);
+ }
+ 
+ int main(int argc, char *argv[])
+diff -up nfs-utils-1.2.3/utils/mount/network.c.orig nfs-utils-1.2.3/utils/mount/network.c
+--- nfs-utils-1.2.3/utils/mount/network.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/network.c	2010-11-29 11:18:48.357596482 -0500
+@@ -59,6 +59,8 @@
+ #define CONNECT_TIMEOUT	(20)
+ #define MOUNT_TIMEOUT	(30)
+ 
++#define SAFE_SOCKADDR(x)	(struct sockaddr *)(char *)(x)
++
+ extern int nfs_mount_data_version;
+ extern char *progname;
+ extern int verbose;
+@@ -208,9 +210,6 @@ int nfs_lookup(const char *hostname, con
+ {
+ 	struct addrinfo *gai_results;
+ 	struct addrinfo gai_hint = {
+-#ifdef HAVE_DECL_AI_ADDRCONFIG
+-		.ai_flags	= AI_ADDRCONFIG,
+-#endif	/* HAVE_DECL_AI_ADDRCONFIG */
+ 		.ai_family	= family,
+ 	};
+ 	socklen_t len = *salen;
+@@ -428,12 +427,12 @@ static int get_socket(struct sockaddr_in
+ 		if (bindresvport(so, &laddr) < 0)
+ 			goto err_bindresvport;
+ 	} else {
+-		cc = bind(so, (struct sockaddr *)&laddr, namelen);
++		cc = bind(so, SAFE_SOCKADDR(&laddr), namelen);
+ 		if (cc < 0)
+ 			goto err_bind;
+ 	}
+ 	if (type == SOCK_STREAM || (conn && type == SOCK_DGRAM)) {
+-		cc = connect_to(so, (struct sockaddr *)saddr, namelen,
++		cc = connect_to(so, SAFE_SOCKADDR(saddr), namelen,
+ 				timeout);
+ 		if (cc < 0)
+ 			goto err_connect;
+@@ -756,11 +755,12 @@ int nfs_probe_bothports(const struct soc
+  */
+ 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),
++	struct sockaddr *mnt_addr = SAFE_SOCKADDR(&mnt_server->saddr);
++	struct sockaddr *nfs_addr = SAFE_SOCKADDR(&nfs_server->saddr);
++
++	return nfs_probe_bothports(mnt_addr, sizeof(mnt_server->saddr),
+ 					&mnt_server->pmap,
+-					(struct sockaddr *)&nfs_server->saddr,
+-					sizeof(nfs_server->saddr),
++					nfs_addr, sizeof(nfs_server->saddr),
+ 					&nfs_server->pmap);
+ }
+ 
+@@ -772,7 +772,7 @@ static int nfs_probe_statd(void)
+ 	};
+ 	rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);
+ 
+-	return nfs_getport_ping((struct sockaddr *)&addr, sizeof(addr),
++	return nfs_getport_ping(SAFE_SOCKADDR(&addr), sizeof(addr),
+ 				program, (rpcvers_t)1, IPPROTO_UDP);
+ }
+ 
+@@ -901,7 +901,7 @@ int nfs_advise_umount(const struct socka
+  */
+ int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
+ {
+-	struct sockaddr *sap = (struct sockaddr *)&mnt_server->saddr;
++	struct sockaddr *sap = SAFE_SOCKADDR(&mnt_server->saddr);
+ 	socklen_t salen = sizeof(mnt_server->saddr);
+ 	struct pmap *pmap = &mnt_server->pmap;
+ 	CLIENT *clnt;
+@@ -1011,11 +1011,11 @@ int clnt_ping(struct sockaddr_in *saddr,
+ 		struct sockaddr_in *caddr)
+ {
+ 	CLIENT *clnt = NULL;
+-	int sock, stat;
++	int sock, status;
+ 	static char clnt_res;
+ 	struct sockaddr dissolve;
+ 
+-	rpc_createerr.cf_stat = stat = 0;
++	rpc_createerr.cf_stat = status = 0;
+ 	sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE);
+ 	if (sock == RPC_ANYSOCK) {
+ 		if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) {
+@@ -1058,18 +1058,18 @@ int clnt_ping(struct sockaddr_in *saddr,
+ 		return 0;
+ 	}
+ 	memset(&clnt_res, 0, sizeof(clnt_res));
+-	stat = clnt_call(clnt, NULLPROC,
++	status = clnt_call(clnt, NULLPROC,
+ 			 (xdrproc_t)xdr_void, (caddr_t)NULL,
+ 			 (xdrproc_t)xdr_void, (caddr_t)&clnt_res,
+ 			 TIMEOUT);
+-	if (stat) {
++	if (status) {
+ 		clnt_geterr(clnt, &rpc_createerr.cf_error);
+-		rpc_createerr.cf_stat = stat;
++		rpc_createerr.cf_stat = status;
+ 	}
+ 	clnt_destroy(clnt);
+ 	close(sock);
+ 
+-	if (stat == RPC_SUCCESS)
++	if (status == RPC_SUCCESS)
+ 		return 1;
+ 	else
+ 		return 0;
+@@ -1103,13 +1103,13 @@ static int nfs_ca_sockname(const struct 
+ 
+ 	switch (sap->sa_family) {
+ 	case AF_INET:
+-		if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
++		if (bind(sock, SAFE_SOCKADDR(&sin), sizeof(sin)) < 0) {
+ 			close(sock);
+ 			return 0;
+ 		}
+ 		break;
+ 	case AF_INET6:
+-		if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
++		if (bind(sock, SAFE_SOCKADDR(&sin6), sizeof(sin6)) < 0) {
+ 			close(sock);
+ 			return 0;
+ 		}
+@@ -1518,7 +1518,11 @@ nfs_mount_protocol(struct mount_options 
+ 	 * set @protocol to zero.  The pmap protocol value will
+ 	 * be filled in later by an rpcbind query in this case.
+ 	 */
+-	return nfs_nfs_protocol(options, protocol);
++	if (!nfs_nfs_protocol(options, protocol))
++		return 0;
++	if (*protocol == NFSPROTO_RDMA)
++		*protocol = IPPROTO_TCP;
++	return 1;
+ }
+ 
+ /*
+diff -up nfs-utils-1.2.3/utils/mount/nfs.man.orig nfs-utils-1.2.3/utils/mount/nfs.man
+--- nfs-utils-1.2.3/utils/mount/nfs.man.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/nfs.man	2010-11-29 11:18:48.358596373 -0500
+@@ -69,10 +69,9 @@ for details on specifying raw IPv6 addre
+ .P
+ The
+ .I fstype
+-field contains "nfs", for whatever version of the protocol.
+-The
+-.B nfs
+-allow several mount options, which are described below.
++field contains "nfs".  Use of the "nfs4" fstype in
++.I /etc/fstab
++is deprecated.
+ .SH "MOUNT OPTIONS"
+ Refer to
+ .BR mount (8)
+@@ -464,9 +463,9 @@ by other clients, but can impact applica
+ .IP
+ The DATA AND METADATA COHERENCE section contains a
+ detailed discussion of these trade-offs.
+-.SS "Options for versions 2 and 3 only"
++.SS "Options for NFS versions 2 and 3 only"
+ Use these options, along with the options in the above subsection,
+-for NFSv2/v3 only. They will be ignored for newer versions.
++for NFS versions 2 and 3 only.
+ .TP 1.5i
+ .BI proto= netid
+ The transport protocol name and protocol family the NFS client uses
+@@ -619,7 +618,7 @@ in such cases.
+ .BI nfsvers= n
+ The NFS protocol version number used to contact the server's NFS service.
+ If the server does not support the requested version, the mount request fails.
+-If this option is not specified, the client negociate a suitable version with
++If this option is not specified, the client negotiates a suitable version with
+ the server, trying version 4 first, version 3 second, and version 2 last.
+ .TP 1.5i
+ .BI vers= n
+@@ -717,9 +716,53 @@ If this option is not specified, the NFS
+ on NFS version 3 mounts to read small directories.
+ Some applications perform better if the client uses only READDIR requests
+ for all directories.
+-.SS "Options for version 4 only"
++.TP 1.5i
++.BR local_lock= mechanism
++Specifies whether to use local locking for any or both of the flock and the
++POSIX locking mechanisms.
++.I mechanism
++can be one of
++.BR all ,
++.BR flock ,
++.BR posix ,
++or
++.BR none .
++This option is supported in kernels 2.6.37 and later.
++.IP
++The Linux NFS client provides a way to make locks local. This means, the
++applications can lock files, but such locks provide exclusion only against
++other applications running on the same client. Remote applications are not
++affected by these locks.
++.IP
++If this option is not specified, or if
++.B none
++is specified, the client assumes that the locks are not local.
++.IP
++If
++.BR all
++is specified, the client assumes that both flock and POSIX locks are local.
++.IP
++If
++.BR flock
++is specified, the client assumes that only flock locks are local and uses
++NLM sideband protocol to lock files when POSIX locks are used.
++.IP
++If
++.BR posix
++is specified, the client assumes that POSIX locks are local and uses NLM
++sideband protocol to lock files when flock locks are used.
++.IP
++To support legacy flock behavior similar to that of NFS clients < 2.6.12, use
++'local_lock=flock'. This option is required when exporting NFS mounts via
++Samba as Samba maps Windows share mode locks as flock. Since NFS clients >
++2.6.12 implement flock by emulating POSIX locks, this will result in
++conflicting locks.
++.IP
++NOTE: When used together, the 'local_lock' mount option will be overridden
++by 'nolock'/'lock' mount option.
++.SS "Options for NFS version 4 only"
+ Use these options, along with the options in the first subsection above,
+-for NFSv4 only. They will be ignored with older versions.
++for NFS version 4 and newer.
+ .TP 1.5i
+ .BI proto= netid
+ The transport protocol name and protocol family the NFS client uses
+@@ -1480,32 +1523,54 @@ of Access Control Lists that are semanti
+ NFS version 4 ACLs are not fully compatible with POSIX ACLs; as such,
+ some translation between the two is required
+ in an environment that mixes POSIX ACLs and NFS version 4.
+-.SH FILES
+-.TP 1.5i
+-.I /etc/fstab
+-file system table
+-.SH BUGS
+-The generic
+-.B remount
+-option is not fully supported.
+-Generic options, such as
+-.BR rw " and " ro
+-can be modified using the
+-.B remount
+-option,
+-but NFS-specific options are not all supported.
++.SH "THE REMOUNT OPTION"
++Generic mount options such as
++.BR rw " and " sync
++can be modified on NFS mount points using the
++.BR remount
++option.
++See
++.BR mount (8)
++for more information on generic mount options.
++.P
++With few exceptions, NFS-specific options
++are not able to be modified during a remount.
+ The underlying transport or NFS version
+ cannot be changed by a remount, for example.
++.P
+ Performing a remount on an NFS file system mounted with the
+ .B noac
+ option may have unintended consequences.
+ The
+ .B noac
+-option is a mixture of a generic option,
++option is a combination of the generic option
+ .BR sync ,
+-and an NFS-specific option
++and the NFS-specific option
+ .BR actimeo=0 .
++.SS "Unmounting after a remount"
++For mount points that use NFS versions 2 or 3, the NFS umount subcommand
++depends on knowing the original set of mount options used to perform the
++MNT operation.
++These options are stored on disk by the NFS mount subcommand,
++and can be erased by a remount.
++.P
++To ensure that the saved mount options are not erased during a remount,
++specify either the local mount directory, or the server hostname and
++export pathname, but not both, during a remount.  For example,
+ .P
++.NF
++.TA 2.5i
++	mount -o remount,ro /mnt
++.FI
++.P
++merges the mount option
++.B ro
++with the mount options already saved on disk for the NFS server mounted at /mnt.
++.SH FILES
++.TP 1.5i
++.I /etc/fstab
++file system table
++.SH BUGS
+ Before 2.4.7, the Linux NFS client did not support NFS over TCP.
+ .P
+ Before 2.4.20, the Linux NFS client used a heuristic
+diff -up nfs-utils-1.2.3/utils/mount/nfsumount.c.orig nfs-utils-1.2.3/utils/mount/nfsumount.c
+--- nfs-utils-1.2.3/utils/mount/nfsumount.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/nfsumount.c	2010-11-29 11:18:48.359596267 -0500
+@@ -31,12 +31,16 @@
+ #include "nls.h"
+ 
+ #include "mount_constants.h"
++#include "nfs_mount.h"
+ #include "mount.h"
+ #include "error.h"
+ #include "network.h"
+ #include "parse_opt.h"
+ #include "parse_dev.h"
+ 
++#define MOUNTSFILE	"/proc/mounts"
++#define LINELEN		(4096)
++
+ #if !defined(MNT_FORCE)
+ /* dare not try to include <linux/mount.h> -- lots of errors */
+ #define MNT_FORCE 1
+@@ -109,7 +113,7 @@ static int del_mtab(const char *spec, co
+ 			res = try_remount(spec, node);
+ 			if (res)
+ 				goto writemtab;
+-			return 0;
++			return EX_SUCCESS;
+ 		} else
+ 			umnt_err = errno;
+ 	}
+@@ -127,7 +131,7 @@ static int del_mtab(const char *spec, co
+ 	}
+ 
+ 	if (res >= 0)
+-		return 0;
++		return EX_SUCCESS;
+ 
+ 	if (umnt_err)
+ 		umount_error(umnt_err, node);
+@@ -241,6 +245,91 @@ static int nfs_umount23(const char *devn
+ 	return result;
+ }
+ 
++/*
++ * Detect NFSv4 mounts.
++ *
++ * Consult /proc/mounts to determine if the mount point
++ * is an NFSv4 mount.  The kernel is authoritative about
++ * what type of mount this is.
++ *
++ * Returns 1 if "mc" is an NFSv4 mount, zero if not, and
++ * -1 if some error occurred.
++ */
++static int nfs_umount_is_vers4(const struct mntentchn *mc)
++{
++	char buffer[LINELEN], *next;
++	int retval;
++	FILE *f;
++
++	if ((f = fopen(MOUNTSFILE, "r")) == NULL) {
++		fprintf(stderr, "%s: %s\n",
++			MOUNTSFILE, strerror(errno));
++		return -1;
++	}
++
++	retval = -1;
++	while (fgets(buffer, sizeof(buffer), f) != NULL) {
++		char *device, *mntdir, *type, *flags;
++		struct mount_options *options;
++		char *line = buffer;
++
++		next = strchr(line, '\n');
++		if (next != NULL)
++			*next = '\0';
++
++		device = strtok(line, " \t");
++		if (device == NULL)
++			continue;
++		mntdir = strtok(NULL, " \t");
++		if (mntdir == NULL)
++			continue;
++		if (strcmp(device, mc->m.mnt_fsname) != 0 &&
++		    strcmp(mntdir, mc->m.mnt_dir) != 0)
++			continue;
++
++		type = strtok(NULL, " \t");
++		if (type == NULL)
++			continue;
++		if (strcmp(type, "nfs4") == 0)
++			goto out_nfs4;
++
++		flags = strtok(NULL, " \t");
++		if (flags == NULL)
++			continue;
++		options = po_split(flags);
++		if (options != NULL) {
++			unsigned long version;
++			int rc;
++
++			rc = nfs_nfs_version(options, &version);
++			po_destroy(options);
++			if (rc && version == 4)
++				goto out_nfs4;
++		}
++
++		goto out_nfs;
++	}
++	if (retval == -1)
++		fprintf(stderr, "%s was not found in %s\n",
++			mc->m.mnt_dir, MOUNTSFILE);
++
++out:
++	fclose(f);
++	return retval;
++
++out_nfs4:
++	if (verbose)
++		fprintf(stderr, "NFSv4 mount point detected\n");
++	retval = 1;
++	goto out;
++
++out_nfs:
++	if (verbose)
++		fprintf(stderr, "Legacy NFS mount point detected\n");
++	retval = 0;
++	goto out;
++}
++
+ static struct option umount_longopts[] =
+ {
+   { "force", 0, 0, 'f' },
+@@ -362,16 +451,25 @@ int nfsumount(int argc, char *argv[])
+ 		}
+ 	}
+ 
+-	ret = 0;
++	ret = EX_SUCCESS;
+ 	if (mc) {
+-		if (!lazy && strcmp(mc->m.mnt_type, "nfs4") != 0)
+-			/* 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!
+-			 */
+-			nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
+-		ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir) ?: ret;
++		if (!lazy) {
++			switch (nfs_umount_is_vers4(mc)) {
++			case 0:
++				/* 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!
++				 */
++				nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
++				break;
++			case 1:
++				break;
++			default:
++				return EX_FAIL;
++			}
++		}
++		ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir);
+ 	} else if (*spec != '/') {
+ 		if (!lazy)
+ 			ret = nfs_umount23(spec, "tcp,v3");
+diff -up nfs-utils-1.2.3/utils/mount/parse_opt.c.orig nfs-utils-1.2.3/utils/mount/parse_opt.c
+--- nfs-utils-1.2.3/utils/mount/parse_opt.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/parse_opt.c	2010-11-29 11:18:48.359596267 -0500
+@@ -508,7 +508,7 @@ po_found_t po_get_numeric(struct mount_o
+ int po_rightmost(struct mount_options *options, const char *keys[])
+ {
+ 	struct mount_option *option;
+-	unsigned int i;
++	int i;
+ 
+ 	if (options) {
+ 		for (option = options->tail; option; option = option->prev) {
+diff -up nfs-utils-1.2.3/utils/mount/stropts.c.orig nfs-utils-1.2.3/utils/mount/stropts.c
+--- nfs-utils-1.2.3/utils/mount/stropts.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/stropts.c	2010-11-29 11:18:48.360596162 -0500
+@@ -49,10 +49,6 @@
+ #include "parse_dev.h"
+ #include "conffile.h"
+ 
+-#ifndef HAVE_DECL_AI_ADDRCONFIG
+-#define AI_ADDRCONFIG	0
+-#endif
+-
+ #ifndef NFS_PROGRAM
+ #define NFS_PROGRAM	(100003)
+ #endif
+@@ -123,10 +119,12 @@ inline void nfs_default_version(struct n
+  * Returns a time_t timeout timestamp, in seconds.
+  */
+ static time_t nfs_parse_retry_option(struct mount_options *options,
+-				     unsigned int timeout_minutes)
++				     const time_t default_timeout)
+ {
++	time_t timeout_minutes;
+ 	long tmp;
+ 
++	timeout_minutes = default_timeout;
+ 	switch (po_get_numeric(options, "retry", &tmp)) {
+ 	case PO_NOT_FOUND:
+ 		break;
+@@ -135,6 +133,7 @@ static time_t nfs_parse_retry_option(str
+ 			timeout_minutes = tmp;
+ 			break;
+ 		}
++		/*FALLTHROUGH*/
+ 	case PO_BAD_VALUE:
+ 		if (verbose)
+ 			nfs_error(_("%s: invalid retry timeout was specified; "
+@@ -142,7 +141,7 @@ static time_t nfs_parse_retry_option(str
+ 		break;
+ 	}
+ 
+-	return time(NULL) + (time_t)(timeout_minutes * 60);
++	return time(NULL) + (timeout_minutes * 60);
+ }
+ 
+ /*
+@@ -343,7 +342,6 @@ static int nfs_validate_options(struct n
+ {
+ 	struct addrinfo hint = {
+ 		.ai_protocol	= (int)IPPROTO_UDP,
+-		.ai_flags	= AI_ADDRCONFIG,
+ 	};
+ 	sa_family_t family;
+ 	int error;
+@@ -570,16 +568,18 @@ static int nfs_sys_mount(struct nfsmount
+ 	char *options = NULL;
+ 	int result;
+ 
++	if (mi->fake)
++		return 1;
++
+ 	if (po_join(opts, &options) == PO_FAILED) {
+ 		errno = EIO;
+ 		return 0;
+ 	}
+ 
+-	if (mi->fake)
+-		return 1;
+-
+ 	result = mount(mi->spec, mi->node, mi->type,
+ 			mi->flags & ~(MS_USER|MS_USERS), options);
++	free(options);
++
+ 	if (verbose && result) {
+ 		int save = errno;
+ 		nfs_error(_("%s: mount(2): %s"), progname, strerror(save));
+@@ -650,7 +650,7 @@ out_fail:
+ static int nfs_try_mount_v3v2(struct nfsmount_info *mi)
+ {
+ 	struct addrinfo *ai;
+-	int ret;
++	int ret = 0;
+ 
+ 	for (ai = mi->address; ai != NULL; ai = ai->ai_next) {
+ 		ret = nfs_do_mount_v3v2(mi, ai->ai_addr, ai->ai_addrlen);
+@@ -737,7 +737,7 @@ out_fail:
+ static int nfs_try_mount_v4(struct nfsmount_info *mi)
+ {
+ 	struct addrinfo *ai;
+-	int ret;
++	int ret = 0;
+ 
+ 	for (ai = mi->address; ai != NULL; ai = ai->ai_next) {
+ 		ret = nfs_do_mount_v4(mi, ai->ai_addr, ai->ai_addrlen);
+diff -up nfs-utils-1.2.3/utils/mount/version.h.orig nfs-utils-1.2.3/utils/mount/version.h
+--- nfs-utils-1.2.3/utils/mount/version.h.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/mount/version.h	2010-11-29 11:18:48.361596059 -0500
+@@ -42,9 +42,9 @@ static inline unsigned int linux_version
+ 	if (uname(&my_utsname))
+ 		return 0;
+ 
+-	p = atoi(strtok(my_utsname.release, "."));
+-	q = atoi(strtok(NULL, "."));
+-	r = atoi(strtok(NULL, "."));
++	p = (unsigned int)atoi(strtok(my_utsname.release, "."));
++	q = (unsigned int)atoi(strtok(NULL, "."));
++	r = (unsigned int)atoi(strtok(NULL, "."));
+ 	return MAKE_VERSION(p, q, r);
+ }
+ 
+diff -up nfs-utils-1.2.3/utils/nfsidmap/Makefile.am.orig nfs-utils-1.2.3/utils/nfsidmap/Makefile.am
+--- nfs-utils-1.2.3/utils/nfsidmap/Makefile.am.orig	2010-11-29 11:18:48.363595859 -0500
++++ nfs-utils-1.2.3/utils/nfsidmap/Makefile.am	2010-11-29 11:18:48.363595859 -0500
+@@ -0,0 +1,9 @@
++## Process this file with automake to produce Makefile.in
++
++man8_MANS = nfsidmap.man
++
++sbin_PROGRAMS	= nfsidmap
++nfsidmap_SOURCES = nfsidmap.c
++nfsidmap_LDADD = -lnfsidmap -lkeyutils
++
++MAINTAINERCLEANFILES = Makefile.in
+diff -up nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.c.orig nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.c
+--- nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.c.orig	2010-11-29 11:18:48.363595859 -0500
++++ nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.c	2010-11-29 11:18:48.363595859 -0500
+@@ -0,0 +1,118 @@
++
++#include <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <pwd.h>
++#include <grp.h>
++#include <keyutils.h>
++#include <nfsidmap.h>
++
++#include <syslog.h>
++
++/* gcc nfsidmap.c -o nfsidmap -l nfsidmap -l keyutils */
++
++#define MAX_ID_LEN   11
++#define IDMAP_NAMESZ 128
++#define USER  1
++#define GROUP 0
++
++
++/*
++ * Find either a user or group id based on the name at domain string
++ */
++int id_lookup(char *name_at_domain, key_serial_t key, int type)
++{
++	char id[MAX_ID_LEN];
++	uid_t uid = 0;
++	gid_t gid = 0;
++	int rc;
++
++	if (type == USER) {
++		rc = nfs4_owner_to_uid(name_at_domain, &uid);
++		sprintf(id, "%u", uid);
++	} else {
++		rc = nfs4_group_owner_to_gid(name_at_domain, &gid);
++		sprintf(id, "%u", gid);
++	}
++
++	if (rc == 0)
++		rc = keyctl_instantiate(key, id, strlen(id) + 1, 0);
++
++	return rc;
++}
++
++/*
++ * Find the name at domain string from either a user or group id
++ */
++int name_lookup(char *id, key_serial_t key, int type)
++{
++	char name[IDMAP_NAMESZ];
++	char domain[NFS4_MAX_DOMAIN_LEN];
++	uid_t uid;
++	gid_t gid;
++	int rc;
++
++	rc = nfs4_get_default_domain(NULL, domain, NFS4_MAX_DOMAIN_LEN);
++	if (rc != 0) {
++		rc = -1;
++		goto out;
++	}
++
++	if (type == USER) {
++		uid = atoi(id);
++		rc = nfs4_uid_to_name(uid, domain, name, IDMAP_NAMESZ);
++	} else {
++		gid = atoi(id);
++		rc = nfs4_gid_to_name(gid, domain, name, IDMAP_NAMESZ);
++	}
++
++	if (rc == 0)
++		rc = keyctl_instantiate(key, &name, strlen(name), 0);
++
++out:
++	return rc;
++}
++
++int main(int argc, char **argv)
++{
++	char *arg;
++	char *value;
++	char *type;
++	int rc = 1;
++	int timeout = 600;
++	key_serial_t key;
++
++	if (argc < 3)
++		return 1;
++
++	arg = malloc(sizeof(char) * strlen(argv[2]) + 1);
++	strcpy(arg, argv[2]);
++	type = strtok(arg, ":");
++	value = strtok(NULL, ":");
++
++	if (argc == 4) {
++		timeout = atoi(argv[3]);
++		if (timeout < 0)
++			timeout = 0;
++	}
++
++	key = strtol(argv[1], NULL, 10);
++
++	if (strcmp(type, "uid") == 0)
++		rc = id_lookup(value, key, USER);
++	else if (strcmp(type, "gid") == 0)
++		rc = id_lookup(value, key, GROUP);
++	else if (strcmp(type, "user") == 0)
++		rc = name_lookup(value, key, USER);
++	else if (strcmp(type, "group") == 0)
++		rc = name_lookup(value, key, GROUP);
++
++	/* Set timeout to 5 (600 seconds) minutes */
++	if (rc == 0)
++		keyctl_set_timeout(key, timeout);
++
++	free(arg);
++	return rc;
++}
+diff -up nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.man.orig nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.man
+--- nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.man.orig	2010-11-29 11:18:48.364595762 -0500
++++ nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.man	2010-11-29 11:18:48.364595762 -0500
+@@ -0,0 +1,60 @@
++.\"
++.\"@(#)nfsidmap(8) - The NFS idmapper upcall program
++.\"
++.\" Copyright (C) 2010 Bryan Schumaker <bjschuma at netapp.com>
++.TH nfsidmap 5 "1 October 2010"
++.SH NAME
++nfsidmap \- The NFS idmapper upcall program
++.SH DESCRIPTION
++The file
++.I /usr/sbin/nfsidmap
++is used by the NFS idmapper to translate user and group ids into names, and to
++translate user and group names into ids. Idmapper uses request-key to perform
++the upcall and cache the result.
++.I /usr/sbin/nfsidmap
++should only be called by request-key, and will perform the translation and
++initialize a key with the resulting information.
++.PP
++NFS_USE_NEW_IDMAPPER must be selected when configuring the kernel to use this
++feature.
++.SH CONFIGURING
++The file
++.I /etc/request-key.conf
++will need to be modified so
++.I /sbin/request-key
++can properly direct the upcall. The following line should be added before a call
++to keyctl negate:
++.PP
++create	nfs_idmap	*	*	/usr/sbin/nfsidmap %k %d 600
++.PP
++This will direct all nfs_idmap requests to the program
++.I /usr/sbin/nfsidmap
++The last parameter, 600, defines how many seconds into the future the key will
++expire.  This is an optional parameter for
++.I /usr/sbin/nfsidmap
++and will default to 600 seconds when not specified.
++.PP
++The idmapper system uses four key descriptions:
++.PP
++	  uid: Find the UID for the given user
++.br
++	  gid: Find the GID for the given group
++.br
++	 user: Find the user name for the given UID
++.br
++	group: Find the group name for the given GID
++.PP
++You can choose to handle any of these individually, rather than using the
++generic upcall program.  If you would like to use your own program for a uid
++lookup then you would edit your request-key.conf so it looks similar to this:
++.PP
++create	nfs_idmap	uid:*	*	/some/other/program %k %d 600
++.br
++create	nfs_idmap	*		*	/usr/sbin/nfsidmap %k %d 600
++.PP
++Notice that the new line was added above the line for the generic program.
++request-key will find the first matching line and run the corresponding program.
++In this case, /some/other/program will handle all uid lookups, and
++/usr/sbin/nfsidmap will handle gid, user, and group lookups.
++.SH AUTHOR
++Bryan Schumaker, <bjschuma at netapp.com>
+diff -up nfs-utils-1.2.3/utils/nfsstat/nfsstat.c.orig nfs-utils-1.2.3/utils/nfsstat/nfsstat.c
+--- nfs-utils-1.2.3/utils/nfsstat/nfsstat.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/nfsstat/nfsstat.c	2010-11-29 11:18:48.365595665 -0500
+@@ -46,7 +46,7 @@ static unsigned int	cltproc3info[CLTPROC
+ static unsigned int	srvproc4info[SRVPROC4_SZ+2],
+ 			srvproc4info_old[SRVPROC4_SZ+2];	/* NFSv4 call counts ([0] == 2) */
+ static unsigned int	cltproc4info[CLTPROC4_SZ+2],
+-			cltproc4info_old[CLTPROC4_SZ+2];	/* NFSv4 call counts ([0] == 48) */
++			cltproc4info_old[CLTPROC4_SZ+2];	/* NFSv4 call counts ([0] == 49) */
+ static unsigned int	srvproc4opsinfo[SRVPROC4OPS_SZ+2],
+ 			srvproc4opsinfo_old[SRVPROC4OPS_SZ+2];	/* NFSv4 call counts ([0] == 59) */
+ static unsigned int	srvnetinfo[5], srvnetinfo_old[5];	/* 0  # of received packets
+@@ -221,8 +221,8 @@ DECLARE_CLT(cltinfo);
+ DECLARE_CLT(cltinfo, _old);
+ 
+ static void		print_all_stats(int, int, int);
+-static void		print_server_stats(int, int);
+-static void		print_client_stats(int, int);
++static void		print_server_stats(int);
++static void		print_client_stats(int);
+ static void		print_stats_list(int, int, int);
+ static void		print_numbers(const char *, unsigned int *,
+ 					unsigned int);
+@@ -239,7 +239,7 @@ static int		mounts(const char *);
+ 
+ static void		get_stats(const char *, struct statinfo *, int *, int,
+ 					int);
+-static int		has_stats(const unsigned int *);
++static int		has_stats(const unsigned int *, int);
+ static int		has_rpcstats(const unsigned int *, int);
+ static void 		diff_stats(struct statinfo *, struct statinfo *, int);
+ static void 		unpause(int);
+@@ -468,7 +468,7 @@ main(int argc, char **argv)
+ 		pause();
+ 	}
+ 
+-	if (opt_since || opt_sleep) {
++	if (opt_since || (opt_sleep && !sleep_time)) {
+ 		if (opt_srv) {
+ 			get_stats(NFSSRVSTAT, serverinfo_tmp, &opt_srv, opt_clt, 1);
+ 			diff_stats(serverinfo_tmp, serverinfo, 1);
+@@ -516,16 +516,16 @@ main(int argc, char **argv)
+ static void
+ print_all_stats (int opt_srv, int opt_clt, int opt_prt)
+ {
+-	print_server_stats(opt_srv, opt_prt);
+-	print_client_stats(opt_clt, opt_prt);
++	if (opt_srv)
++		print_server_stats(opt_prt);
++
++	if (opt_clt)
++		print_client_stats(opt_prt);
+ }
+ 
+ static void 
+-print_server_stats(int opt_srv, int opt_prt) 
++print_server_stats(int opt_prt) 
+ {
+-	if (!opt_srv)
+-		return;
+-
+ 	if (opt_prt & PRNT_NET) {
+ 		if (opt_sleep && !has_rpcstats(srvnetinfo, 4)) {
+ 		} else {
+@@ -582,31 +582,29 @@ print_server_stats(int opt_srv, int opt_
+ 		printf("\n");
+ 	}
+ 	if (opt_prt & PRNT_CALLS) {
++		int has_v2_stats = has_stats(srvproc2info, SRVPROC2_SZ+2);
++		int has_v3_stats = has_stats(srvproc3info, SRVPROC3_SZ+2);
++		int has_v4_stats = has_stats(srvproc4info, SRVPROC4_SZ+2);
++
+ 		if ((opt_prt & PRNT_V2) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(srvproc2info))) {
+-			if (opt_sleep && !has_stats(srvproc2info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v2_stats)) {
++			if (!opt_sleep || has_v2_stats) {
+ 				print_callstats(LABEL_srvproc2,
+ 					nfsv2name, srvproc2info + 1, 
+ 					sizeof(nfsv2name)/sizeof(char *));
+ 			}
+ 		}
+ 		if ((opt_prt & PRNT_V3) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(srvproc3info))) {
+-			if (opt_sleep && !has_stats(srvproc3info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v3_stats)) {
++			if (!opt_sleep || has_v3_stats) {
+ 				print_callstats(LABEL_srvproc3,
+ 					nfsv3name, srvproc3info + 1, 
+ 					sizeof(nfsv3name)/sizeof(char *));
+ 			}
+ 		}
+ 		if ((opt_prt & PRNT_V4) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(srvproc4info))) {
+-			if (opt_sleep && !has_stats(srvproc4info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v4_stats)) {
++			if (!opt_sleep || has_v4_stats) {
+ 				print_callstats( LABEL_srvproc4,
+ 					nfssrvproc4name, srvproc4info + 1, 
+ 					sizeof(nfssrvproc4name)/sizeof(char *));
+@@ -618,11 +616,8 @@ print_server_stats(int opt_srv, int opt_
+ 	}
+ }
+ static void
+-print_client_stats(int opt_clt, int opt_prt) 
++print_client_stats(int opt_prt) 
+ {
+-	if (!opt_clt)
+-		return;
+-
+ 	if (opt_prt & PRNT_NET) {
+ 		if (opt_sleep && !has_rpcstats(cltnetinfo, 4)) {
+ 			;
+@@ -644,31 +639,28 @@ print_client_stats(int opt_clt, int opt_
+ 		}
+ 	}
+ 	if (opt_prt & PRNT_CALLS) {
++		int has_v2_stats = has_stats(cltproc2info, CLTPROC2_SZ+2);
++		int has_v3_stats = has_stats(cltproc3info, CLTPROC3_SZ+2);
++		int has_v4_stats = has_stats(cltproc4info, CLTPROC4_SZ+2);
+ 		if ((opt_prt & PRNT_V2) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(cltproc2info))) {
+-			if (opt_sleep && !has_stats(cltproc2info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v2_stats)) {
++			if (!opt_sleep || has_v2_stats) {
+ 				print_callstats(LABEL_cltproc2,
+ 					nfsv2name, cltproc2info + 1,  
+ 					sizeof(nfsv2name)/sizeof(char *));
+ 			}
+ 		}
+ 		if ((opt_prt & PRNT_V3) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(cltproc3info))) {
+-			if (opt_sleep && !has_stats(cltproc3info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v3_stats)) {
++			if (!opt_sleep || has_v3_stats) {
+ 				print_callstats(LABEL_cltproc3,
+ 					nfsv3name, cltproc3info + 1, 
+ 					sizeof(nfsv3name)/sizeof(char *));
+ 			}
+ 		}
+ 		if ((opt_prt & PRNT_V4) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(cltproc4info))) {
+-			if (opt_sleep && !has_stats(cltproc4info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v4_stats)) {
++			if (!opt_sleep || has_v4_stats) {
+ 				print_callstats(LABEL_cltproc4,
+ 					nfscltproc4name, cltproc4info + 1,  
+ 					sizeof(nfscltproc4name)/sizeof(char *));
+@@ -681,34 +673,28 @@ static void
+ print_clnt_list(int opt_prt) 
+ {
+ 	if (opt_prt & PRNT_CALLS) {
++		int has_v2_stats = has_stats(cltproc2info, CLTPROC2_SZ+2);
++		int has_v3_stats = has_stats(cltproc3info, CLTPROC3_SZ+2);
++		int has_v4_stats = has_stats(cltproc4info, CLTPROC4_SZ+2);
+ 		if ((opt_prt & PRNT_V2) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(cltproc2info))) {
+-			if (opt_sleep && !has_stats(cltproc2info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v2_stats)) {
++			if (!opt_sleep || has_v2_stats) {
+ 				print_callstats_list("nfs v2 client",
+ 					nfsv2name, cltproc2info + 1,  
+ 					sizeof(nfsv2name)/sizeof(char *));
+ 			}
+ 		}
+ 		if ((opt_prt & PRNT_V3) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(cltproc3info))) {
+-			if (opt_sleep && !has_stats(cltproc3info)) {
+-				;
+-			} else { 
++				((opt_prt & PRNT_AUTO) && has_v3_stats)) {
++			if (!opt_sleep || has_v3_stats) {
+ 				print_callstats_list("nfs v3 client",
+ 					nfsv3name, cltproc3info + 1, 
+ 					sizeof(nfsv3name)/sizeof(char *));
+ 			}
+ 		}
+ 		if ((opt_prt & PRNT_V4) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(cltproc4info))) {
+-			if (opt_sleep && !has_stats(cltproc4info)) {
+-				;
+-			} else {
+-				print_callstats_list("nfs v4 ops",
+-					nfssrvproc4opname, srvproc4opsinfo + 1, 
+-					sizeof(nfssrvproc4opname)/sizeof(char *));
++				((opt_prt & PRNT_AUTO) && has_v4_stats)) {
++			if (!opt_sleep || has_v4_stats) {
+ 				print_callstats_list("nfs v4 client",
+ 					nfscltproc4name, cltproc4info + 1,  
+ 					sizeof(nfscltproc4name)/sizeof(char *));
+@@ -720,32 +706,32 @@ static void
+ print_serv_list(int opt_prt) 
+ {
+ 	if (opt_prt & PRNT_CALLS) {
++		int has_v2_stats = has_stats(srvproc2info, SRVPROC2_SZ+2);
++		int has_v3_stats = has_stats(srvproc3info, SRVPROC3_SZ+2);
++		int has_v4_stats = has_stats(srvproc4info, SRVPROC4_SZ+2);
+ 		if ((opt_prt & PRNT_V2) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(srvproc2info))) {
+-			if (opt_sleep && !has_stats(srvproc2info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v2_stats)) {
++			if (!opt_sleep || has_v2_stats) {
+ 				print_callstats_list("nfs v2 server",
+ 					nfsv2name, srvproc2info + 1, 
+ 					sizeof(nfsv2name)/sizeof(char *));
+ 			}
+ 		}
+ 		if ((opt_prt & PRNT_V3) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(srvproc3info))) {
+-			if (opt_sleep && !has_stats(srvproc3info)) {
+-				;
+-			} else {
++				((opt_prt & PRNT_AUTO) && has_v3_stats)) {
++			if (!opt_sleep || has_v3_stats) {
+ 				print_callstats_list("nfs v3 server",
+ 					nfsv3name, srvproc3info + 1, 
+ 					sizeof(nfsv3name)/sizeof(char *));
+ 			}
+ 		}
+ 		if ((opt_prt & PRNT_V4) || 
+-				((opt_prt & PRNT_AUTO) && has_stats(srvproc4opsinfo))) {
+-			if (opt_sleep && !has_stats(srvproc4info)) {
+-				;
+-			} else {
+-				print_callstats_list("nfs v4 ops",
++				((opt_prt & PRNT_AUTO) && has_v4_stats)) {
++			if (!opt_sleep || has_v4_stats) {
++				print_callstats_list("nfs v4 server",
++					nfssrvproc4name, srvproc4info + 1, 
++					sizeof(nfssrvproc4name)/sizeof(char *));
++				print_callstats_list("nfs v4 servop",
+ 					nfssrvproc4opname, srvproc4opsinfo + 1, 
+ 					sizeof(nfssrvproc4opname)/sizeof(char *));
+ 			}
+@@ -1054,9 +1040,9 @@ out:
+  * there are stats if the sum's greater than the entry-count.
+  */
+ static int
+-has_stats(const unsigned int *info)
++has_stats(const unsigned int *info, int nr)
+ {
+-	return (info[0] && info[info[0] + 1] > info[0]);
++	return (info[0] && info[nr-1] > info[0]);
+ }
+ static int
+ has_rpcstats(const unsigned int *info, int size)
+diff -up nfs-utils-1.2.3/utils/nfsstat/nfsstat.man.orig nfs-utils-1.2.3/utils/nfsstat/nfsstat.man
+--- nfs-utils-1.2.3/utils/nfsstat/nfsstat.man.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/nfsstat/nfsstat.man	2010-11-29 11:18:48.366595571 -0500
+@@ -30,10 +30,12 @@ Print only NFS v2 statistics. The defaul
+ about the versions of \fBNFS\fR that have non-zero counts.
+ .TP
+ .B \-3
+-Print only NFS v3 statistics. 
++Print only NFS v3 statistics. The default is to only print information
++about the versions of \fBNFS\fR that have non-zero counts.
+ .TP
+ .B \-4
+-Print only NFS v4 statistics. 
++Print only NFS v4 statistics. The default is to only print information
++about the versions of \fBNFS\fR that have non-zero counts.
+ .TP
+ .B \-m, \-\-mounts
+ Print information about each of the mounted \fBNFS\fR file systems.
+diff -up nfs-utils-1.2.3/utils/statd/hostname.c.orig nfs-utils-1.2.3/utils/statd/hostname.c
+--- nfs-utils-1.2.3/utils/statd/hostname.c.orig	2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/statd/hostname.c	2010-11-29 11:18:48.366595571 -0500
+@@ -39,10 +39,6 @@
+ #include "statd.h"
+ #include "xlog.h"
+ 
+-#ifndef HAVE_DECL_AI_ADDRCONFIG
+-#define AI_ADDRCONFIG	0
+-#endif
+-
+ /**
+  * statd_present_address - convert sockaddr to presentation address
+  * @sap: pointer to socket address to convert
+diff -up nfs-utils-1.2.3/utils/statd/sm-notify.c.orig nfs-utils-1.2.3/utils/statd/sm-notify.c
+--- nfs-utils-1.2.3/utils/statd/sm-notify.c.orig	2010-11-29 11:17:26.908868990 -0500
++++ nfs-utils-1.2.3/utils/statd/sm-notify.c	2010-11-29 11:18:48.367595478 -0500
+@@ -37,10 +37,6 @@
+ #include "nsm.h"
+ #include "nfsrpc.h"
+ 
+-#ifndef HAVE_DECL_AI_ADDRCONFIG
+-#define AI_ADDRCONFIG	0
+-#endif
+-
+ #define NSM_TIMEOUT	2
+ #define NSM_MAX_TIMEOUT	120	/* don't make this too big */
+ 
+@@ -81,7 +77,6 @@ smn_lookup(const char *name)
+ {
+ 	struct addrinfo	*ai = NULL;
+ 	struct addrinfo hint = {
+-		.ai_flags	= AI_ADDRCONFIG,
+ 		.ai_family	= (nsm_family == AF_INET ? AF_INET: AF_UNSPEC),
+ 		.ai_protocol	= (int)IPPROTO_UDP,
+ 	};
diff --git a/nfs-utils.spec b/nfs-utils.spec
index b830f5b..5acadea 100644
--- a/nfs-utils.spec
+++ b/nfs-utils.spec
@@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
 Name: nfs-utils
 URL: http://sourceforge.net/projects/nfs
 Version: 1.2.3
-Release: 2%{?dist}
+Release: 3%{?dist}
 Epoch: 1
 
 # group all 32bit related archs
@@ -17,8 +17,7 @@ Source13: rpcgssd.init
 Source14: rpcsvcgssd.init
 Source15: nfs.sysconfig
 
-Patch001: nfs-utils-1.2.4-rc1.patch
-Patch002: nfs-utils-1.2.3-export-manpage.patch
+Patch001: nfs-utils-1.2.4-rc3.patch
 
 Patch100: nfs-utils-1.2.1-statdpath-man.patch
 Patch101: nfs-utils-1.2.2-statdpath.patch
@@ -73,7 +72,6 @@ This package also contains the mount.nfs and umount.nfs program.
 %setup -q
 
 %patch001 -p1
-%patch002 -p1
 
 %patch100 -p1
 %patch101 -p1
@@ -254,6 +252,9 @@ fi
 %attr(4755,root,root)   /sbin/umount.nfs4
 
 %changelog
+* Mon Nov 29 2010 Steve Dickson <steved at redhat.com> 1.2.3-3
+- Updated to latest upstream release: nfs-utils-1-2-4-rc3
+
 * Fri Oct 15 2010 Steve Dickson <steved at redhat.com> 1.2.3-2
 - Initscripts do not conform to LSB specification (bz 621562)
 - sm-notify needs to call res_init() before each try (bz 625531)


More information about the scm-commits mailing list