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