[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