[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 5/5] Migration support for ephemeral hostdevs.



---
 src/qemu/qemu_migration.c |   98 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 99fc8ce..f3414b0 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -31,6 +31,7 @@
 #include "qemu_monitor.h"
 #include "qemu_domain.h"
 #include "qemu_process.h"
+#include "qemu_hotplug.h"
 #include "qemu_capabilities.h"
 #include "qemu_cgroup.h"
 
@@ -49,6 +50,7 @@
 #include "storage_file.h"
 #include "viruri.h"
 #include "hooks.h"
+#include "network/bridge_driver.h"
 
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
@@ -122,6 +124,79 @@ struct _qemuMigrationCookie {
     virDomainDefPtr persistent;
 };
 
+static void
+qemuMigrationRemoveEphemeralDevices(struct qemud_driver *driver,
+                                    virDomainObjPtr vm)
+{
+    virDomainHostdevDefPtr dev;
+    virDomainDeviceDef def;
+    unsigned int i;
+
+    for (i = 0; i < vm->def->nhostdevs; i++) {
+        dev = vm->def->hostdevs[i];
+        if (dev->ephemeral == 1) {
+            def.type = VIR_DOMAIN_DEVICE_HOSTDEV;
+            def.data.hostdev = dev;
+
+            if (qemuDomainDetachHostDevice(driver, vm, &def) >= 0) {
+                continue; /* nhostdevs reduced */
+            }
+        }
+    }
+}
+
+static void
+qemuMigrationRestoreEphemeralDevices(struct qemud_driver *driver,
+                                     virDomainObjPtr vm)
+{
+    virDomainNetDefPtr net;
+    unsigned int i;
+
+    /* Do nothing if ephemeral devices are present in which case this
+       function was called before qemuMigrationRemoveEphemeralDevices */
+
+    for (i = 0; i < vm->def->nhostdevs; i++) {
+        if (vm->def->hostdevs[i]->ephemeral == 1)
+            return;
+    }
+
+    for (i = 0; i < vm->def->nnets; i++) {
+        net = vm->def->nets[i];
+
+        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+            if (qemuDomainAttachHostDevice(driver, vm,
+                                           virDomainNetGetActualHostdev(net)) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("Hostdev cannot be restored"));
+                networkReleaseActualDevice(net);
+            }
+        }
+        return;
+    }
+}
+
+static void
+qemuMigrationAttachEphemeralDevices(struct qemud_driver *driver,
+                                    virDomainObjPtr vm)
+{
+    virDomainNetDefPtr net;
+    unsigned int i;
+
+    for (i = 0; i < vm->def->nnets; i++) {
+        net = vm->def->nets[i];
+
+        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+            if (qemuDomainAttachHostDevice(driver, vm,
+                                           virDomainNetGetActualHostdev(net)) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("Hostdev cannot be attached after migration"));
+                networkReleaseActualDevice(net);
+            }
+        }
+    }
+    return;
+}
+
 static void qemuMigrationCookieGraphicsFree(qemuMigrationCookieGraphicsPtr grap)
 {
     if (!grap)
@@ -800,6 +875,7 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
                        virDomainDefPtr def)
 {
     int nsnapshots;
+    unsigned int i;
 
     if (vm) {
         if (qemuProcessAutoDestroyActive(driver, vm)) {
@@ -817,10 +893,12 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
 
         def = vm->def;
     }
-    if (def->nhostdevs > 0) {
-        virReportError(VIR_ERR_OPERATION_INVALID,
-                       "%s", _("Domain with assigned host devices cannot be migrated"));
-        return false;
+    for (i = 0; i < def->nhostdevs; i++) {
+        if (def->hostdevs[i]->ephemeral == 0) {
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                           "%s", _("Domain with assigned non-ephemeral host devices cannot be migrated"));
+            return false;
+        }
     }
 
     return true;
@@ -2042,6 +2120,7 @@ static int doNativeMigrate(struct qemud_driver *driver,
               "cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu",
               driver, vm, uri, NULLSTR(cookiein), cookieinlen,
               cookieout, cookieoutlen, flags, resource);
+    qemuMigrationRemoveEphemeralDevices(driver, vm);
 
     if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) {
         char *tmp;
@@ -2069,6 +2148,9 @@ static int doNativeMigrate(struct qemud_driver *driver,
     ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout,
                            cookieoutlen, flags, resource, &spec, dconn);
 
+    if (ret != 0)
+        qemuMigrationRestoreEphemeralDevices(driver, vm);
+
     if (spec.destType == MIGRATION_DEST_FD)
         VIR_FORCE_CLOSE(spec.dest.fd.qemu);
 
@@ -2107,6 +2189,8 @@ static int doTunnelMigrate(struct qemud_driver *driver,
         return -1;
     }
 
+    qemuMigrationRemoveEphemeralDevices(driver, vm);
+
     spec.fwdType = MIGRATION_FWD_STREAM;
     spec.fwd.stream = st;
 
@@ -2153,6 +2237,8 @@ static int doTunnelMigrate(struct qemud_driver *driver,
                            cookieoutlen, flags, resource, &spec, dconn);
 
 cleanup:
+    if (ret != 0)
+        qemuMigrationRestoreEphemeralDevices(driver, vm);
     if (spec.destType == MIGRATION_DEST_FD) {
         VIR_FORCE_CLOSE(spec.dest.fd.qemu);
         VIR_FORCE_CLOSE(spec.dest.fd.local);
@@ -3057,6 +3143,8 @@ qemuMigrationFinish(struct qemud_driver *driver,
             goto endjob;
         }
 
+        qemuMigrationAttachEphemeralDevices(driver, vm);
+
         /* Guest is successfully running, so cancel previous auto destroy */
         qemuProcessAutoDestroyRemove(driver, vm);
     } else {
@@ -3154,6 +3242,8 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
             VIR_WARN("Failed to save status on vm %s", vm->def->name);
             goto cleanup;
         }
+
+        qemuMigrationRestoreEphemeralDevices(driver, vm);
     }
 
     qemuMigrationCookieFree(mig);
-- 
1.7.4.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]