xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: [PATCH 3/3] libxl: introduce QEMU_HEADER
Date: Thu, 19 Jan 2012 12:13:04 +0000	[thread overview]
Message-ID: <1326975184-458-6-git-send-email-stefano.stabellini@eu.citrix.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1201191204370.3150@kaball-desktop>

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@eu.citrix.com>
---
 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

  parent reply	other threads:[~2012-01-19 12:13 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-19 12:12 [PATCH 0/3] libxl: save additional info to the qemu chunk Stefano Stabellini
2012-01-19 12:12 ` [PATCH 1/3] libxc: add a callback to xc_domain_restore Stefano Stabellini
2012-01-19 12:13 ` [PATCH 2/3] libxl: extract the qemu state file from the save image Stefano Stabellini
2012-01-19 12:13 ` [PATCH 3/3] libxl: introduce QEMU_HEADER Stefano Stabellini
2012-01-19 12:24   ` Ian Campbell
2012-01-19 13:00     ` Stefano Stabellini
2012-01-19 12:13 ` [PATCH 1/3] libxc: add a callback to xc_domain_restore Stefano Stabellini
2012-01-19 12:13 ` [PATCH 2/3] libxl: extract the qemu state file from the save image Stefano Stabellini
2012-01-19 12:13 ` Stefano Stabellini [this message]
2012-01-19 12:25 ` [PATCH 0/3] libxl: save additional info to the qemu chunk Ian Campbell
2012-01-19 14:00   ` Stefano Stabellini
2012-01-19 14:01     ` Ian Campbell
2012-01-19 14:06       ` Stefano Stabellini
2012-01-19 14:09         ` Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1326975184-458-6-git-send-email-stefano.stabellini@eu.citrix.com \
    --to=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).