diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8fa3ec3b69..428050f1e2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -942,16 +942,23 @@ cleanup: int -qemuDomainAssignPCIAddresses(virDomainDefPtr def) +qemuDomainAssignPCIAddresses(virDomainDefPtr def, + virBitmapPtr qemuCaps, + virDomainObjPtr obj) { int ret = -1; - virBitmapPtr qemuCaps = NULL; + virBitmapPtr localCaps = NULL; qemuDomainPCIAddressSetPtr addrs = NULL; + qemuDomainObjPrivatePtr priv = NULL; - if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, - NULL, - &qemuCaps) < 0) - goto cleanup; + if (!qemuCaps) { + /* need to get information from real environment */ + if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, + NULL, + &localCaps) < 0) + goto cleanup; + qemuCaps = localCaps; + } if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { if (!(addrs = qemuDomainPCIAddressSetCreate(def))) @@ -961,16 +968,31 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def) goto cleanup; } + if (obj && obj->privateData) { + priv = obj->privateData; + if (addrs) { + /* if this is the live domain object, we persist the PCI addresses*/ + qemuDomainPCIAddressSetFree(priv->pciaddrs); + priv->persistentAddrs = 1; + priv->pciaddrs = addrs; + addrs = NULL; + } else { + priv->persistentAddrs = 0; + } + } + ret = 0; cleanup: - qemuCapsFree(qemuCaps); + qemuCapsFree(localCaps); qemuDomainPCIAddressSetFree(addrs); return ret; } -int qemuDomainAssignAddresses(virDomainDefPtr def) +int qemuDomainAssignAddresses(virDomainDefPtr def, + virBitmapPtr qemuCaps, + virDomainObjPtr obj) { int rc; @@ -978,7 +1000,7 @@ int qemuDomainAssignAddresses(virDomainDefPtr def) if (rc) return rc; - return qemuDomainAssignPCIAddresses(def); + return qemuDomainAssignPCIAddresses(def, qemuCaps, obj); } static void diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 1eafeb3ced..ddf426f653 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -175,10 +175,14 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, virDomainChrSourceDefPtr *monConfig, bool *monJSON); -int qemuDomainAssignAddresses(virDomainDefPtr def); +int qemuDomainAssignAddresses(virDomainDefPtr def, + virBitmapPtr qemuCaps, + virDomainObjPtr); int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def); -int qemuDomainAssignPCIAddresses(virDomainDefPtr def); +int qemuDomainAssignPCIAddresses(virDomainDefPtr def, + virBitmapPtr qemuCaps, + virDomainObjPtr obj); qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def); int qemuDomainPCIAddressReserveFunction(qemuDomainPCIAddressSetPtr addrs, int slot, int function); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 377be9f935..dc04d133c7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1404,7 +1404,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup; - if (qemuDomainAssignAddresses(def) < 0) + if (qemuDomainAssignAddresses(def, NULL, NULL) < 0) goto cleanup; if (!(vm = virDomainAssignDef(driver->caps, @@ -5071,7 +5071,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup; - if (qemuDomainAssignAddresses(def) < 0) + if (qemuDomainAssignAddresses(def, NULL, NULL) < 0) goto cleanup; if (!(vm = virDomainAssignDef(driver->caps, @@ -5549,7 +5549,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) if (virDomainDefAddImplicitControllers(vmdef) < 0) return -1; - if (qemuDomainAssignAddresses(vmdef) < 0) + if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) return -1; break; @@ -5567,7 +5567,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, return -1; } dev->data.net = NULL; - if (qemuDomainAssignAddresses(vmdef) < 0) + if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) return -1; break; @@ -5583,7 +5583,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, return -1; } dev->data.hostdev = NULL; - if (qemuDomainAssignAddresses(vmdef) < 0) + if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) return -1; break; @@ -5737,7 +5737,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef, vmdef->nets[pos] = net; dev->data.net = NULL; - if (qemuDomainAssignAddresses(vmdef) < 0) + if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) return -1; break; @@ -11734,7 +11734,7 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup; - if (qemuDomainAssignAddresses(def) < 0) + if (qemuDomainAssignAddresses(def, NULL, NULL) < 0) goto cleanup; if (!(vm = virDomainAssignDef(driver->caps, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index c5140c3c92..bf324870f1 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3090,13 +3090,8 @@ qemuProcessReconnect(void *opaque) goto endjob; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - priv->persistentAddrs = 1; - - if (!(priv->pciaddrs = qemuDomainPCIAddressSetCreate(obj->def)) || - qemuAssignDevicePCISlots(obj->def, priv->pciaddrs) < 0) - goto error; - } + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) + qemuDomainAssignAddresses(obj->def, priv->qemuCaps, obj); if (virSecurityManagerReserveLabel(driver->securityManager, obj->def, obj->pid) < 0) goto error; @@ -3560,22 +3555,7 @@ int qemuProcessStart(virConnectPtr conn, */ if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { VIR_DEBUG("Assigning domain PCI addresses"); - /* Populate cache with current addresses */ - if (priv->pciaddrs) { - qemuDomainPCIAddressSetFree(priv->pciaddrs); - priv->pciaddrs = NULL; - } - if (!(priv->pciaddrs = qemuDomainPCIAddressSetCreate(vm->def))) - goto cleanup; - - - /* Assign any remaining addresses */ - if (qemuAssignDevicePCISlots(vm->def, priv->pciaddrs) < 0) - goto cleanup; - - priv->persistentAddrs = 1; - } else { - priv->persistentAddrs = 0; + qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm); } VIR_DEBUG("Building emulator command line"); @@ -4257,21 +4237,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, */ if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { VIR_DEBUG("Assigning domain PCI addresses"); - /* Populate cache with current addresses */ - if (priv->pciaddrs) { - qemuDomainPCIAddressSetFree(priv->pciaddrs); - priv->pciaddrs = NULL; - } - if (!(priv->pciaddrs = qemuDomainPCIAddressSetCreate(vm->def))) - goto cleanup; - - /* Assign any remaining addresses */ - if (qemuAssignDevicePCISlots(vm->def, priv->pciaddrs) < 0) - goto cleanup; - - priv->persistentAddrs = 1; - } else { - priv->persistentAddrs = 0; + qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm); } if ((timestamp = virTimeStringNow()) == NULL) {