]> git.proxmox.com Git - mirror_qemu.git/blob - qom/object_interfaces.c
Include qapi/qmp/qdict.h exactly where needed
[mirror_qemu.git] / qom / object_interfaces.c
1 #include "qemu/osdep.h"
2 #include "qapi/error.h"
3 #include "qapi/qmp/qdict.h"
4 #include "qom/object_interfaces.h"
5 #include "qemu/module.h"
6 #include "qapi-visit.h"
7 #include "qapi/opts-visitor.h"
8 #include "qemu/config-file.h"
9
10 void user_creatable_complete(Object *obj, Error **errp)
11 {
12
13 UserCreatableClass *ucc;
14 UserCreatable *uc =
15 (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
16
17 if (!uc) {
18 return;
19 }
20
21 ucc = USER_CREATABLE_GET_CLASS(uc);
22 if (ucc->complete) {
23 ucc->complete(uc, errp);
24 }
25 }
26
27 bool user_creatable_can_be_deleted(UserCreatable *uc)
28 {
29
30 UserCreatableClass *ucc = USER_CREATABLE_GET_CLASS(uc);
31
32 if (ucc->can_be_deleted) {
33 return ucc->can_be_deleted(uc);
34 } else {
35 return true;
36 }
37 }
38
39 Object *user_creatable_add_type(const char *type, const char *id,
40 const QDict *qdict,
41 Visitor *v, Error **errp)
42 {
43 Object *obj;
44 ObjectClass *klass;
45 const QDictEntry *e;
46 Error *local_err = NULL;
47
48 klass = object_class_by_name(type);
49 if (!klass) {
50 error_setg(errp, "invalid object type: %s", type);
51 return NULL;
52 }
53
54 if (!object_class_dynamic_cast(klass, TYPE_USER_CREATABLE)) {
55 error_setg(errp, "object type '%s' isn't supported by object-add",
56 type);
57 return NULL;
58 }
59
60 if (object_class_is_abstract(klass)) {
61 error_setg(errp, "object type '%s' is abstract", type);
62 return NULL;
63 }
64
65 assert(qdict);
66 obj = object_new(type);
67 if (object_property_find(obj, "id", NULL)) {
68 object_property_set_str(obj, id, "id", &local_err);
69 if (local_err) {
70 goto out;
71 }
72 }
73 visit_start_struct(v, NULL, NULL, 0, &local_err);
74 if (local_err) {
75 goto out;
76 }
77 for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
78 object_property_set(obj, v, e->key, &local_err);
79 if (local_err) {
80 break;
81 }
82 }
83 if (!local_err) {
84 visit_check_struct(v, &local_err);
85 }
86 visit_end_struct(v, NULL);
87 if (local_err) {
88 goto out;
89 }
90
91 object_property_add_child(object_get_objects_root(),
92 id, obj, &local_err);
93 if (local_err) {
94 goto out;
95 }
96
97 user_creatable_complete(obj, &local_err);
98 if (local_err) {
99 object_property_del(object_get_objects_root(),
100 id, &error_abort);
101 goto out;
102 }
103 out:
104 if (local_err) {
105 error_propagate(errp, local_err);
106 object_unref(obj);
107 return NULL;
108 }
109 return obj;
110 }
111
112
113 Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
114 {
115 Visitor *v;
116 QDict *pdict;
117 Object *obj;
118 const char *id = qemu_opts_id(opts);
119 char *type = qemu_opt_get_del(opts, "qom-type");
120
121 if (!type) {
122 error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
123 return NULL;
124 }
125 if (!id) {
126 error_setg(errp, QERR_MISSING_PARAMETER, "id");
127 qemu_opt_set(opts, "qom-type", type, &error_abort);
128 g_free(type);
129 return NULL;
130 }
131
132 qemu_opts_set_id(opts, NULL);
133 pdict = qemu_opts_to_qdict(opts, NULL);
134
135 v = opts_visitor_new(opts);
136 obj = user_creatable_add_type(type, id, pdict, v, errp);
137 visit_free(v);
138
139 qemu_opts_set_id(opts, (char *) id);
140 qemu_opt_set(opts, "qom-type", type, &error_abort);
141 g_free(type);
142 QDECREF(pdict);
143 return obj;
144 }
145
146
147 int user_creatable_add_opts_foreach(void *opaque, QemuOpts *opts, Error **errp)
148 {
149 bool (*type_predicate)(const char *) = opaque;
150 Object *obj = NULL;
151 Error *err = NULL;
152 const char *type;
153
154 type = qemu_opt_get(opts, "qom-type");
155 if (type && type_predicate &&
156 !type_predicate(type)) {
157 return 0;
158 }
159
160 obj = user_creatable_add_opts(opts, &err);
161 if (!obj) {
162 error_report_err(err);
163 return -1;
164 }
165 object_unref(obj);
166 return 0;
167 }
168
169
170 void user_creatable_del(const char *id, Error **errp)
171 {
172 Object *container;
173 Object *obj;
174
175 container = object_get_objects_root();
176 obj = object_resolve_path_component(container, id);
177 if (!obj) {
178 error_setg(errp, "object '%s' not found", id);
179 return;
180 }
181
182 if (!user_creatable_can_be_deleted(USER_CREATABLE(obj))) {
183 error_setg(errp, "object '%s' is in use, can not be deleted", id);
184 return;
185 }
186
187 /*
188 * if object was defined on the command-line, remove its corresponding
189 * option group entry
190 */
191 qemu_opts_del(qemu_opts_find(qemu_find_opts_err("object", &error_abort),
192 id));
193
194 object_unparent(obj);
195 }
196
197 void user_creatable_cleanup(void)
198 {
199 object_unparent(object_get_objects_root());
200 }
201
202 static void register_types(void)
203 {
204 static const TypeInfo uc_interface_info = {
205 .name = TYPE_USER_CREATABLE,
206 .parent = TYPE_INTERFACE,
207 .class_size = sizeof(UserCreatableClass),
208 };
209
210 type_register_static(&uc_interface_info);
211 }
212
213 type_init(register_types)