Bug fix for: https://bugzilla.redhat.com/show_bug.cgi?id=1257844 Attach-device can hotplug a virtio disk device with any address type now, it need to validate the address type before the attachment. Attaching a disk device with --config option need to check address type. Otherwise, the domain cloudn't be started normally. This patch add a basic check for address type. Detaching a disk device with --config also need to check disk options, add qemuCheckDiskConfig() method in qemuDomainDetachDeviceConfig(). Add virDomainDeviceAddressTypeIsValid method in domain_conf to check disk address type. Address type should match with disk driver, report error messages if any mismatch. Signed-off-by: Ruifeng Bian <rbian@xxxxxxxxxx> --- src/conf/domain_conf.c | 32 ++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 7 +++++++ src/qemu/qemu_driver.c | 2 ++ src/qemu/qemu_hotplug.c | 22 ++++++++++++++++++++++ 6 files changed, 65 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6df1618..f86760b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3200,6 +3200,38 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, return 0; } +int virDomainDeviceAddressTypeIsValid(virDomainDiskDefPtr disk) +{ + if (disk->info.type) { + switch (disk->bus) { + case VIR_DOMAIN_DISK_BUS_IDE: + case VIR_DOMAIN_DISK_BUS_SCSI: + case VIR_DOMAIN_DISK_BUS_SATA: + case VIR_DOMAIN_DISK_BUS_FDC: + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) + return 1; + break; + case VIR_DOMAIN_DISK_BUS_USB: + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) + return 1; + break; + case VIR_DOMAIN_DISK_BUS_VIRTIO: + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && + disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && + disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO && + disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) + return 1; + break; + case VIR_DOMAIN_DISK_BUS_XEN: + case VIR_DOMAIN_DISK_BUS_UML: + case VIR_DOMAIN_DISK_BUS_SD: + /* no address type currently, return false if address provided */ + return 1; + } + } + return 0; +} + virDomainDeviceInfoPtr virDomainDeviceGetInfo(virDomainDeviceDefPtr device) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f043554..337fe51 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2543,6 +2543,7 @@ virDomainDeviceDefPtr virDomainDeviceDefCopy(virDomainDeviceDefPtr src, virDomainXMLOptionPtr xmlopt); int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, int type); +int virDomainDeviceAddressTypeIsValid(virDomainDiskDefPtr disk); virDomainDeviceInfoPtr virDomainDeviceGetInfo(virDomainDeviceDefPtr device); int virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst, virDomainDeviceInfoPtr src); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5b3da83..6cd5b9e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -229,6 +229,7 @@ virDomainDefPostParse; virDomainDefSetMemoryInitial; virDomainDeleteConfig; virDomainDeviceAddressIsValid; +virDomainDeviceAddressTypeIsValid; virDomainDeviceAddressTypeToString; virDomainDeviceDefCheckUnsupportedMemoryDevice; virDomainDeviceDefCopy; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 25f57f2..56ba08d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3606,6 +3606,13 @@ qemuCheckDiskConfig(virDomainDiskDefPtr disk) goto error; } } + + if (virDomainDeviceAddressTypeIsValid(disk)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("disk cannot have an address of type '%s'"), + virDomainDeviceAddressTypeToString(disk->info.type)); + goto error; + } return 0; error: return -1; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index fcf86b6..26c1502 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -8208,6 +8208,8 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, switch ((virDomainDeviceType) dev->type) { case VIR_DOMAIN_DEVICE_DISK: disk = dev->data.disk; + if (qemuCheckDiskConfig(disk) < 0) + return -1; if (!(det_disk = virDomainDiskRemoveByName(vmdef, disk->dst))) { virReportError(VIR_ERR_INVALID_ARG, _("no target device %s"), disk->dst); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index e84a78d..6156243 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -336,6 +336,28 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, if (!qemuCheckCCWS390AddressSupport(vm->def, disk->info, priv->qemuCaps, disk->dst)) goto cleanup; + + if (qemuDomainMachineIsS390CCW(vm->def) && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { + if (!virDomainDeviceAddressIsValid(&disk->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be attached without a valid CCW address")); + goto cleanup; + } + } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390)) { + if (!virDomainDeviceAddressIsValid(&disk->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be attached without a valid S390 address")); + goto cleanup; + } + } else if (!virDomainDeviceAddressIsValid(&disk->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be attached without a valid PCI address")); + goto cleanup; + } } for (i = 0; i < vm->def->ndisks; i++) { -- 2.4.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list