* 'l' target long (32 or 64 bit)
* 'M' just like 'l', except in user mode the value is
* multiplied by 2^20 (think Mebibyte)
- * 'f' double
- * user mode accepts an optional G, g, M, m, K, k suffix,
- * which multiplies the value by 2^30 for suffixes G and
- * g, 2^20 for M and m, 2^10 for K and k
+ * 'o' octets (aka bytes)
+ * user mode accepts an optional T, t, G, g, M, m, K, k
+ * suffix, which multiplies the value by 2^40 for
+ * suffixes T and t, 2^30 for suffixes G and g, 2^20 for
+ * M and m, 2^10 for K and k
* 'T' double
* user mode accepts an optional ms, us, ns suffix,
* which divides the value by 1e3, 1e6, 1e9, respectively
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;
}
}
-static int monitor_fprintf(FILE *stream, const char *fmt, ...)
+static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
+ const char *fmt, ...)
{
va_list ap;
va_start(ap, 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;
}
-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;
}
-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;
{
const char *tp_name = qdict_get_str(qdict, "name");
bool new_state = qdict_get_bool(qdict, "option");
- st_change_trace_event_state(tp_name, new_state);
+ int ret = st_change_trace_event_state(tp_name, new_state);
+
+ if (!ret) {
+ monitor_printf(mon, "unknown event name \"%s\"\n", tp_name);
+ }
}
static void do_trace_file(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 (monitor_handler_ported(cmd)) {
+ } else if (handler_is_qobject(cmd)) {
QObject *info_data = NULL;
cmd->mhandler.info_new(mon, &info_data);
cmd_list = qlist_new();
- for (cmd = mon_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));
- }
+ for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
+ qlist_append_obj(cmd_list, get_cmd_dict(cmd->name));
}
- for (cmd = info_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));
- }
+ for (cmd = qmp_query_cmds; cmd->name != NULL; cmd++) {
+ 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);
}
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",
.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 = "",
},
};
+static const mon_cmd_t qmp_cmds[] = {
+#include "qmp-commands.h"
+ { /* 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;
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)
{
- return search_dispatch_table(mon_cmds, cmdname);
+ return search_dispatch_table(qmp_cmds, cmdname);
}
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
qdict_put(qdict, key, qint_from_int(val));
}
break;
- case 'f':
+ case 'o':
+ {
+ ssize_t val;
+ char *end;
+
+ while (qemu_isspace(*p)) {
+ p++;
+ }
+ if (*typestr == '?') {
+ typestr++;
+ if (*p == '\0') {
+ break;
+ }
+ }
+ val = strtosz(p, &end);
+ if (val < 0) {
+ monitor_printf(mon, "invalid size\n");
+ goto fail;
+ }
+ qdict_put(qdict, key, qint_from_int(val));
+ p = end;
+ }
+ break;
case 'T':
{
double val;
if (get_double(mon, &val, &p) < 0) {
goto fail;
}
- if (c == 'f' && *p) {
- switch (*p) {
- case 'K': case 'k':
- val *= 1 << 10; p++; break;
- case 'M': case 'm':
- val *= 1 << 20; p++; break;
- case 'G': case 'g':
- val *= 1 << 30; p++; break;
- }
- }
- if (c == 'T' && p[0] && p[1] == 's') {
+ if (p[0] && p[1] == 's') {
switch (*p) {
case 'm':
val /= 1e3; p += 2; break;
}
}
-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;
if (!cmd)
goto out;
- if (monitor_handler_is_async(cmd)) {
+ if (handler_is_async(cmd)) {
user_async_cmd_handler(mon, cmd, qdict);
- } else if (monitor_handler_ported(cmd)) {
- monitor_call_handler(mon, cmd, qdict);
+ } else if (handler_is_qobject(cmd)) {
+ 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);
}
d = readdir(ffs);
if (!d)
break;
+
+ if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) {
+ continue;
+ }
+
if (strstart(d->d_name, file_prefix, NULL)) {
memcpy(file, input, input_path_len);
if (input_path_len < sizeof(file))
case 'i':
case 'l':
case 'M':
+ case 'o':
if (qobject_type(client_arg) != QTYPE_QINT) {
qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
"int");
return -1;
}
break;
- case 'f':
case 'T':
if (qobject_type(client_arg) != QTYPE_QINT &&
qobject_type(client_arg) != QTYPE_QFLOAT) {
{
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);
}
}
+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;
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;
}
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 */
goto err_out;
}
} else {
- monitor_call_handler(mon, cmd, args);
+ qmp_call_cmd(mon, cmd, args);
}
goto out;