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

[xen staging] libxc/restore: STATIC_DATA_END inference for v2 compatibility



commit 4f8b684117f7e6cc02dfbb21cde15aa431259d2c
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Mon Dec 16 19:03:14 2019 +0000
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri May 29 17:33:03 2020 +0100

    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>
    Acked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
 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 904ccc462a..0adfcdcdda 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");
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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