From patchwork Wed Mar 23 00:16:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Liguori X-Patchwork-Id: 87981 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1E0DAB6F76 for ; Wed, 23 Mar 2011 11:36:38 +1100 (EST) Received: from localhost ([127.0.0.1]:48068 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q2C3N-0003B8-50 for incoming@patchwork.ozlabs.org; Tue, 22 Mar 2011 20:36:01 -0400 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 Received: from localhost.localdomain (sig-9-65-76-198.mts.ibm.com [9.65.76.198]) by d01av01.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p2N0GNiT007989; Tue, 22 Mar 2011 20:16:31 -0400 From: Anthony Liguori To: qemu-devel@nongnu.org Date: Tue, 22 Mar 2011 19:16:15 -0500 Message-Id: <1300839376-22520-11-git-send-email-aliguori@us.ibm.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1300839376-22520-1-git-send-email-aliguori@us.ibm.com> References: <1300839376-22520-1-git-send-email-aliguori@us.ibm.com> X-Content-Scanned: Fidelis XPS MAILER X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 32.97.182.138 Cc: Jan Kiszka , Anthony Liguori , Juan Quintela Subject: [Qemu-devel] [PATCH 10/11] vl: add a new -vmstate-dump option to write a VMState JSON schema X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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);