|
|
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 |
|