Linux NFS development
 help / color / mirror / Atom feed
* [PATCH 0/4] Make mount.nfs use new getport() function
@ 2008-12-01 18:48 Chuck Lever
       [not found] ` <20081201183616.10436.71066.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Chuck Lever @ 2008-12-01 18:48 UTC (permalink / raw)
  To: steved, linux-nfs

Hi Steve-

Four new IPv6-related patches for mount.nfs.  These replace the
existing PMAP_GETPORT implementation in utils/mount/network.c with a
call to the new library functions we just added.

The probe_statd() function is used by both the legacy and the text-
based paths, but replacing the mount.nfs command's getport() function
affects only the *legacy* NFS mount path, not text-based mounts.

For anyone testing this code, please try it on pre-2.6.23 kernels,
or patch mount.nfs to use legacy binary style mounts.  This will
exercise the new PMAP_GETPORT implementation using all the special
cases needed by mount.nfs.

The new RPCB_GETADDR implementation will not be used until mount.nfs
can pass in IPv6 addresses.

---

Chuck Lever (4):
      mount command: remove local getport() implementation
      mount command: Replace clnt_ping() and getport() calls in probe_port()
      mount command: Use nfs_error() instead of perror()
      mount command: Use nfs_pmap_getport() in probe_statd()


 utils/mount/network.c |  144 +++++++++++++++----------------------------------
 1 files changed, 43 insertions(+), 101 deletions(-)

-- 
Chuck Lever

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] mount command: Use nfs_pmap_getport() in probe_statd()
       [not found] ` <20081201183616.10436.71066.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2008-12-01 18:48   ` Chuck Lever
  2008-12-01 18:48   ` [PATCH 2/4] mount command: Use nfs_error() instead of perror() Chuck Lever
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever @ 2008-12-01 18:48 UTC (permalink / raw)
  To: steved, linux-nfs

Repace the getport() and clnt_ping() calls in probe_statd() with their
new shared equivalents.

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

 utils/mount/network.c |   34 ++++++++++++++++------------------
 1 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/utils/mount/network.c b/utils/mount/network.c
index 806344c..0ba7bdb 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -47,6 +47,7 @@
 #include "nls.h"
 #include "nfs_mount.h"
 #include "mount_constants.h"
+#include "nfsrpc.h"
 #include "network.h"
 
 /*
@@ -79,6 +80,11 @@ extern int nfs_mount_data_version;
 extern char *progname;
 extern int verbose;
 
+static const char *nfs_ns_pgmtbl[] = {
+	"status",
+	NULL,
+};
+
 static const unsigned long nfs_to_mnt[] = {
 	0,
 	0,
@@ -669,24 +675,16 @@ version_fixed:
 	return probe_mntport(mnt_server);
 }
 
-static int probe_statd(void)
+static int nfs_probe_statd(void)
 {
-	struct sockaddr_in addr;
-	unsigned short port;
-
-	memset(&addr, 0, sizeof(addr));
-	addr.sin_family = AF_INET;
-	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-	port = getport(&addr, 100024, 1, IPPROTO_UDP);
-
-	if (port == 0)
-		return 0;
-	addr.sin_port = htons(port);
-
-	if (clnt_ping(&addr, 100024, 1, IPPROTO_UDP, NULL) <= 0)
-		return 0;
+	struct sockaddr_in addr = {
+		.sin_family		= AF_INET,
+		.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
+	};
+	rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);
 
-	return 1;
+	return nfs_getport_ping((struct sockaddr *)&addr, sizeof(addr),
+				program, (rpcvers_t)1, IPPROTO_UDP);
 }
 
 /**
@@ -700,7 +698,7 @@ int start_statd(void)
 	struct stat stb;
 #endif
 
-	if (probe_statd())
+	if (nfs_probe_statd())
 		return 1;
 
 #ifdef START_STATD
@@ -718,7 +716,7 @@ int start_statd(void)
 				waitpid(pid, NULL,0);
 				break;
 			}
-			if (probe_statd())
+			if (nfs_probe_statd())
 				return 1;
 		}
 	}


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] mount command: Use nfs_error() instead of perror()
       [not found] ` <20081201183616.10436.71066.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2008-12-01 18:48   ` [PATCH 1/4] mount command: Use nfs_pmap_getport() in probe_statd() Chuck Lever
@ 2008-12-01 18:48   ` Chuck Lever
  2008-12-01 18:48   ` [PATCH 3/4] mount command: Replace clnt_ping() and getport() calls in probe_port() Chuck Lever
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever @ 2008-12-01 18:48 UTC (permalink / raw)
  To: steved, linux-nfs

So we can ensure that error output is directed appropriately, use
nfs_error() instead of perror() in start_statd().

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

 utils/mount/network.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/utils/mount/network.c b/utils/mount/network.c
index 0ba7bdb..2231210 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -710,7 +710,8 @@ int start_statd(void)
 				execl(START_STATD, START_STATD, NULL);
 				exit(1);
 			case -1: /* error */
-				perror("Fork failed");
+				nfs_error(_("fork failed: %s"),
+							strerror(errno));
 				break;
 			default: /* parent */
 				waitpid(pid, NULL,0);


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] mount command: Replace clnt_ping() and getport() calls in probe_port()
       [not found] ` <20081201183616.10436.71066.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2008-12-01 18:48   ` [PATCH 1/4] mount command: Use nfs_pmap_getport() in probe_statd() Chuck Lever
  2008-12-01 18:48   ` [PATCH 2/4] mount command: Use nfs_error() instead of perror() Chuck Lever
@ 2008-12-01 18:48   ` Chuck Lever
  2008-12-01 18:48   ` [PATCH 4/4] mount command: remove local getport() implementation Chuck Lever
  2008-12-02 15:22   ` [PATCH 0/4] Make mount.nfs use new getport() function Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever @ 2008-12-01 18:48 UTC (permalink / raw)
  To: steved, linux-nfs

Update the mount command's probe_port() function to call the new shared
rpcbind query and RPC ping functions.  This provides immediate support for
rpcbind v3/v4 queries, and paves the way for supporting AF_INET6 in the
probe_bothports() path.

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

 utils/mount/network.c |   43 +++++++++++++++++++++++++++++--------------
 1 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/utils/mount/network.c b/utils/mount/network.c
index 2231210..8d96e12 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -521,6 +521,27 @@ static unsigned short getport(struct sockaddr_in *saddr,
 	return port;
 }
 
+static void nfs_pp_debug(const struct sockaddr *sap, const socklen_t salen,
+			 const rpcprog_t program, const rpcvers_t version,
+			 const unsigned short protocol,
+			 const unsigned short port)
+{
+	char buf[NI_MAXHOST];
+
+	if (!verbose)
+		return;
+
+	if (nfs_present_sockaddr(sap, salen, buf, sizeof(buf)) == 0) {
+		buf[0] = '\0';
+		strcat(buf, "unknown host");
+	}
+
+	fprintf(stderr, _("%s: trying %s prog %ld vers %ld prot %s port %d\n"),
+			progname, buf, program, version,
+			(protocol == IPPROTO_UDP ? _("UDP") : _("TCP")),
+			port);
+}
+
 /*
  * Use the portmapper to discover whether or not the service we want is
  * available. The lists 'versions' and 'protos' define ordered sequences
@@ -529,7 +550,8 @@ static unsigned short getport(struct sockaddr_in *saddr,
 static int probe_port(clnt_addr_t *server, const unsigned long *versions,
 			const unsigned int *protos)
 {
-	struct sockaddr_in *saddr = &server->saddr;
+	const struct sockaddr *saddr = (struct sockaddr *)&server->saddr;
+	const socklen_t salen = sizeof(server->saddr);
 	struct pmap *pmap = &server->pmap;
 	const unsigned long prog = pmap->pm_prog, *p_vers;
 	const unsigned int prot = (u_int)pmap->pm_prot, *p_prot;
@@ -541,21 +563,14 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions,
 	p_vers = vers ? &vers : versions;
 	rpc_createerr.cf_stat = 0;
 	for (;;) {
-		p_port = getport(saddr, prog, *p_vers, *p_prot);
+		p_port = nfs_getport(saddr, salen, prog, *p_vers, *p_prot);
 		if (p_port) {
 			if (!port || port == p_port) {
-				saddr->sin_port = htons(p_port);
-				if (verbose) {
-					printf(_("%s: trying %s prog %ld vers "
-						"%ld prot %s port %d\n"),
-						progname,
-						inet_ntoa(saddr->sin_addr),
-						prog, *p_vers,
-						*p_prot == IPPROTO_UDP ?
-							_("UDP") : _("TCP"),
-						p_port);
-                                }
-				if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL))
+				server->saddr.sin_port = htons(p_port);
+				nfs_pp_debug(saddr, salen, prog, *p_vers,
+						*p_prot, p_port);
+				if (nfs_rpc_ping(saddr, salen, prog,
+							*p_vers, *p_prot, NULL))
 					goto out_ok;
 			}
 		}


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] mount command: remove local getport() implementation
       [not found] ` <20081201183616.10436.71066.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (2 preceding siblings ...)
  2008-12-01 18:48   ` [PATCH 3/4] mount command: Replace clnt_ping() and getport() calls in probe_port() Chuck Lever
@ 2008-12-01 18:48   ` Chuck Lever
  2008-12-02 15:22   ` [PATCH 0/4] Make mount.nfs use new getport() function Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever @ 2008-12-01 18:48 UTC (permalink / raw)
  To: steved, linux-nfs

Eliminate local getport() implementation from utils/mount/network.c, as
it is no longer used.

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

 utils/mount/network.c |   76 +------------------------------------------------
 1 files changed, 2 insertions(+), 74 deletions(-)

diff --git a/utils/mount/network.c b/utils/mount/network.c
index 8d96e12..0c68993 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -449,78 +449,6 @@ err_connect:
 	return RPC_ANYSOCK;
 }
 
-/*
- * getport() is very similar to pmap_getport() with the exception that
- * this version tries to use an ephemeral port, since reserved ports are
- * not needed for GETPORT queries.  This conserves the very limited
- * reserved port space, which helps reduce failed socket binds
- * during mount storms.
- *
- * A side effect of calling this function is that rpccreateerr is set.
- */
-static unsigned short getport(struct sockaddr_in *saddr,
-				unsigned long program,
-				unsigned long version,
-				unsigned int proto)
-{
-	struct sockaddr_in bind_saddr;
-	unsigned short port = 0;
-	int socket;
-	CLIENT *clnt = NULL;
-	enum clnt_stat stat;
- 
-	bind_saddr = *saddr;
-	bind_saddr.sin_port = htons(PMAPPORT);
-
-	socket = get_socket(&bind_saddr, proto, PMAP_TIMEOUT, FALSE, TRUE);
-	if (socket == RPC_ANYSOCK) {
-		if (proto == IPPROTO_TCP &&
-		    rpc_createerr.cf_error.re_errno == ETIMEDOUT)
-			rpc_createerr.cf_stat = RPC_TIMEDOUT;
-		return 0;
-	}
-
-	switch (proto) {
-	case IPPROTO_UDP:
-		clnt = clntudp_bufcreate(&bind_saddr,
-					 PMAPPROG, PMAPVERS,
-					 RETRY_TIMEOUT, &socket,
-					 RPCSMALLMSGSIZE,
-					 RPCSMALLMSGSIZE);
-		break;
-	case IPPROTO_TCP:
-		clnt = clnttcp_create(&bind_saddr,
-				      PMAPPROG, PMAPVERS,
-				      &socket,
-				      RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
-		break;
-	}
-	if (clnt != NULL) {
-		struct pmap parms = {
-			.pm_prog	= program,
-			.pm_vers	= version,
-			.pm_prot	= proto,
-		};
-
-		stat = clnt_call(clnt, PMAPPROC_GETPORT,
-				 (xdrproc_t)xdr_pmap, (caddr_t)&parms,
-				 (xdrproc_t)xdr_u_short, (caddr_t)&port,
-				 TIMEOUT);
-		if (stat) {
-			clnt_geterr(clnt, &rpc_createerr.cf_error);
-			rpc_createerr.cf_stat = stat;
-		}
-		clnt_destroy(clnt);
-		if (stat != RPC_SUCCESS)
-			port = 0;
-		else if (port == 0)
-			rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
-	}
-	close(socket);
-
-	return port;
-}
-
 static void nfs_pp_debug(const struct sockaddr *sap, const socklen_t salen,
 			 const rpcprog_t program, const rpcvers_t version,
 			 const unsigned short protocol,
@@ -843,9 +771,9 @@ void mnt_closeclnt(CLIENT *clnt, int msock)
  * @prot: target RPC protocol
  * @caddr: filled in with our network address
  *
- * Sigh... getport() doesn't actually check the version number.
+ * Sigh... GETPORT queries don't actually check the version number.
  * In order to make sure that the server actually supports the service
- * we're requesting, we open and RPC client, and fire off a NULL
+ * we're requesting, we open an RPC client, and fire off a NULL
  * RPC call.
  *
  * caddr is the network address that the server will use to call us back.


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] Make mount.nfs use new getport() function
       [not found] ` <20081201183616.10436.71066.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (3 preceding siblings ...)
  2008-12-01 18:48   ` [PATCH 4/4] mount command: remove local getport() implementation Chuck Lever
@ 2008-12-02 15:22   ` Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Steve Dickson @ 2008-12-02 15:22 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs



Chuck Lever wrote:
> Hi Steve-
> 
> Four new IPv6-related patches for mount.nfs.  These replace the
> existing PMAP_GETPORT implementation in utils/mount/network.c with a
> call to the new library functions we just added.
> 
> The probe_statd() function is used by both the legacy and the text-
> based paths, but replacing the mount.nfs command's getport() function
> affects only the *legacy* NFS mount path, not text-based mounts.
> 
> For anyone testing this code, please try it on pre-2.6.23 kernels,
> or patch mount.nfs to use legacy binary style mounts.  This will
> exercise the new PMAP_GETPORT implementation using all the special
> cases needed by mount.nfs.
> 
> The new RPCB_GETADDR implementation will not be used until mount.nfs
> can pass in IPv6 addresses.
> 
> ---
> 
> Chuck Lever (4):
>       mount command: remove local getport() implementation
>       mount command: Replace clnt_ping() and getport() calls in probe_port()
>       mount command: Use nfs_error() instead of perror()
>       mount command: Use nfs_pmap_getport() in probe_statd()
Tested and Committed....

steved.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-12-02 15:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-01 18:48 [PATCH 0/4] Make mount.nfs use new getport() function Chuck Lever
     [not found] ` <20081201183616.10436.71066.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-12-01 18:48   ` [PATCH 1/4] mount command: Use nfs_pmap_getport() in probe_statd() Chuck Lever
2008-12-01 18:48   ` [PATCH 2/4] mount command: Use nfs_error() instead of perror() Chuck Lever
2008-12-01 18:48   ` [PATCH 3/4] mount command: Replace clnt_ping() and getport() calls in probe_port() Chuck Lever
2008-12-01 18:48   ` [PATCH 4/4] mount command: remove local getport() implementation Chuck Lever
2008-12-02 15:22   ` [PATCH 0/4] Make mount.nfs use new getport() function Steve Dickson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox