Signed-off-by: Cristian Klein <cristiklein@xxxxxxxxx> --- src/qemu/qemu_driver.c | 2 ++ src/qemu/qemu_migration.c | 49 +++++++++++++++++++++++++++++++++++++++++++---- src/qemu/qemu_migration.h | 3 ++- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index fc7de23..53347ea 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11348,6 +11348,8 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, virCheckFlags(QEMU_MIGRATION_FLAGS, -1); + if (flags & VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY) + flags |= VIR_MIGRATE_ENABLE_POSTCOPY; if (flags & VIR_MIGRATE_ENABLE_POSTCOPY) { /* post-copy migration does not work with Sequence v2 */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 137ddfa..e5412c5 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2112,7 +2112,8 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver, qemuDomainAsyncJob asyncJob, virConnectPtr dconn, bool abort_on_error, - bool exit_on_postcopy_active) + bool exit_on_postcopy_active, + bool trigger_postcopy) { qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainJobInfoPtr jobInfo = priv->job.current; @@ -2144,6 +2145,34 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver, if (qemuMigrationUpdateJobStatus(driver, vm, job, asyncJob) == -1) break; + /* automatically switch to post-copy if the user requested so */ + if (trigger_postcopy && + jobInfo->status.status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE && + jobInfo->status.ram_dirty_sync_count > 0) { + int rv; + + /* Clear variable to prevent sending this command to qemu twice */ + trigger_postcopy = false; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) { + /* Migration might have finished before we got to + * trigger post-copy */ + break; + } + rv = qemuMonitorMigrateStartPostCopy(priv->mon); + qemuDomainObjExitMonitor(driver, vm); + + if (rv < 0) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("%s: %s"), job, + _("Switching to post-copy failed")); + if (abort_on_error) + break; + } else { + VIR_DEBUG("Switched to post-copy"); + } + } + /* cancel migration if disk I/O error is emitted while migrating */ if (abort_on_error && virDomainObjGetState(vm, &pauseReason) == VIR_DOMAIN_PAUSED && @@ -2822,6 +2851,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, dataFD[1] = -1; /* 'st' owns the FD now & will close it */ } + if (flags & VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY) + flags |= VIR_MIGRATE_ENABLE_POSTCOPY; if (flags & VIR_MIGRATE_ENABLE_POSTCOPY && qemuMigrationTestPostCopy(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) { @@ -3200,13 +3231,17 @@ qemuMigrationConfirmPhase(virQEMUDriverPtr driver, virCheckFlags(QEMU_MIGRATION_FLAGS, -1); /* Wait for post-copy to complete */ + if (flags & VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY) + flags |= VIR_MIGRATE_ENABLE_POSTCOPY; if (flags & VIR_MIGRATE_ENABLE_POSTCOPY) { bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR); bool exit_on_postcopy_active = false; + bool trigger_postcopy = false; rv = qemuMigrationWaitForCompletion(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, conn, abort_on_error, - exit_on_postcopy_active); + exit_on_postcopy_active, + trigger_postcopy); if (rv < 0) goto cleanup; } @@ -3693,6 +3728,8 @@ qemuMigrationRun(virQEMUDriverPtr driver, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) goto cleanup; + if (flags & VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY) + flags |= VIR_MIGRATE_ENABLE_POSTCOPY; if (flags & VIR_MIGRATE_ENABLE_POSTCOPY) { if (!(flags & VIR_MIGRATE_LIVE)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -3809,10 +3846,12 @@ qemuMigrationRun(virQEMUDriverPtr driver, { bool exit_on_postcopy_active = true; + bool trigger_postcopy = (flags & VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY); rc = qemuMigrationWaitForCompletion(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, dconn, abort_on_error, - exit_on_postcopy_active); + exit_on_postcopy_active, + trigger_postcopy); } if (rc == -2) @@ -5280,9 +5319,11 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, { bool abort_on_error = false; bool exit_on_postcopy_active = true; + bool trigger_postcopy = false; rc = qemuMigrationWaitForCompletion(driver, vm, asyncJob, NULL, abort_on_error, - exit_on_postcopy_active); + exit_on_postcopy_active, + trigger_postcopy); } if (rc < 0) { diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 5d60238..8cec9b8 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -42,7 +42,8 @@ VIR_MIGRATE_ABORT_ON_ERROR | \ VIR_MIGRATE_AUTO_CONVERGE | \ VIR_MIGRATE_RDMA_PIN_ALL | \ - VIR_MIGRATE_ENABLE_POSTCOPY) + VIR_MIGRATE_ENABLE_POSTCOPY | \ + VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY) /* All supported migration parameters and their types. */ # define QEMU_MIGRATION_PARAMETERS \ -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list