Mailing List Archive

[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@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 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@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH 2/2] libxl: save/restore qemu's physmap [ In reply to ]
On Fri, 2012-01-20 at 11:18 +0000, Stefano Stabellini wrote:
> Read Qemu's physmap from xenstore and save it using toolstack_save.
> Restore Qemu's physmap using toolstack_restore.

Shall we have a version field now so we don't dig ourselves a hole we
can't get out of?

> 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 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);

Why not define a struct libxl__physmap_info for these three? You could
even do the trick with the "char name[]" at the end and incorporate
namelen too if you wanted.

The maximum size of the allocation is
sizeof(count) + count * (sizeof(uint64_t) * 3 + sizeof(uint32_t)))
here but in the save it is allocating:
sizeof(count) + count * (sizeof(val) * 3 + sizeof(namelen));
these work out the same but it would be more obviously correct if it
were "count * sizeof(struct)"

Actually, hang on where is the space for name itself allocated? I see,
you are reallocing. If you have to do that anyway you may as well start
off with just sizeof(count) and realloc namelen + sizeof(struct) at each
stage.

> +
> + 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,



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH 2/2] libxl: save/restore qemu's physmap [ In reply to ]
On Fri, 20 Jan 2012, Ian Campbell wrote:
> On Fri, 2012-01-20 at 11:18 +0000, Stefano Stabellini wrote:
> > Read Qemu's physmap from xenstore and save it using toolstack_save.
> > Restore Qemu's physmap using toolstack_restore.
>
> Shall we have a version field now so we don't dig ourselves a hole we
> can't get out of?

good idea

> > 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 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);
>
> Why not define a struct libxl__physmap_info for these three? You could
> even do the trick with the "char name[]" at the end and incorporate
> namelen too if you wanted.
>
> The maximum size of the allocation is
> sizeof(count) + count * (sizeof(uint64_t) * 3 + sizeof(uint32_t)))
> here but in the save it is allocating:
> sizeof(count) + count * (sizeof(val) * 3 + sizeof(namelen));
> these work out the same but it would be more obviously correct if it
> were "count * sizeof(struct)"
>
> Actually, hang on where is the space for name itself allocated? I see,
> you are reallocing. If you have to do that anyway you may as well start
> off with just sizeof(count) and realloc namelen + sizeof(struct) at each
> stage.

I played with the idea of the struct for a bit and it has improved the
code, especially on restore.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel