Ian Kent 4a8919
autofs-5.0.5 - fix mountd vers retry
Ian Kent 4a8919
Ian Kent 4a8919
From: Ian Kent <raven@themaw.net>
Ian Kent 4a8919
Ian Kent 4a8919
The autofs RPC function used to get the exports list from a host to
Ian Kent 4a8919
be used by the hosts internal map did not try all potentially available
Ian Kent 4a8919
mountd versions. This leads to a failure to get the export list when
Ian Kent 4a8919
certain mountd protocol versions are disabled.
Ian Kent 4a8919
---
Ian Kent 4a8919
Ian Kent 4a8919
 CHANGELOG      |    1 +
Ian Kent 4a8919
 lib/rpc_subs.c |   26 +++++++++++++++++++++-----
Ian Kent 4a8919
 2 files changed, 22 insertions(+), 5 deletions(-)
Ian Kent 4a8919
Ian Kent 4a8919
Ian Kent 4a8919
--- autofs-5.0.5.orig/CHANGELOG
Ian Kent 4a8919
+++ autofs-5.0.5/CHANGELOG
Ian Kent 4a8919
@@ -58,6 +58,7 @@
Ian Kent 4a8919
 - fix isspace() wild card substition.
Ian Kent 4a8919
 - auto adjust ldap page size.
Ian Kent 4a8919
 - fix prune cache valid check.
Ian Kent 4a8919
+- fix mountd vers retry.
Ian Kent 4a8919
 
Ian Kent 4a8919
 03/09/2009 autofs-5.0.5
Ian Kent 4a8919
 -----------------------
Ian Kent 4a8919
--- autofs-5.0.5.orig/lib/rpc_subs.c
Ian Kent 4a8919
+++ autofs-5.0.5/lib/rpc_subs.c
Ian Kent 4a8919
@@ -53,6 +53,12 @@
Ian Kent 4a8919
 /* Get numeric value of the n bits starting at position p */
Ian Kent 4a8919
 #define getbits(x, p, n)      ((x >> (p + 1 - n)) & ~(~0 << n))
Ian Kent 4a8919
 
Ian Kent 4a8919
+static const rpcvers_t mount_vers[] = {
Ian Kent 4a8919
+        MOUNTVERS_NFSV3,
Ian Kent 4a8919
+        MOUNTVERS_POSIX,
Ian Kent 4a8919
+        MOUNTVERS,
Ian Kent 4a8919
+};
Ian Kent 4a8919
+
Ian Kent 4a8919
 static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *);
Ian Kent 4a8919
 inline void dump_core(void);
Ian Kent 4a8919
 
Ian Kent 4a8919
@@ -846,6 +852,7 @@ static int rpc_get_exports_proto(struct 
Ian Kent 4a8919
 	enum clnt_stat status;
Ian Kent 4a8919
 	int proto = info->proto->p_proto;
Ian Kent 4a8919
 	unsigned int option = info->close_option;
Ian Kent 4a8919
+	int vers_entry;
Ian Kent 4a8919
 
Ian Kent 4a8919
 	if (info->proto->p_proto == IPPROTO_UDP) {
Ian Kent 4a8919
 		info->send_sz = UDPMSGSIZE;
Ian Kent 4a8919
@@ -862,10 +869,19 @@ static int rpc_get_exports_proto(struct 
Ian Kent 4a8919
 
Ian Kent 4a8919
 	client->cl_auth = authunix_create_default();
Ian Kent 4a8919
 
Ian Kent 4a8919
-	status = clnt_call(client, MOUNTPROC_EXPORT,
Ian Kent 4a8919
-			 (xdrproc_t) xdr_void, NULL,
Ian Kent 4a8919
-			 (xdrproc_t) xdr_exports, (caddr_t) exp,
Ian Kent 4a8919
-			 info->timeout);
Ian Kent 4a8919
+	vers_entry = 0;
Ian Kent 4a8919
+	while (1) {
Ian Kent 4a8919
+		status = clnt_call(client, MOUNTPROC_EXPORT,
Ian Kent 4a8919
+				 (xdrproc_t) xdr_void, NULL,
Ian Kent 4a8919
+				 (xdrproc_t) xdr_exports, (caddr_t) exp,
Ian Kent 4a8919
+				 info->timeout);
Ian Kent 4a8919
+		if (status != RPC_PROGVERSMISMATCH)
Ian Kent 4a8919
+			break;
Ian Kent 4a8919
+		if (++vers_entry > 2)
Ian Kent 4a8919
+			break;
Ian Kent 4a8919
+		CLNT_CONTROL(client, CLSET_VERS,
Ian Kent 4a8919
+			    (void *) &mount_vers[vers_entry]);
Ian Kent 4a8919
+	}
Ian Kent 4a8919
 
Ian Kent 4a8919
 	/* Only play with the close options if we think it completed OK */
Ian Kent 4a8919
 	if (proto == IPPROTO_TCP && status == RPC_SUCCESS) {
Ian Kent 4a8919
@@ -934,7 +950,7 @@ exports rpc_get_exports(const char *host
Ian Kent 4a8919
 	info.addr = NULL;
Ian Kent 4a8919
 	info.addr_len = 0;
Ian Kent 4a8919
 	info.program = MOUNTPROG;
Ian Kent 4a8919
-	info.version = MOUNTVERS;
Ian Kent 4a8919
+	info.version = mount_vers[0];
Ian Kent 4a8919
 	info.send_sz = 0;
Ian Kent 4a8919
 	info.recv_sz = 0;
Ian Kent 4a8919
 	info.timeout.tv_sec = seconds;