]> xenbits.xensource.com Git - xen.git/commitdiff
tools/libxc+libxl+xl: Restore v2 streams
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 12 Jun 2015 16:21:41 +0000 (17:21 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 15 Jul 2015 10:22:53 +0000 (11:22 +0100)
This is a complicated set of changes which must be done together for
bisectability.

 * libxl-save-helper is updated to unconditionally use libxc migration
   v2.
 * libxl compatibility workarounds in libxc are disabled for restore
   operations.
 * libxl__stream_read_start() is logically spliced into the event
   location where libxl__xc_domain_restore() used to reside.
 * Ownership of the save_helper_state moves to stream_read_state.

The parameters 'hvm', 'pae', and 'superpages' were previously
superfluous, and are completely unused in migration
v2. callbacks->toolstack_restore is handled via a migration v2 record
now, rather than via a callback from libxc.

NB: this change breaks Remus.  Further untangling needs to happen
before Remus will function.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
v4:
 * Don't use _init() needlessly
v3:
 * Simplify from v2.
 * Alter the ownership of save_helper_state

v2:
 * Drop "legacy_width" from the IDL
 * Gain a LIBXL_HAVE_ to signify support of migration v2 streams

tools/libxc/Makefile
tools/libxl/libxl.h
tools/libxl/libxl_create.c
tools/libxl/libxl_internal.h
tools/libxl/libxl_save_helper.c
tools/libxl/libxl_stream_read.c
tools/libxl/libxl_types.idl
tools/libxl/xl_cmdimpl.c

index b659df4fabd60308d57b8bc5f28ead2b0a85c106..2cd0b1a4137787210b9e28e4bc513865547fccbd 100644 (file)
@@ -64,8 +64,8 @@ GUEST_SRCS-$(CONFIG_X86) += xc_sr_save_x86_hvm.c
 GUEST_SRCS-y += xc_sr_restore.c
 GUEST_SRCS-y += xc_sr_save.c
 GUEST_SRCS-y += xc_offline_page.c xc_compression.c
-$(patsubst %.c,%.o,$(GUEST_SRCS-y)): CFLAGS += -DXG_LIBXL_HVM_COMPAT
-$(patsubst %.c,%.opic,$(GUEST_SRCS-y)): CFLAGS += -DXG_LIBXL_HVM_COMPAT
+xc_sr_save_x86_hvm.o: CFLAGS += -DXG_LIBXL_HVM_COMPAT
+xc_sr_save_x86_hvm.opic: CFLAGS += -DXG_LIBXL_HVM_COMPAT
 else
 GUEST_SRCS-y += xc_nomigrate.c
 endif
index e9d63c9a5bf31bb99b5f7d9fa5212db5a1266bfd..74b082991e01d88a7359fd0a2f670a58269f1a98 100644 (file)
@@ -807,6 +807,23 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src);
  */
 #define LIBXL_HAVE_SOCKET_BITMAP_ALLOC 1
 
+/*
+ * LIBXL_HAVE_SRM_V2
+ *
+ * If this is defined, then the libxl_domain_create_restore() interface takes
+ * a "stream_version" parameter and supports a value of 2.
+ */
+#define LIBXL_HAVE_SRM_V2 1
+
+/*
+ * LIBXL_HAVE_SRM_V1
+ *
+ * In the case that LIBXL_HAVE_SRM_V2 is set, LIBXL_HAVE_SRM_V1
+ * indicates that libxl_domain_create_restore() can handle a "stream_version"
+ * parameter of 1, and convert the stream format automatically.
+ */
+#define LIBXL_HAVE_SRM_V1 1
+
 typedef char **libxl_string_list;
 void libxl_string_list_dispose(libxl_string_list *sl);
 int libxl_string_list_length(const libxl_string_list *sl);
index 7f0ffc6ba92b8260223c4dff9b2b7702d3ece273..c51d64f7493bec77af469ad309d226ea3f9f98fb 100644 (file)
@@ -704,6 +704,10 @@ static void domcreate_attach_dtdev(libxl__egc *egc,
 static void domcreate_console_available(libxl__egc *egc,
                                         libxl__domain_create_state *dcs);
 
+static void domcreate_stream_done(libxl__egc *egc,
+                                  libxl__stream_read_state *srs,
+                                  int ret);
+
 static void domcreate_rebuild_done(libxl__egc *egc,
                                    libxl__domain_create_state *dcs,
                                    int ret);
@@ -933,11 +937,8 @@ static void domcreate_bootloader_done(libxl__egc *egc,
     /* convenience aliases */
     const uint32_t domid = dcs->guest_domid;
     libxl_domain_config *const d_config = dcs->guest_config;
-    libxl_domain_build_info *const info = &d_config->b_info;
     const int restore_fd = dcs->restore_fd;
     libxl__domain_build_state *const state = &dcs->build_state;
-    libxl__srm_restore_autogen_callbacks *const callbacks =
-        &dcs->shs.callbacks.restore.a;
 
     if (rc) {
         domcreate_rebuild_done(egc, dcs, rc);
@@ -970,30 +971,17 @@ static void domcreate_bootloader_done(libxl__egc *egc,
     if (rc)
         goto out;
 
-    /* read signature */
-    int hvm, pae, superpages;
-    switch (info->type) {
-    case LIBXL_DOMAIN_TYPE_HVM:
-        hvm = 1;
-        superpages = 1;
-        pae = libxl_defbool_val(info->u.hvm.pae);
-        callbacks->toolstack_restore = libxl__toolstack_restore;
-        break;
-    case LIBXL_DOMAIN_TYPE_PV:
-        hvm = 0;
-        superpages = 0;
-        pae = 1;
-        break;
-    default:
-        rc = ERROR_INVAL;
-        goto out;
-    }
-    libxl__xc_domain_restore(egc, dcs, &dcs->shs,
-                             hvm, pae, superpages);
+    dcs->srs.ao = ao;
+    dcs->srs.dcs = dcs;
+    dcs->srs.fd = restore_fd;
+    dcs->srs.legacy = (dcs->restore_params.stream_version == 1);
+    dcs->srs.completion_callback = domcreate_stream_done;
+
+    libxl__stream_read_start(egc, &dcs->srs);
     return;
 
  out:
-    libxl__xc_domain_restore_done(egc, dcs, rc, 0, 0);
+    domcreate_stream_done(egc, &dcs->srs, rc);
 }
 
 void libxl__srm_callout_callback_restore_results(unsigned long store_mfn,
@@ -1009,10 +997,11 @@ void libxl__srm_callout_callback_restore_results(unsigned long store_mfn,
     shs->need_results =           0;
 }
 
-void libxl__xc_domain_restore_done(libxl__egc *egc, void *dcs_void,
-                                   int ret, int retval, int errnoval)
+static void domcreate_stream_done(libxl__egc *egc,
+                                  libxl__stream_read_state *srs,
+                                  int ret)
 {
-    libxl__domain_create_state *dcs = dcs_void;
+    libxl__domain_create_state *dcs = srs->dcs;
     STATE_AO_GC(dcs->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char **vments = NULL, **localents = NULL;
@@ -1029,12 +1018,6 @@ void libxl__xc_domain_restore_done(libxl__egc *egc, void *dcs_void,
     if (ret)
         goto out;
 
-    if (retval) {
-        LOGEV(ERROR, errnoval, "restoring domain");
-        ret = ERROR_FAIL;
-        goto out;
-    }
-
     gettimeofday(&start_time, NULL);
 
     switch (info->type) {
index b65019b793f2118f24966e538e3202f18ca58c2d..0a13c7f64340262760eefce4f3065d5070f49113 100644 (file)
@@ -3265,6 +3265,7 @@ struct libxl__stream_read_state {
     /* Private */
     int rc;
     bool running;
+    libxl__save_helper_state shs;
     libxl__conversion_helper_state chs;
 
     /* Main stream-reading data. */
@@ -3312,7 +3313,7 @@ struct libxl__domain_create_state {
     libxl__stub_dm_spawn_state dmss;
         /* If we're not doing stubdom, we use only dmss.dm,
          * for the non-stubdom device model. */
-    libxl__save_helper_state shs;
+    libxl__stream_read_state srs;
     /* necessary if the domain creation failed and we have to destroy it */
     libxl__domain_destroy_state dds;
     libxl__multidev multidev;
index 14675ae79715195ba13bdcc0ac5774e57144680f..efbe2eb966f67eb9e39b2b4760f8e5cefb00db6a 100644 (file)
@@ -313,7 +313,7 @@ int main(int argc, char **argv)
         startup("restore");
         setup_signals(SIG_DFL);
 
-        r = xc_domain_restore(xch, io_fd, dom, store_evtchn, &store_mfn,
+        r = xc_domain_restore2(xch, io_fd, dom, store_evtchn, &store_mfn,
                               store_domid, console_evtchn, &console_mfn,
                               console_domid, hvm, pae, superpages,
                               checkpointed,
index 4b677f63db606a1f0c9045f59e154b3668289c8b..3051a2ba521ba452e74a98b108ae1befce1d5178 100644 (file)
@@ -159,6 +159,7 @@ void libxl__stream_read_init(libxl__stream_read_state *stream)
 {
     stream->rc = 0;
     stream->running = false;
+    libxl__save_helper_init(&stream->shs);
     libxl__conversion_helper_init(&stream->chs);
     FILLZERO(stream->dc);
     FILLZERO(stream->hdr);
@@ -445,9 +446,13 @@ static bool process_record(libxl__egc *egc,
         stream_complete(egc, stream, 0);
         break;
 
+    case REC_TYPE_LIBXC_CONTEXT:
+        libxl__xc_domain_restore(egc, dcs, &stream->shs, 0, 0, 0);
+        break;
+
     case REC_TYPE_XENSTORE_DATA:
         rc = libxl__toolstack_restore(dcs->guest_domid, rec->body,
-                                      rec->hdr.length, &dcs->shs);
+                                      rec->hdr.length, &stream->shs);
         if (rc)
             goto err;
 
@@ -592,6 +597,32 @@ static void stream_done(libxl__egc *egc,
     check_all_finished(egc, stream, stream->rc);
 }
 
+void libxl__xc_domain_restore_done(libxl__egc *egc, void *dcs_void,
+                                   int rc, int retval, int errnoval)
+{
+    libxl__domain_create_state *dcs = dcs_void;
+    libxl__stream_read_state *stream = &dcs->srs;
+    STATE_AO_GC(dcs->ao);
+
+    if (rc)
+        goto err;
+
+    if (retval) {
+        LOGEV(ERROR, errnoval, "restoring domain");
+        rc = ERROR_FAIL;
+        goto err;
+    }
+
+    /*
+     * Libxc has indicated that it is done with the stream.  Resume reading
+     * libxl records from it.
+     */
+    stream_continue(egc, stream);
+
+ err:
+    check_all_finished(egc, stream, rc);
+}
+
 static void conversion_done(libxl__egc *egc,
                             libxl__conversion_helper_state *chs, int rc)
 {
@@ -610,11 +641,13 @@ static void check_all_finished(libxl__egc *egc,
         stream->rc = rc;
 
         libxl__stream_read_abort(egc, stream, rc);
+        libxl__save_helper_abort(egc, &stream->shs);
         libxl__conversion_helper_abort(egc, &stream->chs, rc);
     }
 
     /* Don't fire the callback until all our parallel tasks have stopped. */
     if (libxl__stream_read_inuse(stream) ||
+        libxl__save_helper_inuse(&stream->shs) ||
         libxl__conversion_helper_inuse(&stream->chs))
         return;
 
index 8dacf8d006d2a3106a2cfac9202324c2346eaea3..bc0c4ef330a78864a0104c6d955bc097de781834 100644 (file)
@@ -355,6 +355,7 @@ libxl_domain_create_info = Struct("domain_create_info",[
 
 libxl_domain_restore_params = Struct("domain_restore_params", [
     ("checkpointed_stream", integer),
+    ("stream_version", uint32, {'init_val': '1'}),
     ])
 
 libxl_domain_sched_params = Struct("domain_sched_params",[
index 77647e9c3dc8eb9495c261b12075e439231fc9b3..7406b03be0abab09c45ee8ace53db29a50937434 100644 (file)
@@ -110,7 +110,9 @@ static const char migrate_report[]=
 
 #define XL_MANDATORY_FLAG_JSON (1U << 0) /* config data is in JSON format */
 #define XL_MANDATORY_FLAG_STREAMv2 (1U << 1) /* stream is v2 */
-#define XL_MANDATORY_FLAG_ALL  (XL_MANDATORY_FLAG_JSON)
+#define XL_MANDATORY_FLAG_ALL  (XL_MANDATORY_FLAG_JSON |        \
+                                XL_MANDATORY_FLAG_STREAMv2)
+
 struct save_file_header {
     char magic[32]; /* savefileheader_magic */
     /* All uint32_ts are in domain's byte order. */
@@ -2757,6 +2759,9 @@ start:
         libxl_domain_restore_params_init(&params);
 
         params.checkpointed_stream = dom_info->checkpointed_stream;
+        params.stream_version =
+            (hdr.mandatory_flags & XL_MANDATORY_FLAG_STREAMv2) ? 2 : 1;
+
         ret = libxl_domain_create_restore(ctx, &d_config,
                                           &domid, restore_fd,
                                           &params,