diff --git a/autofs-5.0.5-fix-rpc-large-export-list.patch b/autofs-5.0.5-fix-rpc-large-export-list.patch new file mode 100644 index 0000000..419d063 --- /dev/null +++ b/autofs-5.0.5-fix-rpc-large-export-list.patch @@ -0,0 +1,142 @@ +autofs-5.0.5 - fix rpc fail on large export list + +From: Ian Kent + +If the export list on a server is larger than the UDP transport packet +size the transfer will fail and autofs will try TCP instead, but there +were some problems with the conversion to allow for IPv6 using libtirpc. + +When creating the local socket for an RPC connection we incorrectly +performed a connect instead of a bind to the ilocal TCP socket. Aslo the +timed connect, which should be done before creating the RPC client was +not being done, which can lead to lengthy timeouts. +--- + + CHANGELOG | 1 + + lib/rpc_subs.c | 47 ++++++++++++++++++++++++----------------------- + 2 files changed, 25 insertions(+), 23 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 88bcc1b..20566a6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -15,6 +15,7 @@ + - fix pidof init script usage. + - check for path mount location in generic module. + - dont fail mount on access fail. ++- fix rpc fail on large export list. + + 03/09/2009 autofs-5.0.5 + ----------------------- +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 628f0fc..3b11dce 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -53,6 +53,7 @@ + /* Get numeric value of the n bits starting at position p */ + #define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) + ++static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *); + inline void dump_core(void); + + static CLIENT *rpc_clntudp_create(struct sockaddr *addr, struct conn_info *info, int *fd) +@@ -97,11 +98,17 @@ static CLIENT *rpc_clnttcp_create(struct sockaddr *addr, struct conn_info *info, + struct sockaddr_in *in4_raddr; + struct sockaddr_in6 *in6_raddr; + CLIENT *client = NULL; ++ socklen_t slen; + + switch (addr->sa_family) { + case AF_INET: + in4_raddr = (struct sockaddr_in *) addr; + in4_raddr->sin_port = htons(info->port); ++ slen = sizeof(struct sockaddr_in); ++ ++ if (connect_nb(*fd, addr, slen, &info->timeout) < 0) ++ break; ++ + client = clnttcp_create(in4_raddr, + info->program, info->version, fd, + info->send_sz, info->recv_sz); +@@ -114,6 +121,11 @@ static CLIENT *rpc_clnttcp_create(struct sockaddr *addr, struct conn_info *info, + #else + in6_raddr = (struct sockaddr_in6 *) addr; + in6_raddr->sin6_port = htons(info->port); ++ slen = sizeof(struct sockaddr_in6); ++ ++ if (connect_nb(*fd, addr, slen, &info->timeout) < 0) ++ break; ++ + client = clnttcp6_create(in6_raddr, + info->program, info->version, fd, + info->send_sz, info->recv_sz); +@@ -260,32 +272,21 @@ static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *inf + return NULL; + } + ++ if (!info->client) { ++ *fd = open_sock(addr->sa_family, type, proto); ++ if (*fd < 0) ++ return NULL; ++ ++ if (bind(*fd, laddr, slen) < 0) ++ return NULL; ++ } ++ + switch (info->proto->p_proto) { + case IPPROTO_UDP: +- if (!info->client) { +- *fd = open_sock(addr->sa_family, type, proto); +- if (*fd < 0) +- return NULL; +- +- if (bind(*fd, laddr, slen) < 0) { +- close(*fd); +- return NULL; +- } +- } + client = rpc_clntudp_create(addr, info, fd); + break; + + case IPPROTO_TCP: +- if (!info->client) { +- *fd = open_sock(addr->sa_family, type, proto); +- if (*fd < 0) +- return NULL; +- +- if (connect_nb(*fd, laddr, slen, &info->timeout) < 0) { +- close(*fd); +- return NULL; +- } +- } + client = rpc_clnttcp_create(addr, info, fd); + break; + +@@ -327,7 +328,7 @@ static CLIENT *create_udp_client(struct conn_info *info) + if (client) + goto done; + +- if (!info->client) { ++ if (!info->client && fd != RPC_ANYSOCK) { + close(fd); + fd = RPC_ANYSOCK; + } +@@ -352,7 +353,7 @@ static CLIENT *create_udp_client(struct conn_info *info) + if (client) + break; + +- if (!info->client) { ++ if (!info->client && fd != RPC_ANYSOCK) { + close(fd); + fd = RPC_ANYSOCK; + } +@@ -477,7 +478,7 @@ static CLIENT *create_tcp_client(struct conn_info *info) + if (client) + break; + +- if (!info->client) { ++ if (!info->client && fd != RPC_ANYSOCK) { + close(fd); + fd = RPC_ANYSOCK; + } diff --git a/autofs.spec b/autofs.spec index b74f277..8b54a53 100644 --- a/autofs.spec +++ b/autofs.spec @@ -4,7 +4,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.5 -Release: 12%{?dist} +Release: 14%{?dist} Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -25,6 +25,7 @@ Patch12: autofs-5.0.5-fix-timeout-in-connect_nb.patch Patch13: autofs-5.0.5-fix-pidof-init-script-usage.patch Patch14: autofs-5.0.5-check-for-path-mount-location-in-generic-module.patch Patch15: autofs-5.0.5-dont-fail-mount-on-access-fail.patch +Patch16: autofs-5.0.5-fix-rpc-large-export-list.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs libtirpc-devel Requires: kernel >= 2.6.17 @@ -81,6 +82,7 @@ echo %{version}-%{release} > .version %patch13 -p1 %patch14 -p1 %patch15 -p1 +%patch16 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -133,6 +135,9 @@ fi %{_libdir}/autofs/ %changelog +* Fri Dec 4 2009 Ian Kent - 1:5.0.5-14 +- fix rpc fail on large export list (bz543023). + * Mon Nov 30 2009 Ian Kent - 1:5.0.5-12 - check for path mount location in generic module. - dont fail mount on access fail.