VIR_MIGRATE_OFFLINE = (1 << 10), /* offline migrate */
VIR_MIGRATE_COMPRESSED = (1 << 11), /* compress data during migration */
VIR_MIGRATE_ABORT_ON_ERROR = (1 << 12), /* abort migration on I/O errors happened during migration */
+ VIR_MIGRATE_AUTO_CONVERGE = (1 << 13), /* force convergence */
} virDomainMigrateFlags;
if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_PAUSED;
- destflags = flags & ~VIR_MIGRATE_ABORT_ON_ERROR;
+ destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
+ VIR_MIGRATE_AUTO_CONVERGE);
/* Prepare the migration.
*
if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_PAUSED;
- destflags = flags & ~VIR_MIGRATE_ABORT_ON_ERROR;
+ destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
+ VIR_MIGRATE_AUTO_CONVERGE);
VIR_DEBUG("Prepare2 %p flags=%lx", dconn, destflags);
ret = dconn->driver->domainMigratePrepare2
if (ret == 0 && state == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_PAUSED;
- destflags = flags & ~VIR_MIGRATE_ABORT_ON_ERROR;
+ destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
+ VIR_MIGRATE_AUTO_CONVERGE);
VIR_DEBUG("Prepare3 %p flags=%x", dconn, destflags);
cookiein = cookieout;
return ret;
}
+static int
+qemuMigrationSetAutoConverge(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ enum qemuDomainAsyncJob job)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ int ret;
+
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0)
+ return -1;
+
+ ret = qemuMonitorGetMigrationCapability(
+ priv->mon,
+ QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE);
+
+ if (ret < 0) {
+ goto cleanup;
+ } else if (ret == 0) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Auto-Converge is not supported by "
+ "QEMU binary"));
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = qemuMonitorSetMigrationCapability(
+ priv->mon,
+ QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE);
+
+cleanup:
+ qemuDomainObjExitMonitor(driver, vm);
+ return ret;
+}
+
+
static int
qemuMigrationWaitForSpice(virQEMUDriverPtr driver,
virDomainObjPtr vm)
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
+ if (flags & VIR_MIGRATE_AUTO_CONVERGE &&
+ qemuMigrationSetAutoConverge(driver, vm,
+ QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
+ goto cleanup;
+
if (qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_PAUSED;
- destflags = flags & ~VIR_MIGRATE_ABORT_ON_ERROR;
+ destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
+ VIR_MIGRATE_AUTO_CONVERGE);
VIR_DEBUG("Prepare2 %p", dconn);
if (flags & VIR_MIGRATE_TUNNELLED) {
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_PAUSED;
- destflags = flags & ~VIR_MIGRATE_ABORT_ON_ERROR;
+ destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
+ VIR_MIGRATE_AUTO_CONVERGE);
VIR_DEBUG("Prepare3 %p", dconn);
cookiein = cookieout;
VIR_MIGRATE_UNSAFE | \
VIR_MIGRATE_OFFLINE | \
VIR_MIGRATE_COMPRESSED | \
- VIR_MIGRATE_ABORT_ON_ERROR)
+ VIR_MIGRATE_ABORT_ON_ERROR | \
+ VIR_MIGRATE_AUTO_CONVERGE)
/* All supported migration parameters and their types. */
# define QEMU_MIGRATION_PARAMETERS \
VIR_ENUM_IMPL(qemuMonitorMigrationCaps,
QEMU_MONITOR_MIGRATION_CAPS_LAST,
- "xbzrle")
+ "xbzrle", "auto-converge")
VIR_ENUM_IMPL(qemuMonitorVMStatus,
QEMU_MONITOR_VM_STATUS_LAST,
typedef enum {
QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
+ QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE,
QEMU_MONITOR_MIGRATION_CAPS_LAST
} qemuMonitorMigrationCaps;
.type = VSH_OT_BOOL,
.help = N_("compress repeated pages during live migration")
},
+ {.name = "auto-converge",
+ .type = VSH_OT_BOOL,
+ .help = N_("force convergence during live migration")
+ },
{.name = "abort-on-error",
.type = VSH_OT_BOOL,
.help = N_("abort on soft errors during migration")
if (vshCommandOptBool(cmd, "compressed"))
flags |= VIR_MIGRATE_COMPRESSED;
+ if (vshCommandOptBool(cmd, "auto-converge"))
+ flags |= VIR_MIGRATE_AUTO_CONVERGE;
+
if (vshCommandOptBool(cmd, "offline")) {
flags |= VIR_MIGRATE_OFFLINE;
}