From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46139) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VZMwE-00075x-Sb for qemu-devel@nongnu.org; Thu, 24 Oct 2013 11:35:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VZMw6-0002rS-ST for qemu-devel@nongnu.org; Thu, 24 Oct 2013 11:35:06 -0400 Received: from cantor2.suse.de ([195.135.220.15]:38047 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VZMw6-0002qf-JN for qemu-devel@nongnu.org; Thu, 24 Oct 2013 11:34:58 -0400 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 24 Oct 2013 16:34:50 +0100 Message-Id: <1382628890-3701-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [RFC] vmstate: Add info vmstate HMP command (WIP) List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: amit.shah@redhat.com, qemu-devel@nongnu.org Cc: Luiz Capitulino , agraf@suse.de, =?UTF-8?q?Andreas=20F=C3=A4rber?= , quintela@redhat.com This adds a command "info vmstate" for dumping a textual representation of the currently registered VMStateDescriptions. Being purely for debugging, intentionally no QMP schema is set in stone. Drawback is that conversations from savevm to VMState show up as differences when comparing outputs and require manual code review. Signed-off-by: Andreas F=C3=A4rber --- Hi Amit, =20 Here's my previous work, as promised at your KVM Forum talk. =20 Regards, Andreas include/migration/vmstate.h | 2 ++ monitor.c | 12 ++++++++++ savevm.c | 58 +++++++++++++++++++++++++++++++++++++++= ++++++ 3 files changed, 72 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 9d09e60..70c325c 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -750,4 +750,6 @@ void vmstate_register_ram(struct MemoryRegion *memory= , DeviceState *dev); void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *de= v); void vmstate_register_ram_global(struct MemoryRegion *memory); =20 +void vmstate_info(Monitor *mon); + #endif diff --git a/monitor.c b/monitor.c index 74f3f1b..7265748 100644 --- a/monitor.c +++ b/monitor.c @@ -2039,6 +2039,11 @@ static void do_info_profile(Monitor *mon, const QD= ict *qdict) } #endif =20 +static void do_info_vmstate(Monitor *mon, const QDict *qdict) +{ + vmstate_info(mon); +} + /* Capture support */ static QLIST_HEAD (capture_list_head, CaptureState) capture_head; =20 @@ -2846,6 +2851,13 @@ static mon_cmd_t info_cmds[] =3D { .help =3D "show the vnc server status", .mhandler.cmd =3D hmp_info_vnc, }, + { + .name =3D "vmstate", + .args_type =3D "", + .params =3D "", + .help =3D "show the VMState structure", + .mhandler.cmd =3D do_info_vmstate, + }, #if defined(CONFIG_SPICE) { .name =3D "spice", diff --git a/savevm.c b/savevm.c index 2f631d4..5de76db 100644 --- a/savevm.c +++ b/savevm.c @@ -1482,6 +1482,64 @@ static QTAILQ_HEAD(savevm_handlers, SaveStateEntry= ) savevm_handlers =3D QTAILQ_HEAD_INITIALIZER(savevm_handlers); static int global_section_id; =20 +static void vmstate_info_vmsd(Monitor *mon, const VMStateDescription *vm= sd, int indent); + +static void vmstate_info_vmsf(Monitor *mon, const VMStateField *field, i= nt indent) +{ + monitor_printf(mon, "%*s%s:\n", indent, "", field->name); + indent +=3D 2; + monitor_printf(mon, "%*sversion_id: %d%s\n", indent, "", field->vers= ion_id, + field->field_exists ? " (??\?)" : ""); + monitor_printf(mon, "%*ssize: %zu\n", indent, "", field->size); + if (field->vmsd !=3D NULL) { + vmstate_info_vmsd(mon, field->vmsd, indent); + } +} + +static void vmstate_info_vmss(Monitor *mon, const VMStateSubsection *sub= section, int indent) +{ + if (subsection->vmsd !=3D NULL) { + vmstate_info_vmsd(mon, subsection->vmsd, indent); + } +} + +static void vmstate_info_vmsd(Monitor *mon, const VMStateDescription *vm= sd, int indent) +{ + monitor_printf(mon, "%*s%s:\n", indent, "", vmsd->name); + indent +=3D 2; + monitor_printf(mon, "%*sversion_id: %d\n", indent, "", vmsd->version= _id); + if (vmsd->fields !=3D NULL) { + const VMStateField *field =3D vmsd->fields; + monitor_printf(mon, "%*sFields:\n", indent, ""); + while (field->name !=3D NULL) { + vmstate_info_vmsf(mon, field, indent + 2); + field++; + } + } + if (vmsd->subsections !=3D NULL) { + const VMStateSubsection *subsection =3D vmsd->subsections; + monitor_printf(mon, "%*sSubsections:\n", indent, ""); + while (subsection->vmsd !=3D NULL) { + vmstate_info_vmss(mon, subsection, indent + 2); + subsection++; + } + } +} + +void vmstate_info(Monitor *mon) +{ + SaveStateEntry *se; + + QTAILQ_FOREACH(se, &savevm_handlers, entry) { + int indent =3D 2; + monitor_printf(mon, "%s\n", se->idstr); + monitor_printf(mon, "%*sversion_id: %d\n", indent, "", se->versi= on_id); + if (se->vmsd !=3D NULL) { + vmstate_info_vmsd(mon, se->vmsd, indent); + } + } +} + static int calculate_new_instance_id(const char *idstr) { SaveStateEntry *se; --=20 1.8.1.4