It lists object properties, as equivalent to what info qtree displays. Cc: Hani Benhabiles <h...@linux.com> Signed-off-by: Andreas Färber <afaer...@suse.de> --- monitor.c | 6 +++--- qdev-monitor.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/monitor.c b/monitor.c index 48f7f5a..9e16b4a 100644 --- a/monitor.c +++ b/monitor.c @@ -2890,9 +2890,9 @@ static mon_cmd_t info_cmds[] = { }, { .name = "qom-tree", - .args_type = "path:s?", - .params = "[path]", - .help = "show QOM composition tree", + .args_type = "verbose:-v,path:s?", + .params = "[-v] [path]", + .help = "show QOM composition tree (-v: show properties)", .mhandler.cmd = hmp_info_qom_tree, }, { diff --git a/qdev-monitor.c b/qdev-monitor.c index 1d87f57..845abfa 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -22,6 +22,7 @@ #include "monitor/monitor.h" #include "monitor/qdev.h" #include "qmp-commands.h" +#include "qapi/string-output-visitor.h" #include "sysemu/arch_init.h" #include "qemu/config-file.h" @@ -681,40 +682,74 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict) typedef struct QOMCompositionState { Monitor *mon; int indent; + bool verbose; } QOMCompositionState; -static void print_qom_composition(Monitor *mon, Object *obj, int indent); +static void print_qom_composition(Monitor *mon, Object *obj, int indent, + bool verbose); static int print_qom_composition_child(Object *obj, void *opaque) { QOMCompositionState *s = opaque; - print_qom_composition(s->mon, obj, s->indent); + print_qom_composition(s->mon, obj, s->indent, s->verbose); return 0; } -static void print_qom_composition(Monitor *mon, Object *obj, int indent) +static void print_qom_composition(Monitor *mon, Object *obj, int indent, + bool verbose) { QOMCompositionState s = { .mon = mon, .indent = indent + 2, + .verbose = verbose, }; - char *name; + ObjectProperty *prop; + StringOutputVisitor *mo; + Error *local_err = NULL; + char *name, *str; if (obj == object_get_root()) { name = g_strdup(""); } else { name = object_get_canonical_path_component(obj); } - monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name, - object_get_typename(obj)); + if (verbose) { + monitor_printf(mon, "%*s/%s\n", indent, "", name); + QTAILQ_FOREACH(prop, &obj->properties, node) { + mo = string_output_visitor_new(true); + if (!prop->get) { + monitor_printf(mon, "%*s%s (write-only)\n", indent + 2, "", + prop->name); + } else { + prop->get(obj, string_output_get_visitor(mo), prop->opaque, + prop->name, &local_err); + if (local_err) { + monitor_printf(mon, "%*s%s: Error: %s\n", indent + 2, "", + prop->name, error_get_pretty(local_err)); + error_free(local_err); + local_err = NULL; + } else { + str = string_output_get_string(mo); + monitor_printf(mon, "%*s%s: %s\n", indent + 2, "", + prop->name, str); + g_free(str); + } + } + string_output_visitor_cleanup(mo); + } + } else { + monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name, + object_get_typename(obj)); + } g_free(name); object_child_foreach(obj, print_qom_composition_child, &s); } void hmp_info_qom_tree(Monitor *mon, const QDict *dict) { + bool verbose = qdict_get_try_bool(dict, "verbose", 0); const char *path = qdict_get_try_str(dict, "path"); Object *obj; bool ambiguous = false; @@ -732,7 +767,7 @@ void hmp_info_qom_tree(Monitor *mon, const QDict *dict) } else { obj = qdev_get_machine(); } - print_qom_composition(mon, obj, 0); + print_qom_composition(mon, obj, 0, verbose); } int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data) -- 2.1.4