diff options
Diffstat (limited to 'qom')
-rw-r--r-- | qom/container.c | 27 | ||||
-rw-r--r-- | qom/object.c | 177 | ||||
-rw-r--r-- | qom/object_interfaces.c | 34 | ||||
-rw-r--r-- | qom/qom-hmp-cmds.c | 4 | ||||
-rw-r--r-- | qom/qom-qmp-cmds.c | 27 |
5 files changed, 151 insertions, 118 deletions
diff --git a/qom/container.c b/qom/container.c index 455e841..38a27ec 100644 --- a/qom/container.c +++ b/qom/container.c @@ -15,7 +15,7 @@ #include "qemu/module.h" static const TypeInfo container_info = { - .name = "container", + .name = TYPE_CONTAINER, .parent = TYPE_OBJECT, }; @@ -24,29 +24,14 @@ static void container_register_types(void) type_register_static(&container_info); } -Object *container_get(Object *root, const char *path) +Object *object_property_add_new_container(Object *obj, const char *name) { - Object *obj, *child; - char **parts; - int i; + Object *child = object_new(TYPE_CONTAINER); - parts = g_strsplit(path, "/", 0); - assert(parts != NULL && parts[0] != NULL && !parts[0][0]); - obj = root; + object_property_add_child(obj, name, child); + object_unref(child); - for (i = 1; parts[i] != NULL; i++, obj = child) { - child = object_resolve_path_component(obj, parts[i]); - if (!child) { - child = object_new("container"); - object_property_add_child(obj, parts[i], child); - object_unref(child); - } - } - - g_strfreev(parts); - - return obj; + return child; } - type_init(container_register_types) 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); diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index e0833c8..1ffea1a 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -3,10 +3,12 @@ #include "qemu/cutils.h" #include "qapi/error.h" #include "qapi/qapi-visit-qom.h" -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qobject.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qjson.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "qom/object_interfaces.h" @@ -90,7 +92,7 @@ Object *user_creatable_add_type(const char *type, const char *id, return NULL; } - klass = object_class_by_name(type); + klass = module_object_class_by_name(type); if (!klass) { error_setg(errp, "invalid object type: %s", type); return NULL; @@ -108,7 +110,7 @@ Object *user_creatable_add_type(const char *type, const char *id, } assert(qdict); - obj = object_new(type); + obj = object_new_with_class(klass); object_set_properties_from_qdict(obj, qdict, v, &local_err); if (local_err) { goto out; @@ -177,9 +179,25 @@ char *object_property_help(const char *name, const char *type, g_string_append(str, description); } if (defval) { - g_autofree char *def_json = g_string_free(qobject_to_json(defval), - false); - g_string_append_printf(str, " (default: %s)", def_json); + g_autofree char *def_json = NULL; + const char *def; + + switch (qobject_type(defval)) { + case QTYPE_QSTRING: + def = qstring_get_str(qobject_to(QString, defval)); + break; + + case QTYPE_QBOOL: + def = qbool_get_bool(qobject_to(QBool, defval)) ? "on" : "off"; + break; + + default: + def_json = g_string_free(qobject_to_json(defval), false); + def = def_json; + break; + } + + g_string_append_printf(str, " (default: %s)", def); } return g_string_free(str, false); diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c index 6e3a217..a00a564 100644 --- a/qom/qom-hmp-cmds.c +++ b/qom/qom-hmp-cmds.c @@ -11,8 +11,8 @@ #include "monitor/monitor.h" #include "qapi/error.h" #include "qapi/qapi-commands-qom.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" #include "qemu/readline.h" #include "qom/object.h" #include "qom/object_interfaces.h" diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c index e91a235..293755f 100644 --- a/qom/qom-qmp-cmds.c +++ b/qom/qom-qmp-cmds.c @@ -20,7 +20,7 @@ #include "qapi/qapi-commands-qdev.h" #include "qapi/qapi-commands-qom.h" #include "qapi/qapi-visit-qom.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" @@ -28,15 +28,11 @@ #include "qom/object_interfaces.h" #include "qom/qom-qobject.h" -ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp) +static Object *qom_resolve_path(const char *path, Error **errp) { - Object *obj; bool ambiguous = false; - ObjectPropertyInfoList *props = NULL; - ObjectProperty *prop; - ObjectPropertyIterator iter; + Object *obj = object_resolve_path(path, &ambiguous); - obj = object_resolve_path(path, &ambiguous); if (obj == NULL) { if (ambiguous) { error_setg(errp, "Path '%s' is ambiguous", path); @@ -44,6 +40,19 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp) error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found", path); } + } + return obj; +} + +ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp) +{ + Object *obj; + ObjectPropertyInfoList *props = NULL; + ObjectProperty *prop; + ObjectPropertyIterator iter; + + obj = qom_resolve_path(path, errp); + if (obj == NULL) { return NULL; } @@ -141,7 +150,7 @@ ObjectPropertyInfoList *qmp_device_list_properties(const char *typename, return NULL; } - obj = object_new(typename); + obj = object_new_with_class(klass); object_property_iter_init(&iter, obj); while ((prop = object_property_iter_next(&iter))) { @@ -186,7 +195,7 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename, ObjectPropertyIterator iter; ObjectPropertyInfoList *prop_list = NULL; - klass = object_class_by_name(typename); + klass = module_object_class_by_name(typename); if (klass == NULL) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Class '%s' not found", typename); |