diff options
author | Mike Frysinger <vapier@gentoo.org> | 2010-11-14 00:49:39 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-11-14 00:49:39 +0000 |
commit | 85e1f814f77b6259315a40c44a32c5a85884fd0f (patch) | |
tree | adcfebac587d2af4d458e7afc2fb434521f07db4 /net-fs | |
parent | Version bump #342917 by Peter Volkov. (diff) | |
download | gentoo-2-85e1f814f77b6259315a40c44a32c5a85884fd0f.tar.gz gentoo-2-85e1f814f77b6259315a40c44a32c5a85884fd0f.tar.bz2 gentoo-2-85e1f814f77b6259315a40c44a32c5a85884fd0f.zip |
Add fix from upstream for ti-rpc static port bindings #340797 by John J. Aylward.
(Portage version: 2.2.0_alpha4/cvs/Linux x86_64)
Diffstat (limited to 'net-fs')
-rw-r--r-- | net-fs/nfs-utils/ChangeLog | 10 | ||||
-rw-r--r-- | net-fs/nfs-utils/files/nfs-utils-1.2.3-ti-rpc-static-ports.patch | 352 | ||||
-rw-r--r-- | net-fs/nfs-utils/nfs-utils-1.2.3-r1.ebuild | 108 |
3 files changed, 469 insertions, 1 deletions
diff --git a/net-fs/nfs-utils/ChangeLog b/net-fs/nfs-utils/ChangeLog index 12aaaff3084d..75d600ef94c4 100644 --- a/net-fs/nfs-utils/ChangeLog +++ b/net-fs/nfs-utils/ChangeLog @@ -1,6 +1,14 @@ # ChangeLog for net-fs/nfs-utils # Copyright 1999-2010 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/net-fs/nfs-utils/ChangeLog,v 1.174 2010/10/08 19:48:08 vapier Exp $ +# $Header: /var/cvsroot/gentoo-x86/net-fs/nfs-utils/ChangeLog,v 1.175 2010/11/14 00:49:39 vapier Exp $ + +*nfs-utils-1.2.3-r1 (14 Nov 2010) + + 14 Nov 2010; Mike Frysinger <vapier@gentoo.org> + +nfs-utils-1.2.3-r1.ebuild, + +files/nfs-utils-1.2.3-ti-rpc-static-ports.patch: + Add fix from upstream for ti-rpc static port bindings #340797 by John J. + Aylward. *nfs-utils-1.2.3 (08 Oct 2010) diff --git a/net-fs/nfs-utils/files/nfs-utils-1.2.3-ti-rpc-static-ports.patch b/net-fs/nfs-utils/files/nfs-utils-1.2.3-ti-rpc-static-ports.patch new file mode 100644 index 000000000000..b66e981b44a3 --- /dev/null +++ b/net-fs/nfs-utils/files/nfs-utils-1.2.3-ti-rpc-static-ports.patch @@ -0,0 +1,352 @@ +http://bugs.gentoo.org/340797 + +From 656028f9925f5817c5a37565d27159973db84ec3 Mon Sep 17 00:00:00 2001 +From: Chuck Lever <chuck.lever@oracle.com> +Date: Wed, 13 Oct 2010 11:22:07 -0400 +Subject: [PATCH] libnfs.a: Allow multiple RPC listeners to share listener port number + +Normally, when "-p" is not specified on the mountd command line, the +TI-RPC library chooses random port numbers for each listener. If a +port number _is_ specified on the command line, all the listeners +will get the same port number, so SO_REUSEADDR needs to be set on +each socket. + +Thus we can't let TI-RPC create the listener sockets for us in this +case; we must create them ourselves and then set SO_REUSEADDR (and +other socket options) by hand. + +Different versions of the same RPC program have to share the same +listener and SVCXPRT, so we have to cache xprts we create, and re-use +them when additional requests for registration come from the +application. + +Though it doesn't look like it, this fix was "copied" from the legacy +rpc_init() function. It's more complicated for TI-RPC, of course, +since a TI-RPC application can set up listeners with a nearly +arbitrary number of address families and socket types, not just the +two listeners that legacy RPC applications can set up (one for AF_INET +UDP and one for AF_INET TCP). + +See: + https://bugzilla.linux-nfs.org/show_bug.cgi?id=190 + +Signed-off-by: Chuck Lever <chuck.lever@oracle.com> +Signed-off-by: Steve Dickson <steved@redhat.com> +--- + support/nfs/svc_create.c | 252 ++++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 246 insertions(+), 6 deletions(-) + +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) + { +-- +1.7.3.1 + diff --git a/net-fs/nfs-utils/nfs-utils-1.2.3-r1.ebuild b/net-fs/nfs-utils/nfs-utils-1.2.3-r1.ebuild new file mode 100644 index 000000000000..cd3c9927a0e3 --- /dev/null +++ b/net-fs/nfs-utils/nfs-utils-1.2.3-r1.ebuild @@ -0,0 +1,108 @@ +# Copyright 1999-2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/net-fs/nfs-utils/nfs-utils-1.2.3-r1.ebuild,v 1.1 2010/11/14 00:49:39 vapier Exp $ + +EAPI="2" + +inherit eutils flag-o-matic multilib + +DESCRIPTION="NFS client and server daemons" +HOMEPAGE="http://linux-nfs.org/" +SRC_URI="mirror://sourceforge/nfs/${P}.tar.bz2" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86" +IUSE="caps ipv6 kerberos +nfsv3 +nfsv4 tcpd elibc_glibc" +RESTRICT="test" #315573 + +# kth-krb doesn't provide the right include +# files, and nfs-utils doesn't build against heimdal either, +# so don't depend on virtual/krb. +# (04 Feb 2005 agriffis) +DEPEND_COMMON="tcpd? ( sys-apps/tcp-wrappers ) + caps? ( sys-libs/libcap ) + sys-libs/e2fsprogs-libs + net-nds/rpcbind + net-libs/libtirpc + nfsv4? ( + >=dev-libs/libevent-1.0b + >=net-libs/libnfsidmap-0.21-r1 + kerberos? ( + net-libs/librpcsecgss + net-libs/libgssglue + net-libs/libtirpc[kerberos] + app-crypt/mit-krb5 + ) + )" +RDEPEND="${DEPEND_COMMON} !net-nds/portmap" +# util-linux dep is to prevent man-page collision +DEPEND="${DEPEND_COMMON} + >=sys-apps/util-linux-2.12r-r7" + +src_prepare() { + epatch "${FILESDIR}"/${PN}-1.1.4-mtab-sym.patch + epatch "${FILESDIR}"/${PN}-1.1.4-no-exec.patch + epatch "${FILESDIR}"/${P}-ti-rpc-static-ports.patch #340797 +} + +src_configure() { + econf \ + --with-statedir=/var/lib/nfs \ + --enable-tirpc \ + $(use_with tcpd tcp-wrappers) \ + $(use_enable nfsv3) \ + $(use_enable nfsv4) \ + $(use_enable ipv6) \ + $(use_enable caps) \ + $(use nfsv4 && use_enable kerberos gss || echo "--disable-gss") +} + +src_install() { + emake DESTDIR="${D}" install || die + + # Don't overwrite existing xtab/etab, install the original + # versions somewhere safe... more info in pkg_postinst + keepdir /var/lib/nfs/{,sm,sm.bak} + mv "${D}"/var/lib "${D}"/usr/$(get_libdir) || die + + # Install some client-side binaries in /sbin + dodir /sbin + mv "${D}"/usr/sbin/rpc.statd "${D}"/sbin/ || die + + dodoc ChangeLog README + docinto linux-nfs ; dodoc linux-nfs/* + + insinto /etc + doins "${FILESDIR}"/exports + + local f list="" opt_need="" + if use nfsv4 ; then + opt_need="rpc.idmapd" + list="${list} rpc.idmapd rpc.pipefs" + use kerberos && list="${list} rpc.gssd rpc.svcgssd" + fi + for f in nfs nfsmount rpc.statd ${list} ; do + newinitd "${FILESDIR}"/${f}.initd ${f} || die "doinitd ${f}" + done + newconfd "${FILESDIR}"/nfs.confd nfs + dosed "/^NFS_NEEDED_SERVICES=/s:=.*:=\"${opt_need}\":" /etc/conf.d/nfs #234132 + + # uClibc doesn't provide rpcgen like glibc, so lets steal it from nfs-utils + if ! use elibc_glibc ; then + dobin tools/rpcgen/rpcgen || die "rpcgen" + newdoc tools/rpcgen/README README.rpcgen + fi +} + +pkg_postinst() { + # Install default xtab and friends if there's none existing. In + # src_install we put them in /usr/lib/nfs for safe-keeping, but + # the daemons actually use the files in /var/lib/nfs. #30486 + local f + for f in "${ROOT}"/usr/$(get_libdir)/nfs/*; do + [[ -e ${ROOT}/var/lib/nfs/${f##*/} ]] && continue + einfo "Copying default ${f##*/} from /usr/$(get_libdir)/nfs to /var/lib/nfs" + cp -pPR "${f}" "${ROOT}"/var/lib/nfs/ + done +} |