[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |