From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=44218 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q2Bkr-0004Qi-Nw for qemu-devel@nongnu.org; Tue, 22 Mar 2011 20:16:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q2BkX-0003dk-54 for qemu-devel@nongnu.org; Tue, 22 Mar 2011 20:16:53 -0400 Received: from e8.ny.us.ibm.com ([32.97.182.138]:49564) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q2BkX-0003dg-0w for qemu-devel@nongnu.org; Tue, 22 Mar 2011 20:16:33 -0400 Received: from d01dlp02.pok.ibm.com (d01dlp02.pok.ibm.com [9.56.224.85]) by e8.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p2MNpxdu012296 for ; Tue, 22 Mar 2011 19:51:59 -0400 Received: from d01relay01.pok.ibm.com (d01relay01.pok.ibm.com [9.56.227.233]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id 85D796E803C for ; Tue, 22 Mar 2011 20:16:32 -0400 (EDT) Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by d01relay01.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p2N0GW7i382090 for ; Tue, 22 Mar 2011 20:16:32 -0400 Received: from d01av01.pok.ibm.com (loopback [127.0.0.1]) by d01av01.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p2N0GWdk008559 for ; Tue, 22 Mar 2011 20:16:32 -0400 From: Anthony Liguori Date: Tue, 22 Mar 2011 19:16:15 -0500 Message-Id: <1300839376-22520-11-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1300839376-22520-1-git-send-email-aliguori@us.ibm.com> References: <1300839376-22520-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [PATCH 10/11] vl: add a new -vmstate-dump option to write a VMState JSON schema List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Jan Kiszka , Anthony Liguori , Juan Quintela This ends up being pretty slick as we can store the JSON schema in the tree and then use a test wrapper to validate whether fields change. Current schema will come with the test wrapper. Signed-off-by: Anthony Liguori --- hw/hw.h | 2 + qemu-options.hx | 10 ++++++++ savevm.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ vl.c | 10 ++++++++ 4 files changed, 84 insertions(+), 0 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 9a9012f..531ee30 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -927,4 +927,6 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, void register_vmstate_description(const VMStateDescription *desc); +void vmstate_dump_schema(void); + #endif diff --git a/qemu-options.hx b/qemu-options.hx index ef60730..0faaea5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2368,6 +2368,16 @@ Specify a trace file to log output traces to. ETEXI #endif +DEF("vmstate-dump", 0, QEMU_OPTION_vmstate_dump, + "-vmstate-dump output the current VMState schema and exit\n", + QEMU_ARCH_ALL) +STEXI +@item -vmstate-dump +@findex -vmstate-dump +This option is only used for an internal test suite. The output format may +change in the future. +ETEXI + HXCOMM This is the last statement. Insert new options before this line! STEXI @end table diff --git a/savevm.c b/savevm.c index 4a37917..d35ce8d 100644 --- a/savevm.c +++ b/savevm.c @@ -82,6 +82,7 @@ #include "migration.h" #include "qemu_socket.h" #include "qemu-queue.h" +#include "qemu-objects.h" #define SELF_ANNOUNCE_ROUNDS 5 @@ -1285,8 +1286,69 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, } } +typedef struct VmsdEntry +{ + const VMStateDescription *desc; + QTAILQ_ENTRY(VmsdEntry) node; +} VmsdEntry; + +static QTAILQ_HEAD(, VmsdEntry) vmsd_description_list = + QTAILQ_HEAD_INITIALIZER(vmsd_description_list); + void register_vmstate_description(const VMStateDescription *desc) { + VmsdEntry *e = qemu_mallocz(sizeof(*e)); + + e->desc = desc; + QTAILQ_INSERT_TAIL(&vmsd_description_list, e, node); +} + +static QDict *vmstate_dump_state(const VMStateDescription *desc) +{ + VMStateField *f; + QDict *ret; + + ret = qdict_new(); + + qdict_put(ret, "__version__", qint_from_int(desc->version_id)); + for (f = desc->fields; f && f->name; f++) { + if (qdict_haskey(ret, f->name)) { + fprintf(stderr, "vmstate: duplicate key `%s' in `%s'\n", + f->name, desc->name); + exit(1); + } + if (f->vmsd) { + qdict_put(ret, f->name, vmstate_dump_state(f->vmsd)); + } else { + qdict_put(ret, f->name, qstring_from_str(f->info->name)); + } + } + + return ret; +} + +void vmstate_dump_schema(void) +{ + QDict *items; + QString *str; + VmsdEntry *e; + + items = qdict_new(); + + QTAILQ_FOREACH(e, &vmsd_description_list, node) { + if (qdict_haskey(items, e->desc->name)) { + fprintf(stderr, "vmstate: duplicate devices of name `%s'\n", + e->desc->name); + exit(1); + } + qdict_put(items, e->desc->name, vmstate_dump_state(e->desc)); + } + + str = qobject_to_json_pretty(QOBJECT(items)); + printf("%s\n", qstring_get_str(str)); + + QDECREF(str); + QDECREF(items); } static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, diff --git a/vl.c b/vl.c index dbb927d..f91875b 100644 --- a/vl.c +++ b/vl.c @@ -2038,6 +2038,7 @@ int main(int argc, char **argv, char **envp) #endif int defconfig = 1; const char *trace_file = NULL; + bool vmstate_dump = false; atexit(qemu_run_exit_notifiers); error_set_progname(argv[0]); @@ -2876,6 +2877,9 @@ int main(int argc, char **argv, char **envp) fclose(fp); break; } + case QEMU_OPTION_vmstate_dump: + vmstate_dump = true; + break; default: os_parse_cmd_args(popt->index, optarg); } @@ -3124,6 +3128,12 @@ int main(int argc, char **argv, char **envp) } qemu_add_globals(); + if (vmstate_dump) { + module_call_init(MODULE_INIT_VMSTATE); + vmstate_dump_schema(); + exit(0); + } + machine->init(ram_size, boot_devices, kernel_filename, kernel_cmdline, initrd_filename, cpu_model); -- 1.7.0.4