[AFS3-std] Request for allocation of capability bit

Marcio Barbosa mbarbosa@sinenomine.net
Sat, 27 May 2023 21:51:02 +0000


--_000_1CF79735E33548E5BA636311B528EB5Asinenominenet_
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

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 stru=
ct nvldbentry.spares1 as nvldbentry.matchindex the field is only defined fo=
r use as part of a new RPC: VL_ListAttributesN2.  Best practice is not to m=
odify the semantics of the structures used in existing RPCs.  Instead, new =
RPCs should be allocated to indicate that the caller understands the new se=
mantics.   If the new RPC is supported by the server, then it will be execu=
ted with the expected semantics.  Otherwise, RXGEN_OPCODE is returned indic=
ating to the caller that the requested functionality is unavailable.  The c=
aller then falls back to an older version of the RPC.

In general, service capability bits should not be used for the purpose of a=
ltering the behavior of existing RPCs.   The allocation of CLiENT_CAPABILIT=
Y_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 UA=
E error tables.   The VICED_CAPABILITY_ERRORTRANS informs the client whethe=
r or not the server is capable of returning UAE error codes.   If VICED_CAP=
ABILITY_ERRORTRANS is unavailable the client needs to be careful with proce=
ssing the return codes because the fileserver's OS error code assignments m=
ight not match those of the caller.

Service capability bits for UBIK services are particularly problematic beca=
use there is no requirement that all servers in the cell run the same versi=
on.   Lets say that VL_CAPABILITY_LOCKTIMESTAMP was allocated for the purpo=
se of indicating that nvldbentry.spares2 is a non-zero timestamp value if t=
he 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_GetE=
ntryByIDN RPC.   If VL_CAPABILITY_LOCKTIMESTAMP was set on the server that =
responded to VL_GetCapabilities but the server responding to VL_GetEntryByI=
DN is older and doesn't support that behavior, then the caller might believ=
e that the zero nvldbentry.spares2 field indicates that the entry isn't loc=
ked.

For UBIK services, the callers are not told which server responded to a giv=
en RPC.   The only way of knowing if a new behavior was supported is to iss=
ue 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 =3D VL_GetCapabilities(conn, &caps);

    if (code !=3D 0) return code;
    if ((caps[0] & LOCKTIMESTAMP) =3D=3D 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.

--_000_1CF79735E33548E5BA636311B528EB5Asinenominenet_
Content-Type: text/html; charset="us-ascii"
Content-ID: <FA0AB7433C6C5F4086B870F200CCA05C@namprd15.prod.outlook.com>
Content-Transfer-Encoding: quoted-printable

<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
>
</head>
<body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; line-break:=
 after-white-space;" class=3D"">
<div>Hi&nbsp;Jeffrey,</div>
<div><br class=3D"">
</div>
<div>&gt; Thank you for publishing the I-D which might be misnamed.<br clas=
s=3D"">
<br class=3D"">
Ack.<br class=3D"">
<br class=3D"">
<blockquote type=3D"cite" class=3D"">
<div class=3D"">
<div class=3D"">
<p class=3D"">Although it is true that IBM as part of the AFS 3.5 release r=
epurposed struct nvldbentry.spares1 as nvldbentry.matchindex the field is o=
nly defined for use as part of a new RPC: VL_ListAttributesN2.&nbsp; Best p=
ractice is not to modify the semantics
 of the structures used in existing RPCs.&nbsp; Instead, new RPCs should be=
 allocated to indicate that the caller understands the new semantics. &nbsp=
; If the new RPC is supported by the server, then it will be executed with =
the expected semantics.&nbsp; Otherwise, RXGEN_OPCODE
 is returned indicating to the caller that the requested functionality is u=
navailable.&nbsp; The caller then falls back to an older version of the RPC=
.</p>
<p class=3D"">In general, service capability bits should not be used for th=
e purpose of altering the behavior of existing RPCs.&nbsp;&nbsp; The alloca=
tion 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.&nbsp;=
&nbsp; The VICED_CAPABILITY_ERRORTRANS informs the client whether or not th=
e server is capable of returning UAE error codes.&nbsp;&nbsp; If VICED_CAPA=
BILITY_ERRORTRANS is unavailable the client needs to
 be careful with processing the return codes because the fileserver's OS er=
ror code assignments might not match those of the caller.</p>
<p class=3D"">Service capability bits for UBIK services are particularly pr=
oblematic because there is no requirement that all servers in the cell run =
the same version.&nbsp;&nbsp; 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.&n=
bsp;&nbsp; There is no guarantee that the VL_GetCapabilities RPC result wil=
l be returned from the same server that responded to the VL_GetEntryByIDN R=
PC.&nbsp;&nbsp; If VL_CAPABILITY_LOCKTIMESTAMP was set
 on the server that responded to VL_GetCapabilities but the server respondi=
ng 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.</p>
<p class=3D"">For UBIK services, the callers are not told which server resp=
onded to a given RPC.&nbsp;&nbsp; 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.</p>
</div>
</div>
</blockquote>
<br class=3D"">
</div>
<div>After the introduction of ubik_CallRock(), we can insert additional co=
de to run<br class=3D"">
before relevant RPC. As an example:<br class=3D"">
<br class=3D"">
ListAttributesN3(conn, ...)<br class=3D"">
{<br class=3D"">
&nbsp; &nbsp;&nbsp;code =3D VL_GetCapabilities(conn, &amp;caps);<br class=
=3D"">
<br class=3D"">
&nbsp; &nbsp;&nbsp;if (code !=3D 0) return code;<br class=3D"">
&nbsp; &nbsp;&nbsp;if ((caps[0] &amp; LOCKTIMESTAMP) =3D=3D 0) return -1;<b=
r class=3D"">
<br class=3D"">
&nbsp; &nbsp;&nbsp;return VL_ListAttributesN(conn, ...);<br class=3D"">
}<br class=3D"">
<br class=3D"">
VLDB_ListAttributesN3(...)<br class=3D"">
{<br class=3D"">
&nbsp; &nbsp;&nbsp;return ubik_CallRock(cstruct, 0, ListAttributesN3, &amp;=
args);<br class=3D"">
}<br class=3D"">
<br class=3D"">
Thank you for sharing your thoughts, your feedback is always appreciated.<b=
r class=3D"">
Marcio Barbosa.</div>
</body>
</html>

--_000_1CF79735E33548E5BA636311B528EB5Asinenominenet_--