diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 297553c23a..8753b481d2 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" @@ -18380,3 +18381,34 @@ virDomainDefFindDevice(virDomainDefPtr def, return 0; } + +/** + * 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) +{ + /* No reason to think the disk source is block type if + * the source is empty + */ + if (!def->src) + return false; + + if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) + return true; + + /* For volume types, check the srcpool. + * If it's a block type source pool, then it's possible + */ + if (def->type == VIR_DOMAIN_DISK_TYPE_VOLUME && def->srcpool && + def->srcpool->voltype == VIR_STORAGE_VOL_BLOCK) { + return true; + } + return false; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 900fb01f05..3f9a9bcaf9 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2715,4 +2715,7 @@ int virDomainDefFindDevice(virDomainDefPtr def, virDomainDeviceDefPtr dev, bool reportError); +bool virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def) + ATTRIBUTE_NONNULL(1); + #endif /* __DOMAIN_CONF_H */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 885b03ec91..76873ad058 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -206,6 +206,7 @@ virDomainDiskProtocolTransportTypeToString; virDomainDiskProtocolTypeToString; virDomainDiskRemove; virDomainDiskRemoveByName; +virDomainDiskSourceIsBlockType; virDomainDiskTypeFromString; virDomainDiskTypeToString; virDomainEmulatorPinAdd; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9088c11aa8..8d414a12dc 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" @@ -3492,9 +3493,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 64214b9769..332b9f2db8 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 @@ -867,12 +868,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; @@ -978,12 +974,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; @@ -1073,12 +1064,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;