When a guest with ephemeral device is migrated the PCI- passthrough of the ephemeral device should take place after migration and hence we check for the vmop in qemuBuildCommandLine. We also dicard the PCI slot assigned by qemuCollectPCIAddress as a PCI address will be assigned later during the hotplug. --- src/qemu/qemu_command.c | 62 ++++++++++++++++++++++++++++++---------------- 1 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1b20d23..6e1851c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4954,6 +4954,9 @@ qemuBuildCommandLine(virConnectPtr conn, VIR_DOMAIN_CONTROLLER_TYPE_CCID, }; + virDomainObjPtr vm = NULL; + virDomainObjListPtr doms = &driver->domains; + VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d " "caps=%p migrateFrom=%s migrateFD=%d " "snapshot=%p vmop=%d", @@ -4962,6 +4965,8 @@ qemuBuildCommandLine(virConnectPtr conn, virUUIDFormat(def->uuid, uuid); + vm = virHashLookup(doms->objs, uuid); + emulator = def->emulator; /* @@ -5931,36 +5936,49 @@ qemuBuildCommandLine(virConnectPtr conn, if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net); virDomainHostdevDefPtr found; + qemuDomainObjPrivatePtr priv = vm->privateData; /* For a network with <forward mode='hostdev'>, there is a need to * add the newly minted hostdev to the hostdevs array. */ - if (qemuAssignDeviceHostdevAlias(def, hostdev, - (def->nhostdevs-1)) < 0) { - goto error; - } - - if (virDomainHostdevFind(def, hostdev, &found) < 0) { - if (virDomainHostdevInsert(def, hostdev) < 0) { - virReportOOMError(); + if (vmop == VIR_NETDEV_VPORT_PROFILE_OP_CREATE) { + if (qemuAssignDeviceHostdevAlias(def, hostdev, + (def->nhostdevs-1)) < 0) { goto error; } - if (qemuPrepareHostdevPCIDevices(driver, def->name, def->uuid, - &hostdev, 1) < 0) { + + if (virDomainHostdevFind(def, hostdev, &found) < 0) { + if (virDomainHostdevInsert(def, hostdev) < 0) { + virReportOOMError(); + goto error; + } + if (qemuPrepareHostdevPCIDevices(driver, def->name, def->uuid, + &hostdev, 1) < 0) { + goto error; + } + } + else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("PCI device %04x:%02x:%02x.%x " + "allocated from network %s is already " + "in use by domain %s"), + hostdev->source.subsys.u.pci.domain, + hostdev->source.subsys.u.pci.bus, + hostdev->source.subsys.u.pci.slot, + hostdev->source.subsys.u.pci.function, + net->data.network.name, + def->name); goto error; } } - else { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("PCI device %04x:%02x:%02x.%x " - "allocated from network %s is already " - "in use by domain %s"), - hostdev->source.subsys.u.pci.domain, - hostdev->source.subsys.u.pci.bus, - hostdev->source.subsys.u.pci.slot, - hostdev->source.subsys.u.pci.function, - net->data.network.name, - def->name); - goto error; + else if (vmop == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) { + /* During migration the hostdev device is hotplugged at + * a later stage hence remove the PCI address collected by + * qemuCollectPCIAddress */ + if (qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, + hostdev->info->addr.pci.slot) < 0) + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not release PCI slot during migration " + "for hotplug at a later stage")); } } continue; -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list