From: Cristian Klein <cristiklein(a)gmail.com>
Signed-off-by: Cristian Klein <cristiklein(a)gmail.com>
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_migration.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_migration.h | 3 +-
2 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 6c98c5c..64c1eb8 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2498,6 +2498,54 @@ qemuMigrationSetPinAll(virQEMUDriverPtr driver,
return ret;
}
+
+static int
+qemuMigrationSetPostCopy(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ bool state,
+ qemuDomainAsyncJob job)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ int ret;
+
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0)
+ return -1;
+
+ ret = qemuMonitorGetMigrationCapability(
+ priv->mon,
+ QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY);
+
+ if (ret < 0) {
+ goto cleanup;
+ } else if (ret == 0 && !state) {
+ /* Unsupported but we want it off anyway */
+ goto cleanup;
+ } else if (ret == 0) {
+ if (job == QEMU_ASYNC_JOB_MIGRATION_IN) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Post-copy migration is not supported by "
+ "target QEMU binary"));
+ } else {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Post-copy migration is not supported by "
+ "source QEMU binary"));
+ }
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = qemuMonitorSetMigrationCapability(
+ priv->mon,
+ QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY,
+ state);
+
+ cleanup:
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ ret = -1;
+ return ret;
+}
+
+
static int
qemuMigrationWaitForSpice(virDomainObjPtr vm)
{
@@ -3132,6 +3180,15 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver,
!qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks))
goto cleanup;
+ if (flags & VIR_MIGRATE_POSTCOPY &&
+ (!(flags & VIR_MIGRATE_LIVE) ||
+ flags & VIR_MIGRATE_PAUSED)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("post-copy migration is not supported with non-live "
+ "or paused migration"));
+ goto cleanup;
+ }
+
if (flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) {
bool has_drive_mirror = virQEMUCapsGet(priv->qemuCaps,
QEMU_CAPS_DRIVE_MIRROR);
@@ -3471,6 +3528,15 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
cookieFlags = QEMU_MIGRATION_COOKIE_GRAPHICS;
}
+ if (flags & VIR_MIGRATE_POSTCOPY &&
+ (!(flags & VIR_MIGRATE_LIVE) ||
+ flags & VIR_MIGRATE_PAUSED)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("post-copy migration is not supported with non-live "
+ "or paused migration"));
+ goto cleanup;
+ }
+
if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
goto cleanup;
@@ -3621,6 +3687,11 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
goto stopjob;
+ if (qemuMigrationSetPostCopy(driver, vm,
+ flags & VIR_MIGRATE_POSTCOPY,
+ QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
+ goto stopjob;
+
if (mig->nbd &&
flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)
&&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_SERVER)) {
@@ -4487,6 +4558,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
+ if (qemuMigrationSetPostCopy(driver, vm,
+ flags & VIR_MIGRATE_POSTCOPY,
+ QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
+ goto cleanup;
+
if (qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 2445e13..e30b2ec 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -41,7 +41,8 @@
VIR_MIGRATE_COMPRESSED | \
VIR_MIGRATE_ABORT_ON_ERROR | \
VIR_MIGRATE_AUTO_CONVERGE | \
- VIR_MIGRATE_RDMA_PIN_ALL)
+ VIR_MIGRATE_RDMA_PIN_ALL | \
+ VIR_MIGRATE_POSTCOPY)
/* All supported migration parameters and their types. */
# define QEMU_MIGRATION_PARAMETERS \
--
2.7.0