Perform phase stops once migration switched to post-copy.
Confirm phase waits for post-copy to finish before killing the VM.
Signed-off-by: Cristian Klein <cristian.klein(a)cs.umu.se>
---
src/qemu/qemu_driver.c | 8 ++++++++
src/qemu/qemu_migration.c | 25 ++++++++++++++++++++++---
2 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e873d45..3fe2216 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10942,6 +10942,14 @@ qemuDomainMigratePrepare2(virConnectPtr dconn,
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+ if (flags & VIR_MIGRATE_POSTCOPY) {
+ /* post-copy migration does not work with Sequence v2 */
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Post-copy migration requested but not "
+ "supported by v2 protocol"));
+ goto cleanup;
+ }
+
if (flags & VIR_MIGRATE_TUNNELLED) {
/* this is a logical error; we never should have gotten here with
* VIR_MIGRATE_TUNNELLED set
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 4a36946..436b701 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2039,6 +2039,11 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
ret = 0;
break;
+ case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_ACTIVE:
+ jobInfo->type = VIR_DOMAIN_JOB_PHASE1_COMPLETED;
+ ret = 0;
+ break;
+
case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
jobInfo->type = VIR_DOMAIN_JOB_NONE;
virReportError(VIR_ERR_OPERATION_FAILED,
@@ -2077,6 +2082,7 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
qemuDomainJobInfoPtr jobInfo = priv->job.current;
const char *job;
int pauseReason;
+ bool inPhase2 = (jobInfo->type == VIR_DOMAIN_JOB_PHASE1_COMPLETED);
switch (priv->job.asyncJob) {
case QEMU_ASYNC_JOB_MIGRATION_OUT:
@@ -2092,9 +2098,11 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
job = _("job");
}
- jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
+ if (!inPhase2)
+ jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
- while (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED) {
+ while (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED ||
+ (inPhase2 && jobInfo->type == VIR_DOMAIN_JOB_PHASE1_COMPLETED)) {
/* Poll every 50ms for progress & to allow cancellation */
struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
@@ -2123,7 +2131,8 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
virObjectLock(vm);
}
- if (jobInfo->type == VIR_DOMAIN_JOB_COMPLETED) {
+ if (jobInfo->type == VIR_DOMAIN_JOB_COMPLETED ||
+ jobInfo->type == VIR_DOMAIN_JOB_PHASE1_COMPLETED) {
qemuDomainJobInfoUpdateDowntime(jobInfo);
VIR_FREE(priv->job.completed);
if (VIR_ALLOC(priv->job.completed) == 0)
@@ -3149,6 +3158,16 @@ qemuMigrationConfirmPhase(virQEMUDriverPtr driver,
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+ /* Wait for post-copy to complete */
+ if (flags & VIR_MIGRATE_POSTCOPY) {
+ bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
+ rv = qemuMigrationWaitForCompletion(driver, vm,
+ QEMU_ASYNC_JOB_MIGRATION_OUT,
+ conn, abort_on_error);
+ if (rv < 0)
+ goto cleanup;
+ }
+
qemuMigrationJobSetPhase(driver, vm,
retcode == 0
? QEMU_MIGRATION_PHASE_CONFIRM3
--
1.9.1