xref: /qemu/qom/qom-qmp-cmds.c (revision 443df40c)
1cfbe46fcSMarkus Armbruster /*
2cfbe46fcSMarkus Armbruster  * QMP commands related to QOM
3cfbe46fcSMarkus Armbruster  *
4cfbe46fcSMarkus Armbruster  * Copyright IBM, Corp. 2011
5cfbe46fcSMarkus Armbruster  *
6cfbe46fcSMarkus Armbruster  * Authors:
7cfbe46fcSMarkus Armbruster  *  Anthony Liguori   <aliguori@us.ibm.com>
8cfbe46fcSMarkus Armbruster  *
9cfbe46fcSMarkus Armbruster  * This work is licensed under the terms of the GNU GPL, version 2.  See
10cfbe46fcSMarkus Armbruster  * the COPYING file in the top-level directory.
11cfbe46fcSMarkus Armbruster  *
12cfbe46fcSMarkus Armbruster  * Contributions after 2012-01-13 are licensed under the terms of the
13cfbe46fcSMarkus Armbruster  * GNU GPL, version 2 or (at your option) any later version.
14cfbe46fcSMarkus Armbruster  */
15cfbe46fcSMarkus Armbruster 
16cfbe46fcSMarkus Armbruster #include "qemu/osdep.h"
175f07c4d6SKevin Wolf #include "block/qdict.h"
18a27bd6c7SMarkus Armbruster #include "hw/qdev-core.h"
19cfbe46fcSMarkus Armbruster #include "qapi/error.h"
20cfbe46fcSMarkus Armbruster #include "qapi/qapi-commands-qdev.h"
21cfbe46fcSMarkus Armbruster #include "qapi/qapi-commands-qom.h"
229151e59aSKevin Wolf #include "qapi/qapi-visit-qom.h"
23cfbe46fcSMarkus Armbruster #include "qapi/qmp/qdict.h"
24cfbe46fcSMarkus Armbruster #include "qapi/qmp/qerror.h"
259151e59aSKevin Wolf #include "qapi/qobject-input-visitor.h"
269151e59aSKevin Wolf #include "qapi/qobject-output-visitor.h"
27cfbe46fcSMarkus Armbruster #include "qemu/cutils.h"
28cfbe46fcSMarkus Armbruster #include "qom/object_interfaces.h"
29cfbe46fcSMarkus Armbruster #include "qom/qom-qobject.h"
30cfbe46fcSMarkus Armbruster 
qmp_qom_list(const char * path,Error ** errp)31cfbe46fcSMarkus Armbruster ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
32cfbe46fcSMarkus Armbruster {
33cfbe46fcSMarkus Armbruster     Object *obj;
34cfbe46fcSMarkus Armbruster     bool ambiguous = false;
35cfbe46fcSMarkus Armbruster     ObjectPropertyInfoList *props = NULL;
36cfbe46fcSMarkus Armbruster     ObjectProperty *prop;
37cfbe46fcSMarkus Armbruster     ObjectPropertyIterator iter;
38cfbe46fcSMarkus Armbruster 
39cfbe46fcSMarkus Armbruster     obj = object_resolve_path(path, &ambiguous);
40cfbe46fcSMarkus Armbruster     if (obj == NULL) {
41cfbe46fcSMarkus Armbruster         if (ambiguous) {
42cfbe46fcSMarkus Armbruster             error_setg(errp, "Path '%s' is ambiguous", path);
43cfbe46fcSMarkus Armbruster         } else {
44cfbe46fcSMarkus Armbruster             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
45cfbe46fcSMarkus Armbruster                       "Device '%s' not found", path);
46cfbe46fcSMarkus Armbruster         }
47cfbe46fcSMarkus Armbruster         return NULL;
48cfbe46fcSMarkus Armbruster     }
49cfbe46fcSMarkus Armbruster 
50cfbe46fcSMarkus Armbruster     object_property_iter_init(&iter, obj);
51cfbe46fcSMarkus Armbruster     while ((prop = object_property_iter_next(&iter))) {
52b21e2380SMarkus Armbruster         ObjectPropertyInfo *value = g_new0(ObjectPropertyInfo, 1);
53cfbe46fcSMarkus Armbruster 
5454aa3de7SEric Blake         QAPI_LIST_PREPEND(props, value);
55cfbe46fcSMarkus Armbruster 
5654aa3de7SEric Blake         value->name = g_strdup(prop->name);
5754aa3de7SEric Blake         value->type = g_strdup(prop->type);
58cfbe46fcSMarkus Armbruster     }
59cfbe46fcSMarkus Armbruster 
60cfbe46fcSMarkus Armbruster     return props;
61cfbe46fcSMarkus Armbruster }
62cfbe46fcSMarkus Armbruster 
qmp_qom_set(const char * path,const char * property,QObject * value,Error ** errp)63cfbe46fcSMarkus Armbruster void qmp_qom_set(const char *path, const char *property, QObject *value,
64cfbe46fcSMarkus Armbruster                  Error **errp)
65cfbe46fcSMarkus Armbruster {
66cfbe46fcSMarkus Armbruster     Object *obj;
67cfbe46fcSMarkus Armbruster 
68cfbe46fcSMarkus Armbruster     obj = object_resolve_path(path, NULL);
69cfbe46fcSMarkus Armbruster     if (!obj) {
70cfbe46fcSMarkus Armbruster         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
71cfbe46fcSMarkus Armbruster                   "Device '%s' not found", path);
72cfbe46fcSMarkus Armbruster         return;
73cfbe46fcSMarkus Armbruster     }
74cfbe46fcSMarkus Armbruster 
755325cc34SMarkus Armbruster     object_property_set_qobject(obj, property, value, errp);
76cfbe46fcSMarkus Armbruster }
77cfbe46fcSMarkus Armbruster 
qmp_qom_get(const char * path,const char * property,Error ** errp)78cfbe46fcSMarkus Armbruster QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
79cfbe46fcSMarkus Armbruster {
80cfbe46fcSMarkus Armbruster     Object *obj;
81cfbe46fcSMarkus Armbruster 
82cfbe46fcSMarkus Armbruster     obj = object_resolve_path(path, NULL);
83cfbe46fcSMarkus Armbruster     if (!obj) {
84cfbe46fcSMarkus Armbruster         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
85cfbe46fcSMarkus Armbruster                   "Device '%s' not found", path);
86cfbe46fcSMarkus Armbruster         return NULL;
87cfbe46fcSMarkus Armbruster     }
88cfbe46fcSMarkus Armbruster 
89cfbe46fcSMarkus Armbruster     return object_property_get_qobject(obj, property, errp);
90cfbe46fcSMarkus Armbruster }
91cfbe46fcSMarkus Armbruster 
qom_list_types_tramp(ObjectClass * klass,void * data)92cfbe46fcSMarkus Armbruster static void qom_list_types_tramp(ObjectClass *klass, void *data)
93cfbe46fcSMarkus Armbruster {
9454aa3de7SEric Blake     ObjectTypeInfoList **pret = data;
95cfbe46fcSMarkus Armbruster     ObjectTypeInfo *info;
96cfbe46fcSMarkus Armbruster     ObjectClass *parent = object_class_get_parent(klass);
97cfbe46fcSMarkus Armbruster 
98cfbe46fcSMarkus Armbruster     info = g_malloc0(sizeof(*info));
99cfbe46fcSMarkus Armbruster     info->name = g_strdup(object_class_get_name(klass));
100cfbe46fcSMarkus Armbruster     info->has_abstract = info->abstract = object_class_is_abstract(klass);
101cfbe46fcSMarkus Armbruster     if (parent) {
102cfbe46fcSMarkus Armbruster         info->parent = g_strdup(object_class_get_name(parent));
103cfbe46fcSMarkus Armbruster     }
104cfbe46fcSMarkus Armbruster 
10554aa3de7SEric Blake     QAPI_LIST_PREPEND(*pret, info);
106cfbe46fcSMarkus Armbruster }
107cfbe46fcSMarkus Armbruster 
qmp_qom_list_types(const char * implements,bool has_abstract,bool abstract,Error ** errp)108047f2ca1SMarkus Armbruster ObjectTypeInfoList *qmp_qom_list_types(const char *implements,
109cfbe46fcSMarkus Armbruster                                        bool has_abstract,
110cfbe46fcSMarkus Armbruster                                        bool abstract,
111cfbe46fcSMarkus Armbruster                                        Error **errp)
112cfbe46fcSMarkus Armbruster {
113cfbe46fcSMarkus Armbruster     ObjectTypeInfoList *ret = NULL;
114cfbe46fcSMarkus Armbruster 
1157ab6e7fcSGerd Hoffmann     module_load_qom_all();
116cfbe46fcSMarkus Armbruster     object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
117cfbe46fcSMarkus Armbruster 
118cfbe46fcSMarkus Armbruster     return ret;
119cfbe46fcSMarkus Armbruster }
120cfbe46fcSMarkus Armbruster 
qmp_device_list_properties(const char * typename,Error ** errp)121cfbe46fcSMarkus Armbruster ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
122cfbe46fcSMarkus Armbruster                                                 Error **errp)
123cfbe46fcSMarkus Armbruster {
124cfbe46fcSMarkus Armbruster     ObjectClass *klass;
125cfbe46fcSMarkus Armbruster     Object *obj;
126cfbe46fcSMarkus Armbruster     ObjectProperty *prop;
127cfbe46fcSMarkus Armbruster     ObjectPropertyIterator iter;
128cfbe46fcSMarkus Armbruster     ObjectPropertyInfoList *prop_list = NULL;
129cfbe46fcSMarkus Armbruster 
1307ab6e7fcSGerd Hoffmann     klass = module_object_class_by_name(typename);
131cfbe46fcSMarkus Armbruster     if (klass == NULL) {
132cfbe46fcSMarkus Armbruster         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
133cfbe46fcSMarkus Armbruster                   "Device '%s' not found", typename);
134cfbe46fcSMarkus Armbruster         return NULL;
135cfbe46fcSMarkus Armbruster     }
136cfbe46fcSMarkus Armbruster 
13774b97760SMarkus Armbruster     if (!object_class_dynamic_cast(klass, TYPE_DEVICE)
13874b97760SMarkus Armbruster         || object_class_is_abstract(klass)) {
139cfbe46fcSMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
14074b97760SMarkus Armbruster                    "a non-abstract device type");
141cfbe46fcSMarkus Armbruster         return NULL;
142cfbe46fcSMarkus Armbruster     }
143cfbe46fcSMarkus Armbruster 
144cfbe46fcSMarkus Armbruster     obj = object_new(typename);
145cfbe46fcSMarkus Armbruster 
146cfbe46fcSMarkus Armbruster     object_property_iter_init(&iter, obj);
147cfbe46fcSMarkus Armbruster     while ((prop = object_property_iter_next(&iter))) {
148cfbe46fcSMarkus Armbruster         ObjectPropertyInfo *info;
149cfbe46fcSMarkus Armbruster 
150cfbe46fcSMarkus Armbruster         /* Skip Object and DeviceState properties */
151cfbe46fcSMarkus Armbruster         if (strcmp(prop->name, "type") == 0 ||
152cfbe46fcSMarkus Armbruster             strcmp(prop->name, "realized") == 0 ||
153cfbe46fcSMarkus Armbruster             strcmp(prop->name, "hotpluggable") == 0 ||
154cfbe46fcSMarkus Armbruster             strcmp(prop->name, "hotplugged") == 0 ||
155cfbe46fcSMarkus Armbruster             strcmp(prop->name, "parent_bus") == 0) {
156cfbe46fcSMarkus Armbruster             continue;
157cfbe46fcSMarkus Armbruster         }
158cfbe46fcSMarkus Armbruster 
159cfbe46fcSMarkus Armbruster         /* Skip legacy properties since they are just string versions of
160cfbe46fcSMarkus Armbruster          * properties that we already list.
161cfbe46fcSMarkus Armbruster          */
162cfbe46fcSMarkus Armbruster         if (strstart(prop->name, "legacy-", NULL)) {
163cfbe46fcSMarkus Armbruster             continue;
164cfbe46fcSMarkus Armbruster         }
165cfbe46fcSMarkus Armbruster 
166c1f472eaSPaolo Bonzini         info = g_new0(ObjectPropertyInfo, 1);
167c1f472eaSPaolo Bonzini         info->name = g_strdup(prop->name);
168c1f472eaSPaolo Bonzini         info->type = g_strdup(prop->type);
169c1f472eaSPaolo Bonzini         info->description = g_strdup(prop->description);
1701bb3d7d9SMarc-André Lureau         info->default_value = qobject_ref(prop->defval);
171cfbe46fcSMarkus Armbruster 
17254aa3de7SEric Blake         QAPI_LIST_PREPEND(prop_list, info);
173cfbe46fcSMarkus Armbruster     }
174cfbe46fcSMarkus Armbruster 
175cfbe46fcSMarkus Armbruster     object_unref(obj);
176cfbe46fcSMarkus Armbruster 
177cfbe46fcSMarkus Armbruster     return prop_list;
178cfbe46fcSMarkus Armbruster }
179cfbe46fcSMarkus Armbruster 
qmp_qom_list_properties(const char * typename,Error ** errp)180cfbe46fcSMarkus Armbruster ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
181cfbe46fcSMarkus Armbruster                                              Error **errp)
182cfbe46fcSMarkus Armbruster {
183cfbe46fcSMarkus Armbruster     ObjectClass *klass;
184cfbe46fcSMarkus Armbruster     Object *obj = NULL;
185cfbe46fcSMarkus Armbruster     ObjectProperty *prop;
186cfbe46fcSMarkus Armbruster     ObjectPropertyIterator iter;
187cfbe46fcSMarkus Armbruster     ObjectPropertyInfoList *prop_list = NULL;
188cfbe46fcSMarkus Armbruster 
189cfbe46fcSMarkus Armbruster     klass = object_class_by_name(typename);
190cfbe46fcSMarkus Armbruster     if (klass == NULL) {
191cfbe46fcSMarkus Armbruster         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
192cfbe46fcSMarkus Armbruster                   "Class '%s' not found", typename);
193cfbe46fcSMarkus Armbruster         return NULL;
194cfbe46fcSMarkus Armbruster     }
195cfbe46fcSMarkus Armbruster 
19674b97760SMarkus Armbruster     if (!object_class_dynamic_cast(klass, TYPE_OBJECT)) {
19774b97760SMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
19874b97760SMarkus Armbruster                    "a QOM type");
199cfbe46fcSMarkus Armbruster         return NULL;
200cfbe46fcSMarkus Armbruster     }
201cfbe46fcSMarkus Armbruster 
202cfbe46fcSMarkus Armbruster     if (object_class_is_abstract(klass)) {
203cfbe46fcSMarkus Armbruster         object_class_property_iter_init(&iter, klass);
204cfbe46fcSMarkus Armbruster     } else {
205cfbe46fcSMarkus Armbruster         obj = object_new(typename);
206cfbe46fcSMarkus Armbruster         object_property_iter_init(&iter, obj);
207cfbe46fcSMarkus Armbruster     }
208cfbe46fcSMarkus Armbruster     while ((prop = object_property_iter_next(&iter))) {
209cfbe46fcSMarkus Armbruster         ObjectPropertyInfo *info;
210cfbe46fcSMarkus Armbruster 
211cfbe46fcSMarkus Armbruster         info = g_malloc0(sizeof(*info));
212cfbe46fcSMarkus Armbruster         info->name = g_strdup(prop->name);
213cfbe46fcSMarkus Armbruster         info->type = g_strdup(prop->type);
214cfbe46fcSMarkus Armbruster         info->description = g_strdup(prop->description);
215443df40cSMaksim Davydov         info->default_value = qobject_ref(prop->defval);
216cfbe46fcSMarkus Armbruster 
21754aa3de7SEric Blake         QAPI_LIST_PREPEND(prop_list, info);
218cfbe46fcSMarkus Armbruster     }
219cfbe46fcSMarkus Armbruster 
220cfbe46fcSMarkus Armbruster     object_unref(obj);
221cfbe46fcSMarkus Armbruster 
222cfbe46fcSMarkus Armbruster     return prop_list;
223cfbe46fcSMarkus Armbruster }
224cfbe46fcSMarkus Armbruster 
qmp_object_add(ObjectOptions * options,Error ** errp)2259151e59aSKevin Wolf void qmp_object_add(ObjectOptions *options, Error **errp)
226cfbe46fcSMarkus Armbruster {
227f3750266SKevin Wolf     user_creatable_add_qapi(options, errp);
228cfbe46fcSMarkus Armbruster }
229cfbe46fcSMarkus Armbruster 
qmp_object_del(const char * id,Error ** errp)230cfbe46fcSMarkus Armbruster void qmp_object_del(const char *id, Error **errp)
231cfbe46fcSMarkus Armbruster {
232cfbe46fcSMarkus Armbruster     user_creatable_del(id, errp);
233cfbe46fcSMarkus Armbruster }
234