2023-08-31 17:05:30

by Russell Cattelan

[permalink] [raw]
Subject: Re: Question on RPC_TASK_NO_RETRANS_TIMEOUT / NFS_CS_NO_RETRANS_TIMEOUT for NFSv3



On 8/26/23 10:30 AM, Trond Myklebust wrote:

> Yes. For instance the Linux knfsd server will drop requests if the GSS
> sequence number lies outside the window (no, I don't know why it
> doesn't just return RPCSEC_GSS_CTXPROBLEM). It will also happily drop
> deferred requests (i.e. requests waiting for a reply to an upcall) once
> they start piling up. Finally, if the knfsd reply cache says that an
> earlier transmission of the NFSv3 RPC request is still being processed,
> then the new request gets dropped.
>
>> Wouldn't the rpc code behave the same as v4 and setup a new
>> connection
>> before doing the retrans?
>> At least in our experimentation if we leave the connection down for
>> more
>> 63 seconds we can see from the rpc traces that is what is happening.
>> Once there is a new connection then old message is ignored and
>> processing continues with the new set request / responses.
>>
>>>
>>> The right thing to do is to just fix up rpc_decode_header() to
>>> retry
>>> instead of firing off an error in this case.
>> So you are thinking that rpc_decode_header just returns EAGAIN if the
>> checksum fails?
>> What happens if the GSS context actually goes bad (times out etc)
>> wouldn't that also result in the client get stuck just doing re-sends
>> over and over?
>
> If the GSS context goes bad, then the server is supposed to return
> either RPCSEC_GSS_CREDPROBLEM (if the server no longer has context for
> that handle) or RPCSEC_GSS_CTXPROBLEM (context is stale due to ticket
> expiry, etc).

Test environment got reset so took a day or so try this.

I change the return when rpcauth_checkverf fails to be a EKEYREJECTED
error vs EAGAIN

Which puts the decode failure down this path vs just re-transmitting the
same XID but with a new GSS sequence / checksum.

case -EKEYREJECTED:
task->tk_action = call_reserve;
rpc_check_timeout(task);
rpcauth_invalcred(task);
/* Ensure we obtain a new XID if we retry! */
xprt_release(task);

This does appear to work / address the failure that we are able
to introduce with iptable down ; iptables up.

But question is this a valid thing to do when the gss checksum fails?


diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index ad3e9a40b061..d0bcb6c6b3df 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -2645,7 +2645,8 @@ rpc_decode_header(struct rpc_task *task, struct
xdr_stream *xdr)

out_verifier:
trace_rpc_bad_verifier(task);
- goto out_garbage;
+ return -EKEYREJECTED;
+ //goto out_garbage;

out_msg_denied:
error = -EACCES;



>
> If it just times out, then surely the replay cache should ensure that
> it gets processed quickly after a retry, no?
>
>>
>> I'm really not that up to speed on subtleties of NFS kerberos.
>>
>> Oh note this isn't even krb5p just krb5 mounts. (not that should
>> matter
>> all that much)
>>
>> --Russell Cattelan
>