render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
c1c534
From c043762bfe04d7b10030b76fae12473b031c3c0a Mon Sep 17 00:00:00 2001
c1c534
Message-Id: <c043762bfe04d7b10030b76fae12473b031c3c0a@dist-git>
c1c534
From: Peter Krempa <pkrempa@redhat.com>
c1c534
Date: Fri, 2 Feb 2018 11:05:00 +0100
c1c534
Subject: [PATCH] qemu: migration: Refresh device information after
c1c534
 transferring state
c1c534
c1c534
In my first approach in 4b480d10768c I overlooked the comment in
c1c534
qemuMigrationRunIncoming stating that during actual migration the
c1c534
qemuMigrationRunIncoming does not wait until the migration is complete
c1c534
but rather offloads that to the Finish phase of migration.
c1c534
c1c534
This means that during actual migration qemuProcessRefreshState was
c1c534
called prior to qemu actually transferring the full state and thus the
c1c534
queries did not get the correct information. The approach worked only
c1c534
for restore, where we wait for the migration to finish during qemu
c1c534
startup.
c1c534
c1c534
Fix the issue by calling qemuProcessRefreshState both from
c1c534
qemuProcessStart if there's no incomming migration and from
c1c534
qemuMigrationFinish so that the code actually works as expected.
c1c534
c1c534
(cherry picked from commit 93db7eea1b86408e02852a8c886d473f4f5007e3)
c1c534
c1c534
 https://bugzilla.redhat.com/show_bug.cgi?id=1463168
c1c534
---
c1c534
 src/qemu/qemu_migration.c |  9 +++++++++
c1c534
 src/qemu/qemu_process.c   | 17 ++++++++++-------
c1c534
 src/qemu/qemu_process.h   |  4 ++++
c1c534
 3 files changed, 23 insertions(+), 7 deletions(-)
c1c534
c1c534
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
c1c534
index a50bb7206c..0968dd62a4 100644
c1c534
--- a/src/qemu/qemu_migration.c
c1c534
+++ b/src/qemu/qemu_migration.c
c1c534
@@ -5351,6 +5351,15 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
c1c534
             goto endjob;
c1c534
     }
c1c534
 
c1c534
+    /* Now that the state data was transferred we can refresh the actual state
c1c534
+     * of the devices */
c1c534
+    if (qemuProcessRefreshState(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) {
c1c534
+        /* Similarly to the case above v2 protocol will not be able to recover
c1c534
+         * from this. Let's ignore this and perhaps stuff will not break. */
c1c534
+        if (v3proto)
c1c534
+            goto endjob;
c1c534
+    }
c1c534
+
c1c534
     if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
c1c534
         inPostCopy = true;
c1c534
 
c1c534
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
c1c534
index 3bb4b14948..caf967dac5 100644
c1c534
--- a/src/qemu/qemu_process.c
c1c534
+++ b/src/qemu/qemu_process.c
c1c534
@@ -6080,7 +6080,7 @@ qemuProcessLaunch(virConnectPtr conn,
c1c534
  * function is called after a deferred migration finishes so that we can update
c1c534
  * state influenced by the migration stream.
c1c534
  */
c1c534
-static int
c1c534
+int
c1c534
 qemuProcessRefreshState(virQEMUDriverPtr driver,
c1c534
                         virDomainObjPtr vm,
c1c534
                         qemuDomainAsyncJob asyncJob)
c1c534
@@ -6121,9 +6121,6 @@ qemuProcessFinishStartup(virConnectPtr conn,
c1c534
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
c1c534
     int ret = -1;
c1c534
 
c1c534
-    if (qemuProcessRefreshState(driver, vm, asyncJob) < 0)
c1c534
-        goto cleanup;
c1c534
-
c1c534
     if (startCPUs) {
c1c534
         VIR_DEBUG("Starting domain CPUs");
c1c534
         if (qemuProcessStartCPUs(driver, vm, conn,
c1c534
@@ -6227,11 +6224,17 @@ qemuProcessStart(virConnectPtr conn,
c1c534
                                  VIR_DOMAIN_PAUSED_USER) < 0)
c1c534
         goto stop;
c1c534
 
c1c534
-    /* Keep watching qemu log for errors during incoming migration, otherwise
c1c534
-     * unset reporting errors from qemu log. */
c1c534
-    if (!incoming)
c1c534
+    if (!incoming) {
c1c534
+        /* Keep watching qemu log for errors during incoming migration, otherwise
c1c534
+         * unset reporting errors from qemu log. */
c1c534
         qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL);
c1c534
 
c1c534
+        /* Refresh state of devices from qemu. During migration this needs to
c1c534
+         * happen after the state information is fully transferred. */
c1c534
+        if (qemuProcessRefreshState(driver, vm, asyncJob) < 0)
c1c534
+            goto stop;
c1c534
+    }
c1c534
+
c1c534
     ret = 0;
c1c534
 
c1c534
  cleanup:
c1c534
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
c1c534
index cd9a720313..b383ff309b 100644
c1c534
--- a/src/qemu/qemu_process.h
c1c534
+++ b/src/qemu/qemu_process.h
c1c534
@@ -129,6 +129,10 @@ int qemuProcessFinishStartup(virConnectPtr conn,
c1c534
                              bool startCPUs,
c1c534
                              virDomainPausedReason pausedReason);
c1c534
 
c1c534
+int qemuProcessRefreshState(virQEMUDriverPtr driver,
c1c534
+                            virDomainObjPtr vm,
c1c534
+                            qemuDomainAsyncJob asyncJob);
c1c534
+
c1c534
 typedef enum {
c1c534
     VIR_QEMU_PROCESS_STOP_MIGRATED      = 1 << 0,
c1c534
     VIR_QEMU_PROCESS_STOP_NO_RELABEL    = 1 << 1,
c1c534
-- 
c1c534
2.16.1
c1c534