qemu: Handle 'postcopy-paused' migration state

When connection breaks during post-copy migration, QEMU enters
'postcopy-paused' state. We need to handle this state and make the
situation visible to upper layers.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Jiri Denemark 2022-05-10 15:20:25 +02:00
parent 458fa0e2bf
commit 5dd2d11ec0
8 changed files with 28 additions and 0 deletions

View File

@ -93,6 +93,7 @@ virDomainJobStatusToType(virDomainJobStatus status)
case VIR_DOMAIN_JOB_STATUS_MIGRATING: case VIR_DOMAIN_JOB_STATUS_MIGRATING:
case VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED: case VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED:
case VIR_DOMAIN_JOB_STATUS_POSTCOPY: case VIR_DOMAIN_JOB_STATUS_POSTCOPY:
case VIR_DOMAIN_JOB_STATUS_POSTCOPY_PAUSED:
case VIR_DOMAIN_JOB_STATUS_PAUSED: case VIR_DOMAIN_JOB_STATUS_PAUSED:
return VIR_DOMAIN_JOB_UNBOUNDED; return VIR_DOMAIN_JOB_UNBOUNDED;

View File

@ -78,6 +78,7 @@ typedef enum {
VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED, VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED,
VIR_DOMAIN_JOB_STATUS_PAUSED, VIR_DOMAIN_JOB_STATUS_PAUSED,
VIR_DOMAIN_JOB_STATUS_POSTCOPY, VIR_DOMAIN_JOB_STATUS_POSTCOPY,
VIR_DOMAIN_JOB_STATUS_POSTCOPY_PAUSED,
VIR_DOMAIN_JOB_STATUS_COMPLETED, VIR_DOMAIN_JOB_STATUS_COMPLETED,
VIR_DOMAIN_JOB_STATUS_FAILED, VIR_DOMAIN_JOB_STATUS_FAILED,
VIR_DOMAIN_JOB_STATUS_CANCELED, VIR_DOMAIN_JOB_STATUS_CANCELED,

View File

@ -12545,6 +12545,7 @@ qemuDomainGetJobInfoMigrationStats(virQEMUDriver *driver,
case VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED: case VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED:
case VIR_DOMAIN_JOB_STATUS_POSTCOPY: case VIR_DOMAIN_JOB_STATUS_POSTCOPY:
case VIR_DOMAIN_JOB_STATUS_PAUSED: case VIR_DOMAIN_JOB_STATUS_PAUSED:
case VIR_DOMAIN_JOB_STATUS_POSTCOPY_PAUSED:
if (qemuMigrationAnyFetchStats(driver, vm, VIR_ASYNC_JOB_NONE, if (qemuMigrationAnyFetchStats(driver, vm, VIR_ASYNC_JOB_NONE,
jobData, NULL) < 0) jobData, NULL) < 0)
return -1; return -1;

View File

@ -1747,6 +1747,10 @@ qemuMigrationUpdateJobType(virDomainJobData *jobData)
jobData->status = VIR_DOMAIN_JOB_STATUS_POSTCOPY; jobData->status = VIR_DOMAIN_JOB_STATUS_POSTCOPY;
break; break;
case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_PAUSED:
jobData->status = VIR_DOMAIN_JOB_STATUS_POSTCOPY_PAUSED;
break;
case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED: case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
jobData->status = VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED; jobData->status = VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED;
break; break;
@ -1871,6 +1875,12 @@ qemuMigrationJobCheckStatus(virQEMUDriver *driver,
qemuMigrationJobName(vm), _("canceled by client")); qemuMigrationJobName(vm), _("canceled by client"));
return -1; return -1;
case VIR_DOMAIN_JOB_STATUS_POSTCOPY_PAUSED:
virReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"),
qemuMigrationJobName(vm),
_("post-copy phase failed"));
return -1;
case VIR_DOMAIN_JOB_STATUS_COMPLETED: case VIR_DOMAIN_JOB_STATUS_COMPLETED:
case VIR_DOMAIN_JOB_STATUS_ACTIVE: case VIR_DOMAIN_JOB_STATUS_ACTIVE:
case VIR_DOMAIN_JOB_STATUS_MIGRATING: case VIR_DOMAIN_JOB_STATUS_MIGRATING:
@ -1973,6 +1983,7 @@ qemuMigrationAnyCompleted(virQEMUDriver *driver,
case VIR_DOMAIN_JOB_STATUS_FAILED: case VIR_DOMAIN_JOB_STATUS_FAILED:
case VIR_DOMAIN_JOB_STATUS_CANCELED: case VIR_DOMAIN_JOB_STATUS_CANCELED:
case VIR_DOMAIN_JOB_STATUS_POSTCOPY_PAUSED:
/* QEMU aborted the migration. */ /* QEMU aborted the migration. */
return -1; return -1;

View File

@ -149,6 +149,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
"inactive", "setup", "inactive", "setup",
"active", "pre-switchover", "active", "pre-switchover",
"device", "postcopy-active", "device", "postcopy-active",
"postcopy-paused",
"completed", "failed", "completed", "failed",
"cancelling", "cancelled", "cancelling", "cancelled",
"wait-unplug", "wait-unplug",

View File

@ -795,6 +795,7 @@ typedef enum {
QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER, QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER,
QEMU_MONITOR_MIGRATION_STATUS_DEVICE, QEMU_MONITOR_MIGRATION_STATUS_DEVICE,
QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY, QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY,
QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_PAUSED,
QEMU_MONITOR_MIGRATION_STATUS_COMPLETED, QEMU_MONITOR_MIGRATION_STATUS_COMPLETED,
QEMU_MONITOR_MIGRATION_STATUS_ERROR, QEMU_MONITOR_MIGRATION_STATUS_ERROR,
QEMU_MONITOR_MIGRATION_STATUS_CANCELLING, QEMU_MONITOR_MIGRATION_STATUS_CANCELLING,

View File

@ -3242,6 +3242,7 @@ qemuMonitorJSONGetMigrationStatsReply(virJSONValue *reply,
case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE: case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY: case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY:
case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_PAUSED:
case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED: case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING: case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
case QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER: case QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER:

View File

@ -1513,6 +1513,17 @@ qemuProcessHandleMigrationStatus(qemuMonitor *mon G_GNUC_UNUSED,
} }
break; break;
case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_PAUSED:
if (priv->job.asyncJob == VIR_ASYNC_JOB_MIGRATION_OUT &&
state == VIR_DOMAIN_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.
* Thus we need to handle the event here. */
qemuMigrationSrcPostcopyFailed(vm);
qemuDomainSaveStatus(vm);
}
break;
case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE: case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
case QEMU_MONITOR_MIGRATION_STATUS_SETUP: case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE: case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE: