<?xml version="1.0" encoding="UTF-8"?><?rfc linefile="1:/tmp/CGI17105.1"?><?rfc linefile="1:/tmp/CGI17105.1"?>
<!-- automatically generated by xml2rfc v1.34 on 2009-11-17T02:32:01Z -->
<!-- automatically generated by xml2rfc v1.34 on 2009-11-17T02:32:01Z -->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
     There has to be one entity for each item to be referenced. 
     An alternate method (rfc include) is described in the references. -->

<!-- xml2rfc-processed-entity RFC2119 -->
<!-- xml2rfc-processed-entity RFC2629 -->
<!-- xml2rfc-processed-entity RFC3552 -->
<!-- xml2rfc-processed-entity I-D.narten-iana-considerations-rfc2434bis -->
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<!-- used by XSLT processors -->
<!-- For a complete list and description of processing instructions (PIs), 
     please see http://xml.resource.org/authoring/README.html. -->
<!-- Below are generally applicable Processing Instructions (PIs) that most I-Ds might want to use.
     (Here they are set differently than their defaults in xml2rfc v1.32) -->
<?rfc strict="yes" ?>
<!-- give errors regarding ID-nits and DTD validation -->
<!-- control the table of contents (ToC) -->
<?rfc toc="yes"?>
<!-- generate a ToC -->
<?rfc tocdepth="4"?>
<!-- the number of levels of subsections in ToC. default: 3 -->
<!-- control references -->
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- sort the reference entries alphabetically -->
<!-- control vertical white space 
     (using these PIs as follows is recommended by the RFC Editor) -->
<?rfc compact="yes" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<!-- keep one blank line between list items -->
<!-- end of list of popular I-D processing instructions -->
<rfc category="bcp" docName="draft-tkeiser-afs3-volser-tlv-00" ipr="trust200902">
  <!-- category values: std, bcp, info, exp, and historic
     ipr values: full3667, noModification3667, noDerivatives3667
     you can add the attributes updates="NNNN" and obsoletes="NNNN" 
     they will automatically be output with "(if approved)" -->

  <!-- ***** FRONT MATTER ***** -->

  <front>
    <!-- The abbreviated title is used in the page header - it is only necessary if the 
         full title is longer than 39 characters -->

    <title abbrev="AFSVol TLV RPCs">AFSVol Tag-Length-Value Remote Procedure Call Extensions</title>

    <!-- add 'role="editor"' below for the editors if appropriate -->

    <!-- Another author who claims to be an editor -->

    <author fullname="Thomas Keiser" initials="T.E.K."
            surname="Keiser">
      <organization abbrev="Sine Nomine">Sine Nomine Associates</organization>

      <address>
        <postal>
          <street>43596 Blacksmith Square</street>

          <!-- Reorder these if your country does things differently -->

          <city>Ashburn</city>

          <region>VA</region>

          <code>20147</code>

          <country>USA</country>
        </postal>

        <phone>+1 703 723 6673</phone>

        <email>tkeiser@sinenomine.net</email>

        <!-- uri and facsimile elements may also be added -->
      </address>
    </author>

    <author fullname="Steven Jenkins" initials="S.J."
            surname="Jenkins">
      <organization abbrev="Sine Nomine">Sine Nomine Associates</organization>

      <address>
        <postal>
          <street>43596 Blacksmith Square</street>

          <!-- Reorder these if your country does things differently -->

          <city>Ashburn</city>

          <region>VA</region>

          <code>20147</code>

          <country>USA</country>
        </postal>

        <phone>+1 703 723 6673</phone>

        <email>sjenkins@sinenomine.net</email>

        <!-- uri and facsimile elements may also be added -->
      </address>
    </author>

    <date year="2009" />

    <!-- If the month and year are both specified and are the current ones, xml2rfc will fill 
         in the current day for you. If only the current year is specified, xml2rfc will fill 
	 in the current day and month for you. If the year is not the current one, it is 
	 necessary to specify at least a month (xml2rfc assumes day="1" if not specified for the 
	 purpose of calculating the expiry date).  With drafts it is normally sufficient to 
	 specify just the year. -->

    <!-- Meta-data Declarations -->

    <area>General</area>

    <workgroup>N/A</workgroup>

    <!-- WG name at the upperleft corner of the doc,
         IETF is fine for individual submissions.  
	 If this element is not present, the default is "Network Working Group",
         which is used by the RFC Editor as a nod to the history of the IETF. -->

    <keyword>afsvol</keyword>

    <!-- Keywords will be incorporated into HTML output
         files in a meta tag but they have no effect on text or nroff
         output. If you submit your draft to the RFC Editor, the
         keywords will be used for the search engine. -->

    <abstract>
      <t>
        AFS-3 heavily leverages Remote Procedure Calls (RPCs). 
        This proposal adds a new mechanism to better manage the 
        addition of new, enhancement-specific RPCs through the 
        use of both capability bits via the GetCapabilities RPC, and 
        via standardization of backwards-compatibility behaviors for 
        enhancement-specific RPCs.  These goals are accomplished
        through standardization of Tag-Length-Value (TLV) 
        get/set/enumerate RPCs with  
        value payloads encoded using an XDR discriminated union.
        The XDR union decode problem is circumvented by
        specifying an opaque default leg.  Tags are allocated for 
        existing volume and transaction metadata, and 
        implementation-private tags are allocated for metadata 
        related to the OpenAFS Demand Attach File Server.
      </t>
    </abstract>
  </front>


  <middle>
    <section title="Introduction">
      <t>
        The AFS protocol stores data in volumes on fileservers. 
        Status information for volumes is accessible via various 
        AFSVol RPCs. Adding or modifying fields currently 
        requires creation of new RPCs. As these new RPCs differ 
        only slightly from existing ones, a scalable approach 
        to RPC modification is needed. This is accomplished 
        through the creation of Tag-Length-Value (TLV) RPCs for 
        the existing RPCs; for example, AFSVolGetOneVolumeTLV 
        is the Tag-Length-Value equivalent to the AFS-3 
        AFSVolListOneVolume RPC.
      </t>

      <t>
        As a concrete example of Tag-Length-Value RPCs for 
        volume status information, the Demand Attach File Server 
        creates new states for volumes.  Several new tags are
        allocated by this memo to export raw and canonical
        state information which DAFS can provide, but which
        legacy AFS-3 is incapable of communicating.
      </t>

      <section title="Requirements Language">
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
        document are to be interpreted as described in <xref
        target="RFC2119">RFC 2119</xref>.</t>
      </section>
    </section>

    <section title="GetCapabilities RPC">
      <section title="Description">
        <t>
          The AFS-3 specifications (<xref target="AFS3-FSCM" />, <xref target="AFS3-VVL" />) describe various 
          AFS RPCs. As new extensions and modifications to AFS 
          occur, a mechanism needs to be in place so that growth 
          of RPCs is done in a manageable fashion. Of particular 
          concern is a proliferation of modified versions of RPCs 
          that differ from each other in minor ways; examples are:
        </t>

        <t>
          <list style="symbols">
            <t>RXAFSCB_InitCallBackState, RXAFSCB_InitCallBackState2, and RXAFSCB_InitCallBackState3</t>
            <t>RXAFS_FetchData versus RXAFS_FetchData64</t>
          </list>
        </t>

        <t>
          Instead of continuing the practice of adding a version 
          number, width of value, or other identifier to the end 
          of the RPC name, this document specifies that RPC 
          extensions, where necessary, be created with a "TLV" 
          suffix denoting "Tag-Length-Value", a tag-value 
          identifier be obtained from the Registrar, and that 
          interoperability done according to the following section.
        </t>
      </section>
    </section>

    <section title="Backward Compatibility">
      <t>
        Services providing extended Tag-Length-Value RPCs MUST 
        provide backwards compatible interfaces to both legacy 
        clients and servers. Additionally, interoperability 
        between TLV versions must also be specified if they do 
        not comply with the following requirements:
      </t>

      <t>
        <list style="numbers">
          <t>
            AFS-3 TLV servers replying to AFS-3 clients MUST 
            provide the identical response to an AFS-3 server.
          </t>
          <t>
            AFS-3 TLV clients communicating with AFS-3 servers 
            MUST fall back to using non-TLV RPCs. 
          </t>
          <t>
            AFS-3 TLV clients to AFS-3 TLV servers:

            <list style="letters">
              <t>
                Where capabilities match or the server can 
                provide capabilities including those which the 
                client requests, the server MUST reply with exactly 
                the capabilities requested.
              </t>
              <t>
                Where the client requests capabilities that the 
                server does not provide it MUST either return an
                'unknown tag' error code, or (OPTIONAL) fall back 
                to an AFS-3 response.
              </t>
            </list>
          </t>
        </list>
      </t>

      <section title="GetCapabilities">
        <t>
          All AFS-3 Rx services with Tag-Length-Value RPCs MUST 
          implement a GetCapabilities RPC analogous to that done 
          for the FS-CM interface.
        </t>

        <section title="AFSVol">
          <t>
            This memo introduces a capabilities namespace, and 
            GetCapabilities interface to the AFSVol service. For 
            AFSVol the GetCapabilities interface will be be 
            identical to the afsint interface, and will be defined 
            as follows:
          </t>

          <figure align="center" anchor="getcaps">
            <artwork align="left">
proc GetCapabilities(
    OUT Capabilities * capabilities
) = XXX;
            </artwork>
          </figure>

          <t>
            The "Capabilities" type is defined by the existing afsint 
            interface, which is included here for reference:
          </t>

          <figure align="center" anchor="getcaps_consts">
            <artwork>
const AFSCAPABILITIESMAX = 192;

typedef afs_int32 Capabilities&lt;AFSCAPABILITIESMAX&gt;;
            </artwork>
          </figure>
        </section>

        <section title="Capability Bit Allocations">
          <t>
            Three new capability bit allocations will need to be 
            processed by the Grand Central Registrar:
          </t>

          <t>
            <list style="hanging" hangIndent="4">
              <t hangText="VICED_CAPABILITY_DAFS">
                Announce that this file server supports the OpenAFS 
                Demand Attach File Server version 1 semantics
              </t>
              <t hangText="AFSVOL_CAPABILITY_DAFS">
                Announce that this volume server supports the OpenAFS 
                Demand Attach File Server version 1 semantics
              </t>
              <t hangText="AFSVOL_CAPABILITY_TLV">
                Announce that this volume server supports the 
                Tag-Length-Value RPC
              </t>
            </list>
          </t>
        </section>
      </section>
    </section>

    <section title="TLV Interface">
      <t>
        A new suite of RPCs will be standardized to get/set 
        tag-length-value tuples, and to enumerate supported tags. The 
        tag namespace will be controlled by the Grand Central 
        Registrar as an assigned numbers namespace.
      </t>

      <section title="Encoding">
        <t>
          The TLV data will be encoded using the following XDR 
          specification:
        </t>

        <figure align="center" anchor="tag_enum">
          <artwork>
/* registrar-controlled tag namespace */

enum AFSVol_TLV_tag {
    ...
};

const AFSINT_TLV_TAG_MAX = 1024;         /* upper-bound on number of
                                          * TLV tuples per RPC */
const AFSINT_TLV_OPAQUE_MAX = 262144;    /* upper-bound on size of
                                          * value payload */

enum afsint_TLV_type {
    AFSINT_TLV_TYPE_NULL     = 0,
    AFSINT_TLV_TYPE_TRUE     = 1,
    AFSINT_TLV_TYPE_FALSE    = 2,
    AFSINT_TLV_TYPE_UINT64   = 3,
    AFSINT_TLV_TYPE_UUID     = 4,
    AFSINT_TLV_TYPE_STRING   = 5,
    AFSINT_TLV_TYPE_OPAQUE   = 6
};

union afsint_TLV_value switch(afsint_TLV_type type) {
 case AFSINT_TLV_TYPE_NULL:
 case AFSINT_TLV_TYPE_TRUE:
 case AFSINT_TLV_TYPE_FALSE:
  void;

 case AFSINT_TLV_TYPE_UINT64:
    afs_uint64 u_64;

 case AFSINT_TLV_TYPE_UUID:
    afsUUID u_uuid;

 case AFSINT_TLV_TYPE_STRING:
    string u_string&lt;AFSINT_TLV_OPAQUE_MAX&gt;;

 case AFSINT_TLV_TYPE_OPAQUE:
 default:
    opaque u_opaque&lt;AFSINT_TLV_OPAQUE_MAX&gt;;
};

const AFSINT_TLV_FLAG_UNSUPPORTED = 0x1;
const AFSINT_TLV_FLAG_READ_ERROR = 0x2;
const AFSINT_TLV_FLAG_CRITICAL = 0x4;

struct afsint_TLV {
    afs_uint32 tlv_tag;
    afs_uint32 tlv_flags;
    afsint_TLV_value tlv_value;
};
</artwork>
          <postamble>TLV XDR specification</postamble>
        </figure>

        <t>
          In order to solve the XDR discriminated union decoding 
          problem, all future afsint_TLV_type allocations will 
          map to opaque. All implementations MUST support all 
          arms in the afsint_TLV_value XDR union, as defined above.
        </t>

        <t>
          It is RECOMMENDED that future protocol augmentations 
          requiring the transmission of new data types request 
          allocation of a new standards-track payload type code. 
          Allocation of a type code should coincide with 
          standardization of the payload encoding associated with 
          the type code allocation. However, in limited 
          circumstances where:
        </t>

        <t>
          <list style="numbers">
            <t>
              it is known a priori that there will never be any 
              encoding ambiguity, and 
            </t>
            <t>
              the cost of type code allocation and encoding 
              standardization are deemed too high
            </t>
          </list>
        </t>

        <t>
          use of the type code AFSINT_TLV_TYPE_OPAQUE may be permissible.
        </t>
      </section>

      <section title="Interface">
        <section title="Qualifiers">
          <t>
            In some cases the value associated with a tag will be 
            large, structured data. A qualifier is a tag-specific 
            parameter which allows a caller to address a subset of 
            the value stored in a tag. For TLV get interfaces, 
            specifying a qualifer can reduce the amount of data 
            sent over the wire. For TLV set interfaces, specifying 
            a qualifier permits a client to modify a subset of a 
            structured value without endangering cache coherence. 
            Qualifiers are marshalled over the wire as type 
            afsint_TLV_value. Unless otherwise noted, it should be 
            assumed that a tag only supports the null qualifier 
            (XDR union discriminator set to AFSINT_TLV_TYPE_NULL). 
            The null qualifier always references the entire value 
            for a given tag.
          </t>
        </section>

        <section title="Tag Introspection">
          <t>
            The Rx procedure specification for the tag support RPC 
            will be as follows:
          </t>

          <figure align="center" anchor="tlv_get_tags">
            <artwork>
proc GetVolumeTLVTags(
    IN AFSVol_TLV_tag offset,
    OUT AFSVol_TLV_tag * tags&lt;AFSINT_TLV_TAG_MAX&gt;
) = XXX;
</artwork>
          </figure>

          <t>
            The call parameters are defined as follows:

            <list style="hanging" hangIndent="4">
              <t hangText="offset">
                The offset IN parameter specifies the numeric offset of 
                the first tag to return. A value of zero indicates that 
                the client wants to start the enumeration at the 
                beginning of the tag list.
              </t>
              <t hangText="tags">
                The tags OUT parameter contains a sorted list of 
                supported tags, beginning with the first supported tag 
                greater than or equal to the offset IN parameter.
              </t>
            </list>
          </t>
        </section>

        <section title="TLV Get">
          <t>
            The Rx procedure specification for the TLV get 
            interface will be as follows:
          </t>

          <figure align="center" anchor="tlv_get_single">
            <artwork>
struct AFSVol_TLV_query {
    AFSVol_TLV_tag tq_tag;
    afsint_TLV_value tq_qualifier;
};

proc GetOneVolumeTLV(
    IN afs_uint32 partId,
    IN afs_uint64 volId,
    IN AFSVol_TLV_query queries&lt;AFSINT_TLV_TAG_MAX&gt;,
    OUT afsint_TLV * tuples&lt;AFSINT_TLV_TAG_MAX&gt;
) = XXX;
</artwork>
          </figure>

          <t>
            The call parameters are defined as follows:

            <list style="hanging" hangIndent="4">
              <t hangText="partId">
                The partId IN parameter specifies the disk partition on 
                which the volume is located.
              </t>
              <t hangText="volId">
                The volId IN parameter specifies the volume for which 
                TLV tuples are being requested.
              </t>
              <t hangText="queries">
                The queries IN parameter specifies an optional list of 
                tags for which TLV tuples are desired. If this 
                parameter is zero-length, then the server will return 
                up to AFSINT_TLV_TAG_MAX TLV tuples. If an unknown tag 
                identifier is passed in the tags parameter, then the 
                server will return a tuple with the 
                AFSINT_TLV_FLAG_UNSUPPORTED bit asserted in 
                afsint_TLV.tlv_flags, and the tlv type set to 
                AFSINT_TLV_TYPE_NULL. Similarly, if the server is 
                unable to retrieve the value for a supported tag, then 
                a tuple will be returned with 
                AFSINT_TLV_FLAG_READ_ERROR set in the 
                afsint_TLV.tlv_flags field, and the tlv type set to 
                AFSINT_TLV_TYPE_NULL. The AFSVol_TLV_query.tq_qualifier 
                field contains optional tag-specific qualifiers which 
                would allow the implementation to return a subset of 
                the data for a specific tag.
              </t>
              <t hangText="tuples">
                The tuples OUT parameter contains up to 
                AFSINT_TLV_TAG_MAX TLV tuples for this volume.
              </t>
            </list>
          </t>
        </section>

        <section title="TLV Streaming Get">
          <t>
            This call is similar to the call described in the 
            previous section, with the exception that TLV tuples 
            will be returned for multiple volumes at once using an 
            Rx split call interface. The Rx procedure specification 
            is as follows:
          </t>

          <figure align="center" anchor="tlv_get_multi">
            <artwork>
const AFSVOL_BULK_GETVOLUME_MAX = 1024;

proc GetVolumesTLV(
    IN afs_uint32 partIds&lt;AFSVOL_BULK_GETVOLUME_MAX&gt;,
    IN afs_uint64 volIds&lt;AFSVOL_BULK_GETVOLUME_MAX&gt;,
    IN AFSVol_TLV_query queries&lt;AFSINT_TLV_TAG_MAX&gt;
) split = XXX;
</artwork>
          </figure>

          <t>
            The call parameters are defined as follows:

            <list style="hanging" hangIndent="4">
              <t hangText="partIds">
                The partIds IN parameter specifies as list of vice 
                partitions. If this list is zero-length, then TLV 
                information is requested for all volumes on all vice 
                partitions. If this list is non-zero length, then TLV 
                information is requested only for volumes on specific 
                vice partitions.
              </t>
              <t hangText="volIds">
                The volIds IN parameter specifies a list of volume IDs. 
                If this list is zero-length, then TLV information is 
                requested for all volumes on the vice partitions 
                specified in partIds. 

                <vspace blankLines="1" />
                If the volIds array is non-zero length, then its length 
                MUST match the length of the partIds array. In this 
                case, each matching index in the partIds and volIds 
                arrays together form a tuple which uniquely addresses a 
                volume on a given vice partition.
              </t>
              <t hangText="queries">
                The queries IN parameter specifies an optional list of 
                tags for which TLV tuples are desired. If this 
                parameter is zero-length, then the server will return 
                up to AFSINT_TLV_TAG_MAX TLV tuples. If an unknown tag 
                identifier is passed in the tags parameter, then the 
                server will return a tuple with the 
                AFSINT_TLV_FLAG_UNSUPPORTED bit asserted in 
                afsint_TLV.tlv_flags, and the tlv type set to 
                AFSINT_TLV_TYPE_NULL. Similarly, if the server is 
                unable to retrieve the value for a supported tag, then 
                a tuple will be returned with 
                AFSINT_TLV_FLAG_READ_ERROR set in the 
                afsint_TLV.tlv_flags field, and the tlv type set to 
                AFSINT_TLV_TYPE_NULL. The AFSVol_TLV_query.tq_qualifier 
                field contains optional tag-specific qualifiers which 
                would allow the implementation to return a subset of 
                the data for a specific tag.
              </t>
            </list>
          </t>

          <section title="Split call stream encoding">
            <t>
              The contents of the split call stream shall be an 
              xdrrec stream containing a finite sequence of 
              XDR-encoded afsint_TLV structures, each of which shall 
              be marked as a separate record (typically by calling 
              xdrrec_endofrecord). End of sequence will be annotated 
              by a dummy tuple containing the special tag type 
              AFSVOL_TLV_TAG_EOS.
            </t>
          </section>
        </section>

        <section title="TLV Set">
          <t>
            The Rx procedure specification for the TLV set 
            interface will be as follows:
          </t>

          <figure align="center" anchor="tlv_set">
            <artwork>
struct AFSVol_TLV_store {
    afsint_TLV ts_tuple;
    afsint_TLV_value ts_qualifier;
};

proc SetVolumeTLV(
    IN afs_int32 trans,
    IN AFSVol_TLV_store tuples&lt;AFSINT_TLV_TAG_MAX&gt;,
    OUT afs_int32 * results&lt;AFSINT_TLV_TAG_MAX&gt;
) = XXX;
</artwork>
          </figure>

          <t>
            The call parameters are defined as follows:

            <list style="hanging" hangIndent="4">
              <t hangText="trans">
                The trans IN parameter specifies the transaction ID 
                returned by a previous invocation of AFSVolTransCreate.
              </t>
              <t hangText="tuples">
                The tuples IN parameter contains the list of TLV tuples 
                to be set by the server. 
              </t>
              <t hangText="results">
                The results OUT parameter contains a list of error 
                codes, one per tuple. These error codes provide 
                specific information regarding the success/failure of 
                each TLV set operation. Valid error codes include: 
                VOLSERTAGUNSUPPORTED, VOLSERTAGREADONLY, 
                VOLSERTAGWRITEFAILED, VOLSERTAGDECODEFAILED, 
                VOLSERTAGUNSUPPORTEDENCODING, 
                VOLSERTAGINVALIDQUALIFIER, and VOLSERFAILEDOP.
              </t>
            </list>
          </t>

          <section title="Call preprocessing">
            <t>
              The SetVolumeTLV begins by scanning all elements within 
              the tuples array. If any elements have the 
              AFSINT_TLV_FLAG_CRITICAL bit asserted in 
              tuples[i].ts_tuple.ts_flags, then preprocessing of the 
              tuple must occur. For each tuple with the critical bit 
              set, several preprocessing validation steps will be taken.
            </t>

            <section title="Verify tag is supported">
              <t>
                The tag stored in tuples[i].ts_tuple.tlv_tag is checked 
                to ensure that the server supports it. In the event 
                that the tag is not supported, then the corresponding 
                array index in the results array will be set to 
                VOLSERTAGUNSUPPORTED, and the RPC call abort at the 
                conclusion of critical tuple preprocessing with error 
                code VOLSERFAILEDOP.
              </t>
            </section>

            <section title="Verify tag is writeable">
              <t>
                The tag stored in tuples[i].ts_tuple.tlv_flag is 
                checked to ensure that it is a writeable property. In 
                the event that the tag is read-only, then the 
                corresponding array index in the results array will be 
                set to VOLSERTAGREADONLY, and the RPC call will abort 
                at the conclusion of critical tuple preprocessing with 
                error code VOLSERFAILEDOP.
              </t>
            </section>

            <section title="Verify value encoding is supported">
              <t>
                The XDR union discriminator in 
                tuples[i].ts_tuple.tlv_value is checked to make sure 
                that it is a supported type. If the discriminator is 
                not a supported type, then the corresponding array 
                index in the results array will be set to 
                VOLSERTAGUNSUPPORTEDENCODING, and the RPC call will 
                abort at the conclusion of critical tuple preprocessing 
                with error code VOLSERFAILEDOP.
              </t>
            </section>

            <section title="Verify value can be decoded">
              <t>
                The value stored in tuples[i].ts_tuple.tlv_value is 
                checked to make sure that it can be decoded. If the 
                wire-encoded data cannot be decoded, then the 
                corresponding array index in the results array will be 
                set to VOLSERTAGDECODEFAILED, and the RPC call will 
                abort at the conclusion of critical tuple preprocessing 
                with error code VOLSERFAILEDOP.
              </t>
            </section>

            <section title="Verify qualifier is supported">
              <t>
                Qualifiers are specific to a given tag. If for any 
                reason the tag-specific validation logic determines 
                that the qualifier is invalid, it may set the 
                corresponding array index in the results array to one 
                of VOLSERTLVQUALIFIERUNSUPPORTEDENCODING, 
                VOLSERTLVQUALIFIERDECODEFAILED, or 
                VOLSERTLVQUALIFIERINVALID. As with the other validation 
                steps, if a critical tuple fails qualifier validation, 
                then the RPC call will abort at the conclusion of 
                critical tuple preprocessing with error code VOLSERFAILEDOP.
              </t>
            </section>
          </section>

          <section title="Call processing">
            <t>
              Once the necessary validation steps have been 
              performed, the call will perform the set operations for 
              each tuple. Errors encountered during the processing of 
              each tuple will be recorded in the appropriate array 
              index of the results array. At the conclusion the RPC 
              will either return 0 if all set operations succeeded, 
              or VOLSERFAILEDOP if any failed.
            </t>
          </section>
        </section>
      </section>
    </section>

    <section title="Mapping of existing metadata onto TLV namespace">
      <t>
        Existing metadata available from several interfaces 
        will also be exported as TLV tuples. This is being done 
        not only for completeness, but also to prevent data 
        races between AFSVolGetOneVolumeTLV, and the various 
        legacy introspection interfaces. 
      </t>

      <section title="volintXInfo">
        <t>
          All metadata exported via the volintXInfo XDR structure 
          will now be exported as TLV tuples. Unless otherwise 
          specified, the values associated with each tag shall be 
          identical to that returned for the associated field in 
          volintXInfo by the AFSVolXListOneVolume interface. The 
          following tuples will be allocated to export existing 
          members of volintXInfo:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_TLV_TAG_VOL_NAME">
              This is the TLV analogue of volintXInfo.name. This 
              tuple MUST have a payload of type 
              AFSINT_TLV_TYPE_STRING. The u_string payload field MUST 
              contain a null-terminated string.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STATUS">
              This is the TLV analogue of volintXInfo.status. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_IN_USE">
              This is the TLV analogue of volintXInfo.inUse. This 
              tuple will contain a boolean value, and therefore MUST 
              have a payload type of either: AFSINT_TLV_TYPE_TRUE, or 
              AFSINT_TLV_TYPE_FALSE.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_ID">
              This is the TLV analogue of volintXInfo.volid. This 
              tuple MUST have a payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TYPE">
              This is the TLV analogue of volintXInfo.type. This 
              tuple MUST have a payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_CLONE_ID">
              This is the TLV analogue of volintXInfo.cloneID. This 
              tuple MUST have a payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_BACKUP_ID">
              This is the TLV analogue of volintXInfo.backupID. This 
              tuple MUST have a payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_PARENT_ID">
              This is the TLV analogue of volintXInfo.parentID. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_COPY_DATE">
              This is the TLV analogue of volintXInfo.copyDate. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64. 
              This timestamp shall be encoded using the rules 
              specified in the forthcoming afs3 RPC refresh document.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_CREATE_DATE">
              This is the TLV analogue of volintXInfo.creationDate. 
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_UINT64. This timestamp shall be encoded 
              using the rules specified in the forthcoming afs3 RPC 
              refresh document.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_ACCESS_DATE">
              This is the TLV analogue of volintXInfo.accessDate. 
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_UINT64. This timestamp shall be encoded 
              using the rules specified in the forthcoming afs3 RPC 
              refresh document.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_UPDATE_DATE">
              This is the TLV analogue of volintXInfo.updateDate. 
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_UINT64. This timestamp shall be encoded 
              using the rules specified in the forthcoming afs3 RPC 
              refresh document.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_BACKUP_DATE">
              This is the TLV analogue of volintXInfo.backupDate. 
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_UINT64. This timestamp shall be encoded 
              using the rules specified in the forthcoming afs3 RPC 
              refresh document.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_SIZE">
              This is the TLV analogue of volintXInfo.size. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_tLV_TAG_VOL_FILE_COUNT">
              This is the TLV analogue of volintXInfo.filecount. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_MAX_QUOTA">
              This is the TLV analogue of volintXInfo.maxquota. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_DAY_USE">
              This is the TLV analogue of volintXInfo.dayUse. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_READS">
              This is the TLV analogue of volintXInfo.stat_reads. 
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_OPAQUE. The opaque contents shall be an 
              XDR-encoded structure defined as follows:

              <figure align="center" anchor="tlv_stat_rw">
                <artwork>
const VOLINT_STATS_NUM_RWINFO_FIELDS = 4;

struct AFSVol_stat_rw {
    afs_uint64 stat_rw[VOLINT_STATS_NUM_RWINFO_FIELDS];
};
</artwork>
              </figure>
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_WRITES">
              This is the TLV analogue of volintXInfo.stat_reads. 
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_OPAQUE. The opaque contents shall be an 
              XDR-encoded structure as defined for 
              AFSVOL_TLV_TAG_VOL_STAT_READS.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_FILE_SAME_AUTHOR">
              This is the TLV analogue of 
              volintXInfo.stat_fileSameAuthor. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_OPAQUE. The opaque 
              contents shall be an XDR-encoded structure defined as follows:

              <figure align="center" anchor="tlv_stat_time">
                <artwork>
const VOLINT_STATS_NUM_TIME_FIELDS = 6;

struct AFSVol_stat_time {
    afs_uint64 stat_rw[VOLINT_STATS_NUM_TIME_FIELDS];
};
</artwork>
              </figure>
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_FILE_DIFFERENT_AUTHOR">
              This is the TLV analogue of 
              volintXInfo.stat_fileDiffAuthor. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_OPAQUE. The opaque 
              contents shall be the XDR-encoded structure 
              AFSVol_stat_time, as defined for 
              AFSVOL_TLV_TAG_VOL_STAT_FILE_SAME_AUTHOR.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_DIR_SAME_AUTHOR">
              This is the TLV analogue of 
              volintXInfo.stat_dirSameAuthor. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_OPAQUE. The opaque 
              contents shall be the XDR-encoded structure 
              AFSVol_stat_time, as defined for 
              AFSVOL_TLV_TAG_VOL_STAT_FILE_SAME_AUTHOR.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_DIR_DIFFERENT_AUTHOR">
              This is the TLV analogue of 
              volintXInfo.stat_dirDiffAuthor. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_OPAQUE. The opaque 
              contents shall be the XDR-encoded structure 
              AFSVol_stat_time, as defined for 
              AFSVOL_TLV_TAG_VOL_STAT_FILE_SAME_AUTHOR.
            </t>
          </list>
        </t>
      </section>

      <section title="transDebugInfo">
        <t>
          All metadata exported via the transDebugInfo XDR 
          structure will now be exported as TLV tuples. Unless 
          otherwise specified, the values associated with each 
          tag shall be identical to that returned for the 
          associated field in transDebugInfo by the 
          AFSVolMonitor interface. The following tuples will be 
          allocated to export existing members of transDebugInfo:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_TID">
              This is the TLV analogue of transDebugInfo.tid. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_TIME">
              This is the TLV analogue of transDebugInfo.time. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64. 
              This timestamp shall be encoded using the rules 
              specified in the forthcoming afs3 RPC refresh document.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_CREATE_TIME">
              This is the TLV analogue of 
              transDebugInfo.creationTime. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_UINT64. This timestamp 
              shall be encoded using the rules specified in the 
              forthcoming afs3 RPC refresh document.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_RETURN_CODE">
              This is the TLV analogue of transDebugInfo.returnCode. 
              This tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_ATTACH_MODE">
              This is the TLV analogue of transDebugInfo.iflags. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_STATUS">
              This is the TLV analogue of transDebugInfo.vflags This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_FLAGS">
              This is the TLV analogue of transDebugInfo.tflags. This 
              tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_LAST_PROC_NAME">
              This is the TLV analogue of 
              transDebugInfo.lastProcName. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_STRING. The u_string 
              payload field MUST contain a null-terminated string.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_CALL_VALID">
              This is the TLV analogue of transDebugInfo.callValid. 
              This tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_READ_NEXT">
              This is the TLV analogue of transDebugInfo.readNext. 
              This tuple MUST have payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_XMIT_NEXT">
              This is the TLV analogue of 
              transDebugInfo.transmitNext. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_LAST_RECV_TIME">
              This is the TLV analogue of 
              transDebugInfo.lastReceiveTime. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_UINT64. This timestamp 
              shall be encoded using the rules specified in the 
              forthcoming afs3 RPC refresh document.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_LAST_SEND_TIME">
              This is the TLV analogue of 
              transDebugInfo.lastSendTime. This tuple MUST have 
              payload of type AFSINT_TLV_TYPE_UINT64. This timestamp 
              shall be encoded using the rules specified in the 
              forthcoming afs3 RPC refresh document.
            </t>
          </list>
        </t>
      </section>

      <section title="Additional de facto-standardized fields">
        <t>
          Certain fields from the IBM AFS and OpenAFS file 
          server's VolumeDiskData header are generally useful. In 
          particular, several fields exported via the 
          AFSVolGetFlags and AFSVolSetFlags RPCs should be 
          exported via the TLV interface. The full list of 
          supported TLV tuples are:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_TLV_TAG_VOL_IN_SERVICE">
              This tuple will contain a boolean value, and therefore 
              MUST have a payload type of either: 
              AFSINT_TLV_TYPE_TRUE, or AFSINT_TLV_TYPE_FALSE. When 
              this bit is not asserted, the volume is 
              administratively prohibited from coming online.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_BLESSED">
              This tuple will contain a boolean value, and therefore 
              MUST have a payload type of either: 
              AFSINT_TLV_TYPE_TRUE, or AFSINT_TLV_TYPE_FALSE. When 
              this bit is not asserted, the volume is 
              administratively prohibited from coming online.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_RESTORED_FROM_ID">
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_UINT64. When this field is non-zero, it 
              contains the volume ID contained in the dump from which 
              it was restored.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_DESTROYED">
              This tuple will contain a boolean value, and therefore 
              MUST have a payload type of either: 
              AFSINT_TLV_TYPE_TRUE, or AFSINT_TLV_TYPE_FALSE. When 
              this bit is asserted, this volume is flagged for deletion.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_NEEDS_SALVAGE">
              This tuple will contain a boolean value, and therefore 
              MUST have a payload type of either: 
              AFSINT_TLV_TYPE_TRUE, or AFSINT_TLV_TYPE_FALSE. When 
              this bit is asserted, this volume requires a salvage.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_OFFLINE_MESSAGE">
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_STRING. The u_string payload field MUST 
              contain a null-terminated string. This field stores an 
              administrative message to indicate why the volume is offline.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_EXPIRATION_DATE">
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_UINT64. This timestamp shall be encoded 
              using the rules specified in the forthcoming afs3 RPC 
              refresh document. To the best knowledge of the authors, 
              this field is not standardized by any implementation.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_RESERVATION">
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_UINT64. This field, otherwise known as 
              minquota, specifies the amount of storage (in units of 
              1024 octets) that are reserved on the underlying 
              storage for use by this volume.
            </t>
          </list>
        </t>
      </section>
    </section>

    <section title="Extended volume state exportation">
      <t>
        In addition to exporting the existing volser state, DAFS
        state metadata will also be exported via the TLV interface.
        Specifically, an extended volume state field, and a raw
        DAFS state debugging tag, will be exported.
      </t>

      <section title="Mapped volume states">
        <t>
          Given that volume state information is useful across 
          all server implementations, a collection of generic 
          states shall be standardized. The following states are 
          initially defined in the namespace:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_VOLUME_STATE_OUT_OF_SERVICE">
              This volume is administratively out of service. For 
              example, the IBM AFS and OpenAFS implementations both 
              permit an administrator to force a volume offline by 
              mutating the blessed and inService bits.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_OFFLINE">
              This volume is offline for reasons other than 
              administrative intervention.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_READY">
              This volume is not online, but it is ready to be 
              brought online by the server on-demand.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_ONLINE">
              This volume is online.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_BUSY">
              This volume is busy performing some operation 
              which requires exclusive access.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_IO_BUSY">
              This volume is busy performing an I/O operation which 
              requires exclusive access.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_SALVAGING">
              This volume is currently being salvaged in the background.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_SALVAGE_NEEDED">
              This volume is offline, and will require a salvage 
              before it can be brought online.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_ERROR">
              This volume has been forced offline due to a 
              non-recoverable error. Manual intervention by an 
              administrator will be necessary to bring this volume 
              back to an operable state.
            </t>
            <t hangText="AFSVOL_VOLUME_STATE_VOLUME_OPERATION">
              This volume is currently offline because a volume 
              transaction requires exclusive access.
            </t>
          </list>
        </t>
      </section>

      <section title="Mapped process types">
        <t>
          It is useful to be able to track volume ownership by 
          process type. In order to do this, a new program type 
          namespace must be defined. The following types are 
          initially defined in the program type namespace:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSINT_PROGRAM_TYPE_FILE_SERVER">
              Refers to an afs file server process (Rx udp port 7000, 
              service ID 0).
            </t>
            <t hangText="AFSINT_PROGRAM_TYPE_VOLUME_SERVER">
              Refers to an afs volume server process (Rx udp port 
              7005, service ID 4).
            </t>
            <t hangText="AFSINT_PROGRAM_TYPE_SALVAGER">
              Refers to an afs stand-alone salvager process.
            </t>
            <t hangText="AFSINT_PROGRAM_TYPE_SALVAGE_SERVER">
              Refers to an OpenAFS DAFS salvage server process.
            </t>
            <t hangText="AFSINT_PROGRAM_TYPE_VOLUME_UTILITY">
              Refers to any ancillary stand-alone volume utility process.
            </t>
          </list>
        </t>
      </section>

      <section title="TLV tuples">
        <t>
          Volume state will be exported via three new TLV tuples:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_TLV_TAG_VOL_STATE_MAPPED">
              This tuple MUST have payload of type 
              AFSINT_TLV_TYPE_UINT64. The u_64 payload shall contain 
              a volume state enumeration value, as defined in [sub:Mapped-volume-states].
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STATE_DAFS_RAW">
              For servers exporting capability 
              AFSVOL_CAPABILITY_DAFS, this payload MUST be of type 
              AFSINT_TLV_TYPE_OPAQUE. Encoding of raw state is 
              unspecified and implementation-private.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_OWNING_PROCESS">
              For servers exporting capability 
              AFSVOL_CAPABILITY_DAFS, this payload MUST be of type 
              AFSINT_TLV_TYPE_UINT64. The u_64 payload shall contain 
              a program type enumeration value, as defined in [sub:Mapped-process-types].
            </t>
          </list>
        </t>
      </section>
    </section>

    <section anchor="Acknowledgements" title="Acknowledgements">
      <t>
        We would like to thank all of the participants at the 2009 Edinburgh AFS 
        hackathon for their input into the design of this TLV mechanism.  Alistair
        Ferguson has provided much useful feedback, especially with regard to backwards
        compatibility and discriminated union type identifier namespace allocations.
        Andrew Deason and Michael Meffie have provided considerable input with
        regard to the discriminated union XDR decoding problem, GCO registrar
        and namespace allocation concerns, what metadata should be exported in the
        initial revision, the notion of data qualifiers, as well as commentary about
        how they envision this extension being used to support future protocol
        extensions.
      </t>
    </section>

    <!-- Possibly a 'Contributors' section ... -->

    <section title="IANA Considerations">
      <t>This memo includes no request to IANA.</t>
    </section>

    <section title="GCO Registrar Considerations">
      <t>
        The Grand Central Registrar will need to consider 
        several assigned numbers requests.
      </t>

      <section title="Namespace allocations">
        <t>
          First and foremost, this memo requests that the GCO 
          Registrar assume control over several new namespaces:
        </t>

        <t>
          <list style="numbers">
            <t>AFSVol capability bit namespace</t>
            <t>AFS-3 TLV payload type namespace</t>
            <t>AFSVol TLV tag namespace</t>
            <t>AFSVol mapped volume state namespace</t>
            <t>AFS-3 program type namespace</t>
          </list>
        </t>
      </section>

      <section title="Assigned numbers allocations">
        <t>
          In addition to requesting the allocation of new 
          namespaces, this memo also requests several new 
          allocations within existing assigned numbers 
          namespaces. 
        </t>

        <section title="VICED capability bits">
          <t>
            One new capability bit is requested:

            <list style="symbols"><t>VICED_CAPABILITY_DAFS</t></list>

          </t>
        </section>

        <section title="AFSVol capability bits">
          <t>
            Two new capability bits are requested:

            <list style="symbols">
              <t>AFSVOL_CAPABILITY_DAFS</t>
              <t>AFSVOL_CAPABILITY_TLV</t>
            </list>
          </t>
        </section>

        <section title="AFS-3 TLV payload types">
          <t>
            The following payload type allocations are requested:
          </t>

          <t>
            <list style="symbols">
              <t>AFSINT_TLV_TYPE_NULL</t>
              <t>AFSINT_TLV_TYPE_TRUE</t>
              <t>AFSINT_TLV_TYPE_FALSE</t>
              <t>AFSINT_TLV_TYPE_UINT64</t>
              <t>AFSINT_TLV_TYPE_UUID</t>
              <t>AFSINT_TLV_TYPE_STRING</t>
              <t>AFSINT_TLV_TYPE_OPAQUE</t>
            </list>
          </t>
        </section>

        <section title="AFSVol TLV tags">
          <t>
            The following tag allocations are requested:
          </t>

          <t>
            <list style="symbols">
              <t>AFSVOL_TLV_TAG_VOL_NAME</t>
              <t>AFSVOL_TLV_TAG_VOL_STATUS</t>
              <t>AFSVOL_TLV_TAG_VOL_IN_USE</t>
              <t>AFSVOL_TLV_TAG_VOL_ID</t>
              <t>AFSVOL_TLV_TAG_VOL_TYPE</t>
              <t>AFSVOL_TLV_TAG_VOL_CLONE_ID</t>
              <t>AFSVOL_TLV_TAG_VOL_BACKUP_ID</t>
              <t>AFSVOL_TLV_TAG_VOL_PARENT_ID</t>
              <t>AFSVOL_TLV_TAG_VOL_COPY_DATE</t>
              <t>AFSVOL_TLV_TAG_VOL_CREATE_DATE</t>
              <t>AFSVOL_TLV_TAG_VOL_ACCESS_DATE</t>
              <t>AFSVOL_TLV_TAG_VOL_UPDATE_DATE</t>
              <t>AFSVOL_TLV_TAG_VOL_BACKUP_DATE</t>
              <t>AFSVOL_TLV_TAG_VOL_SIZE</t>
              <t>AFSVOL_TLV_TAG_VOL_FILE_COUNT</t>
              <t>AFSVOL_TLV_TAG_VOL_MAX_QUOTA</t>
              <t>AFSVOL_TLV_TAG_VOL_DAY_USE</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_READS</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_WRITES</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_FILE_SAME_AUTHOR</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_FILE_DIFFERENT_AUTHOR</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_DIR_SAME_AUTHOR</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_DIR_DIFFERENT_AUTHOR</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_ID</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_TIME</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_CREATE_TIME</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_RETURN_CODE</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_ATTACH_MODE</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_STATUS</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_FLAGS</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_LAST_PROC_NAME</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_CALL_VALID</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_READ_NEXT</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_XMIT_NEXT</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_LAST_RECV_TIME</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_LAST_SEND_TIME</t>
              <t>AFSVOL_TLV_TAG_VOL_IN_SERVICE</t>
              <t>AFSVOL_TLV_TAG_VOL_BLESSED</t>
              <t>AFSVOL_TLV_TAG_VOL_RESTORED_FROM_ID</t>
              <t>AFSVOL_TLV_TAG_VOL_DESTROYED</t>
              <t>AFSVOL_TLV_TAG_VOL_NEEDS_SALVAGE</t>
              <t>AFSVOL_TLV_TAG_VOL_OFFLINE_MESSAGE</t>
              <t>AFSVOL_TLV_TAG_VOL_EXPIRATION_DATE</t>
              <t>AFSVOL_TLV_TAG_VOL_RESERVATION</t>
              <t>AFSVOL_TLV_TAG_VOL_STATE_MAPPED</t>
              <t>AFSVOL_TLV_TAG_VOL_STATE_RAW</t>
              <t>AFSVOL_TLV_TAG_VOL_OWNING_PROCESS</t>
              <t>AFSVOL_TLV_TAG_EOS</t>
            </list>
          </t>
        </section>

        <section title="VOLS error table">
          <t>
            Within the VOLS error table (offset 1492325120), 
            several new codes need to be allocated: 
          </t>

          <t>
            <list style="symbols">
              <t>VOLSERTAGUNSUPPORTED</t>
              <t>VOLSERTAGREADONLY</t>
              <t>VOLSERTAGWRITEFAILED</t>
              <t>VOLSERTAGDECODEFAILED</t>
              <t>VOLSERTAGUNSUPPORTEDENCODING</t>
              <t>VOLSERTLVQUALIFIERUNSUPPORTEDENCODING</t>
              <t>VOLSERTLVQUALIFIERDECODEFAILED</t>
              <t>VOLSERTLVQUALIFIERINVALID</t>
            </list>
          </t>
        </section>

        <section title="AFSVol mapped volume names">
          <t>
            Within the new AFSVol mapped volume state namespace, 
            the following allocations are requested:
          </t>

          <t>
            <list style="symbols">
              <t>AFSVOL_VOLUME_STATE_OUT_OF_SERVICE</t>
              <t>AFSVOL_VOLUME_STATE_OFFLINE</t>
              <t>AFSVOL_VOLUME_STATE_READY</t>
              <t>AFSVOL_VOLUME_STATE_ONLINE</t>
              <t>AFSVOL_VOLUME_STATE_BUSY</t>
              <t>AFSVOL_VOLUME_STATE_IO_BUSY</t>
              <t>AFSVOL_VOLUME_STATE_SALVAGING</t>
              <t>AFSVOL_VOLUME_STATE_SALVAGE_NEEDED</t>
              <t>AFSVOL_VOLUME_STATE_ERROR</t>
              <t>AFSVOL_VOLUME_STATE_VOLUME_OPERATION</t>
            </list>
          </t>
        </section>

        <section title="AFS-3 program types">
          <t>
            Within the new AFS program type namespace, the 
            following allocations are requested:
          </t>

          <t>
            <list style="symbols">
              <t>AFSINT_PROGRAM_TYPE_FILE_SERVER</t>
              <t>AFSINT_PROGRAM_TYPE_VOLUME_SERVER</t>
              <t>AFSINT_PROGRAM_TYPE_SALVAGER</t>
              <t>AFSINT_PROGRAM_TYPE_SALVAGE_SERVER</t>
              <t>AFSINT_PROGRAM_TYPE_VOLUME_UTILITY</t>
            </list>
          </t>
        </section>
      </section>
    </section>

    <section anchor="Security" title="Security Considerations">
      <t>
        Security and authorization issues are tag-specific.  The legacy
        AFSVol RPCs permitted rxnull connections to perform the four
        ListVolume RPCs, and AFSVolMonitor.  Arguably, it is time to 
        re-evaluate this decision, and restrict access to certain
        tags, as they do permit potentially sensitive
        volume or operational metadata to leak onto public networks.
      </t>
    </section>
  </middle>

  <!-- BACK MATTER -->

  <back>

    <references title="Normative References">
      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"?-->
      <?rfc linefile="1:http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"?>

<reference anchor='RFC2119'>

<front>
<title abbrev='RFC Key Words'>Key words for use in RFCs to Indicate Requirement Levels</title>
<author initials='S.' surname='Bradner' fullname='Scott Bradner'>
<organization>Harvard University</organization>
<address>
<postal>
<street>1350 Mass. Ave.</street>
<street>Cambridge</street>
<street>MA 02138</street></postal>
<phone>- +1 617 495 3864</phone>
<email>sob@harvard.edu</email></address></author>
<date year='1997' month='March' />
<area>General</area>
<keyword>keyword</keyword>
<abstract>
<t>
   In many standards track documents several words are used to signify
   the requirements in the specification.  These words are often
   capitalized.  This document defines these words as they should be
   interpreted in IETF documents.  Authors who follow these guidelines
   should incorporate this phrase near the beginning of their document:

<list>
<t>
      The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
      NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
      "OPTIONAL" in this document are to be interpreted as described in
      RFC 2119.
</t></list></t>
<t>
   Note that the force of these words is modified by the requirement
   level of the document in which they are used.
</t></abstract></front>

<seriesInfo name='BCP' value='14' />
<seriesInfo name='RFC' value='2119' />
<format type='TXT' octets='4723' target='ftp://ftp.isi.edu/in-notes/rfc2119.txt' />
<format type='HTML' octets='17491' target='http://xml.resource.org/public/rfc/html/rfc2119.html' />
<format type='XML' octets='5777' target='http://xml.resource.org/public/rfc/xml/rfc2119.xml' />
</reference>
<?rfc linefile="1439:/tmp/CGI17105.1"?>
    </references>

    <references title="Informative References">
      <reference anchor="AFS3-FSCM">
        <front>
          <title>AFS-3 Programmer's Reference: File Server/Cache Manager Interface</title>

          <author initials="E.R." surname="Zayas" fullname="Edward R. Zayas">
            <organization abbrev="Transarc">Transarc Corporation</organization>
          </author>

          <date year="1991" month="August" day="20" />
        </front>
        <seriesInfo name="Tech. Rep." value="FS-00-D162" />
      </reference>

      <reference anchor="AFS3-VVL">
        <front>
          <title>AFS-3 Programmer's Reference: Volume Server/Volume Location Server Interface</title>

          <author initials="E.R." surname="Zayas" fullname="Edward R. Zayas">
            <organization abbrev="Transarc">Transarc Corporation</organization>
          </author>

          <date year="1991" month="August" day="29" />
        </front>
        <seriesInfo name="Tech. Rep." value="FS-00-D165" />
      </reference>
    </references>


    <section anchor="app-cap-xdr" title="XDR Grammar for FS-CM Capabilities Mechanism">
      <figure align="center" anchor="fscm-cap-xdr">
        <artwork>
const AFSCAPABILITIESMAX = 196; 

typedef afs_uint32 Capabilities&lt;AFSCAPABILITIESMAX&gt;;

/* Viced Capability Flags */ 
const VICED_CAPABILITY_ERRORTRANS   = 0x0001; 
const VICED_CAPABILITY_64BITFILES   = 0x0002; 
const VICED_CAPABILITY_WRITELOCKACL = 0x0004; 
const VICED_CAPABILITY_SANEACLS     = 0x0008;

/* Cache Manager Capability Flags */ 
const CLIENT_CAPABILITY_ERRORTRANS  = 0x0001; 
</artwork>
      </figure>
    </section>


    <!-- Change Log
v00 2009-11-11  TEK  Initial Version

     -->

  </back>

</rfc>


