diff mbox

[3/3] fix qmp/hmp query-memdev not repporting IDs of memory backends

Message ID 1483371890-289981-4-git-send-email-imammedo@redhat.com
State New
Headers show

Commit Message

Igor Mammedov Jan. 2, 2017, 3:44 p.m. UTC
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(-)

Comments

Eric Blake Jan. 3, 2017, 3:34 p.m. UTC | #1
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;
>
Igor Mammedov Jan. 3, 2017, 5:19 p.m. UTC | #2
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 mbox

Patch

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;