[libvirt] [PATCH 0/6] Support to use iscsi storage in domain conf

This supports to use libvirt iscsi storage volume for qemu with either the LUN's path on host (e.g. /dev/disk/by-path/*-lun-1), or the the libiscsi uri (e.g iscsi://demo.org:6000/$iqn/1)in domain conf. Osier Yang (6): storage_iscsi: Reflect the default target port conf: Introduce new XML tag "mode" for disk source qemu: Translate the iscsi pool/volume disk source security: Ignore to manage the volume type disk if its mode is uri conf: Ignore the volume type disk if its mode is "uri" qemu: Translate the volume type disk source before cgroup setting docs/formatdomain.html.in | 9 ++- docs/schemas/domaincommon.rng | 8 +++ src/conf/domain_conf.c | 71 +++++++++++++++++++++- src/conf/domain_conf.h | 25 ++++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 20 ++++-- src/qemu/qemu_conf.c | 117 +++++++++++++++++++++++++++++------- src/qemu/qemu_process.c | 13 ++-- src/security/security_apparmor.c | 10 ++- src/security/security_dac.c | 10 ++- src/security/security_selinux.c | 10 ++- src/storage/storage_backend_iscsi.c | 6 +- tests/qemuxml2xmltest.c | 1 + 13 files changed, 261 insertions(+), 40 deletions(-) -- 1.8.1.4

The default port for iSCSI target is 3260, which should be reflected to the pool's def. --- src/storage/storage_backend_iscsi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c index 0a4cd22..eb8e128 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -44,12 +44,14 @@ #define VIR_FROM_THIS VIR_FROM_STORAGE +#define ISCSI_DEFAULT_TARGET_PORT 3260 + static char * virStorageBackendISCSIPortal(virStoragePoolSourcePtr source) { char *portal = NULL; const char *host; - int port = 3260; + int port; if (source->nhost != 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -60,6 +62,8 @@ virStorageBackendISCSIPortal(virStoragePoolSourcePtr source) host = source->hosts[0].name; if (source->hosts[0].port != 0) port = source->hosts[0].port; + else + port = source->hosts[0].port = ISCSI_DEFAULT_TARGET_PORT; if (strchr(host, ':')) { if (virAsprintf(&portal, "[%s]:%d,1", host, port) < 0) -- 1.8.1.4

There are two ways to use a iSCSI LUN as disk source for qemu. * The LUN's path showed up on host, e.g. /dev/disk/by-path/ip-$ip:3260-iscsi-$iqn-fc18:iscsi.iscsi0-lun-1 * The libiscsi URI, e.g. iscsi://demo.org:6000/iqn.1992-01.com.example/1 For a "volume" type disk, if the specified "pool" is of iscsi type, we should support to use the LUN either of above 2 ways. That's why to introduce a new XML tag "mode" for the disk source (libvirt should support iscsi pool with libiscsi, but it's another new feature, which should be done later). The "mode" can be either of "host" or "uri". "host" to indicate use the LUN with the path showed up on host. "uri" to indicate use it with the libiscsi URI (future patches may support to use network type libvirt storage too, e.g. Ceph, that's why to use a more general name "uri"). --- docs/formatdomain.html.in | 9 ++++++++- docs/schemas/domaincommon.rng | 8 ++++++++ src/conf/domain_conf.c | 24 +++++++++++++++++++++++- src/conf/domain_conf.h | 22 ++++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 755d084..4e344a2 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1557,7 +1557,14 @@ <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. + storage volume (managed by libvirt) used as the disk source. For a + "volume" type disk, if the underlying storage pool is "iscsi", attribute + <code>mode</code> (<span class="since">since 1.0.7</span>) can be used + to indicate how to represent the LUN as the disk source. value "host" + indicate to use the LUN's path showed up on host, e.g. + /dev/disk/by-path/ip-10.11.12.9:3260-iscsi-iqn.2013-06.fc:iscsi.iscsi0-lun-1) + . Value "uri" indicates to use the libiscsi URI, e.g. + file=iscsi://demo.org:6000/iqn.1992-01.com.example/1. Defaults to "host". <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; diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 3cace35..ac61582 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1145,6 +1145,14 @@ <ref name="volName"/> </attribute> <optional> + <attribute name="mode"> + <choice> + <value>host</value> + <value>uri</value> + </choice> + </attribute> + </optional> + <optional> <ref name="startupPolicy"/> </optional> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3e81013..009a8aa 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -756,6 +756,12 @@ VIR_ENUM_IMPL(virDomainDiskDiscard, VIR_DOMAIN_DISK_DISCARD_LAST, "unmap", "ignore") +VIR_ENUM_IMPL(virDomainDiskSourcePoolMode, + VIR_DOMAIN_DISK_SOURCE_POOL_MODE_LAST, + "default", + "host", + "uri") + #define VIR_DOMAIN_XML_WRITE_FLAGS VIR_DOMAIN_XML_SECURE #define VIR_DOMAIN_XML_READ_FLAGS VIR_DOMAIN_XML_INACTIVE @@ -4600,10 +4606,12 @@ virDomainDiskSourcePoolDefParse(xmlNodePtr node, { char *pool = NULL; char *volume = NULL; + char *mode = NULL; int ret = -1; pool = virXMLPropString(node, "pool"); volume = virXMLPropString(node, "volume"); + mode = virXMLPropString(node, "mode"); /* CD-ROM and Floppy allows no source */ if (!pool && !volume) @@ -4621,6 +4629,14 @@ virDomainDiskSourcePoolDefParse(xmlNodePtr node, goto cleanup; } + if (mode && (def->srcpool->mode = + virDomainDiskSourcePoolModeTypeFromString(mode)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown source mode '%s' for volume type disk"), + mode); + goto cleanup; + } + def->srcpool->pool = pool; pool = NULL; def->srcpool->volume = volume; @@ -4631,6 +4647,7 @@ virDomainDiskSourcePoolDefParse(xmlNodePtr node, cleanup: VIR_FREE(pool); VIR_FREE(volume); + VIR_FREE(mode); return ret; } @@ -13856,9 +13873,14 @@ virDomainDiskSourceDefFormat(virBufferPtr buf, case VIR_DOMAIN_DISK_TYPE_VOLUME: virBufferAddLit(buf, " <source"); - if (def->srcpool) + if (def->srcpool) { virBufferAsprintf(buf, " pool='%s' volume='%s'", def->srcpool->pool, def->srcpool->volume); + if (def->srcpool->mode) + virBufferAsprintf(buf, " mode='%s'", + virDomainDiskSourcePoolModeTypeToString(def->srcpool->mode)); + } + if (def->startupPolicy) virBufferEscapeString(buf, " startupPolicy='%s'", startupPolicy); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index b8edb1e..d57b7c3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -646,11 +646,32 @@ struct _virDomainBlockIoTuneInfo { }; typedef virDomainBlockIoTuneInfo *virDomainBlockIoTuneInfoPtr; +/* + * Used for volume "type" disk to indicate how to represent + * the disk source if the specified "pool" is of iscsi type. + */ +enum virDomainDiskSourcePoolMode { + VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DEFAULT = 0, + + /* Use the path showed up on host, e.g. + * /dev/disk/by-path/ip-$ip-iscsi-$iqn:iscsi.iscsi-pool0-lun-1 + */ + VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST, + + /* Use the URI. E.g. + * file=iscsi://demo.org:6000/iqn.1992-01.com.example/1. + */ + VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI, + + VIR_DOMAIN_DISK_SOURCE_POOL_MODE_LAST +}; + typedef struct _virDomainDiskSourcePoolDef virDomainDiskSourcePoolDef; struct _virDomainDiskSourcePoolDef { char *pool; /* pool name */ char *volume; /* volume name */ int voltype; /* enum virStorageVolType, internal only */ + int mode; /* enum virDomainDiskSourcePoolMode */ }; typedef virDomainDiskSourcePoolDef *virDomainDiskSourcePoolDefPtr; @@ -2497,6 +2518,7 @@ VIR_ENUM_DECL(virDomainDiskSecretType) VIR_ENUM_DECL(virDomainDeviceSGIO) VIR_ENUM_DECL(virDomainDiskTray) VIR_ENUM_DECL(virDomainDiskDiscard) +VIR_ENUM_DECL(virDomainDiskSourcePoolMode) VIR_ENUM_DECL(virDomainIoEventFd) VIR_ENUM_DECL(virDomainVirtioEventIdx) VIR_ENUM_DECL(virDomainDiskCopyOnRead) diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 06e4206..cb14cb9 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -261,6 +261,7 @@ mymain(void) DO_TEST("disk-scsi-disk-vpd"); DO_TEST("disk-source-pool"); + DO_TEST("disk-source-pool-mode"); DO_TEST("disk-drive-discard"); -- 1.8.1.4

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='uri'. For 'host' mode, it copies the volume target path into disk->src. For 'uri' mode, the conresponded info in the *one* pool source host def are copied to disk->hosts[0]. * src/conf/domain_conf.[ch]: (Introduce a new helper to check if the disk source is of block type: virDomainDiskSourceIsBlockType; Introduce "pooltype" for disk->srcpool, to indicate the pool type) src/libvirt_private.syms: (Expose the new helper's symbol) * src/qemu/qemu_conf.c: (Use the helper to ease the checking in "shared disk", "sgio" related helpers; Translate the iscsi pool/volume disk source) * src/qemu/qemu_command.c (Use the helper to ease the checking in qemuBuildDriveDevStr; Build qemu command line for iscsi pool/volume disk source) --- src/conf/domain_conf.c | 42 +++++++++++++++++ src/conf/domain_conf.h | 3 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 20 ++++++-- src/qemu/qemu_conf.c | 117 ++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 158 insertions(+), 25 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 009a8aa..04b14dc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -41,6 +41,7 @@ #include "virbuffer.h" #include "virlog.h" #include "nwfilter_conf.h" +#include "storage_conf.h" #include "virstoragefile.h" #include "virfile.h" #include "virbitmap.h" @@ -17950,3 +17951,44 @@ virDomainDiskDefGenSecurityLabelDef(const char *model) return seclabel; } + +/** + * virDomainDiskSourceIsBlockType: + * + * Check if the disk *source* is of block type. This just tries + * to check from the type of disk def, not to probe the underlying + * storage. + * + * Return true if its source is block type, or false otherwise. + */ +bool +virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def) +{ + if (!def) + return false; + + /* No reason to think the disk source is block type if + * the source is empty + */ + if (!def->src && !def->srcpool) + return false; + + if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) + return true; + + if (def->type == VIR_DOMAIN_DISK_TYPE_VOLUME) { + if (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/shoudn't manage it + * (e.g. set sgio=filtered|unfilered for it) in libvirt. + */ + if (def->srcpool->pooltype == VIR_STORAGE_POOL_ISCSI && + def->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI) + return false; + + return true; + } + } + + return false; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d57b7c3..3c60293 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -671,6 +671,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; @@ -2652,4 +2653,6 @@ virDomainDefMaybeAddController(virDomainDefPtr def, char *virDomainDefGetDefaultEmulator(virDomainDefPtr def, virCapsPtr caps); +bool virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def); + #endif /* __DOMAIN_CONF_H */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1ea7467..fa9f079 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -161,6 +161,7 @@ virDomainDiskProtocolTransportTypeToString; virDomainDiskProtocolTypeToString; virDomainDiskRemove; virDomainDiskRemoveByName; +virDomainDiskSourceIsBlockType; virDomainDiskTypeFromString; virDomainDiskTypeToString; virDomainEmulatorPinAdd; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 486682e..ae5f7dd 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -42,6 +42,7 @@ #include "domain_audit.h" #include "domain_conf.h" #include "snapshot_conf.h" +#include "storage_conf.h" #include "network/bridge_driver.h" #include "virnetdevtap.h" #include "base64.h" @@ -3163,7 +3164,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_URI) { + 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); @@ -3450,9 +3464,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, virDomainDiskProtocolTypeToString(disk->protocol)); goto error; } - } else if (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK && - !(disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && - disk->srcpool->voltype == VIR_STORAGE_VOL_BLOCK)) { + } else if (!virDomainDiskSourceIsBlockType(disk)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("disk device='lun' is only valid for block type disk source")); goto error; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 094f9f7..b67f182 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -52,6 +52,7 @@ #include "virfile.h" #include "virstring.h" #include "viratomic.h" +#include "storage_conf.h" #include "configmake.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -1180,12 +1181,7 @@ qemuAddSharedDevice(virQEMUDriverPtr driver, if (dev->type == VIR_DOMAIN_DEVICE_DISK) { disk = dev->data.disk; - if (!disk->shared || - !disk->src || - (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK && - !(disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && - disk->srcpool && - disk->srcpool->voltype == VIR_STORAGE_VOL_BLOCK))) + if (!disk->shared || !virDomainDiskSourceIsBlockType(disk)) return 0; } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { hostdev = dev->data.hostdev; @@ -1295,12 +1291,7 @@ qemuRemoveSharedDevice(virQEMUDriverPtr driver, if (dev->type == VIR_DOMAIN_DEVICE_DISK) { disk = dev->data.disk; - if (!disk->shared || - !disk->src || - (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK && - !(disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && - disk->srcpool && - disk->srcpool->voltype == VIR_STORAGE_VOL_BLOCK))) + if (!disk->shared || !virDomainDiskSourceIsBlockType(disk)) return 0; } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { hostdev = dev->data.hostdev; @@ -1392,12 +1383,8 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) if (dev->type == VIR_DOMAIN_DEVICE_DISK) { disk = dev->data.disk; - if (!disk->src || - disk->device != VIR_DOMAIN_DISK_DEVICE_LUN || - (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK && - !(disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && - disk->srcpool && - disk->srcpool->voltype == VIR_STORAGE_VOL_BLOCK))) + if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN || + virDomainDiskSourceIsBlockType(disk)) return 0; path = disk->src; @@ -1463,9 +1450,12 @@ int qemuTranslateDiskSourcePool(virConnectPtr conn, virDomainDiskDefPtr def) { + virStoragePoolDefPtr pooldef = NULL; virStoragePoolPtr pool = NULL; virStorageVolPtr vol = NULL; + char *poolxml = NULL; virStorageVolInfo info; + char **tokens = NULL; int ret = -1; if (def->type != VIR_DOMAIN_DISK_TYPE_VOLUME) @@ -1492,11 +1482,91 @@ 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 (pooldef->type != VIR_STORAGE_POOL_ISCSI && + def->srcpool->mode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("disk source mode is only valid when " + "storage pool is of iscsi type")); + goto cleanup; + } + + 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_URI) { + /* iscsi pool only supports one host */ + def->nhosts = 1; + + if (VIR_ALLOC_N(def->hosts, def->nhosts) < 0) { + virReportOOMError(); + 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) { + virReportOOMError(); + 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) { + virReportOOMError(); + goto cleanup; + } + + /* Storage pool have not supportted 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; + } 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; + } + + def->srcpool->pooltype = pooldef->type; + break; case VIR_STORAGE_VOL_NETWORK: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Using network volume as disk source is not supported")); @@ -1506,7 +1576,12 @@ qemuTranslateDiskSourcePool(virConnectPtr conn, def->srcpool->voltype = info.type; ret = 0; cleanup: - virStoragePoolFree(pool); - virStorageVolFree(vol); + if (pool) + virStoragePoolFree(pool); + if (vol) + virStorageVolFree(vol); + VIR_FREE(poolxml); + virStoragePoolDefFree(pooldef); + virStringFreeList(tokens); return ret; } -- 1.8.1.4

It's straightforward to not manage security labels for remote URI like "iscsi://example.org:6000/iqn.1992-01.com.example/1". --- src/security/security_apparmor.c | 10 ++++++++-- src/security/security_dac.c | 10 ++++++++-- src/security/security_selinux.c | 10 ++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index 87c2777..b8a5be2 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -682,7 +682,10 @@ AppArmorRestoreSecurityImageLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, virDomainDiskDefPtr disk) { - if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) + if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK || + (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && + disk->srcpool && + disk->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI)) return 0; return reload_profile(mgr, def, NULL, false); @@ -704,7 +707,10 @@ AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr, if (secdef->norelabel) return 0; - if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) + if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK || + (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && + disk->srcpool && + disk->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI)) return 0; if (secdef->imagelabel) { diff --git a/src/security/security_dac.c b/src/security/security_dac.c index b8d1a92..881101a 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -368,7 +368,10 @@ virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr, if (!priv->dynamicOwnership) return 0; - if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) + if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK || + (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && + disk->srcpool && + disk->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI)) return 0; params[0] = mgr; @@ -391,7 +394,10 @@ virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr, if (!priv->dynamicOwnership) return 0; - if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) + if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK || + (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && + disk->srcpool && + disk->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI)) return 0; /* Don't restore labels on readoly/shared disks, because diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index b862fbf..829bd89 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -1148,7 +1148,10 @@ virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr, if (disk->readonly || disk->shared) return 0; - if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) + if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK || + (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && + disk->srcpool && + disk->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI)) return 0; /* If we have a shared FS & doing migrated, we must not @@ -1248,7 +1251,10 @@ virSecuritySELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr, if (cbdata.secdef->norelabel) return 0; - if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) + if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK || + (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && + disk->srcpool && + disk->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI)) return 0; return virDomainDiskDefForeachPath(disk, -- 1.8.1.4

virDomainDiskDefForeachPath is not only used by the security setting helpers, also used by cgroup setting helpers, so this is to ignore the volume type disk with mode="uri" for cgroup setting. --- src/conf/domain_conf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 04b14dc..2f397de 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17155,7 +17155,10 @@ virDomainDiskDefForeachPath(virDomainDiskDefPtr disk, size_t depth = 0; virStorageFileMetadata *tmp; - if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) + if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK || + (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME && + disk->srcpool && + disk->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_URI)) return 0; if (iter(disk, disk->src, 0, opaque) < 0) -- 1.8.1.4

The translation must be done before both of cgroup and security setting, otherwise since the disk source is not translated yet, it might be skipped on cgroup and security setting. --- src/qemu/qemu_process.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index c412ea2..351440b 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3552,6 +3552,14 @@ int qemuProcessStart(virConnectPtr conn, } hookData.nodemask = nodemask; + /* "volume" type disk's source must be translated before + * cgroup and security setting. + */ + for (i = 0; i < vm->def->ndisks; i++) { + if (qemuTranslateDiskSourcePool(conn, vm->def->disks[i]) < 0) + goto cleanup; + } + VIR_DEBUG("Setting up domain cgroup (if required)"); if (qemuSetupCgroup(driver, vm, nodemask) < 0) goto cleanup; @@ -3598,11 +3606,6 @@ int qemuProcessStart(virConnectPtr conn, goto cleanup; } - for (i = 0; i < vm->def->ndisks; i++) { - if (qemuTranslateDiskSourcePool(conn, vm->def->disks[i]) < 0) - goto cleanup; - } - VIR_DEBUG("Building emulator command line"); if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig, priv->monJSON, priv->qemuCaps, -- 1.8.1.4
participants (1)
-
Osier Yang