]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
libxl/save&restore&convert: Switch to new EMULATOR_XENSTORE_DATA records
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 4 Aug 2015 17:16:35 +0000 (18:16 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Wed, 5 Aug 2015 09:46:46 +0000 (10:46 +0100)
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@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
tools/libxl/libxl_stream_read.c
tools/libxl/libxl_stream_write.c
tools/python/scripts/convert-legacy-stream

index c555542ac99d981b1f708c0727e8226b60177367..4ec29da9abe5c15702d82235a01b9257900c2ce8 100644 (file)
@@ -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;
index 55439dd32d4b060fe452b8b5c502de76e443d175..10a9e0f13a5620bf8cb168aa7cbf4a5f68a2ca7e 100644 (file)
@@ -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);
 }
 
index 16331a492d01ff5413a04a59285262f6ed5b7555..41fee109182de83e1074eaaa3094110aab95074a 100755 (executable)
@@ -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)