#include "sysemu/char.h"
#include "ui/qemu-spice.h"
#include "sysemu/sysemu.h"
+#include "sysemu/numa.h"
#include "monitor/monitor.h"
#include "qemu/readline.h"
#include "ui/console.h"
#include "block/qapi.h"
#include "qapi/qmp-event.h"
#include "qapi-event.h"
+#include "sysemu/block-backend.h"
-/* for pic/irq_info */
+/* for hmp_info_irq/pic */
#if defined(TARGET_SPARC)
#include "hw/sparc/sun4m.h"
#endif
*
*/
-typedef struct MonitorCompletionData MonitorCompletionData;
-struct MonitorCompletionData {
- Monitor *mon;
- void (*user_print)(Monitor *mon, const QObject *data);
-};
-
typedef struct mon_cmd_t {
const char *name;
const char *args_type;
const char *params;
const char *help;
- void (*user_print)(Monitor *mon, const QObject *data);
union {
void (*cmd)(Monitor *mon, const QDict *qdict);
int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
- int (*cmd_async)(Monitor *mon, const QDict *params,
- MonitorCompletion *cb, void *opaque);
} mhandler;
- int flags;
/* @sub_table is a list of 2nd level of commands. If it do not exist,
* mhandler should be used. If it exist, sub_table[?].mhandler should be
* used, and mhandler of 1st level plays the role of help function.
QLIST_ENTRY(MonFdset) next;
};
-typedef struct MonitorControl {
+typedef struct {
QObject *id;
JSONMessageParser parser;
- int command_mode;
-} MonitorControl;
+ /*
+ * When a client connects, we're in capabilities negotiation mode.
+ * When command qmp_capabilities succeeds, we go into command
+ * mode.
+ */
+ bool in_command_mode; /* are we in command mode? */
+} MonitorQMP;
/*
* To prevent flooding clients, events can be throttled. The
int mux_out;
ReadLineState *rs;
- MonitorControl *mc;
+ MonitorQMP qmp;
CPUState *mon_cpu;
BlockCompletionFunc *password_completion_cb;
void *password_opaque;
static void monitor_command_cb(void *opaque, const char *cmdline,
void *readline_opaque);
-static inline int qmp_cmd_mode(const Monitor *mon)
-{
- return (mon->mc ? mon->mc->command_mode : 0);
-}
-
-/* Return true if in control mode, false otherwise */
-static inline int monitor_ctrl_mode(const Monitor *mon)
+/**
+ * Is @mon a QMP monitor?
+ */
+static inline bool monitor_is_qmp(const Monitor *mon)
{
return (mon->flags & MONITOR_USE_CONTROL);
}
-/* Return non-zero iff we have a current monitor, and it is in QMP mode. */
-int monitor_cur_is_qmp(void)
+/**
+ * Is the current monitor, if any, a QMP monitor?
+ */
+bool monitor_cur_is_qmp(void)
{
- return cur_mon && monitor_ctrl_mode(cur_mon);
+ return cur_mon && monitor_is_qmp(cur_mon);
}
void monitor_read_command(Monitor *mon, int show_prompt)
int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
void *opaque)
{
- if (monitor_ctrl_mode(mon)) {
- qerror_report(QERR_MISSING_PARAMETER, "password");
- return -EINVAL;
- } else if (mon->rs) {
+ if (mon->rs) {
readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
/* prompt is printed on return from the command handler */
return 0;
if (!mon)
return;
- if (monitor_ctrl_mode(mon)) {
+ if (monitor_is_qmp(mon)) {
return;
}
return 0;
}
-static void monitor_user_noop(Monitor *mon, const QObject *data) { }
-
-static inline int handler_is_qobject(const mon_cmd_t *cmd)
-{
- return cmd->user_print != NULL;
-}
-
-static inline bool handler_is_async(const mon_cmd_t *cmd)
-{
- return cmd->flags & MONITOR_CMD_ASYNC;
-}
-
-static inline int monitor_has_error(const Monitor *mon)
-{
- return mon->error != NULL;
-}
-
static void monitor_json_emitter(Monitor *mon, const QObject *data)
{
QString *json;
QDECREF(json);
}
-static QDict *build_qmp_error_dict(const QError *err)
+static QDict *build_qmp_error_dict(Error *err)
{
QObject *obj;
- obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %p } }",
- ErrorClass_lookup[err->err_class],
- qerror_human(err));
+ obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %s } }",
+ ErrorClass_lookup[error_get_class(err)],
+ error_get_pretty(err));
return qobject_to_qdict(obj);
}
-static void monitor_protocol_emitter(Monitor *mon, QObject *data)
+static void monitor_protocol_emitter(Monitor *mon, QObject *data,
+ Error *err)
{
QDict *qmp;
trace_monitor_protocol_emitter(mon);
- if (!monitor_has_error(mon)) {
+ if (!err) {
/* success response */
qmp = qdict_new();
if (data) {
}
} else {
/* error response */
- qmp = build_qmp_error_dict(mon->error);
- QDECREF(mon->error);
- mon->error = NULL;
+ qmp = build_qmp_error_dict(err);
}
- if (mon->mc->id) {
- qdict_put_obj(qmp, "id", mon->mc->id);
- mon->mc->id = NULL;
+ if (mon->qmp.id) {
+ qdict_put_obj(qmp, "id", mon->qmp.id);
+ mon->qmp.id = NULL;
}
monitor_json_emitter(mon, QOBJECT(qmp));
trace_monitor_protocol_event_emit(event, data);
QLIST_FOREACH(mon, &mon_list, entry) {
- if (monitor_ctrl_mode(mon) && qmp_cmd_mode(mon)) {
+ if (monitor_is_qmp(mon) && mon->qmp.in_command_mode) {
monitor_json_emitter(mon, data);
}
}
static int do_qmp_capabilities(Monitor *mon, const QDict *params,
QObject **ret_data)
{
- /* Will setup QMP capabilities in the future */
- if (monitor_ctrl_mode(mon)) {
- mon->mc->command_mode = 1;
- }
-
+ mon->qmp.in_command_mode = true;
return 0;
}
-static void handle_user_command(Monitor *mon, const char *cmdline);
+static void handle_hmp_command(Monitor *mon, const char *cmdline);
static void monitor_data_init(Monitor *mon)
{
}
}
- handle_user_command(&hmp, command_line);
+ handle_hmp_command(&hmp, command_line);
cur_mon = old_mon;
qemu_mutex_lock(&hmp.out_lock);
help_cmd(mon, qdict_get_try_str(qdict, "name"));
}
-static void do_trace_event_set_state(Monitor *mon, const QDict *qdict)
+static void hmp_trace_event(Monitor *mon, const QDict *qdict)
{
const char *tp_name = qdict_get_str(qdict, "name");
bool new_state = qdict_get_bool(qdict, "option");
qmp_trace_event_set_state(tp_name, new_state, true, true, &local_err);
if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
+ error_report_err(local_err);
}
}
#ifdef CONFIG_TRACE_SIMPLE
-static void do_trace_file(Monitor *mon, const QDict *qdict)
+static void hmp_trace_file(Monitor *mon, const QDict *qdict)
{
const char *op = qdict_get_try_str(qdict, "op");
const char *arg = qdict_get_try_str(qdict, "arg");
}
#endif
-static void user_monitor_complete(void *opaque, QObject *ret_data)
-{
- MonitorCompletionData *data = (MonitorCompletionData *)opaque;
-
- if (ret_data) {
- data->user_print(data->mon, ret_data);
- }
- monitor_resume(data->mon);
- g_free(data);
-}
-
-static void qmp_monitor_complete(void *opaque, QObject *ret_data)
-{
- monitor_protocol_emitter(opaque, ret_data);
-}
-
-static int qmp_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
- const QDict *params)
-{
- return cmd->mhandler.cmd_async(mon, params, qmp_monitor_complete, mon);
-}
-
-static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
- const QDict *params)
-{
- int ret;
-
- MonitorCompletionData *cb_data = g_malloc(sizeof(*cb_data));
- cb_data->mon = mon;
- cb_data->user_print = cmd->user_print;
- monitor_suspend(mon);
- ret = cmd->mhandler.cmd_async(mon, params,
- user_monitor_complete, cb_data);
- if (ret < 0) {
- monitor_resume(mon);
- g_free(cb_data);
- }
-}
-
-static void do_info_help(Monitor *mon, const QDict *qdict)
+static void hmp_info_help(Monitor *mon, const QDict *qdict)
{
help_cmd(mon, "info");
}
return cpu->cpu_index;
}
-static void do_info_registers(Monitor *mon, const QDict *qdict)
+static void hmp_info_registers(Monitor *mon, const QDict *qdict)
{
CPUState *cpu;
CPUArchState *env;
cpu_dump_state(cpu, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
}
-static void do_info_jit(Monitor *mon, const QDict *qdict)
+static void hmp_info_jit(Monitor *mon, const QDict *qdict)
{
dump_exec_info((FILE *)mon, monitor_fprintf);
dump_drift_info((FILE *)mon, monitor_fprintf);
}
-static void do_info_opcount(Monitor *mon, const QDict *qdict)
+static void hmp_info_opcount(Monitor *mon, const QDict *qdict)
{
dump_opcount_info((FILE *)mon, monitor_fprintf);
}
-static void do_info_history(Monitor *mon, const QDict *qdict)
+static void hmp_info_history(Monitor *mon, const QDict *qdict)
{
int i;
const char *str;
}
}
-static void do_info_cpu_stats(Monitor *mon, const QDict *qdict)
+static void hmp_info_cpustats(Monitor *mon, const QDict *qdict)
{
CPUState *cpu;
CPUArchState *env;
cpu_dump_statistics(cpu, (FILE *)mon, &monitor_fprintf, 0);
}
-static void do_trace_print_events(Monitor *mon, const QDict *qdict)
+static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
{
TraceEventInfoList *events = qmp_trace_event_get_state("*", NULL);
TraceEventInfoList *elem;
qapi_free_TraceEventInfoList(events);
}
-static int client_migrate_info(Monitor *mon, const QDict *qdict,
- MonitorCompletion cb, void *opaque)
+void qmp_client_migrate_info(const char *protocol, const char *hostname,
+ bool has_port, int64_t port,
+ bool has_tls_port, int64_t tls_port,
+ bool has_cert_subject, const char *cert_subject,
+ Error **errp)
{
- const char *protocol = qdict_get_str(qdict, "protocol");
- const char *hostname = qdict_get_str(qdict, "hostname");
- const char *subject = qdict_get_try_str(qdict, "cert-subject");
- int port = qdict_get_try_int(qdict, "port", -1);
- int tls_port = qdict_get_try_int(qdict, "tls-port", -1);
- Error *err;
- int ret;
-
if (strcmp(protocol, "spice") == 0) {
- if (!qemu_using_spice(&err)) {
- qerror_report_err(err);
- return -1;
+ if (!qemu_using_spice(errp)) {
+ return;
}
- if (port == -1 && tls_port == -1) {
- qerror_report(QERR_MISSING_PARAMETER, "port/tls-port");
- return -1;
+ if (!has_port && !has_tls_port) {
+ error_set(errp, QERR_MISSING_PARAMETER, "port/tls-port");
+ return;
}
- ret = qemu_spice_migrate_info(hostname, port, tls_port, subject,
- cb, opaque);
- if (ret != 0) {
- qerror_report(QERR_UNDEFINED_ERROR);
- return -1;
+ if (qemu_spice_migrate_info(hostname,
+ has_port ? port : -1,
+ has_tls_port ? tls_port : -1,
+ cert_subject)) {
+ error_set(errp, QERR_UNDEFINED_ERROR);
+ return;
}
- return 0;
+ return;
}
- qerror_report(QERR_INVALID_PARAMETER, "protocol");
- return -1;
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "spice");
}
-static void do_logfile(Monitor *mon, const QDict *qdict)
+static void hmp_logfile(Monitor *mon, const QDict *qdict)
{
qemu_set_log_filename(qdict_get_str(qdict, "filename"));
}
-static void do_log(Monitor *mon, const QDict *qdict)
+static void hmp_log(Monitor *mon, const QDict *qdict)
{
int mask;
const char *items = qdict_get_str(qdict, "items");
qemu_set_log(mask);
}
-static void do_singlestep(Monitor *mon, const QDict *qdict)
+static void hmp_singlestep(Monitor *mon, const QDict *qdict)
{
const char *option = qdict_get_try_str(qdict, "option");
if (!option || !strcmp(option, "on")) {
}
}
-static void do_gdbserver(Monitor *mon, const QDict *qdict)
+static void hmp_gdbserver(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_try_str(qdict, "device");
if (!device)
}
}
-static void do_watchdog_action(Monitor *mon, const QDict *qdict)
+static void hmp_watchdog_action(Monitor *mon, const QDict *qdict)
{
const char *action = qdict_get_str(qdict, "action");
if (select_watchdog_action(action) == -1) {
}
}
-static void do_memory_dump(Monitor *mon, const QDict *qdict)
+static void hmp_memory_dump(Monitor *mon, const QDict *qdict)
{
int count = qdict_get_int(qdict, "count");
int format = qdict_get_int(qdict, "format");
memory_dump(mon, count, format, size, addr, 0);
}
-static void do_physical_memory_dump(Monitor *mon, const QDict *qdict)
+static void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
{
int count = qdict_get_int(qdict, "count");
int format = qdict_get_int(qdict, "format");
monitor_printf(mon, "\n");
}
-static void do_sum(Monitor *mon, const QDict *qdict)
+static void hmp_sum(Monitor *mon, const QDict *qdict)
{
uint32_t addr;
uint16_t sum;
sum = 0;
for(addr = start; addr < (start + size); addr++) {
- uint8_t val = ldub_phys(&address_space_memory, addr);
+ uint8_t val = address_space_ldub(&address_space_memory, addr,
+ MEMTXATTRS_UNSPECIFIED, NULL);
/* BSD sum algorithm ('sum' Unix command) */
sum = (sum >> 1) | (sum << 15);
sum += val;
static int mouse_button_state;
-static void do_mouse_move(Monitor *mon, const QDict *qdict)
+static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
{
int dx, dy, dz, button;
const char *dx_str = qdict_get_str(qdict, "dx_str");
qemu_input_event_sync();
}
-static void do_mouse_button(Monitor *mon, const QDict *qdict)
+static void hmp_mouse_button(Monitor *mon, const QDict *qdict)
{
static uint32_t bmap[INPUT_BUTTON_MAX] = {
[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
mouse_button_state = button_state;
}
-static void do_ioport_read(Monitor *mon, const QDict *qdict)
+static void hmp_ioport_read(Monitor *mon, const QDict *qdict)
{
int size = qdict_get_int(qdict, "size");
int addr = qdict_get_int(qdict, "addr");
suffix, addr, size * 2, val);
}
-static void do_ioport_write(Monitor *mon, const QDict *qdict)
+static void hmp_ioport_write(Monitor *mon, const QDict *qdict)
{
int size = qdict_get_int(qdict, "size");
int addr = qdict_get_int(qdict, "addr");
}
}
-static void do_boot_set(Monitor *mon, const QDict *qdict)
+static void hmp_boot_set(Monitor *mon, const QDict *qdict)
{
Error *local_err = NULL;
const char *bootdevice = qdict_get_str(qdict, "bootdevice");
}
#endif
-static void tlb_info(Monitor *mon, const QDict *qdict)
+static void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
CPUArchState *env;
}
#endif
-static void mem_info(Monitor *mon, const QDict *qdict)
+static void hmp_info_mem(Monitor *mon, const QDict *qdict)
{
CPUArchState *env;
tlb->d, tlb->wt);
}
-static void tlb_info(Monitor *mon, const QDict *qdict)
+static void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
CPUArchState *env = mon_get_cpu();
int i;
#endif
#if defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_XTENSA)
-static void tlb_info(Monitor *mon, const QDict *qdict)
+static void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
CPUArchState *env1 = mon_get_cpu();
}
#endif
-static void do_info_mtree(Monitor *mon, const QDict *qdict)
+static void hmp_info_mtree(Monitor *mon, const QDict *qdict)
{
mtree_info((fprintf_function)monitor_printf, mon);
}
-static void do_info_numa(Monitor *mon, const QDict *qdict)
+static void hmp_info_numa(Monitor *mon, const QDict *qdict)
{
int i;
CPUState *cpu;
#ifdef CONFIG_PROFILER
-int64_t qemu_time;
+int64_t tcg_time;
int64_t dev_time;
-static void do_info_profile(Monitor *mon, const QDict *qdict)
+static void hmp_info_profile(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n",
dev_time, dev_time / (double)get_ticks_per_sec());
monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n",
- qemu_time, qemu_time / (double)get_ticks_per_sec());
- qemu_time = 0;
+ tcg_time, tcg_time / (double)get_ticks_per_sec());
+ tcg_time = 0;
dev_time = 0;
}
#else
-static void do_info_profile(Monitor *mon, const QDict *qdict)
+static void hmp_info_profile(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "Internal profiler not compiled\n");
}
/* Capture support */
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
-static void do_info_capture(Monitor *mon, const QDict *qdict)
+static void hmp_info_capture(Monitor *mon, const QDict *qdict)
{
int i;
CaptureState *s;
}
}
-static void do_stop_capture(Monitor *mon, const QDict *qdict)
+static void hmp_stopcapture(Monitor *mon, const QDict *qdict)
{
int i;
int n = qdict_get_int(qdict, "n");
}
}
-static void do_wav_capture(Monitor *mon, const QDict *qdict)
+static void hmp_wavcapture(Monitor *mon, const QDict *qdict)
{
const char *path = qdict_get_str(qdict, "path");
int has_freq = qdict_haskey(qdict, "freq");
return acl;
}
-static void do_acl_show(Monitor *mon, const QDict *qdict)
+static void hmp_acl_show(Monitor *mon, const QDict *qdict)
{
const char *aclname = qdict_get_str(qdict, "aclname");
qemu_acl *acl = find_acl(mon, aclname);
}
}
-static void do_acl_reset(Monitor *mon, const QDict *qdict)
+static void hmp_acl_reset(Monitor *mon, const QDict *qdict)
{
const char *aclname = qdict_get_str(qdict, "aclname");
qemu_acl *acl = find_acl(mon, aclname);
}
}
-static void do_acl_policy(Monitor *mon, const QDict *qdict)
+static void hmp_acl_policy(Monitor *mon, const QDict *qdict)
{
const char *aclname = qdict_get_str(qdict, "aclname");
const char *policy = qdict_get_str(qdict, "policy");
}
}
-static void do_acl_add(Monitor *mon, const QDict *qdict)
+static void hmp_acl_add(Monitor *mon, const QDict *qdict)
{
const char *aclname = qdict_get_str(qdict, "aclname");
const char *match = qdict_get_str(qdict, "match");
}
}
-static void do_acl_remove(Monitor *mon, const QDict *qdict)
+static void hmp_acl_remove(Monitor *mon, const QDict *qdict)
{
const char *aclname = qdict_get_str(qdict, "aclname");
const char *match = qdict_get_str(qdict, "match");
}
#if defined(TARGET_I386)
-static void do_inject_mce(Monitor *mon, const QDict *qdict)
+static void hmp_mce(Monitor *mon, const QDict *qdict)
{
X86CPU *cpu;
CPUState *cs;
error_set(errp, QERR_FD_NOT_FOUND, fdname);
}
-static void do_loadvm(Monitor *mon, const QDict *qdict)
+static void hmp_loadvm(Monitor *mon, const QDict *qdict)
{
int saved_vm_running = runstate_is_running();
const char *name = qdict_get_str(qdict, "name");
monitor_fdset_dup_fd_find_remove(dup_fd, true);
}
-int monitor_handle_fd_param(Monitor *mon, const char *fdname)
-{
- int fd;
- Error *local_err = NULL;
-
- fd = monitor_handle_fd_param2(mon, fdname, &local_err);
- if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- }
- return fd;
-}
-
-int monitor_handle_fd_param2(Monitor *mon, const char *fdname, Error **errp)
+int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp)
{
int fd;
Error *local_err = NULL;
.args_type = "",
.params = "",
.help = "show the network state",
- .mhandler.cmd = do_info_network,
+ .mhandler.cmd = hmp_info_network,
},
{
.name = "chardev",
.args_type = "",
.params = "",
.help = "show the cpu registers",
- .mhandler.cmd = do_info_registers,
+ .mhandler.cmd = hmp_info_registers,
},
{
.name = "cpus",
.args_type = "",
.params = "",
.help = "show the command line history",
- .mhandler.cmd = do_info_history,
+ .mhandler.cmd = hmp_info_history,
},
#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \
defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64))
.params = "",
.help = "show the interrupts statistics (if available)",
#ifdef TARGET_SPARC
- .mhandler.cmd = sun4m_irq_info,
+ .mhandler.cmd = sun4m_hmp_info_irq,
#elif defined(TARGET_LM32)
- .mhandler.cmd = lm32_irq_info,
+ .mhandler.cmd = lm32_hmp_info_irq,
#else
- .mhandler.cmd = irq_info,
+ .mhandler.cmd = hmp_info_irq,
#endif
},
{
.params = "",
.help = "show i8259 (PIC) state",
#ifdef TARGET_SPARC
- .mhandler.cmd = sun4m_pic_info,
+ .mhandler.cmd = sun4m_hmp_info_pic,
#elif defined(TARGET_LM32)
- .mhandler.cmd = lm32_do_pic_info,
+ .mhandler.cmd = lm32_hmp_info_pic,
#else
- .mhandler.cmd = pic_info,
+ .mhandler.cmd = hmp_info_pic,
#endif
},
#endif
.args_type = "",
.params = "",
.help = "show virtual to physical memory mappings",
- .mhandler.cmd = tlb_info,
+ .mhandler.cmd = hmp_info_tlb,
},
#endif
#if defined(TARGET_I386)
.args_type = "",
.params = "",
.help = "show the active virtual memory mappings",
- .mhandler.cmd = mem_info,
+ .mhandler.cmd = hmp_info_mem,
},
#endif
{
.args_type = "",
.params = "",
.help = "show memory tree",
- .mhandler.cmd = do_info_mtree,
+ .mhandler.cmd = hmp_info_mtree,
},
{
.name = "jit",
.args_type = "",
.params = "",
.help = "show dynamic compiler info",
- .mhandler.cmd = do_info_jit,
+ .mhandler.cmd = hmp_info_jit,
},
{
.name = "opcount",
.args_type = "",
.params = "",
.help = "show dynamic compiler opcode counters",
- .mhandler.cmd = do_info_opcount,
+ .mhandler.cmd = hmp_info_opcount,
},
{
.name = "kvm",
.args_type = "",
.params = "",
.help = "show NUMA information",
- .mhandler.cmd = do_info_numa,
+ .mhandler.cmd = hmp_info_numa,
},
{
.name = "usb",
.args_type = "",
.params = "",
.help = "show guest USB devices",
- .mhandler.cmd = usb_info,
+ .mhandler.cmd = hmp_info_usb,
},
{
.name = "usbhost",
.args_type = "",
.params = "",
.help = "show host USB devices",
- .mhandler.cmd = usb_host_info,
+ .mhandler.cmd = hmp_info_usbhost,
},
{
.name = "profile",
.args_type = "",
.params = "",
.help = "show profiling information",
- .mhandler.cmd = do_info_profile,
+ .mhandler.cmd = hmp_info_profile,
},
{
.name = "capture",
.args_type = "",
.params = "",
.help = "show capture information",
- .mhandler.cmd = do_info_capture,
+ .mhandler.cmd = hmp_info_capture,
},
{
.name = "snapshots",
.args_type = "",
.params = "",
.help = "show the currently saved VM snapshots",
- .mhandler.cmd = do_info_snapshots,
+ .mhandler.cmd = hmp_info_snapshots,
},
{
.name = "status",
.args_type = "",
.params = "",
.help = "show CPU statistics",
- .mhandler.cmd = do_info_cpu_stats,
+ .mhandler.cmd = hmp_info_cpustats,
},
#if defined(CONFIG_SLIRP)
{
.args_type = "",
.params = "",
.help = "show user network stack connection states",
- .mhandler.cmd = do_info_usernet,
+ .mhandler.cmd = hmp_info_usernet,
},
#endif
{
.help = "show current migration capabilities",
.mhandler.cmd = hmp_info_migrate_capabilities,
},
+ {
+ .name = "migrate_parameters",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration parameters",
+ .mhandler.cmd = hmp_info_migrate_parameters,
+ },
{
.name = "migrate_cache_size",
.args_type = "",
.args_type = "",
.params = "",
.help = "show device tree",
- .mhandler.cmd = do_info_qtree,
+ .mhandler.cmd = hmp_info_qtree,
},
{
.name = "qdm",
.args_type = "",
.params = "",
.help = "show qdev device model list",
- .mhandler.cmd = do_info_qdm,
+ .mhandler.cmd = hmp_info_qdm,
+ },
+ {
+ .name = "qom-tree",
+ .args_type = "path:s?",
+ .params = "[path]",
+ .help = "show QOM composition tree",
+ .mhandler.cmd = hmp_info_qom_tree,
},
{
.name = "roms",
.args_type = "",
.params = "",
.help = "show roms",
- .mhandler.cmd = do_info_roms,
+ .mhandler.cmd = hmp_info_roms,
},
{
.name = "trace-events",
.args_type = "",
.params = "",
.help = "show available trace-events & their state",
- .mhandler.cmd = do_trace_print_events,
+ .mhandler.cmd = hmp_info_trace_events,
},
{
.name = "tpm",
}
}
-static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)
-{
- if (ret && !monitor_has_error(mon)) {
- /*
- * If it returns failure, it must have passed on error.
- *
- * Action: Report an internal error to the client if in QMP.
- */
- qerror_report(QERR_UNDEFINED_ERROR);
- }
-}
-
-static void handle_user_command(Monitor *mon, const char *cmdline)
+static void handle_hmp_command(Monitor *mon, const char *cmdline)
{
QDict *qdict;
const mon_cmd_t *cmd;
qdict = qdict_new();
cmd = monitor_parse_command(mon, cmdline, 0, mon->cmd_table, qdict);
- if (!cmd)
- goto out;
-
- if (handler_is_async(cmd)) {
- user_async_cmd_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 {
+ if (cmd) {
cmd->mhandler.cmd(mon, qdict);
}
-out:
QDECREF(qdict);
}
qapi_free_ChardevInfoList(start);
}
-void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str)
-{
- if (nb_args != 2) {
- return;
- }
- ringbuf_completion(rs, str);
-}
-
void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
{
if (nb_args != 2) {
len = strlen(str);
readline_set_completion_index(rs, len);
if (nb_args == 2) {
- NetClientState *ncs[255];
+ NetClientState *ncs[MAX_QUEUE_NUM];
int count, i;
count = qemu_find_net_clients_except(NULL, ncs,
- NET_CLIENT_OPTIONS_KIND_NONE, 255);
- for (i = 0; i < count; i++) {
+ NET_CLIENT_OPTIONS_KIND_NONE,
+ MAX_QUEUE_NUM);
+ for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
const char *name = ncs[i]->name;
if (!strncmp(str, name, len)) {
readline_add_completion(rs, name);
void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
{
int len, count, i;
- NetClientState *ncs[255];
+ NetClientState *ncs[MAX_QUEUE_NUM];
if (nb_args != 2) {
return;
len = strlen(str);
readline_set_completion_index(rs, len);
count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC,
- 255);
- for (i = 0; i < count; i++) {
+ MAX_QUEUE_NUM);
+ for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
QemuOpts *opts;
const char *name = ncs[i]->name;
if (strncmp(str, name, len)) {
}
}
+void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
+ const char *str)
+{
+ size_t len;
+
+ len = strlen(str);
+ readline_set_completion_index(rs, len);
+ if (nb_args == 2) {
+ int i;
+ for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) {
+ const char *name = MigrationParameter_lookup[i];
+ if (!strncmp(str, name, len)) {
+ readline_add_completion(rs, name);
+ }
+ }
+ }
+}
+
void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str)
{
int i;
void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
{
- NetClientState *ncs[255];
+ NetClientState *ncs[MAX_QUEUE_NUM];
int count, i, len;
len = strlen(str);
readline_set_completion_index(rs, len);
if (nb_args == 2) {
count = qemu_find_net_clients_except(NULL, ncs,
- NET_CLIENT_OPTIONS_KIND_NONE, 255);
- for (i = 0; i < count; i++) {
+ NET_CLIENT_OPTIONS_KIND_NONE,
+ MAX_QUEUE_NUM);
+ for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
int id;
char name[16];
return;
} else if (nb_args == 3) {
count = qemu_find_net_clients_except(NULL, ncs,
- NET_CLIENT_OPTIONS_KIND_NIC, 255);
- for (i = 0; i < count; i++) {
+ NET_CLIENT_OPTIONS_KIND_NIC,
+ MAX_QUEUE_NUM);
+ for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
int id;
const char *name;
if (cmd->sub_table) {
/* do the job again */
- return monitor_find_completion_by_table(mon, cmd->sub_table,
- &args[1], nb_args - 1);
+ monitor_find_completion_by_table(mon, cmd->sub_table,
+ &args[1], nb_args - 1);
+ return;
}
if (cmd->command_completion) {
- return cmd->command_completion(mon->rs, nb_args, args[nb_args - 1]);
+ cmd->command_completion(mon->rs, nb_args, args[nb_args - 1]);
+ return;
}
ptype = next_arg_type(cmd->args_type);
return (mon->suspend_cnt == 0) ? 1 : 0;
}
-static int invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
+static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd,
+ Error **errp)
{
- int is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
- return (qmp_cmd_mode(mon) ? is_cap : !is_cap);
+ bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
+
+ if (is_cap && mon->qmp.in_command_mode) {
+ error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
+ "Capabilities negotiation is already complete, command "
+ "'%s' ignored", cmd->name);
+ return true;
+ }
+ if (!is_cap && !mon->qmp.in_command_mode) {
+ error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
+ "Expecting capabilities negotiation with "
+ "'qmp_capabilities' before command '%s'", cmd->name);
+ return true;
+ }
+ return false;
}
/*
* the QMP_ACCEPT_UNKNOWNS flag is set, then the
* checking is skipped for it.
*/
-static int check_client_args_type(const QDict *client_args,
- const QDict *cmd_args, int flags)
+static void check_client_args_type(const QDict *client_args,
+ const QDict *cmd_args, int flags,
+ Error **errp)
{
const QDictEntry *ent;
continue;
}
/* client arg doesn't exist */
- qerror_report(QERR_INVALID_PARAMETER, client_arg_name);
- return -1;
+ error_set(errp, QERR_INVALID_PARAMETER, client_arg_name);
+ return;
}
arg_type = qobject_to_qstring(obj);
case 'B':
case 's':
if (qobject_type(client_arg) != QTYPE_QSTRING) {
- qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
- "string");
- return -1;
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE,
+ client_arg_name, "string");
+ return;
}
break;
case 'i':
case 'M':
case 'o':
if (qobject_type(client_arg) != QTYPE_QINT) {
- qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
- "int");
- return -1;
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE,
+ client_arg_name, "int");
+ return;
}
break;
case 'T':
if (qobject_type(client_arg) != QTYPE_QINT &&
qobject_type(client_arg) != QTYPE_QFLOAT) {
- qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
- "number");
- return -1;
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE,
+ client_arg_name, "number");
+ return;
}
break;
case 'b':
case '-':
if (qobject_type(client_arg) != QTYPE_QBOOL) {
- qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
- "bool");
- return -1;
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE,
+ client_arg_name, "bool");
+ return;
}
break;
case 'O':
abort();
}
}
-
- return 0;
}
/*
* - Check if the client has passed all mandatory args
* - Set special flags for argument validation
*/
-static int check_mandatory_args(const QDict *cmd_args,
- const QDict *client_args, int *flags)
+static void check_mandatory_args(const QDict *cmd_args,
+ const QDict *client_args, int *flags,
+ Error **errp)
{
const QDictEntry *ent;
} else if (qstring_get_str(type)[0] != '-' &&
qstring_get_str(type)[1] != '?' &&
!qdict_haskey(client_args, cmd_arg_name)) {
- qerror_report(QERR_MISSING_PARAMETER, cmd_arg_name);
- return -1;
+ error_set(errp, QERR_MISSING_PARAMETER, cmd_arg_name);
+ return;
}
}
-
- return 0;
}
static QDict *qdict_from_args_type(const char *args_type)
* 3. Each argument provided by the client must have the type expected
* by the command
*/
-static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args)
+static void qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args,
+ Error **errp)
{
- int flags, err;
+ Error *err = NULL;
+ int flags;
QDict *cmd_args;
cmd_args = qdict_from_args_type(cmd->args_type);
flags = 0;
- err = check_mandatory_args(cmd_args, client_args, &flags);
+ check_mandatory_args(cmd_args, client_args, &flags, &err);
if (err) {
goto out;
}
- err = check_client_args_type(client_args, cmd_args, flags);
+ check_client_args_type(client_args, cmd_args, flags, &err);
out:
+ error_propagate(errp, err);
QDECREF(cmd_args);
- return err;
}
/*
* 5. If the "id" key exists, it can be anything (ie. json-value)
* 6. Any argument not listed above is considered invalid
*/
-static QDict *qmp_check_input_obj(QObject *input_obj)
+static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
{
const QDictEntry *ent;
int has_exec_key = 0;
QDict *input_dict;
if (qobject_type(input_obj) != QTYPE_QDICT) {
- qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "object");
+ error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "object");
return NULL;
}
if (!strcmp(arg_name, "execute")) {
if (qobject_type(arg_obj) != QTYPE_QSTRING) {
- qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute",
- "string");
+ error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
+ "execute", "string");
return NULL;
}
has_exec_key = 1;
} else if (!strcmp(arg_name, "arguments")) {
if (qobject_type(arg_obj) != QTYPE_QDICT) {
- qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments",
- "object");
+ error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
+ "arguments", "object");
return NULL;
}
} else if (!strcmp(arg_name, "id")) {
- /* FIXME: check duplicated IDs for async commands */
+ /* Any string is acceptable as "id", so nothing to check */
} else {
- qerror_report(QERR_QMP_EXTRA_MEMBER, arg_name);
+ error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
return NULL;
}
}
if (!has_exec_key) {
- qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute");
+ error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");
return NULL;
}
return input_dict;
}
-static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd,
- const QDict *params)
-{
- int ret;
- QObject *data = NULL;
-
- 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;
- QObject *obj;
+ Error *local_err = NULL;
+ QObject *obj, *data;
QDict *input, *args;
const mon_cmd_t *cmd;
const char *cmd_name;
Monitor *mon = cur_mon;
args = input = NULL;
+ data = NULL;
obj = json_parser_parse(tokens, NULL);
if (!obj) {
// FIXME: should be triggered in json_parser_parse()
- qerror_report(QERR_JSON_PARSING);
+ error_set(&local_err, QERR_JSON_PARSING);
goto err_out;
}
- input = qmp_check_input_obj(obj);
+ input = qmp_check_input_obj(obj, &local_err);
if (!input) {
qobject_decref(obj);
goto err_out;
}
- mon->mc->id = qdict_get(input, "id");
- qobject_incref(mon->mc->id);
+ mon->qmp.id = qdict_get(input, "id");
+ qobject_incref(mon->qmp.id);
cmd_name = qdict_get_str(input, "execute");
trace_handle_qmp_command(mon, cmd_name);
cmd = qmp_find_cmd(cmd_name);
- if (!cmd || invalid_qmp_mode(mon, cmd)) {
- qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
- "The command %s has not been found", cmd_name);
+ if (!cmd) {
+ error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
+ "The command %s has not been found", cmd_name);
+ goto err_out;
+ }
+ if (invalid_qmp_mode(mon, cmd, &local_err)) {
goto err_out;
}
QINCREF(args);
}
- err = qmp_check_client_args(cmd, args);
- if (err < 0) {
+ qmp_check_client_args(cmd, args, &local_err);
+ if (local_err) {
goto err_out;
}
- if (handler_is_async(cmd)) {
- err = qmp_async_cmd_handler(mon, cmd, args);
- if (err) {
- /* emit the error response */
- goto err_out;
+ if (cmd->mhandler.cmd_new(mon, args, &data)) {
+ /* Command failed... */
+ if (!mon->error) {
+ /* ... without setting an error, so make one up */
+ error_set(&local_err, QERR_UNDEFINED_ERROR);
}
- } else {
- qmp_call_cmd(mon, cmd, args);
}
-
- goto out;
+ if (mon->error) {
+ error_set(&local_err, mon->error->err_class, "%s",
+ mon->error->err_msg);
+ }
err_out:
- monitor_protocol_emitter(mon, NULL);
-out:
+ monitor_protocol_emitter(mon, data, local_err);
+ qobject_decref(data);
+ QDECREF(mon->error);
+ mon->error = NULL;
QDECREF(input);
QDECREF(args);
}
-/**
- * monitor_control_read(): Read and handle QMP input
- */
-static void monitor_control_read(void *opaque, const uint8_t *buf, int size)
+static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
{
Monitor *old_mon = cur_mon;
cur_mon = opaque;
- json_message_parser_feed(&cur_mon->mc->parser, (const char *) buf, size);
+ json_message_parser_feed(&cur_mon->qmp.parser, (const char *) buf, size);
cur_mon = old_mon;
}
if (size == 0 || buf[size - 1] != 0)
monitor_printf(cur_mon, "corrupted command\n");
else
- handle_user_command(cur_mon, (char *)buf);
+ handle_hmp_command(cur_mon, (char *)buf);
}
cur_mon = old_mon;
Monitor *mon = opaque;
monitor_suspend(mon);
- handle_user_command(mon, cmdline);
+ handle_hmp_command(mon, cmdline);
monitor_resume(mon);
}
return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);
}
-/**
- * monitor_control_event(): Print QMP gretting
- */
-static void monitor_control_event(void *opaque, int event)
+static void monitor_qmp_event(void *opaque, int event)
{
QObject *data;
Monitor *mon = opaque;
switch (event) {
case CHR_EVENT_OPENED:
- mon->mc->command_mode = 0;
+ mon->qmp.in_command_mode = false;
data = get_qmp_greeting();
monitor_json_emitter(mon, data);
qobject_decref(data);
mon_refcount++;
break;
case CHR_EVENT_CLOSED:
- json_message_parser_destroy(&mon->mc->parser);
- json_message_parser_init(&mon->mc->parser, handle_qmp_command);
+ json_message_parser_destroy(&mon->qmp.parser);
+ json_message_parser_init(&mon->qmp.parser, handle_qmp_command);
mon_refcount--;
monitor_fdsets_cleanup();
break;
monitor_read_command(mon, 0);
}
- if (monitor_ctrl_mode(mon)) {
- mon->mc = g_malloc0(sizeof(MonitorControl));
- /* Control mode requires special handlers */
- qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
- monitor_control_event, mon);
+ if (monitor_is_qmp(mon)) {
+ qemu_chr_add_handlers(chr, monitor_can_read, monitor_qmp_read,
+ monitor_qmp_event, mon);
qemu_chr_fe_set_echo(chr, true);
-
- json_message_parser_init(&mon->mc->parser, handle_qmp_command);
+ json_message_parser_init(&mon->qmp.parser, handle_qmp_command);
} else {
qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
monitor_event, mon);
monitor_read_command(mon, 1);
}
-ReadLineState *monitor_get_rs(Monitor *mon)
-{
- return mon->rs;
-}
-
int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
BlockCompletionFunc *completion_cb,
void *opaque)
{
- Error *local_err = NULL;
int err;
- bdrv_add_key(bs, NULL, &local_err);
- if (!local_err) {
- if (completion_cb)
- completion_cb(opaque, 0);
- return 0;
- }
-
- /* Need a key for @bs */
-
- if (monitor_ctrl_mode(mon)) {
- qerror_report_err(local_err);
- return -1;
- }
-
monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
bdrv_get_encrypted_filename(bs));
BlockCompletionFunc *completion_cb,
void *opaque)
{
- BlockDriverState *bs;
+ Error *err = NULL;
+ BlockBackend *blk;
- bs = bdrv_find(device);
- if (!bs) {
+ blk = blk_by_name(device);
+ if (!blk) {
monitor_printf(mon, "Device not found %s\n", device);
return -1;
}
- return monitor_read_bdrv_key_start(mon, bs, completion_cb, opaque);
+ bdrv_add_key(blk_bs(blk), NULL, &err);
+ if (err) {
+ error_free(err);
+ return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque);
+ }
+
+ if (completion_cb) {
+ completion_cb(opaque, 0);
+ }
+ return 0;
}
QemuOptsList qemu_mon_opts = {