Message ID | 1483371890-289981-4-git-send-email-imammedo@redhat.com |
---|---|
State | New |
Headers | show |
On 01/02/2017 09:44 AM, Igor Mammedov wrote: s/repporting/reporting/ in the subject > Do it by adding 'id' property to hostmem backends and fetch it > in query-memdev from object directly. > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > --- > +++ b/qom/object_interfaces.c > @@ -4,6 +4,7 @@ > #include "qemu/module.h" > #include "qapi-visit.h" > #include "qapi/opts-visitor.h" > +#include "qapi/qmp/qstring.h" > > void user_creatable_complete(Object *obj, Error **errp) > { > @@ -35,7 +36,7 @@ bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp) > } > > Object *user_creatable_add_type(const char *type, const char *id, > - const QDict *qdict, > + QDict *qdict, > Visitor *v, Error **errp) > { > Object *obj; > @@ -62,6 +63,9 @@ Object *user_creatable_add_type(const char *type, const char *id, > > assert(qdict); > obj = object_new(type); > + if (object_property_find(obj, "id", NULL)) { > + qdict_put(qdict, "id", qstring_from_str(id)); > + } Wait. Isn't this going to inject an 'id' dict member to every use of user_creatable_add_type()? But not all QAPI structs contain an id member. Which means that you are now explicitly relying on the visitor to silently ignore garbage in the dictionary, rather than our desired goal of only validating if the dictionary exactly matches what the QAPI says it will match. I'm not sure if I like this hack, or if there is a better way to do things when using a strict (rather than relaxed) input visitor. > visit_start_struct(v, NULL, NULL, 0, &local_err); > if (local_err) { > goto out; >
On Tue, 3 Jan 2017 09:34:40 -0600 Eric Blake <eblake@redhat.com> wrote: > On 01/02/2017 09:44 AM, Igor Mammedov wrote: > > s/repporting/reporting/ in the subject > > > Do it by adding 'id' property to hostmem backends and fetch it > > in query-memdev from object directly. > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > --- > > > +++ b/qom/object_interfaces.c > > @@ -4,6 +4,7 @@ > > #include "qemu/module.h" > > #include "qapi-visit.h" > > #include "qapi/opts-visitor.h" > > +#include "qapi/qmp/qstring.h" > > > > void user_creatable_complete(Object *obj, Error **errp) > > { > > @@ -35,7 +36,7 @@ bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp) > > } > > > > Object *user_creatable_add_type(const char *type, const char *id, > > - const QDict *qdict, > > + QDict *qdict, > > Visitor *v, Error **errp) > > { > > Object *obj; > > @@ -62,6 +63,9 @@ Object *user_creatable_add_type(const char *type, const char *id, > > > > assert(qdict); > > obj = object_new(type); > > + if (object_property_find(obj, "id", NULL)) { > > + qdict_put(qdict, "id", qstring_from_str(id)); > > + } > > Wait. Isn't this going to inject an 'id' dict member to every use of > user_creatable_add_type()? But not all QAPI structs contain an id > member. it would 'inject' 'id' only for objects that have 'id' property. or more exactly it would restore 'id' that is deleted earlier from the same qdict. Look for qdict_del() usage in this file. This way it'd be able to process both kinds of objects that implement 'id' property and ones that don't. > Which means that you are now explicitly relying on the visitor > to silently ignore garbage in the dictionary, rather than our desired > goal of only validating if the dictionary exactly matches what the QAPI > says it will match. currently 'id' is mandatory, but not enforced by QAPI structs, for all objects created with -object/object_add as it's used for naming object in qom tree: object_property_add_child(object_get_objects_root(), id, obj, &local_err); > > I'm not sure if I like this hack, or if there is a better way to do > things when using a strict (rather than relaxed) input visitor. I'm not sure about a better way to do this. Currently we use 2 visitors: opts (for cli/hmp) and qobject_input for qmp path, which accept anything as target object could take different options. The only things we currently enforce in code is presence of implicit 'qom-type' property and 'id' property. The rest of properties are validated by object's property setters. > > > visit_start_struct(v, NULL, NULL, 0, &local_err); > > if (local_err) { > > goto out; > > >
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h index fdd7603..06cccd9 100644 --- a/include/qom/object_interfaces.h +++ b/include/qom/object_interfaces.h @@ -90,7 +90,7 @@ bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp); * Returns: the newly created object or NULL on error */ Object *user_creatable_add_type(const char *type, const char *id, - const QDict *qdict, + QDict *qdict, Visitor *v, Error **errp); /** diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index 678232a..ecae0cf 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -52,6 +52,7 @@ struct HostMemoryBackend { Object parent; /* protected */ + char *id; uint64_t size; bool merge, dump; bool prealloc, force_prealloc, is_mapped; diff --git a/backends/hostmem.c b/backends/hostmem.c index 4256d24..7f5de70 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -348,6 +348,24 @@ host_memory_backend_can_be_deleted(UserCreatable *uc, Error **errp) } } +static char *get_id(Object *o, Error **errp) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(o); + + return g_strdup(backend->id); +} + +static void set_id(Object *o, const char *str, Error **errp) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(o); + + if (backend->id) { + error_setg(errp, "cannot change property value"); + return; + } + backend->id = g_strdup(str); +} + static void host_memory_backend_class_init(ObjectClass *oc, void *data) { @@ -377,6 +395,13 @@ host_memory_backend_class_init(ObjectClass *oc, void *data) HostMemPolicy_lookup, host_memory_backend_get_policy, host_memory_backend_set_policy, &error_abort); + object_class_property_add_str(oc, "id", get_id, set_id, &error_abort); +} + +static void host_memory_backend_finalize(Object *o) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(o); + g_free(backend->id); } static const TypeInfo host_memory_backend_info = { @@ -387,6 +412,7 @@ static const TypeInfo host_memory_backend_info = { .class_init = host_memory_backend_class_init, .instance_size = sizeof(HostMemoryBackend), .instance_init = host_memory_backend_init, + .instance_finalize = host_memory_backend_finalize, .interfaces = (InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } diff --git a/docs/qmp-commands.txt b/docs/qmp-commands.txt index abf210a..18db4cd 100644 --- a/docs/qmp-commands.txt +++ b/docs/qmp-commands.txt @@ -3529,6 +3529,7 @@ Example (1): "policy": "bind" }, { + "id": "mem1", "size": 536870912, "merge": false, "dump": true, diff --git a/hmp.c b/hmp.c index e7bead5..8522efe 100644 --- a/hmp.c +++ b/hmp.c @@ -2078,13 +2078,11 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) MemdevList *m = memdev_list; Visitor *v; char *str; - int i = 0; - while (m) { v = string_output_visitor_new(false, &str); visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL); - monitor_printf(mon, "memory backend: %d\n", i); + monitor_printf(mon, "memory backend: %s\n", m->value->id); monitor_printf(mon, " size: %" PRId64 "\n", m->value->size); monitor_printf(mon, " merge: %s\n", m->value->merge ? "true" : "false"); @@ -2100,7 +2098,6 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) g_free(str); visit_free(v); m = m->next; - i++; } monitor_printf(mon, "\n"); diff --git a/numa.c b/numa.c index 9c09e45..f5fc7da 100644 --- a/numa.c +++ b/numa.c @@ -518,6 +518,9 @@ static int query_memdev(Object *obj, void *opaque) m->value = g_malloc0(sizeof(*m->value)); + m->value->id = object_property_get_str(obj, "id", NULL); + m->value->has_id = !!m->value->id; + m->value->size = object_property_get_int(obj, "size", &error_abort); m->value->merge = object_property_get_bool(obj, "merge", diff --git a/qapi-schema.json b/qapi-schema.json index a0d3b5d..88eb2b9 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4453,6 +4453,8 @@ # # Information about memory backend # +# @id: #optional backend's ID if backend has 'id' property (since 2.9) +# # @size: memory backend size # # @merge: enables or disables memory merge support @@ -4469,6 +4471,7 @@ ## { 'struct': 'Memdev', 'data': { + '*id': 'str', 'size': 'size', 'merge': 'bool', 'dump': 'bool', diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index 9b4155a..7a8f520 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -4,6 +4,7 @@ #include "qemu/module.h" #include "qapi-visit.h" #include "qapi/opts-visitor.h" +#include "qapi/qmp/qstring.h" void user_creatable_complete(Object *obj, Error **errp) { @@ -35,7 +36,7 @@ bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp) } Object *user_creatable_add_type(const char *type, const char *id, - const QDict *qdict, + QDict *qdict, Visitor *v, Error **errp) { Object *obj; @@ -62,6 +63,9 @@ Object *user_creatable_add_type(const char *type, const char *id, assert(qdict); obj = object_new(type); + if (object_property_find(obj, "id", NULL)) { + qdict_put(qdict, "id", qstring_from_str(id)); + } visit_start_struct(v, NULL, NULL, 0, &local_err); if (local_err) { goto out;
Do it by adding 'id' property to hostmem backends and fetch it in query-memdev from object directly. Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- include/qom/object_interfaces.h | 2 +- include/sysemu/hostmem.h | 1 + backends/hostmem.c | 26 ++++++++++++++++++++++++++ docs/qmp-commands.txt | 1 + hmp.c | 5 +---- numa.c | 3 +++ qapi-schema.json | 3 +++ qom/object_interfaces.c | 6 +++++- 8 files changed, 41 insertions(+), 6 deletions(-)