From 212b6008686369b288a2b71e4f1b25f07d854763 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Mon, 7 Jun 2010 15:42:14 +0100 Subject: [PATCH 01/23] Add support for JSON pretty printing The monitor does not pretty-print JSON output, so that everything will be on a single line reply. When JSON docs get large this is quite unpleasant to read. For the future command line capabilities query ability, huge JSON docs will be available. This needs the ability to pretty-print. This introduces a new API qobject_to_json_pretty() that does a minimal indentation of list and dict members. As an example, this makes {"QMP": {"version": {"micro": 50, "minor": 12, "package": "", "major": 0}, "capabilities": []}} Output as { "QMP": { "version": { "micro": 50, "minor": 12, "package": "", "major": 0 }, "capabilities": [ ] } } NB: this is not turned on for the QMP monitor. Signed-off-by: Daniel P. Berrange Signed-off-by: Luiz Capitulino --- qjson.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-------- qjson.h | 1 + 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/qjson.c b/qjson.c index e4ee433760..f9c8e77516 100644 --- a/qjson.c +++ b/qjson.c @@ -72,43 +72,57 @@ QObject *qobject_from_jsonf(const char *string, ...) typedef struct ToJsonIterState { + int indent; + int pretty; int count; QString *str; } ToJsonIterState; -static void to_json(const QObject *obj, QString *str); +static void to_json(const QObject *obj, QString *str, int pretty, int indent); static void to_json_dict_iter(const char *key, QObject *obj, void *opaque) { ToJsonIterState *s = opaque; QString *qkey; + int j; - if (s->count) { + if (s->count) qstring_append(s->str, ", "); + + if (s->pretty) { + qstring_append(s->str, "\n"); + for (j = 0 ; j < s->indent ; j++) + qstring_append(s->str, " "); } qkey = qstring_from_str(key); - to_json(QOBJECT(qkey), s->str); + to_json(QOBJECT(qkey), s->str, s->pretty, s->indent); QDECREF(qkey); qstring_append(s->str, ": "); - to_json(obj, s->str); + to_json(obj, s->str, s->pretty, s->indent); s->count++; } static void to_json_list_iter(QObject *obj, void *opaque) { ToJsonIterState *s = opaque; + int j; - if (s->count) { + if (s->count) qstring_append(s->str, ", "); + + if (s->pretty) { + qstring_append(s->str, "\n"); + for (j = 0 ; j < s->indent ; j++) + qstring_append(s->str, " "); } - to_json(obj, s->str); + to_json(obj, s->str, s->pretty, s->indent); s->count++; } -static void to_json(const QObject *obj, QString *str) +static void to_json(const QObject *obj, QString *str, int pretty, int indent) { switch (qobject_type(obj)) { case QTYPE_QINT: { @@ -193,8 +207,16 @@ static void to_json(const QObject *obj, QString *str) s.count = 0; s.str = str; + s.indent = indent + 1; + s.pretty = pretty; qstring_append(str, "{"); qdict_iter(val, to_json_dict_iter, &s); + if (pretty) { + int j; + qstring_append(str, "\n"); + for (j = 0 ; j < indent ; j++) + qstring_append(str, " "); + } qstring_append(str, "}"); break; } @@ -204,8 +226,16 @@ static void to_json(const QObject *obj, QString *str) s.count = 0; s.str = str; + s.indent = indent + 1; + s.pretty = pretty; qstring_append(str, "["); qlist_iter(val, (void *)to_json_list_iter, &s); + if (pretty) { + int j; + qstring_append(str, "\n"); + for (j = 0 ; j < indent ; j++) + qstring_append(str, " "); + } qstring_append(str, "]"); break; } @@ -249,7 +279,16 @@ QString *qobject_to_json(const QObject *obj) { QString *str = qstring_new(); - to_json(obj, str); + to_json(obj, str, 0, 0); + + return str; +} + +QString *qobject_to_json_pretty(const QObject *obj) +{ + QString *str = qstring_new(); + + to_json(obj, str, 1, 0); return str; } diff --git a/qjson.h b/qjson.h index 7afec2eec1..cd60e0bbe5 100644 --- a/qjson.h +++ b/qjson.h @@ -24,5 +24,6 @@ QObject *qobject_from_jsonf(const char *string, ...) QObject *qobject_from_jsonv(const char *string, va_list *ap); QString *qobject_to_json(const QObject *obj); +QString *qobject_to_json_pretty(const QObject *obj); #endif /* QJSON_H */ From 39eaab9ac2a82f5370758e8aeb8b7196f34fdabf Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Mon, 7 Jun 2010 15:42:31 +0100 Subject: [PATCH 02/23] Add option to turn on JSON pretty printing in monitor Expaned '-mon' arg to allow a 'pretty=on' flag. This makes the monitor pretty print its replies to easy human debugging / reading Signed-off-by: Daniel P. Berrange Signed-off-by: Luiz Capitulino --- monitor.c | 5 ++++- monitor.h | 1 + qemu-config.c | 3 +++ vl.c | 3 +++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/monitor.c b/monitor.c index e602480ebb..a33cdc2a00 100644 --- a/monitor.c +++ b/monitor.c @@ -351,7 +351,10 @@ static void monitor_json_emitter(Monitor *mon, const QObject *data) { QString *json; - json = qobject_to_json(data); + if (mon->flags & MONITOR_USE_PRETTY) + json = qobject_to_json_pretty(data); + else + json = qobject_to_json(data); assert(json != NULL); qstring_append_chr(json, '\n'); diff --git a/monitor.h b/monitor.h index 38b22a4b28..f2122b5884 100644 --- a/monitor.h +++ b/monitor.h @@ -14,6 +14,7 @@ extern Monitor *default_mon; #define MONITOR_IS_DEFAULT 0x01 #define MONITOR_USE_READLINE 0x02 #define MONITOR_USE_CONTROL 0x04 +#define MONITOR_USE_PRETTY 0x08 /* flags for monitor commands */ #define MONITOR_CMD_ASYNC 0x0001 diff --git a/qemu-config.c b/qemu-config.c index e3b746cc2b..6052a289e9 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -283,6 +283,9 @@ static QemuOptsList qemu_mon_opts = { },{ .name = "default", .type = QEMU_OPT_BOOL, + },{ + .name = "pretty", + .type = QEMU_OPT_BOOL, }, { /* end of list */ } }, diff --git a/vl.c b/vl.c index d352d18cfe..939ee87b66 100644 --- a/vl.c +++ b/vl.c @@ -1562,6 +1562,9 @@ static int mon_init_func(QemuOpts *opts, void *opaque) exit(1); } + if (qemu_opt_get_bool(opts, "pretty", 0)) + flags |= MONITOR_USE_PRETTY; + if (qemu_opt_get_bool(opts, "default", 0)) flags |= MONITOR_IS_DEFAULT; From 07b0403dfc2b2ac179ae5b48105096cc2d03375a Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Tue, 14 Sep 2010 13:43:39 -0300 Subject: [PATCH 03/23] disable guest-provided stats on "info balloon" command The addition of memory stats reporting to the virtio balloon causes the 'info balloon' command to become asynchronous. This is a regression because in some cases it can hang the user monitor. This is an alternative to Adam Litke's patch. Adam's patch disabled the corresponding (guest-visible) virtio feature bit, causing issues for migration. Original discussion is available at: http://marc.info/?l=qemu-devel&m=128448124328314&w=2 Signed-off-by: Eduardo Habkost Acked-by: Adam Litke --- hw/virtio-balloon.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c index 1e746741ff..8adddeaa53 100644 --- a/hw/virtio-balloon.c +++ b/hw/virtio-balloon.c @@ -29,6 +29,10 @@ #include #endif +/* Disable guest-provided stats by now (https://bugzilla.redhat.com/show_bug.cgi?id=623903) */ +#define ENABLE_GUEST_STATS 0 + + typedef struct VirtIOBalloon { VirtIODevice vdev; @@ -83,12 +87,14 @@ static QObject *get_stats_qobject(VirtIOBalloon *dev) VIRTIO_BALLOON_PFN_SHIFT); stat_put(dict, "actual", actual); +#if ENABLE_GUEST_STATS stat_put(dict, "mem_swapped_in", dev->stats[VIRTIO_BALLOON_S_SWAP_IN]); stat_put(dict, "mem_swapped_out", dev->stats[VIRTIO_BALLOON_S_SWAP_OUT]); stat_put(dict, "major_page_faults", dev->stats[VIRTIO_BALLOON_S_MAJFLT]); stat_put(dict, "minor_page_faults", dev->stats[VIRTIO_BALLOON_S_MINFLT]); stat_put(dict, "free_mem", dev->stats[VIRTIO_BALLOON_S_MEMFREE]); stat_put(dict, "total_mem", dev->stats[VIRTIO_BALLOON_S_MEMTOT]); +#endif return QOBJECT(dict); } @@ -214,7 +220,7 @@ static void virtio_balloon_to_target(void *opaque, ram_addr_t target, } dev->stats_callback = cb; dev->stats_opaque_callback_data = cb_data; - if (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ)) { + if (ENABLE_GUEST_STATS && (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ))) { virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset); virtio_notify(&dev->vdev, dev->svq); } else { From 945c5ac8d3c792bab36dc0990f11ca55f6eb3148 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Mon, 13 Sep 2010 13:17:58 -0300 Subject: [PATCH 04/23] Monitor: Introduce search_dispatch_table() It's a generic version of monitor_find_command() which searches the dispatch table passed as an argument. Future commits will introduce new dispatch tables, so we need common code to search them. Signed-off-by: Luiz Capitulino --- monitor.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/monitor.c b/monitor.c index a33cdc2a00..da76eab16a 100644 --- a/monitor.c +++ b/monitor.c @@ -3371,11 +3371,12 @@ static int is_valid_option(const char *c, const char *typestr) return (typestr != NULL); } -static const mon_cmd_t *monitor_find_command(const char *cmdname) +static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table, + const char *cmdname) { const mon_cmd_t *cmd; - for (cmd = mon_cmds; cmd->name != NULL; cmd++) { + for (cmd = disp_table; cmd->name != NULL; cmd++) { if (compare_cmd(cmdname, cmd->name)) { return cmd; } @@ -3384,6 +3385,11 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname) return NULL; } +static const mon_cmd_t *monitor_find_command(const char *cmdname) +{ + return search_dispatch_table(mon_cmds, cmdname); +} + static const mon_cmd_t *monitor_parse_command(Monitor *mon, const char *cmdline, QDict *qdict) From 0fb88582e60e16e809c1aabc2c4b3e1f0832e267 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Wed, 15 Sep 2010 10:56:17 -0300 Subject: [PATCH 05/23] QMP: handle_qmp_command(): Move 'cmd' sanity check Next commit will change how query commands are handled in a way that the 'cmd' sanity check is also going to be needed for query commands handling. Let's move it out of the else body then. Signed-off-by: Luiz Capitulino --- monitor.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/monitor.c b/monitor.c index da76eab16a..2efff8ab24 100644 --- a/monitor.c +++ b/monitor.c @@ -4375,11 +4375,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) qobject_from_jsonf("{ 'item': %s }", info_item)); } else { cmd = monitor_find_command(cmd_name); - if (!cmd || !monitor_handler_ported(cmd) - || monitor_cmd_user_only(cmd)) { - qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); - goto err_out; - } + } + + if (!cmd || !monitor_handler_ported(cmd) || monitor_cmd_user_only(cmd)) { + qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); + goto err_out; } obj = qdict_get(input, "arguments"); From 030db6e89d052fbf689b632d74026030bdf7a02a Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 10 Sep 2010 16:03:38 -0300 Subject: [PATCH 06/23] QMP: Don't use do_info() Since its inception, QMP has been using HMP's do_info() function to run query commands. This was a bad choice, as it made do_info() more complex and contributed to couple QMP and HMP. This commit fixes that by doing the following changes: 1. Introduce qmp_find_query_cmd() and use it to directly lookup the info_cmds table 2. Introduce qmp_call_query_cmd() so that QMP code is able to call query handlers without using do_info() 3. Drop do_info() usage (via monitor_find_command("info")) We need all the three changes in one shot so that we don't break the calling of query commands in QMP. Signed-off-by: Luiz Capitulino --- monitor.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/monitor.c b/monitor.c index 2efff8ab24..ff65f38ed4 100644 --- a/monitor.c +++ b/monitor.c @@ -3390,6 +3390,11 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname) return search_dispatch_table(mon_cmds, cmdname); } +static const mon_cmd_t *qmp_find_query_cmd(const char *info_item) +{ + return search_dispatch_table(info_cmds, info_item); +} + static const mon_cmd_t *monitor_parse_command(Monitor *mon, const char *cmdline, QDict *qdict) @@ -4329,6 +4334,24 @@ static QDict *qmp_check_input_obj(QObject *input_obj) return input_dict; } +static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd) +{ + QObject *ret_data = NULL; + + if (monitor_handler_is_async(cmd)) { + qmp_async_info_handler(mon, cmd); + if (monitor_has_error(mon)) { + monitor_protocol_emitter(mon, NULL); + } + } else { + cmd->mhandler.info_new(mon, &ret_data); + if (ret_data) { + monitor_protocol_emitter(mon, ret_data); + qobject_decref(ret_data); + } + } +} + static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { int err; @@ -4336,8 +4359,9 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) QDict *input, *args; const mon_cmd_t *cmd; Monitor *mon = cur_mon; - const char *cmd_name, *info_item; + const char *cmd_name, *query_cmd; + query_cmd = NULL; args = input = NULL; obj = json_parser_parse(tokens, NULL); @@ -4363,16 +4387,13 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) } /* - * XXX: We need this special case until we get info handlers - * converted into 'query-' commands + * XXX: We need this special case until QMP has its own dispatch table */ if (compare_cmd(cmd_name, "info")) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_out; - } else if (strstart(cmd_name, "query-", &info_item)) { - cmd = monitor_find_command("info"); - qdict_put_obj(input, "arguments", - qobject_from_jsonf("{ 'item': %s }", info_item)); + } else if (strstart(cmd_name, "query-", &query_cmd)) { + cmd = qmp_find_query_cmd(query_cmd); } else { cmd = monitor_find_command(cmd_name); } @@ -4395,7 +4416,9 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) goto err_out; } - if (monitor_handler_is_async(cmd)) { + if (query_cmd) { + qmp_call_query_cmd(mon, cmd); + } else if (monitor_handler_is_async(cmd)) { err = qmp_async_cmd_handler(mon, cmd, args); if (err) { /* emit the error response */ From 1dcbd6f6b79d5cae4d11572ce945653ca93291cc Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 10 Sep 2010 17:00:16 -0300 Subject: [PATCH 07/23] Monitor: Drop QMP bits from do_info() As of last commit, QMP doesn't use do_info() anymore. Simplify it. Signed-off-by: Luiz Capitulino --- monitor.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/monitor.c b/monitor.c index ff65f38ed4..4fc0ad3123 100644 --- a/monitor.c +++ b/monitor.c @@ -642,7 +642,6 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data) const char *item = qdict_get_try_str(qdict, "item"); if (!item) { - assert(monitor_ctrl_mode(mon) == 0); goto help; } @@ -652,24 +651,11 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data) } if (cmd->name == NULL) { - if (monitor_ctrl_mode(mon)) { - qerror_report(QERR_COMMAND_NOT_FOUND, item); - return -1; - } goto help; } - if (monitor_ctrl_mode(mon) && monitor_cmd_user_only(cmd)) { - qerror_report(QERR_COMMAND_NOT_FOUND, item); - return -1; - } - if (monitor_handler_is_async(cmd)) { - if (monitor_ctrl_mode(mon)) { - qmp_async_info_handler(mon, cmd); - } else { - user_async_info_handler(mon, cmd); - } + user_async_info_handler(mon, cmd); /* * Indicate that this command is asynchronous and will not return any * data (not even empty). Instead, the data will be returned via a @@ -677,24 +663,15 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data) */ *ret_data = qobject_from_jsonf("{ '__mon_async': 'return' }"); } else if (monitor_handler_ported(cmd)) { - cmd->mhandler.info_new(mon, ret_data); + QObject *info_data = NULL; - if (!monitor_ctrl_mode(mon)) { - /* - * User Protocol function is called here, Monitor Protocol is - * handled by monitor_call_handler() - */ - if (*ret_data) - cmd->user_print(mon, *ret_data); + cmd->mhandler.info_new(mon, &info_data); + if (info_data) { + cmd->user_print(mon, info_data); + qobject_decref(info_data); } } else { - if (monitor_ctrl_mode(mon)) { - /* handler not converted yet */ - qerror_report(QERR_COMMAND_NOT_FOUND, item); - return -1; - } else { - cmd->mhandler.info(mon); - } + cmd->mhandler.info(mon); } return 0; From d4551293d68a1876df87400be6c71c657756d0bb Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Wed, 15 Sep 2010 16:56:48 -0300 Subject: [PATCH 08/23] Monitor: Drop is_async_return() If I understood it correcty, the is_async_return() logic was only used to prevent QMP from issuing duplicated success responses for asynchronous handlers. However, QMP doesn't use do_info() anymore so this is dead logic and (hopefully) can be safely dropped. Signed-off-by: Luiz Capitulino --- monitor.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/monitor.c b/monitor.c index 4fc0ad3123..7f2af4942c 100644 --- a/monitor.c +++ b/monitor.c @@ -656,12 +656,6 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data) if (monitor_handler_is_async(cmd)) { user_async_info_handler(mon, cmd); - /* - * Indicate that this command is asynchronous and will not return any - * data (not even empty). Instead, the data will be returned via a - * completion callback. - */ - *ret_data = qobject_from_jsonf("{ '__mon_async': 'return' }"); } else if (monitor_handler_ported(cmd)) { QObject *info_data = NULL; @@ -3720,15 +3714,6 @@ void monitor_set_error(Monitor *mon, QError *qerror) } } -static int is_async_return(const QObject *data) -{ - if (data && qobject_type(data) == QTYPE_QDICT) { - return qdict_haskey(qobject_to_qdict(data), "__mon_async"); - } - - return 0; -} - static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret) { if (monitor_ctrl_mode(mon)) { @@ -3787,15 +3772,7 @@ static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd, ret = cmd->mhandler.cmd_new(mon, params, &data); handler_audit(mon, cmd, ret); - if (is_async_return(data)) { - /* - * Asynchronous commands have no initial return data but they can - * generate errors. Data is returned via the async completion handler. - */ - if (monitor_ctrl_mode(mon) && monitor_has_error(mon)) { - monitor_protocol_emitter(mon, NULL); - } - } else if (monitor_ctrl_mode(mon)) { + if (monitor_ctrl_mode(mon)) { /* Monitor Protocol */ monitor_protocol_emitter(mon, data); } else { From 1162daa6c163ca022165a9bcb3078c2e16f32674 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Mon, 13 Sep 2010 12:15:26 -0300 Subject: [PATCH 09/23] Monitor: Convert do_info() back to HMP This is a HMP specific handler, it makes no sense to have it under QMP. Signed-off-by: Luiz Capitulino --- monitor.c | 5 ++--- qemu-monitor.hx | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/monitor.c b/monitor.c index 7f2af4942c..f0854c436f 100644 --- a/monitor.c +++ b/monitor.c @@ -636,7 +636,7 @@ static void user_async_info_handler(Monitor *mon, const mon_cmd_t *cmd) } } -static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data) +static void do_info(Monitor *mon, const QDict *qdict) { const mon_cmd_t *cmd; const char *item = qdict_get_try_str(qdict, "item"); @@ -668,11 +668,10 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data) cmd->mhandler.info(mon); } - return 0; + return; help: help_cmd(mon, "info"); - return 0; } static void do_info_version_print(Monitor *mon, const QObject *data) diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 49bcd8d324..57d28ac1f1 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1654,8 +1654,7 @@ EQMP .args_type = "item:s?", .params = "[subcommand]", .help = "show various information about the system state", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_info, + .mhandler.cmd = do_info, }, STEXI From 82a56f0d83d4bca92bbe8b0546cb70292c1dc65d Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Mon, 13 Sep 2010 12:26:00 -0300 Subject: [PATCH 10/23] Monitor: Introduce the qmp-commands.hx file This file contains a copy of the following information from the qemu-monitor.hx file: o QObject handlers entries o QMP documentation (all SQMP/EQMP sections) Right now it's only used to generate the QMP docs in QMP/, but next commits will turn this into QMP's command dispatch table. It's important to note that QObject handlers entries are going to get duplicated: they will exist in both QMP's and HMP's dispatch tables. This will be fixed in the near future, when we add a proper QMP call interface and HMP is converted to use it. This way we can completely drop QObject handlers entries from HMP's tables. NOTE: HMP specific constructions, like "q|quit", have been dropped. Signed-off-by: Luiz Capitulino --- Makefile | 2 +- QMP/README | 2 +- qmp-commands.hx | 1541 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1543 insertions(+), 2 deletions(-) create mode 100644 qmp-commands.hx diff --git a/Makefile b/Makefile index fca1e7a51f..938d88bc21 100644 --- a/Makefile +++ b/Makefile @@ -252,7 +252,7 @@ qemu-options.texi: $(SRC_PATH)/qemu-options.hx qemu-monitor.texi: $(SRC_PATH)/qemu-monitor.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@") -QMP/qmp-commands.txt: $(SRC_PATH)/qemu-monitor.hx +QMP/qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -q < $< > $@," GEN $@") qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx diff --git a/QMP/README b/QMP/README index 948d4453d5..7e2b51a9b2 100644 --- a/QMP/README +++ b/QMP/README @@ -82,7 +82,7 @@ doing any code change. This is so because: 2. Review can improve your interface. Letting that happen before you implement it can save you work. -* The qmp-commands.txt file is generated from the qemu-monitor.hx one, which +* The qmp-commands.txt file is generated from the qmp-commands.hx one, which is the file that should be edited. Homepage diff --git a/qmp-commands.hx b/qmp-commands.hx new file mode 100644 index 0000000000..793cf1c0f9 --- /dev/null +++ b/qmp-commands.hx @@ -0,0 +1,1541 @@ +HXCOMM QMP dispatch table and documentation +HXCOMM Text between SQMP and EQMP is copied to the QMP documention file and +HXCOMM does not show up in the other formats. + +SQMP + QMP Supported Commands + ---------------------- + +This document describes all commands currently supported by QMP. + +Most of the time their usage is exactly the same as in the user Monitor, this +means that any other document which also describe commands (the manpage, +QEMU's manual, etc) can and should be consulted. + +QMP has two types of commands: regular and query commands. Regular commands +usually change the Virtual Machine's state someway, while query commands just +return information. The sections below are divided accordingly. + +It's important to observe that all communication examples are formatted in +a reader-friendly way, so that they're easier to understand. However, in real +protocol usage, they're emitted as a single line. + +Also, the following notation is used to denote data flow: + +-> data issued by the Client +<- Server data response + +Please, refer to the QMP specification (QMP/qmp-spec.txt) for detailed +information on the Server command and response formats. + +NOTE: This document is temporary and will be replaced soon. + +1. Stability Considerations +=========================== + +The current QMP command set (described in this file) may be useful for a +number of use cases, however it's limited and several commands have bad +defined semantics, specially with regard to command completion. + +These problems are going to be solved incrementally in the next QEMU releases +and we're going to establish a deprecation policy for badly defined commands. + +If you're planning to adopt QMP, please observe the following: + + 1. The deprecation policy will take efect and be documented soon, please + check the documentation of each used command as soon as a new release of + QEMU is available + + 2. DO NOT rely on anything which is not explicit documented + + 3. Errors, in special, are not documented. Applications should NOT check + for specific errors classes or data (it's strongly recommended to only + check for the "error" key) + +2. Regular Commands +=================== + +Server's responses in the examples below are always a success response, please +refer to the QMP specification for more details on error responses. + +EQMP + + { + .name = "quit", + .args_type = "", + .params = "", + .help = "quit the emulator", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_quit, + }, + +SQMP +quit +---- + +Quit the emulator. + +Arguments: None. + +Example: + +-> { "execute": "quit" } +<- { "return": {} } + +EQMP + + { + .name = "eject", + .args_type = "force:-f,device:B", + .params = "[-f] device", + .help = "eject a removable medium (use -f to force it)", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_eject, + }, + +SQMP +eject +----- + +Eject a removable medium. + +Arguments: + +- force: force ejection (json-bool, optional) +- device: device name (json-string) + +Example: + +-> { "execute": "eject", "arguments": { "device": "ide1-cd0" } } +<- { "return": {} } + +Note: The "force" argument defaults to false. + +EQMP + + { + .name = "change", + .args_type = "device:B,target:F,arg:s?", + .params = "device filename [format]", + .help = "change a removable medium, optional format", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_change, + }, + +SQMP +change +------ + +Change a removable medium or VNC configuration. + +Arguments: + +- "device": device name (json-string) +- "target": filename or item (json-string) +- "arg": additional argument (json-string, optional) + +Examples: + +1. Change a removable medium + +-> { "execute": "change", + "arguments": { "device": "ide1-cd0", + "target": "/srv/images/Fedora-12-x86_64-DVD.iso" } } +<- { "return": {} } + +2. Change VNC password + +-> { "execute": "change", + "arguments": { "device": "vnc", "target": "password", + "arg": "foobar1" } } +<- { "return": {} } + +EQMP + + { + .name = "screendump", + .args_type = "filename:F", + .params = "filename", + .help = "save screen into PPM image 'filename'", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_screen_dump, + }, + +SQMP +screendump +---------- + +Save screen into PPM image. + +Arguments: + +- "filename": file path (json-string) + +Example: + +-> { "execute": "screendump", "arguments": { "filename": "/tmp/image" } } +<- { "return": {} } + +EQMP + + { + .name = "stop", + .args_type = "", + .params = "", + .help = "stop emulation", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_stop, + }, + +SQMP +stop +---- + +Stop the emulator. + +Arguments: None. + +Example: + +-> { "execute": "stop" } +<- { "return": {} } + +EQMP + + { + .name = "cont", + .args_type = "", + .params = "", + .help = "resume emulation", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_cont, + }, + +SQMP +cont +---- + +Resume emulation. + +Arguments: None. + +Example: + +-> { "execute": "cont" } +<- { "return": {} } + +EQMP + + { + .name = "system_reset", + .args_type = "", + .params = "", + .help = "reset the system", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_system_reset, + }, + +SQMP +system_reset +------------ + +Reset the system. + +Arguments: None. + +Example: + +-> { "execute": "system_reset" } +<- { "return": {} } + +EQMP + + { + .name = "system_powerdown", + .args_type = "", + .params = "", + .help = "send system power down event", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_system_powerdown, + }, + +SQMP +system_powerdown +---------------- + +Send system power down event. + +Arguments: None. + +Example: + +-> { "execute": "system_powerdown" } +<- { "return": {} } + +EQMP + + { + .name = "device_add", + .args_type = "device:O", + .params = "driver[,prop=value][,...]", + .help = "add device, like -device on the command line", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_device_add, + }, + +SQMP +device_add +---------- + +Add a device. + +Arguments: + +- "driver": the name of the new device's driver (json-string) +- "bus": the device's parent bus (device tree path, json-string, optional) +- "id": the device's ID, must be unique (json-string) +- device properties + +Example: + +-> { "execute": "device_add", "arguments": { "driver": "e1000", "id": "net1" } } +<- { "return": {} } + +Notes: + +(1) For detailed information about this command, please refer to the + 'docs/qdev-device-use.txt' file. + +(2) It's possible to list device properties by running QEMU with the + "-device DEVICE,\?" command-line argument, where DEVICE is the device's name + +EQMP + + { + .name = "device_del", + .args_type = "id:s", + .params = "device", + .help = "remove device", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_device_del, + }, + +SQMP +device_del +---------- + +Remove a device. + +Arguments: + +- "id": the device's ID (json-string) + +Example: + +-> { "execute": "device_del", "arguments": { "id": "net1" } } +<- { "return": {} } + +EQMP + + { + .name = "cpu", + .args_type = "index:i", + .params = "index", + .help = "set the default CPU", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_cpu_set, + }, + +SQMP +cpu +--- + +Set the default CPU. + +Arguments: + +- "index": the CPU's index (json-int) + +Example: + +-> { "execute": "cpu", "arguments": { "index": 0 } } +<- { "return": {} } + +Note: CPUs' indexes are obtained with the 'query-cpus' command. + +EQMP + + { + .name = "memsave", + .args_type = "val:l,size:i,filename:s", + .params = "addr size file", + .help = "save to disk virtual memory dump starting at 'addr' of size 'size'", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_memory_save, + }, + +SQMP +memsave +------- + +Save to disk virtual memory dump starting at 'val' of size 'size'. + +Arguments: + +- "val": the starting address (json-int) +- "size": the memory size, in bytes (json-int) +- "filename": file path (json-string) + +Example: + +-> { "execute": "memsave", + "arguments": { "val": 10, + "size": 100, + "filename": "/tmp/virtual-mem-dump" } } +<- { "return": {} } + +Note: Depends on the current CPU. + +EQMP + + { + .name = "pmemsave", + .args_type = "val:l,size:i,filename:s", + .params = "addr size file", + .help = "save to disk physical memory dump starting at 'addr' of size 'size'", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_physical_memory_save, + }, + +SQMP +pmemsave +-------- + +Save to disk physical memory dump starting at 'val' of size 'size'. + +Arguments: + +- "val": the starting address (json-int) +- "size": the memory size, in bytes (json-int) +- "filename": file path (json-string) + +Example: + +-> { "execute": "pmemsave", + "arguments": { "val": 10, + "size": 100, + "filename": "/tmp/physical-mem-dump" } } +<- { "return": {} } + +EQMP + + { + .name = "migrate", + .args_type = "detach:-d,blk:-b,inc:-i,uri:s", + .params = "[-d] [-b] [-i] uri", + .help = "migrate to URI (using -d to not wait for completion)" + "\n\t\t\t -b for migration without shared storage with" + " full copy of disk\n\t\t\t -i for migration without " + "shared storage with incremental copy of disk " + "(base image shared between src and destination)", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_migrate, + }, + +SQMP +migrate +------- + +Migrate to URI. + +Arguments: + +- "blk": block migration, full disk copy (json-bool, optional) +- "inc": incremental disk copy (json-bool, optional) +- "uri": Destination URI (json-string) + +Example: + +-> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } } +<- { "return": {} } + +Notes: + +(1) The 'query-migrate' command should be used to check migration's progress + and final result (this information is provided by the 'status' member) +(2) All boolean arguments default to false +(3) The user Monitor's "detach" argument is invalid in QMP and should not + be used + +EQMP + + { + .name = "migrate_cancel", + .args_type = "", + .params = "", + .help = "cancel the current VM migration", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_migrate_cancel, + }, + +SQMP +migrate_cancel +-------------- + +Cancel the current migration. + +Arguments: None. + +Example: + +-> { "execute": "migrate_cancel" } +<- { "return": {} } + +EQMP + + { + .name = "migrate_set_speed", + .args_type = "value:f", + .params = "value", + .help = "set maximum speed (in bytes) for migrations", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_migrate_set_speed, + }, + +SQMP +migrate_set_speed +----------------- + +Set maximum speed for migrations. + +Arguments: + +- "value": maximum speed, in bytes per second (json-number) + +Example: + +-> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } } +<- { "return": {} } + +EQMP + + { + .name = "migrate_set_downtime", + .args_type = "value:T", + .params = "value", + .help = "set maximum tolerated downtime (in seconds) for migrations", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_migrate_set_downtime, + }, + +SQMP +migrate_set_downtime +-------------------- + +Set maximum tolerated downtime (in seconds) for migrations. + +Arguments: + +- "value": maximum downtime (json-number) + +Example: + +-> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } } +<- { "return": {} } + +EQMP + + { + .name = "netdev_add", + .args_type = "netdev:O", + .params = "[user|tap|socket],id=str[,prop=value][,...]", + .help = "add host network device", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_netdev_add, + }, + +SQMP +netdev_add +---------- + +Add host network device. + +Arguments: + +- "type": the device type, "tap", "user", ... (json-string) +- "id": the device's ID, must be unique (json-string) +- device options + +Example: + +-> { "execute": "netdev_add", "arguments": { "type": "user", "id": "netdev1" } } +<- { "return": {} } + +Note: The supported device options are the same ones supported by the '-net' + command-line argument, which are listed in the '-help' output or QEMU's + manual + +EQMP + + { + .name = "netdev_del", + .args_type = "id:s", + .params = "id", + .help = "remove host network device", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_netdev_del, + }, + +SQMP +netdev_del +---------- + +Remove host network device. + +Arguments: + +- "id": the device's ID, must be unique (json-string) + +Example: + +-> { "execute": "netdev_del", "arguments": { "id": "netdev1" } } +<- { "return": {} } + +EQMP + + { + .name = "balloon", + .args_type = "value:M", + .params = "target", + .help = "request VM to change its memory allocation (in MB)", + .user_print = monitor_user_noop, + .mhandler.cmd_async = do_balloon, + .flags = MONITOR_CMD_ASYNC, + }, + +SQMP +balloon +------- + +Request VM to change its memory allocation (in bytes). + +Arguments: + +- "value": New memory allocation (json-int) + +Example: + +-> { "execute": "balloon", "arguments": { "value": 536870912 } } +<- { "return": {} } + +EQMP + + { + .name = "set_link", + .args_type = "name:s,up:b", + .params = "name on|off", + .help = "change the link status of a network adapter", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_set_link, + }, + +SQMP +set_link +-------- + +Change the link status of a network adapter. + +Arguments: + +- "name": network device name (json-string) +- "up": status is up (json-bool) + +Example: + +-> { "execute": "set_link", "arguments": { "name": "e1000.0", "up": false } } +<- { "return": {} } + +EQMP + + { + .name = "getfd", + .args_type = "fdname:s", + .params = "getfd name", + .help = "receive a file descriptor via SCM rights and assign it a name", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_getfd, + }, + +SQMP +getfd +----- + +Receive a file descriptor via SCM rights and assign it a name. + +Arguments: + +- "fdname": file descriptor name (json-string) + +Example: + +-> { "execute": "getfd", "arguments": { "fdname": "fd1" } } +<- { "return": {} } + +EQMP + + { + .name = "closefd", + .args_type = "fdname:s", + .params = "closefd name", + .help = "close a file descriptor previously passed via SCM rights", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_closefd, + }, + +SQMP +closefd +------- + +Close a file descriptor previously passed via SCM rights. + +Arguments: + +- "fdname": file descriptor name (json-string) + +Example: + +-> { "execute": "closefd", "arguments": { "fdname": "fd1" } } +<- { "return": {} } + +EQMP + + { + .name = "block_passwd", + .args_type = "device:B,password:s", + .params = "block_passwd device password", + .help = "set the password of encrypted block devices", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_block_set_passwd, + }, + +SQMP +block_passwd +------------ + +Set the password of encrypted block devices. + +Arguments: + +- "device": device name (json-string) +- "password": password (json-string) + +Example: + +-> { "execute": "block_passwd", "arguments": { "device": "ide0-hd0", + "password": "12345" } } +<- { "return": {} } + +EQMP + + { + .name = "qmp_capabilities", + .args_type = "", + .params = "", + .help = "enable QMP capabilities", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_qmp_capabilities, + }, + +SQMP +qmp_capabilities +---------------- + +Enable QMP capabilities. + +Arguments: None. + +Example: + +-> { "execute": "qmp_capabilities" } +<- { "return": {} } + +Note: This command must be issued before issuing any other command. + +3. Query Commands +================= + +HXCOMM Each query command below is inside a SQMP/EQMP section, do NOT change +HXCOMM this! We will possibly move query commands definitions inside those +HXCOMM sections, just like regular commands. + +EQMP + +SQMP +query-version +------------- + +Show QEMU version. + +Return a json-object with the following information: + +- "qemu": A json-object containing three integer values: + - "major": QEMU's major version (json-int) + - "minor": QEMU's minor version (json-int) + - "micro": QEMU's micro version (json-int) +- "package": package's version (json-string) + +Example: + +-> { "execute": "query-version" } +<- { + "return":{ + "qemu":{ + "major":0, + "minor":11, + "micro":5 + }, + "package":"" + } + } + +EQMP + +SQMP +query-commands +-------------- + +List QMP available commands. + +Each command is represented by a json-object, the returned value is a json-array +of all commands. + +Each json-object contain: + +- "name": command's name (json-string) + +Example: + +-> { "execute": "query-commands" } +<- { + "return":[ + { + "name":"query-balloon" + }, + { + "name":"system_powerdown" + } + ] + } + +Note: This example has been shortened as the real response is too long. + +EQMP + +SQMP +query-chardev +------------- + +Each device is represented by a json-object. The returned value is a json-array +of all devices. + +Each json-object contain the following: + +- "label": device's label (json-string) +- "filename": device's file (json-string) + +Example: + +-> { "execute": "query-chardev" } +<- { + "return":[ + { + "label":"monitor", + "filename":"stdio" + }, + { + "label":"serial0", + "filename":"vc" + } + ] + } + +EQMP + +SQMP +query-block +----------- + +Show the block devices. + +Each block device information is stored in a json-object and the returned value +is a json-array of all devices. + +Each json-object contain the following: + +- "device": device name (json-string) +- "type": device type (json-string) + - Possible values: "hd", "cdrom", "floppy", "unknown" +- "removable": true if the device is removable, false otherwise (json-bool) +- "locked": true if the device is locked, false otherwise (json-bool) +- "inserted": only present if the device is inserted, it is a json-object + containing the following: + - "file": device file name (json-string) + - "ro": true if read-only, false otherwise (json-bool) + - "drv": driver format name (json-string) + - Possible values: "blkdebug", "bochs", "cloop", "cow", "dmg", + "file", "file", "ftp", "ftps", "host_cdrom", + "host_device", "host_floppy", "http", "https", + "nbd", "parallels", "qcow", "qcow2", "raw", + "tftp", "vdi", "vmdk", "vpc", "vvfat" + - "backing_file": backing file name (json-string, optional) + - "encrypted": true if encrypted, false otherwise (json-bool) + +Example: + +-> { "execute": "query-block" } +<- { + "return":[ + { + "device":"ide0-hd0", + "locked":false, + "removable":false, + "inserted":{ + "ro":false, + "drv":"qcow2", + "encrypted":false, + "file":"disks/test.img" + }, + "type":"hd" + }, + { + "device":"ide1-cd0", + "locked":false, + "removable":true, + "type":"cdrom" + }, + { + "device":"floppy0", + "locked":false, + "removable":true, + "type": "floppy" + }, + { + "device":"sd0", + "locked":false, + "removable":true, + "type":"floppy" + } + ] + } + +EQMP + +SQMP +query-blockstats +---------------- + +Show block device statistics. + +Each device statistic information is stored in a json-object and the returned +value is a json-array of all devices. + +Each json-object contain the following: + +- "device": device name (json-string) +- "stats": A json-object with the statistics information, it contains: + - "rd_bytes": bytes read (json-int) + - "wr_bytes": bytes written (json-int) + - "rd_operations": read operations (json-int) + - "wr_operations": write operations (json-int) + - "wr_highest_offset": Highest offset of a sector written since the + BlockDriverState has been opened (json-int) +- "parent": Contains recursively the statistics of the underlying + protocol (e.g. the host file for a qcow2 image). If there is + no underlying protocol, this field is omitted + (json-object, optional) + +Example: + +-> { "execute": "query-blockstats" } +<- { + "return":[ + { + "device":"ide0-hd0", + "parent":{ + "stats":{ + "wr_highest_offset":3686448128, + "wr_bytes":9786368, + "wr_operations":751, + "rd_bytes":122567168, + "rd_operations":36772 + } + }, + "stats":{ + "wr_highest_offset":2821110784, + "wr_bytes":9786368, + "wr_operations":692, + "rd_bytes":122739200, + "rd_operations":36604 + } + }, + { + "device":"ide1-cd0", + "stats":{ + "wr_highest_offset":0, + "wr_bytes":0, + "wr_operations":0, + "rd_bytes":0, + "rd_operations":0 + } + }, + { + "device":"floppy0", + "stats":{ + "wr_highest_offset":0, + "wr_bytes":0, + "wr_operations":0, + "rd_bytes":0, + "rd_operations":0 + } + }, + { + "device":"sd0", + "stats":{ + "wr_highest_offset":0, + "wr_bytes":0, + "wr_operations":0, + "rd_bytes":0, + "rd_operations":0 + } + } + ] + } + +EQMP + +SQMP +query-cpus +---------- + +Show CPU information. + +Return a json-array. Each CPU is represented by a json-object, which contains: + +- "CPU": CPU index (json-int) +- "current": true if this is the current CPU, false otherwise (json-bool) +- "halted": true if the cpu is halted, false otherwise (json-bool) +- Current program counter. The key's name depends on the architecture: + "pc": i386/x86_64 (json-int) + "nip": PPC (json-int) + "pc" and "npc": sparc (json-int) + "PC": mips (json-int) + +Example: + +-> { "execute": "query-cpus" } +<- { + "return":[ + { + "CPU":0, + "current":true, + "halted":false, + "pc":3227107138 + }, + { + "CPU":1, + "current":false, + "halted":true, + "pc":7108165 + } + ] + } + +EQMP + +SQMP +query-pci +--------- + +PCI buses and devices information. + +The returned value is a json-array of all buses. Each bus is represented by +a json-object, which has a key with a json-array of all PCI devices attached +to it. Each device is represented by a json-object. + +The bus json-object contains the following: + +- "bus": bus number (json-int) +- "devices": a json-array of json-objects, each json-object represents a + PCI device + +The PCI device json-object contains the following: + +- "bus": identical to the parent's bus number (json-int) +- "slot": slot number (json-int) +- "function": function number (json-int) +- "class_info": a json-object containing: + - "desc": device class description (json-string, optional) + - "class": device class number (json-int) +- "id": a json-object containing: + - "device": device ID (json-int) + - "vendor": vendor ID (json-int) +- "irq": device's IRQ if assigned (json-int, optional) +- "qdev_id": qdev id string (json-string) +- "pci_bridge": It's a json-object, only present if this device is a + PCI bridge, contains: + - "bus": bus number (json-int) + - "secondary": secondary bus number (json-int) + - "subordinate": subordinate bus number (json-int) + - "io_range": I/O memory range information, a json-object with the + following members: + - "base": base address, in bytes (json-int) + - "limit": limit address, in bytes (json-int) + - "memory_range": memory range information, a json-object with the + following members: + - "base": base address, in bytes (json-int) + - "limit": limit address, in bytes (json-int) + - "prefetchable_range": Prefetchable memory range information, a + json-object with the following members: + - "base": base address, in bytes (json-int) + - "limit": limit address, in bytes (json-int) + - "devices": a json-array of PCI devices if there's any attached, each + each element is represented by a json-object, which contains + the same members of the 'PCI device json-object' described + above (optional) +- "regions": a json-array of json-objects, each json-object represents a + memory region of this device + +The memory range json-object contains the following: + +- "base": base memory address (json-int) +- "limit": limit value (json-int) + +The region json-object can be an I/O region or a memory region, an I/O region +json-object contains the following: + +- "type": "io" (json-string, fixed) +- "bar": BAR number (json-int) +- "address": memory address (json-int) +- "size": memory size (json-int) + +A memory region json-object contains the following: + +- "type": "memory" (json-string, fixed) +- "bar": BAR number (json-int) +- "address": memory address (json-int) +- "size": memory size (json-int) +- "mem_type_64": true or false (json-bool) +- "prefetch": true or false (json-bool) + +Example: + +-> { "execute": "query-pci" } +<- { + "return":[ + { + "bus":0, + "devices":[ + { + "bus":0, + "qdev_id":"", + "slot":0, + "class_info":{ + "class":1536, + "desc":"Host bridge" + }, + "id":{ + "device":32902, + "vendor":4663 + }, + "function":0, + "regions":[ + + ] + }, + { + "bus":0, + "qdev_id":"", + "slot":1, + "class_info":{ + "class":1537, + "desc":"ISA bridge" + }, + "id":{ + "device":32902, + "vendor":28672 + }, + "function":0, + "regions":[ + + ] + }, + { + "bus":0, + "qdev_id":"", + "slot":1, + "class_info":{ + "class":257, + "desc":"IDE controller" + }, + "id":{ + "device":32902, + "vendor":28688 + }, + "function":1, + "regions":[ + { + "bar":4, + "size":16, + "address":49152, + "type":"io" + } + ] + }, + { + "bus":0, + "qdev_id":"", + "slot":2, + "class_info":{ + "class":768, + "desc":"VGA controller" + }, + "id":{ + "device":4115, + "vendor":184 + }, + "function":0, + "regions":[ + { + "prefetch":true, + "mem_type_64":false, + "bar":0, + "size":33554432, + "address":4026531840, + "type":"memory" + }, + { + "prefetch":false, + "mem_type_64":false, + "bar":1, + "size":4096, + "address":4060086272, + "type":"memory" + }, + { + "prefetch":false, + "mem_type_64":false, + "bar":6, + "size":65536, + "address":-1, + "type":"memory" + } + ] + }, + { + "bus":0, + "qdev_id":"", + "irq":11, + "slot":4, + "class_info":{ + "class":1280, + "desc":"RAM controller" + }, + "id":{ + "device":6900, + "vendor":4098 + }, + "function":0, + "regions":[ + { + "bar":0, + "size":32, + "address":49280, + "type":"io" + } + ] + } + ] + } + ] + } + +Note: This example has been shortened as the real response is too long. + +EQMP + +SQMP +query-kvm +--------- + +Show KVM information. + +Return a json-object with the following information: + +- "enabled": true if KVM support is enabled, false otherwise (json-bool) +- "present": true if QEMU has KVM support, false otherwise (json-bool) + +Example: + +-> { "execute": "query-kvm" } +<- { "return": { "enabled": true, "present": true } } + +EQMP + +SQMP +query-status +------------ + +Return a json-object with the following information: + +- "running": true if the VM is running, or false if it is paused (json-bool) +- "singlestep": true if the VM is in single step mode, + false otherwise (json-bool) + +Example: + +-> { "execute": "query-status" } +<- { "return": { "running": true, "singlestep": false } } + +EQMP + +SQMP +query-mice +---------- + +Show VM mice information. + +Each mouse is represented by a json-object, the returned value is a json-array +of all mice. + +The mouse json-object contains the following: + +- "name": mouse's name (json-string) +- "index": mouse's index (json-int) +- "current": true if this mouse is receiving events, false otherwise (json-bool) +- "absolute": true if the mouse generates absolute input events (json-bool) + +Example: + +-> { "execute": "query-mice" } +<- { + "return":[ + { + "name":"QEMU Microsoft Mouse", + "index":0, + "current":false, + "absolute":false + }, + { + "name":"QEMU PS/2 Mouse", + "index":1, + "current":true, + "absolute":true + } + ] + } + +EQMP + +SQMP +query-vnc +--------- + +Show VNC server information. + +Return a json-object with server information. Connected clients are returned +as a json-array of json-objects. + +The main json-object contains the following: + +- "enabled": true or false (json-bool) +- "host": server's IP address (json-string) +- "family": address family (json-string) + - Possible values: "ipv4", "ipv6", "unix", "unknown" +- "service": server's port number (json-string) +- "auth": authentication method (json-string) + - Possible values: "invalid", "none", "ra2", "ra2ne", "sasl", "tight", + "tls", "ultra", "unknown", "vencrypt", "vencrypt", + "vencrypt+plain", "vencrypt+tls+none", + "vencrypt+tls+plain", "vencrypt+tls+sasl", + "vencrypt+tls+vnc", "vencrypt+x509+none", + "vencrypt+x509+plain", "vencrypt+x509+sasl", + "vencrypt+x509+vnc", "vnc" +- "clients": a json-array of all connected clients + +Clients are described by a json-object, each one contain the following: + +- "host": client's IP address (json-string) +- "family": address family (json-string) + - Possible values: "ipv4", "ipv6", "unix", "unknown" +- "service": client's port number (json-string) +- "x509_dname": TLS dname (json-string, optional) +- "sasl_username": SASL username (json-string, optional) + +Example: + +-> { "execute": "query-vnc" } +<- { + "return":{ + "enabled":true, + "host":"0.0.0.0", + "service":"50402", + "auth":"vnc", + "family":"ipv4", + "clients":[ + { + "host":"127.0.0.1", + "service":"50401", + "family":"ipv4" + } + ] + } + } + +EQMP + +SQMP +query-name +---------- + +Show VM name. + +Return a json-object with the following information: + +- "name": VM's name (json-string, optional) + +Example: + +-> { "execute": "query-name" } +<- { "return": { "name": "qemu-name" } } + +EQMP + +SQMP +query-uuid +---------- + +Show VM UUID. + +Return a json-object with the following information: + +- "UUID": Universally Unique Identifier (json-string) + +Example: + +-> { "execute": "query-uuid" } +<- { "return": { "UUID": "550e8400-e29b-41d4-a716-446655440000" } } + +EQMP + +SQMP +query-migrate +------------- + +Migration status. + +Return a json-object. If migration is active there will be another json-object +with RAM migration status and if block migration is active another one with +block migration status. + +The main json-object contains the following: + +- "status": migration status (json-string) + - Possible values: "active", "completed", "failed", "cancelled" +- "ram": only present if "status" is "active", it is a json-object with the + following RAM information (in bytes): + - "transferred": amount transferred (json-int) + - "remaining": amount remaining (json-int) + - "total": total (json-int) +- "disk": only present if "status" is "active" and it is a block migration, + it is a json-object with the following disk information (in bytes): + - "transferred": amount transferred (json-int) + - "remaining": amount remaining (json-int) + - "total": total (json-int) + +Examples: + +1. Before the first migration + +-> { "execute": "query-migrate" } +<- { "return": {} } + +2. Migration is done and has succeeded + +-> { "execute": "query-migrate" } +<- { "return": { "status": "completed" } } + +3. Migration is done and has failed + +-> { "execute": "query-migrate" } +<- { "return": { "status": "failed" } } + +4. Migration is being performed and is not a block migration: + +-> { "execute": "query-migrate" } +<- { + "return":{ + "status":"active", + "ram":{ + "transferred":123, + "remaining":123, + "total":246 + } + } + } + +5. Migration is being performed and is a block migration: + +-> { "execute": "query-migrate" } +<- { + "return":{ + "status":"active", + "ram":{ + "total":1057024, + "remaining":1053304, + "transferred":3720 + }, + "disk":{ + "total":20971520, + "remaining":20880384, + "transferred":91136 + } + } + } + +EQMP + +SQMP +query-balloon +------------- + +Show balloon information. + +Make an asynchronous request for balloon info. When the request completes a +json-object will be returned containing the following data: + +- "actual": current balloon value in bytes (json-int) +- "mem_swapped_in": Amount of memory swapped in bytes (json-int, optional) +- "mem_swapped_out": Amount of memory swapped out in bytes (json-int, optional) +- "major_page_faults": Number of major faults (json-int, optional) +- "minor_page_faults": Number of minor faults (json-int, optional) +- "free_mem": Total amount of free and unused memory in + bytes (json-int, optional) +- "total_mem": Total amount of available memory in bytes (json-int, optional) + +Example: + +-> { "execute": "query-balloon" } +<- { + "return":{ + "actual":1073741824, + "mem_swapped_in":0, + "mem_swapped_out":0, + "major_page_faults":142, + "minor_page_faults":239245, + "free_mem":1014185984, + "total_mem":1044668416 + } + } + +EQMP + From bead3ce139025797a7e970f7d2c43e61a60a7c48 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Wed, 15 Sep 2010 17:08:39 -0300 Subject: [PATCH 11/23] QMP: Introduce qmp_find_cmd() Next commit needs this new function: it will introduce the the QMP's command dispatch table and qmp_find_cmd() will be used to search on it. Signed-off-by: Luiz Capitulino --- monitor.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/monitor.c b/monitor.c index f0854c436f..f62c34a946 100644 --- a/monitor.c +++ b/monitor.c @@ -3365,6 +3365,11 @@ static const mon_cmd_t *qmp_find_query_cmd(const char *info_item) return search_dispatch_table(info_cmds, info_item); } +static const mon_cmd_t *qmp_find_cmd(const char *cmdname) +{ + return search_dispatch_table(mon_cmds, cmdname); +} + static const mon_cmd_t *monitor_parse_command(Monitor *mon, const char *cmdline, QDict *qdict) @@ -4348,7 +4353,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) } else if (strstart(cmd_name, "query-", &query_cmd)) { cmd = qmp_find_query_cmd(query_cmd); } else { - cmd = monitor_find_command(cmd_name); + cmd = qmp_find_cmd(cmd_name); } if (!cmd || !monitor_handler_ported(cmd) || monitor_cmd_user_only(cmd)) { From f36b4afba9fe6ab5adefef9ca67521a5f677fccc Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Wed, 15 Sep 2010 17:17:45 -0300 Subject: [PATCH 12/23] QMP: Introduce command dispatch table Also update QMP functions to use it. The table is generated from the qmp-commands.hx file. From now on, QMP and HMP have different command dispatch tables. Signed-off-by: Luiz Capitulino --- Makefile.target | 7 +++++-- monitor.c | 11 +++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Makefile.target b/Makefile.target index 91d03818e8..3a1fa7eff9 100644 --- a/Makefile.target +++ b/Makefile.target @@ -307,7 +307,7 @@ obj-alpha-y = alpha_palcode.o main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) -monitor.o: qemu-monitor.h +monitor.o: qemu-monitor.h qmp-commands.h $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) @@ -331,10 +331,13 @@ gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh qemu-monitor.h: $(SRC_PATH)/qemu-monitor.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") +qmp-commands.h: $(SRC_PATH)/qmp-commands.hx + $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") + clean: rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o rm -f *.d */*.d tcg/*.o ide/*.o - rm -f qemu-monitor.h gdbstub-xml.c + rm -f qemu-monitor.h qmp-commands.h gdbstub-xml.c install: all ifneq ($(PROGS),) diff --git a/monitor.c b/monitor.c index f62c34a946..06141a5bcc 100644 --- a/monitor.c +++ b/monitor.c @@ -189,6 +189,8 @@ static QLIST_HEAD(mon_list, Monitor) mon_list; static const mon_cmd_t mon_cmds[]; static const mon_cmd_t info_cmds[]; +static const mon_cmd_t qmp_cmds[]; + Monitor *cur_mon; Monitor *default_mon; @@ -745,7 +747,7 @@ static void do_info_commands(Monitor *mon, QObject **ret_data) cmd_list = qlist_new(); - for (cmd = mon_cmds; cmd->name != NULL; cmd++) { + for (cmd = qmp_cmds; cmd->name != NULL; cmd++) { if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd) && !compare_cmd(cmd->name, "info")) { qlist_append_obj(cmd_list, get_cmd_dict(cmd->name)); @@ -2635,6 +2637,11 @@ static const mon_cmd_t info_cmds[] = { }, }; +static const mon_cmd_t qmp_cmds[] = { +#include "qmp-commands.h" + { /* NULL */ }, +}; + /*******************************************************************/ static const char *pch; @@ -3367,7 +3374,7 @@ static const mon_cmd_t *qmp_find_query_cmd(const char *info_item) static const mon_cmd_t *qmp_find_cmd(const char *cmdname) { - return search_dispatch_table(mon_cmds, cmdname); + return search_dispatch_table(qmp_cmds, cmdname); } static const mon_cmd_t *monitor_parse_command(Monitor *mon, From 3e12a751edcced7ad40c3b87d9784ffcfe941dcc Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Wed, 15 Sep 2010 17:20:33 -0300 Subject: [PATCH 13/23] QMP: Introduce query commands dispatch table The new table is a copy of HMP's table, containing only QObject handlers. In the near future HMP will be making QMP calls and then we will be able to drop QObject handlers from HMP's table. From now on, QMP and HMP have different query command dispatch tables. Signed-off-by: Luiz Capitulino --- monitor.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) diff --git a/monitor.c b/monitor.c index 06141a5bcc..bf5da506fc 100644 --- a/monitor.c +++ b/monitor.c @@ -190,6 +190,7 @@ static const mon_cmd_t mon_cmds[]; static const mon_cmd_t info_cmds[]; static const mon_cmd_t qmp_cmds[]; +static const mon_cmd_t qmp_query_cmds[]; Monitor *cur_mon; Monitor *default_mon; @@ -754,7 +755,7 @@ static void do_info_commands(Monitor *mon, QObject **ret_data) } } - for (cmd = info_cmds; cmd->name != NULL; cmd++) { + for (cmd = qmp_query_cmds; cmd->name != NULL; cmd++) { if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd)) { char buf[128]; snprintf(buf, sizeof(buf), "query-%s", cmd->name); @@ -2642,6 +2643,131 @@ static const mon_cmd_t qmp_cmds[] = { { /* NULL */ }, }; +static const mon_cmd_t qmp_query_cmds[] = { + { + .name = "version", + .args_type = "", + .params = "", + .help = "show the version of QEMU", + .user_print = do_info_version_print, + .mhandler.info_new = do_info_version, + }, + { + .name = "commands", + .args_type = "", + .params = "", + .help = "list QMP available commands", + .user_print = monitor_user_noop, + .mhandler.info_new = do_info_commands, + }, + { + .name = "chardev", + .args_type = "", + .params = "", + .help = "show the character devices", + .user_print = qemu_chr_info_print, + .mhandler.info_new = qemu_chr_info, + }, + { + .name = "block", + .args_type = "", + .params = "", + .help = "show the block devices", + .user_print = bdrv_info_print, + .mhandler.info_new = bdrv_info, + }, + { + .name = "blockstats", + .args_type = "", + .params = "", + .help = "show block device statistics", + .user_print = bdrv_stats_print, + .mhandler.info_new = bdrv_info_stats, + }, + { + .name = "cpus", + .args_type = "", + .params = "", + .help = "show infos for each CPU", + .user_print = monitor_print_cpus, + .mhandler.info_new = do_info_cpus, + }, + { + .name = "pci", + .args_type = "", + .params = "", + .help = "show PCI info", + .user_print = do_pci_info_print, + .mhandler.info_new = do_pci_info, + }, + { + .name = "kvm", + .args_type = "", + .params = "", + .help = "show KVM information", + .user_print = do_info_kvm_print, + .mhandler.info_new = do_info_kvm, + }, + { + .name = "status", + .args_type = "", + .params = "", + .help = "show the current VM status (running|paused)", + .user_print = do_info_status_print, + .mhandler.info_new = do_info_status, + }, + { + .name = "mice", + .args_type = "", + .params = "", + .help = "show which guest mouse is receiving events", + .user_print = do_info_mice_print, + .mhandler.info_new = do_info_mice, + }, + { + .name = "vnc", + .args_type = "", + .params = "", + .help = "show the vnc server status", + .user_print = do_info_vnc_print, + .mhandler.info_new = do_info_vnc, + }, + { + .name = "name", + .args_type = "", + .params = "", + .help = "show the current VM name", + .user_print = do_info_name_print, + .mhandler.info_new = do_info_name, + }, + { + .name = "uuid", + .args_type = "", + .params = "", + .help = "show the current VM UUID", + .user_print = do_info_uuid_print, + .mhandler.info_new = do_info_uuid, + }, + { + .name = "migrate", + .args_type = "", + .params = "", + .help = "show migration status", + .user_print = do_info_migrate_print, + .mhandler.info_new = do_info_migrate, + }, + { + .name = "balloon", + .args_type = "", + .params = "", + .help = "show balloon information", + .user_print = monitor_print_balloon, + .mhandler.info_async = do_info_balloon, + .flags = MONITOR_CMD_ASYNC, + }, + { /* NULL */ }, +}; + /*******************************************************************/ static const char *pch; @@ -3369,7 +3495,7 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname) static const mon_cmd_t *qmp_find_query_cmd(const char *info_item) { - return search_dispatch_table(info_cmds, info_item); + return search_dispatch_table(qmp_query_cmds, info_item); } static const mon_cmd_t *qmp_find_cmd(const char *cmdname) From 2e061a7c86d77c599676d89c3461f8efe9c275b1 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 16 Sep 2010 10:36:54 -0300 Subject: [PATCH 14/23] QMP: Simplify do_info_commands() We now iterate over QMP's dispatch tables, no need to check for QMP-only handlers anymore. Signed-off-by: Luiz Capitulino --- monitor.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/monitor.c b/monitor.c index bf5da506fc..612ee5675d 100644 --- a/monitor.c +++ b/monitor.c @@ -749,18 +749,13 @@ static void do_info_commands(Monitor *mon, QObject **ret_data) cmd_list = qlist_new(); for (cmd = qmp_cmds; cmd->name != NULL; cmd++) { - if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd) && - !compare_cmd(cmd->name, "info")) { - qlist_append_obj(cmd_list, get_cmd_dict(cmd->name)); - } + qlist_append_obj(cmd_list, get_cmd_dict(cmd->name)); } for (cmd = qmp_query_cmds; cmd->name != NULL; cmd++) { - if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd)) { - char buf[128]; - snprintf(buf, sizeof(buf), "query-%s", cmd->name); - qlist_append_obj(cmd_list, get_cmd_dict(buf)); - } + char buf[128]; + snprintf(buf, sizeof(buf), "query-%s", cmd->name); + qlist_append_obj(cmd_list, get_cmd_dict(buf)); } *ret_data = QOBJECT(cmd_list); From d1249eaa4b5af2a66b56ceb59b484c6337c3e3c7 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Mon, 13 Sep 2010 14:44:27 -0300 Subject: [PATCH 15/23] QMP: Small cleanup in handle_qmp_command() QMP has its own dispatch tables, we can now drop the following checks: o 'info' command: this command doesn't exist in QMP's dispatch table, the right thing will happen when it's issued by a client (ie. command not found error) o monitor_handler_ported(): all QMP handlers are 'ported', no need to check for that o monitor_cmd_user_only(): no HMP handler will exist in QMP's dispatch tables, that's why we have split them after all :-) Signed-off-by: Luiz Capitulino --- monitor.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/monitor.c b/monitor.c index 612ee5675d..6e62643bd3 100644 --- a/monitor.c +++ b/monitor.c @@ -4472,19 +4472,13 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) goto err_out; } - /* - * XXX: We need this special case until QMP has its own dispatch table - */ - if (compare_cmd(cmd_name, "info")) { - qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); - goto err_out; - } else if (strstart(cmd_name, "query-", &query_cmd)) { + if (strstart(cmd_name, "query-", &query_cmd)) { cmd = qmp_find_query_cmd(query_cmd); } else { cmd = qmp_find_cmd(cmd_name); } - if (!cmd || !monitor_handler_ported(cmd) || monitor_cmd_user_only(cmd)) { + if (!cmd) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_out; } From 30f5041ef1ba534af9308d840bf359a50597ba5d Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Mon, 13 Sep 2010 15:34:56 -0300 Subject: [PATCH 16/23] Monitor: Drop QMP info from the qemu-monitor.hx file QMP has its own dispatch table and documentation file (qmp-commands.hx), we can now drop the following QMP specific info from qemu-monitor.hx: o SQMP/EQMP sections o The qmp_capabilities command o The query-commands command However, note that QObject handlers entries are not being removed. This will only happen when we introduce a proper QMP call interface. Signed-off-by: Luiz Capitulino --- monitor.c | 8 - qemu-monitor.hx | 1358 ----------------------------------------------- 2 files changed, 1366 deletions(-) diff --git a/monitor.c b/monitor.c index 6e62643bd3..b43277e580 100644 --- a/monitor.c +++ b/monitor.c @@ -2351,14 +2351,6 @@ static const mon_cmd_t info_cmds[] = { .user_print = do_info_version_print, .mhandler.info_new = do_info_version, }, - { - .name = "commands", - .args_type = "", - .params = "", - .help = "list QMP available commands", - .user_print = monitor_user_noop, - .mhandler.info_new = do_info_commands, - }, { .name = "network", .args_type = "", diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 57d28ac1f1..81999aa1a9 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1,70 +1,10 @@ HXCOMM Use DEFHEADING() to define headings in both help text and texi HXCOMM Text between STEXI and ETEXI are copied to texi version and HXCOMM discarded from C version -HXCOMM Text between SQMP and EQMP is copied to the QMP documention file and -HXCOMM does not show up in the other formats. HXCOMM DEF(command, args, callback, arg_string, help) is used to construct HXCOMM monitor commands HXCOMM HXCOMM can be used for comments, discarded from both texi and C -SQMP - QMP Supported Commands - ---------------------- - -This document describes all commands currently supported by QMP. - -Most of the time their usage is exactly the same as in the user Monitor, this -means that any other document which also describe commands (the manpage, -QEMU's manual, etc) can and should be consulted. - -QMP has two types of commands: regular and query commands. Regular commands -usually change the Virtual Machine's state someway, while query commands just -return information. The sections below are divided accordingly. - -It's important to observe that all communication examples are formatted in -a reader-friendly way, so that they're easier to understand. However, in real -protocol usage, they're emitted as a single line. - -Also, the following notation is used to denote data flow: - --> data issued by the Client -<- Server data response - -Please, refer to the QMP specification (QMP/qmp-spec.txt) for detailed -information on the Server command and response formats. - -NOTE: This document is temporary and will be replaced soon. - -1. Stability Considerations -=========================== - -The current QMP command set (described in this file) may be useful for a -number of use cases, however it's limited and several commands have bad -defined semantics, specially with regard to command completion. - -These problems are going to be solved incrementally in the next QEMU releases -and we're going to establish a deprecation policy for badly defined commands. - -If you're planning to adopt QMP, please observe the following: - - 1. The deprecation policy will take efect and be documented soon, please - check the documentation of each used command as soon as a new release of - QEMU is available - - 2. DO NOT rely on anything which is not explicit documented - - 3. Errors, in special, are not documented. Applications should NOT check - for specific errors classes or data (it's strongly recommended to only - check for the "error" key) - -2. Regular Commands -=================== - -Server's responses in the examples below are always a success response, please -refer to the QMP specification for more details on error responses. - -EQMP - STEXI @table @option ETEXI @@ -111,20 +51,6 @@ STEXI @findex quit Quit the emulator. ETEXI -SQMP -quit ----- - -Quit the emulator. - -Arguments: None. - -Example: - --> { "execute": "quit" } -<- { "return": {} } - -EQMP { .name = "eject", @@ -140,25 +66,6 @@ STEXI @findex eject Eject a removable medium (use -f to force it). ETEXI -SQMP -eject ------ - -Eject a removable medium. - -Arguments: - -- force: force ejection (json-bool, optional) -- device: device name (json-string) - -Example: - --> { "execute": "eject", "arguments": { "device": "ide1-cd0" } } -<- { "return": {} } - -Note: The "force" argument defaults to false. - -EQMP { .name = "change", @@ -206,35 +113,6 @@ Password: ******** @end table ETEXI -SQMP -change ------- - -Change a removable medium or VNC configuration. - -Arguments: - -- "device": device name (json-string) -- "target": filename or item (json-string) -- "arg": additional argument (json-string, optional) - -Examples: - -1. Change a removable medium - --> { "execute": "change", - "arguments": { "device": "ide1-cd0", - "target": "/srv/images/Fedora-12-x86_64-DVD.iso" } } -<- { "return": {} } - -2. Change VNC password - --> { "execute": "change", - "arguments": { "device": "vnc", "target": "password", - "arg": "foobar1" } } -<- { "return": {} } - -EQMP { .name = "screendump", @@ -250,22 +128,6 @@ STEXI @findex screendump Save screen into PPM image @var{filename}. ETEXI -SQMP -screendump ----------- - -Save screen into PPM image. - -Arguments: - -- "filename": file path (json-string) - -Example: - --> { "execute": "screendump", "arguments": { "filename": "/tmp/image" } } -<- { "return": {} } - -EQMP { .name = "logfile", @@ -400,20 +262,6 @@ STEXI @findex stop Stop emulation. ETEXI -SQMP -stop ----- - -Stop the emulator. - -Arguments: None. - -Example: - --> { "execute": "stop" } -<- { "return": {} } - -EQMP { .name = "c|cont", @@ -429,20 +277,6 @@ STEXI @findex cont Resume emulation. ETEXI -SQMP -cont ----- - -Resume emulation. - -Arguments: None. - -Example: - --> { "execute": "cont" } -<- { "return": {} } - -EQMP { .name = "gdbserver", @@ -617,20 +451,6 @@ STEXI Reset the system. ETEXI -SQMP -system_reset ------------- - -Reset the system. - -Arguments: None. - -Example: - --> { "execute": "system_reset" } -<- { "return": {} } - -EQMP { .name = "system_powerdown", @@ -647,20 +467,6 @@ STEXI Power down the system (if supported). ETEXI -SQMP -system_powerdown ----------------- - -Send system power down event. - -Arguments: None. - -Example: - --> { "execute": "system_powerdown" } -<- { "return": {} } - -EQMP { .name = "sum", @@ -725,33 +531,6 @@ STEXI Add device. ETEXI -SQMP -device_add ----------- - -Add a device. - -Arguments: - -- "driver": the name of the new device's driver (json-string) -- "bus": the device's parent bus (device tree path, json-string, optional) -- "id": the device's ID, must be unique (json-string) -- device properties - -Example: - --> { "execute": "device_add", "arguments": { "driver": "e1000", "id": "net1" } } -<- { "return": {} } - -Notes: - -(1) For detailed information about this command, please refer to the - 'docs/qdev-device-use.txt' file. - -(2) It's possible to list device properties by running QEMU with the - "-device DEVICE,\?" command-line argument, where DEVICE is the device's name - -EQMP { .name = "device_del", @@ -768,22 +547,6 @@ STEXI Remove device @var{id}. ETEXI -SQMP -device_del ----------- - -Remove a device. - -Arguments: - -- "id": the device's ID (json-string) - -Example: - --> { "execute": "device_del", "arguments": { "id": "net1" } } -<- { "return": {} } - -EQMP { .name = "cpu", @@ -799,24 +562,6 @@ STEXI @findex cpu Set the default CPU. ETEXI -SQMP -cpu ---- - -Set the default CPU. - -Arguments: - -- "index": the CPU's index (json-int) - -Example: - --> { "execute": "cpu", "arguments": { "index": 0 } } -<- { "return": {} } - -Note: CPUs' indexes are obtained with the 'query-cpus' command. - -EQMP { .name = "mouse_move", @@ -920,29 +665,6 @@ STEXI @findex memsave save to disk virtual memory dump starting at @var{addr} of size @var{size}. ETEXI -SQMP -memsave -------- - -Save to disk virtual memory dump starting at 'val' of size 'size'. - -Arguments: - -- "val": the starting address (json-int) -- "size": the memory size, in bytes (json-int) -- "filename": file path (json-string) - -Example: - --> { "execute": "memsave", - "arguments": { "val": 10, - "size": 100, - "filename": "/tmp/virtual-mem-dump" } } -<- { "return": {} } - -Note: Depends on the current CPU. - -EQMP { .name = "pmemsave", @@ -958,27 +680,6 @@ STEXI @findex pmemsave save to disk physical memory dump starting at @var{addr} of size @var{size}. ETEXI -SQMP -pmemsave --------- - -Save to disk physical memory dump starting at 'val' of size 'size'. - -Arguments: - -- "val": the starting address (json-int) -- "size": the memory size, in bytes (json-int) -- "filename": file path (json-string) - -Example: - --> { "execute": "pmemsave", - "arguments": { "val": 10, - "size": 100, - "filename": "/tmp/physical-mem-dump" } } -<- { "return": {} } - -EQMP { .name = "boot_set", @@ -1035,32 +736,6 @@ Migrate to @var{uri} (using -d to not wait for completion). -b for migration with full copy of disk -i for migration with incremental copy of disk (base image is shared) ETEXI -SQMP -migrate -------- - -Migrate to URI. - -Arguments: - -- "blk": block migration, full disk copy (json-bool, optional) -- "inc": incremental disk copy (json-bool, optional) -- "uri": Destination URI (json-string) - -Example: - --> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } } -<- { "return": {} } - -Notes: - -(1) The 'query-migrate' command should be used to check migration's progress - and final result (this information is provided by the 'status' member) -(2) All boolean arguments default to false -(3) The user Monitor's "detach" argument is invalid in QMP and should not - be used - -EQMP { .name = "migrate_cancel", @@ -1076,20 +751,6 @@ STEXI @findex migrate_cancel Cancel the current VM migration. ETEXI -SQMP -migrate_cancel --------------- - -Cancel the current migration. - -Arguments: None. - -Example: - --> { "execute": "migrate_cancel" } -<- { "return": {} } - -EQMP { .name = "migrate_set_speed", @@ -1105,22 +766,6 @@ STEXI @findex migrate_set_speed Set maximum speed to @var{value} (in bytes) for migrations. ETEXI -SQMP -migrate_set_speed ------------------ - -Set maximum speed for migrations. - -Arguments: - -- "value": maximum speed, in bytes per second (json-number) - -Example: - --> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } } -<- { "return": {} } - -EQMP { .name = "migrate_set_downtime", @@ -1136,22 +781,6 @@ STEXI @findex migrate_set_downtime Set maximum tolerated downtime (in seconds) for migration. ETEXI -SQMP -migrate_set_downtime --------------------- - -Set maximum tolerated downtime (in seconds) for migrations. - -Arguments: - -- "value": maximum downtime (json-number) - -Example: - --> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } } -<- { "return": {} } - -EQMP #if defined(TARGET_I386) { @@ -1247,28 +876,6 @@ STEXI @findex netdev_add Add host network device. ETEXI -SQMP -netdev_add ----------- - -Add host network device. - -Arguments: - -- "type": the device type, "tap", "user", ... (json-string) -- "id": the device's ID, must be unique (json-string) -- device options - -Example: - --> { "execute": "netdev_add", "arguments": { "type": "user", "id": "netdev1" } } -<- { "return": {} } - -Note: The supported device options are the same ones supported by the '-net' - command-line argument, which are listed in the '-help' output or QEMU's - manual - -EQMP { .name = "netdev_del", @@ -1284,22 +891,6 @@ STEXI @findex netdev_del Remove host network device. ETEXI -SQMP -netdev_del ----------- - -Remove host network device. - -Arguments: - -- "id": the device's ID, must be unique (json-string) - -Example: - --> { "execute": "netdev_del", "arguments": { "id": "netdev1" } } -<- { "return": {} } - -EQMP #ifdef CONFIG_SLIRP { @@ -1347,22 +938,6 @@ STEXI @findex balloon Request VM to change its memory allocation to @var{value} (in MB). ETEXI -SQMP -balloon -------- - -Request VM to change its memory allocation (in bytes). - -Arguments: - -- "value": New memory allocation (json-int) - -Example: - --> { "execute": "balloon", "arguments": { "value": 536870912 } } -<- { "return": {} } - -EQMP { .name = "set_link", @@ -1378,23 +953,6 @@ STEXI @findex set_link Switch link @var{name} on (i.e. up) or off (i.e. down). ETEXI -SQMP -set_link --------- - -Change the link status of a network adapter. - -Arguments: - -- "name": network device name (json-string) -- "up": status is up (json-bool) - -Example: - --> { "execute": "set_link", "arguments": { "name": "e1000.0", "up": false } } -<- { "return": {} } - -EQMP { .name = "watchdog_action", @@ -1524,22 +1082,6 @@ If a file descriptor is passed alongside this command using the SCM_RIGHTS mechanism on unix sockets, it is stored using the name @var{fdname} for later use by other monitor commands. ETEXI -SQMP -getfd ------ - -Receive a file descriptor via SCM rights and assign it a name. - -Arguments: - -- "fdname": file descriptor name (json-string) - -Example: - --> { "execute": "getfd", "arguments": { "fdname": "fd1" } } -<- { "return": {} } - -EQMP { .name = "closefd", @@ -1557,22 +1099,6 @@ Close the file descriptor previously assigned to @var{fdname} using the @code{getfd} command. This is only needed if the file descriptor was never used by another monitor command. ETEXI -SQMP -closefd -------- - -Close a file descriptor previously passed via SCM rights. - -Arguments: - -- "fdname": file descriptor name (json-string) - -Example: - --> { "execute": "closefd", "arguments": { "fdname": "fd1" } } -<- { "return": {} } - -EQMP { .name = "block_passwd", @@ -1588,66 +1114,6 @@ STEXI @findex block_passwd Set the encrypted device @var{device} password to @var{password} ETEXI -SQMP -block_passwd ------------- - -Set the password of encrypted block devices. - -Arguments: - -- "device": device name (json-string) -- "password": password (json-string) - -Example: - --> { "execute": "block_passwd", "arguments": { "device": "ide0-hd0", - "password": "12345" } } -<- { "return": {} } - -EQMP - - { - .name = "qmp_capabilities", - .args_type = "", - .params = "", - .help = "enable QMP capabilities", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_qmp_capabilities, - }, - -STEXI -@item qmp_capabilities -@findex qmp_capabilities -Enable the specified QMP capabilities -ETEXI -SQMP -qmp_capabilities ----------------- - -Enable QMP capabilities. - -Arguments: None. - -Example: - --> { "execute": "qmp_capabilities" } -<- { "return": {} } - -Note: This command must be issued before issuing any other command. - -EQMP - - -HXCOMM Keep the 'info' command at the end! -HXCOMM This is required for the QMP documentation layout. - -SQMP - -3. Query Commands -================= - -EQMP { .name = "info", @@ -1665,579 +1131,38 @@ Show various information about the system state. @table @option @item info version show the version of QEMU -ETEXI -SQMP -query-version -------------- - -Show QEMU version. - -Return a json-object with the following information: - -- "qemu": A json-object containing three integer values: - - "major": QEMU's major version (json-int) - - "minor": QEMU's minor version (json-int) - - "micro": QEMU's micro version (json-int) -- "package": package's version (json-string) - -Example: - --> { "execute": "query-version" } -<- { - "return":{ - "qemu":{ - "major":0, - "minor":11, - "micro":5 - }, - "package":"" - } - } - -EQMP - -STEXI -@item info commands -list QMP available commands -ETEXI -SQMP -query-commands --------------- - -List QMP available commands. - -Each command is represented by a json-object, the returned value is a json-array -of all commands. - -Each json-object contain: - -- "name": command's name (json-string) - -Example: - --> { "execute": "query-commands" } -<- { - "return":[ - { - "name":"query-balloon" - }, - { - "name":"system_powerdown" - } - ] - } - -Note: This example has been shortened as the real response is too long. - -EQMP - -STEXI @item info network show the various VLANs and the associated devices -ETEXI - -STEXI @item info chardev show the character devices -ETEXI -SQMP -query-chardev -------------- - -Each device is represented by a json-object. The returned value is a json-array -of all devices. - -Each json-object contain the following: - -- "label": device's label (json-string) -- "filename": device's file (json-string) - -Example: - --> { "execute": "query-chardev" } -<- { - "return":[ - { - "label":"monitor", - "filename":"stdio" - }, - { - "label":"serial0", - "filename":"vc" - } - ] - } - -EQMP - -STEXI @item info block show the block devices -ETEXI -SQMP -query-block ------------ - -Show the block devices. - -Each block device information is stored in a json-object and the returned value -is a json-array of all devices. - -Each json-object contain the following: - -- "device": device name (json-string) -- "type": device type (json-string) - - Possible values: "hd", "cdrom", "floppy", "unknown" -- "removable": true if the device is removable, false otherwise (json-bool) -- "locked": true if the device is locked, false otherwise (json-bool) -- "inserted": only present if the device is inserted, it is a json-object - containing the following: - - "file": device file name (json-string) - - "ro": true if read-only, false otherwise (json-bool) - - "drv": driver format name (json-string) - - Possible values: "blkdebug", "bochs", "cloop", "cow", "dmg", - "file", "file", "ftp", "ftps", "host_cdrom", - "host_device", "host_floppy", "http", "https", - "nbd", "parallels", "qcow", "qcow2", "raw", - "tftp", "vdi", "vmdk", "vpc", "vvfat" - - "backing_file": backing file name (json-string, optional) - - "encrypted": true if encrypted, false otherwise (json-bool) - -Example: - --> { "execute": "query-block" } -<- { - "return":[ - { - "device":"ide0-hd0", - "locked":false, - "removable":false, - "inserted":{ - "ro":false, - "drv":"qcow2", - "encrypted":false, - "file":"disks/test.img" - }, - "type":"hd" - }, - { - "device":"ide1-cd0", - "locked":false, - "removable":true, - "type":"cdrom" - }, - { - "device":"floppy0", - "locked":false, - "removable":true, - "type": "floppy" - }, - { - "device":"sd0", - "locked":false, - "removable":true, - "type":"floppy" - } - ] - } - -EQMP - -STEXI @item info blockstats show block device statistics -ETEXI -SQMP -query-blockstats ----------------- - -Show block device statistics. - -Each device statistic information is stored in a json-object and the returned -value is a json-array of all devices. - -Each json-object contain the following: - -- "device": device name (json-string) -- "stats": A json-object with the statistics information, it contains: - - "rd_bytes": bytes read (json-int) - - "wr_bytes": bytes written (json-int) - - "rd_operations": read operations (json-int) - - "wr_operations": write operations (json-int) - - "wr_highest_offset": Highest offset of a sector written since the - BlockDriverState has been opened (json-int) -- "parent": Contains recursively the statistics of the underlying - protocol (e.g. the host file for a qcow2 image). If there is - no underlying protocol, this field is omitted - (json-object, optional) - -Example: - --> { "execute": "query-blockstats" } -<- { - "return":[ - { - "device":"ide0-hd0", - "parent":{ - "stats":{ - "wr_highest_offset":3686448128, - "wr_bytes":9786368, - "wr_operations":751, - "rd_bytes":122567168, - "rd_operations":36772 - } - }, - "stats":{ - "wr_highest_offset":2821110784, - "wr_bytes":9786368, - "wr_operations":692, - "rd_bytes":122739200, - "rd_operations":36604 - } - }, - { - "device":"ide1-cd0", - "stats":{ - "wr_highest_offset":0, - "wr_bytes":0, - "wr_operations":0, - "rd_bytes":0, - "rd_operations":0 - } - }, - { - "device":"floppy0", - "stats":{ - "wr_highest_offset":0, - "wr_bytes":0, - "wr_operations":0, - "rd_bytes":0, - "rd_operations":0 - } - }, - { - "device":"sd0", - "stats":{ - "wr_highest_offset":0, - "wr_bytes":0, - "wr_operations":0, - "rd_bytes":0, - "rd_operations":0 - } - } - ] - } - -EQMP - -STEXI @item info registers show the cpu registers @item info cpus show infos for each CPU -ETEXI -SQMP -query-cpus ----------- - -Show CPU information. - -Return a json-array. Each CPU is represented by a json-object, which contains: - -- "CPU": CPU index (json-int) -- "current": true if this is the current CPU, false otherwise (json-bool) -- "halted": true if the cpu is halted, false otherwise (json-bool) -- Current program counter. The key's name depends on the architecture: - "pc": i386/x86_64 (json-int) - "nip": PPC (json-int) - "pc" and "npc": sparc (json-int) - "PC": mips (json-int) - -Example: - --> { "execute": "query-cpus" } -<- { - "return":[ - { - "CPU":0, - "current":true, - "halted":false, - "pc":3227107138 - }, - { - "CPU":1, - "current":false, - "halted":true, - "pc":7108165 - } - ] - } - -EQMP - -STEXI @item info history show the command line history @item info irq show the interrupts statistics (if available) @item info pic show i8259 (PIC) state -ETEXI - -STEXI @item info pci show emulated PCI device info -ETEXI -SQMP -query-pci ---------- - -PCI buses and devices information. - -The returned value is a json-array of all buses. Each bus is represented by -a json-object, which has a key with a json-array of all PCI devices attached -to it. Each device is represented by a json-object. - -The bus json-object contains the following: - -- "bus": bus number (json-int) -- "devices": a json-array of json-objects, each json-object represents a - PCI device - -The PCI device json-object contains the following: - -- "bus": identical to the parent's bus number (json-int) -- "slot": slot number (json-int) -- "function": function number (json-int) -- "class_info": a json-object containing: - - "desc": device class description (json-string, optional) - - "class": device class number (json-int) -- "id": a json-object containing: - - "device": device ID (json-int) - - "vendor": vendor ID (json-int) -- "irq": device's IRQ if assigned (json-int, optional) -- "qdev_id": qdev id string (json-string) -- "pci_bridge": It's a json-object, only present if this device is a - PCI bridge, contains: - - "bus": bus number (json-int) - - "secondary": secondary bus number (json-int) - - "subordinate": subordinate bus number (json-int) - - "io_range": I/O memory range information, a json-object with the - following members: - - "base": base address, in bytes (json-int) - - "limit": limit address, in bytes (json-int) - - "memory_range": memory range information, a json-object with the - following members: - - "base": base address, in bytes (json-int) - - "limit": limit address, in bytes (json-int) - - "prefetchable_range": Prefetchable memory range information, a - json-object with the following members: - - "base": base address, in bytes (json-int) - - "limit": limit address, in bytes (json-int) - - "devices": a json-array of PCI devices if there's any attached, each - each element is represented by a json-object, which contains - the same members of the 'PCI device json-object' described - above (optional) -- "regions": a json-array of json-objects, each json-object represents a - memory region of this device - -The memory range json-object contains the following: - -- "base": base memory address (json-int) -- "limit": limit value (json-int) - -The region json-object can be an I/O region or a memory region, an I/O region -json-object contains the following: - -- "type": "io" (json-string, fixed) -- "bar": BAR number (json-int) -- "address": memory address (json-int) -- "size": memory size (json-int) - -A memory region json-object contains the following: - -- "type": "memory" (json-string, fixed) -- "bar": BAR number (json-int) -- "address": memory address (json-int) -- "size": memory size (json-int) -- "mem_type_64": true or false (json-bool) -- "prefetch": true or false (json-bool) - -Example: - --> { "execute": "query-pci" } -<- { - "return":[ - { - "bus":0, - "devices":[ - { - "bus":0, - "qdev_id":"", - "slot":0, - "class_info":{ - "class":1536, - "desc":"Host bridge" - }, - "id":{ - "device":32902, - "vendor":4663 - }, - "function":0, - "regions":[ - - ] - }, - { - "bus":0, - "qdev_id":"", - "slot":1, - "class_info":{ - "class":1537, - "desc":"ISA bridge" - }, - "id":{ - "device":32902, - "vendor":28672 - }, - "function":0, - "regions":[ - - ] - }, - { - "bus":0, - "qdev_id":"", - "slot":1, - "class_info":{ - "class":257, - "desc":"IDE controller" - }, - "id":{ - "device":32902, - "vendor":28688 - }, - "function":1, - "regions":[ - { - "bar":4, - "size":16, - "address":49152, - "type":"io" - } - ] - }, - { - "bus":0, - "qdev_id":"", - "slot":2, - "class_info":{ - "class":768, - "desc":"VGA controller" - }, - "id":{ - "device":4115, - "vendor":184 - }, - "function":0, - "regions":[ - { - "prefetch":true, - "mem_type_64":false, - "bar":0, - "size":33554432, - "address":4026531840, - "type":"memory" - }, - { - "prefetch":false, - "mem_type_64":false, - "bar":1, - "size":4096, - "address":4060086272, - "type":"memory" - }, - { - "prefetch":false, - "mem_type_64":false, - "bar":6, - "size":65536, - "address":-1, - "type":"memory" - } - ] - }, - { - "bus":0, - "qdev_id":"", - "irq":11, - "slot":4, - "class_info":{ - "class":1280, - "desc":"RAM controller" - }, - "id":{ - "device":6900, - "vendor":4098 - }, - "function":0, - "regions":[ - { - "bar":0, - "size":32, - "address":49280, - "type":"io" - } - ] - } - ] - } - ] - } - -Note: This example has been shortened as the real response is too long. - -EQMP - -STEXI @item info tlb show virtual to physical memory mappings (i386 only) @item info mem show the active virtual memory mappings (i386 only) -ETEXI - -STEXI @item info jit show dynamic compiler info @item info kvm show KVM information @item info numa show NUMA information -ETEXI - -STEXI @item info kvm show KVM information -ETEXI -SQMP -query-kvm ---------- - -Show KVM information. - -Return a json-object with the following information: - -- "enabled": true if KVM support is enabled, false otherwise (json-bool) -- "present": true if QEMU has KVM support, false otherwise (json-bool) - -Example: - --> { "execute": "query-kvm" } -<- { "return": { "enabled": true, "present": true } } - -EQMP - -STEXI @item info usb show USB devices plugged on the virtual USB hub @item info usbhost @@ -2248,307 +1173,26 @@ show profiling information show information about active capturing @item info snapshots show list of VM snapshots -ETEXI - -STEXI @item info status show the current VM status (running|paused) -ETEXI -SQMP -query-status ------------- - -Return a json-object with the following information: - -- "running": true if the VM is running, or false if it is paused (json-bool) -- "singlestep": true if the VM is in single step mode, - false otherwise (json-bool) - -Example: - --> { "execute": "query-status" } -<- { "return": { "running": true, "singlestep": false } } - -EQMP - -STEXI @item info pcmcia show guest PCMCIA status -ETEXI - -STEXI @item info mice show which guest mouse is receiving events -ETEXI -SQMP -query-mice ----------- - -Show VM mice information. - -Each mouse is represented by a json-object, the returned value is a json-array -of all mice. - -The mouse json-object contains the following: - -- "name": mouse's name (json-string) -- "index": mouse's index (json-int) -- "current": true if this mouse is receiving events, false otherwise (json-bool) -- "absolute": true if the mouse generates absolute input events (json-bool) - -Example: - --> { "execute": "query-mice" } -<- { - "return":[ - { - "name":"QEMU Microsoft Mouse", - "index":0, - "current":false, - "absolute":false - }, - { - "name":"QEMU PS/2 Mouse", - "index":1, - "current":true, - "absolute":true - } - ] - } - -EQMP - -STEXI @item info vnc show the vnc server status -ETEXI -SQMP -query-vnc ---------- - -Show VNC server information. - -Return a json-object with server information. Connected clients are returned -as a json-array of json-objects. - -The main json-object contains the following: - -- "enabled": true or false (json-bool) -- "host": server's IP address (json-string) -- "family": address family (json-string) - - Possible values: "ipv4", "ipv6", "unix", "unknown" -- "service": server's port number (json-string) -- "auth": authentication method (json-string) - - Possible values: "invalid", "none", "ra2", "ra2ne", "sasl", "tight", - "tls", "ultra", "unknown", "vencrypt", "vencrypt", - "vencrypt+plain", "vencrypt+tls+none", - "vencrypt+tls+plain", "vencrypt+tls+sasl", - "vencrypt+tls+vnc", "vencrypt+x509+none", - "vencrypt+x509+plain", "vencrypt+x509+sasl", - "vencrypt+x509+vnc", "vnc" -- "clients": a json-array of all connected clients - -Clients are described by a json-object, each one contain the following: - -- "host": client's IP address (json-string) -- "family": address family (json-string) - - Possible values: "ipv4", "ipv6", "unix", "unknown" -- "service": client's port number (json-string) -- "x509_dname": TLS dname (json-string, optional) -- "sasl_username": SASL username (json-string, optional) - -Example: - --> { "execute": "query-vnc" } -<- { - "return":{ - "enabled":true, - "host":"0.0.0.0", - "service":"50402", - "auth":"vnc", - "family":"ipv4", - "clients":[ - { - "host":"127.0.0.1", - "service":"50401", - "family":"ipv4" - } - ] - } - } - -EQMP - -STEXI @item info name show the current VM name -ETEXI -SQMP -query-name ----------- - -Show VM name. - -Return a json-object with the following information: - -- "name": VM's name (json-string, optional) - -Example: - --> { "execute": "query-name" } -<- { "return": { "name": "qemu-name" } } - -EQMP - -STEXI @item info uuid show the current VM UUID -ETEXI -SQMP -query-uuid ----------- - -Show VM UUID. - -Return a json-object with the following information: - -- "UUID": Universally Unique Identifier (json-string) - -Example: - --> { "execute": "query-uuid" } -<- { "return": { "UUID": "550e8400-e29b-41d4-a716-446655440000" } } - -EQMP - -STEXI @item info cpustats show CPU statistics @item info usernet show user network stack connection states -ETEXI - -STEXI @item info migrate show migration status -ETEXI -SQMP -query-migrate -------------- - -Migration status. - -Return a json-object. If migration is active there will be another json-object -with RAM migration status and if block migration is active another one with -block migration status. - -The main json-object contains the following: - -- "status": migration status (json-string) - - Possible values: "active", "completed", "failed", "cancelled" -- "ram": only present if "status" is "active", it is a json-object with the - following RAM information (in bytes): - - "transferred": amount transferred (json-int) - - "remaining": amount remaining (json-int) - - "total": total (json-int) -- "disk": only present if "status" is "active" and it is a block migration, - it is a json-object with the following disk information (in bytes): - - "transferred": amount transferred (json-int) - - "remaining": amount remaining (json-int) - - "total": total (json-int) - -Examples: - -1. Before the first migration - --> { "execute": "query-migrate" } -<- { "return": {} } - -2. Migration is done and has succeeded - --> { "execute": "query-migrate" } -<- { "return": { "status": "completed" } } - -3. Migration is done and has failed - --> { "execute": "query-migrate" } -<- { "return": { "status": "failed" } } - -4. Migration is being performed and is not a block migration: - --> { "execute": "query-migrate" } -<- { - "return":{ - "status":"active", - "ram":{ - "transferred":123, - "remaining":123, - "total":246 - } - } - } - -5. Migration is being performed and is a block migration: - --> { "execute": "query-migrate" } -<- { - "return":{ - "status":"active", - "ram":{ - "total":1057024, - "remaining":1053304, - "transferred":3720 - }, - "disk":{ - "total":20971520, - "remaining":20880384, - "transferred":91136 - } - } - } - -EQMP - -STEXI @item info balloon show balloon information -ETEXI -SQMP -query-balloon -------------- - -Show balloon information. - -Make an asynchronous request for balloon info. When the request completes a -json-object will be returned containing the following data: - -- "actual": current balloon value in bytes (json-int) -- "mem_swapped_in": Amount of memory swapped in bytes (json-int, optional) -- "mem_swapped_out": Amount of memory swapped out in bytes (json-int, optional) -- "major_page_faults": Number of major faults (json-int, optional) -- "minor_page_faults": Number of minor faults (json-int, optional) -- "free_mem": Total amount of free and unused memory in - bytes (json-int, optional) -- "total_mem": Total amount of available memory in bytes (json-int, optional) - -Example: - --> { "execute": "query-balloon" } -<- { - "return":{ - "actual":1073741824, - "mem_swapped_in":0, - "mem_swapped_out":0, - "major_page_faults":142, - "minor_page_faults":239245, - "free_mem":1014185984, - "total_mem":1044668416 - } - } - -EQMP - -STEXI @item info qtree show device tree @item info qdm @@ -2567,8 +1211,6 @@ show available trace events and their state ETEXI #endif -HXCOMM DO NOT add new commands after 'info', move your addition before it! - STEXI @end table ETEXI From 0e19a62770a7a0876869432c69a5a5f2d7646e12 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 16 Sep 2010 10:47:54 -0300 Subject: [PATCH 17/23] Monitor: Drop monitor_cmd_user_only() This function was only needed when QMP and HMP were sharing dispatch tables, this is no longer true so just drop it. Signed-off-by: Luiz Capitulino --- monitor.c | 5 ----- monitor.h | 1 - 2 files changed, 6 deletions(-) diff --git a/monitor.c b/monitor.c index b43277e580..8f90250692 100644 --- a/monitor.c +++ b/monitor.c @@ -340,11 +340,6 @@ static inline bool monitor_handler_is_async(const mon_cmd_t *cmd) return cmd->flags & MONITOR_CMD_ASYNC; } -static inline bool monitor_cmd_user_only(const mon_cmd_t *cmd) -{ - return (cmd->flags & MONITOR_CMD_USER_ONLY); -} - static inline int monitor_has_error(const Monitor *mon) { return mon->error != NULL; diff --git a/monitor.h b/monitor.h index f2122b5884..44c3625824 100644 --- a/monitor.h +++ b/monitor.h @@ -18,7 +18,6 @@ extern Monitor *default_mon; /* flags for monitor commands */ #define MONITOR_CMD_ASYNC 0x0001 -#define MONITOR_CMD_USER_ONLY 0x0002 /* QMP events */ typedef enum MonitorEvent { From 9e80721effc4457c1fca38d3b3e9de6a32d5bcd7 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 16 Sep 2010 10:58:59 -0300 Subject: [PATCH 18/23] Monitor: Rename monitor_handler_ported() That name makes no sense anymore, as dispatch tables have been split, a better name is handler_is_qobject(), which really communicates the handler's type. Signed-off-by: Luiz Capitulino --- monitor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/monitor.c b/monitor.c index 8f90250692..b9dab78840 100644 --- a/monitor.c +++ b/monitor.c @@ -330,7 +330,7 @@ static int monitor_fprintf(FILE *stream, const char *fmt, ...) static void monitor_user_noop(Monitor *mon, const QObject *data) { } -static inline int monitor_handler_ported(const mon_cmd_t *cmd) +static inline int handler_is_qobject(const mon_cmd_t *cmd) { return cmd->user_print != NULL; } @@ -654,7 +654,7 @@ static void do_info(Monitor *mon, const QDict *qdict) if (monitor_handler_is_async(cmd)) { user_async_info_handler(mon, cmd); - } else if (monitor_handler_ported(cmd)) { + } else if (handler_is_qobject(cmd)) { QObject *info_data = NULL; cmd->mhandler.info_new(mon, &info_data); @@ -3916,7 +3916,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline) if (monitor_handler_is_async(cmd)) { user_async_cmd_handler(mon, cmd, qdict); - } else if (monitor_handler_ported(cmd)) { + } else if (handler_is_qobject(cmd)) { monitor_call_handler(mon, cmd, qdict); } else { cmd->mhandler.cmd(mon, qdict); From 4903de0cebb6306e8c660dc0ce3e66fe3b5c35f9 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 16 Sep 2010 11:01:32 -0300 Subject: [PATCH 19/23] Monitor: Rename monitor_handler_is_async() Let's follow the convention introduced by the previous commit and call it handler_is_async(). Signed-off-by: Luiz Capitulino --- monitor.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/monitor.c b/monitor.c index b9dab78840..7959504595 100644 --- a/monitor.c +++ b/monitor.c @@ -335,7 +335,7 @@ static inline int handler_is_qobject(const mon_cmd_t *cmd) return cmd->user_print != NULL; } -static inline bool monitor_handler_is_async(const mon_cmd_t *cmd) +static inline bool handler_is_async(const mon_cmd_t *cmd) { return cmd->flags & MONITOR_CMD_ASYNC; } @@ -652,7 +652,7 @@ static void do_info(Monitor *mon, const QDict *qdict) goto help; } - if (monitor_handler_is_async(cmd)) { + if (handler_is_async(cmd)) { user_async_info_handler(mon, cmd); } else if (handler_is_qobject(cmd)) { QObject *info_data = NULL; @@ -3914,7 +3914,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline) if (!cmd) goto out; - if (monitor_handler_is_async(cmd)) { + if (handler_is_async(cmd)) { user_async_cmd_handler(mon, cmd, qdict); } else if (handler_is_qobject(cmd)) { monitor_call_handler(mon, cmd, qdict); @@ -4411,7 +4411,7 @@ static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd) { QObject *ret_data = NULL; - if (monitor_handler_is_async(cmd)) { + if (handler_is_async(cmd)) { qmp_async_info_handler(mon, cmd); if (monitor_has_error(mon)) { monitor_protocol_emitter(mon, NULL); @@ -4485,7 +4485,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) if (query_cmd) { qmp_call_query_cmd(mon, cmd); - } else if (monitor_handler_is_async(cmd)) { + } else if (handler_is_async(cmd)) { err = qmp_async_cmd_handler(mon, cmd, args); if (err) { /* emit the error response */ From de79ba6f53fa78a6132a67c7ff134014dc8479e7 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 16 Sep 2010 11:06:11 -0300 Subject: [PATCH 20/23] Monitor: Directly call QObject handlers This avoids handle_user_command() calling monitor_call_handler(), which is currently shared with QMP. Signed-off-by: Luiz Capitulino --- monitor.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/monitor.c b/monitor.c index 7959504595..03f3c186fd 100644 --- a/monitor.c +++ b/monitor.c @@ -3917,7 +3917,15 @@ static void handle_user_command(Monitor *mon, const char *cmdline) if (handler_is_async(cmd)) { user_async_cmd_handler(mon, cmd, qdict); } else if (handler_is_qobject(cmd)) { - monitor_call_handler(mon, cmd, qdict); + QObject *data = NULL; + + /* XXX: ignores the error code */ + cmd->mhandler.cmd_new(mon, qdict, &data); + assert(!monitor_has_error(mon)); + if (data) { + cmd->user_print(mon, data); + qobject_decref(data); + } } else { cmd->mhandler.cmd(mon, qdict); } From fc29df759e7499446220349809a920ed2dfbc466 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 16 Sep 2010 11:11:18 -0300 Subject: [PATCH 21/23] QMP: Introduce qmp_call_cmd() Calls a QObject handler and emits the QMP response, also drops monitor_call_handler() which is now unused. Signed-off-by: Luiz Capitulino --- monitor.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/monitor.c b/monitor.c index 03f3c186fd..3f3c9bf3da 100644 --- a/monitor.c +++ b/monitor.c @@ -3880,29 +3880,6 @@ static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret) } } -static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd, - const QDict *params) -{ - int ret; - QObject *data = NULL; - - mon_print_count_init(mon); - - ret = cmd->mhandler.cmd_new(mon, params, &data); - handler_audit(mon, cmd, ret); - - if (monitor_ctrl_mode(mon)) { - /* Monitor Protocol */ - monitor_protocol_emitter(mon, data); - } else { - /* User Protocol */ - if (data) - cmd->user_print(mon, data); - } - - qobject_decref(data); -} - static void handle_user_command(Monitor *mon, const char *cmdline) { QDict *qdict; @@ -4433,6 +4410,20 @@ static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd) } } +static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd, + const QDict *params) +{ + int ret; + QObject *data = NULL; + + mon_print_count_init(mon); + + ret = cmd->mhandler.cmd_new(mon, params, &data); + handler_audit(mon, cmd, ret); + monitor_protocol_emitter(mon, data); + qobject_decref(data); +} + static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { int err; @@ -4500,7 +4491,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) goto err_out; } } else { - monitor_call_handler(mon, cmd, args); + qmp_call_cmd(mon, cmd, args); } goto out; From acd0a09337c51d1cd6861f68add45e94361c8974 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 30 Sep 2010 16:00:22 -0300 Subject: [PATCH 22/23] Monitor: Rename the qemu-monitor.hx file Let's be consistent and call it hmp-commands.hx, so that we have qmp-commands.hx for QMP and hmp-commands.hx for HMP. Please, note that this commit doesn't touch qemu-monitor.texi. All texi files have the qemu- prefix and I don't think it's worth changing that. Signed-off-by: Luiz Capitulino --- Makefile | 2 +- Makefile.target | 6 +++--- qemu-monitor.hx => hmp-commands.hx | 0 monitor.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename qemu-monitor.hx => hmp-commands.hx (100%) diff --git a/Makefile b/Makefile index 938d88bc21..3f42fe267b 100644 --- a/Makefile +++ b/Makefile @@ -249,7 +249,7 @@ TEXIFLAG=$(if $(V),,--quiet) qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@") -qemu-monitor.texi: $(SRC_PATH)/qemu-monitor.hx +qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@") QMP/qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx diff --git a/Makefile.target b/Makefile.target index 3a1fa7eff9..518ea27109 100644 --- a/Makefile.target +++ b/Makefile.target @@ -307,7 +307,7 @@ obj-alpha-y = alpha_palcode.o main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) -monitor.o: qemu-monitor.h qmp-commands.h +monitor.o: hmp-commands.h qmp-commands.h $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) @@ -328,7 +328,7 @@ $(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@") -qemu-monitor.h: $(SRC_PATH)/qemu-monitor.hx +hmp-commands.h: $(SRC_PATH)/hmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") qmp-commands.h: $(SRC_PATH)/qmp-commands.hx @@ -337,7 +337,7 @@ qmp-commands.h: $(SRC_PATH)/qmp-commands.hx clean: rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o rm -f *.d */*.d tcg/*.o ide/*.o - rm -f qemu-monitor.h qmp-commands.h gdbstub-xml.c + rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c install: all ifneq ($(PROGS),) diff --git a/qemu-monitor.hx b/hmp-commands.hx similarity index 100% rename from qemu-monitor.hx rename to hmp-commands.hx diff --git a/monitor.c b/monitor.c index 3f3c9bf3da..4148dd9de5 100644 --- a/monitor.c +++ b/monitor.c @@ -2332,11 +2332,11 @@ int monitor_get_fd(Monitor *mon, const char *fdname) } static const mon_cmd_t mon_cmds[] = { -#include "qemu-monitor.h" +#include "hmp-commands.h" { NULL, NULL, }, }; -/* Please update qemu-monitor.hx when adding or changing commands */ +/* Please update hmp-commands.hx when adding or changing commands */ static const mon_cmd_t info_cmds[] = { { .name = "version", From a18b2ce2ed9dc747c2ebab5a220517624e4ff3df Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 10 Sep 2010 14:05:23 -0300 Subject: [PATCH 23/23] QMP/README: Update QMP homepage address Signed-off-by: Luiz Capitulino --- QMP/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QMP/README b/QMP/README index 7e2b51a9b2..80503f2d7a 100644 --- a/QMP/README +++ b/QMP/README @@ -88,4 +88,4 @@ doing any code change. This is so because: Homepage -------- -http://www.linux-kvm.org/page/MonitorProtocol +http://wiki.qemu.org/QMP