[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH for-4.6 v3 5/6] libxl/save&restore&convert: Switch to new EMULATOR_XENSTORE_DATA records



Read and write "toolstack" information using the new
EMULATOR_XENSTORE_DATA record, and have the conversion script take care
of the old format.

The entire libxc and libxl migration v2 streams are now bitness-neutral
in their records.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
CC: Ian Campbell <Ian.Campbell@xxxxxxxxxx>
CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>

Note: This is a binary incompatibility in the libxl migration stream over
the past few weeks, but we don't really care about maintaining
compatibility between development versions of Xen, and it does fix the
one remaining bitness issue in the stream.
---
 tools/libxl/libxl_stream_read.c            |   16 +++++--
 tools/libxl/libxl_stream_write.c           |   25 ++++++-----
 tools/python/scripts/convert-legacy-stream |   66 +++++++++++++++++++++++++---
 3 files changed, 85 insertions(+), 22 deletions(-)

diff --git a/tools/libxl/libxl_stream_read.c b/tools/libxl/libxl_stream_read.c
index c555542..4ec29da 100644
--- a/tools/libxl/libxl_stream_read.c
+++ b/tools/libxl/libxl_stream_read.c
@@ -538,14 +538,22 @@ static bool process_record(libxl__egc *egc,
         libxl__xc_domain_restore(egc, dcs, &stream->shs, 0, 0, 0);
         break;
 
-    case REC_TYPE_XENSTORE_DATA:
-        rc = libxl__toolstack_restore(dcs->guest_domid, rec->body,
-                                      rec->hdr.length, &stream->shs);
+    case REC_TYPE_EMULATOR_XENSTORE_DATA:
+        if (rec->hdr.length < sizeof(libxl__sr_emulator_hdr)) {
+            rc = ERROR_FAIL;
+            LOG(ERROR,
+                "Emulator xenstore data record too short to contain header");
+            goto err;
+        }
+
+        rc = libxl__restore_emulator_xenstore_data(dcs,
+            rec->body + sizeof(libxl__sr_emulator_hdr),
+            rec->hdr.length - sizeof(libxl__sr_emulator_hdr));
         if (rc)
             goto err;
 
         /*
-         * libxl__toolstack_restore() is a synchronous function.
+         * libxl__restore_emulator_xenstore_data() is a synchronous function.
          * Request that our caller queues another action for us.
          */
         further_action_needed = true;
diff --git a/tools/libxl/libxl_stream_write.c b/tools/libxl/libxl_stream_write.c
index 55439dd..10a9e0f 100644
--- a/tools/libxl/libxl_stream_write.c
+++ b/tools/libxl/libxl_stream_write.c
@@ -356,27 +356,30 @@ static void write_emulator_xenstore_record(libxl__egc 
*egc,
     STATE_AO_GC(stream->ao);
     struct libxl__sr_rec_hdr rec;
     int rc;
-    uint8_t *buf = NULL; /* We must free this. */
-    uint32_t len;
+    char *buf = NULL;
+    uint32_t len = 0;
 
-    rc = libxl__toolstack_save(dss->domid, &buf, &len, dss);
+    rc = libxl__save_emulator_xenstore_data(dss, &buf, &len);
     if (rc)
         goto err;
 
-    FILLZERO(rec);
-    rec.type = REC_TYPE_XENSTORE_DATA;
-    rec.length = len;
+    /* No record? - All done. */
+    if (len == 0) {
+        emulator_xenstore_record_done(egc, stream);
+        return;
+    }
 
-    setup_write(egc, stream, "emulator xenstore record",
-                &rec, buf,
-                emulator_xenstore_record_done);
+    FILLZERO(rec);
+    rec.type = REC_TYPE_EMULATOR_XENSTORE_DATA;
+    rec.length = len + sizeof(stream->emu_sub_hdr);
 
-    free(buf);
+    setup_emulator_write(egc, stream, "emulator xenstore record",
+                         &rec, &stream->emu_sub_hdr, buf,
+                         emulator_xenstore_record_done);
     return;
 
  err:
     assert(rc);
-    free(buf);
     stream_complete(egc, stream, rc);
 }
 
diff --git a/tools/python/scripts/convert-legacy-stream 
b/tools/python/scripts/convert-legacy-stream
index 16331a4..41fee10 100755
--- a/tools/python/scripts/convert-legacy-stream
+++ b/tools/python/scripts/convert-legacy-stream
@@ -70,7 +70,7 @@ class VM(object):
 
         # libxl
         self.libxl = fmt == "libxl"
-        self.xenstore = [] # Deferred "toolstack" records
+        self.emu_xenstore = "" # NUL terminated key&val pairs from "toolstack" 
records
 
 def write_libxc_ihdr():
     stream_write(pack(libxc.IHDR_FORMAT,
@@ -169,8 +169,10 @@ def write_libxl_end():
 def write_libxl_libxc_context():
     write_record(libxl.REC_TYPE_libxc_context, "")
 
-def write_libxl_xenstore_data(data):
-    write_record(libxl.REC_TYPE_xenstore_data, data)
+def write_libxl_emulator_xenstore_data(data):
+    write_record(libxl.REC_TYPE_emulator_xenstore_data,
+                 pack(libxl.EMULATOR_HEADER_FORMAT,
+                      libxl.EMULATOR_ID_unknown, 0) + data)
 
 def write_libxl_emulator_context(blob):
     write_record(libxl.REC_TYPE_emulator_context,
@@ -297,6 +299,57 @@ def read_pv_tail(vm):
     write_record(libxc.REC_TYPE_end, "")
 
 
+def read_libxl_toolstack(vm, data):
+
+    if len(data) < 8:
+        raise StreamError("Overly short libxl toolstack data")
+
+    ver, count = unpack("=II", data[:8])
+    data = data[8:]
+
+    if ver != 1:
+        raise StreamError("Cannot decode libxl toolstack version %u" % (ver, ))
+    info("    Version %u, count %u" % (ver, count))
+
+    for x in range(count):
+
+        if len(data) < 28:
+            raise StreamError("Remaining data too short for physmap header")
+
+        phys, start, size, namelen = unpack("=QQQI", data[:28])
+        data = data[28:]
+
+        if namelen == 0:
+            raise StreamError("No physmap info name")
+
+        # 64bit leaked 4 bytes of padding onto the end of name
+        if twidth == 64:
+            namelen += 4
+
+        if len(data) < namelen:
+            raise StreamError("Remaining data too short for physmap name")
+
+        name = data[:namelen]
+        data = data[namelen:]
+
+        # Strip padding off the end of name
+        if twidth == 64:
+            name = name[:-4]
+
+        if name[-1] != '\x00':
+            raise StreamError("physmap name not NUL terminated")
+
+        root = "physmap/%x" % (phys,)
+        kv = [root + "/start_addr", "%x" % (start, ),
+              root + "/size",       "%x" % (size, ),
+              root + "/name",       name[:-1]]
+
+        for key, val in zip(kv[0::2], kv[1::2]):
+            info("    '%s' = '%s'" % (key, val))
+
+        vm.emu_xenstore += '\x00'.join(kv) + '\x00'
+
+
 def read_chunks(vm):
 
     hvm_params = []
@@ -441,7 +494,7 @@ def read_chunks(vm):
                 info("  Toolstack Data: sz 0x%x" % (sz, ))
 
                 if vm.libxl:
-                    vm.xenstore.append(data)
+                    read_libxl_toolstack(vm, data)
                 else:
                     info("    Discarding")
 
@@ -544,9 +597,8 @@ def read_legacy_stream(vm):
         else:
             read_hvm_tail(vm)
 
-        if vm.libxl:
-            for rec in vm.xenstore:
-                write_libxl_xenstore_data(rec)
+        if vm.libxl and len(vm.emu_xenstore):
+            write_libxl_emulator_xenstore_data(vm.emu_xenstore)
 
         if not pv and (vm.libxl or qemu):
             read_qemu(vm)
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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