X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/94ac5cd20c6e441e0ed3aec5c98d6cbefb7f503f..5dea2efb3b141b2e2defe0b01de023cbe9d4232d:/monitor.c diff --git a/monitor.c b/monitor.c index 39791dc555..ffda0feb84 100644 --- a/monitor.c +++ b/monitor.c @@ -57,10 +57,21 @@ #include "json-parser.h" #include "osdep.h" #include "cpu.h" -#ifdef CONFIG_SIMPLE_TRACE #include "trace.h" +#include "trace/control.h" +#ifdef CONFIG_TRACE_SIMPLE +#include "trace/simple.h" #endif #include "ui/qemu-spice.h" +#include "memory.h" +#include "qmp-commands.h" +#include "hmp.h" + +/* for pic/irq_info */ +#if defined(TARGET_SPARC) +#include "hw/sun4m.h" +#endif +#include "hw/lm32_pic.h" //#define DEBUG //#define DEBUG_COMPLETION @@ -119,6 +130,7 @@ typedef struct mon_cmd_t { int (*cmd_async)(Monitor *mon, const QDict *params, MonitorCompletion *cb, void *opaque); } mhandler; + bool qapi; int flags; } mon_cmd_t; @@ -247,7 +259,7 @@ static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, void monitor_flush(Monitor *mon) { if (mon && mon->outbuf_index != 0 && !mon->mux_out) { - qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index); + qemu_chr_fe_write(mon->chr, mon->outbuf, mon->outbuf_index); mon->outbuf_index = 0; } } @@ -367,6 +379,8 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data) { QDict *qmp; + trace_monitor_protocol_emitter(mon); + qmp = qdict_new(); if (!monitor_has_error(mon)) { @@ -592,18 +606,18 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict) help_cmd(mon, qdict_get_try_str(qdict, "name")); } -#ifdef CONFIG_SIMPLE_TRACE -static void do_change_trace_event_state(Monitor *mon, const QDict *qdict) +static void do_trace_event_set_state(Monitor *mon, const QDict *qdict) { const char *tp_name = qdict_get_str(qdict, "name"); bool new_state = qdict_get_bool(qdict, "option"); - int ret = st_change_trace_event_state(tp_name, new_state); + int ret = trace_event_set_state(tp_name, new_state); if (!ret) { monitor_printf(mon, "unknown event name \"%s\"\n", tp_name); } } +#ifdef CONFIG_TRACE_SIMPLE static void do_trace_file(Monitor *mon, const QDict *qdict) { const char *op = qdict_get_try_str(qdict, "op"); @@ -725,105 +739,37 @@ help: help_cmd(mon, "info"); } -static void do_info_version_print(Monitor *mon, const QObject *data) -{ - QDict *qdict; - QDict *qemu; - - qdict = qobject_to_qdict(data); - qemu = qdict_get_qdict(qdict, "qemu"); - - monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n", - qdict_get_int(qemu, "major"), - qdict_get_int(qemu, "minor"), - qdict_get_int(qemu, "micro"), - qdict_get_str(qdict, "package")); -} - -static void do_info_version(Monitor *mon, QObject **ret_data) -{ - const char *version = QEMU_VERSION; - int major = 0, minor = 0, micro = 0; - char *tmp; - - major = strtol(version, &tmp, 10); - tmp++; - minor = strtol(tmp, &tmp, 10); - tmp++; - micro = strtol(tmp, &tmp, 10); - - *ret_data = qobject_from_jsonf("{ 'qemu': { 'major': %d, 'minor': %d, \ - 'micro': %d }, 'package': %s }", major, minor, micro, QEMU_PKGVERSION); -} - -static void do_info_name_print(Monitor *mon, const QObject *data) -{ - QDict *qdict; - - qdict = qobject_to_qdict(data); - if (qdict_size(qdict) == 0) { - return; - } - - monitor_printf(mon, "%s\n", qdict_get_str(qdict, "name")); -} - -static void do_info_name(Monitor *mon, QObject **ret_data) -{ - *ret_data = qemu_name ? qobject_from_jsonf("{'name': %s }", qemu_name) : - qobject_from_jsonf("{}"); -} - -static QObject *get_cmd_dict(const char *name) +static CommandInfoList *alloc_cmd_entry(const char *cmd_name) { - const char *p; + CommandInfoList *info; - /* Remove '|' from some commands */ - p = strchr(name, '|'); - if (p) { - p++; - } else { - p = name; - } + info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->name = g_strdup(cmd_name); - return qobject_from_jsonf("{ 'name': %s }", p); + return info; } -static void do_info_commands(Monitor *mon, QObject **ret_data) +CommandInfoList *qmp_query_commands(Error **errp) { - QList *cmd_list; + CommandInfoList *info, *cmd_list = NULL; const mon_cmd_t *cmd; - cmd_list = qlist_new(); - for (cmd = qmp_cmds; cmd->name != NULL; cmd++) { - qlist_append_obj(cmd_list, get_cmd_dict(cmd->name)); + info = alloc_cmd_entry(cmd->name); + info->next = cmd_list; + cmd_list = info; } 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)); + info = alloc_cmd_entry(buf); + info->next = cmd_list; + cmd_list = info; } - *ret_data = QOBJECT(cmd_list); -} - -static void do_info_uuid_print(Monitor *mon, const QObject *data) -{ - monitor_printf(mon, "%s\n", qdict_get_str(qobject_to_qdict(data), "UUID")); -} - -static void do_info_uuid(Monitor *mon, QObject **ret_data) -{ - char uuid[64]; - - snprintf(uuid, sizeof(uuid), UUID_FMT, qemu_uuid[0], qemu_uuid[1], - qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], - qemu_uuid[6], qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], - qemu_uuid[10], qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], - qemu_uuid[14], qemu_uuid[15]); - *ret_data = qobject_from_jsonf("{ 'UUID': %s }", uuid); + return cmd_list; } /* get the current CPU defined by the user */ @@ -884,7 +830,7 @@ static void print_cpu_iter(QObject *obj, void *opaque) monitor_printf(mon, "nip=0x" TARGET_FMT_lx, (target_long) qdict_get_int(cpu, "nip")); #elif defined(TARGET_SPARC) - monitor_printf(mon, "pc=0x " TARGET_FMT_lx, + monitor_printf(mon, "pc=0x" TARGET_FMT_lx, (target_long) qdict_get_int(cpu, "pc")); monitor_printf(mon, "npc=0x" TARGET_FMT_lx, (target_long) qdict_get_int(cpu, "npc")); @@ -996,28 +942,16 @@ static void do_info_cpu_stats(Monitor *mon) } #endif -#if defined(CONFIG_SIMPLE_TRACE) +#if defined(CONFIG_TRACE_SIMPLE) static void do_info_trace(Monitor *mon) { st_print_trace((FILE *)mon, &monitor_fprintf); } - -static void do_info_trace_events(Monitor *mon) -{ - st_print_trace_events((FILE *)mon, &monitor_fprintf); -} #endif -/** - * do_quit(): Quit QEMU execution - */ -static int do_quit(Monitor *mon, const QDict *qdict, QObject **ret_data) +static void do_trace_print_events(Monitor *mon) { - monitor_suspend(mon); - no_shutdown = 0; - qemu_system_shutdown_request(); - - return 0; + trace_print_events((FILE *)mon, &monitor_fprintf); } #ifdef CONFIG_VNC @@ -1189,7 +1123,6 @@ static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_d { const char *protocol = qdict_get_str(qdict, "protocol"); const char *fdname = qdict_get_str(qdict, "fdname"); - int skipauth = qdict_get_try_bool(qdict, "skipauth", 0); CharDriverState *s; if (strcmp(protocol, "spice") == 0) { @@ -1203,6 +1136,7 @@ static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_d #ifdef CONFIG_VNC } else if (strcmp(protocol, "vnc") == 0) { int fd = monitor_get_fd(mon, fdname); + int skipauth = qdict_get_try_bool(qdict, "skipauth", 0); vnc_display_add_client(NULL, fd, skipauth); return 0; #endif @@ -1286,15 +1220,6 @@ static void do_singlestep(Monitor *mon, const QDict *qdict) } } -/** - * do_stop(): Stop VM execution - */ -static int do_stop(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ - vm_stop(VMSTOP_USER); - return 0; -} - static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs); struct bdrv_iterate_context { @@ -1302,6 +1227,11 @@ struct bdrv_iterate_context { int err; }; +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +{ + bdrv_iostatus_reset(bs); +} + /** * do_cont(): Resume emulation. */ @@ -1309,10 +1239,16 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) { struct bdrv_iterate_context context = { mon, 0 }; - if (incoming_expected) { + if (runstate_check(RUN_STATE_INMIGRATE)) { qerror_report(QERR_MIGRATION_EXPECTED); return -1; + } else if (runstate_check(RUN_STATE_INTERNAL_ERROR) || + runstate_check(RUN_STATE_SHUTDOWN)) { + qerror_report(QERR_RESET_REQUIRED); + return -1; } + + bdrv_iterate(iostatus_bdrv_it, NULL); bdrv_iterate(encrypted_bdrv_it, &context); /* only resume the vm if all keys are set and valid */ if (!context.err) { @@ -2007,16 +1943,6 @@ static void do_boot_set(Monitor *mon, const QDict *qdict) } } -/** - * do_system_reset(): Issue a machine reset - */ -static int do_system_reset(Monitor *mon, const QDict *qdict, - QObject **ret_data) -{ - qemu_system_reset_request(); - return 0; -} - /** * do_system_powerdown(): Issue a machine powerdown */ @@ -2454,7 +2380,7 @@ static void tlb_info(Monitor *mon) #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_PPC) static void tlb_info(Monitor *mon) { CPUState *env1 = mon_get_cpu(); @@ -2463,29 +2389,9 @@ static void tlb_info(Monitor *mon) } #endif -static void do_info_kvm_print(Monitor *mon, const QObject *data) -{ - QDict *qdict; - - qdict = qobject_to_qdict(data); - - monitor_printf(mon, "kvm support: "); - if (qdict_get_bool(qdict, "present")) { - monitor_printf(mon, "%s\n", qdict_get_bool(qdict, "enabled") ? - "enabled" : "disabled"); - } else { - monitor_printf(mon, "not compiled\n"); - } -} - -static void do_info_kvm(Monitor *mon, QObject **ret_data) +static void do_info_mtree(Monitor *mon) { -#ifdef CONFIG_KVM - *ret_data = qobject_from_jsonf("{ 'enabled': %i, 'present': true }", - kvm_enabled()); -#else - *ret_data = qobject_from_jsonf("{ 'enabled': false, 'present': false }"); -#endif + mtree_info((fprintf_function)monitor_printf, mon); } static void do_info_numa(Monitor *mon) @@ -2608,31 +2514,6 @@ static int do_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret_data) } #endif -static void do_info_status_print(Monitor *mon, const QObject *data) -{ - QDict *qdict; - - qdict = qobject_to_qdict(data); - - monitor_printf(mon, "VM status: "); - if (qdict_get_bool(qdict, "running")) { - monitor_printf(mon, "running"); - if (qdict_get_bool(qdict, "singlestep")) { - monitor_printf(mon, " (single step mode)"); - } - } else { - monitor_printf(mon, "paused"); - } - - monitor_printf(mon, "\n"); -} - -static void do_info_status(Monitor *mon, QObject **ret_data) -{ - *ret_data = qobject_from_jsonf("{ 'running': %i, 'singlestep': %i }", - vm_running, singlestep); -} - static qemu_acl *find_acl(Monitor *mon, const char *name) { qemu_acl *acl = qemu_acl_find(name); @@ -2770,7 +2651,7 @@ static int do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data) mon_fd_t *monfd; int fd; - fd = qemu_chr_get_msgfd(mon->chr); + fd = qemu_chr_fe_get_msgfd(mon->chr); if (fd == -1) { qerror_report(QERR_FD_NOT_SUPPLIED); return -1; @@ -2823,10 +2704,10 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data) static void do_loadvm(Monitor *mon, const QDict *qdict) { - int saved_vm_running = vm_running; + int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, "name"); - vm_stop(VMSTOP_LOADVM); + vm_stop(RUN_STATE_RESTORE_VM); if (load_vmstate(name) == 0 && saved_vm_running) { vm_start(); @@ -2869,8 +2750,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the version of QEMU", - .user_print = do_info_version_print, - .mhandler.info_new = do_info_version, + .mhandler.info = hmp_info_version, }, { .name = "network", @@ -2884,8 +2764,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the character devices", - .user_print = qemu_chr_info_print, - .mhandler.info_new = qemu_chr_info, + .mhandler.info = hmp_info_chardev, }, { .name = "block", @@ -2925,20 +2804,35 @@ static const mon_cmd_t info_cmds[] = { .help = "show the command line history", .mhandler.info = do_info_history, }, +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \ + defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64)) { .name = "irq", .args_type = "", .params = "", .help = "show the interrupts statistics (if available)", +#ifdef TARGET_SPARC + .mhandler.info = sun4m_irq_info, +#elif defined(TARGET_LM32) + .mhandler.info = lm32_irq_info, +#else .mhandler.info = irq_info, +#endif }, { .name = "pic", .args_type = "", .params = "", .help = "show i8259 (PIC) state", +#ifdef TARGET_SPARC + .mhandler.info = sun4m_pic_info, +#elif defined(TARGET_LM32) + .mhandler.info = lm32_do_pic_info, +#else .mhandler.info = pic_info, +#endif }, +#endif { .name = "pci", .args_type = "", @@ -2947,7 +2841,8 @@ static const mon_cmd_t info_cmds[] = { .user_print = do_pci_info_print, .mhandler.info_new = do_pci_info, }, -#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) +#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \ + defined(TARGET_PPC) { .name = "tlb", .args_type = "", @@ -2965,6 +2860,13 @@ static const mon_cmd_t info_cmds[] = { .mhandler.info = mem_info, }, #endif + { + .name = "mtree", + .args_type = "", + .params = "", + .help = "show memory tree", + .mhandler.info = do_info_mtree, + }, { .name = "jit", .args_type = "", @@ -2977,8 +2879,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show KVM information", - .user_print = do_info_kvm_print, - .mhandler.info_new = do_info_kvm, + .mhandler.info = hmp_info_kvm, }, { .name = "numa", @@ -3027,8 +2928,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the current VM status (running|paused)", - .user_print = do_info_status_print, - .mhandler.info_new = do_info_status, + .mhandler.info = hmp_info_status, }, { .name = "pcmcia", @@ -3068,16 +2968,14 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the current VM name", - .user_print = do_info_name_print, - .mhandler.info_new = do_info_name, + .mhandler.info = hmp_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, + .mhandler.info = hmp_info_uuid, }, #if defined(TARGET_PPC) { @@ -3135,7 +3033,7 @@ static const mon_cmd_t info_cmds[] = { .help = "show roms", .mhandler.info = do_info_roms, }, -#if defined(CONFIG_SIMPLE_TRACE) +#if defined(CONFIG_TRACE_SIMPLE) { .name = "trace", .args_type = "", @@ -3143,49 +3041,25 @@ static const mon_cmd_t info_cmds[] = { .help = "show current contents of trace buffer", .mhandler.info = do_info_trace, }, +#endif { .name = "trace-events", .args_type = "", .params = "", .help = "show available trace-events & their state", - .mhandler.info = do_info_trace_events, + .mhandler.info = do_trace_print_events, }, -#endif { .name = NULL, }, }; static const mon_cmd_t qmp_cmds[] = { -#include "qmp-commands.h" +#include "qmp-commands-old.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 = "", @@ -3218,22 +3092,6 @@ static const mon_cmd_t qmp_query_cmds[] = { .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 = "", @@ -3260,22 +3118,6 @@ static const mon_cmd_t qmp_query_cmds[] = { .mhandler.info_new = do_info_spice, }, #endif - { - .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 = "", @@ -5077,17 +4919,16 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) qobject_incref(mon->mc->id); cmd_name = qdict_get_str(input, "execute"); + trace_handle_qmp_command(mon, cmd_name); if (invalid_qmp_mode(mon, cmd_name)) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_out; } - if (strstart(cmd_name, "query-", &query_cmd)) { + cmd = qmp_find_cmd(cmd_name); + if (!cmd && strstart(cmd_name, "query-", &query_cmd)) { cmd = qmp_find_query_cmd(query_cmd); - } else { - cmd = qmp_find_cmd(cmd_name); } - if (!cmd) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_out; @@ -5186,9 +5027,9 @@ void monitor_resume(Monitor *mon) static QObject *get_qmp_greeting(void) { - QObject *ver; + QObject *ver = NULL; - do_info_version(NULL, &ver); + qmp_marshal_input_query_version(NULL, NULL, &ver); return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver); } @@ -5287,7 +5128,7 @@ void monitor_init(CharDriverState *chr, int flags) /* Control mode requires special handlers */ qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read, monitor_control_event, mon); - qemu_chr_set_echo(chr, true); + qemu_chr_fe_set_echo(chr, true); } else { qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event, mon);