From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: rshriram@cs.ubc.ca, Ian.Campbell@citrix.com,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: [PATCH v3 2/2] libxl: save/restore qemu's physmap
Date: Mon, 30 Jan 2012 16:54:15 +0000 [thread overview]
Message-ID: <1327942455-23587-2-git-send-email-stefano.stabellini@eu.citrix.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1201301647180.3196@kaball-desktop>
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@eu.citrix.com>
---
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 2c5eec5..a6eb714 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -349,6 +349,66 @@ out:
return rc;
}
+struct libxl__physmap_info {
+ uint64_t phys_offset;
+ uint64_t start_addr;
+ uint64_t size;
+ uint32_t namelen;
+ char name[];
+};
+
+#define TOOLSTACK_SAVE_VERSION 1
+
+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 count = 0, version = 0;
+ struct libxl__physmap_info* pi;
+
+ if (size < sizeof(version) + sizeof(count))
+ return -1;
+
+ memcpy(&version, ptr, sizeof(version));
+ ptr += sizeof(version);
+
+ if (version != TOOLSTACK_SAVE_VERSION)
+ return -1;
+
+ memcpy(&count, ptr, sizeof(count));
+ ptr += sizeof(count);
+
+ if (size < sizeof(version) + sizeof(count) +
+ count * (sizeof(struct libxl__physmap_info)))
+ return -1;
+
+ for (i = 0; i < count; i++) {
+ pi = (struct libxl__physmap_info*) ptr;
+ ptr += sizeof(struct libxl__physmap_info) + pi->namelen;
+
+ ret = libxl__xs_write(gc, 0, libxl__sprintf(gc,
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
+ domid, pi->phys_offset), "%"PRIx64, pi->start_addr);
+ if (ret)
+ return -1;
+ ret = libxl__xs_write(gc, 0, libxl__sprintf(gc,
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
+ domid, pi->phys_offset), "%"PRIx64, pi->size);
+ if (ret)
+ return -1;
+ if (pi->namelen > 0) {
+ ret = libxl__xs_write(gc, 0, libxl__sprintf(gc,
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
+ domid, pi->phys_offset), "%s", pi->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,
@@ -358,6 +418,7 @@ int libxl__domain_restore_common(libxl__gc *gc, uint32_t domid,
/* read signature */
int rc;
int hvm, pae, superpages;
+ struct restore_callbacks callbacks;
int no_incr_generationid;
switch (info->type) {
case LIBXL_DOMAIN_TYPE_HVM:
@@ -365,6 +426,8 @@ int libxl__domain_restore_common(libxl__gc *gc, uint32_t domid,
superpages = 1;
pae = info->u.hvm.pae;
no_incr_generationid = info->u.hvm.no_incr_generationid;
+ callbacks.toolstack_restore = libxl__toolstack_restore;
+ callbacks.data = gc;
break;
case LIBXL_DOMAIN_TYPE_PV:
hvm = 0;
@@ -379,7 +442,7 @@ int libxl__domain_restore_common(libxl__gc *gc, uint32_t domid,
state->store_port, &state->store_mfn,
state->console_port, &state->console_mfn,
hvm, pae, superpages, no_incr_generationid,
- &state->vm_generationid_addr, NULL);
+ &state->vm_generationid_addr, &callbacks);
if ( rc ) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain");
return ERROR_FAIL;
@@ -534,6 +597,72 @@ 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;
+ int i = 0;
+ char *start_addr = NULL, *size = NULL, *phys_offset = NULL, *name = NULL;
+ unsigned int num = 0;
+ uint32_t count = 0, version = TOOLSTACK_SAVE_VERSION, namelen = 0;
+ uint8_t *ptr = NULL;
+ char **entries = NULL;
+ struct libxl__physmap_info *pi;
+
+ entries = libxl__xs_directory(gc, 0, libxl__sprintf(gc,
+ "/local/domain/0/device-model/%d/physmap", domid), &num);
+ count = num;
+
+ *len = sizeof(version) + sizeof(count);
+ *buf = calloc(1, *len);
+ ptr = *buf;
+ if (*buf == NULL)
+ return -1;
+
+ memcpy(ptr, &version, sizeof(version));
+ ptr += sizeof(version);
+ memcpy(ptr, &count, sizeof(count));
+ ptr += sizeof(count);
+
+ for (i = 0; i < count; i++) {
+ unsigned long offset;
+ 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
+ namelen = strlen(name) + 1;
+ *len += namelen + sizeof(struct libxl__physmap_info);
+ offset = ptr - (*buf);
+ *buf = realloc(*buf, *len);
+ if (*buf == NULL)
+ return -1;
+ ptr = (*buf) + offset;
+ pi = (struct libxl__physmap_info *) ptr;
+ pi->phys_offset = strtoll(phys_offset, NULL, 16);
+ pi->start_addr = strtoll(start_addr, NULL, 16);
+ pi->size = strtoll(size, NULL, 16);
+ pi->namelen = namelen;
+ memcpy(pi->name, name, namelen);
+ ptr += sizeof(struct libxl__physmap_info) + namelen;
+ }
+
+ return 0;
+}
+
int libxl__domain_suspend_common(libxl__gc *gc, uint32_t domid, int fd,
libxl_domain_type type,
int live, int debug)
@@ -596,6 +725,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,
--
1.7.2.5
next prev parent reply other threads:[~2012-01-30 16:54 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-30 16:52 [PATCH v3 0/2] libxl: save/restore qemu physmap Stefano Stabellini
2012-01-30 16:54 ` [PATCH v3 1/2] libxc: introduce XC_SAVE_ID_TOOLSTACK Stefano Stabellini
2012-01-30 18:41 ` Shriram Rajagopalan
2012-01-31 15:03 ` Stefano Stabellini
2012-01-31 15:08 ` Stefano Stabellini
2012-01-31 17:23 ` Shriram Rajagopalan
2012-01-31 18:58 ` Stefano Stabellini
2012-01-31 22:51 ` Shriram Rajagopalan
2012-02-01 13:53 ` Stefano Stabellini
2012-02-01 14:25 ` Shriram Rajagopalan
2012-02-01 14:40 ` Stefano Stabellini
2012-01-30 16:54 ` Stefano Stabellini [this message]
2012-01-30 18:02 ` [PATCH v3 2/2] libxl: save/restore qemu's physmap Shriram Rajagopalan
2012-01-30 18:06 ` Stefano Stabellini
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=1327942455-23587-2-git-send-email-stefano.stabellini@eu.citrix.com \
--to=stefano.stabellini@eu.citrix.com \
--cc=Ian.Campbell@citrix.com \
--cc=rshriram@cs.ubc.ca \
--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).