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

[Xen-devel] [PATCH 3/3] libxc/migrationv2: Split {start, end}_of_stream() to make checkpoint variants



This is in preparation for supporting checkpointed streams in migration v2.
 - For PV guests, the VCPU context is moved to end_of_checkpoint().
 - For HVM guests, the HVM context and params are moved to end_of_checkpoint().

For regular migration, this results in a reordering of the tail records, but
no semantic change.

In addition fix a couple of stylistic issues and adjust some comments.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CC: Ian Campbell <Ian.Campbell@xxxxxxxxxx>
CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
CC: Wei Liu <wei.liu2@xxxxxxxxxx>
CC: Yang Hongyang <yanghy@xxxxxxxxxxxxxx>

---
This patch has not tested yet, but is just some code shuffling and should have
no observable effect from the guests point of view.
---
 tools/libxc/xc_sr_common.h       |   25 +++++++++++++++------
 tools/libxc/xc_sr_save.c         |    8 +++++++
 tools/libxc/xc_sr_save_x86_hvm.c |   46 ++++++++++++++++++++++++--------------
 tools/libxc/xc_sr_save_x86_pv.c  |   46 +++++++++++++++++++++++++-------------
 4 files changed, 85 insertions(+), 40 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index ef42412..56169ea 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -61,17 +61,28 @@ struct xc_sr_save_ops
     int (*setup)(struct xc_sr_context *ctx);
 
     /**
-     * Write records which need to be at the start of the stream.  This is
-     * called after the Image and Domain headers are written.  (Any records
-     * which need to be ahead of the memory.)
+     * Send records which need to be at the start of the stream.  This is
+     * called once, after the Image and Domain headers are written.
      */
     int (*start_of_stream)(struct xc_sr_context *ctx);
 
     /**
-     * Write records which need to be at the end of the stream, following the
-     * complete memory contents.  The caller shall handle writing the END
-     * record into the stream.  (Any records which need to be after the memory
-     * is complete.)
+     * Send records which need to be at the start of a checkpoint.  This is
+     * called once, or once per checkpoint in a checkpointed stream, and is
+     * ahead of memory data.
+     */
+    int (*start_of_checkpoint)(struct xc_sr_context *ctx);
+
+    /**
+     * Send records which need to be at the end of the checkpoint.  This is
+     * called once, or once per checkpoint in a checkpointed stream, and is
+     * after the memory data.
+     */
+    int (*end_of_checkpoint)(struct xc_sr_context *ctx);
+
+    /**
+     * Send records which need to be at the end of the stream.  This is called
+     * once, before the END record is written.
      */
     int (*end_of_stream)(struct xc_sr_context *ctx);
 
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index 5d9c267..49c65e9 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -662,6 +662,10 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
     if ( rc )
         goto err;
 
+    rc = ctx->save.ops.start_of_checkpoint(ctx);
+    if ( rc )
+        goto err;
+
     if ( ctx->save.live )
         rc = send_domain_memory_live(ctx);
     else
@@ -678,6 +682,10 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
         goto err;
     }
 
+    rc = ctx->save.ops.end_of_checkpoint(ctx);
+    if ( rc )
+        goto err;
+
     xc_report_progress_single(xch, "End of stream");
 
     rc = ctx->save.ops.end_of_stream(ctx);
diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c
index 8baa104..4ad1264 100644
--- a/tools/libxc/xc_sr_save_x86_hvm.c
+++ b/tools/libxc/xc_sr_save_x86_hvm.c
@@ -191,32 +191,42 @@ static int x86_hvm_start_of_stream(struct xc_sr_context 
*ctx)
     return 0;
 }
 
-static int x86_hvm_end_of_stream(struct xc_sr_context *ctx)
+static int x86_hvm_start_of_checkpoint(struct xc_sr_context *ctx)
+{
+    /* no-op */
+    return 0;
+}
+
+static int x86_hvm_end_of_checkpoint(struct xc_sr_context *ctx)
 {
     int rc;
 
-    /* Write the TSC record. */
-    rc = write_tsc_info(ctx);
+    rc = write_hvm_context(ctx);
     if ( rc )
         return rc;
 
-#ifdef XG_LIBXL_HVM_COMPAT
-    rc = write_toolstack(ctx);
+    rc = write_hvm_params(ctx);
     if ( rc )
         return rc;
-#endif
 
-    /* Write the HVM_CONTEXT record. */
-    rc = write_hvm_context(ctx);
+    return 0;
+}
+
+static int x86_hvm_end_of_stream(struct xc_sr_context *ctx)
+{
+    int rc;
+
+    rc = write_tsc_info(ctx);
     if ( rc )
         return rc;
 
-    /* Write HVM_PARAMS record contains applicable HVM params. */
-    rc = write_hvm_params(ctx);
+#ifdef XG_LIBXL_HVM_COMPAT
+    rc = write_toolstack(ctx);
     if ( rc )
         return rc;
+#endif
 
-    return rc;
+    return 0;
 }
 
 static int x86_hvm_cleanup(struct xc_sr_context *ctx)
@@ -237,12 +247,14 @@ static int x86_hvm_cleanup(struct xc_sr_context *ctx)
 
 struct xc_sr_save_ops save_ops_x86_hvm =
 {
-    .pfn_to_gfn      = x86_hvm_pfn_to_gfn,
-    .normalise_page  = x86_hvm_normalise_page,
-    .setup           = x86_hvm_setup,
-    .start_of_stream = x86_hvm_start_of_stream,
-    .end_of_stream   = x86_hvm_end_of_stream,
-    .cleanup         = x86_hvm_cleanup,
+    .pfn_to_gfn          = x86_hvm_pfn_to_gfn,
+    .normalise_page      = x86_hvm_normalise_page,
+    .setup               = x86_hvm_setup,
+    .start_of_stream     = x86_hvm_start_of_stream,
+    .start_of_checkpoint = x86_hvm_start_of_checkpoint,
+    .end_of_checkpoint   = x86_hvm_end_of_checkpoint,
+    .end_of_stream       = x86_hvm_end_of_stream,
+    .cleanup             = x86_hvm_cleanup,
 };
 
 /*
diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c
index a668221..df54ef3 100644
--- a/tools/libxc/xc_sr_save_x86_pv.c
+++ b/tools/libxc/xc_sr_save_x86_pv.c
@@ -805,9 +805,6 @@ static int x86_pv_setup(struct xc_sr_context *ctx)
     return 0;
 }
 
-/*
- * save_ops function.  Writes PV header records into the stream.
- */
 static int x86_pv_start_of_stream(struct xc_sr_context *ctx)
 {
     int rc;
@@ -816,6 +813,12 @@ static int x86_pv_start_of_stream(struct xc_sr_context 
*ctx)
     if ( rc )
         return rc;
 
+    /*
+     * Ideally should be able to change during migration.  Currently
+     * corruption will occur if the contents or location of the P2M changes
+     * during the live migration loop.  If one is very lucky, the breakage
+     * will not be subtle.
+     */
     rc = write_x86_pv_p2m_frames(ctx);
     if ( rc )
         return rc;
@@ -823,22 +826,31 @@ static int x86_pv_start_of_stream(struct xc_sr_context 
*ctx)
     return 0;
 }
 
-/*
- * save_ops function.  Writes tail records information into the stream.
- */
-static int x86_pv_end_of_stream(struct xc_sr_context *ctx)
+static int x86_pv_start_of_checkpoint(struct xc_sr_context *ctx)
+{
+    return 0;
+}
+
+static int x86_pv_end_of_checkpoint(struct xc_sr_context *ctx)
 {
     int rc;
 
-    rc = write_tsc_info(ctx);
+    rc = write_all_vcpu_information(ctx);
     if ( rc )
         return rc;
 
-    rc = write_shared_info(ctx);
+    return 0;
+}
+
+static int x86_pv_end_of_stream(struct xc_sr_context *ctx)
+{
+    int rc;
+
+    rc = write_tsc_info(ctx);
     if ( rc )
         return rc;
 
-    rc = write_all_vcpu_information(ctx);
+    rc = write_shared_info(ctx);
     if ( rc )
         return rc;
 
@@ -866,12 +878,14 @@ static int x86_pv_cleanup(struct xc_sr_context *ctx)
 
 struct xc_sr_save_ops save_ops_x86_pv =
 {
-    .pfn_to_gfn      = x86_pv_pfn_to_gfn,
-    .normalise_page  = x86_pv_normalise_page,
-    .setup           = x86_pv_setup,
-    .start_of_stream = x86_pv_start_of_stream,
-    .end_of_stream   = x86_pv_end_of_stream,
-    .cleanup         = x86_pv_cleanup,
+    .pfn_to_gfn          = x86_pv_pfn_to_gfn,
+    .normalise_page      = x86_pv_normalise_page,
+    .setup               = x86_pv_setup,
+    .start_of_stream     = x86_pv_start_of_stream,
+    .start_of_checkpoint = x86_pv_start_of_checkpoint,
+    .end_of_checkpoint   = x86_pv_end_of_checkpoint,
+    .end_of_stream       = x86_pv_end_of_stream,
+    .cleanup             = x86_pv_cleanup,
 };
 
 /*
-- 
1.7.10.4


_______________________________________________
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®.