qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio
at master 2214 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 bool disabled = qdict_get_try_bool(qdict, "disabled", false); 961 962 mtree_info(flatview, dispatch_tree, owner, disabled); 963} 964 965#ifdef CONFIG_PROFILER 966 967int64_t dev_time; 968 969static void hmp_info_profile(Monitor *mon, const QDict *qdict) 970{ 971 static int64_t last_cpu_exec_time; 972 int64_t cpu_exec_time; 973 int64_t delta; 974 975 cpu_exec_time = tcg_cpu_exec_time(); 976 delta = cpu_exec_time - last_cpu_exec_time; 977 978 monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n", 979 dev_time, dev_time / (double)NANOSECONDS_PER_SECOND); 980 monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n", 981 delta, delta / (double)NANOSECONDS_PER_SECOND); 982 last_cpu_exec_time = cpu_exec_time; 983 dev_time = 0; 984} 985#else 986static void hmp_info_profile(Monitor *mon, const QDict *qdict) 987{ 988 monitor_printf(mon, "Internal profiler not compiled\n"); 989} 990#endif 991 992/* Capture support */ 993static QLIST_HEAD (capture_list_head, CaptureState) capture_head; 994 995static void hmp_info_capture(Monitor *mon, const QDict *qdict) 996{ 997 int i; 998 CaptureState *s; 999 1000 for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { 1001 monitor_printf(mon, "[%d]: ", i); 1002 s->ops.info (s->opaque); 1003 } 1004} 1005 1006static void hmp_stopcapture(Monitor *mon, const QDict *qdict) 1007{ 1008 int i; 1009 int n = qdict_get_int(qdict, "n"); 1010 CaptureState *s; 1011 1012 for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { 1013 if (i == n) { 1014 s->ops.destroy (s->opaque); 1015 QLIST_REMOVE (s, entries); 1016 g_free (s); 1017 return; 1018 } 1019 } 1020} 1021 1022static void hmp_wavcapture(Monitor *mon, const QDict *qdict) 1023{ 1024 const char *path = qdict_get_str(qdict, "path"); 1025 int freq = qdict_get_try_int(qdict, "freq", 44100); 1026 int bits = qdict_get_try_int(qdict, "bits", 16); 1027 int nchannels = qdict_get_try_int(qdict, "nchannels", 2); 1028 const char *audiodev = qdict_get_str(qdict, "audiodev"); 1029 CaptureState *s; 1030 AudioState *as = audio_state_by_name(audiodev); 1031 1032 if (!as) { 1033 monitor_printf(mon, "Audiodev '%s' not found\n", audiodev); 1034 return; 1035 } 1036 1037 s = g_malloc0 (sizeof (*s)); 1038 1039 if (wav_start_capture(as, s, path, freq, bits, nchannels)) { 1040 monitor_printf(mon, "Failed to add wave capture\n"); 1041 g_free (s); 1042 return; 1043 } 1044 QLIST_INSERT_HEAD (&capture_head, s, entries); 1045} 1046 1047static QAuthZList *find_auth(Monitor *mon, const char *name) 1048{ 1049 Object *obj; 1050 Object *container; 1051 1052 container = object_get_objects_root(); 1053 obj = object_resolve_path_component(container, name); 1054 if (!obj) { 1055 monitor_printf(mon, "acl: unknown list '%s'\n", name); 1056 return NULL; 1057 } 1058 1059 return QAUTHZ_LIST(obj); 1060} 1061 1062static bool warn_acl; 1063static void hmp_warn_acl(void) 1064{ 1065 if (warn_acl) { 1066 return; 1067 } 1068 error_report("The acl_show, acl_reset, acl_policy, acl_add, acl_remove " 1069 "commands are deprecated with no replacement. Authorization " 1070 "for VNC should be performed using the pluggable QAuthZ " 1071 "objects"); 1072 warn_acl = true; 1073} 1074 1075static void hmp_acl_show(Monitor *mon, const QDict *qdict) 1076{ 1077 const char *aclname = qdict_get_str(qdict, "aclname"); 1078 QAuthZList *auth = find_auth(mon, aclname); 1079 QAuthZListRuleList *rules; 1080 size_t i = 0; 1081 1082 hmp_warn_acl(); 1083 1084 if (!auth) { 1085 return; 1086 } 1087 1088 monitor_printf(mon, "policy: %s\n", 1089 QAuthZListPolicy_str(auth->policy)); 1090 1091 rules = auth->rules; 1092 while (rules) { 1093 QAuthZListRule *rule = rules->value; 1094 i++; 1095 monitor_printf(mon, "%zu: %s %s\n", i, 1096 QAuthZListPolicy_str(rule->policy), 1097 rule->match); 1098 rules = rules->next; 1099 } 1100} 1101 1102static void hmp_acl_reset(Monitor *mon, const QDict *qdict) 1103{ 1104 const char *aclname = qdict_get_str(qdict, "aclname"); 1105 QAuthZList *auth = find_auth(mon, aclname); 1106 1107 hmp_warn_acl(); 1108 1109 if (!auth) { 1110 return; 1111 } 1112 1113 auth->policy = QAUTHZ_LIST_POLICY_DENY; 1114 qapi_free_QAuthZListRuleList(auth->rules); 1115 auth->rules = NULL; 1116 monitor_printf(mon, "acl: removed all rules\n"); 1117} 1118 1119static void hmp_acl_policy(Monitor *mon, const QDict *qdict) 1120{ 1121 const char *aclname = qdict_get_str(qdict, "aclname"); 1122 const char *policy = qdict_get_str(qdict, "policy"); 1123 QAuthZList *auth = find_auth(mon, aclname); 1124 int val; 1125 Error *err = NULL; 1126 1127 hmp_warn_acl(); 1128 1129 if (!auth) { 1130 return; 1131 } 1132 1133 val = qapi_enum_parse(&QAuthZListPolicy_lookup, 1134 policy, 1135 QAUTHZ_LIST_POLICY_DENY, 1136 &err); 1137 if (err) { 1138 error_free(err); 1139 monitor_printf(mon, "acl: unknown policy '%s', " 1140 "expected 'deny' or 'allow'\n", policy); 1141 } else { 1142 auth->policy = val; 1143 if (auth->policy == QAUTHZ_LIST_POLICY_ALLOW) { 1144 monitor_printf(mon, "acl: policy set to 'allow'\n"); 1145 } else { 1146 monitor_printf(mon, "acl: policy set to 'deny'\n"); 1147 } 1148 } 1149} 1150 1151static QAuthZListFormat hmp_acl_get_format(const char *match) 1152{ 1153 if (strchr(match, '*')) { 1154 return QAUTHZ_LIST_FORMAT_GLOB; 1155 } else { 1156 return QAUTHZ_LIST_FORMAT_EXACT; 1157 } 1158} 1159 1160static void hmp_acl_add(Monitor *mon, const QDict *qdict) 1161{ 1162 const char *aclname = qdict_get_str(qdict, "aclname"); 1163 const char *match = qdict_get_str(qdict, "match"); 1164 const char *policystr = qdict_get_str(qdict, "policy"); 1165 int has_index = qdict_haskey(qdict, "index"); 1166 int index = qdict_get_try_int(qdict, "index", -1); 1167 QAuthZList *auth = find_auth(mon, aclname); 1168 Error *err = NULL; 1169 QAuthZListPolicy policy; 1170 QAuthZListFormat format; 1171 size_t i = 0; 1172 1173 hmp_warn_acl(); 1174 1175 if (!auth) { 1176 return; 1177 } 1178 1179 policy = qapi_enum_parse(&QAuthZListPolicy_lookup, 1180 policystr, 1181 QAUTHZ_LIST_POLICY_DENY, 1182 &err); 1183 if (err) { 1184 error_free(err); 1185 monitor_printf(mon, "acl: unknown policy '%s', " 1186 "expected 'deny' or 'allow'\n", policystr); 1187 return; 1188 } 1189 1190 format = hmp_acl_get_format(match); 1191 1192 if (has_index && index == 0) { 1193 monitor_printf(mon, "acl: unable to add acl entry\n"); 1194 return; 1195 } 1196 1197 if (has_index) { 1198 i = qauthz_list_insert_rule(auth, match, policy, 1199 format, index - 1, &err); 1200 } else { 1201 i = qauthz_list_append_rule(auth, match, policy, 1202 format, &err); 1203 } 1204 if (err) { 1205 monitor_printf(mon, "acl: unable to add rule: %s", 1206 error_get_pretty(err)); 1207 error_free(err); 1208 } else { 1209 monitor_printf(mon, "acl: added rule at position %zu\n", i + 1); 1210 } 1211} 1212 1213static void hmp_acl_remove(Monitor *mon, const QDict *qdict) 1214{ 1215 const char *aclname = qdict_get_str(qdict, "aclname"); 1216 const char *match = qdict_get_str(qdict, "match"); 1217 QAuthZList *auth = find_auth(mon, aclname); 1218 ssize_t i = 0; 1219 1220 hmp_warn_acl(); 1221 1222 if (!auth) { 1223 return; 1224 } 1225 1226 i = qauthz_list_delete_rule(auth, match); 1227 if (i >= 0) { 1228 monitor_printf(mon, "acl: removed rule at position %zu\n", i + 1); 1229 } else { 1230 monitor_printf(mon, "acl: no matching acl entry\n"); 1231 } 1232} 1233 1234void qmp_getfd(const char *fdname, Error **errp) 1235{ 1236 mon_fd_t *monfd; 1237 int fd, tmp_fd; 1238 1239 fd = qemu_chr_fe_get_msgfd(&cur_mon->chr); 1240 if (fd == -1) { 1241 error_setg(errp, QERR_FD_NOT_SUPPLIED); 1242 return; 1243 } 1244 1245 if (qemu_isdigit(fdname[0])) { 1246 close(fd); 1247 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdname", 1248 "a name not starting with a digit"); 1249 return; 1250 } 1251 1252 qemu_mutex_lock(&cur_mon->mon_lock); 1253 QLIST_FOREACH(monfd, &cur_mon->fds, next) { 1254 if (strcmp(monfd->name, fdname) != 0) { 1255 continue; 1256 } 1257 1258 tmp_fd = monfd->fd; 1259 monfd->fd = fd; 1260 qemu_mutex_unlock(&cur_mon->mon_lock); 1261 /* Make sure close() is outside critical section */ 1262 close(tmp_fd); 1263 return; 1264 } 1265 1266 monfd = g_malloc0(sizeof(mon_fd_t)); 1267 monfd->name = g_strdup(fdname); 1268 monfd->fd = fd; 1269 1270 QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next); 1271 qemu_mutex_unlock(&cur_mon->mon_lock); 1272} 1273 1274void qmp_closefd(const char *fdname, Error **errp) 1275{ 1276 mon_fd_t *monfd; 1277 int tmp_fd; 1278 1279 qemu_mutex_lock(&cur_mon->mon_lock); 1280 QLIST_FOREACH(monfd, &cur_mon->fds, next) { 1281 if (strcmp(monfd->name, fdname) != 0) { 1282 continue; 1283 } 1284 1285 QLIST_REMOVE(monfd, next); 1286 tmp_fd = monfd->fd; 1287 g_free(monfd->name); 1288 g_free(monfd); 1289 qemu_mutex_unlock(&cur_mon->mon_lock); 1290 /* Make sure close() is outside critical section */ 1291 close(tmp_fd); 1292 return; 1293 } 1294 1295 qemu_mutex_unlock(&cur_mon->mon_lock); 1296 error_setg(errp, QERR_FD_NOT_FOUND, fdname); 1297} 1298 1299int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp) 1300{ 1301 mon_fd_t *monfd; 1302 1303 qemu_mutex_lock(&mon->mon_lock); 1304 QLIST_FOREACH(monfd, &mon->fds, next) { 1305 int fd; 1306 1307 if (strcmp(monfd->name, fdname) != 0) { 1308 continue; 1309 } 1310 1311 fd = monfd->fd; 1312 1313 /* caller takes ownership of fd */ 1314 QLIST_REMOVE(monfd, next); 1315 g_free(monfd->name); 1316 g_free(monfd); 1317 qemu_mutex_unlock(&mon->mon_lock); 1318 1319 return fd; 1320 } 1321 1322 qemu_mutex_unlock(&mon->mon_lock); 1323 error_setg(errp, "File descriptor named '%s' has not been found", fdname); 1324 return -1; 1325} 1326 1327static void monitor_fdset_cleanup(MonFdset *mon_fdset) 1328{ 1329 MonFdsetFd *mon_fdset_fd; 1330 MonFdsetFd *mon_fdset_fd_next; 1331 1332 QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, mon_fdset_fd_next) { 1333 if ((mon_fdset_fd->removed || 1334 (QLIST_EMPTY(&mon_fdset->dup_fds) && mon_refcount == 0)) && 1335 runstate_is_running()) { 1336 close(mon_fdset_fd->fd); 1337 g_free(mon_fdset_fd->opaque); 1338 QLIST_REMOVE(mon_fdset_fd, next); 1339 g_free(mon_fdset_fd); 1340 } 1341 } 1342 1343 if (QLIST_EMPTY(&mon_fdset->fds) && QLIST_EMPTY(&mon_fdset->dup_fds)) { 1344 QLIST_REMOVE(mon_fdset, next); 1345 g_free(mon_fdset); 1346 } 1347} 1348 1349void monitor_fdsets_cleanup(void) 1350{ 1351 MonFdset *mon_fdset; 1352 MonFdset *mon_fdset_next; 1353 1354 qemu_mutex_lock(&mon_fdsets_lock); 1355 QLIST_FOREACH_SAFE(mon_fdset, &mon_fdsets, next, mon_fdset_next) { 1356 monitor_fdset_cleanup(mon_fdset); 1357 } 1358 qemu_mutex_unlock(&mon_fdsets_lock); 1359} 1360 1361AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, 1362 const char *opaque, Error **errp) 1363{ 1364 int fd; 1365 Monitor *mon = cur_mon; 1366 AddfdInfo *fdinfo; 1367 1368 fd = qemu_chr_fe_get_msgfd(&mon->chr); 1369 if (fd == -1) { 1370 error_setg(errp, QERR_FD_NOT_SUPPLIED); 1371 goto error; 1372 } 1373 1374 fdinfo = monitor_fdset_add_fd(fd, has_fdset_id, fdset_id, 1375 has_opaque, opaque, errp); 1376 if (fdinfo) { 1377 return fdinfo; 1378 } 1379 1380error: 1381 if (fd != -1) { 1382 close(fd); 1383 } 1384 return NULL; 1385} 1386 1387void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp) 1388{ 1389 MonFdset *mon_fdset; 1390 MonFdsetFd *mon_fdset_fd; 1391 char fd_str[60]; 1392 1393 qemu_mutex_lock(&mon_fdsets_lock); 1394 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1395 if (mon_fdset->id != fdset_id) { 1396 continue; 1397 } 1398 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { 1399 if (has_fd) { 1400 if (mon_fdset_fd->fd != fd) { 1401 continue; 1402 } 1403 mon_fdset_fd->removed = true; 1404 break; 1405 } else { 1406 mon_fdset_fd->removed = true; 1407 } 1408 } 1409 if (has_fd && !mon_fdset_fd) { 1410 goto error; 1411 } 1412 monitor_fdset_cleanup(mon_fdset); 1413 qemu_mutex_unlock(&mon_fdsets_lock); 1414 return; 1415 } 1416 1417error: 1418 qemu_mutex_unlock(&mon_fdsets_lock); 1419 if (has_fd) { 1420 snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64 ", fd:%" PRId64, 1421 fdset_id, fd); 1422 } else { 1423 snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64, fdset_id); 1424 } 1425 error_setg(errp, QERR_FD_NOT_FOUND, fd_str); 1426} 1427 1428FdsetInfoList *qmp_query_fdsets(Error **errp) 1429{ 1430 MonFdset *mon_fdset; 1431 MonFdsetFd *mon_fdset_fd; 1432 FdsetInfoList *fdset_list = NULL; 1433 1434 qemu_mutex_lock(&mon_fdsets_lock); 1435 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1436 FdsetInfoList *fdset_info = g_malloc0(sizeof(*fdset_info)); 1437 FdsetFdInfoList *fdsetfd_list = NULL; 1438 1439 fdset_info->value = g_malloc0(sizeof(*fdset_info->value)); 1440 fdset_info->value->fdset_id = mon_fdset->id; 1441 1442 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { 1443 FdsetFdInfoList *fdsetfd_info; 1444 1445 fdsetfd_info = g_malloc0(sizeof(*fdsetfd_info)); 1446 fdsetfd_info->value = g_malloc0(sizeof(*fdsetfd_info->value)); 1447 fdsetfd_info->value->fd = mon_fdset_fd->fd; 1448 if (mon_fdset_fd->opaque) { 1449 fdsetfd_info->value->has_opaque = true; 1450 fdsetfd_info->value->opaque = g_strdup(mon_fdset_fd->opaque); 1451 } else { 1452 fdsetfd_info->value->has_opaque = false; 1453 } 1454 1455 fdsetfd_info->next = fdsetfd_list; 1456 fdsetfd_list = fdsetfd_info; 1457 } 1458 1459 fdset_info->value->fds = fdsetfd_list; 1460 1461 fdset_info->next = fdset_list; 1462 fdset_list = fdset_info; 1463 } 1464 qemu_mutex_unlock(&mon_fdsets_lock); 1465 1466 return fdset_list; 1467} 1468 1469AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id, 1470 bool has_opaque, const char *opaque, 1471 Error **errp) 1472{ 1473 MonFdset *mon_fdset = NULL; 1474 MonFdsetFd *mon_fdset_fd; 1475 AddfdInfo *fdinfo; 1476 1477 QEMU_LOCK_GUARD(&mon_fdsets_lock); 1478 if (has_fdset_id) { 1479 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1480 /* Break if match found or match impossible due to ordering by ID */ 1481 if (fdset_id <= mon_fdset->id) { 1482 if (fdset_id < mon_fdset->id) { 1483 mon_fdset = NULL; 1484 } 1485 break; 1486 } 1487 } 1488 } 1489 1490 if (mon_fdset == NULL) { 1491 int64_t fdset_id_prev = -1; 1492 MonFdset *mon_fdset_cur = QLIST_FIRST(&mon_fdsets); 1493 1494 if (has_fdset_id) { 1495 if (fdset_id < 0) { 1496 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id", 1497 "a non-negative value"); 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 return fdinfo; 1549} 1550 1551int monitor_fdset_get_fd(int64_t fdset_id, int flags) 1552{ 1553#ifdef _WIN32 1554 return -ENOENT; 1555#else 1556 MonFdset *mon_fdset; 1557 MonFdsetFd *mon_fdset_fd; 1558 int mon_fd_flags; 1559 int ret; 1560 1561 qemu_mutex_lock(&mon_fdsets_lock); 1562 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1563 if (mon_fdset->id != fdset_id) { 1564 continue; 1565 } 1566 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { 1567 mon_fd_flags = fcntl(mon_fdset_fd->fd, F_GETFL); 1568 if (mon_fd_flags == -1) { 1569 ret = -errno; 1570 goto out; 1571 } 1572 1573 if ((flags & O_ACCMODE) == (mon_fd_flags & O_ACCMODE)) { 1574 ret = mon_fdset_fd->fd; 1575 goto out; 1576 } 1577 } 1578 ret = -EACCES; 1579 goto out; 1580 } 1581 ret = -ENOENT; 1582 1583out: 1584 qemu_mutex_unlock(&mon_fdsets_lock); 1585 return ret; 1586#endif 1587} 1588 1589int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd) 1590{ 1591 MonFdset *mon_fdset; 1592 MonFdsetFd *mon_fdset_fd_dup; 1593 1594 qemu_mutex_lock(&mon_fdsets_lock); 1595 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1596 if (mon_fdset->id != fdset_id) { 1597 continue; 1598 } 1599 QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) { 1600 if (mon_fdset_fd_dup->fd == dup_fd) { 1601 goto err; 1602 } 1603 } 1604 mon_fdset_fd_dup = g_malloc0(sizeof(*mon_fdset_fd_dup)); 1605 mon_fdset_fd_dup->fd = dup_fd; 1606 QLIST_INSERT_HEAD(&mon_fdset->dup_fds, mon_fdset_fd_dup, next); 1607 qemu_mutex_unlock(&mon_fdsets_lock); 1608 return 0; 1609 } 1610 1611err: 1612 qemu_mutex_unlock(&mon_fdsets_lock); 1613 return -1; 1614} 1615 1616static int64_t monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove) 1617{ 1618 MonFdset *mon_fdset; 1619 MonFdsetFd *mon_fdset_fd_dup; 1620 1621 qemu_mutex_lock(&mon_fdsets_lock); 1622 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { 1623 QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) { 1624 if (mon_fdset_fd_dup->fd == dup_fd) { 1625 if (remove) { 1626 QLIST_REMOVE(mon_fdset_fd_dup, next); 1627 g_free(mon_fdset_fd_dup); 1628 if (QLIST_EMPTY(&mon_fdset->dup_fds)) { 1629 monitor_fdset_cleanup(mon_fdset); 1630 } 1631 goto err; 1632 } else { 1633 qemu_mutex_unlock(&mon_fdsets_lock); 1634 return mon_fdset->id; 1635 } 1636 } 1637 } 1638 } 1639 1640err: 1641 qemu_mutex_unlock(&mon_fdsets_lock); 1642 return -1; 1643} 1644 1645int64_t monitor_fdset_dup_fd_find(int dup_fd) 1646{ 1647 return monitor_fdset_dup_fd_find_remove(dup_fd, false); 1648} 1649 1650void monitor_fdset_dup_fd_remove(int dup_fd) 1651{ 1652 monitor_fdset_dup_fd_find_remove(dup_fd, true); 1653} 1654 1655int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp) 1656{ 1657 int fd; 1658 Error *local_err = NULL; 1659 1660 if (!qemu_isdigit(fdname[0]) && mon) { 1661 fd = monitor_get_fd(mon, fdname, &local_err); 1662 } else { 1663 fd = qemu_parse_fd(fdname); 1664 if (fd == -1) { 1665 error_setg(&local_err, "Invalid file descriptor number '%s'", 1666 fdname); 1667 } 1668 } 1669 if (local_err) { 1670 error_propagate(errp, local_err); 1671 assert(fd == -1); 1672 } else { 1673 assert(fd != -1); 1674 } 1675 1676 return fd; 1677} 1678 1679/* Please update hmp-commands.hx when adding or changing commands */ 1680static HMPCommand hmp_info_cmds[] = { 1681#include "hmp-commands-info.h" 1682 { NULL, NULL, }, 1683}; 1684 1685/* hmp_cmds and hmp_info_cmds would be sorted at runtime */ 1686HMPCommand hmp_cmds[] = { 1687#include "hmp-commands.h" 1688 { NULL, NULL, }, 1689}; 1690 1691/* 1692 * Set @pval to the value in the register identified by @name. 1693 * return 0 if OK, -1 if not found 1694 */ 1695int get_monitor_def(int64_t *pval, const char *name) 1696{ 1697 const MonitorDef *md = target_monitor_defs(); 1698 CPUState *cs = mon_get_cpu(); 1699 void *ptr; 1700 uint64_t tmp = 0; 1701 int ret; 1702 1703 if (cs == NULL || md == NULL) { 1704 return -1; 1705 } 1706 1707 for(; md->name != NULL; md++) { 1708 if (hmp_compare_cmd(name, md->name)) { 1709 if (md->get_value) { 1710 *pval = md->get_value(md, md->offset); 1711 } else { 1712 CPUArchState *env = mon_get_cpu_env(); 1713 ptr = (uint8_t *)env + md->offset; 1714 switch(md->type) { 1715 case MD_I32: 1716 *pval = *(int32_t *)ptr; 1717 break; 1718 case MD_TLONG: 1719 *pval = *(target_long *)ptr; 1720 break; 1721 default: 1722 *pval = 0; 1723 break; 1724 } 1725 } 1726 return 0; 1727 } 1728 } 1729 1730 ret = target_get_monitor_def(cs, name, &tmp); 1731 if (!ret) { 1732 *pval = (target_long) tmp; 1733 } 1734 1735 return ret; 1736} 1737 1738static void add_completion_option(ReadLineState *rs, const char *str, 1739 const char *option) 1740{ 1741 if (!str || !option) { 1742 return; 1743 } 1744 if (!strncmp(option, str, strlen(str))) { 1745 readline_add_completion(rs, option); 1746 } 1747} 1748 1749void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str) 1750{ 1751 size_t len; 1752 ChardevBackendInfoList *list, *start; 1753 1754 if (nb_args != 2) { 1755 return; 1756 } 1757 len = strlen(str); 1758 readline_set_completion_index(rs, len); 1759 1760 start = list = qmp_query_chardev_backends(NULL); 1761 while (list) { 1762 const char *chr_name = list->value->name; 1763 1764 if (!strncmp(chr_name, str, len)) { 1765 readline_add_completion(rs, chr_name); 1766 } 1767 list = list->next; 1768 } 1769 qapi_free_ChardevBackendInfoList(start); 1770} 1771 1772void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str) 1773{ 1774 size_t len; 1775 int i; 1776 1777 if (nb_args != 2) { 1778 return; 1779 } 1780 len = strlen(str); 1781 readline_set_completion_index(rs, len); 1782 for (i = 0; i < NET_CLIENT_DRIVER__MAX; i++) { 1783 add_completion_option(rs, str, NetClientDriver_str(i)); 1784 } 1785} 1786 1787void device_add_completion(ReadLineState *rs, int nb_args, const char *str) 1788{ 1789 GSList *list, *elt; 1790 size_t len; 1791 1792 if (nb_args != 2) { 1793 return; 1794 } 1795 1796 len = strlen(str); 1797 readline_set_completion_index(rs, len); 1798 list = elt = object_class_get_list(TYPE_DEVICE, false); 1799 while (elt) { 1800 const char *name; 1801 DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data, 1802 TYPE_DEVICE); 1803 name = object_class_get_name(OBJECT_CLASS(dc)); 1804 1805 if (dc->user_creatable 1806 && !strncmp(name, str, len)) { 1807 readline_add_completion(rs, name); 1808 } 1809 elt = elt->next; 1810 } 1811 g_slist_free(list); 1812} 1813 1814void object_add_completion(ReadLineState *rs, int nb_args, const char *str) 1815{ 1816 GSList *list, *elt; 1817 size_t len; 1818 1819 if (nb_args != 2) { 1820 return; 1821 } 1822 1823 len = strlen(str); 1824 readline_set_completion_index(rs, len); 1825 list = elt = object_class_get_list(TYPE_USER_CREATABLE, false); 1826 while (elt) { 1827 const char *name; 1828 1829 name = object_class_get_name(OBJECT_CLASS(elt->data)); 1830 if (!strncmp(name, str, len) && strcmp(name, TYPE_USER_CREATABLE)) { 1831 readline_add_completion(rs, name); 1832 } 1833 elt = elt->next; 1834 } 1835 g_slist_free(list); 1836} 1837 1838static int qdev_add_hotpluggable_device(Object *obj, void *opaque) 1839{ 1840 GSList **list = opaque; 1841 DeviceState *dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE); 1842 1843 if (dev == NULL) { 1844 return 0; 1845 } 1846 1847 if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) { 1848 *list = g_slist_append(*list, dev); 1849 } 1850 1851 return 0; 1852} 1853 1854static GSList *qdev_build_hotpluggable_device_list(Object *peripheral) 1855{ 1856 GSList *list = NULL; 1857 1858 object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list); 1859 1860 return list; 1861} 1862 1863static void peripheral_device_del_completion(ReadLineState *rs, 1864 const char *str, size_t len) 1865{ 1866 Object *peripheral = container_get(qdev_get_machine(), "/peripheral"); 1867 GSList *list, *item; 1868 1869 list = qdev_build_hotpluggable_device_list(peripheral); 1870 if (!list) { 1871 return; 1872 } 1873 1874 for (item = list; item; item = g_slist_next(item)) { 1875 DeviceState *dev = item->data; 1876 1877 if (dev->id && !strncmp(str, dev->id, len)) { 1878 readline_add_completion(rs, dev->id); 1879 } 1880 } 1881 1882 g_slist_free(list); 1883} 1884 1885void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) 1886{ 1887 size_t len; 1888 ChardevInfoList *list, *start; 1889 1890 if (nb_args != 2) { 1891 return; 1892 } 1893 len = strlen(str); 1894 readline_set_completion_index(rs, len); 1895 1896 start = list = qmp_query_chardev(NULL); 1897 while (list) { 1898 ChardevInfo *chr = list->value; 1899 1900 if (!strncmp(chr->label, str, len)) { 1901 readline_add_completion(rs, chr->label); 1902 } 1903 list = list->next; 1904 } 1905 qapi_free_ChardevInfoList(start); 1906} 1907 1908static void ringbuf_completion(ReadLineState *rs, const char *str) 1909{ 1910 size_t len; 1911 ChardevInfoList *list, *start; 1912 1913 len = strlen(str); 1914 readline_set_completion_index(rs, len); 1915 1916 start = list = qmp_query_chardev(NULL); 1917 while (list) { 1918 ChardevInfo *chr_info = list->value; 1919 1920 if (!strncmp(chr_info->label, str, len)) { 1921 Chardev *chr = qemu_chr_find(chr_info->label); 1922 if (chr && CHARDEV_IS_RINGBUF(chr)) { 1923 readline_add_completion(rs, chr_info->label); 1924 } 1925 } 1926 list = list->next; 1927 } 1928 qapi_free_ChardevInfoList(start); 1929} 1930 1931void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str) 1932{ 1933 if (nb_args != 2) { 1934 return; 1935 } 1936 ringbuf_completion(rs, str); 1937} 1938 1939void device_del_completion(ReadLineState *rs, int nb_args, const char *str) 1940{ 1941 size_t len; 1942 1943 if (nb_args != 2) { 1944 return; 1945 } 1946 1947 len = strlen(str); 1948 readline_set_completion_index(rs, len); 1949 peripheral_device_del_completion(rs, str, len); 1950} 1951 1952void object_del_completion(ReadLineState *rs, int nb_args, const char *str) 1953{ 1954 ObjectPropertyInfoList *list, *start; 1955 size_t len; 1956 1957 if (nb_args != 2) { 1958 return; 1959 } 1960 len = strlen(str); 1961 readline_set_completion_index(rs, len); 1962 1963 start = list = qmp_qom_list("/objects", NULL); 1964 while (list) { 1965 ObjectPropertyInfo *info = list->value; 1966 1967 if (!strncmp(info->type, "child<", 5) 1968 && !strncmp(info->name, str, len)) { 1969 readline_add_completion(rs, info->name); 1970 } 1971 list = list->next; 1972 } 1973 qapi_free_ObjectPropertyInfoList(start); 1974} 1975 1976void sendkey_completion(ReadLineState *rs, int nb_args, const char *str) 1977{ 1978 int i; 1979 char *sep; 1980 size_t len; 1981 1982 if (nb_args != 2) { 1983 return; 1984 } 1985 sep = strrchr(str, '-'); 1986 if (sep) { 1987 str = sep + 1; 1988 } 1989 len = strlen(str); 1990 readline_set_completion_index(rs, len); 1991 for (i = 0; i < Q_KEY_CODE__MAX; i++) { 1992 if (!strncmp(str, QKeyCode_str(i), len)) { 1993 readline_add_completion(rs, QKeyCode_str(i)); 1994 } 1995 } 1996} 1997 1998void set_link_completion(ReadLineState *rs, int nb_args, const char *str) 1999{ 2000 size_t len; 2001 2002 len = strlen(str); 2003 readline_set_completion_index(rs, len); 2004 if (nb_args == 2) { 2005 NetClientState *ncs[MAX_QUEUE_NUM]; 2006 int count, i; 2007 count = qemu_find_net_clients_except(NULL, ncs, 2008 NET_CLIENT_DRIVER_NONE, 2009 MAX_QUEUE_NUM); 2010 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { 2011 const char *name = ncs[i]->name; 2012 if (!strncmp(str, name, len)) { 2013 readline_add_completion(rs, name); 2014 } 2015 } 2016 } else if (nb_args == 3) { 2017 add_completion_option(rs, str, "on"); 2018 add_completion_option(rs, str, "off"); 2019 } 2020} 2021 2022void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) 2023{ 2024 int len, count, i; 2025 NetClientState *ncs[MAX_QUEUE_NUM]; 2026 2027 if (nb_args != 2) { 2028 return; 2029 } 2030 2031 len = strlen(str); 2032 readline_set_completion_index(rs, len); 2033 count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_DRIVER_NIC, 2034 MAX_QUEUE_NUM); 2035 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { 2036 const char *name = ncs[i]->name; 2037 if (strncmp(str, name, len)) { 2038 continue; 2039 } 2040 if (ncs[i]->is_netdev) { 2041 readline_add_completion(rs, name); 2042 } 2043 } 2044} 2045 2046void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str) 2047{ 2048 size_t len; 2049 2050 len = strlen(str); 2051 readline_set_completion_index(rs, len); 2052 if (nb_args == 2) { 2053 TraceEventIter iter; 2054 TraceEvent *ev; 2055 char *pattern = g_strdup_printf("%s*", str); 2056 trace_event_iter_init(&iter, pattern); 2057 while ((ev = trace_event_iter_next(&iter)) != NULL) { 2058 readline_add_completion(rs, trace_event_get_name(ev)); 2059 } 2060 g_free(pattern); 2061 } 2062} 2063 2064void trace_event_completion(ReadLineState *rs, int nb_args, const char *str) 2065{ 2066 size_t len; 2067 2068 len = strlen(str); 2069 readline_set_completion_index(rs, len); 2070 if (nb_args == 2) { 2071 TraceEventIter iter; 2072 TraceEvent *ev; 2073 char *pattern = g_strdup_printf("%s*", str); 2074 trace_event_iter_init(&iter, pattern); 2075 while ((ev = trace_event_iter_next(&iter)) != NULL) { 2076 readline_add_completion(rs, trace_event_get_name(ev)); 2077 } 2078 g_free(pattern); 2079 } else if (nb_args == 3) { 2080 add_completion_option(rs, str, "on"); 2081 add_completion_option(rs, str, "off"); 2082 } 2083} 2084 2085void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str) 2086{ 2087 int i; 2088 2089 if (nb_args != 2) { 2090 return; 2091 } 2092 readline_set_completion_index(rs, strlen(str)); 2093 for (i = 0; i < WATCHDOG_ACTION__MAX; i++) { 2094 add_completion_option(rs, str, WatchdogAction_str(i)); 2095 } 2096} 2097 2098void migrate_set_capability_completion(ReadLineState *rs, int nb_args, 2099 const char *str) 2100{ 2101 size_t len; 2102 2103 len = strlen(str); 2104 readline_set_completion_index(rs, len); 2105 if (nb_args == 2) { 2106 int i; 2107 for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { 2108 const char *name = MigrationCapability_str(i); 2109 if (!strncmp(str, name, len)) { 2110 readline_add_completion(rs, name); 2111 } 2112 } 2113 } else if (nb_args == 3) { 2114 add_completion_option(rs, str, "on"); 2115 add_completion_option(rs, str, "off"); 2116 } 2117} 2118 2119void migrate_set_parameter_completion(ReadLineState *rs, int nb_args, 2120 const char *str) 2121{ 2122 size_t len; 2123 2124 len = strlen(str); 2125 readline_set_completion_index(rs, len); 2126 if (nb_args == 2) { 2127 int i; 2128 for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) { 2129 const char *name = MigrationParameter_str(i); 2130 if (!strncmp(str, name, len)) { 2131 readline_add_completion(rs, name); 2132 } 2133 } 2134 } 2135} 2136 2137static void vm_completion(ReadLineState *rs, const char *str) 2138{ 2139 size_t len; 2140 BlockDriverState *bs; 2141 BdrvNextIterator it; 2142 2143 len = strlen(str); 2144 readline_set_completion_index(rs, len); 2145 2146 for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { 2147 SnapshotInfoList *snapshots, *snapshot; 2148 AioContext *ctx = bdrv_get_aio_context(bs); 2149 bool ok = false; 2150 2151 aio_context_acquire(ctx); 2152 if (bdrv_can_snapshot(bs)) { 2153 ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0; 2154 } 2155 aio_context_release(ctx); 2156 if (!ok) { 2157 continue; 2158 } 2159 2160 snapshot = snapshots; 2161 while (snapshot) { 2162 char *completion = snapshot->value->name; 2163 if (!strncmp(str, completion, len)) { 2164 readline_add_completion(rs, completion); 2165 } 2166 completion = snapshot->value->id; 2167 if (!strncmp(str, completion, len)) { 2168 readline_add_completion(rs, completion); 2169 } 2170 snapshot = snapshot->next; 2171 } 2172 qapi_free_SnapshotInfoList(snapshots); 2173 } 2174 2175} 2176 2177void delvm_completion(ReadLineState *rs, int nb_args, const char *str) 2178{ 2179 if (nb_args == 2) { 2180 vm_completion(rs, str); 2181 } 2182} 2183 2184void loadvm_completion(ReadLineState *rs, int nb_args, const char *str) 2185{ 2186 if (nb_args == 2) { 2187 vm_completion(rs, str); 2188 } 2189} 2190 2191static int 2192compare_mon_cmd(const void *a, const void *b) 2193{ 2194 return strcmp(((const HMPCommand *)a)->name, 2195 ((const HMPCommand *)b)->name); 2196} 2197 2198static void sortcmdlist(void) 2199{ 2200 qsort(hmp_cmds, ARRAY_SIZE(hmp_cmds) - 1, 2201 sizeof(*hmp_cmds), 2202 compare_mon_cmd); 2203 qsort(hmp_info_cmds, ARRAY_SIZE(hmp_info_cmds) - 1, 2204 sizeof(*hmp_info_cmds), 2205 compare_mon_cmd); 2206} 2207 2208void monitor_init_globals(void) 2209{ 2210 monitor_init_globals_core(); 2211 monitor_init_qmp_commands(); 2212 sortcmdlist(); 2213 qemu_mutex_init(&mon_fdsets_lock); 2214}