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

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



On Tue, 31 Jan 2012, Shriram Rajagopalan wrote:
> Or if you have to receive them in the pagebuf, then have two pieces of the 
> same state,
>  consistent_state, curr_state, such that you do
> 
>  pagebuf_get(curr_state)
>  tailbuf_get(..)..
>  if (no error so far), then
>   copy curr_state to consistent_state.
>   goto copypages;
> 
> finish:
>  ..
>   finish_hvm:
>      apply consistent_state.

I think I am starting to understand: see appended patch if it makes
things better.

---

diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 3fda6f8..02b523d 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -684,6 +684,11 @@ typedef struct {
     uint64_t vm_generationid_addr;
 } pagebuf_t;
 
+struct toolstack_data_t {
+    uint8_t *data;
+    uint32_t len;
+};
+
 static int pagebuf_init(pagebuf_t* buf)
 {
     memset(buf, 0, sizeof(*buf));
@@ -703,7 +708,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 toolstack_data_t *tdata)
 {
     int count, countpages, oldcount, i;
     void* ptmp;
@@ -726,7 +732,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, tdata);
 
     case XC_SAVE_ID_VCPU_INFO:
         buf->new_ctxt_format = 1;
@@ -737,7 +743,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, tdata);
 
     case XC_SAVE_ID_HVM_IDENT_PT:
         /* Skip padding 4 bytes then read the EPT identity PT location. */
@@ -748,7 +754,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, tdata);
 
     case XC_SAVE_ID_HVM_VM86_TSS:
         /* Skip padding 4 bytes then read the vm86 TSS location. */
@@ -759,7 +765,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, tdata);
 
     case XC_SAVE_ID_TMEM:
         DPRINTF("xc_domain_restore start tmem\n");
@@ -767,14 +773,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, tdata);
 
     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, tdata);
 
     case XC_SAVE_ID_TSC_INFO:
     {
@@ -788,7 +794,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, tdata);
     }
 
     case XC_SAVE_ID_HVM_CONSOLE_PFN :
@@ -800,12 +806,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, tdata);
 
     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, tdata);
 
     case XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION:
         /* Skip padding 4 bytes then read the acpi ioport location. */
@@ -815,7 +821,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, tdata);
 
     case XC_SAVE_ID_HVM_VIRIDIAN:
         /* Skip padding 4 bytes then read the acpi ioport location. */
@@ -825,7 +831,20 @@ 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, tdata);
+
+    case XC_SAVE_ID_TOOLSTACK:
+        {
+            RDEXACT(fd, &tdata->len, sizeof(tdata->len));
+            tdata->data = (uint8_t*) realloc(tdata->data, tdata->len);
+            if ( tdata->data == NULL )
+            {
+                PERROR("error memory allocation");
+                return -1;
+            }
+            RDEXACT(fd, tdata->data, tdata->len);
+            return pagebuf_get_one(xch, ctx, buf, fd, dom, tdata);
+        }
 
     case XC_SAVE_ID_ENABLE_COMPRESSION:
         /* We cannot set compression flag directly in pagebuf structure,
@@ -835,7 +854,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, tdata);
 
     case XC_SAVE_ID_COMPRESSED_DATA:
 
@@ -870,7 +889,7 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
             return -1;
         }
         DPRINTF("read generation id buffer address");
-        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom, tdata);
 
     default:
         if ( (count > MAX_BATCH_SIZE) || (count < 0) ) {
@@ -914,7 +933,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, tdata);
 
     oldcount = buf->nr_physpages;
     buf->nr_physpages += countpages;
@@ -939,7 +958,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 toolstack_data_t *tdata)
 {
     int rc;
 
@@ -947,7 +967,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, tdata);
     } while (rc > 0);
 
     if (rc < 0)
@@ -1262,7 +1282,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
                       unsigned int console_evtchn, unsigned long *console_mfn,
                       unsigned int hvm, unsigned int pae, int superpages,
                       int no_incr_generationid,
-                      unsigned long *vm_generationid_addr)
+                      unsigned long *vm_generationid_addr,
+                      struct restore_callbacks *callbacks)
 {
     DECLARE_DOMCTL;
     int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0;
@@ -1310,6 +1331,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 
     pagebuf_t pagebuf;
     tailbuf_t tailbuf, tmptail;
+    struct toolstack_data_t tdata, tdata2, tdatatmp;
     void* vcpup;
     uint64_t console_pfn = 0;
 
@@ -1322,6 +1344,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
     pagebuf_init(&pagebuf);
     memset(&tailbuf, 0, sizeof(tailbuf));
     tailbuf.ishvm = hvm;
+    memset(&tdata, 0, sizeof(tdata));
+    memset(&tdata2, 0, sizeof(tdata2));
 
     memset(ctx, 0, sizeof(*ctx));
 
@@ -1441,7 +1465,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, &tdata) < 0 ) 
{
                 PERROR("Error when reading batch");
                 goto out;
             }
@@ -1589,7 +1613,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, &tdata2) ) {
         PERROR("error when buffering batch, finishing");
         goto finish;
     }
@@ -1602,6 +1626,9 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
     }
     tailbuf_free(&tailbuf);
     memcpy(&tailbuf, &tmptail, sizeof(tailbuf));
+    tdatatmp = tdata;
+    tdata = tdata2;
+    tdata2 = tdatatmp;
 
     goto loadpages;
 
@@ -2023,6 +2050,20 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
     goto out;
 
   finish_hvm:
+    if ( callbacks != NULL && callbacks->toolstack_restore != NULL )
+    {
+        if ( callbacks->toolstack_restore(dom, tdata.data, tdata.len,
+                    callbacks->data) < 0 )
+        {
+            PERROR("error calling toolstack_restore");
+            free(tdata.data);
+            free(tdata2.data);
+            goto out;
+        }
+    }
+    free(tdata.data);
+    free(tdata2.data);
+
     /* Dump the QEMU state to a state file for QEMU to load */
     if ( dump_qemu(xch, dom, &tailbuf.u.hvm) ) {
         PERROR("Error dumping QEMU state to file");
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index f473dd7..318c433 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -1687,6 +1687,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 6026370..76aa475 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;
 };
@@ -62,6 +70,16 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                    unsigned long vm_generationid_addr);
 
 
+/* 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.
  *
@@ -75,6 +93,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
  * @parm superpages non-zero to allocate guest memory with superpages
  * @parm no_incr_generationid non-zero if generation id is NOT to be 
incremented
  * @parm vm_generationid_addr returned with the address of the generation id 
buffer
+ * @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,
@@ -82,7 +102,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t 
dom,
                       unsigned int console_evtchn, unsigned long *console_mfn,
                       unsigned int hvm, unsigned int pae, int superpages,
                       int no_incr_generationid,
-                     unsigned long *vm_generationid_addr);
+                      unsigned long *vm_generationid_addr,
+                      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 6286b68..46fdeaa 100644
--- a/tools/libxc/xg_save_restore.h
+++ b/tools/libxc/xg_save_restore.h
@@ -254,6 +254,7 @@
 #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_HVM_GENERATION_ID_ADDR -14
+#define XC_SAVE_ID_TOOLSTACK          -15 /* 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 91643a2..2c5eec5 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -379,7 +379,7 @@ int libxl__domain_restore_common(libxl__gc *gc, uint32_t 
domid,
                            state->store_port, &state->store_mfn,
                            state->console_port, &state->console_mfn,
                            hvm, pae, superpages, no_incr_generationid,
-                           &state->vm_generationid_addr);
+                           &state->vm_generationid_addr, 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 63d53a8..306a10e 100644
--- a/tools/xcutils/xc_restore.c
+++ b/tools/xcutils/xc_restore.c
@@ -47,7 +47,7 @@ main(int argc, char **argv)
 
     ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn,
                             console_evtchn, &console_mfn, hvm, pae, superpages,
-                            0, NULL);
+                            0, NULL, NULL);
 
     if ( ret == 0 )
     {
_______________________________________________
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®.