[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 2/3] monitor: Allow passing HMP arguments to QMP HumanReadabl
From: |
Philippe Mathieu-Daudé |
Subject: |
[RFC PATCH 2/3] monitor: Allow passing HMP arguments to QMP HumanReadableText API |
Date: |
Mon, 10 Jun 2024 19:58:51 +0200 |
Allow HMP commands implemented using the HumanReadableText API
(via the HMPCommand::cmd_info_hrt handler) to pass arguments
to the QMP equivalent command. The arguments are serialized as
a JSON dictionary.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
docs/devel/writing-monitor-commands.rst | 15 ++++++++++++++-
qapi/machine.json | 24 ++++++++++++++++++++++++
include/monitor/monitor.h | 3 ++-
monitor/monitor-internal.h | 2 +-
accel/tcg/monitor.c | 4 ++--
hw/core/loader.c | 2 +-
hw/core/machine-qmp-cmds.c | 9 +++++----
hw/usb/bus.c | 2 +-
monitor/hmp-target.c | 3 ++-
monitor/hmp.c | 11 +++++++----
10 files changed, 59 insertions(+), 16 deletions(-)
diff --git a/docs/devel/writing-monitor-commands.rst
b/docs/devel/writing-monitor-commands.rst
index 930da5cd06..843458e52c 100644
--- a/docs/devel/writing-monitor-commands.rst
+++ b/docs/devel/writing-monitor-commands.rst
@@ -561,6 +561,7 @@ returns a ``HumanReadableText``::
# Since: 6.2
##
{ 'command': 'x-query-roms',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'features': [ 'unstable' ] }
@@ -578,7 +579,7 @@ Implementing the QMP command
The QMP implementation will typically involve creating a ``GString``
object and printing formatted data into it, like this::
- HumanReadableText *qmp_x_query_roms(Error **errp)
+ HumanReadableText *qmp_x_query_roms(const char *json_args, Error **errp)
{
g_autoptr(GString) buf = g_string_new("");
Rom *rom;
@@ -596,6 +597,18 @@ object and printing formatted data into it, like this::
The actual implementation emits more information. You can find it in
hw/core/loader.c.
+For QMP command taking (optional) parameters, these parameters are
+serialized as a JSON dictionary, and can be retrieved using the QDict
+API. If the previous ``x-query-roms`` command were taking a "index"
+argument, it could be retrieved as::
+
+ HumanReadableText *qmp_x_query_roms(const char *json_args, Error **errp)
+ {
+ g_autoptr(GString) buf = g_string_new("");
+ QDict *qdict = qobject_to(QDict, qobject_from_json(json_args,
&error_abort));
+ uint64_t index = qdict_get_int(qdict, "index");
+ ...
+ }
Implementing the HMP command
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/qapi/machine.json b/qapi/machine.json
index 1283d14493..6da72f2585 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1697,6 +1697,8 @@
#
# Query interrupt statistics
#
+# @json-args: HMP arguments encoded as JSON string (unused for this command).
+#
# Features:
#
# @unstable: This command is meant for debugging.
@@ -1706,6 +1708,7 @@
# Since: 6.2
##
{ 'command': 'x-query-irq',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'features': [ 'unstable' ] }
@@ -1714,6 +1717,8 @@
#
# Query TCG compiler statistics
#
+# @json-args: HMP arguments encoded as JSON string (unused for this command).
+#
# Features:
#
# @unstable: This command is meant for debugging.
@@ -1723,6 +1728,7 @@
# Since: 6.2
##
{ 'command': 'x-query-jit',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'if': 'CONFIG_TCG',
'features': [ 'unstable' ] }
@@ -1732,6 +1738,8 @@
#
# Query NUMA topology information
#
+# @json-args: HMP arguments encoded as JSON string (unused for this command).
+#
# Features:
#
# @unstable: This command is meant for debugging.
@@ -1741,6 +1749,7 @@
# Since: 6.2
##
{ 'command': 'x-query-numa',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'features': [ 'unstable' ] }
@@ -1749,6 +1758,8 @@
#
# Query TCG opcode counters
#
+# @json-args: HMP arguments encoded as JSON string (unused for this command).
+#
# Features:
#
# @unstable: This command is meant for debugging.
@@ -1758,6 +1769,7 @@
# Since: 6.2
##
{ 'command': 'x-query-opcount',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'if': 'CONFIG_TCG',
'features': [ 'unstable' ] }
@@ -1767,6 +1779,8 @@
#
# Query system ramblock information
#
+# @json-args: HMP arguments encoded as JSON string (unused for this command).
+#
# Features:
#
# @unstable: This command is meant for debugging.
@@ -1776,6 +1790,7 @@
# Since: 6.2
##
{ 'command': 'x-query-ramblock',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'features': [ 'unstable' ] }
@@ -1784,6 +1799,8 @@
#
# Query information on the registered ROMS
#
+# @json-args: HMP arguments encoded as JSON string (unused for this command).
+#
# Features:
#
# @unstable: This command is meant for debugging.
@@ -1793,6 +1810,7 @@
# Since: 6.2
##
{ 'command': 'x-query-roms',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'features': [ 'unstable' ] }
@@ -1801,6 +1819,8 @@
#
# Query information on the USB devices
#
+# @json-args: HMP arguments encoded as JSON string (unused for this command).
+#
# Features:
#
# @unstable: This command is meant for debugging.
@@ -1810,6 +1830,7 @@
# Since: 6.2
##
{ 'command': 'x-query-usb',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'features': [ 'unstable' ] }
@@ -1870,6 +1891,8 @@
#
# Query information on interrupt controller devices
#
+# @json-args: HMP arguments encoded as JSON string (unused for this command).
+#
# Features:
#
# @unstable: This command is meant for debugging.
@@ -1879,5 +1902,6 @@
# Since: 9.1
##
{ 'command': 'x-query-interrupt-controllers',
+ 'data': { 'json-args': 'str'},
'returns': 'HumanReadableText',
'features': [ 'unstable' ]}
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 965f5d5450..b21c702c12 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -58,7 +58,8 @@ int64_t monitor_fdset_dup_fd_find(int dup_fd);
void monitor_register_hmp(const char *name, bool info,
void (*cmd)(Monitor *mon, const QDict *qdict));
void monitor_register_hmp_info_hrt(const char *name,
- HumanReadableText *(*handler)(Error
**errp));
+ HumanReadableText *(*handler)(const char
*json_args,
+ Error
**errp));
int error_vprintf_unless_qmp(const char *fmt, va_list ap) G_GNUC_PRINTF(1, 0);
int error_printf_unless_qmp(const char *fmt, ...) G_GNUC_PRINTF(1, 2);
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index 252de85681..b3aa50834b 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -81,7 +81,7 @@ typedef struct HMPCommand {
* @cmd_info_hrt to the corresponding QMP handler that returns
* the formatted text.
*/
- HumanReadableText *(*cmd_info_hrt)(Error **errp);
+ HumanReadableText *(*cmd_info_hrt)(const char *json_args, Error **errp);
bool coroutine;
/*
* @sub_table is a list of 2nd level of commands. If it does not exist,
diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
index 093efe9714..517c96eeb7 100644
--- a/accel/tcg/monitor.c
+++ b/accel/tcg/monitor.c
@@ -199,7 +199,7 @@ static void dump_exec_info(GString *buf)
tcg_dump_info(buf);
}
-HumanReadableText *qmp_x_query_jit(Error **errp)
+HumanReadableText *qmp_x_query_jit(const char *json_args, Error **errp)
{
g_autoptr(GString) buf = g_string_new("");
@@ -220,7 +220,7 @@ static void tcg_dump_op_count(GString *buf)
g_string_append_printf(buf, "[TCG profiler not compiled]\n");
}
-HumanReadableText *qmp_x_query_opcount(Error **errp)
+HumanReadableText *qmp_x_query_opcount(const char *json_args, Error **errp)
{
g_autoptr(GString) buf = g_string_new("");
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 2f8105d7de..e0da5edbb3 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1679,7 +1679,7 @@ void *rom_ptr_for_as(AddressSpace *as, hwaddr addr,
size_t size)
return cbdata.rom;
}
-HumanReadableText *qmp_x_query_roms(Error **errp)
+HumanReadableText *qmp_x_query_roms(const char *json_args, Error **errp)
{
Rom *rom;
g_autoptr(GString) buf = g_string_new("");
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 130217da8f..fc79772df8 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -214,7 +214,7 @@ MemdevList *qmp_query_memdev(Error **errp)
return list;
}
-HumanReadableText *qmp_x_query_numa(Error **errp)
+HumanReadableText *qmp_x_query_numa(const char *json_args, Error **errp)
{
g_autoptr(GString) buf = g_string_new("");
int i, nb_numa_nodes;
@@ -311,7 +311,7 @@ MemoryInfo *qmp_query_memory_size_summary(Error **errp)
return mem_info;
}
-HumanReadableText *qmp_x_query_ramblock(Error **errp)
+HumanReadableText *qmp_x_query_ramblock(const char *json_args, Error **errp)
{
g_autoptr(GString) buf = ram_block_format();
@@ -351,7 +351,7 @@ static int qmp_x_query_irq_foreach(Object *obj, void
*opaque)
return 0;
}
-HumanReadableText *qmp_x_query_irq(Error **errp)
+HumanReadableText *qmp_x_query_irq(const char *json_args, Error **errp)
{
g_autoptr(GString) buf = g_string_new("");
@@ -382,7 +382,8 @@ static int qmp_x_query_intc_foreach(Object *obj, void
*opaque)
return 0;
}
-HumanReadableText *qmp_x_query_interrupt_controllers(Error **errp)
+HumanReadableText *qmp_x_query_interrupt_controllers(const char *json_args,
+ Error **errp)
{
g_autoptr(GString) buf = g_string_new("");
object_child_foreach_recursive(object_get_root(),
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index bfab2807d7..daa3f71d47 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -598,7 +598,7 @@ static char *usb_get_fw_dev_path(DeviceState *qdev)
return fw_path;
}
-HumanReadableText *qmp_x_query_usb(Error **errp)
+HumanReadableText *qmp_x_query_usb(const char *json_args, Error **errp)
{
g_autoptr(GString) buf = g_string_new("");
USBBus *bus;
diff --git a/monitor/hmp-target.c b/monitor/hmp-target.c
index 0466474354..81e53a5767 100644
--- a/monitor/hmp-target.c
+++ b/monitor/hmp-target.c
@@ -157,7 +157,8 @@ void monitor_register_hmp(const char *name, bool info,
}
void monitor_register_hmp_info_hrt(const char *name,
- HumanReadableText *(*handler)(Error **errp))
+ HumanReadableText *(*handler)(const char
*json_args,
+ Error **errp))
{
HMPCommand *table = hmp_info_cmds;
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 69c1b7e98a..7802a31412 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -29,6 +29,7 @@
#include "monitor/hmp.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qnum.h"
+#include "qapi/qmp/qjson.h"
#include "qemu/config-file.h"
#include "qemu/ctype.h"
#include "qemu/cutils.h"
@@ -1082,11 +1083,13 @@ fail:
return NULL;
}
-static void hmp_info_human_readable_text(Monitor *mon,
- HumanReadableText *(*handler)(Error
**))
+static void hmp_info_human_readable_text(Monitor *mon, QDict *qdict,
+ HumanReadableText *(*handler)(const
char *,
+ Error
**))
{
Error *err = NULL;
- g_autoptr(HumanReadableText) info = handler(&err);
+ g_autoptr(GString) ret_json = qobject_to_json(QOBJECT(qdict));
+ g_autoptr(HumanReadableText) info = handler(ret_json->str, &err);
if (hmp_handle_error(mon, err)) {
return;
@@ -1100,7 +1103,7 @@ static void handle_hmp_command_exec(Monitor *mon,
QDict *qdict)
{
if (cmd->cmd_info_hrt) {
- hmp_info_human_readable_text(mon,
+ hmp_info_human_readable_text(mon, qdict,
cmd->cmd_info_hrt);
} else {
cmd->cmd(mon, qdict);
--
2.41.0