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

[Xen-devel] [PATCH v2 1/2] libxc: introduce XC_SAVE_ID_TOOLSTACK



Introduce a new save_id to save/restore toolstack specific extra
information.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 tools/libxc/xc_domain_restore.c |   66 +++++++++++++++++++++++++++-----------
 tools/libxc/xc_domain_save.c    |   17 ++++++++++
 tools/libxc/xenguest.h          |   23 +++++++++++++-
 tools/libxc/xg_save_restore.h   |    1 +
 tools/libxl/libxl_dom.c         |    2 +-
 tools/xcutils/xc_restore.c      |    3 +-
 6 files changed, 90 insertions(+), 22 deletions(-)

diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 14451d1..72b6d5b 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -702,7 +702,8 @@ static void pagebuf_free(pagebuf_t* buf)
 }
 
 static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx,
-                           pagebuf_t* buf, int fd, uint32_t dom)
+                           pagebuf_t* buf, int fd, uint32_t dom,
+                           struct restore_callbacks* callbacks)
 {
     int count, countpages, oldcount, i;
     void* ptmp;
@@ -725,7 +726,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
     case XC_SAVE_ID_ENABLE_VERIFY_MODE:
         DPRINTF("Entering page verify mode\n");
         buf->verify = 1;
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_VCPU_INFO:
         buf->new_ctxt_format = 1;
@@ -736,7 +737,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             return -1;
         }
         // DPRINTF("Max VCPU ID: %d, vcpumap: %llx\n", buf->max_vcpu_id, 
buf->vcpumap);
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_HVM_IDENT_PT:
         /* Skip padding 4 bytes then read the EPT identity PT location. */
@@ -747,7 +748,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             return -1;
         }
         // DPRINTF("EPT identity map address: %llx\n", buf->identpt);
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_HVM_VM86_TSS:
         /* Skip padding 4 bytes then read the vm86 TSS location. */
@@ -758,7 +759,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             return -1;
         }
         // DPRINTF("VM86 TSS location: %llx\n", buf->vm86_tss);
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_TMEM:
         DPRINTF("xc_domain_restore start tmem\n");
@@ -766,14 +767,14 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             PERROR("error reading/restoring tmem");
             return -1;
         }
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_TMEM_EXTRA:
         if ( xc_tmem_restore_extra(xch, dom, fd) ) {
             PERROR("error reading/restoring tmem extra");
             return -1;
         }
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_TSC_INFO:
     {
@@ -787,7 +788,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             PERROR("error reading/restoring tsc info");
             return -1;
         }
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
     }
 
     case XC_SAVE_ID_HVM_CONSOLE_PFN :
@@ -799,12 +800,12 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             return -1;
         }
         // DPRINTF("console pfn location: %llx\n", buf->console_pfn);
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_LAST_CHECKPOINT:
         ctx->last_checkpoint = 1;
         // DPRINTF("last checkpoint indication received");
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION:
         /* Skip padding 4 bytes then read the acpi ioport location. */
@@ -814,7 +815,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             PERROR("error read the acpi ioport location");
             return -1;
         }
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_HVM_VIRIDIAN:
         /* Skip padding 4 bytes then read the acpi ioport location. */
@@ -824,8 +825,33 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             PERROR("error read the viridian flag");
             return -1;
         }
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
+    case XC_SAVE_ID_TOOLSTACK:
+        {
+            uint32_t len;
+            uint8_t *buf2;
+            RDEXACT(fd, &len, sizeof(len));
+            buf2 = (uint8_t*) malloc(len);
+            if ( buf2 == NULL )
+            {
+                PERROR("error memory allocation");
+                return -1;
+            }
+            RDEXACT(fd, buf2, len);
+            if ( callbacks != NULL && callbacks->toolstack_restore != NULL )
+            {
+                if ( callbacks->toolstack_restore(dom,
+                            buf2, len, callbacks->data) < 0 )
+                {
+                    PERROR("error calling toolstack_restore");
+                    free(buf2);
+                    return -1;
+                }
+            }
+            free(buf2);
+            return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
+        }
     case XC_SAVE_ID_ENABLE_COMPRESSION:
         /* We cannot set compression flag directly in pagebuf structure,
          * since this pagebuf still has uncompressed pages that are yet to
@@ -834,7 +860,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
          */
         ctx->compressing = 1;
         // DPRINTF("compression flag received");
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     case XC_SAVE_ID_COMPRESSED_DATA:
 
@@ -902,7 +928,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
      * following a <XC_SAVE_ID_COMPRESSED_DATA, compressedChunkSize> tuple.
      */
     if (buf->compressing)
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
 
     oldcount = buf->nr_physpages;
     buf->nr_physpages += countpages;
@@ -927,7 +953,8 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
 }
 
 static int pagebuf_get(xc_interface *xch, struct restore_ctx *ctx,
-                       pagebuf_t* buf, int fd, uint32_t dom)
+                       pagebuf_t* buf, int fd, uint32_t dom,
+                       struct restore_callbacks *callbacks)
 {
     int rc;
 
@@ -935,7 +962,7 @@ static int pagebuf_get(xc_interface *xch, struct 
restore_ctx *ctx,
     buf->compbuf_pos = buf->compbuf_size = 0;
 
     do {
-        rc = pagebuf_get_one(xch, ctx, buf, fd, dom);
+        rc = pagebuf_get_one(xch, ctx, buf, fd, dom, callbacks);
     } while (rc > 0);
 
     if (rc < 0)
@@ -1248,7 +1275,8 @@ static int apply_batch(xc_interface *xch, uint32_t dom, 
struct restore_ctx *ctx,
 int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
                       unsigned int console_evtchn, unsigned long *console_mfn,
-                      unsigned int hvm, unsigned int pae, int superpages)
+                      unsigned int hvm, unsigned int pae, int superpages,
+                      struct restore_callbacks* callbacks)
 {
     DECLARE_DOMCTL;
     int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0;
@@ -1427,7 +1455,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
         if ( !ctx->completed ) {
             pagebuf.nr_physpages = pagebuf.nr_pages = 0;
             pagebuf.compbuf_pos = pagebuf.compbuf_size = 0;
-            if ( pagebuf_get_one(xch, ctx, &pagebuf, io_fd, dom) < 0 ) {
+            if ( pagebuf_get_one(xch, ctx, &pagebuf, io_fd, dom, callbacks) < 
0 ) {
                 PERROR("Error when reading batch");
                 goto out;
             }
@@ -1542,7 +1570,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 
     // DPRINTF("Buffered checkpoint\n");
 
-    if ( pagebuf_get(xch, ctx, &pagebuf, io_fd, dom) ) {
+    if ( pagebuf_get(xch, ctx, &pagebuf, io_fd, dom, callbacks) ) {
         PERROR("error when buffering batch, finishing");
         goto finish;
     }
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index a6bb894..67bcfe2 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -1676,6 +1676,23 @@ int xc_domain_save(xc_interface *xch, int io_fd, 
uint32_t dom, uint32_t max_iter
         }
     }
 
+    if ( callbacks != NULL && callbacks->toolstack_save != NULL )
+    {
+        int id = XC_SAVE_ID_TOOLSTACK;
+        uint8_t *buf;
+        uint32_t len;
+
+        if ( callbacks->toolstack_save(dom, &buf, &len, callbacks->data) < 0 )
+        {
+            PERROR("Error calling toolstack_save");
+            goto out;
+        }
+        wrexact(io_fd, &id, sizeof(id));
+        wrexact(io_fd, &len, sizeof(len));
+        wrexact(io_fd, buf, len);
+        free(buf);
+    }
+
     if ( !callbacks->checkpoint )
     {
         /*
diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h
index 4475ee9..3cac30c 100644
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -44,6 +44,14 @@ struct save_callbacks {
     /* Enable qemu-dm logging dirty pages to xen */
     int (*switch_qemu_logdirty)(int domid, unsigned enable, void *data); /* 
HVM only */
 
+    /* Save toolstack specific data
+     * @param buf the buffer with the data to be saved
+     * @param len the length of the buffer
+     * The callee allocates the buffer, the caller frees it (buffer must
+     * be free'able).
+     */
+    int (*toolstack_save)(uint32_t domid, uint8_t **buf, uint32_t *len, void 
*data);
+
     /* to be provided as the last argument to each callback function */
     void* data;
 };
@@ -61,6 +69,16 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                    struct save_callbacks* callbacks, int hvm);
 
 
+/* callbacks provided by xc_domain_restore */
+struct restore_callbacks {
+    /* callback to restore toolstack specific data */
+    int (*toolstack_restore)(uint32_t domid, uint8_t *buf,
+            uint32_t size, void* data);
+
+    /* to be provided as the last argument to each callback function */
+    void* data;
+};
+
 /**
  * This function will restore a saved domain.
  *
@@ -72,12 +90,15 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
  * @parm hvm non-zero if this is a HVM restore
  * @parm pae non-zero if this HVM domain has PAE support enabled
  * @parm superpages non-zero to allocate guest memory with superpages
+ * @parm callbacks non-NULL to receive a callback to restore toolstack
+ *       specific data
  * @return 0 on success, -1 on failure
  */
 int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
                       unsigned int console_evtchn, unsigned long *console_mfn,
-                      unsigned int hvm, unsigned int pae, int superpages);
+                      unsigned int hvm, unsigned int pae, int superpages,
+                      struct restore_callbacks *callbacks);
 /**
  * xc_domain_restore writes a file to disk that contains the device
  * model saved state.
diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h
index c5e0743..68feec5 100644
--- a/tools/libxc/xg_save_restore.h
+++ b/tools/libxc/xg_save_restore.h
@@ -253,6 +253,7 @@
 #define XC_SAVE_ID_HVM_VIRIDIAN       -11
 #define XC_SAVE_ID_COMPRESSED_DATA    -12 /* Marker to indicate arrival of 
compressed data */
 #define XC_SAVE_ID_ENABLE_COMPRESSION -13 /* Marker to enable compression 
logic at receiver side */
+#define XC_SAVE_ID_TOOLSTACK          -14 /* Optional toolstack specific info 
*/
 
 /*
 ** We process save/restore/migrate in batches of pages; the below
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index c898d89..fd2b051 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -373,7 +373,7 @@ int libxl__domain_restore_common(libxl__gc *gc, uint32_t 
domid,
     rc = xc_domain_restore(ctx->xch, fd, domid,
                            state->store_port, &state->store_mfn,
                            state->console_port, &state->console_mfn,
-                           hvm, pae, superpages);
+                           hvm, pae, superpages, NULL);
     if ( rc ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain");
         return ERROR_FAIL;
diff --git a/tools/xcutils/xc_restore.c b/tools/xcutils/xc_restore.c
index 985cbec..eb1d31c 100644
--- a/tools/xcutils/xc_restore.c
+++ b/tools/xcutils/xc_restore.c
@@ -46,7 +46,8 @@ main(int argc, char **argv)
            superpages = !!hvm;
 
     ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn,
-                            console_evtchn, &console_mfn, hvm, pae, 
superpages);
+                            console_evtchn, &console_mfn, hvm, pae, superpages,
+                            NULL);
 
     if ( ret == 0 )
     {
-- 
1.7.2.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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