diff options
Diffstat (limited to 'qom/object.c')
-rw-r--r-- | qom/object.c | 177 |
1 files changed, 99 insertions, 78 deletions
diff --git a/qom/object.c b/qom/object.c index 157a45c..1856bb3 100644 --- a/qom/object.c +++ b/qom/object.c @@ -23,16 +23,16 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/forward-visitor.h" #include "qapi/qapi-builtin-visit.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qjson.h" #include "trace.h" /* TODO: replace QObject with a simpler visitor to avoid a dependency * of the QOM core on QObject? */ #include "qom/qom-qobject.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qemu/error-report.h" #define MAX_INTERFACES 32 @@ -54,10 +54,10 @@ struct TypeImpl size_t instance_size; size_t instance_align; - void (*class_init)(ObjectClass *klass, void *data); - void (*class_base_init)(ObjectClass *klass, void *data); + void (*class_init)(ObjectClass *klass, const void *data); + void (*class_base_init)(ObjectClass *klass, const void *data); - void *class_data; + const void *class_data; void (*instance_init)(Object *obj); void (*instance_post_init)(Object *obj); @@ -175,17 +175,12 @@ static TypeImpl *type_register_internal(const TypeInfo *info) return ti; } -TypeImpl *type_register(const TypeInfo *info) +TypeImpl *type_register_static(const TypeInfo *info) { assert(info->parent); return type_register_internal(info); } -TypeImpl *type_register_static(const TypeInfo *info) -{ - return type_register(info); -} - void type_register_static_array(const TypeInfo *infos, int nr_infos) { int i; @@ -195,7 +190,7 @@ void type_register_static_array(const TypeInfo *infos, int nr_infos) } } -static TypeImpl *type_get_by_name(const char *name) +static TypeImpl *type_get_by_name_noload(const char *name) { if (name == NULL) { return NULL; @@ -204,10 +199,32 @@ static TypeImpl *type_get_by_name(const char *name) return type_table_lookup(name); } +static TypeImpl *type_get_or_load_by_name(const char *name, Error **errp) +{ + TypeImpl *type = type_get_by_name_noload(name); + +#ifdef CONFIG_MODULES + if (!type) { + int rv = module_load_qom(name, errp); + if (rv > 0) { + type = type_get_by_name_noload(name); + } else { + error_prepend(errp, "could not load a module for type '%s'", name); + return NULL; + } + } +#endif + if (!type) { + error_setg(errp, "unknown type '%s'", name); + } + + return type; +} + static TypeImpl *type_get_parent(TypeImpl *type) { if (!type->parent_type && type->parent) { - type->parent_type = type_get_by_name(type->parent); + type->parent_type = type_get_by_name_noload(type->parent); if (!type->parent_type) { fprintf(stderr, "Type '%s' is missing its parent '%s'\n", type->name, type->parent); @@ -262,14 +279,6 @@ static size_t type_object_get_align(TypeImpl *ti) return 0; } -size_t object_type_get_instance_size(const char *typename) -{ - TypeImpl *type = type_get_by_name(typename); - - g_assert(type != NULL); - return type_object_get_size(type); -} - static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) { assert(target_type); @@ -305,7 +314,6 @@ static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type, g_free((char *)info.name); new_iface = (InterfaceClass *)iface_impl->class; - new_iface->concrete_class = ti->class; new_iface->interface_type = interface_type; ti->class->interfaces = g_slist_append(ti->class->interfaces, new_iface); @@ -371,7 +379,7 @@ static void type_initialize(TypeImpl *ti) } for (i = 0; i < ti->num_interfaces; i++) { - TypeImpl *t = type_get_by_name(ti->interfaces[i].typename); + TypeImpl *t = type_get_by_name_noload(ti->interfaces[i].typename); if (!t) { error_report("missing interface '%s' for object '%s'", ti->interfaces[i].typename, parent->name); @@ -423,13 +431,13 @@ static void object_init_with_type(Object *obj, TypeImpl *ti) static void object_post_init_with_type(Object *obj, TypeImpl *ti) { - if (ti->instance_post_init) { - ti->instance_post_init(obj); - } - if (type_has_parent(ti)) { object_post_init_with_type(obj, type_get_parent(ti)); } + + if (ti->instance_post_init) { + ti->instance_post_init(obj); + } } bool object_apply_global_props(Object *obj, const GPtrArray *props, @@ -477,7 +485,7 @@ bool object_apply_global_props(Object *obj, const GPtrArray *props, * Slot 0: accelerator's global property defaults * Slot 1: machine's global property defaults * Slot 2: global properties from legacy command line option - * Each is a GPtrArray of of GlobalProperty. + * Each is a GPtrArray of GlobalProperty. * Applied in order, later entries override earlier ones. */ static GPtrArray *object_compat_props[3]; @@ -565,23 +573,7 @@ static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type void object_initialize(void *data, size_t size, const char *typename) { - TypeImpl *type = type_get_by_name(typename); - -#ifdef CONFIG_MODULES - if (!type) { - int rv = module_load_qom(typename, &error_fatal); - if (rv > 0) { - type = type_get_by_name(typename); - } else { - error_report("missing object type '%s'", typename); - exit(1); - } - } -#endif - if (!type) { - error_report("missing object type '%s'", typename); - abort(); - } + TypeImpl *type = type_get_or_load_by_name(typename, &error_fatal); object_initialize_with_type(data, size, type); } @@ -792,7 +784,7 @@ Object *object_new_with_class(ObjectClass *klass) Object *object_new(const char *typename) { - TypeImpl *ti = type_get_by_name(typename); + TypeImpl *ti = type_get_or_load_by_name(typename, &error_fatal); return object_new_with_type(ti); } @@ -965,7 +957,7 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *class, return class; } - target_type = type_get_by_name(typename); + target_type = type_get_by_name_noload(typename); if (!target_type) { /* target class type unknown, so fail the cast */ return NULL; @@ -1063,7 +1055,7 @@ const char *object_class_get_name(ObjectClass *klass) ObjectClass *object_class_by_name(const char *typename) { - TypeImpl *type = type_get_by_name(typename); + TypeImpl *type = type_get_by_name_noload(typename); if (!type) { return NULL; @@ -1076,21 +1068,15 @@ ObjectClass *object_class_by_name(const char *typename) ObjectClass *module_object_class_by_name(const char *typename) { - ObjectClass *oc; + TypeImpl *type = type_get_or_load_by_name(typename, NULL); - oc = object_class_by_name(typename); -#ifdef CONFIG_MODULES - if (!oc) { - Error *local_err = NULL; - int rv = module_load_qom(typename, &local_err); - if (rv > 0) { - oc = object_class_by_name(typename); - } else if (rv < 0) { - error_report_err(local_err); - } + if (!type) { + return NULL; } -#endif - return oc; + + type_initialize(type); + + return type->class; } ObjectClass *object_class_get_parent(ObjectClass *class) @@ -1205,7 +1191,7 @@ GSList *object_class_get_list(const char *implements_type, return list; } -static gint object_class_cmp(gconstpointer a, gconstpointer b) +static gint object_class_cmp(gconstpointer a, gconstpointer b, gpointer d) { return strcasecmp(object_class_get_name((ObjectClass *)a), object_class_get_name((ObjectClass *)b)); @@ -1214,8 +1200,9 @@ static gint object_class_cmp(gconstpointer a, gconstpointer b) GSList *object_class_get_list_sorted(const char *implements_type, bool include_abstract) { - return g_slist_sort(object_class_get_list(implements_type, include_abstract), - object_class_cmp); + return g_slist_sort_with_data( + object_class_get_list(implements_type, include_abstract), + object_class_cmp, NULL); } Object *object_ref(void *objptr) @@ -1742,12 +1729,44 @@ const char *object_property_get_type(Object *obj, const char *name, Error **errp return prop->type; } +static const char *const root_containers[] = { + "chardevs", + "objects", + "backend" +}; + +static Object *object_root_initialize(void) +{ + Object *root = object_new(TYPE_CONTAINER); + int i; + + /* + * Create all QEMU system containers. "machine" and its sub-containers + * are only created when machine initializes (qemu_create_machine()). + */ + for (i = 0; i < ARRAY_SIZE(root_containers); i++) { + object_property_add_new_container(root, root_containers[i]); + } + + return root; +} + +Object *object_get_container(const char *name) +{ + Object *container; + + container = object_resolve_path_component(object_get_root(), name); + assert(object_dynamic_cast(container, TYPE_CONTAINER)); + + return container; +} + Object *object_get_root(void) { static Object *root; if (!root) { - root = object_new("container"); + root = object_root_initialize(); } return root; @@ -1755,7 +1774,7 @@ Object *object_get_root(void) Object *object_get_objects_root(void) { - return container_get(object_get_root(), "/objects"); + return object_get_container("objects"); } Object *object_get_internal_root(void) @@ -1763,7 +1782,7 @@ Object *object_get_internal_root(void) static Object *internal_root; if (!internal_root) { - internal_root = object_new("container"); + internal_root = object_new(TYPE_CONTAINER); } return internal_root; @@ -2079,7 +2098,6 @@ const char *object_get_canonical_path_component(const Object *obj) /* obj had a parent but was not a child, should never happen */ g_assert_not_reached(); - return NULL; } char *object_get_canonical_path(const Object *obj) @@ -2185,7 +2203,7 @@ static Object *object_resolve_partial_path(Object *parent, } Object *object_resolve_path_type(const char *path, const char *typename, - bool *ambiguousp) + bool *ambiguous) { Object *obj; char **parts; @@ -2194,14 +2212,17 @@ Object *object_resolve_path_type(const char *path, const char *typename, assert(parts); if (parts[0] == NULL || strcmp(parts[0], "") != 0) { - bool ambiguous = false; + bool ambig = false; obj = object_resolve_partial_path(object_get_root(), parts, - typename, &ambiguous); - if (ambiguousp) { - *ambiguousp = ambiguous; + typename, &ambig); + if (ambiguous) { + *ambiguous = ambig; } } else { obj = object_resolve_abs_path(object_get_root(), parts + 1, typename); + if (ambiguous) { + *ambiguous = false; + } } g_strfreev(parts); @@ -2227,7 +2248,7 @@ Object *object_resolve_path_at(Object *parent, const char *path) Object *object_resolve_type_unambiguous(const char *typename, Error **errp) { - bool ambig; + bool ambig = false; Object *o = object_resolve_path_type("", typename, &ambig); if (ambig) { @@ -2871,7 +2892,7 @@ void object_class_property_set_description(ObjectClass *klass, op->description = g_strdup(description); } -static void object_class_init(ObjectClass *klass, void *data) +static void object_class_init(ObjectClass *klass, const void *data) { object_class_property_add_str(klass, "type", object_get_type, NULL); |