libvirt/libxl-set-migration-constraints.patch

406 lines
16 KiB
Diff
Raw Normal View History

From 6409e928eb4c2287dca59b139650fab77ea99fb8 Mon Sep 17 00:00:00 2001
From: Olaf Hering <olaf@aepfle.de>
Date: Fri, 9 May 2014 11:55:31 -0600
Subject: [PATCH] libvirt: set migration constraints from cmdline
References: fate#316614
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
---
include/libvirt/libvirt-domain.h | 25 +++++++++++++++++++++++++
src/libxl/libxl_driver.c | 17 ++++++++++++++++-
src/libxl/libxl_migration.c | 29 +++++++++++++++++++++++++----
src/libxl/libxl_migration.h | 14 +++++++++++++-
tools/virsh-domain.c | 38 ++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 8 ++++++++
6 files changed, 125 insertions(+), 6 deletions(-)
Index: libvirt-6.1.0/include/libvirt/libvirt-domain.h
===================================================================
--- libvirt-6.1.0.orig/include/libvirt/libvirt-domain.h
+++ libvirt-6.1.0/include/libvirt/libvirt-domain.h
@@ -1065,6 +1065,31 @@ typedef enum {
*/
# define VIR_MIGRATE_PARAM_TLS_DESTINATION "tls.destination"
+/**
+ * VIR_MIGRATE_PARAM_SUSE_MAX_ITERS:
+ *
+ * virDomainMigrate* params field: xc_domain_save max_iters
+ */
+#define VIR_MIGRATE_PARAM_SUSE_MAX_ITERS "max_iters"
+/**
+ * VIR_MIGRATE_PARAM_SUSE_MAX_FACTOR:
+ *
+ * virDomainMigrate* params field: xc_domain_save max_factor
+ */
+#define VIR_MIGRATE_PARAM_SUSE_MAX_FACTOR "max_factor"
+/**
+ * VIR_MIGRATE_PARAM_SUSE_MIN_REMAINING:
+ *
+ * virDomainMigrate* params field: xc_domain_save min_remaining
+ */
+#define VIR_MIGRATE_PARAM_SUSE_MIN_REMAINING "min_remaining"
+/**
+ * VIR_MIGRATE_PARAM_SUSE_ABORT_IF_BUSY:
+ *
+ * virDomainMigrate* params field: xc_domain_save abort_if_busy
+ */
+#define VIR_MIGRATE_PARAM_SUSE_ABORT_IF_BUSY "abort_if_busy"
+
/* Domain migration. */
virDomainPtr virDomainMigrate (virDomainPtr domain, virConnectPtr dconn,
unsigned long flags, const char *dname,
Index: libvirt-6.1.0/src/libxl/libxl_driver.c
===================================================================
--- libvirt-6.1.0.orig/src/libxl/libxl_driver.c
+++ libvirt-6.1.0/src/libxl/libxl_driver.c
@@ -6146,6 +6146,9 @@ libxlDomainMigratePerform3Params(virDoma
const char *dname = NULL;
const char *uri = NULL;
int ret = -1;
+ libxlDomainMigrationProps props = {
+ .virFlags = flags,
+ };
#ifdef LIBXL_HAVE_NO_SUSPEND_RESUME
virReportUnsupportedError();
@@ -6162,6 +6165,18 @@ libxlDomainMigratePerform3Params(virDoma
virTypedParamsGetString(params, nparams,
VIR_MIGRATE_PARAM_DEST_NAME,
&dname) < 0 ||
+ virTypedParamsGetUInt(params, nparams,
+ VIR_MIGRATE_PARAM_SUSE_MAX_ITERS,
+ &props.max_iters) < 0 ||
+ virTypedParamsGetUInt(params, nparams,
+ VIR_MIGRATE_PARAM_SUSE_MAX_FACTOR,
+ &props.max_factor) < 0 ||
+ virTypedParamsGetUInt(params, nparams,
+ VIR_MIGRATE_PARAM_SUSE_MIN_REMAINING,
+ &props.min_remaining) < 0 ||
+ virTypedParamsGetUInt(params, nparams,
+ VIR_MIGRATE_PARAM_SUSE_ABORT_IF_BUSY,
+ &props.abort_if_busy) < 0 ||
virTypedParamsGetString(params, nparams,
VIR_MIGRATE_PARAM_URI,
&uri) < 0)
@@ -6176,11 +6191,11 @@ libxlDomainMigratePerform3Params(virDoma
if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
if (libxlDomainMigrationSrcPerformP2P(driver, vm, dom->conn, dom_xml,
- dconnuri, uri, dname, flags) < 0)
+ dconnuri, uri, dname, &props) < 0)
goto cleanup;
} else {
if (libxlDomainMigrationSrcPerform(driver, vm, dom_xml, dconnuri,
- uri, dname, flags) < 0)
+ uri, dname, &props) < 0)
goto cleanup;
}
Index: libvirt-6.1.0/src/libxl/libxl_migration.c
===================================================================
--- libvirt-6.1.0.orig/src/libxl/libxl_migration.c
+++ libvirt-6.1.0/src/libxl/libxl_migration.c
@@ -339,18 +339,39 @@ libxlMigrateDstReceive(virNetSocketPtr s
static int
libxlDoMigrateSrcSend(libxlDriverPrivatePtr driver,
virDomainObjPtr vm,
- unsigned long flags,
+ const libxlDomainMigrationProps *props,
int sockfd)
{
libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
+#ifdef LIBXL_HAVE_DOMAIN_SUSPEND_SUSE
+ libxl_domain_suspend_suse_properties libxl_props = {
+ .flags = 0,
+ };
+#else
int xl_flags = 0;
+#endif
int ret;
- if (flags & VIR_MIGRATE_LIVE)
+#ifdef LIBXL_HAVE_DOMAIN_SUSPEND_SUSE
+ if (props->virFlags & VIR_MIGRATE_LIVE)
+ libxl_props.flags |= LIBXL_SUSPEND_LIVE;
+
+ libxl_props.max_iters = props->max_iters;
+ libxl_props.max_factor = props->max_factor;
+ libxl_props.min_remaining = props->min_remaining;
+ if (props->abort_if_busy)
+ libxl_props.flags |= LIBXL_SUSPEND_ABORT_IF_BUSY;
+
+ ret = libxl_domain_suspend_suse(cfg->ctx, vm->def->id, sockfd,
+ &libxl_props, NULL);
+#else
+ if (props->virFlags & VIR_MIGRATE_LIVE)
xl_flags = LIBXL_SUSPEND_LIVE;
ret = libxl_domain_suspend(cfg->ctx, vm->def->id, sockfd,
xl_flags, NULL);
+#endif
+
if (ret != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Failed to send migration data to destination host"));
@@ -903,7 +924,7 @@ struct libxlTunnelControl {
static int
libxlMigrationSrcStartTunnel(libxlDriverPrivatePtr driver,
virDomainObjPtr vm,
- unsigned long flags,
+ const libxlDomainMigrationProps *props,
virStreamPtr st,
struct libxlTunnelControl **tnl)
{
@@ -934,7 +955,7 @@ libxlMigrationSrcStartTunnel(libxlDriver
virObjectUnlock(vm);
/* Send data to pipe */
- ret = libxlDoMigrateSrcSend(driver, vm, flags, tc->dataFD[1]);
+ ret = libxlDoMigrateSrcSend(driver, vm, props, tc->dataFD[1]);
virObjectLock(vm);
out:
@@ -970,7 +991,7 @@ libxlDoMigrateSrcP2P(libxlDriverPrivateP
const char *dconnuri G_GNUC_UNUSED,
const char *dname,
const char *uri,
- unsigned int flags)
+ const libxlDomainMigrationProps *props)
{
virDomainPtr ddomain = NULL;
virTypedParameterPtr params = NULL;
@@ -1015,11 +1036,11 @@ libxlDoMigrateSrcP2P(libxlDriverPrivateP
/* We don't require the destination to have P2P support
* as it looks to be normal migration from the receiver perspective.
*/
- destflags = flags & ~(VIR_MIGRATE_PEER2PEER);
+ destflags = props->virFlags & ~(VIR_MIGRATE_PEER2PEER);
VIR_DEBUG("Prepare3");
virObjectUnlock(vm);
- if (flags & VIR_MIGRATE_TUNNELLED) {
+ if (props->virFlags & VIR_MIGRATE_TUNNELLED) {
if (!(st = virStreamNew(dconn, 0)))
goto confirm;
ret = dconn->driver->domainMigratePrepareTunnel3Params
@@ -1033,7 +1054,7 @@ libxlDoMigrateSrcP2P(libxlDriverPrivateP
if (ret == -1)
goto confirm;
- if (!(flags & VIR_MIGRATE_TUNNELLED)) {
+ if (!(props->virFlags & VIR_MIGRATE_TUNNELLED)) {
if (uri_out) {
if (virTypedParamsReplaceString(&params, &nparams,
VIR_MIGRATE_PARAM_URI, uri_out) < 0) {
@@ -1048,11 +1069,11 @@ libxlDoMigrateSrcP2P(libxlDriverPrivateP
}
VIR_DEBUG("Perform3 uri=%s", NULLSTR(uri_out));
- if (flags & VIR_MIGRATE_TUNNELLED)
- ret = libxlMigrationSrcStartTunnel(driver, vm, flags, st, &tc);
+ if (props->virFlags & VIR_MIGRATE_TUNNELLED)
+ ret = libxlMigrationSrcStartTunnel(driver, vm, props, st, &tc);
else
ret = libxlDomainMigrationSrcPerform(driver, vm, NULL, NULL,
- uri_out, NULL, flags);
+ uri_out, NULL, props);
if (ret < 0) {
notify_source = false;
virErrorPreserveLast(&orig_err);
@@ -1087,7 +1108,7 @@ libxlDoMigrateSrcP2P(libxlDriverPrivateP
confirm:
if (notify_source) {
VIR_DEBUG("Confirm3 cancelled=%d vm=%p", cancelled, vm);
- ret = libxlDomainMigrationSrcConfirm(driver, vm, flags, cancelled);
+ ret = libxlDomainMigrationSrcConfirm(driver, vm, props->virFlags, cancelled);
if (ret < 0)
VIR_WARN("Guest %s probably left in 'paused' state on source",
@@ -1095,7 +1116,7 @@ libxlDoMigrateSrcP2P(libxlDriverPrivateP
}
cleanup:
- if (flags & VIR_MIGRATE_TUNNELLED) {
+ if (props->virFlags & VIR_MIGRATE_TUNNELLED) {
libxlMigrationSrcStopTunnel(tc);
virObjectUnref(st);
}
@@ -1139,7 +1160,7 @@ libxlDomainMigrationSrcPerformP2P(libxlD
const char *dconnuri,
const char *uri_str G_GNUC_UNUSED,
const char *dname,
- unsigned int flags)
+ const libxlDomainMigrationProps *props)
{
int ret = -1;
bool useParams;
@@ -1174,7 +1195,7 @@ libxlDomainMigrationSrcPerformP2P(libxlD
}
ret = libxlDoMigrateSrcP2P(driver, vm, sconn, xmlin, dconn, dconnuri,
- dname, uri_str, flags);
+ dname, uri_str, props);
if (ret < 0) {
/*
@@ -1201,7 +1222,7 @@ libxlDomainMigrationSrcPerform(libxlDriv
const char *dconnuri G_GNUC_UNUSED,
const char *uri_str,
const char *dname G_GNUC_UNUSED,
- unsigned int flags)
+ const libxlDomainMigrationProps *props)
{
libxlDomainObjPrivatePtr priv = vm->privateData;
char *hostname = NULL;
@@ -1237,7 +1258,7 @@ libxlDomainMigrationSrcPerform(libxlDriv
/* suspend vm and send saved data to dst through socket fd */
virObjectUnlock(vm);
- ret = libxlDoMigrateSrcSend(driver, vm, flags, sockfd);
+ ret = libxlDoMigrateSrcSend(driver, vm, props, sockfd);
virObjectLock(vm);
if (ret == 0) {
Index: libvirt-6.1.0/src/libxl/libxl_migration.h
===================================================================
--- libvirt-6.1.0.orig/src/libxl/libxl_migration.h
+++ libvirt-6.1.0/src/libxl/libxl_migration.h
@@ -35,6 +35,10 @@
VIR_MIGRATE_PARAM_URI, VIR_TYPED_PARAM_STRING, \
VIR_MIGRATE_PARAM_DEST_NAME, VIR_TYPED_PARAM_STRING, \
VIR_MIGRATE_PARAM_DEST_XML, VIR_TYPED_PARAM_STRING, \
+ VIR_MIGRATE_PARAM_SUSE_MAX_ITERS, VIR_TYPED_PARAM_UINT, \
+ VIR_MIGRATE_PARAM_SUSE_MAX_FACTOR, VIR_TYPED_PARAM_UINT, \
+ VIR_MIGRATE_PARAM_SUSE_MIN_REMAINING, VIR_TYPED_PARAM_UINT, \
+ VIR_MIGRATE_PARAM_SUSE_ABORT_IF_BUSY, VIR_TYPED_PARAM_UINT, \
NULL
char *
@@ -66,6 +70,14 @@ libxlDomainMigrationDstPrepare(virConnec
int cookieinlen,
unsigned int flags);
+typedef struct {
+ unsigned int virFlags;
+ unsigned int max_iters;
+ unsigned int max_factor;
+ unsigned int min_remaining;
+ unsigned int abort_if_busy;
+} libxlDomainMigrationProps;
+
int
libxlDomainMigrationSrcPerformP2P(libxlDriverPrivatePtr driver,
virDomainObjPtr vm,
@@ -74,7 +86,7 @@ libxlDomainMigrationSrcPerformP2P(libxlD
const char *dconnuri,
const char *uri_str,
const char *dname,
- unsigned int flags);
+ const libxlDomainMigrationProps *props);
int
libxlDomainMigrationSrcPerform(libxlDriverPrivatePtr driver,
@@ -83,7 +95,7 @@ libxlDomainMigrationSrcPerform(libxlDriv
const char *dconnuri,
const char *uri_str,
const char *dname,
- unsigned int flags);
+ const libxlDomainMigrationProps *props);
virDomainPtr
libxlDomainMigrationDstFinish(virConnectPtr dconn,
Index: libvirt-6.1.0/tools/virsh-domain.c
===================================================================
--- libvirt-6.1.0.orig/tools/virsh-domain.c
+++ libvirt-6.1.0/tools/virsh-domain.c
@@ -10713,6 +10713,22 @@ static const vshCmdOptDef opts_migrate[]
.type = VSH_OT_STRING,
.help = N_("override the destination host name used for TLS verification")
},
+ {.name = "max_iters",
+ .type = VSH_OT_INT,
+ .help = N_("SUSE libxl: Number of iterations before final suspend (default: 30).")
+ },
+ {.name = "max_factor",
+ .type = VSH_OT_INT,
+ .help = N_("SUSE libxl: Max amount of memory to transfer before final suspend (default: 3*RAM).")
+ },
+ {.name = "min_remaining",
+ .type = VSH_OT_INT,
+ .help = N_("SUSE libxl: Number of dirty pages before final suspend (default: 50).")
+ },
+ {.name = "abort_if_busy",
+ .type = VSH_OT_BOOL,
+ .help = N_("SUSE libxl: Abort migration instead of doing final suspend.")
+ },
{.name = NULL}
};
@@ -10735,6 +10751,7 @@ doMigrate(void *opaque)
unsigned long long ullOpt = 0;
int rv;
virConnectPtr dconn = data->dconn;
+ unsigned int uint_opt = 0;
#ifndef WIN32
sigset_t sigmask, oldsigmask;
@@ -10857,6 +10874,27 @@ doMigrate(void *opaque)
goto save_error;
}
+ if (vshCommandOptUInt(ctl, cmd, "max_iters", &uint_opt) > 0 && uint_opt) {
+ if (virTypedParamsAddUInt(&params, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_SUSE_MAX_ITERS, uint_opt) < 0)
+ goto save_error;
+ }
+ if (vshCommandOptUInt(ctl, cmd, "max_factor", &uint_opt) > 0 && uint_opt) {
+ if (virTypedParamsAddUInt(&params, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_SUSE_MAX_FACTOR, uint_opt) < 0)
+ goto save_error;
+ }
+ if (vshCommandOptUInt(ctl, cmd, "min_remaining", &uint_opt) > 0 && uint_opt) {
+ if (virTypedParamsAddUInt(&params, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_SUSE_MIN_REMAINING, uint_opt) < 0)
+ goto save_error;
+ }
+ if (vshCommandOptBool(cmd, "abort_if_busy")) {
+ if (virTypedParamsAddUInt(&params, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_SUSE_ABORT_IF_BUSY, 1) < 0)
+ goto save_error;
+ }
+
if (vshCommandOptStringReq(ctl, cmd, "xml", &opt) < 0)
goto out;
if (opt) {
Index: libvirt-6.1.0/docs/manpages/virsh.rst
===================================================================
--- libvirt-6.1.0.orig/docs/manpages/virsh.rst
+++ libvirt-6.1.0/docs/manpages/virsh.rst
@@ -3093,6 +3093,8 @@ migrate
[--postcopy-bandwidth bandwidth]
[--parallel [--parallel-connections connections]]
[--bandwidth bandwidth] [--tls-destination hostname]
+ [--max_iters num] [--max_factor num] [--min_remaining num]
+ [--abort_if_busy]
Migrate domain to another host. Add *--live* for live migration; <--p2p>
for peer-2-peer migration; *--direct* for direct migration; or *--tunnelled*
@@ -3198,6 +3200,14 @@ parallel connections. The number of such
network link between the source and the target and thus speeding up the
migration.
+SUSE-specific options for Xen: *--max_iters* allows specifying the maximum
+number of iterations before final suspend. Default is 30. *--max_factor*
+allows specifying the maximum amount of memory to transfer before final suspend.
+Default is (3*VM memory size). *--min_remaining* allows specifying the
+number of dirty pages before final suspend. Default is 50. *--abort_if_busy*
+can be used to abort the migration instead of doing the final suspend for VMs
+with busy workloads.
+
Running migration can be canceled by interrupting virsh (usually using
``Ctrl-C``) or by ``domjobabort`` command sent from another virsh instance.