Signed-off-by: Cristian Klein <cristiklein(a)gmail.com>
---
src/qemu/qemu_migration.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_migration.h | 3 +-
2 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index a1b1458..ede938b 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1803,6 +1803,67 @@ qemuMigrationSetOffline(virQEMUDriverPtr driver,
static int
+qemuMigrationTestPostCopy(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ 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);
+
+ qemuDomainObjExitMonitor(driver, vm);
+ return ret;
+}
+
+
+static int
+qemuMigrationSetPostCopy(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob job)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ int ret;
+
+ if (job != QEMU_ASYNC_JOB_MIGRATION_OUT) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Set post-copy only makes sense for outgoing migration"));
+ }
+
+ 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) {
+ 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,
+ true);
+
+ cleanup:
+ qemuDomainObjExitMonitor(driver, vm);
+ return ret;
+}
+
+
+static int
qemuMigrationSetCompression(virQEMUDriverPtr driver,
virDomainObjPtr vm,
bool state,
@@ -2752,6 +2813,15 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
dataFD[1] = -1; /* 'st' owns the FD now & will close it */
}
+ if (flags & VIR_MIGRATE_ENABLE_POSTCOPY &&
+ qemuMigrationTestPostCopy(driver, vm,
+ QEMU_ASYNC_JOB_MIGRATION_IN) < 0) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Post-copy migration is not supported by "
+ "target QEMU binary"));
+ goto stop;
+ }
+
if (qemuMigrationSetCompression(driver, vm,
flags & VIR_MIGRATE_COMPRESSED,
QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
@@ -3602,6 +3672,18 @@ qemuMigrationRun(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
+ if (flags & VIR_MIGRATE_ENABLE_POSTCOPY) {
+ if (!(flags & VIR_MIGRATE_LIVE)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Enabling post-copy only makes sense with "
+ "live migration"));
+ goto cleanup;
+ }
+ if (qemuMigrationSetPostCopy(driver, vm,
+ 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 e7a90c3..5d60238 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_ENABLE_POSTCOPY)
/* All supported migration parameters and their types. */
# define QEMU_MIGRATION_PARAMETERS \
--
1.9.1