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

[libvirt] [PATCH 6/6] restore correctly the state of the VM upon migration



In order to correctly pass the paused/unpaused state on the remote side,
we use the newly introduced return code of qemudDomainMigratePerform.

The return code does not need to be public (it is internal to the QEMU
driver).  A return code of 0 specifies the old behavior.

* src/qemu/qemu_driver.c (qemudDomainMigratePerform): Check if
the machine will have to be resumed on the destination side,
pass a return value to indicate this.
(qemudDomainMigrateFinish2): Conditionalize resumption on
the return code from qemudDomainMigratePerform.
* src/qemu/qemu_driver.h (qemuDomainMigratePerformResult): New enum.
---
 src/qemu/qemu_driver.c |   14 ++++++++++----
 src/qemu/qemu_driver.h |    6 ++++++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d2429de..5811ba2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -37,6 +37,7 @@
 #include <errno.h>
 #include <sys/utsname.h>
 #include <sys/stat.h>
+#include <assert.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <paths.h>
@@ -5969,7 +5970,9 @@ cleanup:
     return ret;
 }
 
-/* Perform is the second step, and it runs on the source host. */
+/* Perform is the second step, and it runs on the source host.  It
+   returns a combination of actions that should (or should not) be
+   done by MigrateFinish2, currently QEMU_MIGRATE_NO_RESUME.  */
 static int
 qemudDomainMigratePerform (virDomainPtr dom,
                            const char *cookie ATTRIBUTE_UNUSED,
@@ -5983,7 +5986,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
     virDomainObjPtr vm;
     virDomainEventPtr event = NULL;
     int ret = -1;
-    int paused = 0;
+    int paused = 0, need_resume = 0;
     int status;
     xmlURIPtr uribits = NULL;
     unsigned long long transferred, remaining, total;
@@ -6004,6 +6007,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
         goto cleanup;
     }
 
+    need_resume = (vm->state == VIR_DOMAIN_RUNNING);
     if (!(flags & VIR_MIGRATE_LIVE)) {
         /* Pause domain for non-live migration */
         if (qemuMonitorStopCPUs(vm) < 0)
@@ -6072,7 +6076,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
         virDomainRemoveInactive(&driver->domains, vm);
         vm = NULL;
     }
-    ret = 0;
+    ret = need_resume ? 0 : QEMU_MIGRATE_NO_RESUME;
 
 cleanup:
     if (paused) {
@@ -6131,7 +6135,9 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
     if (retcode >= 0) {
         dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
 
-        if (!(flags & VIR_MIGRATE_PAUSED)) {
+        assert (vm->state == VIR_DOMAIN_PAUSED);
+        if (!(retcode & QEMU_MIGRATE_NO_RESUME)
+            && !(flags & VIR_MIGRATE_PAUSED)) {
             /* run 'cont' on the destination, which allows migration on qemu
              * >= 0.10.6 to work properly.  This isn't strictly necessary on
              * older qemu's, but it also doesn't hurt anything there
diff --git a/src/qemu/qemu_driver.h b/src/qemu/qemu_driver.h
index 17b184f..74ec089 100644
--- a/src/qemu/qemu_driver.h
+++ b/src/qemu/qemu_driver.h
@@ -47,6 +47,12 @@
 #  define KVM_CAP_NR_VCPUS 9       /* returns max vcpus per vm */
 #endif
 
+/* Flags passed from virDomainMigratePerform to virDomainMigrateFinish.  */
+
+typedef enum {
+  QEMU_MIGRATE_NO_RESUME   = 1  /* destination domain should stay paused */
+} qemuDomainMigratePerformResult;
+
 int qemuRegister(void);
 
 #endif /* QEMUD_DRIVER_H */
-- 
1.6.2.5


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