[nfs-utils] Updated to latest upstream release: nfs-utils-1-2-4-rc1
Steve Dickson
steved at fedoraproject.org
Thu Oct 14 14:51:03 UTC 2010
commit 9c991d660c39aabd9a0302bab706ac444e55fe0b
Author: Steve Dickson <steved at redhat.com>
Date: Thu Oct 14 10:52:40 2010 -0400
Updated to latest upstream release: nfs-utils-1-2-4-rc1
Signed-off-by: Steve Dickson <steved at redhat.com>
nfs-utils-1.2.4-rc1.patch | 1378 +++++++++++++++++++++++++++++++++++++++++++++
nfs-utils.spec | 6 +-
2 files changed, 1383 insertions(+), 1 deletions(-)
---
diff --git a/nfs-utils-1.2.4-rc1.patch b/nfs-utils-1.2.4-rc1.patch
new file mode 100644
index 0000000..849b533
--- /dev/null
+++ b/nfs-utils-1.2.4-rc1.patch
@@ -0,0 +1,1378 @@
+diff --git a/support/export/client.c b/support/export/client.c
+index dbfc2b1..ba2db8f 100644
+--- a/support/export/client.c
++++ b/support/export/client.c
+@@ -178,6 +178,7 @@ out_badprefix:
+ static int
+ init_netmask6(nfs_client *UNUSED(clp), const char *UNUSED(slash))
+ {
++ return 0;
+ }
+ #endif /* IPV6_SUPPORTED */
+
+diff --git a/support/export/export.c b/support/export/export.c
+index f528603..4fda30a 100644
+--- a/support/export/export.c
++++ b/support/export/export.c
+@@ -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 --git a/support/include/nfslib.h b/support/include/nfslib.h
+index 3db5bec..53ece0e 100644
+--- a/support/include/nfslib.h
++++ b/support/include/nfslib.h
+@@ -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 --git a/support/nfs/Makefile.am b/support/nfs/Makefile.am
+index 60400b2..05c2fc4 100644
+--- a/support/nfs/Makefile.am
++++ b/support/nfs/Makefile.am
+@@ -5,7 +5,7 @@ libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
+ 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 --git a/support/nfs/atomicio.c b/support/nfs/atomicio.c
+new file mode 100644
+index 0000000..5e760e6
+--- /dev/null
++++ b/support/nfs/atomicio.c
+@@ -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 --git a/support/nfs/exports.c b/support/nfs/exports.c
+index a93941c..1744ed6 100644
+--- a/support/nfs/exports.c
++++ b/support/nfs/exports.c
+@@ -332,6 +332,8 @@ dupexportent(struct exportent *dst, struct exportent *src)
+ 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 --git a/support/nfs/strlcat.c b/support/nfs/strlcat.c
+new file mode 100644
+index 0000000..daedd7a
+--- /dev/null
++++ b/support/nfs/strlcat.c
+@@ -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 --git a/support/nfs/strlcpy.c b/support/nfs/strlcpy.c
+new file mode 100644
+index 0000000..a2653ee
+--- /dev/null
++++ b/support/nfs/strlcpy.c
+@@ -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 --git a/support/nfs/svc_create.c b/support/nfs/svc_create.c
+index 59ba505..b3f75ed 100644
+--- a/support/nfs/svc_create.c
++++ b/support/nfs/svc_create.c
+@@ -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 *nconf, const uint16_t port)
+ 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 rpcprog_t program,
+ 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 rpcprog_t program,
+ 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 rpcprog_t program,
+ * 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 --git a/utils/idmapd/Makefile.am b/utils/idmapd/Makefile.am
+index 4218048..4328e41 100644
+--- a/utils/idmapd/Makefile.am
++++ b/utils/idmapd/Makefile.am
+@@ -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 --git a/utils/idmapd/atomicio.c b/utils/idmapd/atomicio.c
+deleted file mode 100644
+index 1fb1ff9..0000000
+--- a/utils/idmapd/atomicio.c
++++ /dev/null
+@@ -1,64 +0,0 @@
+-/*
+- * 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>
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif /* HAVE_CONFIG_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;
+- size_t pos = 0;
+-
+- while (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 --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
+index b76607a..76a56ef 100644
+--- a/utils/idmapd/idmapd.c
++++ b/utils/idmapd/idmapd.c
+@@ -158,10 +158,6 @@ static int nfsdopenone(struct idmap_client *);
+ 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 --git a/utils/idmapd/strlcat.c b/utils/idmapd/strlcat.c
+deleted file mode 100644
+index daedd7a..0000000
+--- a/utils/idmapd/strlcat.c
++++ /dev/null
+@@ -1,76 +0,0 @@
+-/* $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 --git a/utils/idmapd/strlcpy.c b/utils/idmapd/strlcpy.c
+deleted file mode 100644
+index a2653ee..0000000
+--- a/utils/idmapd/strlcpy.c
++++ /dev/null
+@@ -1,72 +0,0 @@
+-/* $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 --git a/utils/mount/fstab.c b/utils/mount/fstab.c
+index 051fa38..a742e64 100644
+--- a/utils/mount/fstab.c
++++ b/utils/mount/fstab.c
+@@ -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 --git a/utils/mount/mount.c b/utils/mount/mount.c
+index 82b9169..b4da21f 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)
+ }
+ if (flags & MS_USERS)
+ new_opts = xstrconcat3(new_opts, ",users", "");
+-
++
+ 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;
+- 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;
+
+@@ -321,7 +321,7 @@ static int add_mtab(char *spec, char *mount_point, char *fstype,
+ return result;
+ }
+
+-void mount_usage(void)
++static void mount_usage(void)
+ {
+ printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"),
+ progname);
+@@ -337,7 +337,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 +371,7 @@ static void parse_opts(const char *options, int *flags, char **extra_opts)
+ 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);
+diff --git a/utils/mount/mount_config.h b/utils/mount/mount_config.h
+index 3023306..e86b4ba 100644
+--- a/utils/mount/mount_config.h
++++ b/utils/mount/mount_config.h
+@@ -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 *program)
+ */
+ 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 --git a/utils/mount/mount_constants.h b/utils/mount/mount_constants.h
+index cbfb099..4d050d8 100644
+--- a/utils/mount/mount_constants.h
++++ b/utils/mount/mount_constants.h
+@@ -64,4 +64,8 @@ if we have a stack or plain mount - mount atop of it, forming a stack. */
+ #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 --git a/utils/mount/network.c b/utils/mount/network.c
+index d612427..5b515c3 100644
+--- a/utils/mount/network.c
++++ b/utils/mount/network.c
+@@ -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;
+@@ -428,12 +430,12 @@ static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
+ 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 +758,12 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
+ */
+ 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 +775,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 +904,7 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
+ */
+ 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 +1014,11 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
+ 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 +1061,18 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
+ 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 +1106,13 @@ static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen,
+
+ 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 +1521,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.
+ */
+- return nfs_nfs_protocol(options, protocol);
++ if (!nfs_nfs_protocol(options, protocol))
++ return 0;
++ if (*protocol == NFSPROTO_RDMA)
++ *protocol = IPPROTO_TCP;
++ return 1;
+ }
+
+ /*
+diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
+index d2a4c5f..01bc712 100644
+--- a/utils/mount/nfs.man
++++ b/utils/mount/nfs.man
+@@ -619,7 +619,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
+diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c
+index 1514340..02d40ff 100644
+--- a/utils/mount/nfsumount.c
++++ b/utils/mount/nfsumount.c
+@@ -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, const char *node)
+ 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, const char *node)
+ }
+
+ 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 *devname, char *string)
+ 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 --git a/utils/mount/parse_opt.c b/utils/mount/parse_opt.c
+index f0918f7..ab869d9 100644
+--- a/utils/mount/parse_opt.c
++++ b/utils/mount/parse_opt.c
+@@ -508,7 +508,7 @@ po_found_t po_get_numeric(struct mount_options *options, char *keyword, long *va
+ 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 --git a/utils/mount/version.h b/utils/mount/version.h
+index 46552a1..af61a6f 100644
+--- a/utils/mount/version.h
++++ b/utils/mount/version.h
+@@ -42,9 +42,9 @@ static inline unsigned int linux_version_code(void)
+ 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 --git a/nfs-utils.spec b/nfs-utils.spec
index efd8d4b..71fecc0 100644
--- a/nfs-utils.spec
+++ b/nfs-utils.spec
@@ -18,7 +18,7 @@ Source13: rpcgssd.init
Source14: rpcsvcgssd.init
Source15: nfs.sysconfig
-Patch001: nfs-utils-1.2.3-libnfs-multiports.patch
+Patch001: nfs-utils-1.2.4-rc1.patch
Patch100: nfs-utils-1.2.1-statdpath-man.patch
Patch101: nfs-utils-1.2.2-statdpath.patch
@@ -70,6 +70,7 @@ This package also contains the mount.nfs and umount.nfs program.
%prep
%setup -q
+
%patch001 -p1
%patch100 -p1
@@ -250,6 +251,9 @@ fi
%attr(4755,root,root) /sbin/umount.nfs4
%changelog
+* Thu Oct 14 2010 Steve Dickson <steved at redhat.com> 1.2.3-1
+- Updated to latest upstream release: nfs-utils-1-2-4-rc1
+
* Mon Oct 4 2010 Steve Dickson <steved at redhat.com> 1.2.3-0.1
- Fixed a regession with -p arguemnt to rpc.mountd
More information about the scm-commits
mailing list