@@ -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,
},
{
@@ -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)
It lists object properties, as equivalent to what info qtree displays. Cc: Hani Benhabiles <hani@linux.com> Signed-off-by: Andreas Färber <afaerber@suse.de> --- monitor.c | 6 +++--- qdev-monitor.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 10 deletions(-)