[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3/3] libxl: introduce QEMU_HEADER
Introduce a new QEMU_HEADER stored in the Qemu chunk right after the QEMU_SIGNATURE and record length, before the Qemu state, to preserve the physmap informations written by Qemu on xenstore. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> --- tools/libxl/libxl_dom.c | 104 ++++++++++++++++++++++++++++++++++++++++-- tools/libxl/libxl_internal.h | 1 + 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index f33e572..0f3d0c3 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -359,9 +359,47 @@ static int libxl__domain_restore_device_model(uint8_t *buf, uint32_t size, libxl__gc *gc = (libxl__gc *)arg->gc; libxl_ctx *ctx = libxl__gc_owner(gc); uint32_t domid = arg->domid; - int fd2 = -1, ret = 0; + int fd2 = -1, ret = 0, i = 0; const char *filename; + uint8_t *ptr = buf; + uint32_t count = 0; + uint64_t phys_offset_v = 0, start_addr_v = 0, size_v = 0; + uint32_t header_size = 0; + + if (strncmp((char *)ptr, QEMU_HEADER, size)) + goto no_header; + + ptr += sizeof(QEMU_HEADER); + memcpy(&count, ptr, sizeof(count)); + ptr += sizeof(count); + header_size = sizeof(QEMU_HEADER) + sizeof(count) + count * sizeof(uint64_t) * 3; + size -= header_size; + + for (i = 0; i < count; i++) { + 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) { + ptr = buf + header_size; + break; + } + 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) { + ptr = buf + header_size; + break; + } + } +no_header: filename = libxl__device_model_restorefile(gc, domid); fd2 = open(filename, O_WRONLY|O_CREAT); if (fd2 < 0) { @@ -370,7 +408,7 @@ static int libxl__domain_restore_device_model(uint8_t *buf, uint32_t size, } ret = libxl_write_exactly( - ctx, fd2, buf, size, "saved-state file", "qemu state"); + ctx, fd2, ptr, size, "saved-state file", "qemu state"); if (ret) goto out; ret = 0; @@ -642,11 +680,61 @@ out: return rc; } +static int libxl__domain_save_qemu_header(libxl__gc *gc, uint32_t domid, + int fd, char **buf) +{ + char *start_addr = NULL, *size = NULL, *phys_offset = NULL; + int len = 0, i = 0; + unsigned int num = 0; + uint32_t count = 0; + char *ptr = NULL, **entries = NULL; + uint64_t val = 0; + + entries = libxl__xs_directory(gc, 0, libxl__sprintf(gc, + "/local/domain/0/device-model/%d/physmap", domid), &num); + count = num; + + len = sizeof(QEMU_HEADER) + sizeof(count) + count * (sizeof(val) * 3); + *buf = libxl__calloc(gc, 1, len); + ptr = *buf; + + strcpy(ptr, QEMU_HEADER); + ptr += sizeof(QEMU_HEADER); + + 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)); + + if (start_addr == NULL || size == NULL || phys_offset == NULL) + return 0; + + 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 len; +} + int libxl__domain_save_device_model(libxl__gc *gc, uint32_t domid, int fd) { libxl_ctx *ctx = libxl__gc_owner(gc); - int ret, fd2 = -1, c; - char buf[1024]; + int ret, fd2 = -1, c, len; + char buf[1024], *buf2; const char *filename = libxl__device_model_savefile(gc, domid); struct stat st; uint32_t qemu_state_len; @@ -687,7 +775,8 @@ int libxl__domain_save_device_model(libxl__gc *gc, uint32_t domid, int fd) goto out; } - qemu_state_len = st.st_size; + len = libxl__domain_save_qemu_header(gc, domid, fd, &buf2); + qemu_state_len = st.st_size + len; LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Qemu state is %d bytes\n", qemu_state_len); ret = libxl_write_exactly(ctx, fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE), @@ -700,6 +789,11 @@ int libxl__domain_save_device_model(libxl__gc *gc, uint32_t domid, int fd) if (ret) goto out; + ret = libxl_write_exactly(ctx, fd, buf2, len, + "saved-state file", "saved-state qemu header"); + if (ret) + goto out; + fd2 = open(filename, O_RDONLY); if (fd2 < 0) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Unable to open qemu save file\n"); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 7f7578a..01f866f 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -57,6 +57,7 @@ #define LIBXL_HVM_EXTRA_MEMORY 2048 #define LIBXL_MIN_DOM0_MEM (128*1024) #define QEMU_SIGNATURE "DeviceModelRecord0002" +#define QEMU_HEADER "DeviceModelHeader0001" #define STUBDOM_CONSOLE_LOGGING 0 #define STUBDOM_CONSOLE_SAVE 1 #define STUBDOM_CONSOLE_RESTORE 2 -- 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 |