Hi Jeffrey,

> Thank you for publishing the I-D which might be misnamed.

Ack.


Although it is true that IBM as part of the AFS 3.5 release repurposed struct 
nvldbentry.spares1 as nvldbentry.matchindex the field is only defined for use 
as part of a new RPC: VL_ListAttributesN2.  Best practice is not to modify the 
semantics of the structures used in existing RPCs.  Instead, new RPCs should be 
allocated to indicate that the caller understands the new semantics.   If the 
new RPC is supported by the server, then it will be executed with the expected 
semantics.  Otherwise, RXGEN_OPCODE is returned indicating to the caller that 
the requested functionality is unavailable.  The caller then falls back to an 
older version of the RPC.

In general, service capability bits should not be used for the purpose of 
altering the behavior of existing RPCs.   The allocation of 
CLiENT_CAPABILITY_ERRORTRANS when queried by the fileserver is used to alter 
the output of RXAFS RPCs based upon whether or not the client understands the 
portable UAE error tables.   The VICED_CAPABILITY_ERRORTRANS informs the client 
whether or not the server is capable of returning UAE error codes.   If 
VICED_CAPABILITY_ERRORTRANS is unavailable the client needs to be careful with 
processing the return codes because the fileserver's OS error code assignments 
might not match those of the caller.

Service capability bits for UBIK services are particularly problematic because 
there is no requirement that all servers in the cell run the same version.   
Lets say that VL_CAPABILITY_LOCKTIMESTAMP was allocated for the purpose of 
indicating that nvldbentry.spares2 is a non-zero timestamp value if the entry 
is locked.   There is no guarantee that the VL_GetCapabilities RPC result will 
be returned from the same server that responded to the VL_GetEntryByIDN RPC.   
If VL_CAPABILITY_LOCKTIMESTAMP was set on the server that responded to 
VL_GetCapabilities but the server responding to VL_GetEntryByIDN is older and 
doesn't support that behavior, then the caller might believe that the zero 
nvldbentry.spares2 field indicates that the entry isn't locked.

For UBIK services, the callers are not told which server responded to a given 
RPC.   The only way of knowing if a new behavior was supported is to issue a 
new RPC and fallback to an older RPC if it is unavailable.

After the introduction of ubik_CallRock(), we can insert additional code to run
before relevant RPC. As an example:

ListAttributesN3(conn, ...)
{
    code = VL_GetCapabilities(conn, &caps);

    if (code != 0) return code;
    if ((caps[0] & LOCKTIMESTAMP) == 0) return -1;

    return VL_ListAttributesN(conn, ...);
}

VLDB_ListAttributesN3(...)
{
    return ubik_CallRock(cstruct, 0, ListAttributesN3, &args);
}

Thank you for sharing your thoughts, your feedback is always appreciated.
Marcio Barbosa.

Reply via email to