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

[Xen-devel] [PATCH v3 COLOPre 22/26] tools/libxl: refactor read stream to support back channel



From: Wen Congyang <wency@xxxxxxxxxxxxxx>

Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx>
---
 tools/libxl/libxl_create.c      |  8 +++++---
 tools/libxl/libxl_internal.h    |  9 +++++----
 tools/libxl/libxl_remus.c       |  8 +++++---
 tools/libxl/libxl_stream_read.c | 33 +++++++++++++++++++++++++++++----
 4 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 6fa5ab7..342aa01 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -780,7 +780,7 @@ static void domcreate_console_available(libxl__egc *egc,
                                         libxl__domain_create_state *dcs);
 
 static void domcreate_stream_done(libxl__egc *egc,
-                                  libxl__domain_create_state *dcs,
+                                  libxl__stream_read_state *stream,
                                   int ret);
 
 static void domcreate_rebuild_done(libxl__egc *egc,
@@ -1046,13 +1046,14 @@ static void domcreate_bootloader_done(libxl__egc *egc,
     dcs->srs.ao = ao;
     dcs->srs.fd = restore_fd;
     dcs->srs.legacy = (dcs->restore_params.stream_version == 1);
+    dcs->srs.back_channel = false;
     dcs->srs.completion_callback = domcreate_stream_done;
 
     libxl__stream_read_start(egc, &dcs->srs);
     return;
 
  out:
-    domcreate_stream_done(egc, dcs, rc);
+    domcreate_stream_done(egc, &dcs->srs, rc);
 }
 
 void libxl__srm_callout_callback_restore_results(unsigned long store_mfn,
@@ -1069,9 +1070,10 @@ void 
libxl__srm_callout_callback_restore_results(unsigned long store_mfn,
 }
 
 static void domcreate_stream_done(libxl__egc *egc,
-                                  libxl__domain_create_state *dcs,
+                                  libxl__stream_read_state *stream,
                                   int ret)
 {
+    libxl__domain_create_state *dcs = CONTAINER_OF(stream, *dcs, srs);
     STATE_AO_GC(dcs->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char **vments = NULL, **localents = NULL;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 82a327c..bd369f2 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3223,12 +3223,13 @@ struct libxl__stream_read_state {
     libxl__ao *ao;
     int fd;
     bool legacy;
+    bool back_channel;
     void (*completion_callback)(libxl__egc *egc,
-                                libxl__domain_create_state *dcs,
-                                int rc);
-    void (*checkpoint_callback)(libxl__egc *egc,
-                                libxl__domain_create_state *dcs,
+                                libxl__stream_read_state *stream,
                                 int rc);
+    void (*read_records_callback)(libxl__egc *egc,
+                                  libxl__stream_read_state *stream,
+                                  int rc);
     /* Private */
     libxl__carefd *v2_carefd;
     int rc;
diff --git a/tools/libxl/libxl_remus.c b/tools/libxl/libxl_remus.c
index e143b21..0c449ad 100644
--- a/tools/libxl/libxl_remus.c
+++ b/tools/libxl/libxl_remus.c
@@ -303,7 +303,7 @@ static void remus_next_checkpoint(libxl__egc *egc, 
libxl__ev_time *ev,
 /*----- remus asynchronous checkpoint callback -----*/
 
 static void remus_checkpoint_stream_done(
-    libxl__egc *egc, libxl__domain_create_state *dcs, int rc);
+    libxl__egc *egc, libxl__stream_read_state *stream, int rc);
 
 void libxl__remus_domain_restore_checkpoint_callback(void *data)
 {
@@ -312,13 +312,15 @@ void libxl__remus_domain_restore_checkpoint_callback(void 
*data)
     libxl__egc *egc = dcs->shs.egc;
     STATE_AO_GC(dcs->ao);
 
-    dcs->srs.checkpoint_callback = remus_checkpoint_stream_done;
+    dcs->srs.read_records_callback = remus_checkpoint_stream_done;
     libxl__stream_read_start_checkpoint(egc, &dcs->srs);
 }
 
 static void remus_checkpoint_stream_done(
-    libxl__egc *egc, libxl__domain_create_state *dcs, int rc)
+    libxl__egc *egc, libxl__stream_read_state *stream, int rc)
 {
+    libxl__domain_create_state *dcs = CONTAINER_OF(stream, *dcs, srs);
+
     libxl__xc_domain_saverestore_async_callback_done(egc, &dcs->shs, rc);
 }
 /*
diff --git a/tools/libxl/libxl_stream_read.c b/tools/libxl/libxl_stream_read.c
index 09ef0aa..72a9972 100644
--- a/tools/libxl/libxl_stream_read.c
+++ b/tools/libxl/libxl_stream_read.c
@@ -42,6 +42,15 @@
  * Depending on the contents of the stream, there are likely to be several
  * parallel tasks being managed.  check_stream_finished() is used to join all
  * tasks in both success and error cases.
+ *
+ * For back channel stream:
+ * - libxl__stream_read_start()
+ *    - Set up the stream to running state
+ *
+ * - libxl__stream_read_continue()
+ *     - Set up reading the next record from a started stream.
+ *       You need to add some codes to process_record() to handle
+ *       the record. Then call stream->read_records_callback() to return.
  */
 
 static void stream_success(libxl__egc *egc,
@@ -94,6 +103,12 @@ void libxl__stream_read_start(libxl__egc *egc,
 
     /* State initialisation. */
     assert(!stream->running);
+    assert(!stream->legacy || !stream->back_channel);
+
+    if (stream->back_channel) {
+        stream->running = true;
+        return;
+    }
 
     if (stream->legacy) {
         /* Convert a legacy stream, if needed. */
@@ -174,6 +189,7 @@ void libxl__stream_read_start_checkpoint(libxl__egc *egc,
 
     assert(stream->running);
     assert(!stream->in_checkpoint);
+    assert(!stream->back_channel);
     stream->in_checkpoint = true;
 
     /* Read a record header. */
@@ -224,6 +240,11 @@ static void stream_failed(libxl__egc *egc,
         return;
     }
 
+    if (stream->back_channel) {
+        stream->completion_callback(egc, stream, rc);
+        return;
+    }
+
     if (stream->running) {
         stream->running = false;
         stream_done(egc, stream);
@@ -237,6 +258,7 @@ static void stream_done(libxl__egc *egc,
 
     assert(!stream->running);
     assert(!stream->in_checkpoint);
+    assert(!stream->back_channel);
 
     if (stream->v2_carefd)
         libxl__carefd_close(stream->v2_carefd);
@@ -287,7 +309,7 @@ static void check_stream_finished(libxl__egc *egc,
         LOG(DEBUG, "save/restore still in use");
     else {
         LOG(INFO, "Join complete: result %d", stream->joined_rc);
-        stream->completion_callback(egc, dcs, stream->joined_rc);
+        stream->completion_callback(egc, stream, stream->joined_rc);
     }
 }
 
@@ -471,14 +493,17 @@ static void process_record(libxl__egc *egc,
     switch (rec_hdr->type) {
 
     case REC_TYPE_END:
+        assert(!stream->back_channel);
         /* Handled later, after cleanup. */
         break;
 
     case REC_TYPE_LIBXC_CONTEXT:
+        assert(!stream->back_channel);
         libxl__xc_domain_restore(egc, dcs, stream->fd, 0, 0, 0);
         break;
 
     case REC_TYPE_XENSTORE_DATA:
+        assert(!stream->back_channel);
         ret = libxl__toolstack_restore(dcs->guest_domid, stream->rec_body,
                                        rec_hdr->length, &dcs->shs);
         if (ret)
@@ -492,10 +517,12 @@ static void process_record(libxl__egc *egc,
         break;
 
     case REC_TYPE_EMULATOR_CONTEXT:
+        assert(!stream->back_channel);
         read_emulator_body(egc, stream);
         break;
 
     case REC_TYPE_CHECKPOINT_END:
+        assert(!stream->back_channel);
         if (!stream->in_checkpoint) {
             LOG(ERROR, "Unexpected CHECKPOINT_END record in stream");
             ret = ERROR_FAIL;
@@ -647,11 +674,9 @@ static void emulator_padding_done(libxl__egc *egc,
 static void checkpoint_done(libxl__egc *egc,
                             libxl__stream_read_state *stream, int rc)
 {
-    libxl__domain_create_state *dcs = CONTAINER_OF(stream, *dcs, srs);
-
     assert(stream->in_checkpoint);
     stream->in_checkpoint = false;
-    stream->checkpoint_callback(egc, dcs, rc);
+    stream->read_records_callback(egc, stream, rc);
 }
 
 /*
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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