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;
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);
}
# 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,
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,
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 = []
info(" Toolstack Data: sz 0x%x" % (sz, ))
if vm.libxl:
- vm.xenstore.append(data)
+ read_libxl_toolstack(vm, data)
else:
info(" Discarding")
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)