diff mbox

[RFC,6/7] migrate: hot remove hostdev at perform phase for bond device

Message ID 0c4e3889ab78d025c3c92ba872a63d7e1131a2c0.1429256889.git.chen.fan.fnst@cn.fujitsu.com
State New
Headers show

Commit Message

chenfan April 17, 2015, 8:53 a.m. UTC
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(+)
diff mbox

Patch

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7368145..0ba9e4a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -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,
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 611f53a..9ea83df 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -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;