xref: /openbmc/qemu/qom/object.c (revision 503bb0b9)
1 /*
2  * QEMU Object Model
3  *
4  * Copyright IBM, Corp. 2011
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "qom/object.h"
16 #include "qom/object_interfaces.h"
17 #include "qemu/cutils.h"
18 #include "qapi/visitor.h"
19 #include "qapi/string-input-visitor.h"
20 #include "qapi/string-output-visitor.h"
21 #include "qapi/qapi-builtin-visit.h"
22 #include "qapi/qmp/qerror.h"
23 #include "trace.h"
24 
25 /* TODO: replace QObject with a simpler visitor to avoid a dependency
26  * of the QOM core on QObject?  */
27 #include "qom/qom-qobject.h"
28 #include "qapi/qmp/qbool.h"
29 #include "qapi/qmp/qnum.h"
30 #include "qapi/qmp/qstring.h"
31 
32 #define MAX_INTERFACES 32
33 
34 typedef struct InterfaceImpl InterfaceImpl;
35 typedef struct TypeImpl TypeImpl;
36 
37 struct InterfaceImpl
38 {
39     const char *typename;
40 };
41 
42 struct TypeImpl
43 {
44     const char *name;
45 
46     size_t class_size;
47 
48     size_t instance_size;
49 
50     void (*class_init)(ObjectClass *klass, void *data);
51     void (*class_base_init)(ObjectClass *klass, void *data);
52 
53     void *class_data;
54 
55     void (*instance_init)(Object *obj);
56     void (*instance_post_init)(Object *obj);
57     void (*instance_finalize)(Object *obj);
58 
59     bool abstract;
60 
61     const char *parent;
62     TypeImpl *parent_type;
63 
64     ObjectClass *class;
65 
66     int num_interfaces;
67     InterfaceImpl interfaces[MAX_INTERFACES];
68 };
69 
70 static Type type_interface;
71 
72 static GHashTable *type_table_get(void)
73 {
74     static GHashTable *type_table;
75 
76     if (type_table == NULL) {
77         type_table = g_hash_table_new(g_str_hash, g_str_equal);
78     }
79 
80     return type_table;
81 }
82 
83 static bool enumerating_types;
84 
85 static void type_table_add(TypeImpl *ti)
86 {
87     assert(!enumerating_types);
88     g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
89 }
90 
91 static TypeImpl *type_table_lookup(const char *name)
92 {
93     return g_hash_table_lookup(type_table_get(), name);
94 }
95 
96 static TypeImpl *type_new(const TypeInfo *info)
97 {
98     TypeImpl *ti = g_malloc0(sizeof(*ti));
99     int i;
100 
101     g_assert(info->name != NULL);
102 
103     if (type_table_lookup(info->name) != NULL) {
104         fprintf(stderr, "Registering `%s' which already exists\n", info->name);
105         abort();
106     }
107 
108     ti->name = g_strdup(info->name);
109     ti->parent = g_strdup(info->parent);
110 
111     ti->class_size = info->class_size;
112     ti->instance_size = info->instance_size;
113 
114     ti->class_init = info->class_init;
115     ti->class_base_init = info->class_base_init;
116     ti->class_data = info->class_data;
117 
118     ti->instance_init = info->instance_init;
119     ti->instance_post_init = info->instance_post_init;
120     ti->instance_finalize = info->instance_finalize;
121 
122     ti->abstract = info->abstract;
123 
124     for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
125         ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
126     }
127     ti->num_interfaces = i;
128 
129     return ti;
130 }
131 
132 static TypeImpl *type_register_internal(const TypeInfo *info)
133 {
134     TypeImpl *ti;
135     ti = type_new(info);
136 
137     type_table_add(ti);
138     return ti;
139 }
140 
141 TypeImpl *type_register(const TypeInfo *info)
142 {
143     assert(info->parent);
144     return type_register_internal(info);
145 }
146 
147 TypeImpl *type_register_static(const TypeInfo *info)
148 {
149     return type_register(info);
150 }
151 
152 void type_register_static_array(const TypeInfo *infos, int nr_infos)
153 {
154     int i;
155 
156     for (i = 0; i < nr_infos; i++) {
157         type_register_static(&infos[i]);
158     }
159 }
160 
161 static TypeImpl *type_get_by_name(const char *name)
162 {
163     if (name == NULL) {
164         return NULL;
165     }
166 
167     return type_table_lookup(name);
168 }
169 
170 static TypeImpl *type_get_parent(TypeImpl *type)
171 {
172     if (!type->parent_type && type->parent) {
173         type->parent_type = type_get_by_name(type->parent);
174         g_assert(type->parent_type != NULL);
175     }
176 
177     return type->parent_type;
178 }
179 
180 static bool type_has_parent(TypeImpl *type)
181 {
182     return (type->parent != NULL);
183 }
184 
185 static size_t type_class_get_size(TypeImpl *ti)
186 {
187     if (ti->class_size) {
188         return ti->class_size;
189     }
190 
191     if (type_has_parent(ti)) {
192         return type_class_get_size(type_get_parent(ti));
193     }
194 
195     return sizeof(ObjectClass);
196 }
197 
198 static size_t type_object_get_size(TypeImpl *ti)
199 {
200     if (ti->instance_size) {
201         return ti->instance_size;
202     }
203 
204     if (type_has_parent(ti)) {
205         return type_object_get_size(type_get_parent(ti));
206     }
207 
208     return 0;
209 }
210 
211 size_t object_type_get_instance_size(const char *typename)
212 {
213     TypeImpl *type = type_get_by_name(typename);
214 
215     g_assert(type != NULL);
216     return type_object_get_size(type);
217 }
218 
219 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
220 {
221     assert(target_type);
222 
223     /* Check if target_type is a direct ancestor of type */
224     while (type) {
225         if (type == target_type) {
226             return true;
227         }
228 
229         type = type_get_parent(type);
230     }
231 
232     return false;
233 }
234 
235 static void type_initialize(TypeImpl *ti);
236 
237 static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type,
238                                       TypeImpl *parent_type)
239 {
240     InterfaceClass *new_iface;
241     TypeInfo info = { };
242     TypeImpl *iface_impl;
243 
244     info.parent = parent_type->name;
245     info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name);
246     info.abstract = true;
247 
248     iface_impl = type_new(&info);
249     iface_impl->parent_type = parent_type;
250     type_initialize(iface_impl);
251     g_free((char *)info.name);
252 
253     new_iface = (InterfaceClass *)iface_impl->class;
254     new_iface->concrete_class = ti->class;
255     new_iface->interface_type = interface_type;
256 
257     ti->class->interfaces = g_slist_append(ti->class->interfaces,
258                                            iface_impl->class);
259 }
260 
261 static void object_property_free(gpointer data)
262 {
263     ObjectProperty *prop = data;
264 
265     g_free(prop->name);
266     g_free(prop->type);
267     g_free(prop->description);
268     g_free(prop);
269 }
270 
271 static void type_initialize(TypeImpl *ti)
272 {
273     TypeImpl *parent;
274 
275     if (ti->class) {
276         return;
277     }
278 
279     ti->class_size = type_class_get_size(ti);
280     ti->instance_size = type_object_get_size(ti);
281     /* Any type with zero instance_size is implicitly abstract.
282      * This means interface types are all abstract.
283      */
284     if (ti->instance_size == 0) {
285         ti->abstract = true;
286     }
287     if (type_is_ancestor(ti, type_interface)) {
288         assert(ti->instance_size == 0);
289         assert(ti->abstract);
290         assert(!ti->instance_init);
291         assert(!ti->instance_post_init);
292         assert(!ti->instance_finalize);
293         assert(!ti->num_interfaces);
294     }
295     ti->class = g_malloc0(ti->class_size);
296 
297     parent = type_get_parent(ti);
298     if (parent) {
299         type_initialize(parent);
300         GSList *e;
301         int i;
302 
303         g_assert(parent->class_size <= ti->class_size);
304         memcpy(ti->class, parent->class, parent->class_size);
305         ti->class->interfaces = NULL;
306         ti->class->properties = g_hash_table_new_full(
307             g_str_hash, g_str_equal, g_free, object_property_free);
308 
309         for (e = parent->class->interfaces; e; e = e->next) {
310             InterfaceClass *iface = e->data;
311             ObjectClass *klass = OBJECT_CLASS(iface);
312 
313             type_initialize_interface(ti, iface->interface_type, klass->type);
314         }
315 
316         for (i = 0; i < ti->num_interfaces; i++) {
317             TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
318             for (e = ti->class->interfaces; e; e = e->next) {
319                 TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
320 
321                 if (type_is_ancestor(target_type, t)) {
322                     break;
323                 }
324             }
325 
326             if (e) {
327                 continue;
328             }
329 
330             type_initialize_interface(ti, t, t);
331         }
332     } else {
333         ti->class->properties = g_hash_table_new_full(
334             g_str_hash, g_str_equal, g_free, object_property_free);
335     }
336 
337     ti->class->type = ti;
338 
339     while (parent) {
340         if (parent->class_base_init) {
341             parent->class_base_init(ti->class, ti->class_data);
342         }
343         parent = type_get_parent(parent);
344     }
345 
346     if (ti->class_init) {
347         ti->class_init(ti->class, ti->class_data);
348     }
349 }
350 
351 static void object_init_with_type(Object *obj, TypeImpl *ti)
352 {
353     if (type_has_parent(ti)) {
354         object_init_with_type(obj, type_get_parent(ti));
355     }
356 
357     if (ti->instance_init) {
358         ti->instance_init(obj);
359     }
360 }
361 
362 static void object_post_init_with_type(Object *obj, TypeImpl *ti)
363 {
364     if (ti->instance_post_init) {
365         ti->instance_post_init(obj);
366     }
367 
368     if (type_has_parent(ti)) {
369         object_post_init_with_type(obj, type_get_parent(ti));
370     }
371 }
372 
373 void object_apply_global_props(Object *obj, const GPtrArray *props, Error **errp)
374 {
375     int i;
376 
377     if (!props) {
378         return;
379     }
380 
381     for (i = 0; i < props->len; i++) {
382         GlobalProperty *p = g_ptr_array_index(props, i);
383         Error *err = NULL;
384 
385         if (object_dynamic_cast(obj, p->driver) == NULL) {
386             continue;
387         }
388         if (p->optional && !object_property_find(obj, p->property, NULL)) {
389             continue;
390         }
391         p->used = true;
392         object_property_parse(obj, p->value, p->property, &err);
393         if (err != NULL) {
394             error_prepend(&err, "can't apply global %s.%s=%s: ",
395                           p->driver, p->property, p->value);
396             /*
397              * If errp != NULL, propagate error and return.
398              * If errp == NULL, report a warning, but keep going
399              * with the remaining globals.
400              */
401             if (errp) {
402                 error_propagate(errp, err);
403                 return;
404             } else {
405                 warn_report_err(err);
406             }
407         }
408     }
409 }
410 
411 static void object_initialize_with_type(void *data, size_t size, TypeImpl *type)
412 {
413     Object *obj = data;
414 
415     g_assert(type != NULL);
416     type_initialize(type);
417 
418     g_assert(type->instance_size >= sizeof(Object));
419     g_assert(type->abstract == false);
420     g_assert(size >= type->instance_size);
421 
422     memset(obj, 0, type->instance_size);
423     obj->class = type->class;
424     object_ref(obj);
425     obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
426                                             NULL, object_property_free);
427     object_init_with_type(obj, type);
428     object_post_init_with_type(obj, type);
429 }
430 
431 void object_initialize(void *data, size_t size, const char *typename)
432 {
433     TypeImpl *type = type_get_by_name(typename);
434 
435     object_initialize_with_type(data, size, type);
436 }
437 
438 void object_initialize_child(Object *parentobj, const char *propname,
439                              void *childobj, size_t size, const char *type,
440                              Error **errp, ...)
441 {
442     va_list vargs;
443 
444     va_start(vargs, errp);
445     object_initialize_childv(parentobj, propname, childobj, size, type, errp,
446                              vargs);
447     va_end(vargs);
448 }
449 
450 void object_initialize_childv(Object *parentobj, const char *propname,
451                               void *childobj, size_t size, const char *type,
452                               Error **errp, va_list vargs)
453 {
454     Error *local_err = NULL;
455     Object *obj;
456     UserCreatable *uc;
457 
458     object_initialize(childobj, size, type);
459     obj = OBJECT(childobj);
460 
461     object_set_propv(obj, &local_err, vargs);
462     if (local_err) {
463         goto out;
464     }
465 
466     object_property_add_child(parentobj, propname, obj, &local_err);
467     if (local_err) {
468         goto out;
469     }
470 
471     uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
472     if (uc) {
473         user_creatable_complete(uc, &local_err);
474         if (local_err) {
475             object_unparent(obj);
476             goto out;
477         }
478     }
479 
480     /*
481      * Since object_property_add_child added a reference to the child object,
482      * we can drop the reference added by object_initialize(), so the child
483      * property will own the only reference to the object.
484      */
485     object_unref(obj);
486 
487 out:
488     if (local_err) {
489         error_propagate(errp, local_err);
490         object_unref(obj);
491     }
492 }
493 
494 static inline bool object_property_is_child(ObjectProperty *prop)
495 {
496     return strstart(prop->type, "child<", NULL);
497 }
498 
499 static void object_property_del_all(Object *obj)
500 {
501     ObjectProperty *prop;
502     GHashTableIter iter;
503     gpointer key, value;
504     bool released;
505 
506     do {
507         released = false;
508         g_hash_table_iter_init(&iter, obj->properties);
509         while (g_hash_table_iter_next(&iter, &key, &value)) {
510             prop = value;
511             if (prop->release) {
512                 prop->release(obj, prop->name, prop->opaque);
513                 prop->release = NULL;
514                 released = true;
515                 break;
516             }
517             g_hash_table_iter_remove(&iter);
518         }
519     } while (released);
520 
521     g_hash_table_unref(obj->properties);
522 }
523 
524 static void object_property_del_child(Object *obj, Object *child, Error **errp)
525 {
526     ObjectProperty *prop;
527     GHashTableIter iter;
528     gpointer key, value;
529 
530     g_hash_table_iter_init(&iter, obj->properties);
531     while (g_hash_table_iter_next(&iter, &key, &value)) {
532         prop = value;
533         if (object_property_is_child(prop) && prop->opaque == child) {
534             if (prop->release) {
535                 prop->release(obj, prop->name, prop->opaque);
536                 prop->release = NULL;
537             }
538             break;
539         }
540     }
541     g_hash_table_iter_init(&iter, obj->properties);
542     while (g_hash_table_iter_next(&iter, &key, &value)) {
543         prop = value;
544         if (object_property_is_child(prop) && prop->opaque == child) {
545             g_hash_table_iter_remove(&iter);
546             break;
547         }
548     }
549 }
550 
551 void object_unparent(Object *obj)
552 {
553     if (obj->parent) {
554         object_property_del_child(obj->parent, obj, NULL);
555     }
556 }
557 
558 static void object_deinit(Object *obj, TypeImpl *type)
559 {
560     if (type->instance_finalize) {
561         type->instance_finalize(obj);
562     }
563 
564     if (type_has_parent(type)) {
565         object_deinit(obj, type_get_parent(type));
566     }
567 }
568 
569 static void object_finalize(void *data)
570 {
571     Object *obj = data;
572     TypeImpl *ti = obj->class->type;
573 
574     object_property_del_all(obj);
575     object_deinit(obj, ti);
576 
577     g_assert(obj->ref == 0);
578     if (obj->free) {
579         obj->free(obj);
580     }
581 }
582 
583 static Object *object_new_with_type(Type type)
584 {
585     Object *obj;
586 
587     g_assert(type != NULL);
588     type_initialize(type);
589 
590     obj = g_malloc(type->instance_size);
591     object_initialize_with_type(obj, type->instance_size, type);
592     obj->free = g_free;
593 
594     return obj;
595 }
596 
597 Object *object_new(const char *typename)
598 {
599     TypeImpl *ti = type_get_by_name(typename);
600 
601     return object_new_with_type(ti);
602 }
603 
604 
605 Object *object_new_with_props(const char *typename,
606                               Object *parent,
607                               const char *id,
608                               Error **errp,
609                               ...)
610 {
611     va_list vargs;
612     Object *obj;
613 
614     va_start(vargs, errp);
615     obj = object_new_with_propv(typename, parent, id, errp, vargs);
616     va_end(vargs);
617 
618     return obj;
619 }
620 
621 
622 Object *object_new_with_propv(const char *typename,
623                               Object *parent,
624                               const char *id,
625                               Error **errp,
626                               va_list vargs)
627 {
628     Object *obj;
629     ObjectClass *klass;
630     Error *local_err = NULL;
631     UserCreatable *uc;
632 
633     klass = object_class_by_name(typename);
634     if (!klass) {
635         error_setg(errp, "invalid object type: %s", typename);
636         return NULL;
637     }
638 
639     if (object_class_is_abstract(klass)) {
640         error_setg(errp, "object type '%s' is abstract", typename);
641         return NULL;
642     }
643     obj = object_new(typename);
644 
645     if (object_set_propv(obj, &local_err, vargs) < 0) {
646         goto error;
647     }
648 
649     object_property_add_child(parent, id, obj, &local_err);
650     if (local_err) {
651         goto error;
652     }
653 
654     uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
655     if (uc) {
656         user_creatable_complete(uc, &local_err);
657         if (local_err) {
658             object_unparent(obj);
659             goto error;
660         }
661     }
662 
663     object_unref(OBJECT(obj));
664     return obj;
665 
666  error:
667     error_propagate(errp, local_err);
668     object_unref(obj);
669     return NULL;
670 }
671 
672 
673 int object_set_props(Object *obj,
674                      Error **errp,
675                      ...)
676 {
677     va_list vargs;
678     int ret;
679 
680     va_start(vargs, errp);
681     ret = object_set_propv(obj, errp, vargs);
682     va_end(vargs);
683 
684     return ret;
685 }
686 
687 
688 int object_set_propv(Object *obj,
689                      Error **errp,
690                      va_list vargs)
691 {
692     const char *propname;
693     Error *local_err = NULL;
694 
695     propname = va_arg(vargs, char *);
696     while (propname != NULL) {
697         const char *value = va_arg(vargs, char *);
698 
699         g_assert(value != NULL);
700         object_property_parse(obj, value, propname, &local_err);
701         if (local_err) {
702             error_propagate(errp, local_err);
703             return -1;
704         }
705         propname = va_arg(vargs, char *);
706     }
707 
708     return 0;
709 }
710 
711 
712 Object *object_dynamic_cast(Object *obj, const char *typename)
713 {
714     if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
715         return obj;
716     }
717 
718     return NULL;
719 }
720 
721 Object *object_dynamic_cast_assert(Object *obj, const char *typename,
722                                    const char *file, int line, const char *func)
723 {
724     trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
725                                      typename, file, line, func);
726 
727 #ifdef CONFIG_QOM_CAST_DEBUG
728     int i;
729     Object *inst;
730 
731     for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
732         if (atomic_read(&obj->class->object_cast_cache[i]) == typename) {
733             goto out;
734         }
735     }
736 
737     inst = object_dynamic_cast(obj, typename);
738 
739     if (!inst && obj) {
740         fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
741                 file, line, func, obj, typename);
742         abort();
743     }
744 
745     assert(obj == inst);
746 
747     if (obj && obj == inst) {
748         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
749             atomic_set(&obj->class->object_cast_cache[i - 1],
750                        atomic_read(&obj->class->object_cast_cache[i]));
751         }
752         atomic_set(&obj->class->object_cast_cache[i - 1], typename);
753     }
754 
755 out:
756 #endif
757     return obj;
758 }
759 
760 ObjectClass *object_class_dynamic_cast(ObjectClass *class,
761                                        const char *typename)
762 {
763     ObjectClass *ret = NULL;
764     TypeImpl *target_type;
765     TypeImpl *type;
766 
767     if (!class) {
768         return NULL;
769     }
770 
771     /* A simple fast path that can trigger a lot for leaf classes.  */
772     type = class->type;
773     if (type->name == typename) {
774         return class;
775     }
776 
777     target_type = type_get_by_name(typename);
778     if (!target_type) {
779         /* target class type unknown, so fail the cast */
780         return NULL;
781     }
782 
783     if (type->class->interfaces &&
784             type_is_ancestor(target_type, type_interface)) {
785         int found = 0;
786         GSList *i;
787 
788         for (i = class->interfaces; i; i = i->next) {
789             ObjectClass *target_class = i->data;
790 
791             if (type_is_ancestor(target_class->type, target_type)) {
792                 ret = target_class;
793                 found++;
794             }
795          }
796 
797         /* The match was ambiguous, don't allow a cast */
798         if (found > 1) {
799             ret = NULL;
800         }
801     } else if (type_is_ancestor(type, target_type)) {
802         ret = class;
803     }
804 
805     return ret;
806 }
807 
808 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
809                                               const char *typename,
810                                               const char *file, int line,
811                                               const char *func)
812 {
813     ObjectClass *ret;
814 
815     trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
816                                            typename, file, line, func);
817 
818 #ifdef CONFIG_QOM_CAST_DEBUG
819     int i;
820 
821     for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
822         if (atomic_read(&class->class_cast_cache[i]) == typename) {
823             ret = class;
824             goto out;
825         }
826     }
827 #else
828     if (!class || !class->interfaces) {
829         return class;
830     }
831 #endif
832 
833     ret = object_class_dynamic_cast(class, typename);
834     if (!ret && class) {
835         fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
836                 file, line, func, class, typename);
837         abort();
838     }
839 
840 #ifdef CONFIG_QOM_CAST_DEBUG
841     if (class && ret == class) {
842         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
843             atomic_set(&class->class_cast_cache[i - 1],
844                        atomic_read(&class->class_cast_cache[i]));
845         }
846         atomic_set(&class->class_cast_cache[i - 1], typename);
847     }
848 out:
849 #endif
850     return ret;
851 }
852 
853 const char *object_get_typename(const Object *obj)
854 {
855     return obj->class->type->name;
856 }
857 
858 ObjectClass *object_get_class(Object *obj)
859 {
860     return obj->class;
861 }
862 
863 bool object_class_is_abstract(ObjectClass *klass)
864 {
865     return klass->type->abstract;
866 }
867 
868 const char *object_class_get_name(ObjectClass *klass)
869 {
870     return klass->type->name;
871 }
872 
873 ObjectClass *object_class_by_name(const char *typename)
874 {
875     TypeImpl *type = type_get_by_name(typename);
876 
877     if (!type) {
878         return NULL;
879     }
880 
881     type_initialize(type);
882 
883     return type->class;
884 }
885 
886 ObjectClass *object_class_get_parent(ObjectClass *class)
887 {
888     TypeImpl *type = type_get_parent(class->type);
889 
890     if (!type) {
891         return NULL;
892     }
893 
894     type_initialize(type);
895 
896     return type->class;
897 }
898 
899 typedef struct OCFData
900 {
901     void (*fn)(ObjectClass *klass, void *opaque);
902     const char *implements_type;
903     bool include_abstract;
904     void *opaque;
905 } OCFData;
906 
907 static void object_class_foreach_tramp(gpointer key, gpointer value,
908                                        gpointer opaque)
909 {
910     OCFData *data = opaque;
911     TypeImpl *type = value;
912     ObjectClass *k;
913 
914     type_initialize(type);
915     k = type->class;
916 
917     if (!data->include_abstract && type->abstract) {
918         return;
919     }
920 
921     if (data->implements_type &&
922         !object_class_dynamic_cast(k, data->implements_type)) {
923         return;
924     }
925 
926     data->fn(k, data->opaque);
927 }
928 
929 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
930                           const char *implements_type, bool include_abstract,
931                           void *opaque)
932 {
933     OCFData data = { fn, implements_type, include_abstract, opaque };
934 
935     enumerating_types = true;
936     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
937     enumerating_types = false;
938 }
939 
940 static int do_object_child_foreach(Object *obj,
941                                    int (*fn)(Object *child, void *opaque),
942                                    void *opaque, bool recurse)
943 {
944     GHashTableIter iter;
945     ObjectProperty *prop;
946     int ret = 0;
947 
948     g_hash_table_iter_init(&iter, obj->properties);
949     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
950         if (object_property_is_child(prop)) {
951             Object *child = prop->opaque;
952 
953             ret = fn(child, opaque);
954             if (ret != 0) {
955                 break;
956             }
957             if (recurse) {
958                 do_object_child_foreach(child, fn, opaque, true);
959             }
960         }
961     }
962     return ret;
963 }
964 
965 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
966                          void *opaque)
967 {
968     return do_object_child_foreach(obj, fn, opaque, false);
969 }
970 
971 int object_child_foreach_recursive(Object *obj,
972                                    int (*fn)(Object *child, void *opaque),
973                                    void *opaque)
974 {
975     return do_object_child_foreach(obj, fn, opaque, true);
976 }
977 
978 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
979 {
980     GSList **list = opaque;
981 
982     *list = g_slist_prepend(*list, klass);
983 }
984 
985 GSList *object_class_get_list(const char *implements_type,
986                               bool include_abstract)
987 {
988     GSList *list = NULL;
989 
990     object_class_foreach(object_class_get_list_tramp,
991                          implements_type, include_abstract, &list);
992     return list;
993 }
994 
995 static gint object_class_cmp(gconstpointer a, gconstpointer b)
996 {
997     return strcasecmp(object_class_get_name((ObjectClass *)a),
998                       object_class_get_name((ObjectClass *)b));
999 }
1000 
1001 GSList *object_class_get_list_sorted(const char *implements_type,
1002                                      bool include_abstract)
1003 {
1004     return g_slist_sort(object_class_get_list(implements_type, include_abstract),
1005                         object_class_cmp);
1006 }
1007 
1008 void object_ref(Object *obj)
1009 {
1010     if (!obj) {
1011         return;
1012     }
1013     atomic_inc(&obj->ref);
1014 }
1015 
1016 void object_unref(Object *obj)
1017 {
1018     if (!obj) {
1019         return;
1020     }
1021     g_assert(obj->ref > 0);
1022 
1023     /* parent always holds a reference to its children */
1024     if (atomic_fetch_dec(&obj->ref) == 1) {
1025         object_finalize(obj);
1026     }
1027 }
1028 
1029 ObjectProperty *
1030 object_property_add(Object *obj, const char *name, const char *type,
1031                     ObjectPropertyAccessor *get,
1032                     ObjectPropertyAccessor *set,
1033                     ObjectPropertyRelease *release,
1034                     void *opaque, Error **errp)
1035 {
1036     ObjectProperty *prop;
1037     size_t name_len = strlen(name);
1038 
1039     if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) {
1040         int i;
1041         ObjectProperty *ret;
1042         char *name_no_array = g_strdup(name);
1043 
1044         name_no_array[name_len - 3] = '\0';
1045         for (i = 0; ; ++i) {
1046             char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
1047 
1048             ret = object_property_add(obj, full_name, type, get, set,
1049                                       release, opaque, NULL);
1050             g_free(full_name);
1051             if (ret) {
1052                 break;
1053             }
1054         }
1055         g_free(name_no_array);
1056         return ret;
1057     }
1058 
1059     if (object_property_find(obj, name, NULL) != NULL) {
1060         error_setg(errp, "attempt to add duplicate property '%s'"
1061                    " to object (type '%s')", name,
1062                    object_get_typename(obj));
1063         return NULL;
1064     }
1065 
1066     prop = g_malloc0(sizeof(*prop));
1067 
1068     prop->name = g_strdup(name);
1069     prop->type = g_strdup(type);
1070 
1071     prop->get = get;
1072     prop->set = set;
1073     prop->release = release;
1074     prop->opaque = opaque;
1075 
1076     g_hash_table_insert(obj->properties, prop->name, prop);
1077     return prop;
1078 }
1079 
1080 ObjectProperty *
1081 object_class_property_add(ObjectClass *klass,
1082                           const char *name,
1083                           const char *type,
1084                           ObjectPropertyAccessor *get,
1085                           ObjectPropertyAccessor *set,
1086                           ObjectPropertyRelease *release,
1087                           void *opaque,
1088                           Error **errp)
1089 {
1090     ObjectProperty *prop;
1091 
1092     if (object_class_property_find(klass, name, NULL) != NULL) {
1093         error_setg(errp, "attempt to add duplicate property '%s'"
1094                    " to object (type '%s')", name,
1095                    object_class_get_name(klass));
1096         return NULL;
1097     }
1098 
1099     prop = g_malloc0(sizeof(*prop));
1100 
1101     prop->name = g_strdup(name);
1102     prop->type = g_strdup(type);
1103 
1104     prop->get = get;
1105     prop->set = set;
1106     prop->release = release;
1107     prop->opaque = opaque;
1108 
1109     g_hash_table_insert(klass->properties, g_strdup(name), prop);
1110 
1111     return prop;
1112 }
1113 
1114 ObjectProperty *object_property_find(Object *obj, const char *name,
1115                                      Error **errp)
1116 {
1117     ObjectProperty *prop;
1118     ObjectClass *klass = object_get_class(obj);
1119 
1120     prop = object_class_property_find(klass, name, NULL);
1121     if (prop) {
1122         return prop;
1123     }
1124 
1125     prop = g_hash_table_lookup(obj->properties, name);
1126     if (prop) {
1127         return prop;
1128     }
1129 
1130     error_setg(errp, "Property '.%s' not found", name);
1131     return NULL;
1132 }
1133 
1134 void object_property_iter_init(ObjectPropertyIterator *iter,
1135                                Object *obj)
1136 {
1137     g_hash_table_iter_init(&iter->iter, obj->properties);
1138     iter->nextclass = object_get_class(obj);
1139 }
1140 
1141 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
1142 {
1143     gpointer key, val;
1144     while (!g_hash_table_iter_next(&iter->iter, &key, &val)) {
1145         if (!iter->nextclass) {
1146             return NULL;
1147         }
1148         g_hash_table_iter_init(&iter->iter, iter->nextclass->properties);
1149         iter->nextclass = object_class_get_parent(iter->nextclass);
1150     }
1151     return val;
1152 }
1153 
1154 void object_class_property_iter_init(ObjectPropertyIterator *iter,
1155                                      ObjectClass *klass)
1156 {
1157     g_hash_table_iter_init(&iter->iter, klass->properties);
1158     iter->nextclass = object_class_get_parent(klass);
1159 }
1160 
1161 ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name,
1162                                            Error **errp)
1163 {
1164     ObjectProperty *prop;
1165     ObjectClass *parent_klass;
1166 
1167     parent_klass = object_class_get_parent(klass);
1168     if (parent_klass) {
1169         prop = object_class_property_find(parent_klass, name, NULL);
1170         if (prop) {
1171             return prop;
1172         }
1173     }
1174 
1175     prop = g_hash_table_lookup(klass->properties, name);
1176     if (!prop) {
1177         error_setg(errp, "Property '.%s' not found", name);
1178     }
1179     return prop;
1180 }
1181 
1182 void object_property_del(Object *obj, const char *name, Error **errp)
1183 {
1184     ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
1185 
1186     if (!prop) {
1187         error_setg(errp, "Property '.%s' not found", name);
1188         return;
1189     }
1190 
1191     if (prop->release) {
1192         prop->release(obj, name, prop->opaque);
1193     }
1194     g_hash_table_remove(obj->properties, name);
1195 }
1196 
1197 void object_property_get(Object *obj, Visitor *v, const char *name,
1198                          Error **errp)
1199 {
1200     ObjectProperty *prop = object_property_find(obj, name, errp);
1201     if (prop == NULL) {
1202         return;
1203     }
1204 
1205     if (!prop->get) {
1206         error_setg(errp, QERR_PERMISSION_DENIED);
1207     } else {
1208         prop->get(obj, v, name, prop->opaque, errp);
1209     }
1210 }
1211 
1212 void object_property_set(Object *obj, Visitor *v, const char *name,
1213                          Error **errp)
1214 {
1215     ObjectProperty *prop = object_property_find(obj, name, errp);
1216     if (prop == NULL) {
1217         return;
1218     }
1219 
1220     if (!prop->set) {
1221         error_setg(errp, QERR_PERMISSION_DENIED);
1222     } else {
1223         prop->set(obj, v, name, prop->opaque, errp);
1224     }
1225 }
1226 
1227 void object_property_set_str(Object *obj, const char *value,
1228                              const char *name, Error **errp)
1229 {
1230     QString *qstr = qstring_from_str(value);
1231     object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
1232 
1233     qobject_unref(qstr);
1234 }
1235 
1236 char *object_property_get_str(Object *obj, const char *name,
1237                               Error **errp)
1238 {
1239     QObject *ret = object_property_get_qobject(obj, name, errp);
1240     char *retval;
1241 
1242     if (!ret) {
1243         return NULL;
1244     }
1245 
1246     retval = g_strdup(qobject_get_try_str(ret));
1247     if (!retval) {
1248         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
1249     }
1250 
1251     qobject_unref(ret);
1252     return retval;
1253 }
1254 
1255 void object_property_set_link(Object *obj, Object *value,
1256                               const char *name, Error **errp)
1257 {
1258     if (value) {
1259         gchar *path = object_get_canonical_path(value);
1260         object_property_set_str(obj, path, name, errp);
1261         g_free(path);
1262     } else {
1263         object_property_set_str(obj, "", name, errp);
1264     }
1265 }
1266 
1267 Object *object_property_get_link(Object *obj, const char *name,
1268                                  Error **errp)
1269 {
1270     char *str = object_property_get_str(obj, name, errp);
1271     Object *target = NULL;
1272 
1273     if (str && *str) {
1274         target = object_resolve_path(str, NULL);
1275         if (!target) {
1276             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1277                       "Device '%s' not found", str);
1278         }
1279     }
1280 
1281     g_free(str);
1282     return target;
1283 }
1284 
1285 void object_property_set_bool(Object *obj, bool value,
1286                               const char *name, Error **errp)
1287 {
1288     QBool *qbool = qbool_from_bool(value);
1289     object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
1290 
1291     qobject_unref(qbool);
1292 }
1293 
1294 bool object_property_get_bool(Object *obj, const char *name,
1295                               Error **errp)
1296 {
1297     QObject *ret = object_property_get_qobject(obj, name, errp);
1298     QBool *qbool;
1299     bool retval;
1300 
1301     if (!ret) {
1302         return false;
1303     }
1304     qbool = qobject_to(QBool, ret);
1305     if (!qbool) {
1306         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
1307         retval = false;
1308     } else {
1309         retval = qbool_get_bool(qbool);
1310     }
1311 
1312     qobject_unref(ret);
1313     return retval;
1314 }
1315 
1316 void object_property_set_int(Object *obj, int64_t value,
1317                              const char *name, Error **errp)
1318 {
1319     QNum *qnum = qnum_from_int(value);
1320     object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
1321 
1322     qobject_unref(qnum);
1323 }
1324 
1325 int64_t object_property_get_int(Object *obj, const char *name,
1326                                 Error **errp)
1327 {
1328     QObject *ret = object_property_get_qobject(obj, name, errp);
1329     QNum *qnum;
1330     int64_t retval;
1331 
1332     if (!ret) {
1333         return -1;
1334     }
1335 
1336     qnum = qobject_to(QNum, ret);
1337     if (!qnum || !qnum_get_try_int(qnum, &retval)) {
1338         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
1339         retval = -1;
1340     }
1341 
1342     qobject_unref(ret);
1343     return retval;
1344 }
1345 
1346 void object_property_set_uint(Object *obj, uint64_t value,
1347                               const char *name, Error **errp)
1348 {
1349     QNum *qnum = qnum_from_uint(value);
1350 
1351     object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
1352     qobject_unref(qnum);
1353 }
1354 
1355 uint64_t object_property_get_uint(Object *obj, const char *name,
1356                                   Error **errp)
1357 {
1358     QObject *ret = object_property_get_qobject(obj, name, errp);
1359     QNum *qnum;
1360     uint64_t retval;
1361 
1362     if (!ret) {
1363         return 0;
1364     }
1365     qnum = qobject_to(QNum, ret);
1366     if (!qnum || !qnum_get_try_uint(qnum, &retval)) {
1367         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint");
1368         retval = 0;
1369     }
1370 
1371     qobject_unref(ret);
1372     return retval;
1373 }
1374 
1375 typedef struct EnumProperty {
1376     const QEnumLookup *lookup;
1377     int (*get)(Object *, Error **);
1378     void (*set)(Object *, int, Error **);
1379 } EnumProperty;
1380 
1381 int object_property_get_enum(Object *obj, const char *name,
1382                              const char *typename, Error **errp)
1383 {
1384     Error *err = NULL;
1385     Visitor *v;
1386     char *str;
1387     int ret;
1388     ObjectProperty *prop = object_property_find(obj, name, errp);
1389     EnumProperty *enumprop;
1390 
1391     if (prop == NULL) {
1392         return 0;
1393     }
1394 
1395     if (!g_str_equal(prop->type, typename)) {
1396         error_setg(errp, "Property %s on %s is not '%s' enum type",
1397                    name, object_class_get_name(
1398                        object_get_class(obj)), typename);
1399         return 0;
1400     }
1401 
1402     enumprop = prop->opaque;
1403 
1404     v = string_output_visitor_new(false, &str);
1405     object_property_get(obj, v, name, &err);
1406     if (err) {
1407         error_propagate(errp, err);
1408         visit_free(v);
1409         return 0;
1410     }
1411     visit_complete(v, &str);
1412     visit_free(v);
1413     v = string_input_visitor_new(str);
1414     visit_type_enum(v, name, &ret, enumprop->lookup, errp);
1415 
1416     g_free(str);
1417     visit_free(v);
1418 
1419     return ret;
1420 }
1421 
1422 void object_property_get_uint16List(Object *obj, const char *name,
1423                                     uint16List **list, Error **errp)
1424 {
1425     Error *err = NULL;
1426     Visitor *v;
1427     char *str;
1428 
1429     v = string_output_visitor_new(false, &str);
1430     object_property_get(obj, v, name, &err);
1431     if (err) {
1432         error_propagate(errp, err);
1433         goto out;
1434     }
1435     visit_complete(v, &str);
1436     visit_free(v);
1437     v = string_input_visitor_new(str);
1438     visit_type_uint16List(v, NULL, list, errp);
1439 
1440     g_free(str);
1441 out:
1442     visit_free(v);
1443 }
1444 
1445 void object_property_parse(Object *obj, const char *string,
1446                            const char *name, Error **errp)
1447 {
1448     Visitor *v = string_input_visitor_new(string);
1449     object_property_set(obj, v, name, errp);
1450     visit_free(v);
1451 }
1452 
1453 char *object_property_print(Object *obj, const char *name, bool human,
1454                             Error **errp)
1455 {
1456     Visitor *v;
1457     char *string = NULL;
1458     Error *local_err = NULL;
1459 
1460     v = string_output_visitor_new(human, &string);
1461     object_property_get(obj, v, name, &local_err);
1462     if (local_err) {
1463         error_propagate(errp, local_err);
1464         goto out;
1465     }
1466 
1467     visit_complete(v, &string);
1468 
1469 out:
1470     visit_free(v);
1471     return string;
1472 }
1473 
1474 const char *object_property_get_type(Object *obj, const char *name, Error **errp)
1475 {
1476     ObjectProperty *prop = object_property_find(obj, name, errp);
1477     if (prop == NULL) {
1478         return NULL;
1479     }
1480 
1481     return prop->type;
1482 }
1483 
1484 Object *object_get_root(void)
1485 {
1486     static Object *root;
1487 
1488     if (!root) {
1489         root = object_new("container");
1490     }
1491 
1492     return root;
1493 }
1494 
1495 Object *object_get_objects_root(void)
1496 {
1497     return container_get(object_get_root(), "/objects");
1498 }
1499 
1500 Object *object_get_internal_root(void)
1501 {
1502     static Object *internal_root;
1503 
1504     if (!internal_root) {
1505         internal_root = object_new("container");
1506     }
1507 
1508     return internal_root;
1509 }
1510 
1511 static void object_get_child_property(Object *obj, Visitor *v,
1512                                       const char *name, void *opaque,
1513                                       Error **errp)
1514 {
1515     Object *child = opaque;
1516     gchar *path;
1517 
1518     path = object_get_canonical_path(child);
1519     visit_type_str(v, name, &path, errp);
1520     g_free(path);
1521 }
1522 
1523 static Object *object_resolve_child_property(Object *parent, void *opaque, const gchar *part)
1524 {
1525     return opaque;
1526 }
1527 
1528 static void object_finalize_child_property(Object *obj, const char *name,
1529                                            void *opaque)
1530 {
1531     Object *child = opaque;
1532 
1533     if (child->class->unparent) {
1534         (child->class->unparent)(child);
1535     }
1536     child->parent = NULL;
1537     object_unref(child);
1538 }
1539 
1540 void object_property_add_child(Object *obj, const char *name,
1541                                Object *child, Error **errp)
1542 {
1543     Error *local_err = NULL;
1544     gchar *type;
1545     ObjectProperty *op;
1546 
1547     if (child->parent != NULL) {
1548         error_setg(errp, "child object is already parented");
1549         return;
1550     }
1551 
1552     type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
1553 
1554     op = object_property_add(obj, name, type, object_get_child_property, NULL,
1555                              object_finalize_child_property, child, &local_err);
1556     if (local_err) {
1557         error_propagate(errp, local_err);
1558         goto out;
1559     }
1560 
1561     op->resolve = object_resolve_child_property;
1562     object_ref(child);
1563     child->parent = obj;
1564 
1565 out:
1566     g_free(type);
1567 }
1568 
1569 void object_property_allow_set_link(const Object *obj, const char *name,
1570                                     Object *val, Error **errp)
1571 {
1572     /* Allow the link to be set, always */
1573 }
1574 
1575 typedef struct {
1576     Object **child;
1577     void (*check)(const Object *, const char *, Object *, Error **);
1578     ObjectPropertyLinkFlags flags;
1579 } LinkProperty;
1580 
1581 static void object_get_link_property(Object *obj, Visitor *v,
1582                                      const char *name, void *opaque,
1583                                      Error **errp)
1584 {
1585     LinkProperty *lprop = opaque;
1586     Object **child = lprop->child;
1587     gchar *path;
1588 
1589     if (*child) {
1590         path = object_get_canonical_path(*child);
1591         visit_type_str(v, name, &path, errp);
1592         g_free(path);
1593     } else {
1594         path = (gchar *)"";
1595         visit_type_str(v, name, &path, errp);
1596     }
1597 }
1598 
1599 /*
1600  * object_resolve_link:
1601  *
1602  * Lookup an object and ensure its type matches the link property type.  This
1603  * is similar to object_resolve_path() except type verification against the
1604  * link property is performed.
1605  *
1606  * Returns: The matched object or NULL on path lookup failures.
1607  */
1608 static Object *object_resolve_link(Object *obj, const char *name,
1609                                    const char *path, Error **errp)
1610 {
1611     const char *type;
1612     gchar *target_type;
1613     bool ambiguous = false;
1614     Object *target;
1615 
1616     /* Go from link<FOO> to FOO.  */
1617     type = object_property_get_type(obj, name, NULL);
1618     target_type = g_strndup(&type[5], strlen(type) - 6);
1619     target = object_resolve_path_type(path, target_type, &ambiguous);
1620 
1621     if (ambiguous) {
1622         error_setg(errp, "Path '%s' does not uniquely identify an object",
1623                    path);
1624     } else if (!target) {
1625         target = object_resolve_path(path, &ambiguous);
1626         if (target || ambiguous) {
1627             error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
1628         } else {
1629             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1630                       "Device '%s' not found", path);
1631         }
1632         target = NULL;
1633     }
1634     g_free(target_type);
1635 
1636     return target;
1637 }
1638 
1639 static void object_set_link_property(Object *obj, Visitor *v,
1640                                      const char *name, void *opaque,
1641                                      Error **errp)
1642 {
1643     Error *local_err = NULL;
1644     LinkProperty *prop = opaque;
1645     Object **child = prop->child;
1646     Object *old_target = *child;
1647     Object *new_target = NULL;
1648     char *path = NULL;
1649 
1650     visit_type_str(v, name, &path, &local_err);
1651 
1652     if (!local_err && strcmp(path, "") != 0) {
1653         new_target = object_resolve_link(obj, name, path, &local_err);
1654     }
1655 
1656     g_free(path);
1657     if (local_err) {
1658         error_propagate(errp, local_err);
1659         return;
1660     }
1661 
1662     prop->check(obj, name, new_target, &local_err);
1663     if (local_err) {
1664         error_propagate(errp, local_err);
1665         return;
1666     }
1667 
1668     *child = new_target;
1669     if (prop->flags == OBJ_PROP_LINK_STRONG) {
1670         object_ref(new_target);
1671         object_unref(old_target);
1672     }
1673 }
1674 
1675 static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part)
1676 {
1677     LinkProperty *lprop = opaque;
1678 
1679     return *lprop->child;
1680 }
1681 
1682 static void object_release_link_property(Object *obj, const char *name,
1683                                          void *opaque)
1684 {
1685     LinkProperty *prop = opaque;
1686 
1687     if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->child) {
1688         object_unref(*prop->child);
1689     }
1690     g_free(prop);
1691 }
1692 
1693 void object_property_add_link(Object *obj, const char *name,
1694                               const char *type, Object **child,
1695                               void (*check)(const Object *, const char *,
1696                                             Object *, Error **),
1697                               ObjectPropertyLinkFlags flags,
1698                               Error **errp)
1699 {
1700     Error *local_err = NULL;
1701     LinkProperty *prop = g_malloc(sizeof(*prop));
1702     gchar *full_type;
1703     ObjectProperty *op;
1704 
1705     prop->child = child;
1706     prop->check = check;
1707     prop->flags = flags;
1708 
1709     full_type = g_strdup_printf("link<%s>", type);
1710 
1711     op = object_property_add(obj, name, full_type,
1712                              object_get_link_property,
1713                              check ? object_set_link_property : NULL,
1714                              object_release_link_property,
1715                              prop,
1716                              &local_err);
1717     if (local_err) {
1718         error_propagate(errp, local_err);
1719         g_free(prop);
1720         goto out;
1721     }
1722 
1723     op->resolve = object_resolve_link_property;
1724 
1725 out:
1726     g_free(full_type);
1727 }
1728 
1729 void object_property_add_const_link(Object *obj, const char *name,
1730                                     Object *target, Error **errp)
1731 {
1732     char *link_type;
1733     ObjectProperty *op;
1734 
1735     link_type = g_strdup_printf("link<%s>", object_get_typename(target));
1736     op = object_property_add(obj, name, link_type,
1737                              object_get_child_property, NULL,
1738                              NULL, target, errp);
1739     if (op != NULL) {
1740         op->resolve = object_resolve_child_property;
1741     }
1742     g_free(link_type);
1743 }
1744 
1745 gchar *object_get_canonical_path_component(Object *obj)
1746 {
1747     ObjectProperty *prop = NULL;
1748     GHashTableIter iter;
1749 
1750     if (obj->parent == NULL) {
1751         return NULL;
1752     }
1753 
1754     g_hash_table_iter_init(&iter, obj->parent->properties);
1755     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
1756         if (!object_property_is_child(prop)) {
1757             continue;
1758         }
1759 
1760         if (prop->opaque == obj) {
1761             return g_strdup(prop->name);
1762         }
1763     }
1764 
1765     /* obj had a parent but was not a child, should never happen */
1766     g_assert_not_reached();
1767     return NULL;
1768 }
1769 
1770 gchar *object_get_canonical_path(Object *obj)
1771 {
1772     Object *root = object_get_root();
1773     char *newpath, *path = NULL;
1774 
1775     if (obj == root) {
1776         return g_strdup("/");
1777     }
1778 
1779     do {
1780         char *component = object_get_canonical_path_component(obj);
1781 
1782         if (!component) {
1783             /* A canonical path must be complete, so discard what was
1784              * collected so far.
1785              */
1786             g_free(path);
1787             return NULL;
1788         }
1789 
1790         newpath = g_strdup_printf("/%s%s", component, path ? path : "");
1791         g_free(path);
1792         g_free(component);
1793         path = newpath;
1794         obj = obj->parent;
1795     } while (obj != root);
1796 
1797     return path;
1798 }
1799 
1800 Object *object_resolve_path_component(Object *parent, const gchar *part)
1801 {
1802     ObjectProperty *prop = object_property_find(parent, part, NULL);
1803     if (prop == NULL) {
1804         return NULL;
1805     }
1806 
1807     if (prop->resolve) {
1808         return prop->resolve(parent, prop->opaque, part);
1809     } else {
1810         return NULL;
1811     }
1812 }
1813 
1814 static Object *object_resolve_abs_path(Object *parent,
1815                                           gchar **parts,
1816                                           const char *typename,
1817                                           int index)
1818 {
1819     Object *child;
1820 
1821     if (parts[index] == NULL) {
1822         return object_dynamic_cast(parent, typename);
1823     }
1824 
1825     if (strcmp(parts[index], "") == 0) {
1826         return object_resolve_abs_path(parent, parts, typename, index + 1);
1827     }
1828 
1829     child = object_resolve_path_component(parent, parts[index]);
1830     if (!child) {
1831         return NULL;
1832     }
1833 
1834     return object_resolve_abs_path(child, parts, typename, index + 1);
1835 }
1836 
1837 static Object *object_resolve_partial_path(Object *parent,
1838                                               gchar **parts,
1839                                               const char *typename,
1840                                               bool *ambiguous)
1841 {
1842     Object *obj;
1843     GHashTableIter iter;
1844     ObjectProperty *prop;
1845 
1846     obj = object_resolve_abs_path(parent, parts, typename, 0);
1847 
1848     g_hash_table_iter_init(&iter, parent->properties);
1849     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
1850         Object *found;
1851 
1852         if (!object_property_is_child(prop)) {
1853             continue;
1854         }
1855 
1856         found = object_resolve_partial_path(prop->opaque, parts,
1857                                             typename, ambiguous);
1858         if (found) {
1859             if (obj) {
1860                 *ambiguous = true;
1861                 return NULL;
1862             }
1863             obj = found;
1864         }
1865 
1866         if (*ambiguous) {
1867             return NULL;
1868         }
1869     }
1870 
1871     return obj;
1872 }
1873 
1874 Object *object_resolve_path_type(const char *path, const char *typename,
1875                                  bool *ambiguousp)
1876 {
1877     Object *obj;
1878     gchar **parts;
1879 
1880     parts = g_strsplit(path, "/", 0);
1881     assert(parts);
1882 
1883     if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
1884         bool ambiguous = false;
1885         obj = object_resolve_partial_path(object_get_root(), parts,
1886                                           typename, &ambiguous);
1887         if (ambiguousp) {
1888             *ambiguousp = ambiguous;
1889         }
1890     } else {
1891         obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
1892     }
1893 
1894     g_strfreev(parts);
1895 
1896     return obj;
1897 }
1898 
1899 Object *object_resolve_path(const char *path, bool *ambiguous)
1900 {
1901     return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
1902 }
1903 
1904 typedef struct StringProperty
1905 {
1906     char *(*get)(Object *, Error **);
1907     void (*set)(Object *, const char *, Error **);
1908 } StringProperty;
1909 
1910 static void property_get_str(Object *obj, Visitor *v, const char *name,
1911                              void *opaque, Error **errp)
1912 {
1913     StringProperty *prop = opaque;
1914     char *value;
1915     Error *err = NULL;
1916 
1917     value = prop->get(obj, &err);
1918     if (err) {
1919         error_propagate(errp, err);
1920         return;
1921     }
1922 
1923     visit_type_str(v, name, &value, errp);
1924     g_free(value);
1925 }
1926 
1927 static void property_set_str(Object *obj, Visitor *v, const char *name,
1928                              void *opaque, Error **errp)
1929 {
1930     StringProperty *prop = opaque;
1931     char *value;
1932     Error *local_err = NULL;
1933 
1934     visit_type_str(v, name, &value, &local_err);
1935     if (local_err) {
1936         error_propagate(errp, local_err);
1937         return;
1938     }
1939 
1940     prop->set(obj, value, errp);
1941     g_free(value);
1942 }
1943 
1944 static void property_release_str(Object *obj, const char *name,
1945                                  void *opaque)
1946 {
1947     StringProperty *prop = opaque;
1948     g_free(prop);
1949 }
1950 
1951 void object_property_add_str(Object *obj, const char *name,
1952                            char *(*get)(Object *, Error **),
1953                            void (*set)(Object *, const char *, Error **),
1954                            Error **errp)
1955 {
1956     Error *local_err = NULL;
1957     StringProperty *prop = g_malloc0(sizeof(*prop));
1958 
1959     prop->get = get;
1960     prop->set = set;
1961 
1962     object_property_add(obj, name, "string",
1963                         get ? property_get_str : NULL,
1964                         set ? property_set_str : NULL,
1965                         property_release_str,
1966                         prop, &local_err);
1967     if (local_err) {
1968         error_propagate(errp, local_err);
1969         g_free(prop);
1970     }
1971 }
1972 
1973 void object_class_property_add_str(ObjectClass *klass, const char *name,
1974                                    char *(*get)(Object *, Error **),
1975                                    void (*set)(Object *, const char *,
1976                                                Error **),
1977                                    Error **errp)
1978 {
1979     Error *local_err = NULL;
1980     StringProperty *prop = g_malloc0(sizeof(*prop));
1981 
1982     prop->get = get;
1983     prop->set = set;
1984 
1985     object_class_property_add(klass, name, "string",
1986                               get ? property_get_str : NULL,
1987                               set ? property_set_str : NULL,
1988                               property_release_str,
1989                               prop, &local_err);
1990     if (local_err) {
1991         error_propagate(errp, local_err);
1992         g_free(prop);
1993     }
1994 }
1995 
1996 typedef struct BoolProperty
1997 {
1998     bool (*get)(Object *, Error **);
1999     void (*set)(Object *, bool, Error **);
2000 } BoolProperty;
2001 
2002 static void property_get_bool(Object *obj, Visitor *v, const char *name,
2003                               void *opaque, Error **errp)
2004 {
2005     BoolProperty *prop = opaque;
2006     bool value;
2007     Error *err = NULL;
2008 
2009     value = prop->get(obj, &err);
2010     if (err) {
2011         error_propagate(errp, err);
2012         return;
2013     }
2014 
2015     visit_type_bool(v, name, &value, errp);
2016 }
2017 
2018 static void property_set_bool(Object *obj, Visitor *v, const char *name,
2019                               void *opaque, Error **errp)
2020 {
2021     BoolProperty *prop = opaque;
2022     bool value;
2023     Error *local_err = NULL;
2024 
2025     visit_type_bool(v, name, &value, &local_err);
2026     if (local_err) {
2027         error_propagate(errp, local_err);
2028         return;
2029     }
2030 
2031     prop->set(obj, value, errp);
2032 }
2033 
2034 static void property_release_bool(Object *obj, const char *name,
2035                                   void *opaque)
2036 {
2037     BoolProperty *prop = opaque;
2038     g_free(prop);
2039 }
2040 
2041 void object_property_add_bool(Object *obj, const char *name,
2042                               bool (*get)(Object *, Error **),
2043                               void (*set)(Object *, bool, Error **),
2044                               Error **errp)
2045 {
2046     Error *local_err = NULL;
2047     BoolProperty *prop = g_malloc0(sizeof(*prop));
2048 
2049     prop->get = get;
2050     prop->set = set;
2051 
2052     object_property_add(obj, name, "bool",
2053                         get ? property_get_bool : NULL,
2054                         set ? property_set_bool : NULL,
2055                         property_release_bool,
2056                         prop, &local_err);
2057     if (local_err) {
2058         error_propagate(errp, local_err);
2059         g_free(prop);
2060     }
2061 }
2062 
2063 void object_class_property_add_bool(ObjectClass *klass, const char *name,
2064                                     bool (*get)(Object *, Error **),
2065                                     void (*set)(Object *, bool, Error **),
2066                                     Error **errp)
2067 {
2068     Error *local_err = NULL;
2069     BoolProperty *prop = g_malloc0(sizeof(*prop));
2070 
2071     prop->get = get;
2072     prop->set = set;
2073 
2074     object_class_property_add(klass, name, "bool",
2075                               get ? property_get_bool : NULL,
2076                               set ? property_set_bool : NULL,
2077                               property_release_bool,
2078                               prop, &local_err);
2079     if (local_err) {
2080         error_propagate(errp, local_err);
2081         g_free(prop);
2082     }
2083 }
2084 
2085 static void property_get_enum(Object *obj, Visitor *v, const char *name,
2086                               void *opaque, Error **errp)
2087 {
2088     EnumProperty *prop = opaque;
2089     int value;
2090     Error *err = NULL;
2091 
2092     value = prop->get(obj, &err);
2093     if (err) {
2094         error_propagate(errp, err);
2095         return;
2096     }
2097 
2098     visit_type_enum(v, name, &value, prop->lookup, errp);
2099 }
2100 
2101 static void property_set_enum(Object *obj, Visitor *v, const char *name,
2102                               void *opaque, Error **errp)
2103 {
2104     EnumProperty *prop = opaque;
2105     int value;
2106     Error *err = NULL;
2107 
2108     visit_type_enum(v, name, &value, prop->lookup, &err);
2109     if (err) {
2110         error_propagate(errp, err);
2111         return;
2112     }
2113     prop->set(obj, value, errp);
2114 }
2115 
2116 static void property_release_enum(Object *obj, const char *name,
2117                                   void *opaque)
2118 {
2119     EnumProperty *prop = opaque;
2120     g_free(prop);
2121 }
2122 
2123 void object_property_add_enum(Object *obj, const char *name,
2124                               const char *typename,
2125                               const QEnumLookup *lookup,
2126                               int (*get)(Object *, Error **),
2127                               void (*set)(Object *, int, Error **),
2128                               Error **errp)
2129 {
2130     Error *local_err = NULL;
2131     EnumProperty *prop = g_malloc(sizeof(*prop));
2132 
2133     prop->lookup = lookup;
2134     prop->get = get;
2135     prop->set = set;
2136 
2137     object_property_add(obj, name, typename,
2138                         get ? property_get_enum : NULL,
2139                         set ? property_set_enum : NULL,
2140                         property_release_enum,
2141                         prop, &local_err);
2142     if (local_err) {
2143         error_propagate(errp, local_err);
2144         g_free(prop);
2145     }
2146 }
2147 
2148 void object_class_property_add_enum(ObjectClass *klass, const char *name,
2149                                     const char *typename,
2150                                     const QEnumLookup *lookup,
2151                                     int (*get)(Object *, Error **),
2152                                     void (*set)(Object *, int, Error **),
2153                                     Error **errp)
2154 {
2155     Error *local_err = NULL;
2156     EnumProperty *prop = g_malloc(sizeof(*prop));
2157 
2158     prop->lookup = lookup;
2159     prop->get = get;
2160     prop->set = set;
2161 
2162     object_class_property_add(klass, name, typename,
2163                               get ? property_get_enum : NULL,
2164                               set ? property_set_enum : NULL,
2165                               property_release_enum,
2166                               prop, &local_err);
2167     if (local_err) {
2168         error_propagate(errp, local_err);
2169         g_free(prop);
2170     }
2171 }
2172 
2173 typedef struct TMProperty {
2174     void (*get)(Object *, struct tm *, Error **);
2175 } TMProperty;
2176 
2177 static void property_get_tm(Object *obj, Visitor *v, const char *name,
2178                             void *opaque, Error **errp)
2179 {
2180     TMProperty *prop = opaque;
2181     Error *err = NULL;
2182     struct tm value;
2183 
2184     prop->get(obj, &value, &err);
2185     if (err) {
2186         goto out;
2187     }
2188 
2189     visit_start_struct(v, name, NULL, 0, &err);
2190     if (err) {
2191         goto out;
2192     }
2193     visit_type_int32(v, "tm_year", &value.tm_year, &err);
2194     if (err) {
2195         goto out_end;
2196     }
2197     visit_type_int32(v, "tm_mon", &value.tm_mon, &err);
2198     if (err) {
2199         goto out_end;
2200     }
2201     visit_type_int32(v, "tm_mday", &value.tm_mday, &err);
2202     if (err) {
2203         goto out_end;
2204     }
2205     visit_type_int32(v, "tm_hour", &value.tm_hour, &err);
2206     if (err) {
2207         goto out_end;
2208     }
2209     visit_type_int32(v, "tm_min", &value.tm_min, &err);
2210     if (err) {
2211         goto out_end;
2212     }
2213     visit_type_int32(v, "tm_sec", &value.tm_sec, &err);
2214     if (err) {
2215         goto out_end;
2216     }
2217     visit_check_struct(v, &err);
2218 out_end:
2219     visit_end_struct(v, NULL);
2220 out:
2221     error_propagate(errp, err);
2222 
2223 }
2224 
2225 static void property_release_tm(Object *obj, const char *name,
2226                                 void *opaque)
2227 {
2228     TMProperty *prop = opaque;
2229     g_free(prop);
2230 }
2231 
2232 void object_property_add_tm(Object *obj, const char *name,
2233                             void (*get)(Object *, struct tm *, Error **),
2234                             Error **errp)
2235 {
2236     Error *local_err = NULL;
2237     TMProperty *prop = g_malloc0(sizeof(*prop));
2238 
2239     prop->get = get;
2240 
2241     object_property_add(obj, name, "struct tm",
2242                         get ? property_get_tm : NULL, NULL,
2243                         property_release_tm,
2244                         prop, &local_err);
2245     if (local_err) {
2246         error_propagate(errp, local_err);
2247         g_free(prop);
2248     }
2249 }
2250 
2251 void object_class_property_add_tm(ObjectClass *klass, const char *name,
2252                                   void (*get)(Object *, struct tm *, Error **),
2253                                   Error **errp)
2254 {
2255     Error *local_err = NULL;
2256     TMProperty *prop = g_malloc0(sizeof(*prop));
2257 
2258     prop->get = get;
2259 
2260     object_class_property_add(klass, name, "struct tm",
2261                               get ? property_get_tm : NULL, NULL,
2262                               property_release_tm,
2263                               prop, &local_err);
2264     if (local_err) {
2265         error_propagate(errp, local_err);
2266         g_free(prop);
2267     }
2268 }
2269 
2270 static char *qdev_get_type(Object *obj, Error **errp)
2271 {
2272     return g_strdup(object_get_typename(obj));
2273 }
2274 
2275 static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name,
2276                                    void *opaque, Error **errp)
2277 {
2278     uint8_t value = *(uint8_t *)opaque;
2279     visit_type_uint8(v, name, &value, errp);
2280 }
2281 
2282 static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name,
2283                                     void *opaque, Error **errp)
2284 {
2285     uint16_t value = *(uint16_t *)opaque;
2286     visit_type_uint16(v, name, &value, errp);
2287 }
2288 
2289 static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name,
2290                                     void *opaque, Error **errp)
2291 {
2292     uint32_t value = *(uint32_t *)opaque;
2293     visit_type_uint32(v, name, &value, errp);
2294 }
2295 
2296 static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name,
2297                                     void *opaque, Error **errp)
2298 {
2299     uint64_t value = *(uint64_t *)opaque;
2300     visit_type_uint64(v, name, &value, errp);
2301 }
2302 
2303 void object_property_add_uint8_ptr(Object *obj, const char *name,
2304                                    const uint8_t *v, Error **errp)
2305 {
2306     object_property_add(obj, name, "uint8", property_get_uint8_ptr,
2307                         NULL, NULL, (void *)v, errp);
2308 }
2309 
2310 void object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
2311                                          const uint8_t *v, Error **errp)
2312 {
2313     object_class_property_add(klass, name, "uint8", property_get_uint8_ptr,
2314                               NULL, NULL, (void *)v, errp);
2315 }
2316 
2317 void object_property_add_uint16_ptr(Object *obj, const char *name,
2318                                     const uint16_t *v, Error **errp)
2319 {
2320     object_property_add(obj, name, "uint16", property_get_uint16_ptr,
2321                         NULL, NULL, (void *)v, errp);
2322 }
2323 
2324 void object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
2325                                           const uint16_t *v, Error **errp)
2326 {
2327     object_class_property_add(klass, name, "uint16", property_get_uint16_ptr,
2328                               NULL, NULL, (void *)v, errp);
2329 }
2330 
2331 void object_property_add_uint32_ptr(Object *obj, const char *name,
2332                                     const uint32_t *v, Error **errp)
2333 {
2334     object_property_add(obj, name, "uint32", property_get_uint32_ptr,
2335                         NULL, NULL, (void *)v, errp);
2336 }
2337 
2338 void object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
2339                                           const uint32_t *v, Error **errp)
2340 {
2341     object_class_property_add(klass, name, "uint32", property_get_uint32_ptr,
2342                               NULL, NULL, (void *)v, errp);
2343 }
2344 
2345 void object_property_add_uint64_ptr(Object *obj, const char *name,
2346                                     const uint64_t *v, Error **errp)
2347 {
2348     object_property_add(obj, name, "uint64", property_get_uint64_ptr,
2349                         NULL, NULL, (void *)v, errp);
2350 }
2351 
2352 void object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
2353                                           const uint64_t *v, Error **errp)
2354 {
2355     object_class_property_add(klass, name, "uint64", property_get_uint64_ptr,
2356                               NULL, NULL, (void *)v, errp);
2357 }
2358 
2359 typedef struct {
2360     Object *target_obj;
2361     char *target_name;
2362 } AliasProperty;
2363 
2364 static void property_get_alias(Object *obj, Visitor *v, const char *name,
2365                                void *opaque, Error **errp)
2366 {
2367     AliasProperty *prop = opaque;
2368 
2369     object_property_get(prop->target_obj, v, prop->target_name, errp);
2370 }
2371 
2372 static void property_set_alias(Object *obj, Visitor *v, const char *name,
2373                                void *opaque, Error **errp)
2374 {
2375     AliasProperty *prop = opaque;
2376 
2377     object_property_set(prop->target_obj, v, prop->target_name, errp);
2378 }
2379 
2380 static Object *property_resolve_alias(Object *obj, void *opaque,
2381                                       const gchar *part)
2382 {
2383     AliasProperty *prop = opaque;
2384 
2385     return object_resolve_path_component(prop->target_obj, prop->target_name);
2386 }
2387 
2388 static void property_release_alias(Object *obj, const char *name, void *opaque)
2389 {
2390     AliasProperty *prop = opaque;
2391 
2392     g_free(prop->target_name);
2393     g_free(prop);
2394 }
2395 
2396 void object_property_add_alias(Object *obj, const char *name,
2397                                Object *target_obj, const char *target_name,
2398                                Error **errp)
2399 {
2400     AliasProperty *prop;
2401     ObjectProperty *op;
2402     ObjectProperty *target_prop;
2403     gchar *prop_type;
2404     Error *local_err = NULL;
2405 
2406     target_prop = object_property_find(target_obj, target_name, errp);
2407     if (!target_prop) {
2408         return;
2409     }
2410 
2411     if (object_property_is_child(target_prop)) {
2412         prop_type = g_strdup_printf("link%s",
2413                                     target_prop->type + strlen("child"));
2414     } else {
2415         prop_type = g_strdup(target_prop->type);
2416     }
2417 
2418     prop = g_malloc(sizeof(*prop));
2419     prop->target_obj = target_obj;
2420     prop->target_name = g_strdup(target_name);
2421 
2422     op = object_property_add(obj, name, prop_type,
2423                              property_get_alias,
2424                              property_set_alias,
2425                              property_release_alias,
2426                              prop, &local_err);
2427     if (local_err) {
2428         error_propagate(errp, local_err);
2429         g_free(prop);
2430         goto out;
2431     }
2432     op->resolve = property_resolve_alias;
2433 
2434     object_property_set_description(obj, op->name,
2435                                     target_prop->description,
2436                                     &error_abort);
2437 
2438 out:
2439     g_free(prop_type);
2440 }
2441 
2442 void object_property_set_description(Object *obj, const char *name,
2443                                      const char *description, Error **errp)
2444 {
2445     ObjectProperty *op;
2446 
2447     op = object_property_find(obj, name, errp);
2448     if (!op) {
2449         return;
2450     }
2451 
2452     g_free(op->description);
2453     op->description = g_strdup(description);
2454 }
2455 
2456 void object_class_property_set_description(ObjectClass *klass,
2457                                            const char *name,
2458                                            const char *description,
2459                                            Error **errp)
2460 {
2461     ObjectProperty *op;
2462 
2463     op = g_hash_table_lookup(klass->properties, name);
2464     if (!op) {
2465         error_setg(errp, "Property '.%s' not found", name);
2466         return;
2467     }
2468 
2469     g_free(op->description);
2470     op->description = g_strdup(description);
2471 }
2472 
2473 static void object_class_init(ObjectClass *klass, void *data)
2474 {
2475     object_class_property_add_str(klass, "type", qdev_get_type,
2476                                   NULL, &error_abort);
2477 }
2478 
2479 static void register_types(void)
2480 {
2481     static TypeInfo interface_info = {
2482         .name = TYPE_INTERFACE,
2483         .class_size = sizeof(InterfaceClass),
2484         .abstract = true,
2485     };
2486 
2487     static TypeInfo object_info = {
2488         .name = TYPE_OBJECT,
2489         .instance_size = sizeof(Object),
2490         .class_init = object_class_init,
2491         .abstract = true,
2492     };
2493 
2494     type_interface = type_register_internal(&interface_info);
2495     type_register_internal(&object_info);
2496 }
2497 
2498 type_init(register_types)
2499