xref: /qemu/qom/object.c (revision 1d9c5a12)
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/object.h"
14 #include "qemu-common.h"
15 #include "qapi/qapi-visit-core.h"
16 
17 /* TODO: replace QObject with a simpler visitor to avoid a dependency
18  * of the QOM core on QObject?  */
19 #include "qemu/qom-qobject.h"
20 #include "qobject.h"
21 #include "qbool.h"
22 #include "qint.h"
23 #include "qstring.h"
24 
25 #define MAX_INTERFACES 32
26 
27 typedef struct InterfaceImpl InterfaceImpl;
28 typedef struct TypeImpl TypeImpl;
29 
30 struct InterfaceImpl
31 {
32     const char *parent;
33     void (*interface_initfn)(ObjectClass *class, void *data);
34     TypeImpl *type;
35 };
36 
37 struct TypeImpl
38 {
39     const char *name;
40 
41     size_t class_size;
42 
43     size_t instance_size;
44 
45     void (*class_init)(ObjectClass *klass, void *data);
46     void (*class_finalize)(ObjectClass *klass, void *data);
47 
48     void *class_data;
49 
50     void (*instance_init)(Object *obj);
51     void (*instance_finalize)(Object *obj);
52 
53     bool abstract;
54 
55     const char *parent;
56     TypeImpl *parent_type;
57 
58     ObjectClass *class;
59 
60     int num_interfaces;
61     InterfaceImpl interfaces[MAX_INTERFACES];
62 };
63 
64 typedef struct Interface
65 {
66     Object parent;
67     Object *obj;
68 } Interface;
69 
70 #define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE)
71 
72 static Type type_interface;
73 
74 static GHashTable *type_table_get(void)
75 {
76     static GHashTable *type_table;
77 
78     if (type_table == NULL) {
79         type_table = g_hash_table_new(g_str_hash, g_str_equal);
80     }
81 
82     return type_table;
83 }
84 
85 static void type_table_add(TypeImpl *ti)
86 {
87     g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
88 }
89 
90 static TypeImpl *type_table_lookup(const char *name)
91 {
92     return g_hash_table_lookup(type_table_get(), name);
93 }
94 
95 TypeImpl *type_register(const TypeInfo *info)
96 {
97     TypeImpl *ti = g_malloc0(sizeof(*ti));
98 
99     g_assert(info->name != NULL);
100 
101     if (type_table_lookup(info->name) != NULL) {
102         fprintf(stderr, "Registering `%s' which already exists\n", info->name);
103         abort();
104     }
105 
106     ti->name = g_strdup(info->name);
107     ti->parent = g_strdup(info->parent);
108 
109     ti->class_size = info->class_size;
110     ti->instance_size = info->instance_size;
111 
112     ti->class_init = info->class_init;
113     ti->class_finalize = info->class_finalize;
114     ti->class_data = info->class_data;
115 
116     ti->instance_init = info->instance_init;
117     ti->instance_finalize = info->instance_finalize;
118 
119     ti->abstract = info->abstract;
120 
121     if (info->interfaces) {
122         int i;
123 
124         for (i = 0; info->interfaces[i].type; i++) {
125             ti->interfaces[i].parent = info->interfaces[i].type;
126             ti->interfaces[i].interface_initfn = info->interfaces[i].interface_initfn;
127             ti->num_interfaces++;
128         }
129     }
130 
131     type_table_add(ti);
132 
133     return ti;
134 }
135 
136 TypeImpl *type_register_static(const TypeInfo *info)
137 {
138     return type_register(info);
139 }
140 
141 static TypeImpl *type_get_by_name(const char *name)
142 {
143     if (name == NULL) {
144         return NULL;
145     }
146 
147     return type_table_lookup(name);
148 }
149 
150 static TypeImpl *type_get_parent(TypeImpl *type)
151 {
152     if (!type->parent_type && type->parent) {
153         type->parent_type = type_get_by_name(type->parent);
154         g_assert(type->parent_type != NULL);
155     }
156 
157     return type->parent_type;
158 }
159 
160 static bool type_has_parent(TypeImpl *type)
161 {
162     return (type->parent != NULL);
163 }
164 
165 static size_t type_class_get_size(TypeImpl *ti)
166 {
167     if (ti->class_size) {
168         return ti->class_size;
169     }
170 
171     if (type_has_parent(ti)) {
172         return type_class_get_size(type_get_parent(ti));
173     }
174 
175     return sizeof(ObjectClass);
176 }
177 
178 static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface)
179 {
180     TypeInfo info = {
181         .instance_size = sizeof(Interface),
182         .parent = iface->parent,
183         .class_size = sizeof(InterfaceClass),
184         .class_init = iface->interface_initfn,
185         .abstract = true,
186     };
187     char *name = g_strdup_printf("<%s::%s>", ti->name, iface->parent);
188 
189     info.name = name;
190     iface->type = type_register(&info);
191     g_free(name);
192 }
193 
194 static void type_class_init(TypeImpl *ti)
195 {
196     size_t class_size = sizeof(ObjectClass);
197     int i;
198 
199     if (ti->class) {
200         return;
201     }
202 
203     ti->class_size = type_class_get_size(ti);
204 
205     ti->class = g_malloc0(ti->class_size);
206     ti->class->type = ti;
207 
208     if (type_has_parent(ti)) {
209         TypeImpl *parent = type_get_parent(ti);
210 
211         type_class_init(parent);
212 
213         class_size = parent->class_size;
214         g_assert(parent->class_size <= ti->class_size);
215 
216         memcpy((void *)ti->class + sizeof(ObjectClass),
217                (void *)parent->class + sizeof(ObjectClass),
218                parent->class_size - sizeof(ObjectClass));
219     }
220 
221     memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
222 
223     for (i = 0; i < ti->num_interfaces; i++) {
224         type_class_interface_init(ti, &ti->interfaces[i]);
225     }
226 
227     if (ti->class_init) {
228         ti->class_init(ti->class, ti->class_data);
229     }
230 }
231 
232 static void object_interface_init(Object *obj, InterfaceImpl *iface)
233 {
234     TypeImpl *ti = iface->type;
235     Interface *iface_obj;
236 
237     iface_obj = INTERFACE(object_new(ti->name));
238     iface_obj->obj = obj;
239 
240     obj->interfaces = g_slist_prepend(obj->interfaces, iface_obj);
241 }
242 
243 static void object_init_with_type(Object *obj, TypeImpl *ti)
244 {
245     int i;
246 
247     if (type_has_parent(ti)) {
248         object_init_with_type(obj, type_get_parent(ti));
249     }
250 
251     for (i = 0; i < ti->num_interfaces; i++) {
252         object_interface_init(obj, &ti->interfaces[i]);
253     }
254 
255     if (ti->instance_init) {
256         ti->instance_init(obj);
257     }
258 }
259 
260 void object_initialize_with_type(void *data, TypeImpl *type)
261 {
262     Object *obj = data;
263 
264     g_assert(type != NULL);
265     g_assert(type->instance_size >= sizeof(ObjectClass));
266 
267     type_class_init(type);
268     g_assert(type->abstract == false);
269 
270     memset(obj, 0, type->instance_size);
271     obj->class = type->class;
272     QTAILQ_INIT(&obj->properties);
273     object_init_with_type(obj, type);
274 }
275 
276 void object_initialize(void *data, const char *typename)
277 {
278     TypeImpl *type = type_get_by_name(typename);
279 
280     object_initialize_with_type(data, type);
281 }
282 
283 static void object_property_del_all(Object *obj)
284 {
285     while (!QTAILQ_EMPTY(&obj->properties)) {
286         ObjectProperty *prop = QTAILQ_FIRST(&obj->properties);
287 
288         QTAILQ_REMOVE(&obj->properties, prop, node);
289 
290         if (prop->release) {
291             prop->release(obj, prop->name, prop->opaque);
292         }
293 
294         g_free(prop->name);
295         g_free(prop->type);
296         g_free(prop);
297     }
298 }
299 
300 static void object_property_del_child(Object *obj, Object *child, Error **errp)
301 {
302     ObjectProperty *prop;
303 
304     QTAILQ_FOREACH(prop, &obj->properties, node) {
305         if (!strstart(prop->type, "child<", NULL)) {
306             continue;
307         }
308 
309         if (prop->opaque == child) {
310             object_property_del(obj, prop->name, errp);
311         }
312     }
313 }
314 
315 void object_unparent(Object *obj)
316 {
317     if (obj->parent) {
318         object_property_del_child(obj->parent, obj, NULL);
319     }
320 }
321 
322 static void object_deinit(Object *obj, TypeImpl *type)
323 {
324     if (type->instance_finalize) {
325         type->instance_finalize(obj);
326     }
327 
328     while (obj->interfaces) {
329         Interface *iface_obj = obj->interfaces->data;
330         obj->interfaces = g_slist_delete_link(obj->interfaces, obj->interfaces);
331         object_delete(OBJECT(iface_obj));
332     }
333 
334     if (type_has_parent(type)) {
335         object_deinit(obj, type_get_parent(type));
336     }
337 
338     object_unparent(obj);
339 }
340 
341 void object_finalize(void *data)
342 {
343     Object *obj = data;
344     TypeImpl *ti = obj->class->type;
345 
346     object_deinit(obj, ti);
347     object_property_del_all(obj);
348 
349     g_assert(obj->ref == 0);
350 }
351 
352 Object *object_new_with_type(Type type)
353 {
354     Object *obj;
355 
356     g_assert(type != NULL);
357 
358     obj = g_malloc(type->instance_size);
359     object_initialize_with_type(obj, type);
360     object_ref(obj);
361 
362     return obj;
363 }
364 
365 Object *object_new(const char *typename)
366 {
367     TypeImpl *ti = type_get_by_name(typename);
368 
369     return object_new_with_type(ti);
370 }
371 
372 void object_delete(Object *obj)
373 {
374     object_unref(obj);
375     g_assert(obj->ref == 0);
376     g_free(obj);
377 }
378 
379 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
380 {
381     assert(target_type);
382 
383     /* Check if typename is a direct ancestor of type */
384     while (type) {
385         if (type == target_type) {
386             return true;
387         }
388 
389         type = type_get_parent(type);
390     }
391 
392     return false;
393 }
394 
395 static bool object_is_type(Object *obj, TypeImpl *target_type)
396 {
397     return !target_type || type_is_ancestor(obj->class->type, target_type);
398 }
399 
400 Object *object_dynamic_cast(Object *obj, const char *typename)
401 {
402     TypeImpl *target_type = type_get_by_name(typename);
403     GSList *i;
404 
405     /* Check if typename is a direct ancestor.  Special-case TYPE_OBJECT,
406      * we want to go back from interfaces to the parent.
407     */
408     if (target_type && object_is_type(obj, target_type)) {
409         return obj;
410     }
411 
412     /* Check if obj is an interface and its containing object is a direct
413      * ancestor of typename.  In principle we could do this test at the very
414      * beginning of object_dynamic_cast, avoiding a second call to
415      * object_is_type.  However, casting between interfaces is relatively
416      * rare, and object_is_type(obj, type_interface) would fail almost always.
417      *
418      * Perhaps we could add a magic value to the object header for increased
419      * (run-time) type safety and to speed up tests like this one.  If we ever
420      * do that we can revisit the order here.
421      */
422     if (object_is_type(obj, type_interface)) {
423         assert(!obj->interfaces);
424         obj = INTERFACE(obj)->obj;
425         if (object_is_type(obj, target_type)) {
426             return obj;
427         }
428     }
429 
430     if (!target_type) {
431         return obj;
432     }
433 
434     /* Check if obj has an interface of typename */
435     for (i = obj->interfaces; i; i = i->next) {
436         Interface *iface = i->data;
437 
438         if (object_is_type(OBJECT(iface), target_type)) {
439             return OBJECT(iface);
440         }
441     }
442 
443     return NULL;
444 }
445 
446 
447 static void register_interface(void)
448 {
449     static TypeInfo interface_info = {
450         .name = TYPE_INTERFACE,
451         .instance_size = sizeof(Interface),
452         .abstract = true,
453     };
454 
455     type_interface = type_register_static(&interface_info);
456 }
457 
458 device_init(register_interface);
459 
460 Object *object_dynamic_cast_assert(Object *obj, const char *typename)
461 {
462     Object *inst;
463 
464     inst = object_dynamic_cast(obj, typename);
465 
466     if (!inst) {
467         fprintf(stderr, "Object %p is not an instance of type %s\n",
468                 obj, typename);
469         abort();
470     }
471 
472     return inst;
473 }
474 
475 ObjectClass *object_class_dynamic_cast(ObjectClass *class,
476                                        const char *typename)
477 {
478     TypeImpl *target_type = type_get_by_name(typename);
479     TypeImpl *type = class->type;
480 
481     while (type) {
482         if (type == target_type) {
483             return class;
484         }
485 
486         type = type_get_parent(type);
487     }
488 
489     return NULL;
490 }
491 
492 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
493                                               const char *typename)
494 {
495     ObjectClass *ret = object_class_dynamic_cast(class, typename);
496 
497     if (!ret) {
498         fprintf(stderr, "Object %p is not an instance of type %s\n",
499                 class, typename);
500         abort();
501     }
502 
503     return ret;
504 }
505 
506 const char *object_get_typename(Object *obj)
507 {
508     return obj->class->type->name;
509 }
510 
511 ObjectClass *object_get_class(Object *obj)
512 {
513     return obj->class;
514 }
515 
516 const char *object_class_get_name(ObjectClass *klass)
517 {
518     return klass->type->name;
519 }
520 
521 ObjectClass *object_class_by_name(const char *typename)
522 {
523     TypeImpl *type = type_get_by_name(typename);
524 
525     if (!type) {
526         return NULL;
527     }
528 
529     type_class_init(type);
530 
531     return type->class;
532 }
533 
534 typedef struct OCFData
535 {
536     void (*fn)(ObjectClass *klass, void *opaque);
537     const char *implements_type;
538     bool include_abstract;
539     void *opaque;
540 } OCFData;
541 
542 static void object_class_foreach_tramp(gpointer key, gpointer value,
543                                        gpointer opaque)
544 {
545     OCFData *data = opaque;
546     TypeImpl *type = value;
547     ObjectClass *k;
548 
549     type_class_init(type);
550     k = type->class;
551 
552     if (!data->include_abstract && type->abstract) {
553         return;
554     }
555 
556     if (data->implements_type &&
557         !object_class_dynamic_cast(k, data->implements_type)) {
558         return;
559     }
560 
561     data->fn(k, data->opaque);
562 }
563 
564 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
565                           const char *implements_type, bool include_abstract,
566                           void *opaque)
567 {
568     OCFData data = { fn, implements_type, include_abstract, opaque };
569 
570     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
571 }
572 
573 void object_ref(Object *obj)
574 {
575     obj->ref++;
576 }
577 
578 void object_unref(Object *obj)
579 {
580     g_assert(obj->ref > 0);
581     obj->ref--;
582 
583     /* parent always holds a reference to its children */
584     if (obj->ref == 0) {
585         object_finalize(obj);
586     }
587 }
588 
589 void object_property_add(Object *obj, const char *name, const char *type,
590                          ObjectPropertyAccessor *get,
591                          ObjectPropertyAccessor *set,
592                          ObjectPropertyRelease *release,
593                          void *opaque, Error **errp)
594 {
595     ObjectProperty *prop = g_malloc0(sizeof(*prop));
596 
597     prop->name = g_strdup(name);
598     prop->type = g_strdup(type);
599 
600     prop->get = get;
601     prop->set = set;
602     prop->release = release;
603     prop->opaque = opaque;
604 
605     QTAILQ_INSERT_TAIL(&obj->properties, prop, node);
606 }
607 
608 static ObjectProperty *object_property_find(Object *obj, const char *name)
609 {
610     ObjectProperty *prop;
611 
612     QTAILQ_FOREACH(prop, &obj->properties, node) {
613         if (strcmp(prop->name, name) == 0) {
614             return prop;
615         }
616     }
617 
618     return NULL;
619 }
620 
621 void object_property_del(Object *obj, const char *name, Error **errp)
622 {
623     ObjectProperty *prop = object_property_find(obj, name);
624 
625     QTAILQ_REMOVE(&obj->properties, prop, node);
626 
627     prop->release(obj, prop->name, prop->opaque);
628 
629     g_free(prop->name);
630     g_free(prop->type);
631     g_free(prop);
632 }
633 
634 void object_property_get(Object *obj, Visitor *v, const char *name,
635                          Error **errp)
636 {
637     ObjectProperty *prop = object_property_find(obj, name);
638 
639     if (prop == NULL) {
640         error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
641         return;
642     }
643 
644     if (!prop->get) {
645         error_set(errp, QERR_PERMISSION_DENIED);
646     } else {
647         prop->get(obj, v, prop->opaque, name, errp);
648     }
649 }
650 
651 void object_property_set(Object *obj, Visitor *v, const char *name,
652                          Error **errp)
653 {
654     ObjectProperty *prop = object_property_find(obj, name);
655 
656     if (prop == NULL) {
657         error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
658         return;
659     }
660 
661     if (!prop->set) {
662         error_set(errp, QERR_PERMISSION_DENIED);
663     } else {
664         prop->set(obj, v, prop->opaque, name, errp);
665     }
666 }
667 
668 void object_property_set_str(Object *obj, const char *value,
669                              const char *name, Error **errp)
670 {
671     QString *qstr = qstring_from_str(value);
672     object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
673 
674     QDECREF(qstr);
675 }
676 
677 char *object_property_get_str(Object *obj, const char *name,
678                               Error **errp)
679 {
680     QObject *ret = object_property_get_qobject(obj, name, errp);
681     QString *qstring;
682     char *retval;
683 
684     if (!ret) {
685         return NULL;
686     }
687     qstring = qobject_to_qstring(ret);
688     if (!qstring) {
689         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
690         retval = NULL;
691     } else {
692         retval = g_strdup(qstring_get_str(qstring));
693     }
694 
695     QDECREF(qstring);
696     return retval;
697 }
698 
699 void object_property_set_link(Object *obj, Object *value,
700                               const char *name, Error **errp)
701 {
702     object_property_set_str(obj, object_get_canonical_path(value),
703                             name, errp);
704 }
705 
706 Object *object_property_get_link(Object *obj, const char *name,
707                                  Error **errp)
708 {
709     char *str = object_property_get_str(obj, name, errp);
710     Object *target = NULL;
711 
712     if (str && *str) {
713         target = object_resolve_path(str, NULL);
714         if (!target) {
715             error_set(errp, QERR_DEVICE_NOT_FOUND, str);
716         }
717     }
718 
719     g_free(str);
720     return target;
721 }
722 
723 void object_property_set_bool(Object *obj, bool value,
724                               const char *name, Error **errp)
725 {
726     QBool *qbool = qbool_from_int(value);
727     object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
728 
729     QDECREF(qbool);
730 }
731 
732 bool object_property_get_bool(Object *obj, const char *name,
733                               Error **errp)
734 {
735     QObject *ret = object_property_get_qobject(obj, name, errp);
736     QBool *qbool;
737     bool retval;
738 
739     if (!ret) {
740         return false;
741     }
742     qbool = qobject_to_qbool(ret);
743     if (!qbool) {
744         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
745         retval = false;
746     } else {
747         retval = qbool_get_int(qbool);
748     }
749 
750     QDECREF(qbool);
751     return retval;
752 }
753 
754 void object_property_set_int(Object *obj, int64_t value,
755                              const char *name, Error **errp)
756 {
757     QInt *qint = qint_from_int(value);
758     object_property_set_qobject(obj, QOBJECT(qint), name, errp);
759 
760     QDECREF(qint);
761 }
762 
763 int64_t object_property_get_int(Object *obj, const char *name,
764                                 Error **errp)
765 {
766     QObject *ret = object_property_get_qobject(obj, name, errp);
767     QInt *qint;
768     int64_t retval;
769 
770     if (!ret) {
771         return -1;
772     }
773     qint = qobject_to_qint(ret);
774     if (!qint) {
775         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
776         retval = -1;
777     } else {
778         retval = qint_get_int(qint);
779     }
780 
781     QDECREF(qint);
782     return retval;
783 }
784 
785 const char *object_property_get_type(Object *obj, const char *name, Error **errp)
786 {
787     ObjectProperty *prop = object_property_find(obj, name);
788 
789     if (prop == NULL) {
790         error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
791         return NULL;
792     }
793 
794     return prop->type;
795 }
796 
797 Object *object_get_root(void)
798 {
799     static Object *root;
800 
801     if (!root) {
802         root = object_new("container");
803     }
804 
805     return root;
806 }
807 
808 static void object_get_child_property(Object *obj, Visitor *v, void *opaque,
809                                       const char *name, Error **errp)
810 {
811     Object *child = opaque;
812     gchar *path;
813 
814     path = object_get_canonical_path(child);
815     visit_type_str(v, &path, name, errp);
816     g_free(path);
817 }
818 
819 static void object_finalize_child_property(Object *obj, const char *name,
820                                            void *opaque)
821 {
822     Object *child = opaque;
823 
824     object_unref(child);
825 }
826 
827 void object_property_add_child(Object *obj, const char *name,
828                                Object *child, Error **errp)
829 {
830     gchar *type;
831 
832     /* Registering an interface object in the composition tree will mightily
833      * confuse object_get_canonical_path (which, on the other hand, knows how
834      * to get the canonical path of an interface object).
835      */
836     assert(!object_is_type(obj, type_interface));
837 
838     type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
839 
840     object_property_add(obj, name, type, object_get_child_property,
841                         NULL, object_finalize_child_property, child, errp);
842 
843     object_ref(child);
844     g_assert(child->parent == NULL);
845     child->parent = obj;
846 
847     g_free(type);
848 }
849 
850 static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
851                                      const char *name, Error **errp)
852 {
853     Object **child = opaque;
854     gchar *path;
855 
856     if (*child) {
857         path = object_get_canonical_path(*child);
858         visit_type_str(v, &path, name, errp);
859         g_free(path);
860     } else {
861         path = (gchar *)"";
862         visit_type_str(v, &path, name, errp);
863     }
864 }
865 
866 static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
867                                      const char *name, Error **errp)
868 {
869     Object **child = opaque;
870     bool ambiguous = false;
871     const char *type;
872     char *path;
873     gchar *target_type;
874 
875     type = object_property_get_type(obj, name, NULL);
876 
877     visit_type_str(v, &path, name, errp);
878 
879     if (*child) {
880         object_unref(*child);
881         *child = NULL;
882     }
883 
884     if (strcmp(path, "") != 0) {
885         Object *target;
886 
887         /* Go from link<FOO> to FOO.  */
888         target_type = g_strndup(&type[5], strlen(type) - 6);
889         target = object_resolve_path_type(path, target_type, &ambiguous);
890 
891         if (ambiguous) {
892             error_set(errp, QERR_AMBIGUOUS_PATH, path);
893         } else if (target) {
894             object_ref(target);
895             *child = target;
896         } else {
897             target = object_resolve_path(path, &ambiguous);
898             if (target || ambiguous) {
899                 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
900             } else {
901                 error_set(errp, QERR_DEVICE_NOT_FOUND, path);
902             }
903         }
904         g_free(target_type);
905     }
906 
907     g_free(path);
908 }
909 
910 void object_property_add_link(Object *obj, const char *name,
911                               const char *type, Object **child,
912                               Error **errp)
913 {
914     gchar *full_type;
915 
916     full_type = g_strdup_printf("link<%s>", type);
917 
918     object_property_add(obj, name, full_type,
919                         object_get_link_property,
920                         object_set_link_property,
921                         NULL, child, errp);
922 
923     g_free(full_type);
924 }
925 
926 gchar *object_get_canonical_path(Object *obj)
927 {
928     Object *root = object_get_root();
929     char *newpath = NULL, *path = NULL;
930 
931     if (object_is_type(obj, type_interface)) {
932         obj = INTERFACE(obj)->obj;
933     }
934 
935     while (obj != root) {
936         ObjectProperty *prop = NULL;
937 
938         g_assert(obj->parent != NULL);
939 
940         QTAILQ_FOREACH(prop, &obj->parent->properties, node) {
941             if (!strstart(prop->type, "child<", NULL)) {
942                 continue;
943             }
944 
945             if (prop->opaque == obj) {
946                 if (path) {
947                     newpath = g_strdup_printf("%s/%s", prop->name, path);
948                     g_free(path);
949                     path = newpath;
950                 } else {
951                     path = g_strdup(prop->name);
952                 }
953                 break;
954             }
955         }
956 
957         g_assert(prop != NULL);
958 
959         obj = obj->parent;
960     }
961 
962     newpath = g_strdup_printf("/%s", path);
963     g_free(path);
964 
965     return newpath;
966 }
967 
968 static Object *object_resolve_abs_path(Object *parent,
969                                           gchar **parts,
970                                           const char *typename,
971                                           int index)
972 {
973     ObjectProperty *prop;
974     Object *child;
975 
976     if (parts[index] == NULL) {
977         return object_dynamic_cast(parent, typename);
978     }
979 
980     if (strcmp(parts[index], "") == 0) {
981         return object_resolve_abs_path(parent, parts, typename, index + 1);
982     }
983 
984     prop = object_property_find(parent, parts[index]);
985     if (prop == NULL) {
986         return NULL;
987     }
988 
989     child = NULL;
990     if (strstart(prop->type, "link<", NULL)) {
991         Object **pchild = prop->opaque;
992         if (*pchild) {
993             child = *pchild;
994         }
995     } else if (strstart(prop->type, "child<", NULL)) {
996         child = prop->opaque;
997     }
998 
999     if (!child) {
1000         return NULL;
1001     }
1002 
1003     return object_resolve_abs_path(child, parts, typename, index + 1);
1004 }
1005 
1006 static Object *object_resolve_partial_path(Object *parent,
1007                                               gchar **parts,
1008                                               const char *typename,
1009                                               bool *ambiguous)
1010 {
1011     Object *obj;
1012     ObjectProperty *prop;
1013 
1014     obj = object_resolve_abs_path(parent, parts, typename, 0);
1015 
1016     QTAILQ_FOREACH(prop, &parent->properties, node) {
1017         Object *found;
1018 
1019         if (!strstart(prop->type, "child<", NULL)) {
1020             continue;
1021         }
1022 
1023         found = object_resolve_partial_path(prop->opaque, parts,
1024                                             typename, ambiguous);
1025         if (found) {
1026             if (obj) {
1027                 if (ambiguous) {
1028                     *ambiguous = true;
1029                 }
1030                 return NULL;
1031             }
1032             obj = found;
1033         }
1034 
1035         if (ambiguous && *ambiguous) {
1036             return NULL;
1037         }
1038     }
1039 
1040     return obj;
1041 }
1042 
1043 Object *object_resolve_path_type(const char *path, const char *typename,
1044                                  bool *ambiguous)
1045 {
1046     bool partial_path = true;
1047     Object *obj;
1048     gchar **parts;
1049 
1050     parts = g_strsplit(path, "/", 0);
1051     if (parts == NULL || parts[0] == NULL) {
1052         g_strfreev(parts);
1053         return object_get_root();
1054     }
1055 
1056     if (strcmp(parts[0], "") == 0) {
1057         partial_path = false;
1058     }
1059 
1060     if (partial_path) {
1061         if (ambiguous) {
1062             *ambiguous = false;
1063         }
1064         obj = object_resolve_partial_path(object_get_root(), parts,
1065                                           typename, ambiguous);
1066     } else {
1067         obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
1068     }
1069 
1070     g_strfreev(parts);
1071 
1072     return obj;
1073 }
1074 
1075 Object *object_resolve_path(const char *path, bool *ambiguous)
1076 {
1077     return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
1078 }
1079 
1080 typedef struct StringProperty
1081 {
1082     char *(*get)(Object *, Error **);
1083     void (*set)(Object *, const char *, Error **);
1084 } StringProperty;
1085 
1086 static void property_get_str(Object *obj, Visitor *v, void *opaque,
1087                              const char *name, Error **errp)
1088 {
1089     StringProperty *prop = opaque;
1090     char *value;
1091 
1092     value = prop->get(obj, errp);
1093     if (value) {
1094         visit_type_str(v, &value, name, errp);
1095         g_free(value);
1096     }
1097 }
1098 
1099 static void property_set_str(Object *obj, Visitor *v, void *opaque,
1100                              const char *name, Error **errp)
1101 {
1102     StringProperty *prop = opaque;
1103     char *value;
1104     Error *local_err = NULL;
1105 
1106     visit_type_str(v, &value, name, &local_err);
1107     if (local_err) {
1108         error_propagate(errp, local_err);
1109         return;
1110     }
1111 
1112     prop->set(obj, value, errp);
1113     g_free(value);
1114 }
1115 
1116 static void property_release_str(Object *obj, const char *name,
1117                                  void *opaque)
1118 {
1119     StringProperty *prop = opaque;
1120     g_free(prop);
1121 }
1122 
1123 void object_property_add_str(Object *obj, const char *name,
1124                            char *(*get)(Object *, Error **),
1125                            void (*set)(Object *, const char *, Error **),
1126                            Error **errp)
1127 {
1128     StringProperty *prop = g_malloc0(sizeof(*prop));
1129 
1130     prop->get = get;
1131     prop->set = set;
1132 
1133     object_property_add(obj, name, "string",
1134                         get ? property_get_str : NULL,
1135                         set ? property_set_str : NULL,
1136                         property_release_str,
1137                         prop, errp);
1138 }
1139