[libvirt PATCH 23/80] qemu: Add support for postcopy-recover QEMU migration state

Jiri Denemark jdenemar at redhat.com
Tue May 10 15:20:44 UTC 2022


Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/qemu/qemu_migration.c    |  1 +
 src/qemu/qemu_monitor.c      |  2 +-
 src/qemu/qemu_monitor.h      |  1 +
 src/qemu/qemu_monitor_json.c |  1 +
 src/qemu/qemu_process.c      | 31 ++++++++++++++++++++++++++++++-
 5 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index e5e33556e3..5fbc930e7c 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1754,6 +1754,7 @@ qemuMigrationUpdateJobType(virDomainJobData *jobData)
 
     switch ((qemuMonitorMigrationStatus) priv->stats.mig.status) {
     case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY:
+    case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_RECOVER:
         jobData->status = VIR_DOMAIN_JOB_STATUS_POSTCOPY;
         break;
 
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 36cf4e57b5..589fef4385 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -149,7 +149,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
               "inactive", "setup",
               "active", "pre-switchover",
               "device", "postcopy-active",
-              "postcopy-paused",
+              "postcopy-paused", "postcopy-recover",
               "completed", "failed",
               "cancelling", "cancelled",
               "wait-unplug",
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 46cdc04925..5949e21a39 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -832,6 +832,7 @@ typedef enum {
     QEMU_MONITOR_MIGRATION_STATUS_DEVICE,
     QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY,
     QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_PAUSED,
+    QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_RECOVER,
     QEMU_MONITOR_MIGRATION_STATUS_COMPLETED,
     QEMU_MONITOR_MIGRATION_STATUS_ERROR,
     QEMU_MONITOR_MIGRATION_STATUS_CANCELLING,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index ac3ec42fdd..3a497dceae 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3243,6 +3243,7 @@ qemuMonitorJSONGetMigrationStatsReply(virJSONValue *reply,
     case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
     case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY:
     case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_PAUSED:
+    case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_RECOVER:
     case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
     case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
     case QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fc61aa71a0..c3a966983f 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1549,6 +1549,7 @@ qemuProcessHandleMigrationStatus(qemuMonitor *mon G_GNUC_UNUSED,
     qemuDomainJobDataPrivate *privJob = NULL;
     virQEMUDriver *driver = opaque;
     virObjectEvent *event = NULL;
+    virDomainState state;
     int reason;
 
     virObjectLock(vm);
@@ -1568,8 +1569,10 @@ qemuProcessHandleMigrationStatus(qemuMonitor *mon G_GNUC_UNUSED,
     privJob->stats.mig.status = status;
     virDomainObjBroadcast(vm);
 
+    state = virDomainObjGetState(vm, &reason);
+
     if (priv->job.asyncJob == VIR_ASYNC_JOB_MIGRATION_OUT &&
-        virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED) {
+        state == VIR_DOMAIN_PAUSED) {
         if (status == QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_PAUSED) {
             /* At this point no thread is watching the migration progress on
              * the source as it is just waiting for the Finish phase to end.
@@ -1590,6 +1593,32 @@ qemuProcessHandleMigrationStatus(qemuMonitor *mon G_GNUC_UNUSED,
         }
     }
 
+    if ((status == QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY ||
+         status == QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_RECOVER) &&
+        virDomainObjIsFailedPostcopy(vm)) {
+        int eventType = -1;
+        int eventDetail = -1;
+
+        if (state == VIR_DOMAIN_PAUSED) {
+            reason = VIR_DOMAIN_PAUSED_POSTCOPY;
+            eventType = VIR_DOMAIN_EVENT_SUSPENDED;
+            eventDetail = qemuDomainPausedReasonToSuspendedEvent(reason);
+        } else {
+            reason = VIR_DOMAIN_RUNNING_POSTCOPY;
+            eventType = VIR_DOMAIN_EVENT_RESUMED;
+            eventDetail = qemuDomainRunningReasonToResumeEvent(reason);
+        }
+
+        VIR_DEBUG("Post-copy migration recovered; correcting state for domain "
+                  "%s to %s/%s",
+                  vm->def->name,
+                  virDomainStateTypeToString(state),
+                  NULLSTR(virDomainStateReasonToString(state, reason)));
+        virDomainObjSetState(vm, state, reason);
+        event = virDomainEventLifecycleNewFromObj(vm, eventType, eventDetail);
+        qemuDomainSaveStatus(vm);
+    }
+
  cleanup:
     virObjectUnlock(vm);
     virObjectEventStateQueue(driver->domainEventState, event);
-- 
2.35.1



More information about the libvir-list mailing list