|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] tools/libxl: Save and restore EMULATOR_XENSTORE_DATA content
commit 874820999dd51533ca408ec72e8bba2a35cd1207
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Tue Aug 4 18:16:33 2015 +0100
Commit: Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Wed Aug 5 10:46:38 2015 +0100
tools/libxl: Save and restore EMULATOR_XENSTORE_DATA content
The new EMULATOR_XENSTORE_DATA content is a sequence of NUL terminated
key/value strings, with the key relative to the device model's xenstore
tree.
A sample might look like (as decoded by verify-stream-v2):
Emulator Xenstore Data (Qemu Upstream, idx 0)
'physmap/1f00000/start_addr' = 'f0000000'
'physmap/1f00000/size' = '800000'
'physmap/1f00000/name' = 'vga.vram'
This patch introduces libxl helpers to save and restore this new format,
which reimplement the existing libxl__toolstack_{save,restore}() logic.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
tools/libxl/libxl_dom.c | 135 ++++++++++++++++++++++++++++++++++++++++++
tools/libxl/libxl_internal.h | 4 +
2 files changed, 139 insertions(+), 0 deletions(-)
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 5555fea..d54d892 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -1151,6 +1151,76 @@ out:
return ret;
}
+/*
+ * Inspect the buffer between start and end, and return a pointer to the
+ * character following the NUL terminator of start, or NULL if start is not
+ * terminated before end.
+ */
+static const char *next_string(const char *start, const char *end)
+{
+ if (start >= end) return NULL;
+
+ size_t total_len = end - start;
+ size_t len = strnlen(start, total_len);
+
+ if (len == total_len)
+ return NULL;
+ else
+ return start + len + 1;
+}
+
+int libxl__restore_emulator_xenstore_data(libxl__domain_create_state *dcs,
+ const char *ptr, uint32_t size)
+{
+ STATE_AO_GC(dcs->ao);
+ const char *next = ptr, *end = ptr + size, *key, *val;
+ int rc;
+
+ const uint32_t domid = dcs->guest_domid;
+ const uint32_t dm_domid = libxl_get_stubdom_id(CTX, domid);
+ const char *xs_root = libxl__device_model_xs_path(gc, dm_domid, domid, "");
+
+ while (next < end) {
+ key = next;
+ next = next_string(next, end);
+
+ /* Sanitise 'key'. */
+ if (!next) {
+ rc = ERROR_FAIL;
+ LOG(ERROR, "Key in xenstore data not NUL terminated");
+ goto out;
+ }
+ if (key[0] == '\0') {
+ rc = ERROR_FAIL;
+ LOG(ERROR, "empty key found in xenstore data");
+ goto out;
+ }
+ if (key[0] == '/') {
+ rc = ERROR_FAIL;
+ LOG(ERROR, "Key in xenstore data not relative");
+ goto out;
+ }
+
+ val = next;
+ next = next_string(next, end);
+
+ /* Sanitise 'val'. */
+ if (!next) {
+ rc = ERROR_FAIL;
+ LOG(ERROR, "Val in xenstore data not NUL terminated");
+ goto out;
+ }
+
+ libxl__xs_write(gc, XBT_NULL,
+ GCSPRINTF("%s/%s", xs_root, key), "%s", val);
+ }
+
+ rc = 0;
+
+ out:
+ return rc;
+}
+
/*==================== Domain suspend (save) ====================*/
static void stream_done(libxl__egc *egc,
@@ -1487,6 +1557,71 @@ out:
return ret;
}
+/*
+ * Expand the buffer 'buf' of length 'len', to append 'str' including its NUL
+ * terminator.
+ */
+static void append_string(libxl__gc *gc, char **buf, uint32_t *len,
+ const char *str)
+{
+ size_t extralen = strlen(str) + 1;
+ char *new = libxl__realloc(gc, *buf, *len + extralen);
+
+ *buf = new;
+ memcpy(new + *len, str, extralen);
+ *len += extralen;
+}
+
+int libxl__save_emulator_xenstore_data(libxl__domain_suspend_state *dss,
+ char **callee_buf,
+ uint32_t *callee_len)
+{
+ STATE_AO_GC(dss->ao);
+ const char *xs_root;
+ char **entries, *buf = NULL;
+ unsigned int nr_entries, i, j, len = 0;
+ int rc;
+
+ const uint32_t domid = dss->domid;
+ const uint32_t dm_domid = libxl_get_stubdom_id(CTX, domid);
+
+ xs_root = libxl__device_model_xs_path(gc, dm_domid, domid, "");
+
+ entries = libxl__xs_directory(gc, 0, GCSPRINTF("%s/physmap", xs_root),
+ &nr_entries);
+ if (!entries || nr_entries == 0) { rc = 0; goto out; }
+
+ for (i = 0; i < nr_entries; ++i) {
+ static const char *const physmap_subkeys[] = {
+ "start_addr", "size", "name"
+ };
+
+ for (j = 0; j < ARRAY_SIZE(physmap_subkeys); ++j) {
+ const char *key = GCSPRINTF("physmap/%s/%s",
+ entries[i], physmap_subkeys[j]);
+
+ const char *val =
+ libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/%s", xs_root, key));
+
+ if (!val) { rc = ERROR_FAIL; goto out; }
+
+ append_string(gc, &buf, &len, key);
+ append_string(gc, &buf, &len, val);
+ }
+ }
+
+ rc = 0;
+
+ out:
+ if (!rc) {
+ *callee_buf = buf;
+ *callee_len = len;
+ }
+
+ return rc;
+}
+
/*----- remus callbacks -----*/
static void remus_domain_suspend_callback_common_done(libxl__egc *egc,
libxl__domain_suspend_state *dss, int ok);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 0253b49..54c3a6d 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3436,6 +3436,10 @@ _hidden void
libxl__domain_suspend_common_switch_qemu_logdirty
(int domid, unsigned int enable, void *data);
_hidden int libxl__toolstack_save(uint32_t domid, uint8_t **buf,
uint32_t *len, void *data);
+_hidden int libxl__save_emulator_xenstore_data(libxl__domain_suspend_state
*dss,
+ char **buf, uint32_t *len);
+_hidden int libxl__restore_emulator_xenstore_data
+ (libxl__domain_create_state *dcs, const char *ptr, uint32_t size);
/* calls libxl__xc_domain_restore_done when done */
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |