[libvirt] [PATCH 2/8] Introduce new XMLs to specify disk source using libvirt storage

Osier Yang jyang at redhat.com
Sat Apr 6 01:56:32 UTC 2013


On 06/04/13 06:24, John Ferlan wrote:
> On 04/04/2013 03:37 PM, Osier Yang wrote:
>> With this patch, one can specify the disk source using libvirt
>> storage like:
>>
>>    <disk type='volume' device='disk'>
>>      <driver name='qemu' type='raw' cache='none'/>
>>      <source pool='default' volume='fc18.img'/>
>>      <target dev='vdb' bus='virtio'/>
>>    </disk>
>>
>> "seclables" and "startupPolicy" are not supported for this new
> s/seclables/seclabels/
>
>> disk type ("volume"). They will be supported in later patches.
>>
>> docs/formatdomain.html.in:
>>    * Add documents for new XMLs
>> docs/schemas/domaincommon.rng:
>>    * Add rng for new XMLs;
>> src/conf/domain_conf.h:
>>    * New struct for 'volume' type disk source (virDomainDiskSourcePoolDef)
>>    * Add VIR_DOMAIN_DISK_TYPE_VOLUME for enum virDomainDiskType
>> src/conf/domain_conf.c:
>>    * New helper virDomainDiskSourcePoolDefParse to parse the 'volume'
>>      type disk source.
>>    * New helper virDomainDiskSourcePoolDefFree to free the source def
>>      if 'volume' type disk.
>> tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml:
>> tests/qemuxml2xmltest.c:
>>    * New test
>> ---
>>   docs/formatdomain.html.in                          | 15 +++-
>>   docs/schemas/domaincommon.rng                      | 18 +++++
>>   src/conf/domain_conf.c                             | 89 ++++++++++++++++++++--
>>   src/conf/domain_conf.h                             |  9 +++
>>   .../qemuxml2argv-disk-source-pool.xml              | 33 ++++++++
>>   tests/qemuxml2xmltest.c                            |  1 +
>>   6 files changed, 157 insertions(+), 8 deletions(-)
>>   create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml
>>
> ACK, mechanically speaking what's here seems right - although I just get
> the feeling something is missing. I just don't have enough time yet to
> "just know" that the "<driver" and "<target" tags have a specific
> meaning and whether something else might be missing.

The only things which could be missed is some tags could prevent volume
type disk out of the door.
>
> The volume listed must be present in some pool and there's some sort of
> linkage that I don't see/get yet with this patch to validate that
>
> Maybe this should have waited for the other patches you mentioned in the
> response to Paolo.

Yeah, it should be done in driver, in later patches.

>
> My other hangup is my view of a volume is not a device like 'cdrom'
> rather it's more like /dev/sda# (on hpux it could have been
> /dev/rdisk/disk4).  That is presented to the guest as a complete volume
> or of course we also allowed partitions.  The example above using
> 'fc18.img' speaks "file" to me.

Except network volume, all other types are supported, e.g. File,
Dir, Block.

>
> John
>
>> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
>> index cf382e8..bdc815f 100644
>> --- a/docs/formatdomain.html.in
>> +++ b/docs/formatdomain.html.in
>> @@ -1372,6 +1372,11 @@
>>         <blockio logical_block_size='512' physical_block_size='4096'/>
>>         <target dev='hda' bus='ide'/>
>>       </disk>
>> +    <disk type='volume' device='disk'>
>> +      <driver name='qemu' type='raw'/>
>> +      <source pool='blk-pool0' volume='blk-pool0-vol0'/>
>> +      <target dev='hda' bus='ide'/>
>> +    </disk>
>>     </devices>
>>     ...</pre>
>>   
>> @@ -1452,10 +1457,16 @@
>>           <code>iqn.1992-01.com.example/1</code>); the default LUN is zero.
>>           When the disk <code>type</code> is "network", the <code>source</code>
>>           may have zero or more <code>host</code> sub-elements used to
>> -        specify the hosts to connect.
>> +        specify the hosts to connect.  If the disk <code>type</code> is
>> +        "volume", the underlying disk source is represented by attributes
>> +        <code>pool</code> and <code>volume</code>. Attribute <code>pool</code>
>> +        specifies the name of storage pool (managed by libvirt) where the disk
>> +        source resides, and attribute <code>volume</code> specifies the name of
>> +        storage volume (managed by libvirt) used as the disk source.
>>           <span class="since">Since 0.0.3; <code>type='dir'</code> since
>>           0.7.5; <code>type='network'</code> since
>> -        0.8.7; <code>protocol='iscsi'</code> since 1.0.4</span><br/>
>> +        0.8.7; <code>protocol='iscsi'</code> since 1.0.4;
>> +        <code>type='volume'</code> since 1.0.5;</span><br/>
>>           For a "file" disk type which represents a cdrom or floppy
>>           (the <code>device</code> attribute), it is possible to define
>>           policy what to do with the disk if the source file is not accessible.
>> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
>> index 454ebdb..46cccc4 100644
>> --- a/docs/schemas/domaincommon.rng
>> +++ b/docs/schemas/domaincommon.rng
>> @@ -1090,6 +1090,24 @@
>>               <ref name="diskspec"/>
>>             </interleave>
>>           </group>
>> +        <group>
>> +          <attribute name="type">
>> +            <value>volume</value>
>> +          </attribute>
>> +          <interleave>
>> +            <optional>
>> +              <element name="source">
>> +                <attribute name="pool">
>> +                  <ref name="genericName"/>
>> +                </attribute>
>> +                <attribute name="volume">
>> +                  <ref name="volName"/>
>> +                </attribute>
>> +              </element>
>> +            </optional>
>> +            <ref name="diskspec"/>
>> +          </interleave>
>> +        </group>
>>           <ref name="diskspec"/>
>>         </choice>
>>       </element>
>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>> index 8288959..8538d5f 100644
>> --- a/src/conf/domain_conf.c
>> +++ b/src/conf/domain_conf.c
>> @@ -207,7 +207,8 @@ VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
>>                 "block",
>>                 "file",
>>                 "dir",
>> -              "network")
>> +              "network",
>> +              "volume")
>>   
>>   VIR_ENUM_IMPL(virDomainDiskDevice, VIR_DOMAIN_DISK_DEVICE_LAST,
>>                 "disk",
>> @@ -1085,6 +1086,18 @@ void virDomainLeaseDefFree(virDomainLeaseDefPtr def)
>>       VIR_FREE(def);
>>   }
>>   
>> +static void
>> +virDomainDiskSourcePoolDefFree(virDomainDiskSourcePoolDefPtr def)
>> +{
>> +    if (!def)
>> +        return;
>> +
>> +    VIR_FREE(def->pool);
>> +    VIR_FREE(def->volume);
>> +
>> +    VIR_FREE(def);
>> +}
>> +
>>   void virDomainDiskDefFree(virDomainDiskDefPtr def)
>>   {
>>       unsigned int i;
>> @@ -1094,6 +1107,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
>>   
>>       VIR_FREE(def->serial);
>>       VIR_FREE(def->src);
>> +    virDomainDiskSourcePoolDefFree(def->srcpool);
>>       VIR_FREE(def->dst);
>>       VIR_FREE(def->driverName);
>>       virStorageFileFreeMetadata(def->backingChain);
>> @@ -3935,6 +3949,46 @@ cleanup:
>>       goto cleanup;
>>   }
>>   
>> +static int
>> +virDomainDiskSourcePoolDefParse(xmlNodePtr node,
>> +                                virDomainDiskDefPtr def)
>> +{
>> +    char *pool = NULL;
>> +    char *volume = NULL;
>> +    int ret = -1;
>> +
>> +    pool = virXMLPropString(node, "pool");
>> +    volume = virXMLPropString(node, "volume");
>> +
>> +    /* CD-ROM and Floppy allows no source */
>> +    if (!pool && !volume)
>> +        return 0;
>> +
>> +    if (!pool || !volume) {
>> +        virReportError(VIR_ERR_XML_ERROR, "%s",
>> +                       _("'pool' and 'volume' must be specified together "
>> +                         "for 'pool' type source"));
>> +        goto cleanup;
>> +    }
>> +
>> +    if (VIR_ALLOC(def->srcpool) < 0) {
>> +        virReportOOMError();
>> +        goto cleanup;
>> +    }
>> +
>> +    def->srcpool->pool = pool;
>> +    pool = NULL;
>> +    def->srcpool->volume = volume;
>> +    volume = NULL;
>> +
>> +    ret = 0;
>> +
>> +cleanup:
>> +    VIR_FREE(pool);
>> +    VIR_FREE(volume);
>> +    return ret;
>> +}
>> +
>>   #define VENDOR_LEN  8
>>   #define PRODUCT_LEN 16
>>   
>> @@ -4030,7 +4084,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>>       cur = node->children;
>>       while (cur != NULL) {
>>           if (cur->type == XML_ELEMENT_NODE) {
>> -            if (!source && !hosts &&
>> +            if (!source && !hosts && !def->srcpool &&
>>                   xmlStrEqual(cur->name, BAD_CAST "source")) {
>>                   sourceNode = cur;
>>   
>> @@ -4123,6 +4177,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>>                           child = child->next;
>>                       }
>>                       break;
>> +                case VIR_DOMAIN_DISK_TYPE_VOLUME:
>> +                    if (virDomainDiskSourcePoolDefParse(cur, def) < 0)
>> +                        goto error;
>> +                    break;
>>                   default:
>>                       virReportError(VIR_ERR_INTERNAL_ERROR,
>>                                      _("unexpected disk type %s"),
>> @@ -4421,7 +4479,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>>   
>>       /* Only CDROM and Floppy devices are allowed missing source path
>>        * to indicate no media present */
>> -    if (source == NULL && hosts == NULL &&
>> +    if (source == NULL && hosts == NULL && !def->srcpool &&
>>           def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
>>           def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
>>           virReportError(VIR_ERR_NO_SOURCE,
>> @@ -4443,8 +4501,19 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>>       }
>>   
>>       if (target == NULL) {
>> -        virReportError(VIR_ERR_NO_TARGET,
>> -                       source ? "%s" : NULL, source);
>> +        if (def->srcpool) {
>> +            char *tmp;
>> +            if (virAsprintf(&tmp, "pool = '%s', volume = '%s'",
>> +                def->srcpool->pool, def->srcpool->volume) < 0) {
>> +                virReportOOMError();
>> +                goto error;
>> +            }
>> +
>> +            virReportError(VIR_ERR_NO_TARGET, "%s", tmp);
>> +            VIR_FREE(tmp);
>> +        } else {
>> +            virReportError(VIR_ERR_NO_TARGET, source ? "%s" : NULL, source);
>> +        }
>>           goto error;
>>       }
>>   
>> @@ -12745,7 +12814,7 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
>>       int n;
>>       const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
>>   
>> -    if (def->src || def->nhosts > 0 ||
>> +    if (def->src || def->nhosts > 0 || def->srcpool ||
>>           def->startupPolicy) {
>>           switch (def->type) {
>>           case VIR_DOMAIN_DISK_TYPE_FILE:
>> @@ -12817,6 +12886,14 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
>>                   virBufferAddLit(buf, "      </source>\n");
>>               }
>>               break;
>> +        case VIR_DOMAIN_DISK_TYPE_VOLUME:
>> +            /* Parsing guarantees the def->srcpool->volume cannot be NULL
>> +             * if def->srcpool->pool is not NULL.
>> +             */
>> +            if (def->srcpool->pool)
>> +                virBufferAsprintf(buf, "      <source pool='%s' volume='%s'/>\n",
>> +                                  def->srcpool->pool, def->srcpool->volume);
>> +            break;
>>           default:
>>               virReportError(VIR_ERR_INTERNAL_ERROR,
>>                              _("unexpected disk type %s"),
>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>> index edddf25..988636e 100644
>> --- a/src/conf/domain_conf.h
>> +++ b/src/conf/domain_conf.h
>> @@ -447,6 +447,7 @@ enum virDomainDiskType {
>>       VIR_DOMAIN_DISK_TYPE_FILE,
>>       VIR_DOMAIN_DISK_TYPE_DIR,
>>       VIR_DOMAIN_DISK_TYPE_NETWORK,
>> +    VIR_DOMAIN_DISK_TYPE_VOLUME,
>>   
>>       VIR_DOMAIN_DISK_TYPE_LAST
>>   };
>> @@ -606,6 +607,13 @@ struct _virDomainBlockIoTuneInfo {
>>   };
>>   typedef virDomainBlockIoTuneInfo *virDomainBlockIoTuneInfoPtr;
>>   
>> +typedef struct _virDomainDiskSourcePoolDef virDomainDiskSourcePoolDef;
>> +struct _virDomainDiskSourcePoolDef {
>> +    char *pool; /* pool name */
>> +    char *volume; /* volume name */
>> +};
>> +typedef virDomainDiskSourcePoolDef *virDomainDiskSourcePoolDefPtr;
>> +
>>   /* Stores the virtual disk configuration */
>>   struct _virDomainDiskDef {
>>       int type;
>> @@ -617,6 +625,7 @@ struct _virDomainDiskDef {
>>       int protocol;
>>       size_t nhosts;
>>       virDomainDiskHostDefPtr hosts;
>> +    virDomainDiskSourcePoolDefPtr srcpool;
>>       struct {
>>           char *username;
>>           int secretType; /* enum virDomainDiskSecretType */
>> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml
>> new file mode 100644
>> index 0000000..876eebe
>> --- /dev/null
>> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml
>> @@ -0,0 +1,33 @@
>> +<domain type='qemu'>
>> +  <name>QEMUGuest1</name>
>> +  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
>> +  <memory unit='KiB'>219136</memory>
>> +  <currentMemory unit='KiB'>219136</currentMemory>
>> +  <vcpu placement='static'>1</vcpu>
>> +  <os>
>> +    <type arch='i686' machine='pc'>hvm</type>
>> +    <boot dev='hd'/>
>> +  </os>
>> +  <clock offset='utc'/>
>> +  <on_poweroff>destroy</on_poweroff>
>> +  <on_reboot>restart</on_reboot>
>> +  <on_crash>destroy</on_crash>
>> +  <devices>
>> +    <emulator>/usr/bin/qemu</emulator>
>> +    <disk type='volume' device='cdrom'>
>> +      <source pool='blk-pool0' volume='blk-pool0-vol0'/>
>> +      <target dev='hda' bus='ide'/>
>> +      <readonly/>
>> +      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
>> +    </disk>
>> +    <disk type='file' device='disk'>
>> +      <source file='/tmp/idedisk.img'/>
>> +      <target dev='hdc' bus='ide'/>
>> +      <address type='drive' controller='0' bus='0' target='0' unit='2'/>
>> +    </disk>
>> +    <controller type='usb' index='0'/>
>> +    <controller type='ide' index='0'/>
>> +    <controller type='ide' index='1'/>
>> +    <memballoon model='virtio'/>
>> +  </devices>
>> +</domain>
>> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
>> index ba9aa96..fa79960 100644
>> --- a/tests/qemuxml2xmltest.c
>> +++ b/tests/qemuxml2xmltest.c
>> @@ -252,6 +252,7 @@ mymain(void)
>>       DO_TEST("disk-scsi-lun-passthrough-sgio");
>>   
>>       DO_TEST("disk-scsi-disk-vpd");
>> +    DO_TEST("disk-source-pool");
>>   
>>       DO_TEST("virtio-rng-random");
>>       DO_TEST("virtio-rng-egd");
>>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list




More information about the libvir-list mailing list