Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- 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