qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio
at jcs-vmm 2216 lines 59 kB view raw
1/* 2 * QEMU monitor 3 * 4 * Copyright (c) 2003-2004 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25#include "qemu/osdep.h" 26#include "monitor-internal.h" 27#include "cpu.h" 28#include "monitor/qdev.h" 29#include "hw/usb.h" 30#include "hw/pci/pci.h" 31#include "sysemu/watchdog.h" 32#include "hw/loader.h" 33#include "exec/gdbstub.h" 34#include "net/net.h" 35#include "net/slirp.h" 36#include "chardev/char-mux.h" 37#include "ui/qemu-spice.h" 38#include "qemu/config-file.h" 39#include "qemu/ctype.h" 40#include "ui/console.h" 41#include "ui/input.h" 42#include "audio/audio.h" 43#include "disas/disas.h" 44#include "sysemu/balloon.h" 45#include "qemu/timer.h" 46#include "sysemu/hw_accel.h" 47#include "sysemu/runstate.h" 48#include "authz/list.h" 49#include "qapi/util.h" 50#include "sysemu/blockdev.h" 51#include "sysemu/sysemu.h" 52#include "sysemu/tcg.h" 53#include "sysemu/tpm.h" 54#include "qapi/qmp/qdict.h" 55#include "qapi/qmp/qerror.h" 56#include "qapi/qmp/qstring.h" 57#include "qom/object_interfaces.h" 58#include "trace/control.h" 59#include "monitor/hmp-target.h" 60#include "monitor/hmp.h" 61#ifdef CONFIG_TRACE_SIMPLE 62#include "trace/simple.h" 63#endif 64#include "exec/memory.h" 65#include "exec/exec-all.h" 66#include "qemu/option.h" 67#include "qemu/thread.h" 68#include "block/qapi.h" 69#include "block/block-hmp-cmds.h" 70#include "qapi/qapi-commands-char.h" 71#include "qapi/qapi-commands-control.h" 72#include "qapi/qapi-commands-migration.h" 73#include "qapi/qapi-commands-misc.h" 74#include "qapi/qapi-commands-qom.h" 75#include "qapi/qapi-commands-trace.h" 76#include "qapi/qapi-init-commands.h" 77#include "qapi/error.h" 78#include "qapi/qmp-event.h" 79#include "sysemu/cpus.h" 80#include "qemu/cutils.h" 81#include "tcg/tcg.h" 82 83#if defined(TARGET_S390X) 84#include "hw/s390x/storage-keys.h" 85#include "hw/s390x/storage-attributes.h" 86#endif 87 88/* file descriptors passed via SCM_RIGHTS */ 89typedef struct mon_fd_t mon_fd_t; 90struct mon_fd_t { 91 char *name; 92 int fd; 93 QLIST_ENTRY(mon_fd_t) next; 94}; 95 96/* file descriptor associated with a file descriptor set */ 97typedef struct MonFdsetFd MonFdsetFd; 98struct MonFdsetFd { 99 int fd; 100 bool removed; 101 char *opaque; 102 QLIST_ENTRY(MonFdsetFd) next; 103}; 104 105/* file descriptor set containing fds passed via SCM_RIGHTS */ 106typedef struct MonFdset MonFdset; 107struct MonFdset { 108 int64_t id; 109 QLIST_HEAD(, MonFdsetFd) fds; 110 QLIST_HEAD(, MonFdsetFd) dup_fds; 111 QLIST_ENTRY(MonFdset) next; 112}; 113 114/* Protects mon_fdsets */ 115static QemuMutex mon_fdsets_lock; 116static QLIST_HEAD(, MonFdset) mon_fdsets; 117 118static HMPCommand hmp_info_cmds[]; 119 120char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, 121 int64_t cpu_index, Error **errp) 122{ 123 char *output = NULL; 124 Monitor *old_mon; 125 MonitorHMP hmp = {}; 126 127 monitor_data_init(&hmp.common, false, true, false); 128 129 old_mon = cur_mon; 130 cur_mon = &hmp.common; 131 132 if (has_cpu_index) { 133 int ret = monitor_set_cpu(cpu_index); 134 if (ret < 0) { 135 cur_mon = old_mon; 136 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", 137 "a CPU number"); 138 goto out; 139 } 140 } 141 142 handle_hmp_command(&hmp, command_line); 143 cur_mon = old_mon; 144 145 qemu_mutex_lock(&hmp.common.mon_lock); 146 if (qstring_get_length(hmp.common.outbuf) > 0) { 147 output = g_strdup(qstring_get_str(hmp.common.outbuf)); 148 } else { 149 output = g_strdup(""); 150 } 151 qemu_mutex_unlock(&hmp.common.mon_lock); 152 153out: 154 monitor_data_destroy(&hmp.common); 155 return output; 156} 157 158/** 159 * Is @name in the '|' separated list of names @list? 160 */ 161int hmp_compare_cmd(const char *name, const char *list) 162{ 163 const char *p, *pstart; 164 int len; 165 len = strlen(name); 166 p = list; 167 for (;;) { 168 pstart = p; 169 p = qemu_strchrnul(p, '|'); 170 if ((p - pstart) == len && !memcmp(pstart, name, len)) { 171 return 1; 172 } 173 if (*p == '\0') { 174 break; 175 } 176 p++; 177 } 178 return 0; 179} 180 181static void do_help_cmd(Monitor *mon, const QDict *qdict) 182{ 183 help_cmd(mon, qdict_get_try_str(qdict, "name")); 184} 185 186static void hmp_trace_event(Monitor *mon, const QDict *qdict) 187{ 188 const char *tp_name = qdict_get_str(qdict, "name"); 189 bool new_state = qdict_get_bool(qdict, "option"); 190 bool has_vcpu = qdict_haskey(qdict, "vcpu"); 191 int vcpu = qdict_get_try_int(qdict, "vcpu", 0); 192 Error *local_err = NULL; 193 194 if (vcpu < 0) { 195 monitor_printf(mon, "argument vcpu must be positive"); 196 return; 197 } 198 199 qmp_trace_event_set_state(tp_name, new_state, true, true, has_vcpu, vcpu, &local_err); 200 if (local_err) { 201 error_report_err(local_err); 202 } 203} 204 205#ifdef CONFIG_TRACE_SIMPLE 206static void hmp_trace_file(Monitor *mon, const QDict *qdict) 207{ 208 const char *op = qdict_get_try_str(qdict, "op"); 209 const char *arg = qdict_get_try_str(qdict, "arg"); 210 211 if (!op) { 212 st_print_trace_file_status(); 213 } else if (!strcmp(op, "on")) { 214 st_set_trace_file_enabled(true); 215 } else if (!strcmp(op, "off")) { 216 st_set_trace_file_enabled(false); 217 } else if (!strcmp(op, "flush")) { 218 st_flush_trace_buffer(); 219 } else if (!strcmp(op, "set")) { 220 if (arg) { 221 st_set_trace_file(arg); 222 } 223 } else { 224 monitor_printf(mon, "unexpected argument \"%s\"\n", op); 225 help_cmd(mon, "trace-file"); 226 } 227} 228#endif 229 230static void hmp_info_help(Monitor *mon, const QDict *qdict) 231{ 232 help_cmd(mon, "info"); 233} 234 235static void monitor_init_qmp_commands(void) 236{ 237 /* 238 * Two command lists: 239 * - qmp_commands contains all QMP commands 240 * - qmp_cap_negotiation_commands contains just 241 * "qmp_capabilities", to enforce capability negotiation 242 */ 243 244 qmp_init_marshal(&qmp_commands); 245 246 qmp_register_command(&qmp_commands, "query-qmp-schema", 247 qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG); 248 qmp_register_command(&qmp_commands, "device_add", qmp_device_add, 249 QCO_NO_OPTIONS); 250 qmp_register_command(&qmp_commands, "object-add", qmp_object_add, 251 QCO_NO_OPTIONS); 252 253 QTAILQ_INIT(&qmp_cap_negotiation_commands); 254 qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities", 255 qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG); 256} 257 258/* Set the current CPU defined by the user. Callers must hold BQL. */ 259int monitor_set_cpu(int cpu_index) 260{ 261 CPUState *cpu; 262 263 cpu = qemu_get_cpu(cpu_index); 264 if (cpu == NULL) { 265 return -1; 266 } 267 g_free(cur_mon->mon_cpu_path); 268 cur_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu)); 269 return 0; 270} 271 272/* Callers must hold BQL. */ 273static CPUState *mon_get_cpu_sync(bool synchronize) 274{ 275 CPUState *cpu = NULL; 276 277 if (cur_mon->mon_cpu_path) { 278 cpu = (CPUState *) object_resolve_path_type(cur_mon->mon_cpu_path, 279 TYPE_CPU, NULL); 280 if (!cpu) { 281 g_free(cur_mon->mon_cpu_path); 282 cur_mon->mon_cpu_path = NULL; 283 } 284 } 285 if (!cur_mon->mon_cpu_path) { 286 if (!first_cpu) { 287 return NULL; 288 } 289 monitor_set_cpu(first_cpu->cpu_index); 290 cpu = first_cpu; 291 } 292 assert(cpu != NULL); 293 if (synchronize) { 294 cpu_synchronize_state(cpu); 295 } 296 return cpu; 297} 298 299CPUState *mon_get_cpu(void) 300{ 301 return mon_get_cpu_sync(true); 302} 303 304CPUArchState *mon_get_cpu_env(void) 305{ 306 CPUState *cs = mon_get_cpu(); 307 308 return cs ? cs->env_ptr : NULL; 309} 310 311int monitor_get_cpu_index(void) 312{ 313 CPUState *cs = mon_get_cpu_sync(false); 314 315 return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX; 316} 317 318static void hmp_info_registers(Monitor *mon, const QDict *qdict) 319{ 320 bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false); 321 CPUState *cs; 322 323 if (all_cpus) { 324 CPU_FOREACH(cs) { 325 monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index); 326 cpu_dump_state(cs, NULL, CPU_DUMP_FPU); 327 } 328 } else { 329 cs = mon_get_cpu(); 330 331 if (!cs) { 332 monitor_printf(mon, "No CPU available\n"); 333 return; 334 } 335 336 cpu_dump_state(cs, NULL, CPU_DUMP_FPU); 337 } 338} 339 340#ifdef CONFIG_TCG 341static void hmp_info_jit(Monitor *mon, const QDict *qdict) 342{ 343 if (!tcg_enabled()) { 344 error_report("JIT information is only available with accel=tcg"); 345 return; 346 } 347 348 dump_exec_info(); 349 dump_drift_info(); 350} 351 352static void hmp_info_opcount(Monitor *mon, const QDict *qdict) 353{ 354 dump_opcount_info(); 355} 356#endif 357 358static void hmp_info_sync_profile(Monitor *mon, const QDict *qdict) 359{ 360 int64_t max = qdict_get_try_int(qdict, "max", 10); 361 bool mean = qdict_get_try_bool(qdict, "mean", false); 362 bool coalesce = !qdict_get_try_bool(qdict, "no_coalesce", false); 363 enum QSPSortBy sort_by; 364 365 sort_by = mean ? QSP_SORT_BY_AVG_WAIT_TIME : QSP_SORT_BY_TOTAL_WAIT_TIME; 366 qsp_report(max, sort_by, coalesce); 367} 368 369static void hmp_info_history(Monitor *mon, const QDict *qdict) 370{ 371 MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common); 372 int i; 373 const char *str; 374 375 if (!hmp_mon->rs) { 376 return; 377 } 378 i = 0; 379 for(;;) { 380 str = readline_get_history(hmp_mon->rs, i); 381 if (!str) { 382 break; 383 } 384 monitor_printf(mon, "%d: '%s'\n", i, str); 385 i++; 386 } 387} 388 389static void hmp_info_cpustats(Monitor *mon, const QDict *qdict) 390{ 391 CPUState *cs = mon_get_cpu(); 392 393 if (!cs) { 394 monitor_printf(mon, "No CPU available\n"); 395 return; 396 } 397 cpu_dump_statistics(cs, 0); 398} 399 400static void hmp_info_trace_events(Monitor *mon, const QDict *qdict) 401{ 402 const char *name = qdict_get_try_str(qdict, "name"); 403 bool has_vcpu = qdict_haskey(qdict, "vcpu"); 404 int vcpu = qdict_get_try_int(qdict, "vcpu", 0); 405 TraceEventInfoList *events; 406 TraceEventInfoList *elem; 407 Error *local_err = NULL; 408 409 if (name == NULL) { 410 name = "*"; 411 } 412 if (vcpu < 0) { 413 monitor_printf(mon, "argument vcpu must be positive"); 414 return; 415 } 416 417 events = qmp_trace_event_get_state(name, has_vcpu, vcpu, &local_err); 418 if (local_err) { 419 error_report_err(local_err); 420 return; 421 } 422 423 for (elem = events; elem != NULL; elem = elem->next) { 424 monitor_printf(mon, "%s : state %u\n", 425 elem->value->name, 426 elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0); 427 } 428 qapi_free_TraceEventInfoList(events); 429} 430 431void qmp_client_migrate_info(const char *protocol, const char *hostname, 432 bool has_port, int64_t port, 433 bool has_tls_port, int64_t tls_port, 434 bool has_cert_subject, const char *cert_subject, 435 Error **errp) 436{ 437 if (strcmp(protocol, "spice") == 0) { 438 if (!qemu_using_spice(errp)) { 439 return; 440 } 441 442 if (!has_port && !has_tls_port) { 443 error_setg(errp, QERR_MISSING_PARAMETER, "port/tls-port"); 444 return; 445 } 446 447 if (qemu_spice_migrate_info(hostname, 448 has_port ? port : -1, 449 has_tls_port ? tls_port : -1, 450 cert_subject)) { 451 error_setg(errp, QERR_UNDEFINED_ERROR); 452 return; 453 } 454 return; 455 } 456 457 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "spice"); 458} 459 460static void hmp_logfile(Monitor *mon, const QDict *qdict) 461{ 462 Error *err = NULL; 463 464 qemu_set_log_filename(qdict_get_str(qdict, "filename"), &err); 465 if (err) { 466 error_report_err(err); 467 } 468} 469 470static void hmp_log(Monitor *mon, const QDict *qdict) 471{ 472 int mask; 473 const char *items = qdict_get_str(qdict, "items"); 474 475 if (!strcmp(items, "none")) { 476 mask = 0; 477 } else { 478 mask = qemu_str_to_log_mask(items); 479 if (!mask) { 480 help_cmd(mon, "log"); 481 return; 482 } 483 } 484 qemu_set_log(mask); 485} 486 487static void hmp_singlestep(Monitor *mon, const QDict *qdict) 488{ 489 const char *option = qdict_get_try_str(qdict, "option"); 490 if (!option || !strcmp(option, "on")) { 491 singlestep = 1; 492 } else if (!strcmp(option, "off")) { 493 singlestep = 0; 494 } else { 495 monitor_printf(mon, "unexpected option %s\n", option); 496 } 497} 498 499static void hmp_gdbserver(Monitor *mon, const QDict *qdict) 500{ 501 const char *device = qdict_get_try_str(qdict, "device"); 502 if (!device) 503 device = "tcp::" DEFAULT_GDBSTUB_PORT; 504 if (gdbserver_start(device) < 0) { 505 monitor_printf(mon, "Could not open gdbserver on device '%s'\n", 506 device); 507 } else if (strcmp(device, "none") == 0) { 508 monitor_printf(mon, "Disabled gdbserver\n"); 509 } else { 510 monitor_printf(mon, "Waiting for gdb connection on device '%s'\n", 511 device); 512 } 513} 514 515static void hmp_watchdog_action(Monitor *mon, const QDict *qdict) 516{ 517 const char *action = qdict_get_str(qdict, "action"); 518 if (select_watchdog_action(action) == -1) { 519 monitor_printf(mon, "Unknown watchdog action '%s'\n", action); 520 } 521} 522 523static void monitor_printc(Monitor *mon, int c) 524{ 525 monitor_printf(mon, "'"); 526 switch(c) { 527 case '\'': 528 monitor_printf(mon, "\\'"); 529 break; 530 case '\\': 531 monitor_printf(mon, "\\\\"); 532 break; 533 case '\n': 534 monitor_printf(mon, "\\n"); 535 break; 536 case '\r': 537 monitor_printf(mon, "\\r"); 538 break; 539 default: 540 if (c >= 32 && c <= 126) { 541 monitor_printf(mon, "%c", c); 542 } else { 543 monitor_printf(mon, "\\x%02x", c); 544 } 545 break; 546 } 547 monitor_printf(mon, "'"); 548} 549 550static void memory_dump(Monitor *mon, int count, int format, int wsize, 551 hwaddr addr, int is_physical) 552{ 553 int l, line_size, i, max_digits, len; 554 uint8_t buf[16]; 555 uint64_t v; 556 CPUState *cs = mon_get_cpu(); 557 558 if (!cs && (format == 'i' || !is_physical)) { 559 monitor_printf(mon, "Can not dump without CPU\n"); 560 return; 561 } 562 563 if (format == 'i') { 564 monitor_disas(mon, cs, addr, count, is_physical); 565 return; 566 } 567 568 len = wsize * count; 569 if (wsize == 1) 570 line_size = 8; 571 else 572 line_size = 16; 573 max_digits = 0; 574 575 switch(format) { 576 case 'o': 577 max_digits = DIV_ROUND_UP(wsize * 8, 3); 578 break; 579 default: 580 case 'x': 581 max_digits = (wsize * 8) / 4; 582 break; 583 case 'u': 584 case 'd': 585 max_digits = DIV_ROUND_UP(wsize * 8 * 10, 33); 586 break; 587 case 'c': 588 wsize = 1; 589 break; 590 } 591 592 while (len > 0) { 593 if (is_physical) 594 monitor_printf(mon, TARGET_FMT_plx ":", addr); 595 else 596 monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr); 597 l = len; 598 if (l > line_size) 599 l = line_size; 600 if (is_physical) { 601 AddressSpace *as = cs ? cs->as : &address_space_memory; 602 MemTxResult r = address_space_read(as, addr, 603 MEMTXATTRS_UNSPECIFIED, buf, l); 604 if (r != MEMTX_OK) { 605 monitor_printf(mon, " Cannot access memory\n"); 606 break; 607 } 608 } else { 609 if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) { 610 monitor_printf(mon, " Cannot access memory\n"); 611 break; 612 } 613 } 614 i = 0; 615 while (i < l) { 616 switch(wsize) { 617 default: 618 case 1: 619 v = ldub_p(buf + i); 620 break; 621 case 2: 622 v = lduw_p(buf + i); 623 break; 624 case 4: 625 v = (uint32_t)ldl_p(buf + i); 626 break; 627 case 8: 628 v = ldq_p(buf + i); 629 break; 630 } 631 monitor_printf(mon, " "); 632 switch(format) { 633 case 'o': 634 monitor_printf(mon, "%#*" PRIo64, max_digits, v); 635 break; 636 case 'x': 637 monitor_printf(mon, "0x%0*" PRIx64, max_digits, v); 638 break; 639 case 'u': 640 monitor_printf(mon, "%*" PRIu64, max_digits, v); 641 break; 642 case 'd': 643 monitor_printf(mon, "%*" PRId64, max_digits, v); 644 break; 645 case 'c': 646 monitor_printc(mon, v); 647 break; 648 } 649 i += wsize; 650 } 651 monitor_printf(mon, "\n"); 652 addr += l; 653 len -= l; 654 } 655} 656 657static void hmp_memory_dump(Monitor *mon, const QDict *qdict) 658{ 659 int count = qdict_get_int(qdict, "count"); 660 int format = qdict_get_int(qdict, "format"); 661 int size = qdict_get_int(qdict, "size"); 662 target_long addr = qdict_get_int(qdict, "addr"); 663 664 memory_dump(mon, count, format, size, addr, 0); 665} 666 667static void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict) 668{ 669 int count = qdict_get_int(qdict, "count"); 670 int format = qdict_get_int(qdict, "format"); 671 int size = qdict_get_int(qdict, "size"); 672 hwaddr addr = qdict_get_int(qdict, "addr"); 673 674 memory_dump(mon, count, format, size, addr, 1); 675} 676 677static void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp) 678{ 679 MemoryRegionSection mrs = memory_region_find(get_system_memory(), 680 addr, 1); 681 682 if (!mrs.mr) { 683 error_setg(errp, "No memory is mapped at address 0x%" HWADDR_PRIx, addr); 684 return NULL; 685 } 686 687 if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) { 688 error_setg(errp, "Memory at address 0x%" HWADDR_PRIx "is not RAM", addr); 689 memory_region_unref(mrs.mr); 690 return NULL; 691 } 692 693 *p_mr = mrs.mr; 694 return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region); 695} 696 697static void hmp_gpa2hva(Monitor *mon, const QDict *qdict) 698{ 699 hwaddr addr = qdict_get_int(qdict, "addr"); 700 Error *local_err = NULL; 701 MemoryRegion *mr = NULL; 702 void *ptr; 703 704 ptr = gpa2hva(&mr, addr, &local_err); 705 if (local_err) { 706 error_report_err(local_err); 707 return; 708 } 709 710 monitor_printf(mon, "Host virtual address for 0x%" HWADDR_PRIx 711 " (%s) is %p\n", 712 addr, mr->name, ptr); 713 714 memory_region_unref(mr); 715} 716 717static void hmp_gva2gpa(Monitor *mon, const QDict *qdict) 718{ 719 target_ulong addr = qdict_get_int(qdict, "addr"); 720 MemTxAttrs attrs; 721 CPUState *cs = mon_get_cpu(); 722 hwaddr gpa; 723 724 if (!cs) { 725 monitor_printf(mon, "No cpu\n"); 726 return; 727 } 728 729 gpa = cpu_get_phys_page_attrs_debug(cs, addr & TARGET_PAGE_MASK, &attrs); 730 if (gpa == -1) { 731 monitor_printf(mon, "Unmapped\n"); 732 } else { 733 monitor_printf(mon, "gpa: %#" HWADDR_PRIx "\n", 734 gpa + (addr & ~TARGET_PAGE_MASK)); 735 } 736} 737 738#ifdef CONFIG_LINUX 739static uint64_t vtop(void *ptr, Error **errp) 740{ 741 uint64_t pinfo; 742 uint64_t ret = -1; 743 uintptr_t addr = (uintptr_t) ptr; 744 uintptr_t pagesize = qemu_real_host_page_size; 745 off_t offset = addr / pagesize * sizeof(pinfo); 746 int fd; 747 748 fd = open("/proc/self/pagemap", O_RDONLY); 749 if (fd == -1) { 750 error_setg_errno(errp, errno, "Cannot open /proc/self/pagemap"); 751 return -1; 752 } 753 754 /* Force copy-on-write if necessary. */ 755 atomic_add((uint8_t *)ptr, 0); 756 757 if (pread(fd, &pinfo, sizeof(pinfo), offset) != sizeof(pinfo)) { 758 error_setg_errno(errp, errno, "Cannot read pagemap"); 759 goto out; 760 } 761 if ((pinfo & (1ull << 63)) == 0) { 762 error_setg(errp, "Page not present"); 763 goto out; 764 } 765 ret = ((pinfo & 0x007fffffffffffffull) * pagesize) | (addr & (pagesize - 1)); 766 767out: 768 close(fd); 769 return ret; 770} 771 772static void hmp_gpa2hpa(Monitor *mon, const QDict *qdict) 773{ 774 hwaddr addr = qdict_get_int(qdict, "addr"); 775 Error *local_err = NULL; 776 MemoryRegion *mr = NULL; 777 void *ptr; 778 uint64_t physaddr; 779 780 ptr = gpa2hva(&mr, addr, &local_err); 781 if (local_err) { 782 error_report_err(local_err); 783 return; 784 } 785 786 physaddr = vtop(ptr, &local_err); 787 if (local_err) { 788 error_report_err(local_err); 789 } else { 790 monitor_printf(mon, "Host physical address for 0x%" HWADDR_PRIx 791 " (%s) is 0x%" PRIx64 "\n", 792 addr, mr->name, (uint64_t) physaddr); 793 } 794 795 memory_region_unref(mr); 796} 797#endif 798 799static void do_print(Monitor *mon, const QDict *qdict) 800{ 801 int format = qdict_get_int(qdict, "format"); 802 hwaddr val = qdict_get_int(qdict, "val"); 803 804 switch(format) { 805 case 'o': 806 monitor_printf(mon, "%#" HWADDR_PRIo, val); 807 break; 808 case 'x': 809 monitor_printf(mon, "%#" HWADDR_PRIx, val); 810 break; 811 case 'u': 812 monitor_printf(mon, "%" HWADDR_PRIu, val); 813 break; 814 default: 815 case 'd': 816 monitor_printf(mon, "%" HWADDR_PRId, val); 817 break; 818 case 'c': 819 monitor_printc(mon, val); 820 break; 821 } 822 monitor_printf(mon, "\n"); 823} 824 825static void hmp_sum(Monitor *mon, const QDict *qdict) 826{ 827 uint32_t addr; 828 uint16_t sum; 829 uint32_t start = qdict_get_int(qdict, "start"); 830 uint32_t size = qdict_get_int(qdict, "size"); 831 832 sum = 0; 833 for(addr = start; addr < (start + size); addr++) { 834 uint8_t val = address_space_ldub(&address_space_memory, addr, 835 MEMTXATTRS_UNSPECIFIED, NULL); 836 /* BSD sum algorithm ('sum' Unix command) */ 837 sum = (sum >> 1) | (sum << 15); 838 sum += val; 839 } 840 monitor_printf(mon, "%05d\n", sum); 841} 842 843static int mouse_button_state; 844 845static void hmp_mouse_move(Monitor *mon, const QDict *qdict) 846{ 847 int dx, dy, dz, button; 848 const char *dx_str = qdict_get_str(qdict, "dx_str"); 849 const char *dy_str = qdict_get_str(qdict, "dy_str"); 850 const char *dz_str = qdict_get_try_str(qdict, "dz_str"); 851 852 dx = strtol(dx_str, NULL, 0); 853 dy = strtol(dy_str, NULL, 0); 854 qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx); 855 qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy); 856 857 if (dz_str) { 858 dz = strtol(dz_str, NULL, 0); 859 if (dz != 0) { 860 button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN; 861 qemu_input_queue_btn(NULL, button, true); 862 qemu_input_event_sync(); 863 qemu_input_queue_btn(NULL, button, false); 864 } 865 } 866 qemu_input_event_sync(); 867} 868 869static void hmp_mouse_button(Monitor *mon, const QDict *qdict) 870{ 871 static uint32_t bmap[INPUT_BUTTON__MAX] = { 872 [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, 873 [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, 874 [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, 875 }; 876 int button_state = qdict_get_int(qdict, "button_state"); 877 878 if (mouse_button_state == button_state) { 879 return; 880 } 881 qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state); 882 qemu_input_event_sync(); 883 mouse_button_state = button_state; 884} 885 886static void hmp_ioport_read(Monitor *mon, const QDict *qdict) 887{ 888 int size = qdict_get_int(qdict, "size"); 889 int addr = qdict_get_int(qdict, "addr"); 890 int has_index = qdict_haskey(qdict, "index"); 891 uint32_t val; 892 int suffix; 893 894 if (has_index) { 895 int index = qdict_get_int(qdict, "index"); 896 cpu_outb(addr & IOPORTS_MASK, index & 0xff); 897 addr++; 898 } 899 addr &= 0xffff; 900 901 switch(size) { 902 default: 903 case 1: 904 val = cpu_inb(addr); 905 suffix = 'b'; 906 break; 907 case 2: 908 val = cpu_inw(addr); 909 suffix = 'w'; 910 break; 911 case 4: 912 val = cpu_inl(addr); 913 suffix = 'l'; 914 break; 915 } 916 monitor_printf(mon, "port%c[0x%04x] = %#0*x\n", 917 suffix, addr, size * 2, val); 918} 919 920static void hmp_ioport_write(Monitor *mon, const QDict *qdict) 921{ 922 int size = qdict_get_int(qdict, "size"); 923 int addr = qdict_get_int(qdict, "addr"); 924 int val = qdict_get_int(qdict, "val"); 925 926 addr &= IOPORTS_MASK; 927 928 switch (size) { 929 default: 930 case 1: 931 cpu_outb(addr, val); 932 break; 933 case 2: 934 cpu_outw(addr, val); 935 break; 936 case 4: 937 cpu_outl(addr, val); 938 break; 939 } 940} 941 942static void hmp_boot_set(Monitor *mon, const QDict *qdict) 943{ 944 Error *local_err = NULL; 945 const char *bootdevice = qdict_get_str(qdict, "bootdevice"); 946 947 qemu_boot_set(bootdevice, &local_err); 948 if (local_err) { 949 error_report_err(local_err); 950 } else { 951 monitor_printf(mon, "boot device list now set to %s\n", bootdevice); 952 } 953} 954 955static void hmp_info_mtree(Monitor *mon, const QDict *qdict) 956{ 957 bool flatview = qdict_get_try_bool(qdict, "flatview", false); 958 bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false); 959 bool owner = qdict_get_try_bool(qdict, "owner", false); 960 961 mtree_info(flatview, dispatch_tree, owner); 962} 963 964#ifdef CONFIG_PROFILER 965 966int64_t dev_time; 967 968static void hmp_info_profile(Monitor *mon, const QDict *qdict) 969{ 970 static int64_t last_cpu_exec_time; 971 int64_t cpu_exec_time; 972 int64_t delta; 973 974 cpu_exec_time = tcg_cpu_exec_time(); 975 delta = cpu_exec_time - last_cpu_exec_time; 976 977 monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n", 978 dev_time, dev_time / (double)NANOSECONDS_PER_SECOND); 979 monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n", 980 delta, delta / (double)NANOSECONDS_PER_SECOND); 981 last_cpu_exec_time = cpu_exec_time; 982 dev_time = 0; 983} 984#else 985static void hmp_info_profile(Monitor *mon, const QDict *qdict) 986{ 987 monitor_printf(mon, "Internal profiler not compiled\n"); 988} 989#endif 990 991/* Capture support */ 992static QLIST_HEAD (capture_list_head, CaptureState) capture_head; 993 994static void hmp_info_capture(Monitor *mon, const QDict *qdict) 995{ 996 int i; 997 CaptureState *s; 998 999 for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { 1000 monitor_printf(mon, "[%d]: ", i); 1001 s->ops.info (s->opaque); 1002 } 1003} 1004 1005static void hmp_stopcapture(Monitor *mon, const QDict *qdict) 1006{ 1007 int i; 1008 int n = qdict_get_int(qdict, "n"); 1009 CaptureState *s; 1010 1011 for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { 1012 if (i == n) { 1013 s->ops.destroy (s->opaque); 1014 QLIST_REMOVE (s, entries); 1015 g_free (s); 1016 return; 1017 } 1018 } 1019} 1020 1021static void hmp_wavcapture(Monitor *mon, const QDict *qdict) 1022{ 1023 const char *path = qdict_get_str(qdict, "path"); 1024 int freq = qdict_get_try_int(qdict, "freq", 44100); 1025 int bits = qdict_get_try_int(qdict, "bits", 16); 1026 int nchannels = qdict_get_try_int(qdict, "nchannels", 2); 1027 const char *audiodev = qdict_get_str(qdict, "audiodev"); 1028 CaptureState *s; 1029 AudioState *as = audio_state_by_name(audiodev); 1030 1031 if (!as) { 1032 monitor_printf(mon, "Audiodev '%s' not found\n", audiodev); 1033 return; 1034 } 1035 1036 s = g_malloc0 (sizeof (*s)); 1037 1038 if (wav_start_capture(as, s, path, freq, bits, nchannels)) { 1039 monitor_printf(mon, "Failed to add wave capture\n"); 1040 g_free (s); 1041 return; 1042 } 1043 QLIST_INSERT_HEAD (&capture_head, s, entries); 1044} 1045 1046static QAuthZList *find_auth(Monitor *mon, const char *name) 1047{ 1048 Object *obj; 1049 Object *container; 1050 1051 container = object_get_objects_root(); 1052 obj = object_resolve_path_component(container, name); 1053 if (!obj) { 1054 monitor_printf(mon, "acl: unknown list '%s'\n", name); 1055 return NULL; 1056 } 1057 1058 return QAUTHZ_LIST(obj); 1059} 1060 1061static bool warn_acl; 1062static void hmp_warn_acl(void) 1063{ 1064 if (warn_acl) { 1065 return; 1066 } 1067 error_report("The acl_show, acl_reset, acl_policy, acl_add, acl_remove " 1068 "commands are deprecated with no replacement. Authorization " 1069 "for VNC should be performed using the pluggable QAuthZ " 1070 "objects"); 1071 warn_acl = true; 1072} 1073 1074static void hmp_acl_show(Monitor *mon, const QDict *qdict) 1075{ 1076 const char *aclname = qdict_get_str(qdict, "aclname"); 1077 QAuthZList *auth = find_auth(mon, aclname); 1078 QAuthZListRuleList *rules; 1079 size_t i = 0; 1080 1081 hmp_warn_acl(); 1082 1083 if (!auth) { 1084 return; 1085 } 1086 1087 monitor_printf(mon, "policy: %s\n", 1088 QAuthZListPolicy_str(auth->policy)); 1089 1090 rules = auth->rules; 1091 while (rules) { 1092 QAuthZListRule *rule = rules->value; 1093 i++; 1094 monitor_printf(mon, "%zu: %s %s\n", i, 1095 QAuthZListPolicy_str(rule->policy), 1096 rule->match); 1097 rules = rules->next; 1098 } 1099} 1100 1101static void hmp_acl_reset(Monitor *mon, const QDict *qdict) 1102{ 1103 const char *aclname = qdict_get_str(qdict, "aclname"); 1104 QAuthZList *auth = find_auth(mon, aclname); 1105 1106 hmp_warn_acl(); 1107 1108 if (!auth) { 1109 return; 1110 } 1111 1112 auth->policy = QAUTHZ_LIST_POLICY_DENY; 1113 qapi_free_QAuthZListRuleList(auth->rules); 1114 auth->rules = NULL; 1115 monitor_printf(mon, "acl: removed all rules\n"); 1116} 1117 1118static void hmp_acl_policy(Monitor *mon, const QDict *qdict) 1119{ 1120 const char *aclname = qdict_get_str(qdict, "aclname"); 1121 const char *policy = qdict_get_str(qdict, "policy"); 1122 QAuthZList *auth = find_auth(mon, aclname); 1123 int val; 1124 Error *err = NULL; 1125 1126 hmp_warn_acl(); 1127 1128 if (!auth) { 1129 return; 1130 } 1131 1132 val = qapi_enum_parse(&QAuthZListPolicy_lookup, 1133 policy, 1134 QAUTHZ_LIST_POLICY_DENY, 1135 &err); 1136 if (err) { 1137 error_free(err); 1138 monitor_printf(mon, "acl: unknown policy '%s', " 1139 "expected 'deny' or 'allow'\n", policy); 1140 } else { 1141 auth->policy = val; 1142 if (auth->policy == QAUTHZ_LIST_POLICY_ALLOW) { 1143 monitor_printf(mon, "acl: policy set to 'allow'\n"); 1144 } else { 1145 monitor_printf(mon, "acl: policy set to 'deny'\n"); 1146 } 1147 } 1148} 1149 1150static QAuthZListFormat hmp_acl_get_format(const char *match) 1151{ 1152 if (strchr(match, '*')) { 1153 return QAUTHZ_LIST_FORMAT_GLOB; 1154 } else { 1155 return QAUTHZ_LIST_FORMAT_EXACT; 1156 } 1157} 1158 1159static void hmp_acl_add(Monitor *mon, const QDict *qdict) 1160{ 1161 const char *aclname = qdict_get_str(qdict, "aclname"); 1162 const char *match = qdict_get_str(qdict, "match"); 1163 const char *policystr = qdict_get_str(qdict, "policy"); 1164 int has_index = qdict_haskey(qdict, "index"); 1165 int index = qdict_get_try_int(qdict, "index", -1); 1166 QAuthZList *auth = find_auth(mon, aclname); 1167 Error *err = NULL; 1168 QAuthZListPolicy policy; 1169 QAuthZListFormat format; 1170 size_t i = 0; 1171 1172 hmp_warn_acl(); 1173 1174 if (!auth) { 1175 return; 1176 } 1177 1178 policy = qapi_enum_parse(&QAuthZListPolicy_lookup, 1179 policystr, 1180 QAUTHZ_LIST_POLICY_DENY, 1181 &err); 1182 if (err) { 1183 error_free(err); 1184 monitor_printf(mon, "acl: unknown policy '%s', " 1185 "expected 'deny' or 'allow'\n", policystr); 1186 return; 1187 } 1188 1189 format = hmp_acl_get_format(match); 1190 1191 if (has_index && index == 0) { 1192 monitor_printf(mon, "acl: unable to add acl entry\n"); 1193 return; 1194 } 1195 1196 if (has_index) { 1197 i = qauthz_list_insert_rule(auth, match, policy, 1198 format, index - 1, &err); 1199 } else { 1200 i = qauthz_list_append_rule(auth, match, policy, 1201 format, &err); 1202 } 1203 if (err) { 1204 monitor_printf(mon, "acl: unable to add rule: %s", 1205 error_get_pretty(err)); 1206 error_free(err); 1207 } else { 1208 monitor_printf(mon, "acl: added rule at position %zu\n", i + 1); 1209 } 1210} 1211 1212static void hmp_acl_remove(Monitor *mon, const QDict *qdict) 1213{ 1214 const char *aclname = qdict_get_str(qdict, "aclname"); 1215 const char *match = qdict_get_str(qdict, "match"); 1216 QAuthZList *auth = find_auth(mon, aclname); 1217 ssize_t i = 0; 1218 1219 hmp_warn_acl(); 1220 1221 if (!auth) { 1222 return; 1223 } 1224 1225 i = qauthz_list_delete_rule(auth, match); 1226 if (i >= 0) { 1227 monitor_printf(mon, "acl: removed rule at position %zu\n", i + 1); 1228 } else { 1229 monitor_printf(mon, "acl: no matching acl entry\n"); 1230 } 1231} 1232 1233void qmp_getfd(const char *fdname, Error **errp) 1234{ 1235 mon_fd_t *monfd; 1236 int fd, tmp_fd; 1237 1238 fd = qemu_chr_fe_get_msgfd(&cur_mon->chr); 1239 if (fd == -1) { 1240 error_setg(errp, QERR_FD_NOT_SUPPLIED); 1241 return; 1242 } 1243 1244 if (qemu_isdigit(fdname[0])) { 1245 close(fd); 1246 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdname", 1247 "a name not starting with a digit"); 1248 return; 1249 } 1250 1251 qemu_mutex_lock(&cur_mon->mon_lock); 1252 QLIST_FOREACH(monfd, &cur_mon->fds, next) { 1253 if (strcmp(monfd->name, fdname) != 0) { 1254 continue; 1255 } 1256 1257 tmp_fd = monfd->fd; 1258 monfd->fd = fd; 1259 qemu_mutex_unlock(&cur_mon->mon_lock); 1260 /* Make sure close() is outside critical section */ 1261 close(tmp_fd); 1262 return; 1263 } 1264 1265 monfd = g_malloc0(sizeof(mon_fd_t)); 1266 monfd->name = g_strdup(fdname); 1267 monfd->fd = fd; 1268 1269 QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next); 1270 qemu_mutex_unlock(&cur_mon->mon_lock); 1271} 1272 1273void qmp_closefd(const char *fdname, Error **errp) 1274{ 1275 mon_fd_t *monfd; 1276 int tmp_fd; 1277 1278 qemu_mutex_lock(&cur_mon->mon_lock); 1279 QLIST_FOREACH(monfd, &cur_mon->fds, next) { 1280 if (strcmp(monfd->name, fdname) != 0) { 1281 continue; 1282 } 1283 1284 QLIST_REMOVE(monfd, next); 1285 tmp_fd = monfd->fd; 1286 g_free(monfd->name); 1287 g_free(monfd); 1288 qemu_mutex_unlock(&cur_mon->mon_lock); 1289 /* Make sure close() is outside critical section */ 1290 close(tmp_fd); 1291 return; 1292 } 1293 1294 qemu_mutex_unlock(&cur_mon->mon_lock); 1295 error_setg(errp, QERR_FD_NOT_FOUND, fdname); 1296} 1297 1298int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp) 1299{ 1300 mon_fd_t *monfd; 1301 1302 qemu_mutex_lock(&mon->mon_lock); 1303 QLIST_FOREACH(monfd, &mon->fds, next) { 1304 int fd; 1305 1306 if (strcmp(monfd->name, fdname) != 0) { 1307 continue; 1308 } 1309 1310 fd = monfd->fd; 1311 1312 /* caller takes ownership of fd */ 1313 QLIST_REMOVE(monfd, next); 1314 g_free(monfd->name); 1315 g_free(monfd); 1316 qemu_mutex_unlock(&mon->mon_lock); 1317 1318 return fd; 1319 } 1320 1321 qemu_mutex_unlock(&mon->mon_lock); 1322 error_setg(errp, "File descriptor named '%s' has not been found", fdname); 1323 return -1; 1324} 1325 1326static void monitor_fdset_cleanup(MonFdset *mon_fdset) 1327{ 1328 MonFdsetFd *mon_fdset_fd; 1329 MonFdsetFd *mon_fdset_fd_next; 1330 1331 QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, mon_fdset_fd_next) { 1332 if ((mon_fdset_fd->removed || 1333 (QLIST_EMPTY(&mon_fdset->dup_fds) && mon_refcount == 0)) && 1334 runstate_is_running()) { 1335 close(mon_fdset_fd->fd); 1336 g_free(mon_fdset_fd->opaque); 1337 QLIST_REMOVE(mon_fdset_fd, next); 1338 g_free(mon_fdset_fd); 1339 } 1340 } 1341 1342 if (QLIST_EMPTY(&mon_fdset->fds) && QLIST_EMPTY(&mon_fdset->dup_fds)) { 1343 QLIST_REMOVE(mon_fdset, next); 1344 g_free(mon_fdset); 1345 } 1346} 1347 1348void monitor_fdsets_cleanup(void) 1349{ 1350 MonFdset *mon_fdset; 1351 MonFdset *mon_fdset_next; 1352 1353 qemu_mutex_lock(&mon_fdsets_lock); 1354 QLIST_FOREACH_SAFE(mon_fdset, &mon_fdsets, next, mon_fdset_next) { 1355 monitor_fdset_cleanup(mon_fdset); 1356 } 1357 qemu_mutex_unlock(&mon_fdsets_lock); 1358} 1359 1360AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, 1361 const char *opaque, Error **errp) 1362{ 1363 int fd; 1364 Monitor *mon = cur_mon; 1365 AddfdInfo *fdinfo; 1366 1367 fd = qemu_chr_fe_get_msgfd(&mon->chr); 1368 if (fd == -1) { 1369 error_setg(errp, QERR_FD_NOT_SUPPLIED); 1370 goto error; 1371 } 1372 1373 fdinfo = monitor_fdset_add_fd(fd, has_fdset_id, fdset_id, 1374 has_opaque, opaque, errp); 1375 if (fdinfo) { 1376 return fdinfo; 1377 } 1378 1379error: 1380 if (fd != -1) { 1381 close(fd); 1382 } 1383 return NULL; 1384} 1385 1386void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp) 1387{ 1388 MonFdset *mon_fdset; 1389 MonFdsetFd *mon_fdset_fd; 1390 char fd_str[60]; 1391 1392 qemu_mutex_lock(&mon_fdsets_lock); 1393 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1394 if (mon_fdset->id != fdset_id) { 1395 continue; 1396 } 1397 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { 1398 if (has_fd) { 1399 if (mon_fdset_fd->fd != fd) { 1400 continue; 1401 } 1402 mon_fdset_fd->removed = true; 1403 break; 1404 } else { 1405 mon_fdset_fd->removed = true; 1406 } 1407 } 1408 if (has_fd && !mon_fdset_fd) { 1409 goto error; 1410 } 1411 monitor_fdset_cleanup(mon_fdset); 1412 qemu_mutex_unlock(&mon_fdsets_lock); 1413 return; 1414 } 1415 1416error: 1417 qemu_mutex_unlock(&mon_fdsets_lock); 1418 if (has_fd) { 1419 snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64 ", fd:%" PRId64, 1420 fdset_id, fd); 1421 } else { 1422 snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64, fdset_id); 1423 } 1424 error_setg(errp, QERR_FD_NOT_FOUND, fd_str); 1425} 1426 1427FdsetInfoList *qmp_query_fdsets(Error **errp) 1428{ 1429 MonFdset *mon_fdset; 1430 MonFdsetFd *mon_fdset_fd; 1431 FdsetInfoList *fdset_list = NULL; 1432 1433 qemu_mutex_lock(&mon_fdsets_lock); 1434 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1435 FdsetInfoList *fdset_info = g_malloc0(sizeof(*fdset_info)); 1436 FdsetFdInfoList *fdsetfd_list = NULL; 1437 1438 fdset_info->value = g_malloc0(sizeof(*fdset_info->value)); 1439 fdset_info->value->fdset_id = mon_fdset->id; 1440 1441 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { 1442 FdsetFdInfoList *fdsetfd_info; 1443 1444 fdsetfd_info = g_malloc0(sizeof(*fdsetfd_info)); 1445 fdsetfd_info->value = g_malloc0(sizeof(*fdsetfd_info->value)); 1446 fdsetfd_info->value->fd = mon_fdset_fd->fd; 1447 if (mon_fdset_fd->opaque) { 1448 fdsetfd_info->value->has_opaque = true; 1449 fdsetfd_info->value->opaque = g_strdup(mon_fdset_fd->opaque); 1450 } else { 1451 fdsetfd_info->value->has_opaque = false; 1452 } 1453 1454 fdsetfd_info->next = fdsetfd_list; 1455 fdsetfd_list = fdsetfd_info; 1456 } 1457 1458 fdset_info->value->fds = fdsetfd_list; 1459 1460 fdset_info->next = fdset_list; 1461 fdset_list = fdset_info; 1462 } 1463 qemu_mutex_unlock(&mon_fdsets_lock); 1464 1465 return fdset_list; 1466} 1467 1468AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id, 1469 bool has_opaque, const char *opaque, 1470 Error **errp) 1471{ 1472 MonFdset *mon_fdset = NULL; 1473 MonFdsetFd *mon_fdset_fd; 1474 AddfdInfo *fdinfo; 1475 1476 qemu_mutex_lock(&mon_fdsets_lock); 1477 if (has_fdset_id) { 1478 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1479 /* Break if match found or match impossible due to ordering by ID */ 1480 if (fdset_id <= mon_fdset->id) { 1481 if (fdset_id < mon_fdset->id) { 1482 mon_fdset = NULL; 1483 } 1484 break; 1485 } 1486 } 1487 } 1488 1489 if (mon_fdset == NULL) { 1490 int64_t fdset_id_prev = -1; 1491 MonFdset *mon_fdset_cur = QLIST_FIRST(&mon_fdsets); 1492 1493 if (has_fdset_id) { 1494 if (fdset_id < 0) { 1495 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id", 1496 "a non-negative value"); 1497 qemu_mutex_unlock(&mon_fdsets_lock); 1498 return NULL; 1499 } 1500 /* Use specified fdset ID */ 1501 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1502 mon_fdset_cur = mon_fdset; 1503 if (fdset_id < mon_fdset_cur->id) { 1504 break; 1505 } 1506 } 1507 } else { 1508 /* Use first available fdset ID */ 1509 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1510 mon_fdset_cur = mon_fdset; 1511 if (fdset_id_prev == mon_fdset_cur->id - 1) { 1512 fdset_id_prev = mon_fdset_cur->id; 1513 continue; 1514 } 1515 break; 1516 } 1517 } 1518 1519 mon_fdset = g_malloc0(sizeof(*mon_fdset)); 1520 if (has_fdset_id) { 1521 mon_fdset->id = fdset_id; 1522 } else { 1523 mon_fdset->id = fdset_id_prev + 1; 1524 } 1525 1526 /* The fdset list is ordered by fdset ID */ 1527 if (!mon_fdset_cur) { 1528 QLIST_INSERT_HEAD(&mon_fdsets, mon_fdset, next); 1529 } else if (mon_fdset->id < mon_fdset_cur->id) { 1530 QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next); 1531 } else { 1532 QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next); 1533 } 1534 } 1535 1536 mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd)); 1537 mon_fdset_fd->fd = fd; 1538 mon_fdset_fd->removed = false; 1539 if (has_opaque) { 1540 mon_fdset_fd->opaque = g_strdup(opaque); 1541 } 1542 QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next); 1543 1544 fdinfo = g_malloc0(sizeof(*fdinfo)); 1545 fdinfo->fdset_id = mon_fdset->id; 1546 fdinfo->fd = mon_fdset_fd->fd; 1547 1548 qemu_mutex_unlock(&mon_fdsets_lock); 1549 return fdinfo; 1550} 1551 1552int monitor_fdset_get_fd(int64_t fdset_id, int flags) 1553{ 1554#ifdef _WIN32 1555 return -ENOENT; 1556#else 1557 MonFdset *mon_fdset; 1558 MonFdsetFd *mon_fdset_fd; 1559 int mon_fd_flags; 1560 int ret; 1561 1562 qemu_mutex_lock(&mon_fdsets_lock); 1563 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1564 if (mon_fdset->id != fdset_id) { 1565 continue; 1566 } 1567 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { 1568 mon_fd_flags = fcntl(mon_fdset_fd->fd, F_GETFL); 1569 if (mon_fd_flags == -1) { 1570 ret = -errno; 1571 goto out; 1572 } 1573 1574 if ((flags & O_ACCMODE) == (mon_fd_flags & O_ACCMODE)) { 1575 ret = mon_fdset_fd->fd; 1576 goto out; 1577 } 1578 } 1579 ret = -EACCES; 1580 goto out; 1581 } 1582 ret = -ENOENT; 1583 1584out: 1585 qemu_mutex_unlock(&mon_fdsets_lock); 1586 return ret; 1587#endif 1588} 1589 1590int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd) 1591{ 1592 MonFdset *mon_fdset; 1593 MonFdsetFd *mon_fdset_fd_dup; 1594 1595 qemu_mutex_lock(&mon_fdsets_lock); 1596 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1597 if (mon_fdset->id != fdset_id) { 1598 continue; 1599 } 1600 QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) { 1601 if (mon_fdset_fd_dup->fd == dup_fd) { 1602 goto err; 1603 } 1604 } 1605 mon_fdset_fd_dup = g_malloc0(sizeof(*mon_fdset_fd_dup)); 1606 mon_fdset_fd_dup->fd = dup_fd; 1607 QLIST_INSERT_HEAD(&mon_fdset->dup_fds, mon_fdset_fd_dup, next); 1608 qemu_mutex_unlock(&mon_fdsets_lock); 1609 return 0; 1610 } 1611 1612err: 1613 qemu_mutex_unlock(&mon_fdsets_lock); 1614 return -1; 1615} 1616 1617static int64_t monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove) 1618{ 1619 MonFdset *mon_fdset; 1620 MonFdsetFd *mon_fdset_fd_dup; 1621 1622 qemu_mutex_lock(&mon_fdsets_lock); 1623 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1624 QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) { 1625 if (mon_fdset_fd_dup->fd == dup_fd) { 1626 if (remove) { 1627 QLIST_REMOVE(mon_fdset_fd_dup, next); 1628 g_free(mon_fdset_fd_dup); 1629 if (QLIST_EMPTY(&mon_fdset->dup_fds)) { 1630 monitor_fdset_cleanup(mon_fdset); 1631 } 1632 goto err; 1633 } else { 1634 qemu_mutex_unlock(&mon_fdsets_lock); 1635 return mon_fdset->id; 1636 } 1637 } 1638 } 1639 } 1640 1641err: 1642 qemu_mutex_unlock(&mon_fdsets_lock); 1643 return -1; 1644} 1645 1646int64_t monitor_fdset_dup_fd_find(int dup_fd) 1647{ 1648 return monitor_fdset_dup_fd_find_remove(dup_fd, false); 1649} 1650 1651void monitor_fdset_dup_fd_remove(int dup_fd) 1652{ 1653 monitor_fdset_dup_fd_find_remove(dup_fd, true); 1654} 1655 1656int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp) 1657{ 1658 int fd; 1659 Error *local_err = NULL; 1660 1661 if (!qemu_isdigit(fdname[0]) && mon) { 1662 fd = monitor_get_fd(mon, fdname, &local_err); 1663 } else { 1664 fd = qemu_parse_fd(fdname); 1665 if (fd == -1) { 1666 error_setg(&local_err, "Invalid file descriptor number '%s'", 1667 fdname); 1668 } 1669 } 1670 if (local_err) { 1671 error_propagate(errp, local_err); 1672 assert(fd == -1); 1673 } else { 1674 assert(fd != -1); 1675 } 1676 1677 return fd; 1678} 1679 1680/* Please update hmp-commands.hx when adding or changing commands */ 1681static HMPCommand hmp_info_cmds[] = { 1682#include "hmp-commands-info.h" 1683 { NULL, NULL, }, 1684}; 1685 1686/* hmp_cmds and hmp_info_cmds would be sorted at runtime */ 1687HMPCommand hmp_cmds[] = { 1688#include "hmp-commands.h" 1689 { NULL, NULL, }, 1690}; 1691 1692/* 1693 * Set @pval to the value in the register identified by @name. 1694 * return 0 if OK, -1 if not found 1695 */ 1696int get_monitor_def(int64_t *pval, const char *name) 1697{ 1698 const MonitorDef *md = target_monitor_defs(); 1699 CPUState *cs = mon_get_cpu(); 1700 void *ptr; 1701 uint64_t tmp = 0; 1702 int ret; 1703 1704 if (cs == NULL || md == NULL) { 1705 return -1; 1706 } 1707 1708 for(; md->name != NULL; md++) { 1709 if (hmp_compare_cmd(name, md->name)) { 1710 if (md->get_value) { 1711 *pval = md->get_value(md, md->offset); 1712 } else { 1713 CPUArchState *env = mon_get_cpu_env(); 1714 ptr = (uint8_t *)env + md->offset; 1715 switch(md->type) { 1716 case MD_I32: 1717 *pval = *(int32_t *)ptr; 1718 break; 1719 case MD_TLONG: 1720 *pval = *(target_long *)ptr; 1721 break; 1722 default: 1723 *pval = 0; 1724 break; 1725 } 1726 } 1727 return 0; 1728 } 1729 } 1730 1731 ret = target_get_monitor_def(cs, name, &tmp); 1732 if (!ret) { 1733 *pval = (target_long) tmp; 1734 } 1735 1736 return ret; 1737} 1738 1739static void add_completion_option(ReadLineState *rs, const char *str, 1740 const char *option) 1741{ 1742 if (!str || !option) { 1743 return; 1744 } 1745 if (!strncmp(option, str, strlen(str))) { 1746 readline_add_completion(rs, option); 1747 } 1748} 1749 1750void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str) 1751{ 1752 size_t len; 1753 ChardevBackendInfoList *list, *start; 1754 1755 if (nb_args != 2) { 1756 return; 1757 } 1758 len = strlen(str); 1759 readline_set_completion_index(rs, len); 1760 1761 start = list = qmp_query_chardev_backends(NULL); 1762 while (list) { 1763 const char *chr_name = list->value->name; 1764 1765 if (!strncmp(chr_name, str, len)) { 1766 readline_add_completion(rs, chr_name); 1767 } 1768 list = list->next; 1769 } 1770 qapi_free_ChardevBackendInfoList(start); 1771} 1772 1773void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str) 1774{ 1775 size_t len; 1776 int i; 1777 1778 if (nb_args != 2) { 1779 return; 1780 } 1781 len = strlen(str); 1782 readline_set_completion_index(rs, len); 1783 for (i = 0; i < NET_CLIENT_DRIVER__MAX; i++) { 1784 add_completion_option(rs, str, NetClientDriver_str(i)); 1785 } 1786} 1787 1788void device_add_completion(ReadLineState *rs, int nb_args, const char *str) 1789{ 1790 GSList *list, *elt; 1791 size_t len; 1792 1793 if (nb_args != 2) { 1794 return; 1795 } 1796 1797 len = strlen(str); 1798 readline_set_completion_index(rs, len); 1799 list = elt = object_class_get_list(TYPE_DEVICE, false); 1800 while (elt) { 1801 const char *name; 1802 DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data, 1803 TYPE_DEVICE); 1804 name = object_class_get_name(OBJECT_CLASS(dc)); 1805 1806 if (dc->user_creatable 1807 && !strncmp(name, str, len)) { 1808 readline_add_completion(rs, name); 1809 } 1810 elt = elt->next; 1811 } 1812 g_slist_free(list); 1813} 1814 1815void object_add_completion(ReadLineState *rs, int nb_args, const char *str) 1816{ 1817 GSList *list, *elt; 1818 size_t len; 1819 1820 if (nb_args != 2) { 1821 return; 1822 } 1823 1824 len = strlen(str); 1825 readline_set_completion_index(rs, len); 1826 list = elt = object_class_get_list(TYPE_USER_CREATABLE, false); 1827 while (elt) { 1828 const char *name; 1829 1830 name = object_class_get_name(OBJECT_CLASS(elt->data)); 1831 if (!strncmp(name, str, len) && strcmp(name, TYPE_USER_CREATABLE)) { 1832 readline_add_completion(rs, name); 1833 } 1834 elt = elt->next; 1835 } 1836 g_slist_free(list); 1837} 1838 1839static int qdev_add_hotpluggable_device(Object *obj, void *opaque) 1840{ 1841 GSList **list = opaque; 1842 DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj), 1843 TYPE_DEVICE); 1844 1845 if (dev == NULL) { 1846 return 0; 1847 } 1848 1849 if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) { 1850 *list = g_slist_append(*list, dev); 1851 } 1852 1853 return 0; 1854} 1855 1856static GSList *qdev_build_hotpluggable_device_list(Object *peripheral) 1857{ 1858 GSList *list = NULL; 1859 1860 object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list); 1861 1862 return list; 1863} 1864 1865static void peripheral_device_del_completion(ReadLineState *rs, 1866 const char *str, size_t len) 1867{ 1868 Object *peripheral = container_get(qdev_get_machine(), "/peripheral"); 1869 GSList *list, *item; 1870 1871 list = qdev_build_hotpluggable_device_list(peripheral); 1872 if (!list) { 1873 return; 1874 } 1875 1876 for (item = list; item; item = g_slist_next(item)) { 1877 DeviceState *dev = item->data; 1878 1879 if (dev->id && !strncmp(str, dev->id, len)) { 1880 readline_add_completion(rs, dev->id); 1881 } 1882 } 1883 1884 g_slist_free(list); 1885} 1886 1887void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) 1888{ 1889 size_t len; 1890 ChardevInfoList *list, *start; 1891 1892 if (nb_args != 2) { 1893 return; 1894 } 1895 len = strlen(str); 1896 readline_set_completion_index(rs, len); 1897 1898 start = list = qmp_query_chardev(NULL); 1899 while (list) { 1900 ChardevInfo *chr = list->value; 1901 1902 if (!strncmp(chr->label, str, len)) { 1903 readline_add_completion(rs, chr->label); 1904 } 1905 list = list->next; 1906 } 1907 qapi_free_ChardevInfoList(start); 1908} 1909 1910static void ringbuf_completion(ReadLineState *rs, const char *str) 1911{ 1912 size_t len; 1913 ChardevInfoList *list, *start; 1914 1915 len = strlen(str); 1916 readline_set_completion_index(rs, len); 1917 1918 start = list = qmp_query_chardev(NULL); 1919 while (list) { 1920 ChardevInfo *chr_info = list->value; 1921 1922 if (!strncmp(chr_info->label, str, len)) { 1923 Chardev *chr = qemu_chr_find(chr_info->label); 1924 if (chr && CHARDEV_IS_RINGBUF(chr)) { 1925 readline_add_completion(rs, chr_info->label); 1926 } 1927 } 1928 list = list->next; 1929 } 1930 qapi_free_ChardevInfoList(start); 1931} 1932 1933void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str) 1934{ 1935 if (nb_args != 2) { 1936 return; 1937 } 1938 ringbuf_completion(rs, str); 1939} 1940 1941void device_del_completion(ReadLineState *rs, int nb_args, const char *str) 1942{ 1943 size_t len; 1944 1945 if (nb_args != 2) { 1946 return; 1947 } 1948 1949 len = strlen(str); 1950 readline_set_completion_index(rs, len); 1951 peripheral_device_del_completion(rs, str, len); 1952} 1953 1954void object_del_completion(ReadLineState *rs, int nb_args, const char *str) 1955{ 1956 ObjectPropertyInfoList *list, *start; 1957 size_t len; 1958 1959 if (nb_args != 2) { 1960 return; 1961 } 1962 len = strlen(str); 1963 readline_set_completion_index(rs, len); 1964 1965 start = list = qmp_qom_list("/objects", NULL); 1966 while (list) { 1967 ObjectPropertyInfo *info = list->value; 1968 1969 if (!strncmp(info->type, "child<", 5) 1970 && !strncmp(info->name, str, len)) { 1971 readline_add_completion(rs, info->name); 1972 } 1973 list = list->next; 1974 } 1975 qapi_free_ObjectPropertyInfoList(start); 1976} 1977 1978void sendkey_completion(ReadLineState *rs, int nb_args, const char *str) 1979{ 1980 int i; 1981 char *sep; 1982 size_t len; 1983 1984 if (nb_args != 2) { 1985 return; 1986 } 1987 sep = strrchr(str, '-'); 1988 if (sep) { 1989 str = sep + 1; 1990 } 1991 len = strlen(str); 1992 readline_set_completion_index(rs, len); 1993 for (i = 0; i < Q_KEY_CODE__MAX; i++) { 1994 if (!strncmp(str, QKeyCode_str(i), len)) { 1995 readline_add_completion(rs, QKeyCode_str(i)); 1996 } 1997 } 1998} 1999 2000void set_link_completion(ReadLineState *rs, int nb_args, const char *str) 2001{ 2002 size_t len; 2003 2004 len = strlen(str); 2005 readline_set_completion_index(rs, len); 2006 if (nb_args == 2) { 2007 NetClientState *ncs[MAX_QUEUE_NUM]; 2008 int count, i; 2009 count = qemu_find_net_clients_except(NULL, ncs, 2010 NET_CLIENT_DRIVER_NONE, 2011 MAX_QUEUE_NUM); 2012 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { 2013 const char *name = ncs[i]->name; 2014 if (!strncmp(str, name, len)) { 2015 readline_add_completion(rs, name); 2016 } 2017 } 2018 } else if (nb_args == 3) { 2019 add_completion_option(rs, str, "on"); 2020 add_completion_option(rs, str, "off"); 2021 } 2022} 2023 2024void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) 2025{ 2026 int len, count, i; 2027 NetClientState *ncs[MAX_QUEUE_NUM]; 2028 2029 if (nb_args != 2) { 2030 return; 2031 } 2032 2033 len = strlen(str); 2034 readline_set_completion_index(rs, len); 2035 count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_DRIVER_NIC, 2036 MAX_QUEUE_NUM); 2037 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { 2038 const char *name = ncs[i]->name; 2039 if (strncmp(str, name, len)) { 2040 continue; 2041 } 2042 if (ncs[i]->is_netdev) { 2043 readline_add_completion(rs, name); 2044 } 2045 } 2046} 2047 2048void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str) 2049{ 2050 size_t len; 2051 2052 len = strlen(str); 2053 readline_set_completion_index(rs, len); 2054 if (nb_args == 2) { 2055 TraceEventIter iter; 2056 TraceEvent *ev; 2057 char *pattern = g_strdup_printf("%s*", str); 2058 trace_event_iter_init(&iter, pattern); 2059 while ((ev = trace_event_iter_next(&iter)) != NULL) { 2060 readline_add_completion(rs, trace_event_get_name(ev)); 2061 } 2062 g_free(pattern); 2063 } 2064} 2065 2066void trace_event_completion(ReadLineState *rs, int nb_args, const char *str) 2067{ 2068 size_t len; 2069 2070 len = strlen(str); 2071 readline_set_completion_index(rs, len); 2072 if (nb_args == 2) { 2073 TraceEventIter iter; 2074 TraceEvent *ev; 2075 char *pattern = g_strdup_printf("%s*", str); 2076 trace_event_iter_init(&iter, pattern); 2077 while ((ev = trace_event_iter_next(&iter)) != NULL) { 2078 readline_add_completion(rs, trace_event_get_name(ev)); 2079 } 2080 g_free(pattern); 2081 } else if (nb_args == 3) { 2082 add_completion_option(rs, str, "on"); 2083 add_completion_option(rs, str, "off"); 2084 } 2085} 2086 2087void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str) 2088{ 2089 int i; 2090 2091 if (nb_args != 2) { 2092 return; 2093 } 2094 readline_set_completion_index(rs, strlen(str)); 2095 for (i = 0; i < WATCHDOG_ACTION__MAX; i++) { 2096 add_completion_option(rs, str, WatchdogAction_str(i)); 2097 } 2098} 2099 2100void migrate_set_capability_completion(ReadLineState *rs, int nb_args, 2101 const char *str) 2102{ 2103 size_t len; 2104 2105 len = strlen(str); 2106 readline_set_completion_index(rs, len); 2107 if (nb_args == 2) { 2108 int i; 2109 for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { 2110 const char *name = MigrationCapability_str(i); 2111 if (!strncmp(str, name, len)) { 2112 readline_add_completion(rs, name); 2113 } 2114 } 2115 } else if (nb_args == 3) { 2116 add_completion_option(rs, str, "on"); 2117 add_completion_option(rs, str, "off"); 2118 } 2119} 2120 2121void migrate_set_parameter_completion(ReadLineState *rs, int nb_args, 2122 const char *str) 2123{ 2124 size_t len; 2125 2126 len = strlen(str); 2127 readline_set_completion_index(rs, len); 2128 if (nb_args == 2) { 2129 int i; 2130 for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) { 2131 const char *name = MigrationParameter_str(i); 2132 if (!strncmp(str, name, len)) { 2133 readline_add_completion(rs, name); 2134 } 2135 } 2136 } 2137} 2138 2139static void vm_completion(ReadLineState *rs, const char *str) 2140{ 2141 size_t len; 2142 BlockDriverState *bs; 2143 BdrvNextIterator it; 2144 2145 len = strlen(str); 2146 readline_set_completion_index(rs, len); 2147 2148 for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { 2149 SnapshotInfoList *snapshots, *snapshot; 2150 AioContext *ctx = bdrv_get_aio_context(bs); 2151 bool ok = false; 2152 2153 aio_context_acquire(ctx); 2154 if (bdrv_can_snapshot(bs)) { 2155 ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0; 2156 } 2157 aio_context_release(ctx); 2158 if (!ok) { 2159 continue; 2160 } 2161 2162 snapshot = snapshots; 2163 while (snapshot) { 2164 char *completion = snapshot->value->name; 2165 if (!strncmp(str, completion, len)) { 2166 readline_add_completion(rs, completion); 2167 } 2168 completion = snapshot->value->id; 2169 if (!strncmp(str, completion, len)) { 2170 readline_add_completion(rs, completion); 2171 } 2172 snapshot = snapshot->next; 2173 } 2174 qapi_free_SnapshotInfoList(snapshots); 2175 } 2176 2177} 2178 2179void delvm_completion(ReadLineState *rs, int nb_args, const char *str) 2180{ 2181 if (nb_args == 2) { 2182 vm_completion(rs, str); 2183 } 2184} 2185 2186void loadvm_completion(ReadLineState *rs, int nb_args, const char *str) 2187{ 2188 if (nb_args == 2) { 2189 vm_completion(rs, str); 2190 } 2191} 2192 2193static int 2194compare_mon_cmd(const void *a, const void *b) 2195{ 2196 return strcmp(((const HMPCommand *)a)->name, 2197 ((const HMPCommand *)b)->name); 2198} 2199 2200static void sortcmdlist(void) 2201{ 2202 qsort(hmp_cmds, ARRAY_SIZE(hmp_cmds) - 1, 2203 sizeof(*hmp_cmds), 2204 compare_mon_cmd); 2205 qsort(hmp_info_cmds, ARRAY_SIZE(hmp_info_cmds) - 1, 2206 sizeof(*hmp_info_cmds), 2207 compare_mon_cmd); 2208} 2209 2210void monitor_init_globals(void) 2211{ 2212 monitor_init_globals_core(); 2213 monitor_init_qmp_commands(); 2214 sortcmdlist(); 2215 qemu_mutex_init(&mon_fdsets_lock); 2216}