aboutsummaryrefslogtreecommitdiff
path: root/qom/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'qom/object.c')
-rw-r--r--qom/object.c177
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);