[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.