[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 Jeffrey,</div>
<div><br class=3D"">
</div>
<div>> 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. Best p=
ractice 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 u=
navailable. 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. 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. =
The VICED_CAPABILITY_ERRORTRANS informs the client whether or not th=
e server is capable of returning UAE error codes. 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. 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; 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. 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. 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"">
code =3D VL_GetCapabilities(conn, &caps);<br class=
=3D"">
<br class=3D"">
if (code !=3D 0) return code;<br class=3D"">
if ((caps[0] & LOCKTIMESTAMP) =3D=3D 0) return -1;<b=
r class=3D"">
<br class=3D"">
return VL_ListAttributesN(conn, ...);<br class=3D"">
}<br class=3D"">
<br class=3D"">
VLDB_ListAttributesN3(...)<br class=3D"">
{<br class=3D"">
return ubik_CallRock(cstruct, 0, ListAttributesN3, &=
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_--