[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] monitor: Add info qom-tree subcommand.
From: |
Hani Benhabiles |
Subject: |
[Qemu-devel] [PATCH] monitor: Add info qom-tree subcommand. |
Date: |
Sun, 27 Apr 2014 11:29:30 +0100 |
Signed-off-by: Hani Benhabiles <address@hidden>
---
Not sure whether the qobject stringifying functions could fit or be of some use
elsewhere. Thus, I kept them as static near the only place where they are used
at the moment.
hmp-commands.hx | 2 +
hmp.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hmp.h | 1 +
monitor.c | 7 +++
4 files changed, 153 insertions(+)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f3fc514..65b5e33 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1754,6 +1754,8 @@ show qdev device model list
show roms
@item info tpm
show the TPM device
address@hidden info qom-tree
+show the QOM tree
@end table
ETEXI
diff --git a/hmp.c b/hmp.c
index 2f279c4..891a34e 100644
--- a/hmp.c
+++ b/hmp.c
@@ -22,9 +22,11 @@
#include "qemu/sockets.h"
#include "monitor/monitor.h"
#include "qapi/opts-visitor.h"
+#include "qapi/qmp/types.h"
#include "ui/console.h"
#include "block/qapi.h"
#include "qemu-io.h"
+#include "qom/qom-qobject.h"
static void hmp_handle_error(Monitor *mon, Error **errp)
{
@@ -712,6 +714,147 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
qapi_free_TPMInfoList(info_list);
}
+static char *qobject_to_str(const QObject *, int);
+
+static char *qlist_to_str(const QObject *obj, int indent)
+{
+ char *buf = NULL;
+ const QListEntry *entry;
+ int i = 0;
+
+ assert(qobject_type(obj) == QTYPE_QLIST);
+
+ entry = qlist_first(qobject_to_qlist(obj));
+ while (entry) {
+ char *new, *str;
+ int type = qobject_type(entry->value);
+ str = qobject_to_str(entry->value, indent);
+ if (type == QTYPE_QLIST || type == QTYPE_QDICT) {
+ new = g_strdup_printf("%s%*sElement #%d:\n%s", buf ?: "",
+ indent, "", i++, str);
+ } else {
+ new = g_strdup_printf("%s%*sElement #%d: %s\n", buf ?: "",
+ indent, "", i++, str);
+ }
+ g_free(buf);
+ g_free(str);
+ buf = new;
+ entry = qlist_next(entry);
+ }
+ return buf;
+}
+
+static char *qdict_to_str(const QObject *obj, int indent)
+{
+ QDict *dict = qobject_to_qdict(obj);
+ const QDictEntry *entry;
+ char *buf = NULL;
+
+ assert(qobject_type(obj) == QTYPE_QDICT);
+
+ for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) {
+ char *str, *new;
+ int type = qobject_type(entry->value);
+ str = qobject_to_str(entry->value, indent);
+ if (type == QTYPE_QLIST || type == QTYPE_QDICT) {
+ new = g_strdup_printf("%s%*s%s:\n%s", buf ?: "", indent, "",
+ entry->key, str);
+ } else {
+ new = g_strdup_printf("%s%*s%s: %s\n", buf ?: "", indent, "",
+ entry->key, str);
+ }
+ g_free(buf);
+ g_free(str);
+ buf = new;
+ }
+ return buf;
+}
+
+static char *qobject_to_str(const QObject *obj, int indent)
+{
+ switch (qobject_type(obj)) {
+ case QTYPE_QSTRING: {
+ QString *value = qobject_to_qstring(obj);
+ return g_strdup(qstring_get_str(value));
+ }
+ case QTYPE_QINT: {
+ QInt *value = qobject_to_qint(obj);
+ return g_strdup_printf("%" PRId64, qint_get_int(value));
+ }
+ case QTYPE_QBOOL: {
+ QBool *value = qobject_to_qbool(obj);
+ return g_strdup(qbool_get_int(value) ? "True" : "False");
+ }
+ case QTYPE_QERROR: {
+ QString *value = qerror_human((QError *)obj);
+ return g_strdup(qstring_get_str(value));
+ }
+ case QTYPE_QFLOAT: {
+ QFloat *value = qobject_to_qfloat(obj);
+ return g_strdup_printf("%g", qfloat_get_double(value));
+ }
+ case QTYPE_QLIST:
+ return qlist_to_str(obj, indent + 2);
+ case QTYPE_QDICT:
+ return qdict_to_str(obj, indent + 2);
+ case QTYPE_NONE:
+ break;
+ case QTYPE_MAX:
+ default:
+ abort();
+ }
+ return NULL;
+}
+
+static void hmp_print_qom_tree(Monitor *mon, const char *path, int indent)
+{
+ ObjectPropertyInfoList *list, *start;
+
+ monitor_printf(mon, "%*s%s:\n", indent, "", path);
+ start = list = qmp_qom_list(path, NULL);
+ indent += 2;
+ while (list) {
+ ObjectPropertyInfo *info = list->value;
+
+ if (!strncmp(info->type, "child<", 5)) {
+ char *name = g_strdup_printf("%s/%s", path, info->name);
+ hmp_print_qom_tree(mon, name, indent);
+ g_free(name);
+ } else {
+ Object *obj = NULL;
+ QObject *data = NULL;
+ char *str;
+
+ obj = object_resolve_path(path, NULL);
+ if (!obj) {
+ list = list->next;
+ continue;
+ }
+ data = object_property_get_qobject(obj, info->name, NULL);
+ if (!data) {
+ list = list->next;
+ continue;
+ }
+ str = qobject_to_str(data, indent);
+ if (qobject_type(data) == QTYPE_QDICT
+ || qobject_type(data) == QTYPE_QLIST) {
+ monitor_printf(mon, "%*s%s:\n%s", indent, "", info->name, str);
+ } else {
+ monitor_printf(mon, "%*s%s: %s\n", indent, "", info->name,
str);
+ }
+ g_free(str);
+ qobject_decref(data);
+ }
+ list = list->next;
+ }
+ qapi_free_ObjectPropertyInfoList(start);
+}
+
+void hmp_info_qom_tree(Monitor *mon, const QDict *qdict)
+{
+ hmp_print_qom_tree(mon, "/machine", 0);
+}
+
void hmp_quit(Monitor *mon, const QDict *qdict)
{
monitor_suspend(mon);
diff --git a/hmp.h b/hmp.h
index ed58f0e..1733242 100644
--- a/hmp.h
+++ b/hmp.h
@@ -37,6 +37,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict);
void hmp_info_pci(Monitor *mon, const QDict *qdict);
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
void hmp_info_tpm(Monitor *mon, const QDict *qdict);
+void hmp_info_qom_tree(Monitor *mon, const QDict *qdict);
void hmp_quit(Monitor *mon, const QDict *qdict);
void hmp_stop(Monitor *mon, const QDict *qdict);
void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 342e83b..fcb1d0c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2966,6 +2966,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.cmd = hmp_info_tpm,
},
{
+ .name = "qom-tree",
+ .args_type = "",
+ .params = "",
+ .help = "show the QOM tree",
+ .mhandler.cmd = hmp_info_qom_tree,
+ },
+ {
.name = NULL,
},
};
--
1.8.3.2
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH] monitor: Add info qom-tree subcommand.,
Hani Benhabiles <=