[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 01/21] monitor: Drop broken, unused asynchronous comm
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PULL 01/21] monitor: Drop broken, unused asynchronous command interface |
Date: |
Tue, 2 Jun 2015 10:23:39 +0200 |
The asynchronous monitor command interface goes back to commit 940cc30
(Jan 2010). Added a third case to command execution. The hope back
then according to the commit message was that all commands get
converted to the asynchronous interface, killing off the other two
cases. Didn't happen.
The initial asynchronous commands balloon and info balloon were
converted back to synchronous long ago (commit 96637bc and d72f32),
with commit messages calling the asynchronous interface "not fully
working" and "deprecated". The only other user went away in commit
3b5704b.
New code generally uses synchronous commands and asynchronous events.
What exactly is still "not fully working" with asynchronous commands?
Well, here's a bug that defeats actual asynchronous use pretty
reliably: the reply's ID is wrong (and has always been wrong) unless
you use the command synchronously! To reproduce, we need an
asynchronous command, so we have to go back before commit 3b5704b.
Run QEMU with spice:
$ qemu-system-x86_64 -nodefaults -S -spice port=5900,disable-ticketing -qmp
stdio
{"QMP": {"version": {"qemu": {"micro": 94, "minor": 2, "major": 2},
"package": ""}, "capabilities": []}}
Connect a spice client in another terminal:
$ remote-viewer spice://localhost:5900
Set up a migration destination dummy in a third terminal:
$ socat TCP-LISTEN:12345 STDIO
Now paste the following into the QMP monitor:
{ "execute": "qmp_capabilities", "id": "i0" }
{ "execute": "client_migrate_info", "id": "i1", "arguments": { "protocol":
"spice", "hostname": "localhost", "port": 12345 } }
{ "execute": "query-kvm", "id": "i2" }
Produces two replies immediately, one to qmp_capabilities, and one to
query-kvm:
{"return": {}, "id": "i0"}
{"return": {"enabled": false, "present": true}, "id": "i2"}
Both are correct. Two lines of debug output from libspice-server not
shown.
Now EOF socat's standard input to make it close the connection. This
makes the asynchronous client_migrate_info complete. It replies:
{"return": {}}
Bug: "id": "i1" is missing. Two lines of debug output from
libspice-server not shown. Cherry on top: storage for the missing ID
is leaked.
Get rid of this stuff before somebody hurts himself with it.
Signed-off-by: Markus Armbruster <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Reviewed-by: Luiz Capitulino <address@hidden>
---
include/monitor/monitor.h | 5 ----
monitor.c | 70 ++---------------------------------------------
2 files changed, 2 insertions(+), 73 deletions(-)
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index df67d56..d409b6a 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -16,9 +16,6 @@ extern Monitor *default_mon;
#define MONITOR_USE_CONTROL 0x04
#define MONITOR_USE_PRETTY 0x08
-/* flags for monitor commands */
-#define MONITOR_CMD_ASYNC 0x0001
-
int monitor_cur_is_qmp(void);
void monitor_init(CharDriverState *chr, int flags);
@@ -43,8 +40,6 @@ void monitor_flush(Monitor *mon);
int monitor_set_cpu(int cpu_index);
int monitor_get_cpu_index(void);
-typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
-
void monitor_set_error(Monitor *mon, QError *qerror);
void monitor_read_command(Monitor *mon, int show_prompt);
int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
diff --git a/monitor.c b/monitor.c
index b2561e1..27efeb6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -118,12 +118,6 @@
*
*/
-typedef struct MonitorCompletionData MonitorCompletionData;
-struct MonitorCompletionData {
- Monitor *mon;
- void (*user_print)(Monitor *mon, const QObject *data);
-};
-
typedef struct mon_cmd_t {
const char *name;
const char *args_type;
@@ -133,10 +127,7 @@ typedef struct mon_cmd_t {
union {
void (*cmd)(Monitor *mon, const QDict *qdict);
int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
- int (*cmd_async)(Monitor *mon, const QDict *params,
- MonitorCompletion *cb, void *opaque);
} mhandler;
- int flags;
/* @sub_table is a list of 2nd level of commands. If it do not exist,
* mhandler should be used. If it exist, sub_table[?].mhandler should be
* used, and mhandler of 1st level plays the role of help function.
@@ -394,11 +385,6 @@ static inline int handler_is_qobject(const mon_cmd_t *cmd)
return cmd->user_print != NULL;
}
-static inline bool handler_is_async(const mon_cmd_t *cmd)
-{
- return cmd->flags & MONITOR_CMD_ASYNC;
-}
-
static inline int monitor_has_error(const Monitor *mon)
{
return mon->error != NULL;
@@ -917,45 +903,6 @@ static void hmp_trace_file(Monitor *mon, const QDict
*qdict)
}
#endif
-static void user_monitor_complete(void *opaque, QObject *ret_data)
-{
- MonitorCompletionData *data = (MonitorCompletionData *)opaque;
-
- if (ret_data) {
- data->user_print(data->mon, ret_data);
- }
- monitor_resume(data->mon);
- g_free(data);
-}
-
-static void qmp_monitor_complete(void *opaque, QObject *ret_data)
-{
- monitor_protocol_emitter(opaque, ret_data);
-}
-
-static int qmp_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
- const QDict *params)
-{
- return cmd->mhandler.cmd_async(mon, params, qmp_monitor_complete, mon);
-}
-
-static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
- const QDict *params)
-{
- int ret;
-
- MonitorCompletionData *cb_data = g_malloc(sizeof(*cb_data));
- cb_data->mon = mon;
- cb_data->user_print = cmd->user_print;
- monitor_suspend(mon);
- ret = cmd->mhandler.cmd_async(mon, params,
- user_monitor_complete, cb_data);
- if (ret < 0) {
- monitor_resume(mon);
- g_free(cb_data);
- }
-}
-
static void hmp_info_help(Monitor *mon, const QDict *qdict)
{
help_cmd(mon, "info");
@@ -4121,9 +4068,7 @@ static void handle_user_command(Monitor *mon, const char
*cmdline)
if (!cmd)
goto out;
- if (handler_is_async(cmd)) {
- user_async_cmd_handler(mon, cmd, qdict);
- } else if (handler_is_qobject(cmd)) {
+ if (handler_is_qobject(cmd)) {
QObject *data = NULL;
/* XXX: ignores the error code */
@@ -5054,8 +4999,6 @@ static QDict *qmp_check_input_obj(QObject *input_obj)
"object");
return NULL;
}
- } else if (!strcmp(arg_name, "id")) {
- /* FIXME: check duplicated IDs for async commands */
} else {
qerror_report(QERR_QMP_EXTRA_MEMBER, arg_name);
return NULL;
@@ -5134,16 +5077,7 @@ static void handle_qmp_command(JSONMessageParser
*parser, QList *tokens)
goto err_out;
}
- if (handler_is_async(cmd)) {
- err = qmp_async_cmd_handler(mon, cmd, args);
- if (err) {
- /* emit the error response */
- goto err_out;
- }
- } else {
- qmp_call_cmd(mon, cmd, args);
- }
-
+ qmp_call_cmd(mon, cmd, args);
goto out;
err_out:
--
1.9.3
- [Qemu-devel] [PULL 08/21] monitor: Drop unused "new" HMP command interface, (continued)
- [Qemu-devel] [PULL 08/21] monitor: Drop unused "new" HMP command interface, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 11/21] monitor: Propagate errors through invalid_qmp_mode(), Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 02/21] monitor: Clean up after previous commit, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 12/21] monitor: Wean monitor_protocol_emitter() off mon->error, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 05/21] monitor: Use traditional command interface for HMP drive_del, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 06/21] monitor: Use traditional command interface for HMP device_add, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 09/21] monitor: Propagate errors through qmp_check_client_args(), Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 07/21] monitor: Use trad. command interface for HMP pcie_aer_inject_error, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 03/21] monitor: Improve and document client_migrate_info protocol error, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 04/21] monitor: Convert client_migrate_info to QAPI, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 01/21] monitor: Drop broken, unused asynchronous command interface,
Markus Armbruster <=
- [Qemu-devel] [PULL 13/21] monitor: Inline monitor_has_error() into its only caller, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 20/21] monitor: Rename monitor_ctrl_mode() to monitor_is_qmp(), Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 21/21] monitor: Change return type of monitor_cur_is_qmp() to bool, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 10/21] monitor: Propagate errors through qmp_check_input_obj(), Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 16/21] monitor: Rename monitor_control_read(), monitor_control_event(), Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 15/21] monitor: Rename handle_user_command() to handle_hmp_command(), Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 18/21] monitor: Drop do_qmp_capabilities()'s superfluous QMP check, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 19/21] monitor: Turn int command_mode into bool in_command_mode, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 17/21] monitor: Unbox Monitor member mc and rename to qmp, Markus Armbruster, 2015/06/02
- [Qemu-devel] [PULL 14/21] monitor: Limit QError use to command handlers, Markus Armbruster, 2015/06/02