On Sep 6, 2010, at 9:32 PM, Neil Brown wrote: > On Tue, 31 Aug 2010 12:38:09 -0400 > Chuck Lever <chuck.lever@xxxxxxxxxx> 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. My impression is that today RDMA is stable only on vers=3; someday it should be stable with vers=4 too. I think Steve and I need to agree on the final form of the RDMA patches before we can say with authority how fallback will work. > 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? nfs_try_mount_v4() will try all address families provided by getaddrinfo(3). So when ECONNREFUSED finally bubbles up to nfs_try_mount(), mount.nfs should have already tried NFSv4 via both tcp and tcp6. Anyway, this seems to answer my original question about "what are the risks of trying the portmapper-based approach?" It looks like a complex solution no matter what. I'm not suggesting you abandon this direction, but if the nfs_try_mount() logic does nothing more but fallback to v2/v3 if the NFSv4 mount attempt fails with ECONNREFUSED, what harm could that cause? > From 60dae9b9c14869ae630db683e2524ad230064b19 Mon Sep 17 00:00:00 2001 > From: Neil Brown <neilb@xxxxxxx> > 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@xxxxxxx> > > 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; > } -- chuck[dot]lever[at]oracle[dot]com -- 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