From dc67d00cd22844dbe4c57134e3ab21abd6742235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Fri, 21 Oct 2016 13:09:04 +0200 Subject: [PATCH] Recreate the USB address cache at reconnect 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 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;