提交 05e1b06a 编写于 作者: C Chegu Vinod 提交者: Jiri Denemark

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: NChegu Vinod <chegu_vinod@hp.com>
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 bfb29654
...@@ -1200,6 +1200,7 @@ typedef enum { ...@@ -1200,6 +1200,7 @@ typedef enum {
VIR_MIGRATE_OFFLINE = (1 << 10), /* offline migrate */ VIR_MIGRATE_OFFLINE = (1 << 10), /* offline migrate */
VIR_MIGRATE_COMPRESSED = (1 << 11), /* compress data during migration */ 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_ABORT_ON_ERROR = (1 << 12), /* abort migration on I/O errors happened during migration */
VIR_MIGRATE_AUTO_CONVERGE = (1 << 13), /* force convergence */
} virDomainMigrateFlags; } virDomainMigrateFlags;
......
...@@ -4408,7 +4408,8 @@ virDomainMigrateVersion1(virDomainPtr domain, ...@@ -4408,7 +4408,8 @@ virDomainMigrateVersion1(virDomainPtr domain,
if (ret == 0 && info.state == VIR_DOMAIN_PAUSED) if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_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. /* Prepare the migration.
* *
...@@ -4538,7 +4539,8 @@ virDomainMigrateVersion2(virDomainPtr domain, ...@@ -4538,7 +4539,8 @@ virDomainMigrateVersion2(virDomainPtr domain,
if (ret == 0 && info.state == VIR_DOMAIN_PAUSED) if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_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); VIR_DEBUG("Prepare2 %p flags=%lx", dconn, destflags);
ret = dconn->driver->domainMigratePrepare2 ret = dconn->driver->domainMigratePrepare2
...@@ -4710,7 +4712,8 @@ virDomainMigrateVersion3Full(virDomainPtr domain, ...@@ -4710,7 +4712,8 @@ virDomainMigrateVersion3Full(virDomainPtr domain,
if (ret == 0 && state == VIR_DOMAIN_PAUSED) if (ret == 0 && state == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_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); VIR_DEBUG("Prepare3 %p flags=%x", dconn, destflags);
cookiein = cookieout; cookiein = cookieout;
......
...@@ -1621,6 +1621,41 @@ cleanup: ...@@ -1621,6 +1621,41 @@ cleanup:
return ret; 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 static int
qemuMigrationWaitForSpice(virQEMUDriverPtr driver, qemuMigrationWaitForSpice(virQEMUDriverPtr driver,
virDomainObjPtr vm) virDomainObjPtr vm)
...@@ -3234,6 +3269,11 @@ qemuMigrationRun(virQEMUDriverPtr driver, ...@@ -3234,6 +3269,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup; goto cleanup;
if (flags & VIR_MIGRATE_AUTO_CONVERGE &&
qemuMigrationSetAutoConverge(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
if (qemuDomainObjEnterMonitorAsync(driver, vm, if (qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup; goto cleanup;
...@@ -3587,7 +3627,8 @@ static int doPeer2PeerMigrate2(virQEMUDriverPtr driver, ...@@ -3587,7 +3627,8 @@ static int doPeer2PeerMigrate2(virQEMUDriverPtr driver,
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_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); VIR_DEBUG("Prepare2 %p", dconn);
if (flags & VIR_MIGRATE_TUNNELLED) { if (flags & VIR_MIGRATE_TUNNELLED) {
...@@ -3780,7 +3821,8 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, ...@@ -3780,7 +3821,8 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_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); VIR_DEBUG("Prepare3 %p", dconn);
cookiein = cookieout; cookiein = cookieout;
......
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
VIR_MIGRATE_UNSAFE | \ VIR_MIGRATE_UNSAFE | \
VIR_MIGRATE_OFFLINE | \ VIR_MIGRATE_OFFLINE | \
VIR_MIGRATE_COMPRESSED | \ VIR_MIGRATE_COMPRESSED | \
VIR_MIGRATE_ABORT_ON_ERROR) VIR_MIGRATE_ABORT_ON_ERROR | \
VIR_MIGRATE_AUTO_CONVERGE)
/* All supported migration parameters and their types. */ /* All supported migration parameters and their types. */
# define QEMU_MIGRATION_PARAMETERS \ # define QEMU_MIGRATION_PARAMETERS \
......
...@@ -121,7 +121,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus, ...@@ -121,7 +121,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
VIR_ENUM_IMPL(qemuMonitorMigrationCaps, VIR_ENUM_IMPL(qemuMonitorMigrationCaps,
QEMU_MONITOR_MIGRATION_CAPS_LAST, QEMU_MONITOR_MIGRATION_CAPS_LAST,
"xbzrle") "xbzrle", "auto-converge")
VIR_ENUM_IMPL(qemuMonitorVMStatus, VIR_ENUM_IMPL(qemuMonitorVMStatus,
QEMU_MONITOR_VM_STATUS_LAST, QEMU_MONITOR_VM_STATUS_LAST,
......
...@@ -451,6 +451,7 @@ int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon, ...@@ -451,6 +451,7 @@ int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
typedef enum { typedef enum {
QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE,
QEMU_MONITOR_MIGRATION_CAPS_LAST QEMU_MONITOR_MIGRATION_CAPS_LAST
} qemuMonitorMigrationCaps; } qemuMonitorMigrationCaps;
......
...@@ -8757,6 +8757,10 @@ static const vshCmdOptDef opts_migrate[] = { ...@@ -8757,6 +8757,10 @@ static const vshCmdOptDef opts_migrate[] = {
.type = VSH_OT_BOOL, .type = VSH_OT_BOOL,
.help = N_("compress repeated pages during live migration") .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", {.name = "abort-on-error",
.type = VSH_OT_BOOL, .type = VSH_OT_BOOL,
.help = N_("abort on soft errors during migration") .help = N_("abort on soft errors during migration")
...@@ -8901,6 +8905,9 @@ doMigrate(void *opaque) ...@@ -8901,6 +8905,9 @@ doMigrate(void *opaque)
if (vshCommandOptBool(cmd, "compressed")) if (vshCommandOptBool(cmd, "compressed"))
flags |= VIR_MIGRATE_COMPRESSED; flags |= VIR_MIGRATE_COMPRESSED;
if (vshCommandOptBool(cmd, "auto-converge"))
flags |= VIR_MIGRATE_AUTO_CONVERGE;
if (vshCommandOptBool(cmd, "offline")) { if (vshCommandOptBool(cmd, "offline")) {
flags |= VIR_MIGRATE_OFFLINE; flags |= VIR_MIGRATE_OFFLINE;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册