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;
}
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox