xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging
@ 2013-03-28 14:43 Olaf Hering
  2013-03-28 14:43 ` [PATCH 1 of 9] tools/xc: print messages from xc_save with xc_report Olaf Hering
                   ` (9 more replies)
  0 siblings, 10 replies; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell


This series improves logging capabilities of xm migrate.
It also adds new options to xm/xl migrate to tweak the
max_iter/max_factor options passed to xc_domain_save. Being able to
tweak those knobs helps with migrating large and busy guests.

v3:
 - update "tools/xc: rework xc_save.c:switch_qemu_logdirty" v1 -> v2
 - add "tools/libxc: print stats if migration is aborted"
 - add "tools: set number of dirty pages during migration"
 - add "tools: notify restore to hangup during migration --abort_if_busy"

v2:
 - update "tools: set migration constraints from cmdline" v6 -> v7
 - add "tools/xend: move assert to exception block"
 - this iteration is not runtime tested, yet

Changes:
tools/xc: print messages from xc_save with xc_report
tools/xc: document printf calls in xc_restore
tools/xc: rework xc_save.c:switch_qemu_logdirty
tools: set migration constraints from cmdline
tools: add xm migrate --log_progress option
tools/xend: move assert to exception block
tools/libxc: print stats if migration is aborted
tools: set number of dirty pages during migration
tools: notify restore to hangup during migration --abort_if_busy

 docs/man/xl.pod.1                                    |   20 +++
 tools/libxc/Makefile                                 |    2 
 tools/libxc/xc_domain_restore.c                      |    4 
 tools/libxc/xc_domain_save.c                         |   20 ++-
 tools/libxc/xc_nomigrate.c                           |    2 
 tools/libxc/xc_private.h                             |    1 
 tools/libxc/xenguest.h                               |    4 
 tools/libxc/xg_save_restore.h                        |    1 
 tools/libxl/Makefile                                 |    2 
 tools/libxl/libxl.c                                  |   13 +-
 tools/libxl/libxl.h                                  |   22 +++
 tools/libxl/libxl_dom.c                              |    1 
 tools/libxl/libxl_internal.h                         |    4 
 tools/libxl/libxl_save_callout.c                     |    5 
 tools/libxl/libxl_save_helper.c                      |    5 
 tools/libxl/xl_cmdimpl.c                             |   41 +++++-
 tools/libxl/xl_cmdtable.c                            |   21 ++-
 tools/python/xen/lowlevel/checkpoint/libcheckpoint.c |    2 
 tools/python/xen/xend/XendCheckpoint.py              |   26 +++-
 tools/python/xen/xend/XendDomain.py                  |   14 ++
 tools/python/xen/xend/XendDomainInfo.py              |   16 ++
 tools/python/xen/xm/migrate.py                       |   26 ++++
 tools/xcutils/xc_restore.c                           |    1 
 tools/xcutils/xc_save.c                              |  123 ++++++++++---------
 24 files changed, 288 insertions(+), 88 deletions(-)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1 of 9] tools/xc: print messages from xc_save with xc_report
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-03-28 14:43 ` [PATCH 2 of 9] tools/xc: document printf calls in xc_restore Olaf Hering
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481323 -3600
# Node ID 73c20d36304349ecb58033d7ec8f5922c74cab7f
# Parent  75942bb6768f0fe98a210c2269734a662eb3aab3
tools/xc: print messages from xc_save with xc_report

Make use of xc_report in xc_save to log also pid if some error occoured.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 75942bb6768f -r 73c20d363043 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -119,6 +119,7 @@ void xc_report_progress_step(xc_interfac
 
 /* anamorphic macros:  struct xc_interface *xch  must be in scope */
 
+#define WPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_WARN,0, _f , ## _a)
 #define IPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_INFO,0, _f , ## _a)
 #define DPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DETAIL,0, _f , ## _a)
 #define DBGPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DEBUG,0, _f , ## _a)
diff -r 75942bb6768f -r 73c20d363043 tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c
+++ b/tools/xcutils/xc_save.c
@@ -7,6 +7,7 @@
  *
  */
 
+#include <unistd.h>
 #include <err.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -19,6 +20,7 @@
 #include <fcntl.h>
 #include <err.h>
 
+#include <xc_private.h>
 #include <xenstore.h>
 #include <xenctrl.h>
 #include <xenguest.h>
@@ -51,16 +53,17 @@ static int compat_suspend(void)
  * receive the acknowledgement from the subscribe event channel. */
 static int evtchn_suspend(void)
 {
+    xc_interface *xch = si.xch;
     int rc;
 
     rc = xc_evtchn_notify(si.xce, si.suspend_evtchn);
     if (rc < 0) {
-        warnx("failed to notify suspend request channel: %d", rc);
+        WPRINTF("failed to notify suspend request channel: %d", rc);
         return 0;
     }
 
-    if (xc_await_suspend(si.xch, si.xce, si.suspend_evtchn) < 0) {
-        warnx("suspend failed");
+    if (xc_await_suspend(xch, si.xce, si.suspend_evtchn) < 0) {
+        WPRINTF("suspend failed");
         return 0;
     }
 
@@ -104,20 +107,27 @@ static int suspend(void* data)
 
 static int switch_qemu_logdirty(int domid, unsigned int enable, void *data)
 {
+    xc_interface *xch = si.xch;
     struct xs_handle *xs;
     char *path, *p, *ret_str, *cmd_str, **watch;
     unsigned int len;
     struct timeval tv;
     fd_set fdset;
 
-    if ((xs = xs_daemon_open()) == NULL)
-        errx(1, "Couldn't contact xenstore");
-    if (!(path = strdup("/local/domain/0/device-model/")))
-        errx(1, "can't get domain path in store");
+    if ((xs = xs_daemon_open()) == NULL) {
+        PERROR("Couldn't contact xenstore");
+        exit(1);
+    }
+    if (!(path = strdup("/local/domain/0/device-model/"))) {
+        PERROR("can't get domain path in store");
+        exit(1);
+    }
     if (!(path = realloc(path, strlen(path) 
                          + 10 
-                         + strlen("/logdirty/cmd") + 1)))
-        errx(1, "no memory for constructing xenstore path");
+                         + strlen("/logdirty/cmd") + 1))) {
+        PERROR("no memory for constructing xenstore path");
+        exit(1);
+    }
     snprintf(path + strlen(path), 11, "%i", domid);
     strcat(path, "/logdirty/");
     p = path + strlen(path);
@@ -126,16 +136,22 @@ static int switch_qemu_logdirty(int domi
     /* Watch for qemu's return value */
     strcpy(p, "ret");
     if (!xs_watch(xs, path, "qemu-logdirty-ret"))
-        errx(1, "can't set watch in store (%s)\n", path);
+    {
+        ERROR("can't set watch in store (%s)\n", path);
+        exit(1);
+    }
 
-    if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable")))
-        errx(1, "can't get logdirty cmd path in store");
+    if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable"))) {
+        PERROR("can't get logdirty cmd path in store");
+        exit(1);
+    }
 
     /* Tell qemu that we want it to start logging dirty page to Xen */
     strcpy(p, "cmd");
-    if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str)))
-        errx(1, "can't write  to store path (%s)\n",
-             path);
+    if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str))) {
+        PERROR("can't write  to store path (%s)\n", path);
+        exit(1);
+    }
 
     /* Wait a while for qemu to signal that it has service logdirty command */
  read_again:
@@ -144,8 +160,10 @@ static int switch_qemu_logdirty(int domi
     FD_ZERO(&fdset);
     FD_SET(xs_fileno(xs), &fdset);
 
-    if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1)
-        errx(1, "timed out waiting for qemu logdirty response.\n");
+    if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) {
+        PERROR("timed out waiting for qemu logdirty response.\n");
+        exit(1);
+    }
 
     watch = xs_read_watch(xs, &len);
     free(watch);
@@ -166,6 +184,7 @@ static int switch_qemu_logdirty(int domi
 int
 main(int argc, char **argv)
 {
+    xc_interface *xch;
     unsigned int maxit, max_f, lflags;
     int io_fd, ret, port;
     struct save_callbacks callbacks;
@@ -186,26 +205,26 @@ main(int argc, char **argv)
     lvl = si.flags & XCFLAGS_DEBUG ? XTL_DEBUG: XTL_DETAIL;
     lflags = XTL_STDIOSTREAM_SHOW_PID | XTL_STDIOSTREAM_HIDE_PROGRESS;
     l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags);
-    si.xch = xc_interface_open(l, 0, 0);
+    xch = si.xch = xc_interface_open(l, 0, 0);
     if (!si.xch)
-        errx(1, "failed to open control interface");
+        errx(1, "[%lu] failed to open control interface", (unsigned long)getpid());
 
     si.xce = xc_evtchn_open(NULL, 0);
     if (si.xce == NULL)
-        warnx("failed to open event channel handle");
+        WPRINTF("failed to open event channel handle");
     else
     {
         port = xs_suspend_evtchn_port(si.domid);
 
         if (port < 0)
-            warnx("failed to get the suspend evtchn port\n");
+            WPRINTF("failed to get the suspend evtchn port\n");
         else
         {
             si.suspend_evtchn =
               xc_suspend_evtchn_init(si.xch, si.xce, si.domid, port);
 
             if (si.suspend_evtchn < 0)
-                warnx("suspend event channel initialization failed, "
+                WPRINTF("suspend event channel initialization failed, "
                        "using slow path");
         }
     }

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2 of 9] tools/xc: document printf calls in xc_restore
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
  2013-03-28 14:43 ` [PATCH 1 of 9] tools/xc: print messages from xc_save with xc_report Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-03-28 14:43 ` [PATCH 3 of 9] tools/xc: rework xc_save.c:switch_qemu_logdirty Olaf Hering
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481332 -3600
# Node ID 2b4e40439417fa09c3a6a49565a161c6dc4ddc15
# Parent  73c20d36304349ecb58033d7ec8f5922c74cab7f
tools/xc: document printf calls in xc_restore

... to prevent conversion to DPRINTF.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 73c20d363043 -r 2b4e40439417 tools/xcutils/xc_restore.c
--- a/tools/xcutils/xc_restore.c
+++ b/tools/xcutils/xc_restore.c
@@ -56,6 +56,7 @@ main(int argc, char **argv)
 
     if ( ret == 0 )
     {
+        /* xend expects this output, part of protocol */
 	printf("store-mfn %li\n", store_mfn);
         if ( !hvm )
             printf("console-mfn %li\n", console_mfn);

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 3 of 9] tools/xc: rework xc_save.c:switch_qemu_logdirty
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
  2013-03-28 14:43 ` [PATCH 1 of 9] tools/xc: print messages from xc_save with xc_report Olaf Hering
  2013-03-28 14:43 ` [PATCH 2 of 9] tools/xc: document printf calls in xc_restore Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-04-08 17:12   ` Ian Jackson
  2013-03-28 14:43 ` [PATCH 4 of 9] tools: set migration constraints from cmdline Olaf Hering
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481337 -3600
# Node ID 99d809a358d9748d97044cc5721a028cffbcf5fe
# Parent  2b4e40439417fa09c3a6a49565a161c6dc4ddc15
tools/xc: rework xc_save.c:switch_qemu_logdirty

Rework code in switch_qemu_logdirty, fix also memleak.

v2:
 - use DPRINTF to print watchpoint result

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 2b4e40439417 -r 99d809a358d9 tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c
+++ b/tools/xcutils/xc_save.c
@@ -7,6 +7,7 @@
  *
  */
 
+#define _GNU_SOURCE
 #include <unistd.h>
 #include <err.h>
 #include <stdlib.h>
@@ -109,8 +110,10 @@ static int switch_qemu_logdirty(int domi
 {
     xc_interface *xch = si.xch;
     struct xs_handle *xs;
-    char *path, *p, *ret_str, *cmd_str, **watch;
+    char *path, *dir_p, *ret_str, **watch;
+    const char *cmd_str;
     unsigned int len;
+    int ret, again;
     struct timeval tv;
     fd_set fdset;
 
@@ -118,65 +121,56 @@ static int switch_qemu_logdirty(int domi
         PERROR("Couldn't contact xenstore");
         exit(1);
     }
-    if (!(path = strdup("/local/domain/0/device-model/"))) {
-        PERROR("can't get domain path in store");
+
+    ret = asprintf(&path, "/local/domain/0/device-model/%i/logdirty/ret", domid);
+    if (ret < 0) {
+        ERROR("Couldn't construct xenstore path");
         exit(1);
     }
-    if (!(path = realloc(path, strlen(path) 
-                         + 10 
-                         + strlen("/logdirty/cmd") + 1))) {
-        PERROR("no memory for constructing xenstore path");
-        exit(1);
-    }
-    snprintf(path + strlen(path), 11, "%i", domid);
-    strcat(path, "/logdirty/");
-    p = path + strlen(path);
-
+    /* Pointer to directory */
+    dir_p = path + ret - 3;
 
     /* Watch for qemu's return value */
-    strcpy(p, "ret");
-    if (!xs_watch(xs, path, "qemu-logdirty-ret"))
-    {
-        ERROR("can't set watch in store (%s)\n", path);
+    if (!xs_watch(xs, path, "qemu-logdirty-ret")) {
+        PERROR("can't set watch in store (%s)", path);
         exit(1);
     }
 
-    if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable"))) {
-        PERROR("can't get logdirty cmd path in store");
+    cmd_str = enable ? "enable" : "disable";
+
+    /* Tell qemu that we want it to start logging dirty pages to Xen */
+    strcpy(dir_p, "cmd");
+    if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str))) {
+        PERROR("can't write to store path (%s)", path);
         exit(1);
     }
 
-    /* Tell qemu that we want it to start logging dirty page to Xen */
-    strcpy(p, "cmd");
-    if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str))) {
-        PERROR("can't write  to store path (%s)\n", path);
-        exit(1);
-    }
+    /* Restore initial path */
+    strcpy(dir_p, "ret");
+    /* Wait a while for qemu to signal that it has serviced logdirty command */
+    do {
+        tv.tv_sec = 5;
+        tv.tv_usec = 0;
+        FD_ZERO(&fdset);
+        FD_SET(xs_fileno(xs), &fdset);
+        errno = 0;
 
-    /* Wait a while for qemu to signal that it has service logdirty command */
- read_again:
-    tv.tv_sec = 5;
-    tv.tv_usec = 0;
-    FD_ZERO(&fdset);
-    FD_SET(xs_fileno(xs), &fdset);
-
-    if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) {
-        PERROR("timed out waiting for qemu logdirty response.\n");
-        exit(1);
-    }
-
-    watch = xs_read_watch(xs, &len);
-    free(watch);
-
-    strcpy(p, "ret");
-    ret_str = xs_read(xs, XBT_NULL, path, &len);
-    if (ret_str == NULL || strcmp(ret_str, cmd_str))
+        if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) {
+            PERROR("timed out waiting for qemu logdirty response.");
+            exit(1);
+        }
+    
+        watch = xs_read_watch(xs, &len);
+        free(watch);
+    
+        ret_str = xs_read(xs, XBT_NULL, path, &len);
+        again = ret_str == NULL || strcmp(ret_str, cmd_str);
+        DPRINTF("Got '%s' from logdirty%s.\n", ret_str, again ? ", retrying" : "");
+        free(ret_str);
         /* Watch fired but value is not yet right */
-        goto read_again;
+    } while (again);
 
     free(path);
-    free(cmd_str);
-    free(ret_str);
 
     return 0;
 }

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 4 of 9] tools: set migration constraints from cmdline
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
                   ` (2 preceding siblings ...)
  2013-03-28 14:43 ` [PATCH 3 of 9] tools/xc: rework xc_save.c:switch_qemu_logdirty Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-04-08 17:16   ` Ian Jackson
  2013-03-28 14:43 ` [PATCH 5 of 9] tools: add xm migrate --log_progress option Olaf Hering
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481348 -3600
# Node ID f6fedb087442fb54e31d0f8a233a1ce51d787e22
# Parent  99d809a358d9748d97044cc5721a028cffbcf5fe
tools: set migration constraints from cmdline

Add new options to xm/xl migrate to control the process of migration.
The intention is to optionally abort the migration if it takes too long
to migrate a busy guest due to the high number of new dirty pages.
Currently the guest is suspended to transfer the remaining dirty pages.
This transfer can take a long time, which can confuse the guest if its
suspended for too long.
The new options allow to override the built-in default values, which are
not changed by this patch.

--max_iters <number>  Number of iterations before final suspend (default: 30)

--max_factor <factor> Max amount of memory to transfer before final suspend (default: 3*RAM)

--abort_if_busy       Abort migration instead of doing final suspend.



The changes to libxl change the API, handle LIBXL_API_VERSION == 0x040200.

v7:
  - remove short options
  - update description of --abort_if_busy in xl.1
  - extend description of --abort_if_busy in xl help
  - add comment to libxl_domain_suspend declaration, props is optional

v6:
 - update the LIBXL_API_VERSION handling for libxl_domain_suspend
   change it to an inline function if LIBXL_API_VERSION is defined to 4.2.0
 - rename libxl_save_properties to libxl_domain_suspend_properties
 - rename ->xlflags to ->flags within that struct

v5:
 - adjust libxl_domain_suspend prototype, move flags, max_iters,
   max_factor into a new, optional struct libxl_save_properties
 - rename XCFLAGS_DOMSAVE_NOSUSPEND to XCFLAGS_DOMSAVE_ABORT_IF_BUSY
 - rename LIBXL_SUSPEND_NO_FINAL_SUSPEND to LIBXL_SUSPEND_ABORT_IF_BUSY
 - rename variables no_suspend to abort_if_busy
 - rename option -N/--no_suspend to -A/--abort_if_busy
 - update xl.1, extend description of -A option

v4:
 - update default for no_suspend from None to 0 in XendCheckpoint.py:save
 - update logoutput in setMigrateConstraints
 - change xm migrate defaults from None to 0
 - add new options to xl.1
 - fix syntax error in XendDomain.py:domain_migrate_constraints_set
 - fix xm migrate -N option name to match xl migrate

v3:
 - move logic errors in libxl__domain_suspend and fixed help text in
   cmd_table to separate patches
 - fix syntax error in XendCheckpoint.py
 - really pass max_iters and max_factor in libxl__xc_domain_save
 - make libxl_domain_suspend_0x040200 declaration globally visible
 - bump libxenlight.so SONAME from 2.0 to 2.1 due to changed
   libxl_domain_suspend

v2:
 - use LIBXL_API_VERSION and define libxl_domain_suspend_0x040200
 - fix logic error in min_reached check in xc_domain_save
 - add longopts
 - update --help text
 - correct description of migrate --help text

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 99d809a358d9 -r f6fedb087442 docs/man/xl.pod.1
--- a/docs/man/xl.pod.1
+++ b/docs/man/xl.pod.1
@@ -391,6 +391,21 @@ Send <config> instead of config file fro
 
 Print huge (!) amount of debug during the migration process.
 
+=item B<--max_iters> I<number>
+
+Number of iterations before final suspend (default: 30)
+
+=item B<--max_factor> I<factor>
+
+Max amount of memory to transfer before final suspend (default: 3*RAM)
+
+=item B<--abort_if_busy>
+
+Abort migration instead of doing final suspend/transfer/resume if the
+guest has still dirty pages after the number of iterations and/or the
+amount of RAM transferred. This avoids long periods of time where the
+guest is suspended.
+
 =back
 
 =item B<remus> [I<OPTIONS>] I<domain-id> I<host>
diff -r 99d809a358d9 -r f6fedb087442 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -804,6 +804,7 @@ int xc_domain_save(xc_interface *xch, in
     int rc = 1, frc, i, j, last_iter = 0, iter = 0;
     int live  = (flags & XCFLAGS_LIVE);
     int debug = (flags & XCFLAGS_DEBUG);
+    int abort_if_busy = (flags & XCFLAGS_DOMSAVE_ABORT_IF_BUSY);
     int superpages = !!hvm;
     int race = 0, sent_last_iter, skip_this_iter = 0;
     unsigned int sent_this_iter = 0;
@@ -1527,10 +1528,20 @@ int xc_domain_save(xc_interface *xch, in
 
         if ( live )
         {
+            int min_reached = sent_this_iter + skip_this_iter < 50;
             if ( (iter >= max_iters) ||
-                 (sent_this_iter+skip_this_iter < 50) ||
+                 min_reached ||
                  (total_sent > dinfo->p2m_size*max_factor) )
             {
+                if ( !min_reached && abort_if_busy )
+                {
+                    ERROR("Live migration aborted, as requested. (guest too busy?)"
+                     " total_sent %lu iter %d, max_iters %u max_factor %u",
+                      total_sent, iter, max_iters, max_factor);
+                    rc = 1;
+                    goto out;
+                }
+
                 DPRINTF("Start last iteration\n");
                 last_iter = 1;
 
diff -r 99d809a358d9 -r f6fedb087442 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -28,6 +28,7 @@
 #define XCFLAGS_HVM       (1 << 2)
 #define XCFLAGS_STDVGA    (1 << 3)
 #define XCFLAGS_CHECKPOINT_COMPRESS    (1 << 4)
+#define XCFLAGS_DOMSAVE_ABORT_IF_BUSY  (1 << 5)
 
 #define X86_64_B_SIZE   64 
 #define X86_32_B_SIZE   32
diff -r 99d809a358d9 -r f6fedb087442 tools/libxl/Makefile
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -5,7 +5,7 @@
 XEN_ROOT = $(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-MAJOR = 2.0
+MAJOR = 2.1
 MINOR = 0
 
 XLUMAJOR = 1.0
diff -r 99d809a358d9 -r f6fedb087442 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -756,7 +756,8 @@ static void domain_suspend_cb(libxl__egc
 
 }
 
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+                         const libxl_domain_suspend_properties *props,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
@@ -777,8 +778,13 @@ int libxl_domain_suspend(libxl_ctx *ctx,
     dss->domid = domid;
     dss->fd = fd;
     dss->type = type;
-    dss->live = flags & LIBXL_SUSPEND_LIVE;
-    dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+    if (props) {
+        dss->live = props->flags & LIBXL_SUSPEND_LIVE;
+        dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
+        dss->max_iters = props->max_iters;
+        dss->max_factor = props->max_factor;
+        dss->xlflags = props->flags;
+    }
 
     libxl__domain_suspend(egc, dss);
     return AO_INPROGRESS;
diff -r 99d809a358d9 -r f6fedb087442 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -507,12 +507,31 @@ int libxl_domain_create_restore(libxl_ct
 void libxl_domain_config_init(libxl_domain_config *d_config);
 void libxl_domain_config_dispose(libxl_domain_config *d_config);
 
+typedef struct {
+    int flags; /* LIBXL_SUSPEND_* */
+    int max_iters;
+    int max_factor;
+} libxl_domain_suspend_properties;
+
 int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
-                         int flags, /* LIBXL_SUSPEND_* */
+                         const libxl_domain_suspend_properties *props, /* optional */
                          const libxl_asyncop_how *ao_how)
                          LIBXL_EXTERNAL_CALLERS_ONLY;
+#ifdef LIBXL_API_VERSION
+#if LIBXL_API_VERSION == 0x040200
+static inline int libxl_domain_suspend_0x040200(libxl_ctx *ctx, uint32_t domid, int fd,
+                          int flags, const libxl_asyncop_how *ao_how)
+{
+    libxl_domain_suspend_properties props = { .flags = flags };
+    return libxl_domain_suspend(ctx, domid, fd, &props, ao_how);
+}
+#define libxl_domain_suspend libxl_domain_suspend_0x040200
+#endif
+#endif
+
 #define LIBXL_SUSPEND_DEBUG 1
 #define LIBXL_SUSPEND_LIVE 2
+#define LIBXL_SUSPEND_ABORT_IF_BUSY 4
 
 /* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
  *   If this parameter is true, use co-operative resume. The guest
diff -r 99d809a358d9 -r f6fedb087442 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -1297,6 +1297,7 @@ void libxl__domain_suspend(libxl__egc *e
 
     dss->xcflags = (live ? XCFLAGS_LIVE : 0)
           | (debug ? XCFLAGS_DEBUG : 0)
+          | (dss->xlflags & LIBXL_SUSPEND_ABORT_IF_BUSY ? XCFLAGS_DOMSAVE_ABORT_IF_BUSY : 0)
           | (dss->hvm ? XCFLAGS_HVM : 0);
 
     dss->suspend_eventchn = -1;
diff -r 99d809a358d9 -r f6fedb087442 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2249,6 +2249,9 @@ struct libxl__domain_suspend_state {
     xc_evtchn *xce; /* event channel handle */
     int suspend_eventchn;
     int hvm;
+    int max_iters;
+    int max_factor;
+    int xlflags;
     int xcflags;
     int guest_responded;
     const char *dm_savefile;
diff -r 99d809a358d9 -r f6fedb087442 tools/libxl/libxl_save_callout.c
--- a/tools/libxl/libxl_save_callout.c
+++ b/tools/libxl/libxl_save_callout.c
@@ -108,8 +108,8 @@ void libxl__xc_domain_save(libxl__egc *e
     }
 
     const unsigned long argnums[] = {
-        dss->domid, 0, 0, dss->xcflags, dss->hvm, vm_generationid_addr,
-        toolstack_data_fd, toolstack_data_len,
+        dss->domid, dss->max_iters, dss->max_factor, dss->xcflags, dss->hvm,
+        vm_generationid_addr, toolstack_data_fd, toolstack_data_len,
         cbflags,
     };
 
diff -r 99d809a358d9 -r f6fedb087442 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -3201,7 +3201,7 @@ static int save_domain(uint32_t domid, c
 
     save_domain_core_writeconfig(fd, filename, config_data, config_len);
 
-    int rc = libxl_domain_suspend(ctx, domid, fd, 0, NULL);
+    int rc = libxl_domain_suspend(ctx, domid, fd, NULL, NULL);
     close(fd);
 
     if (rc < 0)
@@ -3361,6 +3361,7 @@ static void migrate_do_preamble(int send
 }
 
 static void migrate_domain(uint32_t domid, const char *rune, int debug,
+                           int max_iters, int max_factor, int abort_if_busy,
                            const char *override_config_file)
 {
     pid_t child = -1;
@@ -3369,7 +3370,12 @@ static void migrate_domain(uint32_t domi
     char *away_domname;
     char rc_buf;
     uint8_t *config_data;
-    int config_len, flags = LIBXL_SUSPEND_LIVE;
+    int config_len;
+    libxl_domain_suspend_properties props = {
+        .flags = LIBXL_SUSPEND_LIVE,
+        .max_iters = max_iters,
+        .max_factor = max_factor,
+    };
 
     save_domain_core_begin(domid, override_config_file,
                            &config_data, &config_len);
@@ -3388,8 +3394,11 @@ static void migrate_domain(uint32_t domi
     xtl_stdiostream_adjust_flags(logger, XTL_STDIOSTREAM_HIDE_PROGRESS, 0);
 
     if (debug)
-        flags |= LIBXL_SUSPEND_DEBUG;
-    rc = libxl_domain_suspend(ctx, domid, send_fd, flags, NULL);
+        props.flags |= LIBXL_SUSPEND_DEBUG;
+    if (abort_if_busy)
+        props.flags |= LIBXL_SUSPEND_ABORT_IF_BUSY;
+
+    rc = libxl_domain_suspend(ctx, domid, send_fd, &props, NULL);
     if (rc) {
         fprintf(stderr, "migration sender: libxl_domain_suspend failed"
                 " (rc=%d)\n", rc);
@@ -3782,13 +3791,17 @@ int main_migrate(int argc, char **argv)
     char *rune = NULL;
     char *host;
     int opt, daemonize = 1, monitor = 1, debug = 0;
+    int max_iters = 0, max_factor = 0, abort_if_busy = 0;
     static struct option opts[] = {
         {"debug", 0, 0, 0x100},
+        {"max_iters", 1, 0, 0x101},
+        {"max_factor", 1, 0, 0x102},
+        {"abort_if_busy", 0, 0, 0x103},
         COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
-    SWITCH_FOREACH_OPT(opt, "FC:s:e", opts, "migrate", 2) {
+    SWITCH_FOREACH_OPT(opt, "FC:s:eM:m:A", opts, "migrate", 2) {
     case 'C':
         config_filename = optarg;
         break;
@@ -3805,6 +3818,15 @@ int main_migrate(int argc, char **argv)
     case 0x100:
         debug = 1;
         break;
+    case 0x101:
+        max_iters = atoi(optarg);
+        break;
+    case 0x102:
+        max_factor = atoi(optarg);
+        break;
+    case 0x103:
+        abort_if_busy = 1;
+        break;
     }
 
     domid = find_domain(argv[optind]);
@@ -3820,7 +3842,7 @@ int main_migrate(int argc, char **argv)
             return 1;
     }
 
-    migrate_domain(domid, rune, debug, config_filename);
+    migrate_domain(domid, rune, debug, max_iters, max_factor, abort_if_busy, config_filename);
     return 0;
 }
 
diff -r 99d809a358d9 -r f6fedb087442 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -147,14 +147,18 @@ struct cmd_spec cmd_table[] = {
       &main_migrate, 0, 1,
       "Migrate a domain to another host",
       "[options] <Domain> <host>",
-      "-h              Print this help.\n"
-      "-C <config>     Send <config> instead of config file from creation.\n"
-      "-s <sshcommand> Use <sshcommand> instead of ssh.  String will be passed\n"
-      "                to sh. If empty, run <host> instead of ssh <host> xl\n"
-      "                migrate-receive [-d -e]\n"
-      "-e              Do not wait in the background (on <host>) for the death\n"
-      "                of the domain.\n"
-      "--debug         Print huge (!) amount of debug during the migration process."
+      "-h                    Print this help.\n"
+      "-C <config>           Send <config> instead of config file from creation.\n"
+      "-s <sshcommand>       Use <sshcommand> instead of ssh.  String will be passed\n"
+      "                      to sh. If empty, run <host> instead of ssh <host> xl\n"
+      "                      migrate-receive [-d -e]\n"
+      "-e                    Do not wait in the background (on <host>) for the death\n"
+      "                      of the domain.\n"
+      "--debug               Print huge (!) amount of debug during the migration process.\n"
+      "--max_iters <number>  Number of iterations before final suspend (default: 30)\n"
+      "--max_factor <factor> Max amount of memory to transfer before final suspend (default: 3*RAM).\n"
+      "--abort_if_busy       Abort migration instead of doing final suspend, if number\n"
+      "                      of iterations or amount of transfered memory is exceeded."
     },
     { "dump-core",
       &main_dump_core, 0, 1,
diff -r 99d809a358d9 -r f6fedb087442 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py
+++ b/tools/python/xen/xend/XendCheckpoint.py
@@ -118,9 +118,19 @@ def save(fd, dominfo, network, live, dst
         # enabled. Passing "0" simply uses the defaults compiled into
         # libxenguest; see the comments and/or code in xc_linux_save() for
         # more information.
+        max_iters = dominfo.info.get('max_iters', "0")
+        max_factor = dominfo.info.get('max_factor', "0")
+        abort_if_busy = dominfo.info.get('abort_if_busy', "0")
+        if max_iters == "None":
+            max_iters = "0"
+        if max_factor == "None":
+            max_factor = "0"
+        if abort_if_busy == "None":
+            abort_if_busy = "0"
         cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd),
-               str(dominfo.getDomid()), "0", "0", 
-               str(int(live) | (int(hvm) << 2)) ]
+               str(dominfo.getDomid()),
+               max_iters, max_factor,
+               str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) ) ]
         log.debug("[xc_save]: %s", string.join(cmd))
 
         def saveInputHandler(line, tochild):
diff -r 99d809a358d9 -r f6fedb087442 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py
+++ b/tools/python/xen/xend/XendDomain.py
@@ -1832,6 +1832,18 @@ class XendDomain:
             log.exception(ex)
             raise XendError(str(ex))
 
+    def domain_migrate_constraints_set(self, domid, max_iters, max_factor, abort_if_busy):
+        """Set the Migrate Constraints of this domain.
+        @param domid: Domain ID or Name
+        @param max_iters: Number of iterations before final suspend
+        @param max_factor: Max amount of memory to transfer before final suspend
+        @param abort_if_busy: Abort migration instead of doing final suspend
+        """
+        dominfo = self.domain_lookup_nr(domid)
+        if not dominfo:
+            raise XendInvalidDomain(str(domid))
+        dominfo.setMigrateConstraints(max_iters, max_factor, abort_if_busy)
+
     def domain_maxmem_set(self, domid, mem):
         """Set the memory limit for a domain.
 
diff -r 99d809a358d9 -r f6fedb087442 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -1459,6 +1459,18 @@ class XendDomainInfo:
         pci_conf = self.info['devices'][dev_uuid][1]
         return map(pci_dict_to_bdf_str, pci_conf['devs'])
 
+    def setMigrateConstraints(self, max_iters, max_factor, abort_if_busy):
+        """Set the Migrate Constraints of this domain.
+        @param max_iters: Number of iterations before final suspend
+        @param max_factor: Max amount of memory to transfer before final suspend
+        @param abort_if_busy: Abort migration instead of doing final suspend
+        """
+        log.debug("Setting migration constraints of domain %s (%s) to '%s' '%s' '%s'.",
+                  self.info['name_label'], str(self.domid), max_iters, max_factor, abort_if_busy)
+        self.info['max_iters'] = str(max_iters)
+        self.info['max_factor'] = str(max_factor)
+        self.info['abort_if_busy'] = str(abort_if_busy)
+
     def setMemoryTarget(self, target):
         """Set the memory target of this domain.
         @param target: In MiB.
diff -r 99d809a358d9 -r f6fedb087442 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py
+++ b/tools/python/xen/xm/migrate.py
@@ -55,6 +55,18 @@ gopts.opt('change_home_server', short='c
           fn=set_true, default=0,
           use="Change home server for managed domains.")
 
+gopts.opt('max_iters',val='max_iters',
+          fn=set_int, default=0,
+          use="Number of iterations before final suspend (default: 30).")
+
+gopts.opt('max_factor', val='max_factor',
+          fn=set_int, default=0,
+          use="Max amount of memory to transfer before final suspend (default: 3*RAM).")
+
+gopts.opt('abort_if_busy',
+          fn=set_true, default=0,
+          use="Abort migration instead of doing final suspend.")
+
 def help():
     return str(gopts)
     
@@ -80,6 +92,10 @@ def main(argv):
         server.xenapi.VM.migrate(vm_ref, dst, bool(opts.vals.live),
                                  other_config)
     else:
+        server.xend.domain.migrate_constraints_set(dom,
+                                                   opts.vals.max_iters,
+                                                   opts.vals.max_factor,
+                                                   opts.vals.abort_if_busy)
         server.xend.domain.migrate(dom, dst, opts.vals.live,
                                    opts.vals.port,
                                    opts.vals.node,

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 5 of 9] tools: add xm migrate --log_progress option
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
                   ` (3 preceding siblings ...)
  2013-03-28 14:43 ` [PATCH 4 of 9] tools: set migration constraints from cmdline Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-03-28 14:43 ` [PATCH 6 of 9] tools/xend: move assert to exception block Olaf Hering
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481357 -3600
# Node ID 9ad7bb166540392657f049441c88ae727e1526b9
# Parent  f6fedb087442fb54e31d0f8a233a1ce51d787e22
tools: add xm migrate --log_progress option

xc_domain_save does print progress messages. These verbose messages are
disabled per default to avoid flood in xend.log. Sometimes it is helpful
to see progress when migrating large and busy guests. So add a new
option to xm migrate to actually enable the printing of progress
messsages.

xl migrate is not modified with this change because it does not use the
stdio logger.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r f6fedb087442 -r 9ad7bb166540 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -29,6 +29,7 @@
 #define XCFLAGS_STDVGA    (1 << 3)
 #define XCFLAGS_CHECKPOINT_COMPRESS    (1 << 4)
 #define XCFLAGS_DOMSAVE_ABORT_IF_BUSY  (1 << 5)
+#define XCFLAGS_PROGRESS  (1 << 6)
 
 #define X86_64_B_SIZE   64 
 #define X86_32_B_SIZE   32
diff -r f6fedb087442 -r 9ad7bb166540 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py
+++ b/tools/python/xen/xend/XendCheckpoint.py
@@ -121,16 +121,19 @@ def save(fd, dominfo, network, live, dst
         max_iters = dominfo.info.get('max_iters', "0")
         max_factor = dominfo.info.get('max_factor', "0")
         abort_if_busy = dominfo.info.get('abort_if_busy', "0")
+        log_save_progress = dominfo.info.get('log_save_progress', "0")
         if max_iters == "None":
             max_iters = "0"
         if max_factor == "None":
             max_factor = "0"
         if abort_if_busy == "None":
             abort_if_busy = "0"
+        if log_save_progress == "None":
+            log_save_progress = "0"
         cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd),
                str(dominfo.getDomid()),
                max_iters, max_factor,
-               str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) ) ]
+               str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) | (int(log_save_progress) << 6) ) ]
         log.debug("[xc_save]: %s", string.join(cmd))
 
         def saveInputHandler(line, tochild):
diff -r f6fedb087442 -r 9ad7bb166540 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py
+++ b/tools/python/xen/xend/XendDomain.py
@@ -1832,17 +1832,18 @@ class XendDomain:
             log.exception(ex)
             raise XendError(str(ex))
 
-    def domain_migrate_constraints_set(self, domid, max_iters, max_factor, abort_if_busy):
+    def domain_migrate_constraints_set(self, domid, max_iters, max_factor, abort_if_busy, log_save_progress):
         """Set the Migrate Constraints of this domain.
         @param domid: Domain ID or Name
         @param max_iters: Number of iterations before final suspend
         @param max_factor: Max amount of memory to transfer before final suspend
         @param abort_if_busy: Abort migration instead of doing final suspend
+        @param log_save_progress: Log progress of migrate to xend.log
         """
         dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
-        dominfo.setMigrateConstraints(max_iters, max_factor, abort_if_busy)
+        dominfo.setMigrateConstraints(max_iters, max_factor, abort_if_busy, log_save_progress)
 
     def domain_maxmem_set(self, domid, mem):
         """Set the memory limit for a domain.
diff -r f6fedb087442 -r 9ad7bb166540 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -1459,17 +1459,19 @@ class XendDomainInfo:
         pci_conf = self.info['devices'][dev_uuid][1]
         return map(pci_dict_to_bdf_str, pci_conf['devs'])
 
-    def setMigrateConstraints(self, max_iters, max_factor, abort_if_busy):
+    def setMigrateConstraints(self, max_iters, max_factor, abort_if_busy, log_save_progress):
         """Set the Migrate Constraints of this domain.
         @param max_iters: Number of iterations before final suspend
         @param max_factor: Max amount of memory to transfer before final suspend
         @param abort_if_busy: Abort migration instead of doing final suspend
+        @param log_save_progress: Log progress of migrate to xend.log
         """
         log.debug("Setting migration constraints of domain %s (%s) to '%s' '%s' '%s'.",
                   self.info['name_label'], str(self.domid), max_iters, max_factor, abort_if_busy)
         self.info['max_iters'] = str(max_iters)
         self.info['max_factor'] = str(max_factor)
         self.info['abort_if_busy'] = str(abort_if_busy)
+        self.info['log_save_progress'] = str(log_save_progress)
 
     def setMemoryTarget(self, target):
         """Set the memory target of this domain.
diff -r f6fedb087442 -r 9ad7bb166540 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py
+++ b/tools/python/xen/xm/migrate.py
@@ -67,6 +67,10 @@ gopts.opt('abort_if_busy',
           fn=set_true, default=0,
           use="Abort migration instead of doing final suspend.")
 
+gopts.opt('log_progress',
+          fn=set_true, default=0,
+          use="Log progress of migration to xend.log")
+
 def help():
     return str(gopts)
     
@@ -95,7 +99,8 @@ def main(argv):
         server.xend.domain.migrate_constraints_set(dom,
                                                    opts.vals.max_iters,
                                                    opts.vals.max_factor,
-                                                   opts.vals.abort_if_busy)
+                                                   opts.vals.abort_if_busy,
+                                                   opts.vals.log_progress)
         server.xend.domain.migrate(dom, dst, opts.vals.live,
                                    opts.vals.port,
                                    opts.vals.node,
diff -r f6fedb087442 -r 9ad7bb166540 tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c
+++ b/tools/xcutils/xc_save.c
@@ -197,7 +197,8 @@ main(int argc, char **argv)
     si.suspend_evtchn = -1;
 
     lvl = si.flags & XCFLAGS_DEBUG ? XTL_DEBUG: XTL_DETAIL;
-    lflags = XTL_STDIOSTREAM_SHOW_PID | XTL_STDIOSTREAM_HIDE_PROGRESS;
+    lflags = XTL_STDIOSTREAM_SHOW_PID;
+    lflags |= si.flags & XCFLAGS_PROGRESS ? 0 : XTL_STDIOSTREAM_HIDE_PROGRESS;
     l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags);
     xch = si.xch = xc_interface_open(l, 0, 0);
     if (!si.xch)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 6 of 9] tools/xend: move assert to exception block
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
                   ` (4 preceding siblings ...)
  2013-03-28 14:43 ` [PATCH 5 of 9] tools: add xm migrate --log_progress option Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-04-08 17:13   ` Ian Jackson
  2013-03-28 14:43 ` [PATCH 7 of 9] tools/libxc: print stats if migration is aborted Olaf Hering
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481362 -3600
# Node ID 586d440c496f2f873bb2bd702032d6cc37ffdf54
# Parent  9ad7bb166540392657f049441c88ae727e1526b9
tools/xend: move assert to exception block

The two assert in restore trigger sometimes after hundreds of
migrations. If they trigger the destination host will not destroy the
newly created, still empty guest. After a second migration attempt to
this host there will be two guets with the same name and uuid. This
situation is poorly handled by the xm tools.
With this change the guest will be destroyed.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 9ad7bb166540 -r 586d440c496f tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py
+++ b/tools/python/xen/xend/XendCheckpoint.py
@@ -262,9 +262,6 @@ def restore(xd, fd, dominfo = None, paus
     store_port   = dominfo.getStorePort()
     console_port = dominfo.getConsolePort()
 
-    assert store_port
-    assert console_port
-
     # if hvm, pass mem size to calculate the store_mfn
     if is_hvm:
         apic = int(dominfo.info['platform'].get('apic', 0))
@@ -276,6 +273,9 @@ def restore(xd, fd, dominfo = None, paus
         pae  = 0
 
     try:
+        assert store_port
+        assert console_port
+
         restore_image = image.create(dominfo, dominfo.info)
         memory = restore_image.getRequiredAvailableMemory(
             dominfo.info['memory_dynamic_max'] / 1024)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 7 of 9] tools/libxc: print stats if migration is aborted
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
                   ` (5 preceding siblings ...)
  2013-03-28 14:43 ` [PATCH 6 of 9] tools/xend: move assert to exception block Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-03-28 14:43 ` [PATCH 8 of 9] tools: set number of dirty pages during migration Olaf Hering
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481367 -3600
# Node ID 82ff5fb38a092a4b162da90ad0b4d295f18ace13
# Parent  586d440c496f2f873bb2bd702032d6cc37ffdf54
tools/libxc: print stats if migration is aborted

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 586d440c496f -r 82ff5fb38a09 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -1538,6 +1538,7 @@ int xc_domain_save(xc_interface *xch, in
                     ERROR("Live migration aborted, as requested. (guest too busy?)"
                      " total_sent %lu iter %d, max_iters %u max_factor %u",
                       total_sent, iter, max_iters, max_factor);
+                    print_stats(xch, dom, sent_this_iter, &time_stats, &shadow_stats, 1);
                     rc = 1;
                     goto out;
                 }

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 8 of 9] tools: set number of dirty pages during migration
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
                   ` (6 preceding siblings ...)
  2013-03-28 14:43 ` [PATCH 7 of 9] tools/libxc: print stats if migration is aborted Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-03-28 14:43 ` [PATCH 9 of 9] tools: notify restore to hangup during migration --abort_if_busy Olaf Hering
  2013-04-08 17:12 ` [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Ian Jackson
  9 siblings, 0 replies; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481734 -3600
# Node ID 4bf71e887b838dd643399b8b8a65406d5f8eb94f
# Parent  82ff5fb38a092a4b162da90ad0b4d295f18ace13
tools: set number of dirty pages during migration

If a guest is really busy it will not reach the low number of remaining
50 dirty pages for the final suspend. As a result the guest is either
suspendend for a long time during the final transfer, or if the number
of iterations is increased the migration will take a long time.

Add a new option xm/xl migrate --min_remaing <pages> to increase the
default from command line. The default of 50 is 200kb, which is
appearently an arbitrary number. With todays network speeds a larger
block of memory can be transfered quickly without causing too much
suspension time. This knob gives the admin the chance to adapt the
suspension time to the given workload.

The existing default of 50 pages is not altered by this change.

Due to the changed xc_domain_save API, bump SONAME of libxc to 4.3.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 82ff5fb38a09 -r 4bf71e887b83 docs/man/xl.pod.1
--- a/docs/man/xl.pod.1
+++ b/docs/man/xl.pod.1
@@ -399,6 +399,11 @@ Number of iterations before final suspen
 
 Max amount of memory to transfer before final suspend (default: 3*RAM)
 
+=item B<--min_remaining>
+
+Number of remaining dirty pages. If the number of dirty pages drops that 
+low the guest is suspended and the remaing pages are transfered to <host>.
+
 =item B<--abort_if_busy>
 
 Abort migration instead of doing final suspend/transfer/resume if the
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxc/Makefile
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -1,7 +1,7 @@
 XEN_ROOT = $(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-MAJOR    = 4.2
+MAJOR    = 4.3
 MINOR    = 0
 
 CTRL_SRCS-y       :=
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -43,6 +43,7 @@
 */
 #define DEF_MAX_ITERS   29   /* limit us to 30 times round loop   */
 #define DEF_MAX_FACTOR   3   /* never send more than 3x p2m_size  */
+#define DEF_MIN_REMAINING 50 /* low water mark of dirty pages */
 
 struct save_ctx {
     unsigned long hvirt_start; /* virtual starting address of the hypervisor */
@@ -794,7 +795,7 @@ static int save_tsc_info(xc_interface *x
 }
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
-                   uint32_t max_factor, uint32_t flags,
+                   uint32_t max_factor, uint32_t min_remaining, uint32_t flags,
                    struct save_callbacks* callbacks, int hvm,
                    unsigned long vm_generationid_addr)
 {
@@ -905,6 +906,7 @@ int xc_domain_save(xc_interface *xch, in
     /* If no explicit control parameters given, use defaults */
     max_iters  = max_iters  ? : DEF_MAX_ITERS;
     max_factor = max_factor ? : DEF_MAX_FACTOR;
+    min_remaining = min_remaining ? : DEF_MIN_REMAINING;
 
     if ( !get_platform_info(xch, dom,
                             &ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, &dinfo->guest_width) )
@@ -1528,7 +1530,7 @@ int xc_domain_save(xc_interface *xch, in
 
         if ( live )
         {
-            int min_reached = sent_this_iter + skip_this_iter < 50;
+            int min_reached = sent_this_iter + skip_this_iter < min_remaining;
             if ( (iter >= max_iters) ||
                  min_reached ||
                  (total_sent > dinfo->p2m_size*max_factor) )
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxc/xc_nomigrate.c
--- a/tools/libxc/xc_nomigrate.c
+++ b/tools/libxc/xc_nomigrate.c
@@ -22,7 +22,7 @@
 #include <xenguest.h>
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
-                   uint32_t max_factor, uint32_t flags,
+                   uint32_t max_factor, uint32_t min_remaining, uint32_t flags,
                    struct save_callbacks* callbacks, int hvm,
                    unsigned long vm_generationid_addr)
 {
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -87,7 +87,7 @@ struct save_callbacks {
  * @return 0 on success, -1 on failure
  */
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
-                   uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
+                   uint32_t max_factor, uint32_t min_remaining, uint32_t flags /* XCFLAGS_xxx */,
                    struct save_callbacks* callbacks, int hvm,
                    unsigned long vm_generationid_addr);
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -783,6 +783,7 @@ int libxl_domain_suspend(libxl_ctx *ctx,
         dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
         dss->max_iters = props->max_iters;
         dss->max_factor = props->max_factor;
+        dss->min_remaining = props->min_remaining;
         dss->xlflags = props->flags;
     }
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -511,6 +511,7 @@ typedef struct {
     int flags; /* LIBXL_SUSPEND_* */
     int max_iters;
     int max_factor;
+    int min_remaining;
 } libxl_domain_suspend_properties;
 
 int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2251,6 +2251,7 @@ struct libxl__domain_suspend_state {
     int hvm;
     int max_iters;
     int max_factor;
+    int min_remaining;
     int xlflags;
     int xcflags;
     int guest_responded;
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl_save_callout.c
--- a/tools/libxl/libxl_save_callout.c
+++ b/tools/libxl/libxl_save_callout.c
@@ -108,7 +108,8 @@ void libxl__xc_domain_save(libxl__egc *e
     }
 
     const unsigned long argnums[] = {
-        dss->domid, dss->max_iters, dss->max_factor, dss->xcflags, dss->hvm,
+        dss->domid, dss->max_iters, dss->max_factor, dss->min_remaining,
+        dss->xcflags, dss->hvm,
         vm_generationid_addr, toolstack_data_fd, toolstack_data_len,
         cbflags,
     };
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl_save_helper.c
--- a/tools/libxl/libxl_save_helper.c
+++ b/tools/libxl/libxl_save_helper.c
@@ -221,6 +221,7 @@ int main(int argc, char **argv)
         uint32_t dom =             strtoul(NEXTARG,0,10);
         uint32_t max_iters =       strtoul(NEXTARG,0,10);
         uint32_t max_factor =      strtoul(NEXTARG,0,10);
+        uint32_t min_remaining =   strtoul(NEXTARG,0,10);
         uint32_t flags =           strtoul(NEXTARG,0,10);
         int hvm =                  atoi(NEXTARG);
         unsigned long genidad =    strtoul(NEXTARG,0,10);
@@ -235,8 +236,8 @@ int main(int argc, char **argv)
         helper_setcallbacks_save(&helper_save_callbacks, cbflags);
 
         startup("save");
-        r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags,
-                           &helper_save_callbacks, hvm, genidad);
+        r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, min_remaining,
+                           flags, &helper_save_callbacks, hvm, genidad);
         complete(r);
 
     } else if (!strcmp(mode,"--restore-domain")) {
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -3361,7 +3361,8 @@ static void migrate_do_preamble(int send
 }
 
 static void migrate_domain(uint32_t domid, const char *rune, int debug,
-                           int max_iters, int max_factor, int abort_if_busy,
+                           int max_iters, int max_factor,
+                           int min_remaining, int abort_if_busy,
                            const char *override_config_file)
 {
     pid_t child = -1;
@@ -3375,6 +3376,7 @@ static void migrate_domain(uint32_t domi
         .flags = LIBXL_SUSPEND_LIVE,
         .max_iters = max_iters,
         .max_factor = max_factor,
+        .min_remaining = min_remaining,
     };
 
     save_domain_core_begin(domid, override_config_file,
@@ -3791,12 +3793,13 @@ int main_migrate(int argc, char **argv)
     char *rune = NULL;
     char *host;
     int opt, daemonize = 1, monitor = 1, debug = 0;
-    int max_iters = 0, max_factor = 0, abort_if_busy = 0;
+    int max_iters = 0, max_factor = 0, min_remaining = 0, abort_if_busy = 0;
     static struct option opts[] = {
         {"debug", 0, 0, 0x100},
         {"max_iters", 1, 0, 0x101},
         {"max_factor", 1, 0, 0x102},
-        {"abort_if_busy", 0, 0, 0x103},
+        {"min_remaining", 1, 0, 0x103},
+        {"abort_if_busy", 0, 0, 0x104},
         COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
@@ -3825,6 +3828,9 @@ int main_migrate(int argc, char **argv)
         max_factor = atoi(optarg);
         break;
     case 0x103:
+        min_remaining = atoi(optarg);
+        break;
+    case 0x104:
         abort_if_busy = 1;
         break;
     }
@@ -3842,7 +3848,8 @@ int main_migrate(int argc, char **argv)
             return 1;
     }
 
-    migrate_domain(domid, rune, debug, max_iters, max_factor, abort_if_busy, config_filename);
+    migrate_domain(domid, rune, debug, max_iters, max_factor, min_remaining,
+                   abort_if_busy, config_filename);
     return 0;
 }
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -147,18 +147,19 @@ struct cmd_spec cmd_table[] = {
       &main_migrate, 0, 1,
       "Migrate a domain to another host",
       "[options] <Domain> <host>",
-      "-h                    Print this help.\n"
-      "-C <config>           Send <config> instead of config file from creation.\n"
-      "-s <sshcommand>       Use <sshcommand> instead of ssh.  String will be passed\n"
-      "                      to sh. If empty, run <host> instead of ssh <host> xl\n"
-      "                      migrate-receive [-d -e]\n"
-      "-e                    Do not wait in the background (on <host>) for the death\n"
-      "                      of the domain.\n"
-      "--debug               Print huge (!) amount of debug during the migration process.\n"
-      "--max_iters <number>  Number of iterations before final suspend (default: 30)\n"
-      "--max_factor <factor> Max amount of memory to transfer before final suspend (default: 3*RAM).\n"
-      "--abort_if_busy       Abort migration instead of doing final suspend, if number\n"
-      "                      of iterations or amount of transfered memory is exceeded."
+      "-h                      Print this help.\n"
+      "-C <config>             Send <config> instead of config file from creation.\n"
+      "-s <sshcommand>         Use <sshcommand> instead of ssh.  String will be passed\n"
+      "                        to sh. If empty, run <host> instead of ssh <host> xl\n"
+      "                        migrate-receive [-d -e]\n"
+      "-e                      Do not wait in the background (on <host>) for the death\n"
+      "                        of the domain.\n"
+      "--debug                 Print huge (!) amount of debug during the migration process.\n"
+      "--max_iters <number>    Number of iterations before final suspend (default: 30)\n"
+      "--max_factor <factor>   Max amount of memory to transfer before final suspend (default: 3*RAM).\n"
+      "--min_remaining <pages> Number of remaining dirty pages before final suspend (default: 50).\n"
+      "--abort_if_busy         Abort migration instead of doing final suspend, if number\n"
+      "                        of iterations or amount of transfered memory is exceeded."
     },
     { "dump-core",
       &main_dump_core, 0, 1,
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
--- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
+++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
@@ -206,7 +206,7 @@ int checkpoint_start(checkpoint_state* s
 
     callbacks->switch_qemu_logdirty = noop_switch_logdirty;
 
-    rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, callbacks, hvm,
+    rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, 0, flags, callbacks, hvm,
                         vm_generationid_addr);
 
     if (hvm)
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py
+++ b/tools/python/xen/xend/XendCheckpoint.py
@@ -120,19 +120,22 @@ def save(fd, dominfo, network, live, dst
         # more information.
         max_iters = dominfo.info.get('max_iters', "0")
         max_factor = dominfo.info.get('max_factor', "0")
+        min_remaining = dominfo.info.get('min_remaining', "0")
         abort_if_busy = dominfo.info.get('abort_if_busy', "0")
         log_save_progress = dominfo.info.get('log_save_progress', "0")
         if max_iters == "None":
             max_iters = "0"
         if max_factor == "None":
             max_factor = "0"
+        if min_remaining == "None":
+            min_remaining = "0"
         if abort_if_busy == "None":
             abort_if_busy = "0"
         if log_save_progress == "None":
             log_save_progress = "0"
         cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd),
                str(dominfo.getDomid()),
-               max_iters, max_factor,
+               max_iters, max_factor, min_remaining,
                str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) | (int(log_save_progress) << 6) ) ]
         log.debug("[xc_save]: %s", string.join(cmd))
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py
+++ b/tools/python/xen/xend/XendDomain.py
@@ -1832,18 +1832,19 @@ class XendDomain:
             log.exception(ex)
             raise XendError(str(ex))
 
-    def domain_migrate_constraints_set(self, domid, max_iters, max_factor, abort_if_busy, log_save_progress):
+    def domain_migrate_constraints_set(self, domid, max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress):
         """Set the Migrate Constraints of this domain.
         @param domid: Domain ID or Name
         @param max_iters: Number of iterations before final suspend
         @param max_factor: Max amount of memory to transfer before final suspend
+        @param min_remaining: Number of dirty pages before final suspend
         @param abort_if_busy: Abort migration instead of doing final suspend
         @param log_save_progress: Log progress of migrate to xend.log
         """
         dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
-        dominfo.setMigrateConstraints(max_iters, max_factor, abort_if_busy, log_save_progress)
+        dominfo.setMigrateConstraints(max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress)
 
     def domain_maxmem_set(self, domid, mem):
         """Set the memory limit for a domain.
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -1459,17 +1459,19 @@ class XendDomainInfo:
         pci_conf = self.info['devices'][dev_uuid][1]
         return map(pci_dict_to_bdf_str, pci_conf['devs'])
 
-    def setMigrateConstraints(self, max_iters, max_factor, abort_if_busy, log_save_progress):
+    def setMigrateConstraints(self, max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress):
         """Set the Migrate Constraints of this domain.
         @param max_iters: Number of iterations before final suspend
         @param max_factor: Max amount of memory to transfer before final suspend
+        @param min_remaining: Number of dirty pages before final suspend
         @param abort_if_busy: Abort migration instead of doing final suspend
         @param log_save_progress: Log progress of migrate to xend.log
         """
-        log.debug("Setting migration constraints of domain %s (%s) to '%s' '%s' '%s'.",
-                  self.info['name_label'], str(self.domid), max_iters, max_factor, abort_if_busy)
+        log.debug("Setting migration constraints of domain %s (%s) to '%s' '%s' '%s' '%s'.",
+                  self.info['name_label'], str(self.domid), max_iters, max_factor, min_remaining, abort_if_busy)
         self.info['max_iters'] = str(max_iters)
         self.info['max_factor'] = str(max_factor)
+        self.info['min_remaining'] = str(min_remaining)
         self.info['abort_if_busy'] = str(abort_if_busy)
         self.info['log_save_progress'] = str(log_save_progress)
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py
+++ b/tools/python/xen/xm/migrate.py
@@ -63,6 +63,10 @@ gopts.opt('max_factor', val='max_factor'
           fn=set_int, default=0,
           use="Max amount of memory to transfer before final suspend (default: 3*RAM).")
 
+gopts.opt('min_remaining', val='min_remaining',
+          fn=set_int, default=0,
+          use="Number of dirty pages before final suspend (default: 50).")
+
 gopts.opt('abort_if_busy',
           fn=set_true, default=0,
           use="Abort migration instead of doing final suspend.")
@@ -99,6 +103,7 @@ def main(argv):
         server.xend.domain.migrate_constraints_set(dom,
                                                    opts.vals.max_iters,
                                                    opts.vals.max_factor,
+                                                   opts.vals.min_remaining,
                                                    opts.vals.abort_if_busy,
                                                    opts.vals.log_progress)
         server.xend.domain.migrate(dom, dst, opts.vals.live,
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c
+++ b/tools/xcutils/xc_save.c
@@ -179,20 +179,21 @@ int
 main(int argc, char **argv)
 {
     xc_interface *xch;
-    unsigned int maxit, max_f, lflags;
+    unsigned int maxit, max_f, min_r, lflags;
     int io_fd, ret, port;
     struct save_callbacks callbacks;
     xentoollog_level lvl;
     xentoollog_logger *l;
 
-    if (argc != 6)
-        errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]);
+    if (argc != 7)
+        errx(1, "usage: %s iofd domid maxit maxf minr flags", argv[0]);
 
     io_fd = atoi(argv[1]);
     si.domid = atoi(argv[2]);
     maxit = atoi(argv[3]);
     max_f = atoi(argv[4]);
-    si.flags = atoi(argv[5]);
+    min_r = atoi(argv[5]);
+    si.flags = atoi(argv[6]);
 
     si.suspend_evtchn = -1;
 
@@ -226,7 +227,7 @@ main(int argc, char **argv)
     memset(&callbacks, 0, sizeof(callbacks));
     callbacks.suspend = suspend;
     callbacks.switch_qemu_logdirty = switch_qemu_logdirty;
-    ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, si.flags, 
+    ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, min_r, si.flags, 
                          &callbacks, !!(si.flags & XCFLAGS_HVM), 0);
 
     if (si.suspend_evtchn > 0)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 9 of 9] tools: notify restore to hangup during migration --abort_if_busy
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
                   ` (7 preceding siblings ...)
  2013-03-28 14:43 ` [PATCH 8 of 9] tools: set number of dirty pages during migration Olaf Hering
@ 2013-03-28 14:43 ` Olaf Hering
  2013-04-08 17:14   ` Ian Jackson
  2013-04-08 17:12 ` [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Ian Jackson
  9 siblings, 1 reply; 15+ messages in thread
From: Olaf Hering @ 2013-03-28 14:43 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1364481743 -3600
# Node ID 756d175cefa9885112b6d1337d1e855a223d94a9
# Parent  4bf71e887b838dd643399b8b8a65406d5f8eb94f
tools: notify restore to hangup during migration --abort_if_busy

If a guest is too busy to finish migration, the remote side is not
notified and as a result an imcomplete, paused guest will remain on the
remote side. Add a new flag to notify the receiver about the aborted
migration so that both sides can cleanup properly.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 4bf71e887b83 -r 756d175cefa9 tools/libxc/xc_domain_restore.c
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -983,6 +983,10 @@ static int pagebuf_get_one(xc_interface 
         DPRINTF("read generation id buffer address");
         return pagebuf_get_one(xch, ctx, buf, fd, dom);
 
+    case XC_SAVE_ID_BUSY_ABORT:
+        ERROR("Source host requested cancelation, guest is busy.");
+        errno = EBUSY;
+        return -1;
     default:
         if ( (count > MAX_BATCH_SIZE) || (count < 0) ) {
             ERROR("Max batch size exceeded (%d). Giving up.", count);
diff -r 4bf71e887b83 -r 756d175cefa9 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -1537,9 +1537,11 @@ int xc_domain_save(xc_interface *xch, in
             {
                 if ( !min_reached && abort_if_busy )
                 {
+                    unsigned int cmd = XC_SAVE_ID_BUSY_ABORT;
                     ERROR("Live migration aborted, as requested. (guest too busy?)"
                      " total_sent %lu iter %d, max_iters %u max_factor %u",
                       total_sent, iter, max_iters, max_factor);
+                    wrexact(io_fd, &cmd, sizeof(cmd));
                     print_stats(xch, dom, sent_this_iter, &time_stats, &shadow_stats, 1);
                     rc = 1;
                     goto out;
diff -r 4bf71e887b83 -r 756d175cefa9 tools/libxc/xg_save_restore.h
--- a/tools/libxc/xg_save_restore.h
+++ b/tools/libxc/xg_save_restore.h
@@ -259,6 +259,7 @@
 #define XC_SAVE_ID_HVM_ACCESS_RING_PFN  -16
 #define XC_SAVE_ID_HVM_SHARING_RING_PFN -17
 #define XC_SAVE_ID_TOOLSTACK          -18 /* Optional toolstack specific info */
+#define XC_SAVE_ID_BUSY_ABORT         -19 /* Source requested cancelation */
 
 /*
 ** We process save/restore/migrate in batches of pages; the below

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging
  2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
                   ` (8 preceding siblings ...)
  2013-03-28 14:43 ` [PATCH 9 of 9] tools: notify restore to hangup during migration --abort_if_busy Olaf Hering
@ 2013-04-08 17:12 ` Ian Jackson
  9 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2013-04-08 17:12 UTC (permalink / raw)
  To: Olaf Hering; +Cc: Ian.Campbell, xen-devel

Olaf Hering writes ("[Xen-devel] [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging"):
> This series improves logging capabilities of xm migrate.
> It also adds new options to xm/xl migrate to tweak the
> max_iter/max_factor options passed to xc_domain_save. Being able to
> tweak those knobs helps with migrating large and busy guests.

We aren't accepting new features in xend, and that includes
tools/xcutils.

Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3 of 9] tools/xc: rework xc_save.c:switch_qemu_logdirty
  2013-03-28 14:43 ` [PATCH 3 of 9] tools/xc: rework xc_save.c:switch_qemu_logdirty Olaf Hering
@ 2013-04-08 17:12   ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2013-04-08 17:12 UTC (permalink / raw)
  To: Olaf Hering; +Cc: Ian.Campbell, xen-devel

Olaf Hering writes ("[Xen-devel] [PATCH 3 of 9] tools/xc: rework xc_save.c:switch_qemu_logdirty"):
> tools/xc: rework xc_save.c:switch_qemu_logdirty

Why ?

Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 6 of 9] tools/xend: move assert to exception block
  2013-03-28 14:43 ` [PATCH 6 of 9] tools/xend: move assert to exception block Olaf Hering
@ 2013-04-08 17:13   ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2013-04-08 17:13 UTC (permalink / raw)
  To: Olaf Hering; +Cc: Ian.Campbell, xen-devel

Olaf Hering writes ("[Xen-devel] [PATCH 6 of 9] tools/xend: move assert to exception block"):
> tools/xend: move assert to exception block

This looks like a plausible bugfix.

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 9 of 9] tools: notify restore to hangup during migration --abort_if_busy
  2013-03-28 14:43 ` [PATCH 9 of 9] tools: notify restore to hangup during migration --abort_if_busy Olaf Hering
@ 2013-04-08 17:14   ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2013-04-08 17:14 UTC (permalink / raw)
  To: Olaf Hering; +Cc: Ian.Campbell, xen-devel

Olaf Hering writes ("[Xen-devel] [PATCH 9 of 9] tools: notify restore to hangup during migration --abort_if_busy"):
> tools: notify restore to hangup during migration --abort_if_busy
> 
> If a guest is too busy to finish migration, the remote side is not
> notified and as a result an imcomplete, paused guest will remain on the
> remote side. Add a new flag to notify the receiver about the aborted
> migration so that both sides can cleanup properly.

This should be handled at a higher layer.

Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 4 of 9] tools: set migration constraints from cmdline
  2013-03-28 14:43 ` [PATCH 4 of 9] tools: set migration constraints from cmdline Olaf Hering
@ 2013-04-08 17:16   ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2013-04-08 17:16 UTC (permalink / raw)
  To: Olaf Hering; +Cc: Ian.Campbell, xen-devel

Olaf Hering writes ("[Xen-devel] [PATCH 4 of 9] tools: set migration constraints from cmdline"):
> tools: set migration constraints from cmdline
> 
> Add new options to xm/xl migrate to control the process of migration.
> The intention is to optionally abort the migration if it takes too long
> to migrate a busy guest due to the high number of new dirty pages.
> Currently the guest is suspended to transfer the remaining dirty pages.
> This transfer can take a long time, which can confuse the guest if its
> suspended for too long.

As I say we're not accepting new features for xend/xm.

> --max_iters <number>  Number of iterations before final suspend (default: 30)
> 
> --max_factor <factor> Max amount of memory to transfer before final suspend (default: 3*RAM)
> 
> --abort_if_busy       Abort migration instead of doing final suspend.

These option names should have hyphens (-) not underscores (_).

And I think they probably need options in the global xl config to set
the defaults.

Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2013-04-08 17:16 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-28 14:43 [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Olaf Hering
2013-03-28 14:43 ` [PATCH 1 of 9] tools/xc: print messages from xc_save with xc_report Olaf Hering
2013-03-28 14:43 ` [PATCH 2 of 9] tools/xc: document printf calls in xc_restore Olaf Hering
2013-03-28 14:43 ` [PATCH 3 of 9] tools/xc: rework xc_save.c:switch_qemu_logdirty Olaf Hering
2013-04-08 17:12   ` Ian Jackson
2013-03-28 14:43 ` [PATCH 4 of 9] tools: set migration constraints from cmdline Olaf Hering
2013-04-08 17:16   ` Ian Jackson
2013-03-28 14:43 ` [PATCH 5 of 9] tools: add xm migrate --log_progress option Olaf Hering
2013-03-28 14:43 ` [PATCH 6 of 9] tools/xend: move assert to exception block Olaf Hering
2013-04-08 17:13   ` Ian Jackson
2013-03-28 14:43 ` [PATCH 7 of 9] tools/libxc: print stats if migration is aborted Olaf Hering
2013-03-28 14:43 ` [PATCH 8 of 9] tools: set number of dirty pages during migration Olaf Hering
2013-03-28 14:43 ` [PATCH 9 of 9] tools: notify restore to hangup during migration --abort_if_busy Olaf Hering
2013-04-08 17:14   ` Ian Jackson
2013-04-08 17:12 ` [PATCH 0 of 9] set migrate constraints from cmdline, better xend.log logging Ian Jackson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).