[PATCH 2/2] showmount: Use CLNT_CONTROL for version fallback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When retrying MNT requests with lower RPC protocol versions, the
showmount command leaves several TCP sockets in TIME_WAIT:  at least
one socket for each rpcbind GETPORT call, and one for each attempted
MNT request.  Note that TIME_WAIT sockets may not be a problem on
an individual client, but this does tie up potentially valuable
network resources on the server for up to 120 seconds.

To reduce the resources required when retrying, downshift the RPC
protocol version of the existing RPC client using CLNT_CONTROL(),
rather than creating a new RPC client for each RPC protocol version.

Without this patch, "showmount -e" targeting a TCP-capable server with
a single export takes 64 packets and leaves 6 sockets in TIME_WAIT if
the server supports only MNTv1.  With it, showmount takes 29 packets
and leaves two TIME_WAIT sockets.

Newer versions of libtirpc will reduce that by one more socket (on
IPv4), and a handful of packets.

Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---

 utils/showmount/showmount.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/utils/showmount/showmount.c b/utils/showmount/showmount.c
index 652aa85..343f94b 100644
--- a/utils/showmount/showmount.c
+++ b/utils/showmount/showmount.c
@@ -193,12 +193,12 @@ int main(int argc, char **argv)
 		break;
 	}
 
-again:
 	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));
 
@@ -207,8 +207,11 @@ again:
 			(xdrproc_t) xdr_exports, (caddr_t) &exportlist,
 			total_timeout);
 		if (clnt_stat == RPC_PROGVERSMISMATCH) {
-			if (++vers <  max_vers_tblsz)
+			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");
@@ -246,8 +249,11 @@ again:
 		(xdrproc_t) xdr_mountlist, (caddr_t) &dumplist,
 		total_timeout);
 	if (clnt_stat == RPC_PROGVERSMISMATCH) {
-		if (++vers <  max_vers_tblsz)
+		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");

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux