<?xml version="1.0"?>
<!-- A Relax NG schema for the libvirt storage pool XML format -->
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
    datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <include href="basictypes.rng"/>
  <include href="storagecommon.rng"/>
  <start>
    <ref name="pool"/>
  </start>


  <define name="pool">
    <element name="pool">
      <choice>
        <ref name="pooldir"/>
        <ref name="poolfs"/>
        <ref name="poolnetfs"/>
        <ref name="poollogical"/>
        <ref name="pooldisk"/>
        <ref name="pooliscsi"/>
        <ref name="pooliscsidirect"/>
        <ref name="poolscsi"/>
        <ref name="poolmpath"/>
        <ref name="poolrbd"/>
        <ref name="poolsheepdog"/>
        <ref name="poolgluster"/>
        <ref name="poolzfs"/>
        <ref name="poolvstorage"/>
      </choice>
    </element>
  </define>

  <define name="pooldir">
    <attribute name="type">
      <value>dir</value>
    </attribute>
    <interleave>
      <ref name="commonmetadata"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcedir"/>
      <ref name="target"/>
    </interleave>
  </define>

  <define name="poolfs">
    <attribute name="type">
      <value>fs</value>
    </attribute>
    <interleave>
      <ref name="commonmetadata"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcefs"/>
      <ref name="target"/>
    </interleave>
    <optional>
      <ref name="fs_mount_opts"/>
    </optional>
  </define>

  <define name="poolnetfs">
    <attribute name="type">
      <value>netfs</value>
    </attribute>
    <interleave>
      <ref name="commonmetadata"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcenetfs"/>
      <ref name="target"/>
    </interleave>
    <optional>
      <ref name="fs_mount_opts"/>
    </optional>
  </define>

  <define name="poollogical">
    <attribute name="type">
      <value>logical</value>
    </attribute>
    <interleave>
      <ref name="commonMetadataNameOptional"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcelogical"/>
      <ref name="targetlogical"/>
    </interleave>
  </define>

  <define name="pooldisk">
    <attribute name="type">
      <value>disk</value>
    </attribute>
    <interleave>
      <ref name="commonmetadata"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcedisk"/>
      <ref name="target"/>
    </interleave>
  </define>

  <define name="pooliscsi">
    <attribute name="type">
      <value>iscsi</value>
    </attribute>
    <interleave>
      <ref name="commonmetadata"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourceiscsi"/>
      <ref name="target"/>
    </interleave>
  </define>

  <define name="pooliscsidirect">
    <attribute name="type">
      <value>iscsi-direct</value>
    </attribute>
    <interleave>
      <ref name="commonmetadata"/>
      <optional>
        <ref name="sizing"/>
      </optional>
      <ref name="features"/>
      <ref name="sourceiscsidirect"/>
    </interleave>
  </define>

  <define name="poolscsi">
    <attribute name="type">
      <value>scsi</value>
    </attribute>
    <interleave>
      <ref name="commonmetadata"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcescsi"/>
      <ref name="target"/>
    </interleave>
  </define>

  <define name="poolmpath">
    <attribute name="type">
      <value>mpath</value>
    </attribute>
    <interleave>
      <ref name="commonmetadata"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <optional>
        <ref name="sourcempath"/>
      </optional>
      <ref name="target"/>
    </interleave>
  </define>

  <define name="poolrbd">
    <attribute name="type">
      <value>rbd</value>
    </attribute>
    <interleave>
      <ref name="commonMetadataNameOptional"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcerbd"/>
      <ref name="refresh"/>
    </interleave>
    <optional>
      <ref name="rbd_config_opts"/>
    </optional>
  </define>

  <define name="poolsheepdog">
    <attribute name="type">
      <value>sheepdog</value>
    </attribute>
    <interleave>
      <ref name="commonMetadataNameOptional"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcesheepdog"/>
    </interleave>
  </define>

  <define name="poolgluster">
    <attribute name="type">
      <value>gluster</value>
    </attribute>
    <interleave>
      <ref name="commonMetadataNameOptional"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcegluster"/>
    </interleave>
  </define>

  <define name="poolzfs">
    <attribute name="type">
      <value>zfs</value>
    </attribute>
    <interleave>
      <ref name="commonMetadataNameOptional"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcezfs"/>
      <optional>
        <ref name="target"/>
      </optional>
    </interleave>
  </define>

  <define name="poolvstorage">
    <attribute name="type">
      <value>vstorage</value>
    </attribute>
    <interleave>
      <ref name="commonMetadataNameOptional"/>
      <ref name="sizing"/>
      <ref name="features"/>
      <ref name="sourcevstorage"/>
      <ref name="target"/>
    </interleave>
  </define>

  <define name="sourceinfovendor">
    <interleave>
      <optional>
        <element name="vendor">
          <attribute name="name">
            <text/>
          </attribute>
        </element>
      </optional>
      <optional>
        <element name="product">
          <attribute name="name">
            <text/>
          </attribute>
        </element>
      </optional>
    </interleave>
  </define>

  <define name="commonMetadataNameOptional">
    <interleave>
      <optional>
        <element name="name">
          <ref name="objectName"/>
        </element>
      </optional>
      <optional>
        <element name="uuid">
          <ref name="UUID"/>
        </element>
      </optional>
    </interleave>
  </define>

  <define name="commonmetadata">
    <interleave>
      <element name="name">
        <ref name="objectName"/>
      </element>
      <optional>
        <element name="uuid">
          <ref name="UUID"/>
        </element>
      </optional>
    </interleave>
  </define>

  <define name="sizing">
    <interleave>
      <optional>
        <element name="capacity">
          <ref name="scaledInteger"/>
        </element>
      </optional>
      <optional>
        <element name="allocation">
          <ref name="scaledInteger"/>
        </element>
      </optional>
      <optional>
        <element name="available">
          <ref name="scaledInteger"/>
        </element>
      </optional>
    </interleave>
  </define>

  <define name="features">
    <optional>
      <element name="features">
        <interleave>
          <optional>
            <element name="cow">
              <attribute name="state">
                <ref name="virYesNo"/>
                </attribute>
            </element>
          </optional>
        </interleave>
      </element>
    </optional>
  </define>

  <define name="target">
    <element name="target">
      <interleave>
        <element name="path">
          <ref name="absFilePath"/>
        </element>
        <ref name="permissions"/>
      </interleave>
    </element>
  </define>

  <define name="targetlogical">
    <element name="target">
      <interleave>
        <optional>
          <element name="path">
            <ref name="absFilePath"/>
          </element>
        </optional>
        <ref name="permissions"/>
      </interleave>
    </element>
  </define>

  <define name="sourceinfohost">
    <oneOrMore>
      <element name="host">
        <attribute name="name">
          <choice>
            <ref name="dnsName"/>
            <ref name="ipAddr"/>
          </choice>
        </attribute>
        <optional>
          <attribute name="port">
            <ref name="PortNumber"/>
          </attribute>
        </optional>
        <empty/>
      </element>
    </oneOrMore>
  </define>

  <define name="sourceinfodev">
    <element name="device">
      <attribute name="path">
        <choice>
          <ref name="absFilePath"/>
          <ref name="genericName"/>
          <ref name="IscsiQualifiedName"/>
        </choice>
      </attribute>
      <choice>
        <empty/>
        <ref name="devextents"/>
      </choice>
      <optional>
        <attribute name="part_separator">
          <ref name="virYesNo"/>
        </attribute>
      </optional>
    </element>
  </define>

  <define name="sourceinfodeviscsidirect">
    <element name="device">
      <attribute name="path">
        <ref name="IscsiQualifiedName"/>
      </attribute>
    </element>
  </define>

  <define name="devextents">
    <oneOrMore>
      <element name="freeExtent">
        <attribute name="start">
          <ref name="unsignedLong"/>
        </attribute>
        <attribute name="end">
          <ref name="unsignedLong"/>
        </attribute>
      </element>
    </oneOrMore>
  </define>

  <define name="sourceinfodir">
    <element name="dir">
      <attribute name="path">
        <ref name="absDirPath"/>
      </attribute>
      <empty/>
    </element>
  </define>

  <define name="sourceinfonetrelativepath">
    <element name="dir">
      <attribute name="path">
        <ref name="dirPath"/>
      </attribute>
      <empty/>
    </element>
  </define>

  <define name="sourceinfoname">
    <element name="name">
      <text/>
    </element>
  </define>

  <define name="sourceinfoauth">
    <element name="auth">
      <attribute name="type">
        <choice>
          <value>chap</value>
          <value>ceph</value>
        </choice>
      </attribute>
      <attribute name="username">
        <text/>
      </attribute>
      <ref name="sourceinfoauthsecret"/>
    </element>
  </define>

  <define name="sourceinfoauthsecret">
    <element name="secret">
      <choice>
        <attribute name="uuid">
          <text/>
        </attribute>
        <attribute name="usage">
          <text/>
        </attribute>
      </choice>
    </element>
  </define>

  <define name="sourcezfs">
    <element name="source">
      <interleave>
        <ref name="sourceinfoname"/>
        <optional>
          <ref name="sourceinfodev"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="sourcevstorage">
    <element name="source">
      <interleave>
        <ref name="sourceinfoname"/>
      </interleave>
    </element>
  </define>

  <define name="sourcefmtfs">
    <optional>
      <element name="format">
        <attribute name="type">
          <choice>
            <value>auto</value>
            <value>ext2</value>
            <value>ext3</value>
            <value>ext4</value>
            <value>ufs</value>
            <value>iso9660</value>
            <value>udf</value>
            <value>gfs</value>
            <value>gfs2</value>
            <value>vfat</value>
            <value>hfs+</value>
            <value>xfs</value>
            <value>ocfs2</value>
            <value>vmfs</value>
          </choice>
        </attribute>
      </element>
    </optional>
  </define>


  <define name="sourcefmtnetfs">
    <optional>
      <element name="format">
        <attribute name="type">
          <choice>
            <value>auto</value>
            <value>nfs</value>
          </choice>
        </attribute>
      </element>
    </optional>
  </define>


  <define name="sourcefmtdisk">
    <optional>
      <element name="format">
        <attribute name="type">
          <choice>
            <value>unknown</value>
            <value>dos</value>
            <value>dvh</value>
            <value>gpt</value>
            <value>mac</value>
            <value>bsd</value>
            <value>pc98</value>
            <value>sun</value>
            <value>lvm2</value>
          </choice>
        </attribute>
        <optional>
          <ref name="sourceinfovendor"/>
        </optional>
      </element>
    </optional>
  </define>


  <define name="sourcefmtlogical">
    <optional>
      <element name="format">
        <attribute name="type">
          <choice>
            <value>unknown</value> <!-- back-compat requires keeping "unknown" not "auto" -->
            <value>lvm2</value>
          </choice>
        </attribute>
        <optional>
          <ref name="sourceinfovendor"/>
        </optional>
      </element>
    </optional>
  </define>


  <define name="sourcedir">
    <optional>
      <element name="source">
        <empty/>
        <optional>
          <ref name="sourceinfovendor"/>
        </optional>
      </element>
    </optional>
  </define>

  <define name="sourcefs">
    <element name="source">
      <interleave>
        <ref name="sourceinfodev"/>
        <ref name="sourcefmtfs"/>
        <optional>
          <ref name="sourceinfovendor"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="sourcenetfs">
    <element name="source">
      <choice>
        <group>
          <interleave>
            <ref name="sourceinfohost"/>
            <ref name="sourceinfodir"/>
            <ref name="sourcefmtnetfs"/>
            <optional>
              <element name="protocol">
                <attribute name="ver">
                  <ref name="unsignedInt"/>
                </attribute>
              </element>
            </optional>
            <optional>
              <ref name="sourceinfovendor"/>
            </optional>
          </interleave>
        </group>
        <group>
          <interleave>
            <ref name="sourceinfohost"/>
            <ref name="sourceinfonetrelativepath"/>
            <element name="format">
              <attribute name="type">
                <choice>
                  <value>cifs</value>
                  <value>glusterfs</value>
                </choice>
              </attribute>
            </element>
            <optional>
              <ref name="sourceinfovendor"/>
            </optional>
          </interleave>
        </group>
      </choice>
    </element>
  </define>

  <define name="sourcelogical">
    <element name="source">
      <interleave>
        <oneOrMore>
          <optional>
            <ref name="sourceinfoname"/>
          </optional>
          <optional>
            <ref name="sourceinfodev"/>
          </optional>
        </oneOrMore>
        <ref name="sourcefmtlogical"/>
        <optional>
          <ref name="sourceinfovendor"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="sourcedisk">
    <element name="source">
      <interleave>
        <ref name="sourceinfodev"/>
        <ref name="sourcefmtdisk"/>
        <optional>
          <ref name="sourceinfovendor"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="sourceiscsi">
    <element name="source">
      <interleave>
        <ref name="sourceinfohost"/>
        <ref name="sourceinfodev"/>
        <optional>
          <ref name="initiatorinfo"/>
        </optional>
        <optional>
          <ref name="sourceinfoauth"/>
        </optional>
        <optional>
          <ref name="sourceinfovendor"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="sourceiscsidirect">
    <element name="source">
      <interleave>
        <ref name="sourceinfohost"/>
        <ref name="sourceinfodeviscsidirect"/>
        <ref name="initiatorinfo"/>
        <optional>
          <ref name="sourceinfoauth"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="sourcescsi">
    <element name="source">
      <interleave>
        <ref name="sourceinfoadapter"/>
        <optional>
          <ref name="sourceinfovendor"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="sourcempath">
    <element name="source">
      <empty/>
    </element>
  </define>

  <define name="sourcerbd">
    <element name="source">
      <interleave>
        <ref name="sourceinfoname"/>
        <ref name="sourceinfohost"/>
        <optional>
          <ref name="sourceinfoauth"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="sourcesheepdog">
    <element name="source">
      <interleave>
        <ref name="sourceinfohost"/>
        <ref name="sourceinfoname"/>
      </interleave>
    </element>
  </define>

  <define name="sourcegluster">
    <element name="source">
      <interleave>
        <ref name="sourceinfohost"/>
        <ref name="sourceinfoname"/>
        <optional>
          <ref name="sourceinfodir"/>
        </optional>
      </interleave>
    </element>
  </define>

  <define name="IscsiQualifiedName">
    <data type="string">
      <param name="pattern">iqn\.[0-9]{4}-(0[1-9]|1[0-2])\.[a-zA-Z0-9\.\-]+(:.+)?</param>
    </data>
  </define>

  <define name="refresh">
    <optional>
      <element name="refresh">
        <interleave>
          <ref name="refreshVolume"/>
        </interleave>
      </element>
    </optional>
  </define>

  <define name="refreshVolume">
    <optional>
      <element name="volume">
        <optional>
          <attribute name="allocation">
            <ref name="refreshVolumeAllocation"/>
          </attribute>
        </optional>
      </element>
    </optional>
  </define>

  <!--
       Optional storage pool extensions in their own namespace:
         "fs" or "netfs"
    -->

  <define name="fs_mount_opts">
    <element name="mount_opts" ns="http://libvirt.org/schemas/storagepool/fs/1.0">
      <zeroOrMore>
        <element name="option">
          <attribute name="name">
            <text/>
          </attribute>
        </element>
      </zeroOrMore>
    </element>
  </define>

  <!--
       Optional storage pool extensions in their own namespace:
         RBD
    -->

  <define name="rbd_config_opts">
    <element name="config_opts" ns="http://libvirt.org/schemas/storagepool/rbd/1.0">
      <zeroOrMore>
        <element name="option">
          <attribute name="name">
            <text/>
          </attribute>
          <attribute name="value">
            <text/>
          </attribute>
        </element>
      </zeroOrMore>
    </element>
  </define>

</grammar>
