On Sun, Mar 26, 2006 at 04:40:58PM +0200, Steinar H. Gunderson wrote:
>   http://home.samfundet.no/~sesse/dump.bad
>   http://home.samfundet.no/~sesse/dump.good
> 
> The first one is with 2.12.nfsv4-11 (from CITI); the second is with 2.12r-8
> (Debian unstable).

I looked a bit into this; ramblings ahead. :-) What fails is the client ping
after getting port 2049. The bad dump probes for NFSv3, which the user server
doesn't support; the good dump probes for NFSv2. If I mount using -o
nfsvers=2, the mount goes through.

In other words, the fallback from v3 -> v2 isn't working. This is probably
because somewhere along the path, pm_vers gets set to 3; if I force it to 0
inside probe_port(), the mount works fine. So, what's forcing this? More
printf debugging shows that it gets set in probe_bothports():

        nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);

This is a loop through all the different versions we'd support (in this case,
3 and 2, in that order). However, it exits early, since we get an unexpected
error message:

        if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED)
                break;

Actually, rpc_createerr.cf_stat is 0, which indicates success. However,
Ethereal indicates that we definitely didn't have any success; the accept
state is "remote can't support version # (2)". At this point, we're into RPC
stuff I don't really understand, but it looks to me as if it's simply not
there we'd expect the error to be. clnt_ping() (which raises the error in the
first place) does _not_ check for rpc_createerr.cf_stat; rather, it checks
the return value of the clnt_call():

        if (stat != RPC_PROGVERSMISMATCH)
                return 1;

It looks to me as if the error check in probe_bothports() is simply wrong; it
thinks that if it didn't receive "program not registered", something
unexpected and dangerous happened, so it's best to abort right away.
Something should signal the "RPC_PROGVERSMISMATCH" error to it, and the bug
should go away. If I simply do a

        rpc_createerr.cf_stat = stat;

after the clnt_call(), and then in probe_bothports() change the if to

        if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED && 
            rpc_createerr.cf_stat != RPC_PROGVERSMISMATCH)

it works as expected. This is a hack, of course, but I guess it should be
easy enough for either Lamont or Trond to figure out the right patch from
this.

/* Steinar */
-- 
Homepage: http://www.sesse.net/


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to