xref: /openbmc/qemu/qom/object.c (revision 99d46107)
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     if (id != NULL) {
650         object_property_add_child(parent, id, obj, &local_err);
651         if (local_err) {
652             goto error;
653         }
654     }
655 
656     uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
657     if (uc) {
658         user_creatable_complete(uc, &local_err);
659         if (local_err) {
660             if (id != NULL) {
661                 object_unparent(obj);
662             }
663             goto error;
664         }
665     }
666 
667     object_unref(OBJECT(obj));
668     return obj;
669 
670  error:
671     error_propagate(errp, local_err);
672     object_unref(obj);
673     return NULL;
674 }
675 
676 
677 int object_set_props(Object *obj,
678                      Error **errp,
679                      ...)
680 {
681     va_list vargs;
682     int ret;
683 
684     va_start(vargs, errp);
685     ret = object_set_propv(obj, errp, vargs);
686     va_end(vargs);
687 
688     return ret;
689 }
690 
691 
692 int object_set_propv(Object *obj,
693                      Error **errp,
694                      va_list vargs)
695 {
696     const char *propname;
697     Error *local_err = NULL;
698 
699     propname = va_arg(vargs, char *);
700     while (propname != NULL) {
701         const char *value = va_arg(vargs, char *);
702 
703         g_assert(value != NULL);
704         object_property_parse(obj, value, propname, &local_err);
705         if (local_err) {
706             error_propagate(errp, local_err);
707             return -1;
708         }
709         propname = va_arg(vargs, char *);
710     }
711 
712     return 0;
713 }
714 
715 
716 Object *object_dynamic_cast(Object *obj, const char *typename)
717 {
718     if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
719         return obj;
720     }
721 
722     return NULL;
723 }
724 
725 Object *object_dynamic_cast_assert(Object *obj, const char *typename,
726                                    const char *file, int line, const char *func)
727 {
728     trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
729                                      typename, file, line, func);
730 
731 #ifdef CONFIG_QOM_CAST_DEBUG
732     int i;
733     Object *inst;
734 
735     for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
736         if (atomic_read(&obj->class->object_cast_cache[i]) == typename) {
737             goto out;
738         }
739     }
740 
741     inst = object_dynamic_cast(obj, typename);
742 
743     if (!inst && obj) {
744         fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
745                 file, line, func, obj, typename);
746         abort();
747     }
748 
749     assert(obj == inst);
750 
751     if (obj && obj == inst) {
752         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
753             atomic_set(&obj->class->object_cast_cache[i - 1],
754                        atomic_read(&obj->class->object_cast_cache[i]));
755         }
756         atomic_set(&obj->class->object_cast_cache[i - 1], typename);
757     }
758 
759 out:
760 #endif
761     return obj;
762 }
763 
764 ObjectClass *object_class_dynamic_cast(ObjectClass *class,
765                                        const char *typename)
766 {
767     ObjectClass *ret = NULL;
768     TypeImpl *target_type;
769     TypeImpl *type;
770 
771     if (!class) {
772         return NULL;
773     }
774 
775     /* A simple fast path that can trigger a lot for leaf classes.  */
776     type = class->type;
777     if (type->name == typename) {
778         return class;
779     }
780 
781     target_type = type_get_by_name(typename);
782     if (!target_type) {
783         /* target class type unknown, so fail the cast */
784         return NULL;
785     }
786 
787     if (type->class->interfaces &&
788             type_is_ancestor(target_type, type_interface)) {
789         int found = 0;
790         GSList *i;
791 
792         for (i = class->interfaces; i; i = i->next) {
793             ObjectClass *target_class = i->data;
794 
795             if (type_is_ancestor(target_class->type, target_type)) {
796                 ret = target_class;
797                 found++;
798             }
799          }
800 
801         /* The match was ambiguous, don't allow a cast */
802         if (found > 1) {
803             ret = NULL;
804         }
805     } else if (type_is_ancestor(type, target_type)) {
806         ret = class;
807     }
808 
809     return ret;
810 }
811 
812 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
813                                               const char *typename,
814                                               const char *file, int line,
815                                               const char *func)
816 {
817     ObjectClass *ret;
818 
819     trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
820                                            typename, file, line, func);
821 
822 #ifdef CONFIG_QOM_CAST_DEBUG
823     int i;
824 
825     for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
826         if (atomic_read(&class->class_cast_cache[i]) == typename) {
827             ret = class;
828             goto out;
829         }
830     }
831 #else
832     if (!class || !class->interfaces) {
833         return class;
834     }
835 #endif
836 
837     ret = object_class_dynamic_cast(class, typename);
838     if (!ret && class) {
839         fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
840                 file, line, func, class, typename);
841         abort();
842     }
843 
844 #ifdef CONFIG_QOM_CAST_DEBUG
845     if (class && ret == class) {
846         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
847             atomic_set(&class->class_cast_cache[i - 1],
848                        atomic_read(&class->class_cast_cache[i]));
849         }
850         atomic_set(&class->class_cast_cache[i - 1], typename);
851     }
852 out:
853 #endif
854     return ret;
855 }
856 
857 const char *object_get_typename(const Object *obj)
858 {
859     return obj->class->type->name;
860 }
861 
862 ObjectClass *object_get_class(Object *obj)
863 {
864     return obj->class;
865 }
866 
867 bool object_class_is_abstract(ObjectClass *klass)
868 {
869     return klass->type->abstract;
870 }
871 
872 const char *object_class_get_name(ObjectClass *klass)
873 {
874     return klass->type->name;
875 }
876 
877 ObjectClass *object_class_by_name(const char *typename)
878 {
879     TypeImpl *type = type_get_by_name(typename);
880 
881     if (!type) {
882         return NULL;
883     }
884 
885     type_initialize(type);
886 
887     return type->class;
888 }
889 
890 ObjectClass *object_class_get_parent(ObjectClass *class)
891 {
892     TypeImpl *type = type_get_parent(class->type);
893 
894     if (!type) {
895         return NULL;
896     }
897 
898     type_initialize(type);
899 
900     return type->class;
901 }
902 
903 typedef struct OCFData
904 {
905     void (*fn)(ObjectClass *klass, void *opaque);
906     const char *implements_type;
907     bool include_abstract;
908     void *opaque;
909 } OCFData;
910 
911 static void object_class_foreach_tramp(gpointer key, gpointer value,
912                                        gpointer opaque)
913 {
914     OCFData *data = opaque;
915     TypeImpl *type = value;
916     ObjectClass *k;
917 
918     type_initialize(type);
919     k = type->class;
920 
921     if (!data->include_abstract && type->abstract) {
922         return;
923     }
924 
925     if (data->implements_type &&
926         !object_class_dynamic_cast(k, data->implements_type)) {
927         return;
928     }
929 
930     data->fn(k, data->opaque);
931 }
932 
933 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
934                           const char *implements_type, bool include_abstract,
935                           void *opaque)
936 {
937     OCFData data = { fn, implements_type, include_abstract, opaque };
938 
939     enumerating_types = true;
940     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
941     enumerating_types = false;
942 }
943 
944 static int do_object_child_foreach(Object *obj,
945                                    int (*fn)(Object *child, void *opaque),
946                                    void *opaque, bool recurse)
947 {
948     GHashTableIter iter;
949     ObjectProperty *prop;
950     int ret = 0;
951 
952     g_hash_table_iter_init(&iter, obj->properties);
953     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
954         if (object_property_is_child(prop)) {
955             Object *child = prop->opaque;
956 
957             ret = fn(child, opaque);
958             if (ret != 0) {
959                 break;
960             }
961             if (recurse) {
962                 do_object_child_foreach(child, fn, opaque, true);
963             }
964         }
965     }
966     return ret;
967 }
968 
969 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
970                          void *opaque)
971 {
972     return do_object_child_foreach(obj, fn, opaque, false);
973 }
974 
975 int object_child_foreach_recursive(Object *obj,
976                                    int (*fn)(Object *child, void *opaque),
977                                    void *opaque)
978 {
979     return do_object_child_foreach(obj, fn, opaque, true);
980 }
981 
982 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
983 {
984     GSList **list = opaque;
985 
986     *list = g_slist_prepend(*list, klass);
987 }
988 
989 GSList *object_class_get_list(const char *implements_type,
990                               bool include_abstract)
991 {
992     GSList *list = NULL;
993 
994     object_class_foreach(object_class_get_list_tramp,
995                          implements_type, include_abstract, &list);
996     return list;
997 }
998 
999 static gint object_class_cmp(gconstpointer a, gconstpointer b)
1000 {
1001     return strcasecmp(object_class_get_name((ObjectClass *)a),
1002                       object_class_get_name((ObjectClass *)b));
1003 }
1004 
1005 GSList *object_class_get_list_sorted(const char *implements_type,
1006                                      bool include_abstract)
1007 {
1008     return g_slist_sort(object_class_get_list(implements_type, include_abstract),
1009                         object_class_cmp);
1010 }
1011 
1012 void object_ref(Object *obj)
1013 {
1014     if (!obj) {
1015         return;
1016     }
1017     atomic_inc(&obj->ref);
1018 }
1019 
1020 void object_unref(Object *obj)
1021 {
1022     if (!obj) {
1023         return;
1024     }
1025     g_assert(obj->ref > 0);
1026 
1027     /* parent always holds a reference to its children */
1028     if (atomic_fetch_dec(&obj->ref) == 1) {
1029         object_finalize(obj);
1030     }
1031 }
1032 
1033 ObjectProperty *
1034 object_property_add(Object *obj, const char *name, const char *type,
1035                     ObjectPropertyAccessor *get,
1036                     ObjectPropertyAccessor *set,
1037                     ObjectPropertyRelease *release,
1038                     void *opaque, Error **errp)
1039 {
1040     ObjectProperty *prop;
1041     size_t name_len = strlen(name);
1042 
1043     if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) {
1044         int i;
1045         ObjectProperty *ret;
1046         char *name_no_array = g_strdup(name);
1047 
1048         name_no_array[name_len - 3] = '\0';
1049         for (i = 0; ; ++i) {
1050             char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
1051 
1052             ret = object_property_add(obj, full_name, type, get, set,
1053                                       release, opaque, NULL);
1054             g_free(full_name);
1055             if (ret) {
1056                 break;
1057             }
1058         }
1059         g_free(name_no_array);
1060         return ret;
1061     }
1062 
1063     if (object_property_find(obj, name, NULL) != NULL) {
1064         error_setg(errp, "attempt to add duplicate property '%s'"
1065                    " to object (type '%s')", name,
1066                    object_get_typename(obj));
1067         return NULL;
1068     }
1069 
1070     prop = g_malloc0(sizeof(*prop));
1071 
1072     prop->name = g_strdup(name);
1073     prop->type = g_strdup(type);
1074 
1075     prop->get = get;
1076     prop->set = set;
1077     prop->release = release;
1078     prop->opaque = opaque;
1079 
1080     g_hash_table_insert(obj->properties, prop->name, prop);
1081     return prop;
1082 }
1083 
1084 ObjectProperty *
1085 object_class_property_add(ObjectClass *klass,
1086                           const char *name,
1087                           const char *type,
1088                           ObjectPropertyAccessor *get,
1089                           ObjectPropertyAccessor *set,
1090                           ObjectPropertyRelease *release,
1091                           void *opaque,
1092                           Error **errp)
1093 {
1094     ObjectProperty *prop;
1095 
1096     if (object_class_property_find(klass, name, NULL) != NULL) {
1097         error_setg(errp, "attempt to add duplicate property '%s'"
1098                    " to object (type '%s')", name,
1099                    object_class_get_name(klass));
1100         return NULL;
1101     }
1102 
1103     prop = g_malloc0(sizeof(*prop));
1104 
1105     prop->name = g_strdup(name);
1106     prop->type = g_strdup(type);
1107 
1108     prop->get = get;
1109     prop->set = set;
1110     prop->release = release;
1111     prop->opaque = opaque;
1112 
1113     g_hash_table_insert(klass->properties, g_strdup(name), prop);
1114 
1115     return prop;
1116 }
1117 
1118 ObjectProperty *object_property_find(Object *obj, const char *name,
1119                                      Error **errp)
1120 {
1121     ObjectProperty *prop;
1122     ObjectClass *klass = object_get_class(obj);
1123 
1124     prop = object_class_property_find(klass, name, NULL);
1125     if (prop) {
1126         return prop;
1127     }
1128 
1129     prop = g_hash_table_lookup(obj->properties, name);
1130     if (prop) {
1131         return prop;
1132     }
1133 
1134     error_setg(errp, "Property '.%s' not found", name);
1135     return NULL;
1136 }
1137 
1138 void object_property_iter_init(ObjectPropertyIterator *iter,
1139                                Object *obj)
1140 {
1141     g_hash_table_iter_init(&iter->iter, obj->properties);
1142     iter->nextclass = object_get_class(obj);
1143 }
1144 
1145 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
1146 {
1147     gpointer key, val;
1148     while (!g_hash_table_iter_next(&iter->iter, &key, &val)) {
1149         if (!iter->nextclass) {
1150             return NULL;
1151         }
1152         g_hash_table_iter_init(&iter->iter, iter->nextclass->properties);
1153         iter->nextclass = object_class_get_parent(iter->nextclass);
1154     }
1155     return val;
1156 }
1157 
1158 void object_class_property_iter_init(ObjectPropertyIterator *iter,
1159                                      ObjectClass *klass)
1160 {
1161     g_hash_table_iter_init(&iter->iter, klass->properties);
1162     iter->nextclass = object_class_get_parent(klass);
1163 }
1164 
1165 ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name,
1166                                            Error **errp)
1167 {
1168     ObjectProperty *prop;
1169     ObjectClass *parent_klass;
1170 
1171     parent_klass = object_class_get_parent(klass);
1172     if (parent_klass) {
1173         prop = object_class_property_find(parent_klass, name, NULL);
1174         if (prop) {
1175             return prop;
1176         }
1177     }
1178 
1179     prop = g_hash_table_lookup(klass->properties, name);
1180     if (!prop) {
1181         error_setg(errp, "Property '.%s' not found", name);
1182     }
1183     return prop;
1184 }
1185 
1186 void object_property_del(Object *obj, const char *name, Error **errp)
1187 {
1188     ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
1189 
1190     if (!prop) {
1191         error_setg(errp, "Property '.%s' not found", name);
1192         return;
1193     }
1194 
1195     if (prop->release) {
1196         prop->release(obj, name, prop->opaque);
1197     }
1198     g_hash_table_remove(obj->properties, name);
1199 }
1200 
1201 void object_property_get(Object *obj, Visitor *v, const char *name,
1202                          Error **errp)
1203 {
1204     ObjectProperty *prop = object_property_find(obj, name, errp);
1205     if (prop == NULL) {
1206         return;
1207     }
1208 
1209     if (!prop->get) {
1210         error_setg(errp, QERR_PERMISSION_DENIED);
1211     } else {
1212         prop->get(obj, v, name, prop->opaque, errp);
1213     }
1214 }
1215 
1216 void object_property_set(Object *obj, Visitor *v, const char *name,
1217                          Error **errp)
1218 {
1219     ObjectProperty *prop = object_property_find(obj, name, errp);
1220     if (prop == NULL) {
1221         return;
1222     }
1223 
1224     if (!prop->set) {
1225         error_setg(errp, QERR_PERMISSION_DENIED);
1226     } else {
1227         prop->set(obj, v, name, prop->opaque, errp);
1228     }
1229 }
1230 
1231 void object_property_set_str(Object *obj, const char *value,
1232                              const char *name, Error **errp)
1233 {
1234     QString *qstr = qstring_from_str(value);
1235     object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
1236 
1237     qobject_unref(qstr);
1238 }
1239 
1240 char *object_property_get_str(Object *obj, const char *name,
1241                               Error **errp)
1242 {
1243     QObject *ret = object_property_get_qobject(obj, name, errp);
1244     char *retval;
1245 
1246     if (!ret) {
1247         return NULL;
1248     }
1249 
1250     retval = g_strdup(qobject_get_try_str(ret));
1251     if (!retval) {
1252         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
1253     }
1254 
1255     qobject_unref(ret);
1256     return retval;
1257 }
1258 
1259 void object_property_set_link(Object *obj, Object *value,
1260                               const char *name, Error **errp)
1261 {
1262     if (value) {
1263         gchar *path = object_get_canonical_path(value);
1264         object_property_set_str(obj, path, name, errp);
1265         g_free(path);
1266     } else {
1267         object_property_set_str(obj, "", name, errp);
1268     }
1269 }
1270 
1271 Object *object_property_get_link(Object *obj, const char *name,
1272                                  Error **errp)
1273 {
1274     char *str = object_property_get_str(obj, name, errp);
1275     Object *target = NULL;
1276 
1277     if (str && *str) {
1278         target = object_resolve_path(str, NULL);
1279         if (!target) {
1280             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1281                       "Device '%s' not found", str);
1282         }
1283     }
1284 
1285     g_free(str);
1286     return target;
1287 }
1288 
1289 void object_property_set_bool(Object *obj, bool value,
1290                               const char *name, Error **errp)
1291 {
1292     QBool *qbool = qbool_from_bool(value);
1293     object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
1294 
1295     qobject_unref(qbool);
1296 }
1297 
1298 bool object_property_get_bool(Object *obj, const char *name,
1299                               Error **errp)
1300 {
1301     QObject *ret = object_property_get_qobject(obj, name, errp);
1302     QBool *qbool;
1303     bool retval;
1304 
1305     if (!ret) {
1306         return false;
1307     }
1308     qbool = qobject_to(QBool, ret);
1309     if (!qbool) {
1310         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
1311         retval = false;
1312     } else {
1313         retval = qbool_get_bool(qbool);
1314     }
1315 
1316     qobject_unref(ret);
1317     return retval;
1318 }
1319 
1320 void object_property_set_int(Object *obj, int64_t value,
1321                              const char *name, Error **errp)
1322 {
1323     QNum *qnum = qnum_from_int(value);
1324     object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
1325 
1326     qobject_unref(qnum);
1327 }
1328 
1329 int64_t object_property_get_int(Object *obj, const char *name,
1330                                 Error **errp)
1331 {
1332     QObject *ret = object_property_get_qobject(obj, name, errp);
1333     QNum *qnum;
1334     int64_t retval;
1335 
1336     if (!ret) {
1337         return -1;
1338     }
1339 
1340     qnum = qobject_to(QNum, ret);
1341     if (!qnum || !qnum_get_try_int(qnum, &retval)) {
1342         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
1343         retval = -1;
1344     }
1345 
1346     qobject_unref(ret);
1347     return retval;
1348 }
1349 
1350 void object_property_set_uint(Object *obj, uint64_t value,
1351                               const char *name, Error **errp)
1352 {
1353     QNum *qnum = qnum_from_uint(value);
1354 
1355     object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
1356     qobject_unref(qnum);
1357 }
1358 
1359 uint64_t object_property_get_uint(Object *obj, const char *name,
1360                                   Error **errp)
1361 {
1362     QObject *ret = object_property_get_qobject(obj, name, errp);
1363     QNum *qnum;
1364     uint64_t retval;
1365 
1366     if (!ret) {
1367         return 0;
1368     }
1369     qnum = qobject_to(QNum, ret);
1370     if (!qnum || !qnum_get_try_uint(qnum, &retval)) {
1371         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint");
1372         retval = 0;
1373     }
1374 
1375     qobject_unref(ret);
1376     return retval;
1377 }
1378 
1379 typedef struct EnumProperty {
1380     const QEnumLookup *lookup;
1381     int (*get)(Object *, Error **);
1382     void (*set)(Object *, int, Error **);
1383 } EnumProperty;
1384 
1385 int object_property_get_enum(Object *obj, const char *name,
1386                              const char *typename, Error **errp)
1387 {
1388     Error *err = NULL;
1389     Visitor *v;
1390     char *str;
1391     int ret;
1392     ObjectProperty *prop = object_property_find(obj, name, errp);
1393     EnumProperty *enumprop;
1394 
1395     if (prop == NULL) {
1396         return 0;
1397     }
1398 
1399     if (!g_str_equal(prop->type, typename)) {
1400         error_setg(errp, "Property %s on %s is not '%s' enum type",
1401                    name, object_class_get_name(
1402                        object_get_class(obj)), typename);
1403         return 0;
1404     }
1405 
1406     enumprop = prop->opaque;
1407 
1408     v = string_output_visitor_new(false, &str);
1409     object_property_get(obj, v, name, &err);
1410     if (err) {
1411         error_propagate(errp, err);
1412         visit_free(v);
1413         return 0;
1414     }
1415     visit_complete(v, &str);
1416     visit_free(v);
1417     v = string_input_visitor_new(str);
1418     visit_type_enum(v, name, &ret, enumprop->lookup, errp);
1419 
1420     g_free(str);
1421     visit_free(v);
1422 
1423     return ret;
1424 }
1425 
1426 void object_property_get_uint16List(Object *obj, const char *name,
1427                                     uint16List **list, Error **errp)
1428 {
1429     Error *err = NULL;
1430     Visitor *v;
1431     char *str;
1432 
1433     v = string_output_visitor_new(false, &str);
1434     object_property_get(obj, v, name, &err);
1435     if (err) {
1436         error_propagate(errp, err);
1437         goto out;
1438     }
1439     visit_complete(v, &str);
1440     visit_free(v);
1441     v = string_input_visitor_new(str);
1442     visit_type_uint16List(v, NULL, list, errp);
1443 
1444     g_free(str);
1445 out:
1446     visit_free(v);
1447 }
1448 
1449 void object_property_parse(Object *obj, const char *string,
1450                            const char *name, Error **errp)
1451 {
1452     Visitor *v = string_input_visitor_new(string);
1453     object_property_set(obj, v, name, errp);
1454     visit_free(v);
1455 }
1456 
1457 char *object_property_print(Object *obj, const char *name, bool human,
1458                             Error **errp)
1459 {
1460     Visitor *v;
1461     char *string = NULL;
1462     Error *local_err = NULL;
1463 
1464     v = string_output_visitor_new(human, &string);
1465     object_property_get(obj, v, name, &local_err);
1466     if (local_err) {
1467         error_propagate(errp, local_err);
1468         goto out;
1469     }
1470 
1471     visit_complete(v, &string);
1472 
1473 out:
1474     visit_free(v);
1475     return string;
1476 }
1477 
1478 const char *object_property_get_type(Object *obj, const char *name, Error **errp)
1479 {
1480     ObjectProperty *prop = object_property_find(obj, name, errp);
1481     if (prop == NULL) {
1482         return NULL;
1483     }
1484 
1485     return prop->type;
1486 }
1487 
1488 Object *object_get_root(void)
1489 {
1490     static Object *root;
1491 
1492     if (!root) {
1493         root = object_new("container");
1494     }
1495 
1496     return root;
1497 }
1498 
1499 Object *object_get_objects_root(void)
1500 {
1501     return container_get(object_get_root(), "/objects");
1502 }
1503 
1504 Object *object_get_internal_root(void)
1505 {
1506     static Object *internal_root;
1507 
1508     if (!internal_root) {
1509         internal_root = object_new("container");
1510     }
1511 
1512     return internal_root;
1513 }
1514 
1515 static void object_get_child_property(Object *obj, Visitor *v,
1516                                       const char *name, void *opaque,
1517                                       Error **errp)
1518 {
1519     Object *child = opaque;
1520     gchar *path;
1521 
1522     path = object_get_canonical_path(child);
1523     visit_type_str(v, name, &path, errp);
1524     g_free(path);
1525 }
1526 
1527 static Object *object_resolve_child_property(Object *parent, void *opaque, const gchar *part)
1528 {
1529     return opaque;
1530 }
1531 
1532 static void object_finalize_child_property(Object *obj, const char *name,
1533                                            void *opaque)
1534 {
1535     Object *child = opaque;
1536 
1537     if (child->class->unparent) {
1538         (child->class->unparent)(child);
1539     }
1540     child->parent = NULL;
1541     object_unref(child);
1542 }
1543 
1544 void object_property_add_child(Object *obj, const char *name,
1545                                Object *child, Error **errp)
1546 {
1547     Error *local_err = NULL;
1548     gchar *type;
1549     ObjectProperty *op;
1550 
1551     if (child->parent != NULL) {
1552         error_setg(errp, "child object is already parented");
1553         return;
1554     }
1555 
1556     type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
1557 
1558     op = object_property_add(obj, name, type, object_get_child_property, NULL,
1559                              object_finalize_child_property, child, &local_err);
1560     if (local_err) {
1561         error_propagate(errp, local_err);
1562         goto out;
1563     }
1564 
1565     op->resolve = object_resolve_child_property;
1566     object_ref(child);
1567     child->parent = obj;
1568 
1569 out:
1570     g_free(type);
1571 }
1572 
1573 void object_property_allow_set_link(const Object *obj, const char *name,
1574                                     Object *val, Error **errp)
1575 {
1576     /* Allow the link to be set, always */
1577 }
1578 
1579 typedef struct {
1580     Object **child;
1581     void (*check)(const Object *, const char *, Object *, Error **);
1582     ObjectPropertyLinkFlags flags;
1583 } LinkProperty;
1584 
1585 static void object_get_link_property(Object *obj, Visitor *v,
1586                                      const char *name, void *opaque,
1587                                      Error **errp)
1588 {
1589     LinkProperty *lprop = opaque;
1590     Object **child = lprop->child;
1591     gchar *path;
1592 
1593     if (*child) {
1594         path = object_get_canonical_path(*child);
1595         visit_type_str(v, name, &path, errp);
1596         g_free(path);
1597     } else {
1598         path = (gchar *)"";
1599         visit_type_str(v, name, &path, errp);
1600     }
1601 }
1602 
1603 /*
1604  * object_resolve_link:
1605  *
1606  * Lookup an object and ensure its type matches the link property type.  This
1607  * is similar to object_resolve_path() except type verification against the
1608  * link property is performed.
1609  *
1610  * Returns: The matched object or NULL on path lookup failures.
1611  */
1612 static Object *object_resolve_link(Object *obj, const char *name,
1613                                    const char *path, Error **errp)
1614 {
1615     const char *type;
1616     gchar *target_type;
1617     bool ambiguous = false;
1618     Object *target;
1619 
1620     /* Go from link<FOO> to FOO.  */
1621     type = object_property_get_type(obj, name, NULL);
1622     target_type = g_strndup(&type[5], strlen(type) - 6);
1623     target = object_resolve_path_type(path, target_type, &ambiguous);
1624 
1625     if (ambiguous) {
1626         error_setg(errp, "Path '%s' does not uniquely identify an object",
1627                    path);
1628     } else if (!target) {
1629         target = object_resolve_path(path, &ambiguous);
1630         if (target || ambiguous) {
1631             error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
1632         } else {
1633             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1634                       "Device '%s' not found", path);
1635         }
1636         target = NULL;
1637     }
1638     g_free(target_type);
1639 
1640     return target;
1641 }
1642 
1643 static void object_set_link_property(Object *obj, Visitor *v,
1644                                      const char *name, void *opaque,
1645                                      Error **errp)
1646 {
1647     Error *local_err = NULL;
1648     LinkProperty *prop = opaque;
1649     Object **child = prop->child;
1650     Object *old_target = *child;
1651     Object *new_target = NULL;
1652     char *path = NULL;
1653 
1654     visit_type_str(v, name, &path, &local_err);
1655 
1656     if (!local_err && strcmp(path, "") != 0) {
1657         new_target = object_resolve_link(obj, name, path, &local_err);
1658     }
1659 
1660     g_free(path);
1661     if (local_err) {
1662         error_propagate(errp, local_err);
1663         return;
1664     }
1665 
1666     prop->check(obj, name, new_target, &local_err);
1667     if (local_err) {
1668         error_propagate(errp, local_err);
1669         return;
1670     }
1671 
1672     *child = new_target;
1673     if (prop->flags == OBJ_PROP_LINK_STRONG) {
1674         object_ref(new_target);
1675         object_unref(old_target);
1676     }
1677 }
1678 
1679 static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part)
1680 {
1681     LinkProperty *lprop = opaque;
1682 
1683     return *lprop->child;
1684 }
1685 
1686 static void object_release_link_property(Object *obj, const char *name,
1687                                          void *opaque)
1688 {
1689     LinkProperty *prop = opaque;
1690 
1691     if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->child) {
1692         object_unref(*prop->child);
1693     }
1694     g_free(prop);
1695 }
1696 
1697 void object_property_add_link(Object *obj, const char *name,
1698                               const char *type, Object **child,
1699                               void (*check)(const Object *, const char *,
1700                                             Object *, Error **),
1701                               ObjectPropertyLinkFlags flags,
1702                               Error **errp)
1703 {
1704     Error *local_err = NULL;
1705     LinkProperty *prop = g_malloc(sizeof(*prop));
1706     gchar *full_type;
1707     ObjectProperty *op;
1708 
1709     prop->child = child;
1710     prop->check = check;
1711     prop->flags = flags;
1712 
1713     full_type = g_strdup_printf("link<%s>", type);
1714 
1715     op = object_property_add(obj, name, full_type,
1716                              object_get_link_property,
1717                              check ? object_set_link_property : NULL,
1718                              object_release_link_property,
1719                              prop,
1720                              &local_err);
1721     if (local_err) {
1722         error_propagate(errp, local_err);
1723         g_free(prop);
1724         goto out;
1725     }
1726 
1727     op->resolve = object_resolve_link_property;
1728 
1729 out:
1730     g_free(full_type);
1731 }
1732 
1733 void object_property_add_const_link(Object *obj, const char *name,
1734                                     Object *target, Error **errp)
1735 {
1736     char *link_type;
1737     ObjectProperty *op;
1738 
1739     link_type = g_strdup_printf("link<%s>", object_get_typename(target));
1740     op = object_property_add(obj, name, link_type,
1741                              object_get_child_property, NULL,
1742                              NULL, target, errp);
1743     if (op != NULL) {
1744         op->resolve = object_resolve_child_property;
1745     }
1746     g_free(link_type);
1747 }
1748 
1749 gchar *object_get_canonical_path_component(Object *obj)
1750 {
1751     ObjectProperty *prop = NULL;
1752     GHashTableIter iter;
1753 
1754     if (obj->parent == NULL) {
1755         return NULL;
1756     }
1757 
1758     g_hash_table_iter_init(&iter, obj->parent->properties);
1759     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
1760         if (!object_property_is_child(prop)) {
1761             continue;
1762         }
1763 
1764         if (prop->opaque == obj) {
1765             return g_strdup(prop->name);
1766         }
1767     }
1768 
1769     /* obj had a parent but was not a child, should never happen */
1770     g_assert_not_reached();
1771     return NULL;
1772 }
1773 
1774 gchar *object_get_canonical_path(Object *obj)
1775 {
1776     Object *root = object_get_root();
1777     char *newpath, *path = NULL;
1778 
1779     if (obj == root) {
1780         return g_strdup("/");
1781     }
1782 
1783     do {
1784         char *component = object_get_canonical_path_component(obj);
1785 
1786         if (!component) {
1787             /* A canonical path must be complete, so discard what was
1788              * collected so far.
1789              */
1790             g_free(path);
1791             return NULL;
1792         }
1793 
1794         newpath = g_strdup_printf("/%s%s", component, path ? path : "");
1795         g_free(path);
1796         g_free(component);
1797         path = newpath;
1798         obj = obj->parent;
1799     } while (obj != root);
1800 
1801     return path;
1802 }
1803 
1804 Object *object_resolve_path_component(Object *parent, const gchar *part)
1805 {
1806     ObjectProperty *prop = object_property_find(parent, part, NULL);
1807     if (prop == NULL) {
1808         return NULL;
1809     }
1810 
1811     if (prop->resolve) {
1812         return prop->resolve(parent, prop->opaque, part);
1813     } else {
1814         return NULL;
1815     }
1816 }
1817 
1818 static Object *object_resolve_abs_path(Object *parent,
1819                                           gchar **parts,
1820                                           const char *typename,
1821                                           int index)
1822 {
1823     Object *child;
1824 
1825     if (parts[index] == NULL) {
1826         return object_dynamic_cast(parent, typename);
1827     }
1828 
1829     if (strcmp(parts[index], "") == 0) {
1830         return object_resolve_abs_path(parent, parts, typename, index + 1);
1831     }
1832 
1833     child = object_resolve_path_component(parent, parts[index]);
1834     if (!child) {
1835         return NULL;
1836     }
1837 
1838     return object_resolve_abs_path(child, parts, typename, index + 1);
1839 }
1840 
1841 static Object *object_resolve_partial_path(Object *parent,
1842                                               gchar **parts,
1843                                               const char *typename,
1844                                               bool *ambiguous)
1845 {
1846     Object *obj;
1847     GHashTableIter iter;
1848     ObjectProperty *prop;
1849 
1850     obj = object_resolve_abs_path(parent, parts, typename, 0);
1851 
1852     g_hash_table_iter_init(&iter, parent->properties);
1853     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
1854         Object *found;
1855 
1856         if (!object_property_is_child(prop)) {
1857             continue;
1858         }
1859 
1860         found = object_resolve_partial_path(prop->opaque, parts,
1861                                             typename, ambiguous);
1862         if (found) {
1863             if (obj) {
1864                 *ambiguous = true;
1865                 return NULL;
1866             }
1867             obj = found;
1868         }
1869 
1870         if (*ambiguous) {
1871             return NULL;
1872         }
1873     }
1874 
1875     return obj;
1876 }
1877 
1878 Object *object_resolve_path_type(const char *path, const char *typename,
1879                                  bool *ambiguousp)
1880 {
1881     Object *obj;
1882     gchar **parts;
1883 
1884     parts = g_strsplit(path, "/", 0);
1885     assert(parts);
1886 
1887     if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
1888         bool ambiguous = false;
1889         obj = object_resolve_partial_path(object_get_root(), parts,
1890                                           typename, &ambiguous);
1891         if (ambiguousp) {
1892             *ambiguousp = ambiguous;
1893         }
1894     } else {
1895         obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
1896     }
1897 
1898     g_strfreev(parts);
1899 
1900     return obj;
1901 }
1902 
1903 Object *object_resolve_path(const char *path, bool *ambiguous)
1904 {
1905     return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
1906 }
1907 
1908 typedef struct StringProperty
1909 {
1910     char *(*get)(Object *, Error **);
1911     void (*set)(Object *, const char *, Error **);
1912 } StringProperty;
1913 
1914 static void property_get_str(Object *obj, Visitor *v, const char *name,
1915                              void *opaque, Error **errp)
1916 {
1917     StringProperty *prop = opaque;
1918     char *value;
1919     Error *err = NULL;
1920 
1921     value = prop->get(obj, &err);
1922     if (err) {
1923         error_propagate(errp, err);
1924         return;
1925     }
1926 
1927     visit_type_str(v, name, &value, errp);
1928     g_free(value);
1929 }
1930 
1931 static void property_set_str(Object *obj, Visitor *v, const char *name,
1932                              void *opaque, Error **errp)
1933 {
1934     StringProperty *prop = opaque;
1935     char *value;
1936     Error *local_err = NULL;
1937 
1938     visit_type_str(v, name, &value, &local_err);
1939     if (local_err) {
1940         error_propagate(errp, local_err);
1941         return;
1942     }
1943 
1944     prop->set(obj, value, errp);
1945     g_free(value);
1946 }
1947 
1948 static void property_release_str(Object *obj, const char *name,
1949                                  void *opaque)
1950 {
1951     StringProperty *prop = opaque;
1952     g_free(prop);
1953 }
1954 
1955 void object_property_add_str(Object *obj, const char *name,
1956                            char *(*get)(Object *, Error **),
1957                            void (*set)(Object *, const char *, Error **),
1958                            Error **errp)
1959 {
1960     Error *local_err = NULL;
1961     StringProperty *prop = g_malloc0(sizeof(*prop));
1962 
1963     prop->get = get;
1964     prop->set = set;
1965 
1966     object_property_add(obj, name, "string",
1967                         get ? property_get_str : NULL,
1968                         set ? property_set_str : NULL,
1969                         property_release_str,
1970                         prop, &local_err);
1971     if (local_err) {
1972         error_propagate(errp, local_err);
1973         g_free(prop);
1974     }
1975 }
1976 
1977 void object_class_property_add_str(ObjectClass *klass, const char *name,
1978                                    char *(*get)(Object *, Error **),
1979                                    void (*set)(Object *, const char *,
1980                                                Error **),
1981                                    Error **errp)
1982 {
1983     Error *local_err = NULL;
1984     StringProperty *prop = g_malloc0(sizeof(*prop));
1985 
1986     prop->get = get;
1987     prop->set = set;
1988 
1989     object_class_property_add(klass, name, "string",
1990                               get ? property_get_str : NULL,
1991                               set ? property_set_str : NULL,
1992                               property_release_str,
1993                               prop, &local_err);
1994     if (local_err) {
1995         error_propagate(errp, local_err);
1996         g_free(prop);
1997     }
1998 }
1999 
2000 typedef struct BoolProperty
2001 {
2002     bool (*get)(Object *, Error **);
2003     void (*set)(Object *, bool, Error **);
2004 } BoolProperty;
2005 
2006 static void property_get_bool(Object *obj, Visitor *v, const char *name,
2007                               void *opaque, Error **errp)
2008 {
2009     BoolProperty *prop = opaque;
2010     bool value;
2011     Error *err = NULL;
2012 
2013     value = prop->get(obj, &err);
2014     if (err) {
2015         error_propagate(errp, err);
2016         return;
2017     }
2018 
2019     visit_type_bool(v, name, &value, errp);
2020 }
2021 
2022 static void property_set_bool(Object *obj, Visitor *v, const char *name,
2023                               void *opaque, Error **errp)
2024 {
2025     BoolProperty *prop = opaque;
2026     bool value;
2027     Error *local_err = NULL;
2028 
2029     visit_type_bool(v, name, &value, &local_err);
2030     if (local_err) {
2031         error_propagate(errp, local_err);
2032         return;
2033     }
2034 
2035     prop->set(obj, value, errp);
2036 }
2037 
2038 static void property_release_bool(Object *obj, const char *name,
2039                                   void *opaque)
2040 {
2041     BoolProperty *prop = opaque;
2042     g_free(prop);
2043 }
2044 
2045 void object_property_add_bool(Object *obj, const char *name,
2046                               bool (*get)(Object *, Error **),
2047                               void (*set)(Object *, bool, Error **),
2048                               Error **errp)
2049 {
2050     Error *local_err = NULL;
2051     BoolProperty *prop = g_malloc0(sizeof(*prop));
2052 
2053     prop->get = get;
2054     prop->set = set;
2055 
2056     object_property_add(obj, name, "bool",
2057                         get ? property_get_bool : NULL,
2058                         set ? property_set_bool : NULL,
2059                         property_release_bool,
2060                         prop, &local_err);
2061     if (local_err) {
2062         error_propagate(errp, local_err);
2063         g_free(prop);
2064     }
2065 }
2066 
2067 void object_class_property_add_bool(ObjectClass *klass, const char *name,
2068                                     bool (*get)(Object *, Error **),
2069                                     void (*set)(Object *, bool, Error **),
2070                                     Error **errp)
2071 {
2072     Error *local_err = NULL;
2073     BoolProperty *prop = g_malloc0(sizeof(*prop));
2074 
2075     prop->get = get;
2076     prop->set = set;
2077 
2078     object_class_property_add(klass, name, "bool",
2079                               get ? property_get_bool : NULL,
2080                               set ? property_set_bool : NULL,
2081                               property_release_bool,
2082                               prop, &local_err);
2083     if (local_err) {
2084         error_propagate(errp, local_err);
2085         g_free(prop);
2086     }
2087 }
2088 
2089 static void property_get_enum(Object *obj, Visitor *v, const char *name,
2090                               void *opaque, Error **errp)
2091 {
2092     EnumProperty *prop = opaque;
2093     int value;
2094     Error *err = NULL;
2095 
2096     value = prop->get(obj, &err);
2097     if (err) {
2098         error_propagate(errp, err);
2099         return;
2100     }
2101 
2102     visit_type_enum(v, name, &value, prop->lookup, errp);
2103 }
2104 
2105 static void property_set_enum(Object *obj, Visitor *v, const char *name,
2106                               void *opaque, Error **errp)
2107 {
2108     EnumProperty *prop = opaque;
2109     int value;
2110     Error *err = NULL;
2111 
2112     visit_type_enum(v, name, &value, prop->lookup, &err);
2113     if (err) {
2114         error_propagate(errp, err);
2115         return;
2116     }
2117     prop->set(obj, value, errp);
2118 }
2119 
2120 static void property_release_enum(Object *obj, const char *name,
2121                                   void *opaque)
2122 {
2123     EnumProperty *prop = opaque;
2124     g_free(prop);
2125 }
2126 
2127 void object_property_add_enum(Object *obj, const char *name,
2128                               const char *typename,
2129                               const QEnumLookup *lookup,
2130                               int (*get)(Object *, Error **),
2131                               void (*set)(Object *, int, Error **),
2132                               Error **errp)
2133 {
2134     Error *local_err = NULL;
2135     EnumProperty *prop = g_malloc(sizeof(*prop));
2136 
2137     prop->lookup = lookup;
2138     prop->get = get;
2139     prop->set = set;
2140 
2141     object_property_add(obj, name, typename,
2142                         get ? property_get_enum : NULL,
2143                         set ? property_set_enum : NULL,
2144                         property_release_enum,
2145                         prop, &local_err);
2146     if (local_err) {
2147         error_propagate(errp, local_err);
2148         g_free(prop);
2149     }
2150 }
2151 
2152 void object_class_property_add_enum(ObjectClass *klass, const char *name,
2153                                     const char *typename,
2154                                     const QEnumLookup *lookup,
2155                                     int (*get)(Object *, Error **),
2156                                     void (*set)(Object *, int, Error **),
2157                                     Error **errp)
2158 {
2159     Error *local_err = NULL;
2160     EnumProperty *prop = g_malloc(sizeof(*prop));
2161 
2162     prop->lookup = lookup;
2163     prop->get = get;
2164     prop->set = set;
2165 
2166     object_class_property_add(klass, name, typename,
2167                               get ? property_get_enum : NULL,
2168                               set ? property_set_enum : NULL,
2169                               property_release_enum,
2170                               prop, &local_err);
2171     if (local_err) {
2172         error_propagate(errp, local_err);
2173         g_free(prop);
2174     }
2175 }
2176 
2177 typedef struct TMProperty {
2178     void (*get)(Object *, struct tm *, Error **);
2179 } TMProperty;
2180 
2181 static void property_get_tm(Object *obj, Visitor *v, const char *name,
2182                             void *opaque, Error **errp)
2183 {
2184     TMProperty *prop = opaque;
2185     Error *err = NULL;
2186     struct tm value;
2187 
2188     prop->get(obj, &value, &err);
2189     if (err) {
2190         goto out;
2191     }
2192 
2193     visit_start_struct(v, name, NULL, 0, &err);
2194     if (err) {
2195         goto out;
2196     }
2197     visit_type_int32(v, "tm_year", &value.tm_year, &err);
2198     if (err) {
2199         goto out_end;
2200     }
2201     visit_type_int32(v, "tm_mon", &value.tm_mon, &err);
2202     if (err) {
2203         goto out_end;
2204     }
2205     visit_type_int32(v, "tm_mday", &value.tm_mday, &err);
2206     if (err) {
2207         goto out_end;
2208     }
2209     visit_type_int32(v, "tm_hour", &value.tm_hour, &err);
2210     if (err) {
2211         goto out_end;
2212     }
2213     visit_type_int32(v, "tm_min", &value.tm_min, &err);
2214     if (err) {
2215         goto out_end;
2216     }
2217     visit_type_int32(v, "tm_sec", &value.tm_sec, &err);
2218     if (err) {
2219         goto out_end;
2220     }
2221     visit_check_struct(v, &err);
2222 out_end:
2223     visit_end_struct(v, NULL);
2224 out:
2225     error_propagate(errp, err);
2226 
2227 }
2228 
2229 static void property_release_tm(Object *obj, const char *name,
2230                                 void *opaque)
2231 {
2232     TMProperty *prop = opaque;
2233     g_free(prop);
2234 }
2235 
2236 void object_property_add_tm(Object *obj, const char *name,
2237                             void (*get)(Object *, struct tm *, Error **),
2238                             Error **errp)
2239 {
2240     Error *local_err = NULL;
2241     TMProperty *prop = g_malloc0(sizeof(*prop));
2242 
2243     prop->get = get;
2244 
2245     object_property_add(obj, name, "struct tm",
2246                         get ? property_get_tm : NULL, NULL,
2247                         property_release_tm,
2248                         prop, &local_err);
2249     if (local_err) {
2250         error_propagate(errp, local_err);
2251         g_free(prop);
2252     }
2253 }
2254 
2255 void object_class_property_add_tm(ObjectClass *klass, const char *name,
2256                                   void (*get)(Object *, struct tm *, Error **),
2257                                   Error **errp)
2258 {
2259     Error *local_err = NULL;
2260     TMProperty *prop = g_malloc0(sizeof(*prop));
2261 
2262     prop->get = get;
2263 
2264     object_class_property_add(klass, name, "struct tm",
2265                               get ? property_get_tm : NULL, NULL,
2266                               property_release_tm,
2267                               prop, &local_err);
2268     if (local_err) {
2269         error_propagate(errp, local_err);
2270         g_free(prop);
2271     }
2272 }
2273 
2274 static char *qdev_get_type(Object *obj, Error **errp)
2275 {
2276     return g_strdup(object_get_typename(obj));
2277 }
2278 
2279 static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name,
2280                                    void *opaque, Error **errp)
2281 {
2282     uint8_t value = *(uint8_t *)opaque;
2283     visit_type_uint8(v, name, &value, errp);
2284 }
2285 
2286 static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name,
2287                                     void *opaque, Error **errp)
2288 {
2289     uint16_t value = *(uint16_t *)opaque;
2290     visit_type_uint16(v, name, &value, errp);
2291 }
2292 
2293 static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name,
2294                                     void *opaque, Error **errp)
2295 {
2296     uint32_t value = *(uint32_t *)opaque;
2297     visit_type_uint32(v, name, &value, errp);
2298 }
2299 
2300 static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name,
2301                                     void *opaque, Error **errp)
2302 {
2303     uint64_t value = *(uint64_t *)opaque;
2304     visit_type_uint64(v, name, &value, errp);
2305 }
2306 
2307 void object_property_add_uint8_ptr(Object *obj, const char *name,
2308                                    const uint8_t *v, Error **errp)
2309 {
2310     object_property_add(obj, name, "uint8", property_get_uint8_ptr,
2311                         NULL, NULL, (void *)v, errp);
2312 }
2313 
2314 void object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
2315                                          const uint8_t *v, Error **errp)
2316 {
2317     object_class_property_add(klass, name, "uint8", property_get_uint8_ptr,
2318                               NULL, NULL, (void *)v, errp);
2319 }
2320 
2321 void object_property_add_uint16_ptr(Object *obj, const char *name,
2322                                     const uint16_t *v, Error **errp)
2323 {
2324     object_property_add(obj, name, "uint16", property_get_uint16_ptr,
2325                         NULL, NULL, (void *)v, errp);
2326 }
2327 
2328 void object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
2329                                           const uint16_t *v, Error **errp)
2330 {
2331     object_class_property_add(klass, name, "uint16", property_get_uint16_ptr,
2332                               NULL, NULL, (void *)v, errp);
2333 }
2334 
2335 void object_property_add_uint32_ptr(Object *obj, const char *name,
2336                                     const uint32_t *v, Error **errp)
2337 {
2338     object_property_add(obj, name, "uint32", property_get_uint32_ptr,
2339                         NULL, NULL, (void *)v, errp);
2340 }
2341 
2342 void object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
2343                                           const uint32_t *v, Error **errp)
2344 {
2345     object_class_property_add(klass, name, "uint32", property_get_uint32_ptr,
2346                               NULL, NULL, (void *)v, errp);
2347 }
2348 
2349 void object_property_add_uint64_ptr(Object *obj, const char *name,
2350                                     const uint64_t *v, Error **errp)
2351 {
2352     object_property_add(obj, name, "uint64", property_get_uint64_ptr,
2353                         NULL, NULL, (void *)v, errp);
2354 }
2355 
2356 void object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
2357                                           const uint64_t *v, Error **errp)
2358 {
2359     object_class_property_add(klass, name, "uint64", property_get_uint64_ptr,
2360                               NULL, NULL, (void *)v, errp);
2361 }
2362 
2363 typedef struct {
2364     Object *target_obj;
2365     char *target_name;
2366 } AliasProperty;
2367 
2368 static void property_get_alias(Object *obj, Visitor *v, const char *name,
2369                                void *opaque, Error **errp)
2370 {
2371     AliasProperty *prop = opaque;
2372 
2373     object_property_get(prop->target_obj, v, prop->target_name, errp);
2374 }
2375 
2376 static void property_set_alias(Object *obj, Visitor *v, const char *name,
2377                                void *opaque, Error **errp)
2378 {
2379     AliasProperty *prop = opaque;
2380 
2381     object_property_set(prop->target_obj, v, prop->target_name, errp);
2382 }
2383 
2384 static Object *property_resolve_alias(Object *obj, void *opaque,
2385                                       const gchar *part)
2386 {
2387     AliasProperty *prop = opaque;
2388 
2389     return object_resolve_path_component(prop->target_obj, prop->target_name);
2390 }
2391 
2392 static void property_release_alias(Object *obj, const char *name, void *opaque)
2393 {
2394     AliasProperty *prop = opaque;
2395 
2396     g_free(prop->target_name);
2397     g_free(prop);
2398 }
2399 
2400 void object_property_add_alias(Object *obj, const char *name,
2401                                Object *target_obj, const char *target_name,
2402                                Error **errp)
2403 {
2404     AliasProperty *prop;
2405     ObjectProperty *op;
2406     ObjectProperty *target_prop;
2407     gchar *prop_type;
2408     Error *local_err = NULL;
2409 
2410     target_prop = object_property_find(target_obj, target_name, errp);
2411     if (!target_prop) {
2412         return;
2413     }
2414 
2415     if (object_property_is_child(target_prop)) {
2416         prop_type = g_strdup_printf("link%s",
2417                                     target_prop->type + strlen("child"));
2418     } else {
2419         prop_type = g_strdup(target_prop->type);
2420     }
2421 
2422     prop = g_malloc(sizeof(*prop));
2423     prop->target_obj = target_obj;
2424     prop->target_name = g_strdup(target_name);
2425 
2426     op = object_property_add(obj, name, prop_type,
2427                              property_get_alias,
2428                              property_set_alias,
2429                              property_release_alias,
2430                              prop, &local_err);
2431     if (local_err) {
2432         error_propagate(errp, local_err);
2433         g_free(prop);
2434         goto out;
2435     }
2436     op->resolve = property_resolve_alias;
2437 
2438     object_property_set_description(obj, op->name,
2439                                     target_prop->description,
2440                                     &error_abort);
2441 
2442 out:
2443     g_free(prop_type);
2444 }
2445 
2446 void object_property_set_description(Object *obj, const char *name,
2447                                      const char *description, Error **errp)
2448 {
2449     ObjectProperty *op;
2450 
2451     op = object_property_find(obj, name, errp);
2452     if (!op) {
2453         return;
2454     }
2455 
2456     g_free(op->description);
2457     op->description = g_strdup(description);
2458 }
2459 
2460 void object_class_property_set_description(ObjectClass *klass,
2461                                            const char *name,
2462                                            const char *description,
2463                                            Error **errp)
2464 {
2465     ObjectProperty *op;
2466 
2467     op = g_hash_table_lookup(klass->properties, name);
2468     if (!op) {
2469         error_setg(errp, "Property '.%s' not found", name);
2470         return;
2471     }
2472 
2473     g_free(op->description);
2474     op->description = g_strdup(description);
2475 }
2476 
2477 static void object_class_init(ObjectClass *klass, void *data)
2478 {
2479     object_class_property_add_str(klass, "type", qdev_get_type,
2480                                   NULL, &error_abort);
2481 }
2482 
2483 static void register_types(void)
2484 {
2485     static TypeInfo interface_info = {
2486         .name = TYPE_INTERFACE,
2487         .class_size = sizeof(InterfaceClass),
2488         .abstract = true,
2489     };
2490 
2491     static TypeInfo object_info = {
2492         .name = TYPE_OBJECT,
2493         .instance_size = sizeof(Object),
2494         .class_init = object_class_init,
2495         .abstract = true,
2496     };
2497 
2498     type_interface = type_register_internal(&interface_info);
2499     type_register_internal(&object_info);
2500 }
2501 
2502 type_init(register_types)
2503