From 917cd9a5532d90745d94045f49ee49d0a7636d6d Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Mon, 11 Jan 2010 18:26:41 -0500 Subject: [PATCH] showmount: Try the highest mount version then fall back to lower ones Showmount should try the highest mount version first then fall back to the lower ones when the server returns a RPC_PROGVERSMISMATCH error. The idea being not using the lower mount versions will begin the process of moving away from NFSv2 support. Reviewed-by: Chuck Lever Signed-off-by: Steve Dickson --- utils/showmount/showmount.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/utils/showmount/showmount.c b/utils/showmount/showmount.c index 418e8b9..f567093 100644 --- a/utils/showmount/showmount.c +++ b/utils/showmount/showmount.c @@ -78,29 +78,36 @@ static void usage(FILE *fp, int n) exit(n); } -static const char *nfs_sm_pgmtbl[] = { +static const char *mount_pgm_tbl[] = { "showmount", "mount", "mountd", NULL, }; +static const rpcvers_t mount_vers_tbl[] = { + MOUNTVERS_NFSV3, + MOUNTVERS_POSIX, + MOUNTVERS, +}; +static const unsigned int max_vers_tblsz = + (sizeof(mount_vers_tbl)/sizeof(mount_vers_tbl[0])); + /* * Generate an RPC client handle connected to the mountd service * at @hostname, or die trying. * * Supports both AF_INET and AF_INET6 server addresses. */ -static CLIENT *nfs_get_mount_client(const char *hostname) +static CLIENT *nfs_get_mount_client(const char *hostname, rpcvers_t vers) { - rpcprog_t program = nfs_getrpcbyname(MOUNTPROG, nfs_sm_pgmtbl); + rpcprog_t program = nfs_getrpcbyname(MOUNTPROG, mount_pgm_tbl); CLIENT *client; - client = clnt_create(hostname, program, MOUNTVERS, "tcp"); + client = clnt_create(hostname, program, vers, "tcp"); if (client) return client; - - client = clnt_create(hostname, program, MOUNTVERS, "udp"); + client = clnt_create(hostname, program, vers, "udp"); if (client) return client; @@ -123,6 +130,7 @@ int main(int argc, char **argv) int i; int n; int maxlen; + int unsigned vers=0; char **dumpv; program_name = argv[0]; @@ -185,11 +193,12 @@ int main(int argc, char **argv) break; } - mclient = nfs_get_mount_client(hostname); + mclient = nfs_get_mount_client(hostname, mount_vers_tbl[vers]); mclient->cl_auth = authunix_create_default(); total_timeout.tv_sec = TOTAL_TIMEOUT; total_timeout.tv_usec = 0; +again: if (eflag) { memset(&exportlist, '\0', sizeof(exportlist)); @@ -197,6 +206,13 @@ int main(int argc, char **argv) (xdrproc_t) xdr_void, NULL, (xdrproc_t) xdr_exports, (caddr_t) &exportlist, total_timeout); + if (clnt_stat == RPC_PROGVERSMISMATCH) { + if (++vers < max_vers_tblsz) { + (void)CLNT_CONTROL(mclient, CLSET_VERS, + (void *)&mount_vers_tbl[vers]); + goto again; + } + } if (clnt_stat != RPC_SUCCESS) { clnt_perror(mclient, "rpc mount export"); clnt_destroy(mclient); @@ -232,6 +248,13 @@ int main(int argc, char **argv) (xdrproc_t) xdr_void, NULL, (xdrproc_t) xdr_mountlist, (caddr_t) &dumplist, total_timeout); + if (clnt_stat == RPC_PROGVERSMISMATCH) { + if (++vers < max_vers_tblsz) { + (void)CLNT_CONTROL(mclient, CLSET_VERS, + (void *)&mount_vers_tbl[vers]); + goto again; + } + } if (clnt_stat != RPC_SUCCESS) { clnt_perror(mclient, "rpc mount dump"); clnt_destroy(mclient); -- 2.39.2