diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 2e0c9818db..2af9c646c2 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1830,6 +1830,18 @@ virDomainUSBAddressAssign(virDomainUSBAddressSetPtr addrs, } +int +virDomainUSBAddressPresent(virDomainDeviceInfoPtr info, + void *data ATTRIBUTE_UNUSED) +{ + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB && + virDomainUSBAddressPortIsValid(info->addr.usb.port)) + return 0; + + return -1; +} + + int virDomainUSBAddressReserve(virDomainDeviceInfoPtr info, void *data) diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 7b6fff058a..ff80fce6fe 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -300,6 +300,10 @@ size_t virDomainUSBAddressCountAllPorts(virDomainDefPtr def); void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs); +int +virDomainUSBAddressPresent(virDomainDeviceInfoPtr info, + void *data) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int virDomainUSBAddressReserve(virDomainDeviceInfoPtr info, void *data) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d2156bd725..162fda54f9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -116,6 +116,7 @@ virDomainUSBAddressEnsure; virDomainUSBAddressPortFormat; virDomainUSBAddressPortFormatBuf; virDomainUSBAddressPortIsValid; +virDomainUSBAddressPresent; virDomainUSBAddressRelease; virDomainUSBAddressReserve; virDomainUSBAddressSetAddControllers; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 12f3a29f94..b35a95f08c 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1750,12 +1750,24 @@ qemuDomainUSBAddressAddHubs(virDomainDefPtr def) static int qemuDomainAssignUSBAddresses(virDomainDefPtr def, - virDomainObjPtr obj) + virDomainObjPtr obj, + bool newDomain) { int ret = -1; virDomainUSBAddressSetPtr addrs = NULL; qemuDomainObjPrivatePtr priv = NULL; + if (!newDomain) { + /* only create the address cache for: + * new domains + * domains that already have all the addresses specified + * otherwise libvirt's attempt to recreate the USB topology via + * QEMU command line might fail */ + if (virDomainUSBDeviceDefForeach(def, virDomainUSBAddressPresent, NULL, + false) < 0) + return 0; + } + if (!(addrs = virDomainUSBAddressSetCreate())) goto cleanup; @@ -1812,7 +1824,7 @@ qemuDomainAssignAddresses(virDomainDefPtr def, if (qemuDomainAssignPCIAddresses(def, qemuCaps, obj) < 0) return -1; - if (newDomain && qemuDomainAssignUSBAddresses(def, obj) < 0) + if (qemuDomainAssignUSBAddresses(def, obj, newDomain) < 0) return -1; return 0;