File libxl-set-migration-constraints.patch of Package libvirt.3100

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-1.2.18.4/include/libvirt/libvirt-domain.h
===================================================================
--- libvirt-1.2.18.4.orig/include/libvirt/libvirt-domain.h
+++ libvirt-1.2.18.4/include/libvirt/libvirt-domain.h
@@ -757,6 +757,31 @@ typedef enum {
  */
 # define VIR_MIGRATE_PARAM_MIGRATE_DISKS    "migrate_disks"
 
+/**
+ * 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-1.2.18.4/src/libxl/libxl_driver.c
===================================================================
--- libvirt-1.2.18.4.orig/src/libxl/libxl_driver.c
+++ libvirt-1.2.18.4/src/libxl/libxl_driver.c
@@ -5068,6 +5068,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();
@@ -5084,6 +5087,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)
@@ -5097,7 +5112,7 @@ libxlDomainMigratePerform3Params(virDoma
         goto cleanup;
 
     if (libxlDomainMigrationPerform(driver, vm, dom_xml, dconnuri,
-                                    uri, dname, flags) < 0)
+                                    uri, dname, &props) < 0)
         goto cleanup;
 
     ret = 0;
Index: libvirt-1.2.18.4/src/libxl/libxl_migration.c
===================================================================
--- libvirt-1.2.18.4.orig/src/libxl/libxl_migration.c
+++ libvirt-1.2.18.4/src/libxl/libxl_migration.c
@@ -188,18 +188,39 @@ libxlMigrateReceive(virNetSocketPtr sock
 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"));
@@ -463,7 +484,7 @@ libxlDomainMigrationPerform(libxlDriverP
                             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;
@@ -503,7 +524,7 @@ libxlDomainMigrationPerform(libxlDriverP
 
     /* 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:
Index: libvirt-1.2.18.4/src/libxl/libxl_migration.h
===================================================================
--- libvirt-1.2.18.4.orig/src/libxl/libxl_migration.h
+++ libvirt-1.2.18.4/src/libxl/libxl_migration.h
@@ -36,6 +36,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 *
@@ -55,6 +59,14 @@ libxlDomainMigrationPrepare(virConnectPt
                             char **uri_out,
                             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
 libxlDomainMigrationPerform(libxlDriverPrivatePtr driver,
                             virDomainObjPtr vm,
@@ -62,7 +74,7 @@ libxlDomainMigrationPerform(libxlDriverP
                             const char *dconnuri,
                             const char *uri_str,
                             const char *dname,
-                            unsigned int flags);
+                            const libxlDomainMigrationProps *props);
 
 virDomainPtr
 libxlDomainMigrationFinish(virConnectPtr dconn,
Index: libvirt-1.2.18.4/tools/virsh-domain.c
===================================================================
--- libvirt-1.2.18.4.orig/tools/virsh-domain.c
+++ libvirt-1.2.18.4/tools/virsh-domain.c
@@ -9940,6 +9940,22 @@ static const vshCmdOptDef opts_migrate[]
      .type = VSH_OT_STRING,
      .help = N_("comma separated list of disks to be migrated")
     },
+    {.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}
 };
 
@@ -9959,6 +9975,7 @@ doMigrate(void *opaque)
     int nparams = 0;
     int maxparams = 0;
     virConnectPtr dconn = data->dconn;
+    unsigned int uint_opt = 0;
 
     sigemptyset(&sigmask);
     sigaddset(&sigmask, SIGINT);
@@ -10018,6 +10035,27 @@ doMigrate(void *opaque)
         VIR_FREE(val);
     }
 
+    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-1.2.18.4/tools/virsh.pod
===================================================================
--- libvirt-1.2.18.4.orig/tools/virsh.pod
+++ libvirt-1.2.18.4/tools/virsh.pod
@@ -1572,6 +1572,14 @@ I<--timeout> B<seconds> forces guest to
 that many seconds, and
 then the migration will complete offline. It can only be used with I<--live>.
 
+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.