All of lore.kernel.org
 help / color / mirror / Atom feed
From: Neil Brown <neilb@suse.de>
To: Chuck Lever <chuck.lever@oracle.com>
Cc: Linux NFS Mailing list <linux-nfs@vger.kernel.org>
Subject: Re: mount.nfs: protocol fallback when server doesn't support TCP
Date: Tue, 7 Sep 2010 11:32:25 +1000	[thread overview]
Message-ID: <20100907113225.4a018ba3@notabene> (raw)
In-Reply-To: <EC686BD1-834D-4060-84E7-FBF0733B7ACA@oracle.com>

On Tue, 31 Aug 2010 12:38:09 -0400
Chuck Lever <chuck.lever@oracle.com> wrote:


> >> 
> >>> +						/* OK to try different protocols. Lets see
> >>> +						 * what portmap thinks.
> >>> +						 */
> >>> +						int oldfake = mi->fake;
> >>> +						int res;
> >>> +						mi->fake = 1;
> >>> +						res = nfs_try_mount_v3v2(mi);
> >> 
> >> If you just want to probe the server's portmapper, I think you can use nfs_probe_bothports() directly.
> >> 
> > 
> > Not quite.  You would need to wrap it in a loop over all addresses in
> > md->address, and would need to worry about the mounthost option.  It seems
> > easier to just call nfs_try_mount_v3v2 which already does this.
> 
> /me smacks forehead
> 
> Complexity that I guess we have to live with.  A comment that explains the oldfake hack would be helpful.

And often trying to write such a comment can make it clear why the code was a
bad idea in the first place.... :-)

Rather than write a comment I wouldn't believe myself, here is something
quite different - my third draft.
This is on top of the nice tidy-up patches you posted earlier.

It uses nfs_getport to make very focussed requests to portmap.

Two things I'm still not really sure about:

1/ RDMA.  How does that interact with fallback.  Do we only support v4 over
   RDMA?  That would be nice was we could simply avoid fallback in that case.

2/ IPv6.  I should possibly be checking if v3v2 are available via UDP6 as well
   as UDP - and similarly if v4 has become available via TCP6?? Or is that
   all magically handled somewhere under the hood?

Thanks,
NeilBrown

>From 60dae9b9c14869ae630db683e2524ad230064b19 Mon Sep 17 00:00:00 2001
From: Neil Brown <neilb@suse.de>
Date: Tue, 7 Sep 2010 11:23:02 +1000
Subject: [PATCH] mount: correctly handle fallback for  ECONNREFUSED during mount attempt.

If we get ECONNREFUSED when attempting a v4 mount, it could be that
the server just isn't ready yet (the current assumption) or it could
be that the server only support UDP - and thus only v3/v2.  The latter
possibility isn't handled currently.

So if we get ECONNREFUSED when fallback is an option, check with
portmap/rpcbind to see if it could be that case that v2/v3 are
supported over UDP, and v4 still is not.  In that case, fall back to v2v3.

I'm not at all sure if IPv6 possibilities are RDMA are handled correctly..

Signed-off-by: NeilBrown <neilb@suse.de>

diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 9e29a19..5ebcf3e 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -750,6 +750,7 @@ static int nfs_autonegotiate(struct nfsmount_info *mi)
 {
 	unsigned long protocol;
 	int result;
+	struct addrinfo *ai;
 
 	/*
 	 * If UDP was requested from the command line, try
@@ -796,6 +797,33 @@ static int nfs_autonegotiate(struct nfsmount_info *mi)
 		/* Linux servers prior to 2.6.25 may return
 		 * EPERM when NFS version 4 is not supported. */
 		goto fall_back;
+	case ECONNREFUSED:
+		/* Either the server doesn't accept TCP connections,
+		 * or it just isn't quite ready yet.
+		 * In the first case, fall back to v3v2, in the second
+		 * return failure - as this isn't a permanent error
+		 * the attempt will be retried.
+		 * To determine which, we need to check with portmap/rpcbind.
+		 * If v2 or v3 are supported on UDP, but v4 isn't on TCP then fall-back.
+		 */
+		for (ai = mi->address; ai != NULL; ai = ai->ai_next) {
+			if (nfs_getport(ai->ai_addr, ai->ai_addrlen,
+					NFS_PROGRAM, 3, IPPROTO_UDP) != 0 ||
+			    nfs_getport(ai->ai_addr, ai->ai_addrlen,
+					NFS_PROGRAM, 2, IPPROTO_UDP) != 0) {
+				if (nfs_getport(ai->ai_addr, ai->ai_addrlen,
+						NFS_PROGRAM, 4, IPPROTO_TCP) != 0) {
+					/* v4 support is almost online, wait for it. */
+					errno = ECONNREFUSED;
+					return result;
+				} else
+					/* v2/v3 is supported, but v4 isn't, fall_back */
+					goto fall_back;
+			}
+		}
+		/* portmap is not responding yet either, so just try again */
+		errno = ECONNREFUSED;
+		return result;
 	default:
 		return result;
 	}

  reply	other threads:[~2010-09-07  1:32 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-26  2:06 mount.nfs: protocol fallback when server doesn't support TCP Neil Brown
2010-08-26 14:51 ` Chuck Lever
2010-08-26 15:27   ` Jim Rees
2010-08-26 16:09     ` Chuck Lever
2010-08-30  0:30   ` Neil Brown
2010-08-30 19:29     ` Chuck Lever
2010-08-31  1:00       ` Neil Brown
2010-08-31 16:38         ` Chuck Lever
2010-09-07  1:32           ` Neil Brown [this message]
2010-09-07 17:37             ` Chuck Lever
2010-09-08  2:35               ` Neil Brown
2010-09-08 18:52                 ` Chuck Lever
2010-08-31 20:29         ` Chuck Lever
2010-09-07  0:02           ` 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=20100907113225.4a018ba3@notabene \
    --to=neilb@suse.de \
    --cc=chuck.lever@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.