diff mbox series

[1/2] hmp: Implement qom-get HMP command

Message ID 20200520151108.160598-2-dgilbert@redhat.com
State New
Headers show
Series [1/2] hmp: Implement qom-get HMP command | expand

Commit Message

Dr. David Alan Gilbert May 20, 2020, 3:11 p.m. UTC
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

This started off as Andreas Färber's implementation from
March 2015, but after feedback from Paolo and Markus it morphed into
using the json output which handles structs reasonably.

Use with qom-list to find the members of an object.

(qemu) qom-get /backend/console[0]/device/vga.rom[0] size
65536
(qemu) qom-get /machine smm
"auto"
(qemu) qom-get /machine rtc-time
{
    "tm_year": 120,
    "tm_sec": 51,
    "tm_hour": 9,
    "tm_min": 50,
    "tm_mon": 4,
    "tm_mday": 20
}
(qemu) qom-get /machine frob
Error: Property '.frob' not found

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 hmp-commands.hx        | 14 ++++++++++++++
 include/monitor/hmp.h  |  1 +
 qom/qom-hmp-cmds.c     | 18 ++++++++++++++++++
 tests/qtest/test-hmp.c |  1 +
 4 files changed, 34 insertions(+)

Comments

Philippe Mathieu-Daudé May 20, 2020, 4:44 p.m. UTC | #1
On 5/20/20 5:11 PM, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> 
> This started off as Andreas Färber's implementation from
> March 2015, but after feedback from Paolo and Markus it morphed into
> using the json output which handles structs reasonably.
> 
> Use with qom-list to find the members of an object.
> 
> (qemu) qom-get /backend/console[0]/device/vga.rom[0] size
> 65536
> (qemu) qom-get /machine smm
> "auto"
> (qemu) qom-get /machine rtc-time
> {
>      "tm_year": 120,
>      "tm_sec": 51,
>      "tm_hour": 9,
>      "tm_min": 50,
>      "tm_mon": 4,
>      "tm_mday": 20
> }
> (qemu) qom-get /machine frob
> Error: Property '.frob' not found
> 
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
>   hmp-commands.hx        | 14 ++++++++++++++
>   include/monitor/hmp.h  |  1 +
>   qom/qom-hmp-cmds.c     | 18 ++++++++++++++++++
>   tests/qtest/test-hmp.c |  1 +
>   4 files changed, 34 insertions(+)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 7f0f3974ad..250ddae54d 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1790,6 +1790,20 @@ SRST
>     Print QOM properties of object at location *path*
>   ERST
>   
> +    {
> +        .name       = "qom-get",
> +        .args_type  = "path:s,property:s",
> +        .params     = "path property",
> +        .help       = "print QOM property",
> +        .cmd        = hmp_qom_get,
> +        .flags      = "p",
> +    },
> +
> +SRST
> +``qom-get`` *path* *property*
> +  Print QOM property *property* of object at location *path*
> +ERST
> +
>       {
>           .name       = "qom-set",
>           .args_type  = "path:s,property:s,value:s",
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index e33ca5a911..c986cfd28b 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -96,6 +96,7 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict);
>   void hmp_info_numa(Monitor *mon, const QDict *qdict);
>   void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
>   void hmp_qom_list(Monitor *mon, const QDict *qdict);
> +void hmp_qom_get(Monitor *mon, const QDict *qdict);
>   void hmp_qom_set(Monitor *mon, const QDict *qdict);
>   void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
>   void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
> diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
> index cd08233a4c..a8b0a080c7 100644
> --- a/qom/qom-hmp-cmds.c
> +++ b/qom/qom-hmp-cmds.c
> @@ -12,6 +12,8 @@
>   #include "qapi/error.h"
>   #include "qapi/qapi-commands-qom.h"
>   #include "qapi/qmp/qdict.h"
> +#include "qapi/qmp/qjson.h"
> +#include "qapi/qmp/qstring.h"
>   #include "qom/object.h"
>   
>   void hmp_qom_list(Monitor *mon, const QDict *qdict)
> @@ -62,6 +64,22 @@ void hmp_qom_set(Monitor *mon, const QDict *qdict)
>       hmp_handle_error(mon, err);
>   }
>   
> +void hmp_qom_get(Monitor *mon, const QDict *qdict)
> +{
> +    const char *path = qdict_get_str(qdict, "path");
> +    const char *property = qdict_get_str(qdict, "property");
> +    Error *err = NULL;
> +    QObject *obj = qmp_qom_get(path, property, &err);
> +
> +    if (err == NULL) {
> +        QString *str = qobject_to_json_pretty(obj);
> +        monitor_printf(mon, "%s\n", qstring_get_str(str));
> +        qobject_unref(str);

Simple, does the job, lovely!

> +    }
> +
> +    hmp_handle_error(mon, err);
> +}
> +
>   typedef struct QOMCompositionState {
>       Monitor *mon;
>       int indent;
> diff --git a/tests/qtest/test-hmp.c b/tests/qtest/test-hmp.c
> index f8aa5f92c5..b8b1271b9e 100644
> --- a/tests/qtest/test-hmp.c
> +++ b/tests/qtest/test-hmp.c
> @@ -61,6 +61,7 @@ static const char *hmp_cmds[] = {
>       "p $pc + 8",
>       "qom-list /",
>       "qom-set /machine initrd test",
> +    "qom-get /machine initrd",
>       "screendump /dev/null",
>       "sendkey x",
>       "singlestep on",
> 

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Markus Armbruster May 25, 2020, 9:02 a.m. UTC | #2
"Dr. David Alan Gilbert (git)" <dgilbert@redhat.com> writes:

> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> This started off as Andreas Färber's implementation from
> March 2015, but after feedback from Paolo and Markus it morphed into
> using the json output which handles structs reasonably.
>
> Use with qom-list to find the members of an object.
>
> (qemu) qom-get /backend/console[0]/device/vga.rom[0] size
> 65536
> (qemu) qom-get /machine smm
> "auto"
> (qemu) qom-get /machine rtc-time
> {
>     "tm_year": 120,
>     "tm_sec": 51,
>     "tm_hour": 9,
>     "tm_min": 50,
>     "tm_mon": 4,
>     "tm_mday": 20
> }
> (qemu) qom-get /machine frob
> Error: Property '.frob' not found

  (qemu) qom-get /machine peripheral
  "/machine/peripheral"

Not this patch's fault, but WTF?

Turns out it's simply what object_get_child_property() does.

Paolo, is this what we want for qom-get?

Also not this patch's fault: separating path and property feels like a
pointless complication of the interface to me.  Why

    {"execute": "qom-get", "arguments": {"path": "/machine", "property": "smm"}}

and not

    {"execute": "qom-get", "arguments": {"path": "/machine/smm"}}

?

Too late to change for QMP, I guess.
Markus Armbruster May 29, 2020, 6:59 a.m. UTC | #3
Markus Armbruster <armbru@redhat.com> writes:

> "Dr. David Alan Gilbert (git)" <dgilbert@redhat.com> writes:
>
>> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>>
>> This started off as Andreas Färber's implementation from
>> March 2015, but after feedback from Paolo and Markus it morphed into
>> using the json output which handles structs reasonably.
>>
>> Use with qom-list to find the members of an object.
>>
>> (qemu) qom-get /backend/console[0]/device/vga.rom[0] size
>> 65536
>> (qemu) qom-get /machine smm
>> "auto"
>> (qemu) qom-get /machine rtc-time
>> {
>>     "tm_year": 120,
>>     "tm_sec": 51,
>>     "tm_hour": 9,
>>     "tm_min": 50,
>>     "tm_mon": 4,
>>     "tm_mday": 20
>> }
>> (qemu) qom-get /machine frob
>> Error: Property '.frob' not found
>
>   (qemu) qom-get /machine peripheral
>   "/machine/peripheral"
>
> Not this patch's fault, but WTF?

Because it's not this patch's fault (QMP behaves the same way), we
shouldn't let it block the patch, so
Reviewed-by: Markus Armbruster <armbru@redhat.com>

I just sent

    Subject: QMP qom-get feels useless for child properties
    Date: Fri, 29 May 2020 08:57:11 +0200
    Message-ID: <87lflbns8o.fsf@dusky.pond.sub.org>

[...]
diff mbox series

Patch

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 7f0f3974ad..250ddae54d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1790,6 +1790,20 @@  SRST
   Print QOM properties of object at location *path*
 ERST
 
+    {
+        .name       = "qom-get",
+        .args_type  = "path:s,property:s",
+        .params     = "path property",
+        .help       = "print QOM property",
+        .cmd        = hmp_qom_get,
+        .flags      = "p",
+    },
+
+SRST
+``qom-get`` *path* *property*
+  Print QOM property *property* of object at location *path*
+ERST
+
     {
         .name       = "qom-set",
         .args_type  = "path:s,property:s,value:s",
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index e33ca5a911..c986cfd28b 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -96,6 +96,7 @@  void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 void hmp_info_numa(Monitor *mon, const QDict *qdict);
 void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
 void hmp_qom_list(Monitor *mon, const QDict *qdict);
+void hmp_qom_get(Monitor *mon, const QDict *qdict);
 void hmp_qom_set(Monitor *mon, const QDict *qdict);
 void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
index cd08233a4c..a8b0a080c7 100644
--- a/qom/qom-hmp-cmds.c
+++ b/qom/qom-hmp-cmds.c
@@ -12,6 +12,8 @@ 
 #include "qapi/error.h"
 #include "qapi/qapi-commands-qom.h"
 #include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qstring.h"
 #include "qom/object.h"
 
 void hmp_qom_list(Monitor *mon, const QDict *qdict)
@@ -62,6 +64,22 @@  void hmp_qom_set(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
+void hmp_qom_get(Monitor *mon, const QDict *qdict)
+{
+    const char *path = qdict_get_str(qdict, "path");
+    const char *property = qdict_get_str(qdict, "property");
+    Error *err = NULL;
+    QObject *obj = qmp_qom_get(path, property, &err);
+
+    if (err == NULL) {
+        QString *str = qobject_to_json_pretty(obj);
+        monitor_printf(mon, "%s\n", qstring_get_str(str));
+        qobject_unref(str);
+    }
+
+    hmp_handle_error(mon, err);
+}
+
 typedef struct QOMCompositionState {
     Monitor *mon;
     int indent;
diff --git a/tests/qtest/test-hmp.c b/tests/qtest/test-hmp.c
index f8aa5f92c5..b8b1271b9e 100644
--- a/tests/qtest/test-hmp.c
+++ b/tests/qtest/test-hmp.c
@@ -61,6 +61,7 @@  static const char *hmp_cmds[] = {
     "p $pc + 8",
     "qom-list /",
     "qom-set /machine initrd test",
+    "qom-get /machine initrd",
     "screendump /dev/null",
     "sendkey x",
     "singlestep on",