Linux NFS development
 help / color / mirror / Atom feed
From: Neil Brown <neilb@suse.de>
To: Jeff Layton <jlayton@poochiereds.net>
Cc: nfs@lists.sourceforge.net, Steve Dickson <SteveD@redhat.com>
Subject: Re: [PATCH 09/11] nfs-utils: mount: Fixed mounts to multi-home servers
Date: Thu, 1 Mar 2007 12:48:34 +1100	[thread overview]
Message-ID: <17894.12530.165078.511522@notabene.brown> (raw)
In-Reply-To: message from Jeff Layton on Tuesday February 27

On Tuesday February 27, jlayton@poochiereds.net wrote:
> 
> I know we saw this with Solaris servers in particular (it's been a 
> while, but I think I was testing against Solaris 8). The fedora BZ is 
> here if you want to see all the gory details:
> 
> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=212471
> 
> I'm thinking we will have to deal with this situation, unfortunately, so 
> maybe disconnecting the socket after getting the address is the best thing?
> 
> -- Jeff

Thanks for the link... Looks like we do need to be very careful about
connecting UDP sockets.

This patch maybe?

NeilBrown


diff --git a/support/include/conn.h b/support/include/conn.h
index 1761dc4..11f16ab 100644
--- a/support/include/conn.h
+++ b/support/include/conn.h
@@ -35,7 +35,7 @@ int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int,
 	      struct sockaddr_in *);
 u_long nfsvers_to_mnt(const u_long);
 u_long mntvers_to_nfs(const u_long);
-int get_socket(struct sockaddr_in *, u_int, int);
+int get_socket(struct sockaddr_in *, u_int, int, int);
 CLIENT * mnt_openclnt(clnt_addr_t *, int *);
 void mnt_closeclnt(CLIENT *, int);
 
diff --git a/support/nfs/conn.c b/support/nfs/conn.c
index 89f7676..1020b47 100644
--- a/support/nfs/conn.c
+++ b/support/nfs/conn.c
@@ -49,7 +49,7 @@ u_long mntvers_to_nfs(const u_long vers)
  * RPC_ANYSOCK is returned which will cause 
  * the RPC code to create the socket instead. 
  */
-int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)
+int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp, int conn)
 {
 	int so, cc, type;
 	struct sockaddr_in laddr;
@@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)
 			return RPC_ANYSOCK;
 		}
 	}
-	if (type == SOCK_STREAM || type == SOCK_DGRAM) {
+	if (type == SOCK_STREAM || (conn && type == SOCK_DGRAM)) {
 		cc = connect(so, (struct sockaddr *)saddr, namelen);
 		if (cc < 0) {
 			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
@@ -129,9 +129,10 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
 	CLIENT *clnt=NULL;
 	int sock, stat;
 	static char clnt_res;
+	struct sockaddr dissolve;
 
 	rpc_createerr.cf_stat = stat = errno = 0;
-	sock = get_socket(saddr, prot, FALSE);
+	sock = get_socket(saddr, prot, FALSE, TRUE);
 	if (sock == RPC_ANYSOCK && errno == ETIMEDOUT) {
 		/*
 		 * TCP timeout. Bubble up the error to see 
@@ -141,8 +142,22 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
 		goto out_bad;
 	}
 
+	if (caddr) {
+		/* Get the address of our end of this connection */
+		socklen_t len = sizeof(*caddr);
+		if (getsockname(sock, caddr, &len) != 0)
+			caddr->sin_family = 0;
+	}
+
 	switch(prot) {
 	case IPPROTO_UDP:
+		/* The socket is connected (so we could getsockname successfully),
+		 * but some servers on multi-homed hosts reply from
+		 * the wrong address, so if we stay connected, we lose the reply.
+		 */
+		dissolve.sa_family = AF_UNSPEC;
+		connect(sock, &dissolve, sizeof(dissolve));
+
 		clnt = clntudp_bufcreate(saddr, prog, vers,
 					 RETRY_TIMEOUT, &sock,
 					 RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
@@ -166,15 +181,7 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
 		rpc_createerr.cf_stat = stat;
 	}
 	clnt_destroy(clnt);
-	if (sock != -1) {
-		if (caddr) {
-			/* Get the address of our end of this connection */
-			socklen_t len = sizeof(*caddr);
-			if (getsockname(sock, caddr, &len) != 0)
-				caddr->sin_family = 0;
-		}
-		close(sock);
-	}
+	close(sock);
 
 	if (stat == RPC_SUCCESS)
 		return 1;
@@ -191,7 +198,7 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
 
 	/* contact the mount daemon via TCP */
 	mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
-	*msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE);
+	*msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE, FALSE);
 
 	switch (mnt_pmap->pm_prot) {
 	case IPPROTO_UDP:
diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c
index 507ccdb..0f66bdf 100644
--- a/utils/mount/nfsmount.c
+++ b/utils/mount/nfsmount.c
@@ -306,7 +306,7 @@ getport(
 	enum clnt_stat stat;
 
 	saddr->sin_port = htons (PMAPPORT);
-	socket = get_socket(saddr, prot, FALSE);
+	socket = get_socket(saddr, prot, FALSE, FALSE);
 
 	switch (prot) {
 	case IPPROTO_UDP:

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

  reply	other threads:[~2007-03-01  1:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-26 11:18 [PATCH 09/11] nfs-utils: mount: Fixed mounts to multi-home servers Steve Dickson
2007-02-27  6:32 ` Neil Brown
2007-02-27 18:12   ` Jeff Layton
2007-03-01  1:48     ` Neil Brown [this message]
2007-03-11 19:58       ` Jeff Layton
2007-03-11 22:38         ` Neil Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=17894.12530.165078.511522@notabene.brown \
    --to=neilb@suse.de \
    --cc=SteveD@redhat.com \
    --cc=jlayton@poochiereds.net \
    --cc=nfs@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox