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