[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] libxl: save/restore qemu's physmap
Read Qemu's physmap from xenstore and save it using toolstack_save. Restore Qemu's physmap using toolstack_restore. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> --- tools/libxl/libxl_dom.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 131 insertions(+), 1 deletions(-) diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index fd2b051..3d60a35 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -347,6 +347,62 @@ out: return rc; } +static int libxl__toolstack_restore(uint32_t domid, uint8_t *buf, + uint32_t size, void *data) +{ + libxl__gc *gc = (libxl__gc *) data; + int i, ret; + uint8_t *ptr = buf; + uint32_t namelen = 0; + char *name = NULL; + uint32_t count = 0; + uint64_t phys_offset_v = 0, start_addr_v = 0, size_v = 0; + + if (size < sizeof(count)) + return -1; + + memcpy(&count, ptr, sizeof(count)); + ptr += sizeof(count); + + if (size < + sizeof(count) + count * (sizeof(uint64_t) * 3 + sizeof(uint32_t))) + return -1; + + for (i = 0; i < count; i++) { + memcpy(&namelen, ptr, sizeof(namelen)); + ptr += sizeof(namelen); + if (namelen > 0) { + name = (char *)ptr; + ptr += namelen; + } + memcpy(&phys_offset_v, ptr, sizeof(uint64_t)); + ptr += sizeof(uint64_t); + memcpy(&start_addr_v, ptr, sizeof(uint64_t)); + ptr += sizeof(uint64_t); + memcpy(&size_v, ptr, sizeof(uint64_t)); + ptr += sizeof(uint64_t); + + ret = libxl__xs_write(gc, 0, libxl__sprintf(gc, + "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr", + domid, phys_offset_v), "%"PRIx64, start_addr_v); + if (ret) + return -1; + ret = libxl__xs_write(gc, 0, libxl__sprintf(gc, + "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size", + domid, phys_offset_v), "%"PRIx64, size_v); + if (ret) + return -1; + if (namelen > 0) { + ret = libxl__xs_write(gc, 0, libxl__sprintf(gc, + "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name", + domid, phys_offset_v), "%s", name); + if (ret) + return -1; + } + } + return 0; +} + int libxl__domain_restore_common(libxl__gc *gc, uint32_t domid, libxl_domain_build_info *info, libxl__domain_build_state *state, @@ -356,11 +412,14 @@ int libxl__domain_restore_common(libxl__gc *gc, uint32_t domid, /* read signature */ int rc; int hvm, pae, superpages; + struct restore_callbacks callbacks; switch (info->type) { case LIBXL_DOMAIN_TYPE_HVM: hvm = 1; superpages = 1; pae = info->u.hvm.pae; + callbacks.toolstack_restore = libxl__toolstack_restore; + callbacks.data = gc; break; case LIBXL_DOMAIN_TYPE_PV: hvm = 0; @@ -373,7 +432,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, NULL); + hvm, pae, superpages, &callbacks); if ( rc ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain"); return ERROR_FAIL; @@ -528,6 +587,76 @@ static int libxl__domain_suspend_common_callback(void *data) return 0; } +static int libxl__toolstack_save(uint32_t domid, uint8_t **buf, + uint32_t *len, void *data) +{ + struct suspendinfo *si = (struct suspendinfo *) data; + libxl__gc *gc = (libxl__gc *) si->gc; + char *start_addr = NULL, *size = NULL, *phys_offset = NULL, *name = NULL; + int i = 0; + unsigned int num = 0; + uint32_t count = 0; + uint8_t *ptr = NULL; + char **entries = NULL; + uint64_t val = 0; + uint32_t namelen = 0; + + entries = libxl__xs_directory(gc, 0, libxl__sprintf(gc, + "/local/domain/0/device-model/%d/physmap", domid), &num); + count = num; + + *len = sizeof(count) + count * (sizeof(val) * 3 + sizeof(namelen)); + *buf = libxl__calloc(gc, 1, *len); + ptr = *buf; + + memcpy(ptr, &count, sizeof(count)); + ptr += sizeof(count); + + for (i = 0; i < count; i++) { + phys_offset = entries[i]; + start_addr = libxl__xs_read(gc, 0, libxl__sprintf(gc, + "/local/domain/0/device-model/%d/physmap/%s/start_addr", + domid, phys_offset)); + size = libxl__xs_read(gc, 0, libxl__sprintf(gc, + "/local/domain/0/device-model/%d/physmap/%s/size", + domid, phys_offset)); + name = libxl__xs_read(gc, 0, libxl__sprintf(gc, + "/local/domain/0/device-model/%d/physmap/%s/name", + domid, phys_offset)); + + if (start_addr == NULL || size == NULL || phys_offset == NULL) + return -1; + + if (name == NULL) { + namelen = 0; + } else { + unsigned long offset; + namelen = strlen(name) + 1; + *len += namelen; + offset = ptr - (*buf); + *buf = libxl__realloc(gc, *buf, *len); + ptr = (*buf) + offset; + } + memcpy(ptr, &namelen, sizeof(namelen)); + ptr += sizeof(namelen); + if (namelen > 0) { + memcpy(ptr, name, namelen); + ptr += namelen; + } + val = strtoll(phys_offset, NULL, 16); + memcpy(ptr, &val, sizeof(val)); + ptr += sizeof(val); + val = strtoll(start_addr, NULL, 16); + memcpy(ptr, &val, sizeof(val)); + ptr += sizeof(val); + val = strtoll(size, NULL, 16); + memcpy(ptr, &val, sizeof(val)); + ptr += sizeof(val); + } + + return 0; +} + int libxl__domain_suspend_common(libxl__gc *gc, uint32_t domid, int fd, libxl_domain_type type, int live, int debug) @@ -579,6 +708,7 @@ int libxl__domain_suspend_common(libxl__gc *gc, uint32_t domid, int fd, memset(&callbacks, 0, sizeof(callbacks)); callbacks.suspend = libxl__domain_suspend_common_callback; callbacks.switch_qemu_logdirty = libxl__domain_suspend_common_switch_qemu_logdirty; + callbacks.toolstack_save = libxl__toolstack_save; callbacks.data = &si; rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm); -- 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 |