@@ -12353,6 +12353,58 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
cookieout, cookieoutlen, flags);
}
+static int
+qemuDomainRemovePciPassThruDevices(virConnectPtr conn,
+ virDomainObjPtr vm)
+{
+ virQEMUDriverPtr driver = conn->privateData;
+ virDomainDeviceDef dev;
+ virDomainDeviceDefPtr dev_copy = NULL;
+ virCapsPtr caps = NULL;
+ int ret = -1;
+ size_t i;
+
+ if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT))
+ goto cleanup;
+
+ /* unplug passthrough bond device */
+ for (i = 0; i < vm->def->nhostdevs; i++) {
+ virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+
+ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+ hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
+ hostdev->source.subsys.u.pci.device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND) {
+
+ dev.type = VIR_DOMAIN_DEVICE_HOSTDEV;
+ dev.data.hostdev = hostdev;
+
+ dev_copy = virDomainDeviceDefCopy(&dev, vm->def, caps, driver->xmlopt);
+ if (!dev_copy)
+ goto cleanup;
+
+ if (qemuDomainDetachHostDevice(driver, vm, dev_copy) < 0) {
+ virDomainDeviceDefFree(dev_copy);
+ goto cleanup;
+ }
+
+ virDomainDeviceDefFree(dev_copy);
+ if (qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+
+ cleanup:
+ virObjectUnref(caps);
+
+ return ret;
+}
+
static char *
qemuDomainMigrateBegin3Params(virDomainPtr domain,
virTypedParameterPtr params,
@@ -12688,6 +12740,11 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
return -1;
}
+ if (qemuDomainRemovePciPassThruDevices(dom->conn, vm) < 0) {
+ qemuDomObjEndAPI(&vm);
+ return -1;
+ }
+
return qemuMigrationPerform(driver, dom->conn, vm, dom_xml,
dconnuri, uri, graphicsuri, listenAddress,
cookiein, cookieinlen, cookieout, cookieoutlen,
@@ -2000,6 +2000,13 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm,
forbid = false;
for (i = 0; i < def->nhostdevs; i++) {
virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+
+ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+ hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
+ hostdev->source.subsys.u.pci.device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND)
+ continue;
+
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
forbid = true;
For bond device, we can support the migrate, we can simple to hot remove the device from source side, and after migration end, we hot add the new device at destination side. Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com> --- src/qemu/qemu_driver.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_migration.c | 7 ++++++ 2 files changed, 64 insertions(+)