Now that virDomainDefCompatibleDevice accepts an action,
let's use that to generically determine whether a to be
cold plugged device with a defined <address> would conflict
with any existing address for the domain config. This
replaces the RNG check in qemuDomainAttachDeviceConfig.
This type of check would need to be made before a device
is inserted into its domain device list (disk, rng, hostdev,
etc.). This type of check cannot be done during the post
parse processing because the check would conflict with
itself as the device would be placed onto the its device
list prior to post parse.
By comparison this is similar to the validation phase
checks in virDomainDefCheckDuplicateDriveAddresses that
occur during define/startup processing, but are not run
during config attach of a live guest.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/conf/domain_conf.c | 22 ++++++++++++++++++++++
src/qemu/qemu_driver.c | 7 -------
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 82df8012af..fd5bc10c82 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -28270,11 +28270,25 @@ virDomainDefCompatibleDevice(virDomainDefPtr def,
virDomainDeviceAction action,
bool live)
{
+ int target_bus = -1;
virDomainCompatibleDeviceData data = {
.newInfo = virDomainDeviceGetInfo(dev),
.oldInfo = NULL,
};
+ if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+ target_bus = dev->data.disk->bus;
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
+ dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
+ virDomainHostdevSubsysPtr subsys = &dev->data.hostdev->source.subsys;
+
+ /* If using 'scsi' or 'scsi_host', then the device can be placed
+ * on the same bus as a <disk>, so account for that */
+ if (subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI ||
+ subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST)
+ target_bus = VIR_DOMAIN_DISK_BUS_SCSI;
+ }
+
if (oldDev)
data.oldInfo = virDomainDeviceGetInfo(oldDev);
@@ -28288,6 +28302,14 @@ virDomainDefCompatibleDevice(virDomainDefPtr def,
return -1;
}
+ if (action == VIR_DOMAIN_DEVICE_ACTION_ATTACH && !live &&
data.newInfo &&
+ data.newInfo->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+ virDomainDefHasDeviceAddress(def, target_bus, data.newInfo)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("a device with the same address already exists"));
+ return -1;
+ }
+
if (!virDomainDefHasUSB(def) &&
def->os.type != VIR_DOMAIN_OSTYPE_EXE &&
virDomainDeviceIsUSB(dev)) {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5f91d463ae..7d519c0714 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8081,13 +8081,6 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
break;
case VIR_DOMAIN_DEVICE_RNG:
- if (dev->data.rng->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
&&
- virDomainDefHasDeviceAddress(vmdef, -1, &dev->data.rng->info)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("a device with the same address already exists
"));
- return -1;
- }
-
if (VIR_APPEND_ELEMENT(vmdef->rngs, vmdef->nrngs, dev->data.rng) <
0)
return -1;
dev->data.rng = NULL;
--
2.17.1