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

[Xen-devel] [PATCH v2 07/17] libxc/restore: STATIC_DATA_END inference for v2 compatibility



A v3 stream can compatibly read a v2 stream by inferring the position of the
STATIC_DATA_END record.

v2 compatibility is only needed for x86.  No other architectures exist yet,
but they will have a minimum of v3 when introduced.

The x86 HVM compatibility point being in handle_page_data() (which is common
code) is a bit awkward.  However, as the two compatibility points are subtly
different, and it is (intentionally) not possible to call into arch specific
code from common code (except via the ops hooks), use some #ifdef-ary and
opencode the check, rather than make handle_page_data() a per-arch helper.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Ian Jackson <Ian.Jackson@xxxxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>

v2:
 * Split/rearranged from v1
 * Rewrite the commit message to explain why compatibility is done this way.
---
 tools/libxc/include/xenguest.h     |  2 +-
 tools/libxc/xc_sr_common.h         |  5 ++++-
 tools/libxc/xc_sr_restore.c        | 27 ++++++++++++++++++++++++++-
 tools/libxc/xc_sr_restore_x86_pv.c | 17 +++++++++++++++++
 4 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index efd90b0d42..b4df8d0ffe 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -139,7 +139,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom,
 
 /* callbacks provided by xc_domain_restore */
 struct restore_callbacks {
-    /* Called once the STATIC_DATA_END record has been received. */
+    /* Called once the STATIC_DATA_END record has been received/inferred. */
     int (*static_data_done)(void *data);
 
     /* Called after a new checkpoint to suspend the guest. */
diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index ae0ab70f76..51e3d3ee3b 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -253,7 +253,7 @@ struct xc_sr_context
             /* Currently buffering records between a checkpoint */
             bool buffer_all_records;
 
-            /* Whether a STATIC_DATA_END record has been seen. */
+            /* Whether a STATIC_DATA_END record has been seen/inferred. */
             bool seen_static_data_end;
 
 /*
@@ -428,6 +428,9 @@ int read_record(struct xc_sr_context *ctx, int fd, struct 
xc_sr_record *rec);
 int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
                   const xen_pfn_t *original_pfns, const uint32_t *types);
 
+/* Handle a STATIC_DATA_END record. */
+int handle_static_data_end(struct xc_sr_context *ctx);
+
 #endif
 /*
  * Local variables:
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 9c924387ae..bb94cd879d 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -342,6 +342,31 @@ static int handle_page_data(struct xc_sr_context *ctx, 
struct xc_sr_record *rec)
     xen_pfn_t *pfns = NULL, pfn;
     uint32_t *types = NULL, type;
 
+    /*
+     * v2 compatibility only exists for x86 streams.  This is a bit of a
+     * bodge, but it is less bad than duplicating handle_page_data() between
+     * different architectures.
+     */
+#if defined(__i386__) || defined(__x86_64__)
+    /* v2 compat.  Infer the position of STATIC_DATA_END. */
+    if ( ctx->restore.format_version < 3 && !ctx->restore.seen_static_data_end 
)
+    {
+        rc = handle_static_data_end(ctx);
+        if ( rc )
+        {
+            ERROR("Inferred STATIC_DATA_END record failed");
+            goto err;
+        }
+        rc = -1;
+    }
+
+    if ( !ctx->restore.seen_static_data_end )
+    {
+        ERROR("No STATIC_DATA_END seen");
+        goto err;
+    }
+#endif
+
     if ( rec->length < sizeof(*pages) )
     {
         ERROR("PAGE_DATA record truncated: length %u, min %zu",
@@ -631,7 +656,7 @@ static int buffer_record(struct xc_sr_context *ctx, struct 
xc_sr_record *rec)
     return 0;
 }
 
-static int handle_static_data_end(struct xc_sr_context *ctx)
+int handle_static_data_end(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
     int rc = 0;
diff --git a/tools/libxc/xc_sr_restore_x86_pv.c 
b/tools/libxc/xc_sr_restore_x86_pv.c
index 16e738884e..3756225be6 100644
--- a/tools/libxc/xc_sr_restore_x86_pv.c
+++ b/tools/libxc/xc_sr_restore_x86_pv.c
@@ -679,6 +679,23 @@ static int handle_x86_pv_p2m_frames(struct xc_sr_context 
*ctx,
     unsigned int start, end, x, fpp = PAGE_SIZE / ctx->x86.pv.width;
     int rc;
 
+    /* v2 compat.  Infer the position of STATIC_DATA_END. */
+    if ( ctx->restore.format_version < 3 && !ctx->restore.seen_static_data_end 
)
+    {
+        rc = handle_static_data_end(ctx);
+        if ( rc )
+        {
+            ERROR("Inferred STATIC_DATA_END record failed");
+            return rc;
+        }
+    }
+
+    if ( !ctx->restore.seen_static_data_end )
+    {
+        ERROR("No STATIC_DATA_END seen");
+        return -1;
+    }
+
     if ( !ctx->x86.pv.restore.seen_pv_info )
     {
         ERROR("Not yet received X86_PV_INFO record");
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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