2016-06-24 19:07:56 +02:00
|
|
|
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(-)
|
|
|
|
|
2016-07-01 18:39:05 +02:00
|
|
|
Index: libvirt-2.0.0/include/libvirt/libvirt-domain.h
|
2016-06-24 19:07:56 +02:00
|
|
|
===================================================================
|
2016-07-01 18:39:05 +02:00
|
|
|
--- libvirt-2.0.0.orig/include/libvirt/libvirt-domain.h
|
|
|
|
+++ libvirt-2.0.0/include/libvirt/libvirt-domain.h
|
|
|
|
@@ -864,6 +864,31 @@ typedef enum {
|
2016-06-24 19:07:56 +02:00
|
|
|
*/
|
2016-07-01 18:39:05 +02:00
|
|
|
# define VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT "auto_converge.increment"
|
2016-06-24 19:07:56 +02:00
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * 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,
|
2016-07-01 18:39:05 +02:00
|
|
|
Index: libvirt-2.0.0/src/libxl/libxl_driver.c
|
2016-06-24 19:07:56 +02:00
|
|
|
===================================================================
|
2016-07-01 18:39:05 +02:00
|
|
|
--- libvirt-2.0.0.orig/src/libxl/libxl_driver.c
|
|
|
|
+++ libvirt-2.0.0/src/libxl/libxl_driver.c
|
|
|
|
@@ -5428,6 +5428,9 @@ libxlDomainMigratePerform3Params(virDoma
|
2016-06-24 19:07:56 +02:00
|
|
|
const char *dname = NULL;
|
|
|
|
const char *uri = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
+ libxlDomainMigrationProps props = {
|
|
|
|
+ .virFlags = flags,
|
|
|
|
+ };
|
|
|
|
|
|
|
|
#ifdef LIBXL_HAVE_NO_SUSPEND_RESUME
|
|
|
|
virReportUnsupportedError();
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -5444,6 +5447,18 @@ libxlDomainMigratePerform3Params(virDoma
|
2016-06-24 19:07:56 +02:00
|
|
|
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)
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -5458,11 +5473,11 @@ libxlDomainMigratePerform3Params(virDoma
|
2016-06-24 19:07:56 +02:00
|
|
|
|
|
|
|
if (flags & VIR_MIGRATE_PEER2PEER) {
|
|
|
|
if (libxlDomainMigrationPerformP2P(driver, vm, dom->conn, dom_xml,
|
|
|
|
- dconnuri, uri, dname, flags) < 0)
|
|
|
|
+ dconnuri, uri, dname, &props) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else {
|
|
|
|
if (libxlDomainMigrationPerform(driver, vm, dom_xml, dconnuri,
|
|
|
|
- uri, dname, flags) < 0)
|
|
|
|
+ uri, dname, &props) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-07-01 18:39:05 +02:00
|
|
|
Index: libvirt-2.0.0/src/libxl/libxl_migration.c
|
2016-06-24 19:07:56 +02:00
|
|
|
===================================================================
|
2016-07-01 18:39:05 +02:00
|
|
|
--- libvirt-2.0.0.orig/src/libxl/libxl_migration.c
|
|
|
|
+++ libvirt-2.0.0/src/libxl/libxl_migration.c
|
|
|
|
@@ -357,18 +357,39 @@ libxlMigrateReceive(virNetSocketPtr sock
|
2016-06-24 19:07:56 +02:00
|
|
|
static int
|
|
|
|
libxlDoMigrateSend(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"));
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -663,7 +684,7 @@ libxlDoMigrateP2P(libxlDriverPrivatePtr
|
2016-06-24 19:07:56 +02:00
|
|
|
const char *dconnuri ATTRIBUTE_UNUSED,
|
|
|
|
const char *dname,
|
|
|
|
const char *uri,
|
|
|
|
- unsigned int flags)
|
|
|
|
+ const libxlDomainMigrationProps *props)
|
|
|
|
{
|
|
|
|
virDomainPtr ddomain = NULL;
|
|
|
|
virTypedParameterPtr params = NULL;
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -700,7 +721,7 @@ libxlDoMigrateP2P(libxlDriverPrivatePtr
|
2016-06-24 19:07:56 +02:00
|
|
|
/* We don't require the destination to have P2P support
|
|
|
|
* as it looks to be normal migration from the receiver perpective.
|
|
|
|
*/
|
|
|
|
- destflags = flags & ~(VIR_MIGRATE_PEER2PEER);
|
|
|
|
+ destflags = props->virFlags & ~(VIR_MIGRATE_PEER2PEER);
|
|
|
|
|
|
|
|
VIR_DEBUG("Prepare3");
|
|
|
|
virObjectUnlock(vm);
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -725,7 +746,7 @@ libxlDoMigrateP2P(libxlDriverPrivatePtr
|
2016-06-24 19:07:56 +02:00
|
|
|
|
|
|
|
VIR_DEBUG("Perform3 uri=%s", NULLSTR(uri_out));
|
|
|
|
ret = libxlDomainMigrationPerform(driver, vm, NULL, NULL,
|
|
|
|
- uri_out, NULL, flags);
|
|
|
|
+ uri_out, NULL, props);
|
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
orig_err = virSaveLastError();
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -757,7 +778,7 @@ libxlDoMigrateP2P(libxlDriverPrivatePtr
|
2016-06-24 19:07:56 +02:00
|
|
|
orig_err = virSaveLastError();
|
|
|
|
|
|
|
|
VIR_DEBUG("Confirm3 cancelled=%d vm=%p", cancelled, vm);
|
|
|
|
- ret = libxlDomainMigrationConfirm(driver, vm, flags, cancelled);
|
|
|
|
+ ret = libxlDomainMigrationConfirm(driver, vm, props->virFlags, cancelled);
|
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
VIR_WARN("Guest %s probably left in 'paused' state on source",
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -806,7 +827,7 @@ libxlDomainMigrationPerformP2P(libxlDriv
|
2016-06-24 19:07:56 +02:00
|
|
|
const char *dconnuri,
|
|
|
|
const char *uri_str ATTRIBUTE_UNUSED,
|
|
|
|
const char *dname,
|
|
|
|
- unsigned int flags)
|
|
|
|
+ const libxlDomainMigrationProps *props)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
bool useParams;
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -841,7 +862,7 @@ libxlDomainMigrationPerformP2P(libxlDriv
|
2016-06-24 19:07:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = libxlDoMigrateP2P(driver, vm, sconn, xmlin, dconn, dconnuri,
|
|
|
|
- dname, uri_str, flags);
|
|
|
|
+ dname, uri_str, props);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
orig_err = virSaveLastError();
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -863,7 +884,7 @@ libxlDomainMigrationPerform(libxlDriverP
|
2016-06-24 19:07:56 +02:00
|
|
|
const char *dconnuri ATTRIBUTE_UNUSED,
|
|
|
|
const char *uri_str,
|
|
|
|
const char *dname ATTRIBUTE_UNUSED,
|
|
|
|
- unsigned int flags)
|
|
|
|
+ const libxlDomainMigrationProps *props)
|
|
|
|
{
|
|
|
|
libxlDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
char *hostname = NULL;
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -903,7 +924,7 @@ libxlDomainMigrationPerform(libxlDriverP
|
2016-06-24 19:07:56 +02:00
|
|
|
|
|
|
|
/* suspend vm and send saved data to dst through socket fd */
|
|
|
|
virObjectUnlock(vm);
|
|
|
|
- ret = libxlDoMigrateSend(driver, vm, flags, sockfd);
|
|
|
|
+ ret = libxlDoMigrateSend(driver, vm, props, sockfd);
|
|
|
|
virObjectLock(vm);
|
|
|
|
|
|
|
|
cleanup:
|
2016-07-01 18:39:05 +02:00
|
|
|
Index: libvirt-2.0.0/src/libxl/libxl_migration.h
|
2016-06-24 19:07:56 +02:00
|
|
|
===================================================================
|
2016-07-01 18:39:05 +02:00
|
|
|
--- libvirt-2.0.0.orig/src/libxl/libxl_migration.h
|
|
|
|
+++ libvirt-2.0.0/src/libxl/libxl_migration.h
|
2016-06-24 19:07:56 +02:00
|
|
|
@@ -37,6 +37,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 *
|
|
|
|
@@ -60,6 +64,14 @@ libxlDomainMigrationPrepare(virConnectPt
|
|
|
|
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
|
|
|
|
libxlDomainMigrationPerformP2P(libxlDriverPrivatePtr driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
@@ -68,7 +80,7 @@ libxlDomainMigrationPerformP2P(libxlDriv
|
|
|
|
const char *dconnuri,
|
|
|
|
const char *uri_str,
|
|
|
|
const char *dname,
|
|
|
|
- unsigned int flags);
|
|
|
|
+ const libxlDomainMigrationProps *props);
|
|
|
|
|
|
|
|
int
|
|
|
|
libxlDomainMigrationPerform(libxlDriverPrivatePtr driver,
|
|
|
|
@@ -77,7 +89,7 @@ libxlDomainMigrationPerform(libxlDriverP
|
|
|
|
const char *dconnuri,
|
|
|
|
const char *uri_str,
|
|
|
|
const char *dname,
|
|
|
|
- unsigned int flags);
|
|
|
|
+ const libxlDomainMigrationProps *props);
|
|
|
|
|
|
|
|
virDomainPtr
|
|
|
|
libxlDomainMigrationFinish(virConnectPtr dconn,
|
2016-07-01 18:39:05 +02:00
|
|
|
Index: libvirt-2.0.0/tools/virsh-domain.c
|
2016-06-24 19:07:56 +02:00
|
|
|
===================================================================
|
2016-07-01 18:39:05 +02:00
|
|
|
--- libvirt-2.0.0.orig/tools/virsh-domain.c
|
|
|
|
+++ libvirt-2.0.0/tools/virsh-domain.c
|
|
|
|
@@ -9977,6 +9977,22 @@ static const vshCmdOptDef opts_migrate[]
|
2016-06-24 19:07:56 +02:00
|
|
|
.type = VSH_OT_INT,
|
2016-07-01 18:39:05 +02:00
|
|
|
.help = N_("CPU throttling rate increment for auto-convergence")
|
2016-06-24 19:07:56 +02:00
|
|
|
},
|
|
|
|
+ {.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}
|
|
|
|
};
|
|
|
|
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -10000,6 +10016,7 @@ doMigrate(void *opaque)
|
2016-06-24 19:07:56 +02:00
|
|
|
unsigned long long ullOpt = 0;
|
|
|
|
int rv;
|
|
|
|
virConnectPtr dconn = data->dconn;
|
|
|
|
+ unsigned int uint_opt = 0;
|
|
|
|
|
|
|
|
sigemptyset(&sigmask);
|
|
|
|
sigaddset(&sigmask, SIGINT);
|
2016-07-01 18:39:05 +02:00
|
|
|
@@ -10119,6 +10136,27 @@ doMigrate(void *opaque)
|
2016-06-24 19:07:56 +02:00
|
|
|
goto save_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if (vshCommandOptUInt(ctl, cmd, "max_iters", &uint_opt) > 0 && uint_opt) {
|
|
|
|
+ if (virTypedParamsAddUInt(¶ms, &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(¶ms, &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(¶ms, &nparams, &maxparams,
|
|
|
|
+ VIR_MIGRATE_PARAM_SUSE_MIN_REMAINING, uint_opt) < 0)
|
|
|
|
+ goto save_error;
|
|
|
|
+ }
|
|
|
|
+ if (vshCommandOptBool(cmd, "abort_if_busy")) {
|
|
|
|
+ if (virTypedParamsAddUInt(¶ms, &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) {
|
2016-07-01 18:39:05 +02:00
|
|
|
Index: libvirt-2.0.0/tools/virsh.pod
|
2016-06-24 19:07:56 +02:00
|
|
|
===================================================================
|
2016-07-01 18:39:05 +02:00
|
|
|
--- libvirt-2.0.0.orig/tools/virsh.pod
|
|
|
|
+++ libvirt-2.0.0/tools/virsh.pod
|
|
|
|
@@ -1631,6 +1631,14 @@ compression. I<--comp-mt-threads> and I<
|
2016-06-24 19:07:56 +02:00
|
|
|
of compress threads on source and the number of decompress threads on target
|
|
|
|
respectively. I<--comp-xbzrle-cache> sets size of page cache in bytes.
|
|
|
|
|
|
|
|
+SUSE-specific options for Xen: I<--max_iters> B<num> allows specifying the maximum
|
|
|
|
+number of iterations before final suspend. Default is 30. I<--max_factor> B<num>
|
|
|
|
+allows specifying the maximum amount of memory to transfer before final suspend.
|
|
|
|
+Default is (3*VM memory size). I<--min_remaining> B<num> allows specifying the
|
|
|
|
+number of dirty pages before final suspend. Default is 50. I<--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
|
|
|
|
C<Ctrl-C>) or by B<domjobabort> command sent from another virsh instance.
|
|
|
|
|