libvirt support to force convergence of live guest migration

Busy enterprise workloads hosted on large sized VM's tend to dirty
memory faster than the transfer rate achieved via live guest migration.
Despite some good recent improvements (& using dedicated 10Gig NICs
between hosts) the live migration may NOT converge.

Recently support was added in qemu (version 1.6) to allow a user to
choose if they wish to force convergence of their migration via a
new migration capability : "auto-converge". This feature allows for qemu
to auto-detect lack of convergence and trigger a throttle-down of the
VCPUs.

This patch includes the libvirt support needed to trigger this
feature. (Testing is in progress)

Signed-off-by:  Chegu Vinod <chegu_vinod@hp.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Chegu Vinod 2014-02-06 15:44:36 -08:00 committed by Jiri Denemark
parent bfb29654c8
commit 05e1b06ab7
7 changed files with 62 additions and 7 deletions

View File

@ -1200,6 +1200,7 @@ typedef enum {
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;

View File

@ -4408,7 +4408,8 @@ virDomainMigrateVersion1(virDomainPtr domain,
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.
*
@ -4538,7 +4539,8 @@ virDomainMigrateVersion2(virDomainPtr domain,
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
@ -4710,7 +4712,8 @@ virDomainMigrateVersion3Full(virDomainPtr domain,
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;

View File

@ -1621,6 +1621,41 @@ cleanup:
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)
@ -3234,6 +3269,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
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;
@ -3587,7 +3627,8 @@ static int doPeer2PeerMigrate2(virQEMUDriverPtr driver,
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) {
@ -3780,7 +3821,8 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
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;

View File

@ -39,7 +39,8 @@
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 \

View File

@ -121,7 +121,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
VIR_ENUM_IMPL(qemuMonitorMigrationCaps,
QEMU_MONITOR_MIGRATION_CAPS_LAST,
"xbzrle")
"xbzrle", "auto-converge")
VIR_ENUM_IMPL(qemuMonitorVMStatus,
QEMU_MONITOR_VM_STATUS_LAST,

View File

@ -451,6 +451,7 @@ int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
typedef enum {
QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE,
QEMU_MONITOR_MIGRATION_CAPS_LAST
} qemuMonitorMigrationCaps;

View File

@ -8757,6 +8757,10 @@ static const vshCmdOptDef opts_migrate[] = {
.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")
@ -8901,6 +8905,9 @@ doMigrate(void *opaque)
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;
}