When starting a new domain, we allocate the USB addresses and keep
an address cache in the domain object's private data.

However this data is lost on libvirtd restart.

Also generate the address cache if all the addresses have been
specified, so that devices hotplugged after libvirtd restart
also get theirs assigned.

https://bugzilla.redhat.com/show_bug.cgi?id=1387666
---
 src/conf/domain_addr.c         | 12 ++++++++++++
 src/conf/domain_addr.h         |  4 ++++
 src/libvirt_private.syms       |  1 +
 src/qemu/qemu_domain_address.c | 16 ++++++++++++++--
 4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index 92a5516..34fa01b 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -1797,6 +1797,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 141f83b..ee8dc04 100644
--- a/src/conf/domain_addr.h
+++ b/src/conf/domain_addr.h
@@ -299,6 +299,10 @@ 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)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ce9c4c4..cbc97f7 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 7d92e0b..a6001ad 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1710,12 +1710,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;
 
@@ -1772,7 +1784,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;
-- 
2.7.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to