Subject: RE: NFS4ERR_BADHANDLE

From: "Noveck, Dave" <[email-masked]>
Date: Wed, 28 Nov 2001 06:37:52 -0800

I think the situation with regard to STALE is not quite as
ugly as you make out.  You don't need to explicitly distinguish 
in your testing between the various types of implementations.

You are going to have to be able to issue all of those 
operations to test the cases in which the filehandle is valid,
in any case.  Presumably, the code to do those will be parametrized
so that it can be tested with a stale filehandle as well as a 
valid one.  In that case, you need to check for NFS4ERR_STALE
being returned for the operation as a whole and for the last
op to be either the PUTFH or the one that actually uses the
handle.  That isn't *so* bad.

If you could reliably construct a "BAD" handle, then the same
sort of logic could be used to test those cases as well.  Just
substitute NFS4ERR_BADHANDLE for NFS4ERR_STALE and you are done.

However, there is another problem that I see with testing for
the NFS4ERR_BADHANDLE error.  I don't see how it is possible
to construct a handle which is guaranteed to generate it.
The handle is opaque to the client.  So if the client doesn't
know what the format of a valid handle is, then it can't know
how to construct one which isn't valid.  Any random array of
bits might look like a STALE handle as far as the client knows,
or even be a valid file handle.  From a client's point of view,
the important thing is that a server never return BADHANDLE
when presented with any handle that the client receieved from
the server and that the server does not lose its mind when a
handle is presented, no matter how wierd.  I think those are
the things that it is most important to test for.

-----Original Message-----
From: Peter Åstrand [mailto:[email-masked]]
Sent: Wednesday, November 28, 2001 4:35 AM
To: [email-masked]
Subject: Re: NFS4ERR_BADHANDLE

> > For NFS4ERR_BADHANDLE, most of that doesn't apply.  Handles
> > can't become bad in the middle of a COMPOUND, so we could
> > require that this check be made at PUTFH time and remove
> > the errors from the point of use.  Or we could handle
> > BADHANDLE like STALE and give servers their choice about
> > when they wanted to check for this. 
> 
> I prefer that we leave this to implementation choice.  The advantage
> of requiring the check at PUTFH doesn't seem necessary since the
> client needs to deal with STALE errors already for the reasons you
> have provided.

Thanks for good explanations. My preferences would be to require the check
to be done at PUTFH time only. Limiting the number of possible errors is a
good thing, IMHO. Allowing NFS4ERR_BADHANDLE for 20 operations or so just
with the motivation that NFS4ERR_STALE can occur, which is similiar,
sounds strange.

If the spec. does not specify if PUTFH should return NFS4ERR_BADHANDLE or 
not for a BAD handle, this makes testing harder. I have to distinguish 
between two types of implementations:

1) With implementations that does the check at PUTFH time, it's sufficient
with one single testcase to trigger NFS4ERR_BADHANDLE. 

2) With implementations that does the check later, on some other 
operation, I have to write testcases for each of those operations which 
can return NFS4ERR_BADHANDLE. This means something like 20 testcases. 

I also have to write code to distinguish between these two types of
implementations and since test cases should not depend on each other, the
check for which type if implementation we are testing has to be done at
every of these 20 operations that can return NFS4ERR_BADHANDLE. Not
pretty.

In general, I think the protocol should be always "deterministic", unless
there is a good reason for it not to be. For NFS4ERR_STALE, there is a
reason for leaving the behaviour as an implementation choice[1], but I
cannot clearly see the advantage of not defining when the check for
NFS4ERR_BADHANDLE should be done.

([1]: I actually would prefer that NFS4ERR_STALE would be removed from
PUTFH also, ie that PUTFH should not check for stale fh:s. The performance
gain for allowing the check to be done at PUTFH instead of at operation
time will probably be small. And wouldn't it be possible for servers to
internally do the check at PUTFH time, save the result, but not returning
it until some operation is trying to use it?)

-- 
Peter Åstrand                Telephone: +46-13-21 46 00
Cendio Systems               E-mail: [email-masked]
Teknikringen 3
583 30 Linköping
Sweden

---

From: Peter Åstrand <[email-masked]>
Date: Wed, 28 Nov 2001 16:35:01 +0100 (CET)

> handle.  That isn't *so* bad.

Well, I suppose you are right, at least in practice. I'm using a bit of 
formalia and doing equivalence partitioning on all input parameters. (cfh) 
is such an parameter. If (cfh) by any chance can be BAD, this should lead 
to a new equivalence class. Each class means a few lines of
documentation and a new test case, with my current way of doing things. 

With the current spec, both PUTFH and ops like ACCESS can generate
BADHANDLE. With implementations that does the check on PUTFH, it's not
possible to verify that ACCESS returns BADHANDLE upon bad (cfh). With
implementations that does the check on ACCESS, it's not possible trigger
PUTFH to return BADHANDLE. Well, it will never do that. But it leaves
holes in the equivalence partitioning coverage, which looks ugly. 

So maybe this is not a big problem in practice, but I thought I should let
you know.

> However, there is another problem that I see with testing for the
> NFS4ERR_BADHANDLE error.  I don't see how it is possible to construct
> a handle which is guaranteed to generate it. The handle is opaque to
> the client.  So if the client doesn't know what the format of a valid
> handle is, then it can't know how to construct one which isn't valid.  

True.