From 9c991d660c39aabd9a0302bab706ac444e55fe0b Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Thu, 14 Oct 2010 10:52:40 -0400 Subject: [PATCH] Updated to latest upstream release: nfs-utils-1-2-4-rc1 Signed-off-by: Steve Dickson --- nfs-utils-1.2.4-rc1.patch | 1378 +++++++++++++++++++++++++++++++++++++ nfs-utils.spec | 6 +- 2 files changed, 1383 insertions(+), 1 deletion(-) create mode 100644 nfs-utils-1.2.4-rc1.patch 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 ++ * 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 ++#include ++#include ++ ++/* ++ * 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 ++ * 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 ++#include ++ ++#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 ++ * 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 ++#include ++ ++#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 + #include + #include ++#include + #include + + #include +@@ -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 +- * 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 +-#include +-#include +- +-#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 +- * 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 +-#include +- +-#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 +- * 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 +-#include +- +-#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 + * + * 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 -- 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 1.2.3-1 +- Updated to latest upstream release: nfs-utils-1-2-4-rc1 + * Mon Oct 4 2010 Steve Dickson 1.2.3-0.1 - Fixed a regession with -p arguemnt to rpc.mountd