[libvirt] [PATCH v3 4/7] qemu: Translate the iscsi pool/volume disk source

Osier Yang jyang at redhat.com
Mon Jul 22 10:30:51 UTC 2013


On 19/07/13 20:32, John Ferlan wrote:
> The difference with already supported pool types (dir, fs, block)
> is: there are two modes for iscsi pool (or network pools in future),
> one can specify it either to use the volume target path (the path
> showed up on host) with mode='host', or to use the remote URI qemu
> supports (e.g. file=iscsi://example.org:6000/iqn.1992-01.com.example/1)
> with mode='direct'.
>
> For 'host' mode, it copies the volume target path into disk->src. For
> 'direct' mode, the corresponding info in the *one* pool source host def
> is copied to disk->hosts[0].
> ---
>   src/conf/domain_conf.c  |   8 ++++
>   src/conf/domain_conf.h  |   1 +
>   src/qemu/qemu_command.c |  15 ++++++-
>   src/qemu/qemu_conf.c    | 101 +++++++++++++++++++++++++++++++++++++++++++++++-
>   4 files changed, 123 insertions(+), 2 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index dddd55d..231edb5 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -18403,6 +18403,14 @@ virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def)
>        */
>       if (def->type == VIR_DOMAIN_DISK_TYPE_VOLUME && def->srcpool &&
>           def->srcpool->voltype == VIR_STORAGE_VOL_BLOCK) {
> +        /* We don't think the volume accessed by remote URI is
> +         * block type source, since we can't/shouldn't manage it
> +         * (e.g. set sgio=filtered|unfiltered for it) in libvirt.
> +         */
> +         if (def->srcpool->pooltype == VIR_STORAGE_POOL_ISCSI &&
> +             def->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT)
> +             return false;
> +
>           return true;
>       }
>       return false;
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 4db981d..327f3f9 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -677,6 +677,7 @@ struct _virDomainDiskSourcePoolDef {
>       char *pool; /* pool name */
>       char *volume; /* volume name */
>       int voltype; /* enum virStorageVolType, internal only */
> +    int pooltype; /* enum virStoragePoolType, internal only */
>       int mode; /* enum virDomainDiskSourcePoolMode */
>   };
>   typedef virDomainDiskSourcePoolDef *virDomainDiskSourcePoolDefPtr;
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 5265f77..4e4ee9e 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -3214,7 +3214,20 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
>                                        "block type volume"));
>                       goto error;
>                   }
> -                virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
> +
> +                if (disk->srcpool->pooltype == VIR_STORAGE_POOL_ISCSI) {
> +                    if (disk->srcpool->mode ==
> +                        VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT) {
> +                        if (qemuBuildISCSIString(conn, disk, &opt) < 0)
> +                            goto error;
> +                        virBufferAddChar(&opt, ',');
> +                    } else if (disk->srcpool->mode ==
> +                               VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST) {
> +                        virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
> +                    }
> +                } else {
> +                    virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
> +                }
>                   break;
>               case VIR_STORAGE_VOL_FILE:
>                   virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> index 332b9f2..6e6163f 100644
> --- a/src/qemu/qemu_conf.c
> +++ b/src/qemu/qemu_conf.c
> @@ -1125,12 +1125,75 @@ int qemuDriverAllocateID(virQEMUDriverPtr driver)
>       return virAtomicIntInc(&driver->nextvmid);
>   }
>   
> +static int
> +qemuAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
> +                           virStoragePoolDefPtr pooldef)

nice abstraction. it's good other network pools' support in future.

> +{
> +    int ret = -1;
> +    char **tokens = NULL;
> +
> +    /* Only support one host */
> +    if (pooldef->source.nhost != 1) {
> +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                       _("Expected exactly 1 host for the storage pool"));
> +        goto cleanup;
> +    }
> +
> +    /* iscsi pool only supports one host */
> +    def->nhosts = 1;
> +
> +    if (VIR_ALLOC_N(def->hosts, def->nhosts) < 0)
> +        goto cleanup;
> +
> +    if (VIR_STRDUP(def->hosts[0].name, pooldef->source.hosts[0].name) < 0)
> +        goto cleanup;
> +
> +    if (virAsprintf(&def->hosts[0].port, "%d",
> +                    pooldef->source.hosts[0].port ?
> +                    pooldef->source.hosts[0].port :
> +                    3260) < 0)
> +        goto cleanup;
> +
> +    /* iscsi volume has name like "unit:0:0:1" */
> +    if (!(tokens = virStringSplit(def->srcpool->volume, ":", 0)))
> +        goto cleanup;
> +
> +    if (virStringListLength(tokens) != 4) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("unexpected iscsi volume name '%s'"),
> +                       def->srcpool->volume);
> +        goto cleanup;
> +    }
> +
> +    /* iscsi pool has only one source device path */
> +    if (virAsprintf(&def->src, "%s/%s",
> +                    pooldef->source.devices[0].path,
> +                    tokens[3]) < 0)
> +        goto cleanup;
> +
> +    /* Storage pool have not supported these 2 attributes yet,
> +     * use the defaults.
> +     */
> +    def->hosts[0].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
> +    def->hosts[0].socket = NULL;
> +
> +    def->protocol = VIR_DOMAIN_DISK_PROTOCOL_ISCSI;
> +
> +    ret = 0;
> +
> +cleanup:
> +    virStringFreeList(tokens);
> +    return ret;
> +}
> +
>   int
>   qemuTranslateDiskSourcePool(virConnectPtr conn,
>                               virDomainDiskDefPtr def)
>   {
> +    virStoragePoolDefPtr pooldef = NULL;
>       virStoragePoolPtr pool = NULL;
>       virStorageVolPtr vol = NULL;
> +    char *poolxml = NULL;
>       virStorageVolInfo info;
>       int ret = -1;
>   
> @@ -1158,11 +1221,45 @@ qemuTranslateDiskSourcePool(virConnectPtr conn,
>   
>       switch (info.type) {
>       case VIR_STORAGE_VOL_FILE:
> -    case VIR_STORAGE_VOL_BLOCK:
>       case VIR_STORAGE_VOL_DIR:
>           if (!(def->src = virStorageVolGetPath(vol)))
>               goto cleanup;
>           break;
> +    case VIR_STORAGE_VOL_BLOCK:
> +        if (!(poolxml = virStoragePoolGetXMLDesc(pool, 0)))
> +            goto cleanup;
> +
> +        if (!(pooldef = virStoragePoolDefParseString(poolxml)))
> +            goto cleanup;
> +
> +        if (def->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
> +            virReportError(VIR_ERR_XML_ERROR, "%s",
> +                           _("disk source mode is only valid when "
> +                             "storage pool is of iscsi type"));
> +            goto cleanup;
> +        }
> +
> +        def->srcpool->pooltype = pooldef->type;
> +        if (pooldef->type == VIR_STORAGE_POOL_ISCSI) {
> +            /* Default to use the LUN's path on host */
> +            if (!def->srcpool->mode)
> +                def->srcpool->mode = VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST;
> +
> +            if (def->srcpool->mode ==
> +                VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT) {
> +                if (qemuAddISCSIPoolSourceHost(def, pooldef) < 0)
> +                    goto cleanup;
> +            } else if (def->srcpool->mode ==
> +                       VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST) {
> +                if (!(def->src = virStorageVolGetPath(vol)))
> +                    goto cleanup;
> +            }
> +        } else {
> +            if (!(def->src = virStorageVolGetPath(vol)))
> +                goto cleanup;
> +        }
> +
> +        break;
>       case VIR_STORAGE_VOL_NETWORK:
>           virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
>                          _("Using network volume as disk source is not supported"));
> @@ -1174,5 +1271,7 @@ qemuTranslateDiskSourcePool(virConnectPtr conn,
>   cleanup:
>       virStoragePoolFree(pool);
>       virStorageVolFree(vol);
> +    VIR_FREE(poolxml);
> +    virStoragePoolDefFree(pooldef);
>       return ret;
>   }
though i'm the original author, but it's long time and there are changes.

ACK.




More information about the libvir-list mailing list