[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] libxl: Fix migration of HVM guests



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1288264783 -3600
# Node ID 4ac03710fc320e8f76014ca27849da03b85dff9d
# Parent  902fdaaa1fe6e081bb1d8acbc21ed81931556f4c
libxl: Fix migration of HVM guests

In the default "QemuDeviceModelRecord"-style HVM tail of the migration
protocol the size of the qemu save record is unknown at the receiver
and therefore it must read until EOF. This is not compatible with the
xl migration protocol which contains a post-migration handshake and
therefore cannot close the socket on the sending end.

What is required is an explicit length field for the save record,
which the "RemusDeviceModelState"-style HVM tail includes.

Rather than overload the "RemusDeviceModelState" name for a non-Remus
use case (on off chance that they need to diverge for some reason in
the future) introduce a third style called "DeviceModelRecord0002"
which is identical to current "RemusDeviceModelState"-style.

Hopefully the inclusion of a number here will allow easier extension
in the future without needing to come up with increasingly less
helpful names!

Also propagate errors from xc_domain_save and
libxl__domain_suspend_common to callers.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
 tools/libxc/xc_domain_restore.c |   13 +++++++++----
 tools/libxc/xg_save_restore.h   |    3 ++-
 tools/libxl/libxl.c             |    4 ++--
 tools/libxl/libxl_dom.c         |   24 ++++++++++++++++++++++--
 tools/libxl/libxl_internal.h    |    2 +-
 5 files changed, 36 insertions(+), 10 deletions(-)

diff -r 902fdaaa1fe6 -r 4ac03710fc32 tools/libxc/xc_domain_restore.c
--- a/tools/libxc/xc_domain_restore.c   Thu Oct 28 12:16:48 2010 +0100
+++ b/tools/libxc/xc_domain_restore.c   Thu Oct 28 12:19:43 2010 +0100
@@ -494,13 +494,18 @@ static int buffer_tail_hvm(xc_interface 
         return -1;
     }
 
-    /* The normal live-migration QEMU record has no length information.
+    /* The legacy live-migration QEMU record has no length information.
      * Short of reimplementing the QEMU parser, we're forced to just read
-     * until EOF. Remus gets around this by sending a different signature
-     * which includes a length prefix */
+     * until EOF.
+     *
+     * Gets around this by sending a different signatures for the new
+     * live-migration QEMU record and Remus which includes a length
+     * prefix
+     */
     if ( !memcmp(qemusig, "QemuDeviceModelRecord", sizeof(qemusig)) )
         return compat_buffer_qemu(xch, ctx, fd, buf);
-    else if ( !memcmp(qemusig, "RemusDeviceModelState", sizeof(qemusig)) )
+    else if ( !memcmp(qemusig, "DeviceModelRecord0002", sizeof(qemusig)) ||
+              !memcmp(qemusig, "RemusDeviceModelState", sizeof(qemusig)) )
         return buffer_qemu(xch, ctx, fd, buf);
 
     qemusig[20] = '\0';
diff -r 902fdaaa1fe6 -r 4ac03710fc32 tools/libxc/xg_save_restore.h
--- a/tools/libxc/xg_save_restore.h     Thu Oct 28 12:16:48 2010 +0100
+++ b/tools/libxc/xg_save_restore.h     Thu Oct 28 12:19:43 2010 +0100
@@ -104,8 +104,9 @@
  *  Qemu context:
  *     char[21]         : Signature:
  *       "QemuDeviceModelRecord" : Read Qemu save data until EOF
- *       "RemusDeviceModelState" : uint32_t length field followed by that many
+ *       "DeviceModelRecord0002" : uint32_t length field followed by that many
  *                                 bytes of Qemu save data
+ *       "RemusDeviceModelState" : Currently the same as 
"DeviceModelRecord0002".
  *
  * PV TAIL:
  *
diff -r 902fdaaa1fe6 -r 4ac03710fc32 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Thu Oct 28 12:16:48 2010 +0100
+++ b/tools/libxl/libxl.c       Thu Oct 28 12:19:43 2010 +0100
@@ -686,8 +686,8 @@ int libxl_domain_suspend(libxl_ctx *ctx,
     int debug = info != NULL && info->flags & XL_SUSPEND_DEBUG;
     int rc = 0;
 
-    libxl__domain_suspend_common(ctx, domid, fd, hvm, live, debug);
-    if (hvm)
+    rc = libxl__domain_suspend_common(ctx, domid, fd, hvm, live, debug);
+    if (!rc && hvm)
         rc = libxl__domain_save_device_model(ctx, domid, fd);
     return rc;
 }
diff -r 902fdaaa1fe6 -r 4ac03710fc32 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c   Thu Oct 28 12:16:48 2010 +0100
+++ b/tools/libxl/libxl_dom.c   Thu Oct 28 12:19:43 2010 +0100
@@ -442,14 +442,17 @@ int libxl__domain_suspend_common(libxl_c
     callbacks.switch_qemu_logdirty = 
libxl__domain_suspend_common_switch_qemu_logdirty;
     callbacks.data = &si;
 
-    xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm);
+    rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm);
+    if ( rc ) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain");
+        rc = ERROR_FAIL;
+    }
 
     if (si.suspend_eventchn > 0)
         xc_suspend_evtchn_release(ctx->xch, si.xce, domid, 
si.suspend_eventchn);
     if (si.xce > 0)
         xc_evtchn_close(si.xce);
 
-    rc = 0;
 out:
     libxl__free_all(&gc);
     return rc;
@@ -461,15 +464,32 @@ int libxl__domain_save_device_model(libx
     int fd2, c;
     char buf[1024];
     char *filename = libxl__sprintf(&gc, "/var/lib/xen/qemu-save.%d", domid);
+    struct stat st;
+    uint32_t qemu_state_len;
 
     LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Saving device model state to %s", 
filename);
     libxl__xs_write(&gc, XBT_NULL, libxl__sprintf(&gc, 
"/local/domain/0/device-model/%d/command", domid), "save");
     libxl__wait_for_device_model(ctx, domid, "paused", NULL, NULL);
+
+    if (stat(filename, &st) < 0)
+    {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to stat qemu save file\n");
+        return ERROR_FAIL;
+    }
+
+    qemu_state_len = st.st_size;
+    LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Qemu state is %d bytes\n", 
qemu_state_len);
 
     c = libxl_write_exactly(ctx, fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE),
                             "saved-state file", "qemu signature");
     if (c)
         return c;
+
+    c = libxl_write_exactly(ctx, fd, &qemu_state_len, sizeof(qemu_state_len),
+                            "saved-state file", "saved-state length");
+    if (c)
+        return c;
+
     fd2 = open(filename, O_RDONLY);
     while ((c = read(fd2, buf, sizeof(buf))) != 0) {
         if (c < 0) {
diff -r 902fdaaa1fe6 -r 4ac03710fc32 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Thu Oct 28 12:16:48 2010 +0100
+++ b/tools/libxl/libxl_internal.h      Thu Oct 28 12:19:43 2010 +0100
@@ -44,7 +44,7 @@
 #define LIBXL_PV_EXTRA_MEMORY 1024
 #define LIBXL_HVM_EXTRA_MEMORY 2048
 #define LIBXL_MIN_DOM0_MEM (128*1024)
-#define QEMU_SIGNATURE "QemuDeviceModelRecord"
+#define QEMU_SIGNATURE "DeviceModelRecord0002"
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.