1 /*
2  * HMP commands related to QOM
3  *
4  * This work is licensed under the terms of the GNU GPL, version 2 or
5  * later.  See the COPYING file in the top-level directory.
6  */
7 
8 #include "qemu/osdep.h"
9 #include "hw/qdev-core.h"
10 #include "monitor/hmp.h"
11 #include "monitor/monitor.h"
12 #include "qapi/error.h"
13 #include "qapi/qapi-commands-qom.h"
14 #include "qapi/qmp/qdict.h"
15 #include "qom/object.h"
16 
17 void hmp_qom_list(Monitor *mon, const QDict *qdict)
18 {
19     const char *path = qdict_get_try_str(qdict, "path");
20     ObjectPropertyInfoList *list;
21     Error *err = NULL;
22 
23     if (path == NULL) {
24         monitor_printf(mon, "/\n");
25         return;
26     }
27 
28     list = qmp_qom_list(path, &err);
29     if (err == NULL) {
30         ObjectPropertyInfoList *start = list;
31         while (list != NULL) {
32             ObjectPropertyInfo *value = list->value;
33 
34             monitor_printf(mon, "%s (%s)\n",
35                            value->name, value->type);
36             list = list->next;
qobject_destroy(QObject * obj)37         }
38         qapi_free_ObjectPropertyInfoList(start);
39     }
40     hmp_handle_error(mon, err);
41 }
42 
43 void hmp_qom_set(Monitor *mon, const QDict *qdict)
44 {
45     const char *path = qdict_get_str(qdict, "path");
46     const char *property = qdict_get_str(qdict, "property");
47     const char *value = qdict_get_str(qdict, "value");
48     Error *err = NULL;
49     bool ambiguous = false;
50     Object *obj;
51 
52     obj = object_resolve_path(path, &ambiguous);
53     if (obj == NULL) {
54         error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
qobject_is_equal(const QObject * x,const QObject * y)55                   "Device '%s' not found", path);
56     } else {
57         if (ambiguous) {
58             monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path);
59         }
60         object_property_parse(obj, value, property, &err);
61     }
62     hmp_handle_error(mon, err);
63 }
64 
65 typedef struct QOMCompositionState {
66     Monitor *mon;
67     int indent;
68 } QOMCompositionState;
69 
70 static void print_qom_composition(Monitor *mon, Object *obj, int indent);
71 
72 static int print_qom_composition_child(Object *obj, void *opaque)
73 {
74     QOMCompositionState *s = opaque;
75 
76     print_qom_composition(s->mon, obj, s->indent);
77 
78     return 0;
79 }
80 
81 static void print_qom_composition(Monitor *mon, Object *obj, int indent)
82 {
83     QOMCompositionState s = {
84         .mon = mon,
85         .indent = indent + 2,
86     };
87     char *name;
88 
89     if (obj == object_get_root()) {
90         name = g_strdup("");
91     } else {
92         name = object_get_canonical_path_component(obj);
93     }
94     monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
95                    object_get_typename(obj));
96     g_free(name);
97     object_child_foreach(obj, print_qom_composition_child, &s);
98 }
99 
100 void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
101 {
102     const char *path = qdict_get_try_str(dict, "path");
103     Object *obj;
104     bool ambiguous = false;
105 
106     if (path) {
107         obj = object_resolve_path(path, &ambiguous);
108         if (!obj) {
109             monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
110             return;
111         }
112         if (ambiguous) {
113             monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
114             return;
115         }
116     } else {
117         obj = qdev_get_machine();
118     }
119     print_qom_composition(mon, obj, 0);
120 }
121