1 /* 2 * Human Monitor Interface commands 3 * 4 * Copyright IBM, Corp. 2011 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. See 10 * the COPYING file in the top-level directory. 11 * 12 * Contributions after 2012-01-13 are licensed under the terms of the 13 * GNU GPL, version 2 or (at your option) any later version. 14 */ 15 16 #include "qemu/osdep.h" 17 #include "monitor/hmp.h" 18 #include "net/net.h" 19 #include "net/eth.h" 20 #include "chardev/char.h" 21 #include "sysemu/block-backend.h" 22 #include "sysemu/runstate.h" 23 #include "qemu/config-file.h" 24 #include "qemu/option.h" 25 #include "qemu/timer.h" 26 #include "qemu/sockets.h" 27 #include "monitor/monitor-internal.h" 28 #include "qapi/error.h" 29 #include "qapi/clone-visitor.h" 30 #include "qapi/opts-visitor.h" 31 #include "qapi/qapi-builtin-visit.h" 32 #include "qapi/qapi-commands-block.h" 33 #include "qapi/qapi-commands-char.h" 34 #include "qapi/qapi-commands-migration.h" 35 #include "qapi/qapi-commands-misc.h" 36 #include "qapi/qapi-commands-net.h" 37 #include "qapi/qapi-commands-rocker.h" 38 #include "qapi/qapi-commands-run-state.h" 39 #include "qapi/qapi-commands-tpm.h" 40 #include "qapi/qapi-commands-ui.h" 41 #include "qapi/qapi-visit-net.h" 42 #include "qapi/qmp/qdict.h" 43 #include "qapi/qmp/qerror.h" 44 #include "qapi/string-input-visitor.h" 45 #include "qapi/string-output-visitor.h" 46 #include "qom/object_interfaces.h" 47 #include "ui/console.h" 48 #include "block/nbd.h" 49 #include "block/qapi.h" 50 #include "qemu-io.h" 51 #include "qemu/cutils.h" 52 #include "qemu/error-report.h" 53 #include "exec/ramlist.h" 54 #include "hw/intc/intc.h" 55 #include "hw/rdma/rdma.h" 56 #include "migration/snapshot.h" 57 #include "migration/misc.h" 58 59 #ifdef CONFIG_SPICE 60 #include <spice/enums.h> 61 #endif 62 63 void hmp_handle_error(Monitor *mon, Error *err) 64 { 65 if (err) { 66 error_reportf_err(err, "Error: "); 67 } 68 } 69 70 /* 71 * Produce a strList from a comma separated list. 72 * A NULL or empty input string return NULL. 73 */ 74 static strList *strList_from_comma_list(const char *in) 75 { 76 strList *res = NULL; 77 strList **hook = &res; 78 79 while (in && in[0]) { 80 char *comma = strchr(in, ','); 81 *hook = g_new0(strList, 1); 82 83 if (comma) { 84 (*hook)->value = g_strndup(in, comma - in); 85 in = comma + 1; /* skip the , */ 86 } else { 87 (*hook)->value = g_strdup(in); 88 in = NULL; 89 } 90 hook = &(*hook)->next; 91 } 92 93 return res; 94 } 95 96 void hmp_info_name(Monitor *mon, const QDict *qdict) 97 { 98 NameInfo *info; 99 100 info = qmp_query_name(NULL); 101 if (info->has_name) { 102 monitor_printf(mon, "%s\n", info->name); 103 } 104 qapi_free_NameInfo(info); 105 } 106 107 void hmp_info_version(Monitor *mon, const QDict *qdict) 108 { 109 VersionInfo *info; 110 111 info = qmp_query_version(NULL); 112 113 monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n", 114 info->qemu->major, info->qemu->minor, info->qemu->micro, 115 info->package); 116 117 qapi_free_VersionInfo(info); 118 } 119 120 void hmp_info_kvm(Monitor *mon, const QDict *qdict) 121 { 122 KvmInfo *info; 123 124 info = qmp_query_kvm(NULL); 125 monitor_printf(mon, "kvm support: "); 126 if (info->present) { 127 monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled"); 128 } else { 129 monitor_printf(mon, "not compiled\n"); 130 } 131 132 qapi_free_KvmInfo(info); 133 } 134 135 void hmp_info_status(Monitor *mon, const QDict *qdict) 136 { 137 StatusInfo *info; 138 139 info = qmp_query_status(NULL); 140 141 monitor_printf(mon, "VM status: %s%s", 142 info->running ? "running" : "paused", 143 info->singlestep ? " (single step mode)" : ""); 144 145 if (!info->running && info->status != RUN_STATE_PAUSED) { 146 monitor_printf(mon, " (%s)", RunState_str(info->status)); 147 } 148 149 monitor_printf(mon, "\n"); 150 151 qapi_free_StatusInfo(info); 152 } 153 154 void hmp_info_uuid(Monitor *mon, const QDict *qdict) 155 { 156 UuidInfo *info; 157 158 info = qmp_query_uuid(NULL); 159 monitor_printf(mon, "%s\n", info->UUID); 160 qapi_free_UuidInfo(info); 161 } 162 163 void hmp_info_chardev(Monitor *mon, const QDict *qdict) 164 { 165 ChardevInfoList *char_info, *info; 166 167 char_info = qmp_query_chardev(NULL); 168 for (info = char_info; info; info = info->next) { 169 monitor_printf(mon, "%s: filename=%s\n", info->value->label, 170 info->value->filename); 171 } 172 173 qapi_free_ChardevInfoList(char_info); 174 } 175 176 void hmp_info_mice(Monitor *mon, const QDict *qdict) 177 { 178 MouseInfoList *mice_list, *mouse; 179 180 mice_list = qmp_query_mice(NULL); 181 if (!mice_list) { 182 monitor_printf(mon, "No mouse devices connected\n"); 183 return; 184 } 185 186 for (mouse = mice_list; mouse; mouse = mouse->next) { 187 monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n", 188 mouse->value->current ? '*' : ' ', 189 mouse->value->index, mouse->value->name, 190 mouse->value->absolute ? " (absolute)" : ""); 191 } 192 193 qapi_free_MouseInfoList(mice_list); 194 } 195 196 static char *SocketAddress_to_str(SocketAddress *addr) 197 { 198 switch (addr->type) { 199 case SOCKET_ADDRESS_TYPE_INET: 200 return g_strdup_printf("tcp:%s:%s", 201 addr->u.inet.host, 202 addr->u.inet.port); 203 case SOCKET_ADDRESS_TYPE_UNIX: 204 return g_strdup_printf("unix:%s", 205 addr->u.q_unix.path); 206 case SOCKET_ADDRESS_TYPE_FD: 207 return g_strdup_printf("fd:%s", addr->u.fd.str); 208 case SOCKET_ADDRESS_TYPE_VSOCK: 209 return g_strdup_printf("tcp:%s:%s", 210 addr->u.vsock.cid, 211 addr->u.vsock.port); 212 default: 213 return g_strdup("unknown address type"); 214 } 215 } 216 217 void hmp_info_migrate(Monitor *mon, const QDict *qdict) 218 { 219 MigrationInfo *info; 220 221 info = qmp_query_migrate(NULL); 222 223 migration_global_dump(mon); 224 225 if (info->has_status) { 226 monitor_printf(mon, "Migration status: %s", 227 MigrationStatus_str(info->status)); 228 if (info->status == MIGRATION_STATUS_FAILED && 229 info->has_error_desc) { 230 monitor_printf(mon, " (%s)\n", info->error_desc); 231 } else { 232 monitor_printf(mon, "\n"); 233 } 234 235 monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n", 236 info->total_time); 237 if (info->has_expected_downtime) { 238 monitor_printf(mon, "expected downtime: %" PRIu64 " milliseconds\n", 239 info->expected_downtime); 240 } 241 if (info->has_downtime) { 242 monitor_printf(mon, "downtime: %" PRIu64 " milliseconds\n", 243 info->downtime); 244 } 245 if (info->has_setup_time) { 246 monitor_printf(mon, "setup: %" PRIu64 " milliseconds\n", 247 info->setup_time); 248 } 249 } 250 251 if (info->has_ram) { 252 monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", 253 info->ram->transferred >> 10); 254 monitor_printf(mon, "throughput: %0.2f mbps\n", 255 info->ram->mbps); 256 monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", 257 info->ram->remaining >> 10); 258 monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", 259 info->ram->total >> 10); 260 monitor_printf(mon, "duplicate: %" PRIu64 " pages\n", 261 info->ram->duplicate); 262 monitor_printf(mon, "skipped: %" PRIu64 " pages\n", 263 info->ram->skipped); 264 monitor_printf(mon, "normal: %" PRIu64 " pages\n", 265 info->ram->normal); 266 monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n", 267 info->ram->normal_bytes >> 10); 268 monitor_printf(mon, "dirty sync count: %" PRIu64 "\n", 269 info->ram->dirty_sync_count); 270 monitor_printf(mon, "page size: %" PRIu64 " kbytes\n", 271 info->ram->page_size >> 10); 272 monitor_printf(mon, "multifd bytes: %" PRIu64 " kbytes\n", 273 info->ram->multifd_bytes >> 10); 274 monitor_printf(mon, "pages-per-second: %" PRIu64 "\n", 275 info->ram->pages_per_second); 276 277 if (info->ram->dirty_pages_rate) { 278 monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n", 279 info->ram->dirty_pages_rate); 280 } 281 if (info->ram->postcopy_requests) { 282 monitor_printf(mon, "postcopy request count: %" PRIu64 "\n", 283 info->ram->postcopy_requests); 284 } 285 } 286 287 if (info->has_disk) { 288 monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n", 289 info->disk->transferred >> 10); 290 monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n", 291 info->disk->remaining >> 10); 292 monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n", 293 info->disk->total >> 10); 294 } 295 296 if (info->has_xbzrle_cache) { 297 monitor_printf(mon, "cache size: %" PRIu64 " bytes\n", 298 info->xbzrle_cache->cache_size); 299 monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n", 300 info->xbzrle_cache->bytes >> 10); 301 monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n", 302 info->xbzrle_cache->pages); 303 monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n", 304 info->xbzrle_cache->cache_miss); 305 monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n", 306 info->xbzrle_cache->cache_miss_rate); 307 monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n", 308 info->xbzrle_cache->overflow); 309 } 310 311 if (info->has_compression) { 312 monitor_printf(mon, "compression pages: %" PRIu64 " pages\n", 313 info->compression->pages); 314 monitor_printf(mon, "compression busy: %" PRIu64 "\n", 315 info->compression->busy); 316 monitor_printf(mon, "compression busy rate: %0.2f\n", 317 info->compression->busy_rate); 318 monitor_printf(mon, "compressed size: %" PRIu64 "\n", 319 info->compression->compressed_size); 320 monitor_printf(mon, "compression rate: %0.2f\n", 321 info->compression->compression_rate); 322 } 323 324 if (info->has_cpu_throttle_percentage) { 325 monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n", 326 info->cpu_throttle_percentage); 327 } 328 329 if (info->has_postcopy_blocktime) { 330 monitor_printf(mon, "postcopy blocktime: %u\n", 331 info->postcopy_blocktime); 332 } 333 334 if (info->has_postcopy_vcpu_blocktime) { 335 Visitor *v; 336 char *str; 337 v = string_output_visitor_new(false, &str); 338 visit_type_uint32List(v, NULL, &info->postcopy_vcpu_blocktime, NULL); 339 visit_complete(v, &str); 340 monitor_printf(mon, "postcopy vcpu blocktime: %s\n", str); 341 g_free(str); 342 visit_free(v); 343 } 344 if (info->has_socket_address) { 345 SocketAddressList *addr; 346 347 monitor_printf(mon, "socket address: [\n"); 348 349 for (addr = info->socket_address; addr; addr = addr->next) { 350 char *s = SocketAddress_to_str(addr->value); 351 monitor_printf(mon, "\t%s\n", s); 352 g_free(s); 353 } 354 monitor_printf(mon, "]\n"); 355 } 356 qapi_free_MigrationInfo(info); 357 } 358 359 void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict) 360 { 361 MigrationCapabilityStatusList *caps, *cap; 362 363 caps = qmp_query_migrate_capabilities(NULL); 364 365 if (caps) { 366 for (cap = caps; cap; cap = cap->next) { 367 monitor_printf(mon, "%s: %s\n", 368 MigrationCapability_str(cap->value->capability), 369 cap->value->state ? "on" : "off"); 370 } 371 } 372 373 qapi_free_MigrationCapabilityStatusList(caps); 374 } 375 376 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) 377 { 378 MigrationParameters *params; 379 380 params = qmp_query_migrate_parameters(NULL); 381 382 if (params) { 383 monitor_printf(mon, "%s: %" PRIu64 " ms\n", 384 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL), 385 params->announce_initial); 386 monitor_printf(mon, "%s: %" PRIu64 " ms\n", 387 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX), 388 params->announce_max); 389 monitor_printf(mon, "%s: %" PRIu64 "\n", 390 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS), 391 params->announce_rounds); 392 monitor_printf(mon, "%s: %" PRIu64 " ms\n", 393 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP), 394 params->announce_step); 395 assert(params->has_compress_level); 396 monitor_printf(mon, "%s: %u\n", 397 MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_LEVEL), 398 params->compress_level); 399 assert(params->has_compress_threads); 400 monitor_printf(mon, "%s: %u\n", 401 MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_THREADS), 402 params->compress_threads); 403 assert(params->has_compress_wait_thread); 404 monitor_printf(mon, "%s: %s\n", 405 MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD), 406 params->compress_wait_thread ? "on" : "off"); 407 assert(params->has_decompress_threads); 408 monitor_printf(mon, "%s: %u\n", 409 MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS), 410 params->decompress_threads); 411 assert(params->has_cpu_throttle_initial); 412 monitor_printf(mon, "%s: %u\n", 413 MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL), 414 params->cpu_throttle_initial); 415 assert(params->has_cpu_throttle_increment); 416 monitor_printf(mon, "%s: %u\n", 417 MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT), 418 params->cpu_throttle_increment); 419 assert(params->has_max_cpu_throttle); 420 monitor_printf(mon, "%s: %u\n", 421 MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE), 422 params->max_cpu_throttle); 423 assert(params->has_tls_creds); 424 monitor_printf(mon, "%s: '%s'\n", 425 MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS), 426 params->tls_creds); 427 assert(params->has_tls_hostname); 428 monitor_printf(mon, "%s: '%s'\n", 429 MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME), 430 params->tls_hostname); 431 assert(params->has_max_bandwidth); 432 monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n", 433 MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH), 434 params->max_bandwidth); 435 assert(params->has_downtime_limit); 436 monitor_printf(mon, "%s: %" PRIu64 " milliseconds\n", 437 MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT), 438 params->downtime_limit); 439 assert(params->has_x_checkpoint_delay); 440 monitor_printf(mon, "%s: %u\n", 441 MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY), 442 params->x_checkpoint_delay); 443 assert(params->has_block_incremental); 444 monitor_printf(mon, "%s: %s\n", 445 MigrationParameter_str(MIGRATION_PARAMETER_BLOCK_INCREMENTAL), 446 params->block_incremental ? "on" : "off"); 447 monitor_printf(mon, "%s: %u\n", 448 MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS), 449 params->multifd_channels); 450 monitor_printf(mon, "%s: %" PRIu64 "\n", 451 MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE), 452 params->xbzrle_cache_size); 453 monitor_printf(mon, "%s: %" PRIu64 "\n", 454 MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH), 455 params->max_postcopy_bandwidth); 456 monitor_printf(mon, " %s: '%s'\n", 457 MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ), 458 params->has_tls_authz ? params->tls_authz : ""); 459 } 460 461 qapi_free_MigrationParameters(params); 462 } 463 464 void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict) 465 { 466 monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n", 467 qmp_query_migrate_cache_size(NULL) >> 10); 468 } 469 470 static void print_block_info(Monitor *mon, BlockInfo *info, 471 BlockDeviceInfo *inserted, bool verbose) 472 { 473 ImageInfo *image_info; 474 475 assert(!info || !info->has_inserted || info->inserted == inserted); 476 477 if (info && *info->device) { 478 monitor_printf(mon, "%s", info->device); 479 if (inserted && inserted->has_node_name) { 480 monitor_printf(mon, " (%s)", inserted->node_name); 481 } 482 } else { 483 assert(info || inserted); 484 monitor_printf(mon, "%s", 485 inserted && inserted->has_node_name ? inserted->node_name 486 : info && info->has_qdev ? info->qdev 487 : "<anonymous>"); 488 } 489 490 if (inserted) { 491 monitor_printf(mon, ": %s (%s%s%s)\n", 492 inserted->file, 493 inserted->drv, 494 inserted->ro ? ", read-only" : "", 495 inserted->encrypted ? ", encrypted" : ""); 496 } else { 497 monitor_printf(mon, ": [not inserted]\n"); 498 } 499 500 if (info) { 501 if (info->has_qdev) { 502 monitor_printf(mon, " Attached to: %s\n", info->qdev); 503 } 504 if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) { 505 monitor_printf(mon, " I/O status: %s\n", 506 BlockDeviceIoStatus_str(info->io_status)); 507 } 508 509 if (info->removable) { 510 monitor_printf(mon, " Removable device: %slocked, tray %s\n", 511 info->locked ? "" : "not ", 512 info->tray_open ? "open" : "closed"); 513 } 514 } 515 516 517 if (!inserted) { 518 return; 519 } 520 521 monitor_printf(mon, " Cache mode: %s%s%s\n", 522 inserted->cache->writeback ? "writeback" : "writethrough", 523 inserted->cache->direct ? ", direct" : "", 524 inserted->cache->no_flush ? ", ignore flushes" : ""); 525 526 if (inserted->has_backing_file) { 527 monitor_printf(mon, 528 " Backing file: %s " 529 "(chain depth: %" PRId64 ")\n", 530 inserted->backing_file, 531 inserted->backing_file_depth); 532 } 533 534 if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) { 535 monitor_printf(mon, " Detect zeroes: %s\n", 536 BlockdevDetectZeroesOptions_str(inserted->detect_zeroes)); 537 } 538 539 if (inserted->bps || inserted->bps_rd || inserted->bps_wr || 540 inserted->iops || inserted->iops_rd || inserted->iops_wr) 541 { 542 monitor_printf(mon, " I/O throttling: bps=%" PRId64 543 " bps_rd=%" PRId64 " bps_wr=%" PRId64 544 " bps_max=%" PRId64 545 " bps_rd_max=%" PRId64 546 " bps_wr_max=%" PRId64 547 " iops=%" PRId64 " iops_rd=%" PRId64 548 " iops_wr=%" PRId64 549 " iops_max=%" PRId64 550 " iops_rd_max=%" PRId64 551 " iops_wr_max=%" PRId64 552 " iops_size=%" PRId64 553 " group=%s\n", 554 inserted->bps, 555 inserted->bps_rd, 556 inserted->bps_wr, 557 inserted->bps_max, 558 inserted->bps_rd_max, 559 inserted->bps_wr_max, 560 inserted->iops, 561 inserted->iops_rd, 562 inserted->iops_wr, 563 inserted->iops_max, 564 inserted->iops_rd_max, 565 inserted->iops_wr_max, 566 inserted->iops_size, 567 inserted->group); 568 } 569 570 if (verbose) { 571 monitor_printf(mon, "\nImages:\n"); 572 image_info = inserted->image; 573 while (1) { 574 bdrv_image_info_dump(image_info); 575 if (image_info->has_backing_image) { 576 image_info = image_info->backing_image; 577 } else { 578 break; 579 } 580 } 581 } 582 } 583 584 void hmp_info_block(Monitor *mon, const QDict *qdict) 585 { 586 BlockInfoList *block_list, *info; 587 BlockDeviceInfoList *blockdev_list, *blockdev; 588 const char *device = qdict_get_try_str(qdict, "device"); 589 bool verbose = qdict_get_try_bool(qdict, "verbose", false); 590 bool nodes = qdict_get_try_bool(qdict, "nodes", false); 591 bool printed = false; 592 593 /* Print BlockBackend information */ 594 if (!nodes) { 595 block_list = qmp_query_block(NULL); 596 } else { 597 block_list = NULL; 598 } 599 600 for (info = block_list; info; info = info->next) { 601 if (device && strcmp(device, info->value->device)) { 602 continue; 603 } 604 605 if (info != block_list) { 606 monitor_printf(mon, "\n"); 607 } 608 609 print_block_info(mon, info->value, info->value->has_inserted 610 ? info->value->inserted : NULL, 611 verbose); 612 printed = true; 613 } 614 615 qapi_free_BlockInfoList(block_list); 616 617 if ((!device && !nodes) || printed) { 618 return; 619 } 620 621 /* Print node information */ 622 blockdev_list = qmp_query_named_block_nodes(NULL); 623 for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) { 624 assert(blockdev->value->has_node_name); 625 if (device && strcmp(device, blockdev->value->node_name)) { 626 continue; 627 } 628 629 if (blockdev != blockdev_list) { 630 monitor_printf(mon, "\n"); 631 } 632 633 print_block_info(mon, NULL, blockdev->value, verbose); 634 } 635 qapi_free_BlockDeviceInfoList(blockdev_list); 636 } 637 638 void hmp_info_blockstats(Monitor *mon, const QDict *qdict) 639 { 640 BlockStatsList *stats_list, *stats; 641 642 stats_list = qmp_query_blockstats(false, false, NULL); 643 644 for (stats = stats_list; stats; stats = stats->next) { 645 if (!stats->value->has_device) { 646 continue; 647 } 648 649 monitor_printf(mon, "%s:", stats->value->device); 650 monitor_printf(mon, " rd_bytes=%" PRId64 651 " wr_bytes=%" PRId64 652 " rd_operations=%" PRId64 653 " wr_operations=%" PRId64 654 " flush_operations=%" PRId64 655 " wr_total_time_ns=%" PRId64 656 " rd_total_time_ns=%" PRId64 657 " flush_total_time_ns=%" PRId64 658 " rd_merged=%" PRId64 659 " wr_merged=%" PRId64 660 " idle_time_ns=%" PRId64 661 "\n", 662 stats->value->stats->rd_bytes, 663 stats->value->stats->wr_bytes, 664 stats->value->stats->rd_operations, 665 stats->value->stats->wr_operations, 666 stats->value->stats->flush_operations, 667 stats->value->stats->wr_total_time_ns, 668 stats->value->stats->rd_total_time_ns, 669 stats->value->stats->flush_total_time_ns, 670 stats->value->stats->rd_merged, 671 stats->value->stats->wr_merged, 672 stats->value->stats->idle_time_ns); 673 } 674 675 qapi_free_BlockStatsList(stats_list); 676 } 677 678 #ifdef CONFIG_VNC 679 /* Helper for hmp_info_vnc_clients, _servers */ 680 static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info, 681 const char *name) 682 { 683 monitor_printf(mon, " %s: %s:%s (%s%s)\n", 684 name, 685 info->host, 686 info->service, 687 NetworkAddressFamily_str(info->family), 688 info->websocket ? " (Websocket)" : ""); 689 } 690 691 /* Helper displaying and auth and crypt info */ 692 static void hmp_info_vnc_authcrypt(Monitor *mon, const char *indent, 693 VncPrimaryAuth auth, 694 VncVencryptSubAuth *vencrypt) 695 { 696 monitor_printf(mon, "%sAuth: %s (Sub: %s)\n", indent, 697 VncPrimaryAuth_str(auth), 698 vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none"); 699 } 700 701 static void hmp_info_vnc_clients(Monitor *mon, VncClientInfoList *client) 702 { 703 while (client) { 704 VncClientInfo *cinfo = client->value; 705 706 hmp_info_VncBasicInfo(mon, qapi_VncClientInfo_base(cinfo), "Client"); 707 monitor_printf(mon, " x509_dname: %s\n", 708 cinfo->has_x509_dname ? 709 cinfo->x509_dname : "none"); 710 monitor_printf(mon, " sasl_username: %s\n", 711 cinfo->has_sasl_username ? 712 cinfo->sasl_username : "none"); 713 714 client = client->next; 715 } 716 } 717 718 static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server) 719 { 720 while (server) { 721 VncServerInfo2 *sinfo = server->value; 722 hmp_info_VncBasicInfo(mon, qapi_VncServerInfo2_base(sinfo), "Server"); 723 hmp_info_vnc_authcrypt(mon, " ", sinfo->auth, 724 sinfo->has_vencrypt ? &sinfo->vencrypt : NULL); 725 server = server->next; 726 } 727 } 728 729 void hmp_info_vnc(Monitor *mon, const QDict *qdict) 730 { 731 VncInfo2List *info2l; 732 Error *err = NULL; 733 734 info2l = qmp_query_vnc_servers(&err); 735 if (err) { 736 hmp_handle_error(mon, err); 737 return; 738 } 739 if (!info2l) { 740 monitor_printf(mon, "None\n"); 741 return; 742 } 743 744 while (info2l) { 745 VncInfo2 *info = info2l->value; 746 monitor_printf(mon, "%s:\n", info->id); 747 hmp_info_vnc_servers(mon, info->server); 748 hmp_info_vnc_clients(mon, info->clients); 749 if (!info->server) { 750 /* The server entry displays its auth, we only 751 * need to display in the case of 'reverse' connections 752 * where there's no server. 753 */ 754 hmp_info_vnc_authcrypt(mon, " ", info->auth, 755 info->has_vencrypt ? &info->vencrypt : NULL); 756 } 757 if (info->has_display) { 758 monitor_printf(mon, " Display: %s\n", info->display); 759 } 760 info2l = info2l->next; 761 } 762 763 qapi_free_VncInfo2List(info2l); 764 765 } 766 #endif 767 768 #ifdef CONFIG_SPICE 769 void hmp_info_spice(Monitor *mon, const QDict *qdict) 770 { 771 SpiceChannelList *chan; 772 SpiceInfo *info; 773 const char *channel_name; 774 const char * const channel_names[] = { 775 [SPICE_CHANNEL_MAIN] = "main", 776 [SPICE_CHANNEL_DISPLAY] = "display", 777 [SPICE_CHANNEL_INPUTS] = "inputs", 778 [SPICE_CHANNEL_CURSOR] = "cursor", 779 [SPICE_CHANNEL_PLAYBACK] = "playback", 780 [SPICE_CHANNEL_RECORD] = "record", 781 [SPICE_CHANNEL_TUNNEL] = "tunnel", 782 [SPICE_CHANNEL_SMARTCARD] = "smartcard", 783 [SPICE_CHANNEL_USBREDIR] = "usbredir", 784 [SPICE_CHANNEL_PORT] = "port", 785 #if 0 786 /* minimum spice-protocol is 0.12.3, webdav was added in 0.12.7, 787 * no easy way to #ifdef (SPICE_CHANNEL_* is a enum). Disable 788 * as quick fix for build failures with older versions. */ 789 [SPICE_CHANNEL_WEBDAV] = "webdav", 790 #endif 791 }; 792 793 info = qmp_query_spice(NULL); 794 795 if (!info->enabled) { 796 monitor_printf(mon, "Server: disabled\n"); 797 goto out; 798 } 799 800 monitor_printf(mon, "Server:\n"); 801 if (info->has_port) { 802 monitor_printf(mon, " address: %s:%" PRId64 "\n", 803 info->host, info->port); 804 } 805 if (info->has_tls_port) { 806 monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n", 807 info->host, info->tls_port); 808 } 809 monitor_printf(mon, " migrated: %s\n", 810 info->migrated ? "true" : "false"); 811 monitor_printf(mon, " auth: %s\n", info->auth); 812 monitor_printf(mon, " compiled: %s\n", info->compiled_version); 813 monitor_printf(mon, " mouse-mode: %s\n", 814 SpiceQueryMouseMode_str(info->mouse_mode)); 815 816 if (!info->has_channels || info->channels == NULL) { 817 monitor_printf(mon, "Channels: none\n"); 818 } else { 819 for (chan = info->channels; chan; chan = chan->next) { 820 monitor_printf(mon, "Channel:\n"); 821 monitor_printf(mon, " address: %s:%s%s\n", 822 chan->value->host, chan->value->port, 823 chan->value->tls ? " [tls]" : ""); 824 monitor_printf(mon, " session: %" PRId64 "\n", 825 chan->value->connection_id); 826 monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n", 827 chan->value->channel_type, chan->value->channel_id); 828 829 channel_name = "unknown"; 830 if (chan->value->channel_type > 0 && 831 chan->value->channel_type < ARRAY_SIZE(channel_names) && 832 channel_names[chan->value->channel_type]) { 833 channel_name = channel_names[chan->value->channel_type]; 834 } 835 836 monitor_printf(mon, " channel name: %s\n", channel_name); 837 } 838 } 839 840 out: 841 qapi_free_SpiceInfo(info); 842 } 843 #endif 844 845 void hmp_info_balloon(Monitor *mon, const QDict *qdict) 846 { 847 BalloonInfo *info; 848 Error *err = NULL; 849 850 info = qmp_query_balloon(&err); 851 if (err) { 852 hmp_handle_error(mon, err); 853 return; 854 } 855 856 monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20); 857 858 qapi_free_BalloonInfo(info); 859 } 860 861 static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev) 862 { 863 PciMemoryRegionList *region; 864 865 monitor_printf(mon, " Bus %2" PRId64 ", ", dev->bus); 866 monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n", 867 dev->slot, dev->function); 868 monitor_printf(mon, " "); 869 870 if (dev->class_info->has_desc) { 871 monitor_printf(mon, "%s", dev->class_info->desc); 872 } else { 873 monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class); 874 } 875 876 monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n", 877 dev->id->vendor, dev->id->device); 878 if (dev->id->has_subsystem_vendor && dev->id->has_subsystem) { 879 monitor_printf(mon, " PCI subsystem %04" PRIx64 ":%04" PRIx64 "\n", 880 dev->id->subsystem_vendor, dev->id->subsystem); 881 } 882 883 if (dev->has_irq) { 884 monitor_printf(mon, " IRQ %" PRId64 ".\n", dev->irq); 885 } 886 887 if (dev->has_pci_bridge) { 888 monitor_printf(mon, " BUS %" PRId64 ".\n", 889 dev->pci_bridge->bus->number); 890 monitor_printf(mon, " secondary bus %" PRId64 ".\n", 891 dev->pci_bridge->bus->secondary); 892 monitor_printf(mon, " subordinate bus %" PRId64 ".\n", 893 dev->pci_bridge->bus->subordinate); 894 895 monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n", 896 dev->pci_bridge->bus->io_range->base, 897 dev->pci_bridge->bus->io_range->limit); 898 899 monitor_printf(mon, 900 " memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n", 901 dev->pci_bridge->bus->memory_range->base, 902 dev->pci_bridge->bus->memory_range->limit); 903 904 monitor_printf(mon, " prefetchable memory range " 905 "[0x%08"PRIx64", 0x%08"PRIx64"]\n", 906 dev->pci_bridge->bus->prefetchable_range->base, 907 dev->pci_bridge->bus->prefetchable_range->limit); 908 } 909 910 for (region = dev->regions; region; region = region->next) { 911 uint64_t addr, size; 912 913 addr = region->value->address; 914 size = region->value->size; 915 916 monitor_printf(mon, " BAR%" PRId64 ": ", region->value->bar); 917 918 if (!strcmp(region->value->type, "io")) { 919 monitor_printf(mon, "I/O at 0x%04" PRIx64 920 " [0x%04" PRIx64 "].\n", 921 addr, addr + size - 1); 922 } else { 923 monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64 924 " [0x%08" PRIx64 "].\n", 925 region->value->mem_type_64 ? 64 : 32, 926 region->value->prefetch ? " prefetchable" : "", 927 addr, addr + size - 1); 928 } 929 } 930 931 monitor_printf(mon, " id \"%s\"\n", dev->qdev_id); 932 933 if (dev->has_pci_bridge) { 934 if (dev->pci_bridge->has_devices) { 935 PciDeviceInfoList *cdev; 936 for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) { 937 hmp_info_pci_device(mon, cdev->value); 938 } 939 } 940 } 941 } 942 943 static int hmp_info_irq_foreach(Object *obj, void *opaque) 944 { 945 InterruptStatsProvider *intc; 946 InterruptStatsProviderClass *k; 947 Monitor *mon = opaque; 948 949 if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) { 950 intc = INTERRUPT_STATS_PROVIDER(obj); 951 k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj); 952 uint64_t *irq_counts; 953 unsigned int nb_irqs, i; 954 if (k->get_statistics && 955 k->get_statistics(intc, &irq_counts, &nb_irqs)) { 956 if (nb_irqs > 0) { 957 monitor_printf(mon, "IRQ statistics for %s:\n", 958 object_get_typename(obj)); 959 for (i = 0; i < nb_irqs; i++) { 960 if (irq_counts[i] > 0) { 961 monitor_printf(mon, "%2d: %" PRId64 "\n", i, 962 irq_counts[i]); 963 } 964 } 965 } 966 } else { 967 monitor_printf(mon, "IRQ statistics not available for %s.\n", 968 object_get_typename(obj)); 969 } 970 } 971 972 return 0; 973 } 974 975 void hmp_info_irq(Monitor *mon, const QDict *qdict) 976 { 977 object_child_foreach_recursive(object_get_root(), 978 hmp_info_irq_foreach, mon); 979 } 980 981 static int hmp_info_pic_foreach(Object *obj, void *opaque) 982 { 983 InterruptStatsProvider *intc; 984 InterruptStatsProviderClass *k; 985 Monitor *mon = opaque; 986 987 if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) { 988 intc = INTERRUPT_STATS_PROVIDER(obj); 989 k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj); 990 if (k->print_info) { 991 k->print_info(intc, mon); 992 } else { 993 monitor_printf(mon, "Interrupt controller information not available for %s.\n", 994 object_get_typename(obj)); 995 } 996 } 997 998 return 0; 999 } 1000 1001 void hmp_info_pic(Monitor *mon, const QDict *qdict) 1002 { 1003 object_child_foreach_recursive(object_get_root(), 1004 hmp_info_pic_foreach, mon); 1005 } 1006 1007 static int hmp_info_rdma_foreach(Object *obj, void *opaque) 1008 { 1009 RdmaProvider *rdma; 1010 RdmaProviderClass *k; 1011 Monitor *mon = opaque; 1012 1013 if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) { 1014 rdma = RDMA_PROVIDER(obj); 1015 k = RDMA_PROVIDER_GET_CLASS(obj); 1016 if (k->print_statistics) { 1017 k->print_statistics(mon, rdma); 1018 } else { 1019 monitor_printf(mon, "RDMA statistics not available for %s.\n", 1020 object_get_typename(obj)); 1021 } 1022 } 1023 1024 return 0; 1025 } 1026 1027 void hmp_info_rdma(Monitor *mon, const QDict *qdict) 1028 { 1029 object_child_foreach_recursive(object_get_root(), 1030 hmp_info_rdma_foreach, mon); 1031 } 1032 1033 void hmp_info_pci(Monitor *mon, const QDict *qdict) 1034 { 1035 PciInfoList *info_list, *info; 1036 Error *err = NULL; 1037 1038 info_list = qmp_query_pci(&err); 1039 if (err) { 1040 monitor_printf(mon, "PCI devices not supported\n"); 1041 error_free(err); 1042 return; 1043 } 1044 1045 for (info = info_list; info; info = info->next) { 1046 PciDeviceInfoList *dev; 1047 1048 for (dev = info->value->devices; dev; dev = dev->next) { 1049 hmp_info_pci_device(mon, dev->value); 1050 } 1051 } 1052 1053 qapi_free_PciInfoList(info_list); 1054 } 1055 1056 void hmp_info_block_jobs(Monitor *mon, const QDict *qdict) 1057 { 1058 BlockJobInfoList *list; 1059 Error *err = NULL; 1060 1061 list = qmp_query_block_jobs(&err); 1062 assert(!err); 1063 1064 if (!list) { 1065 monitor_printf(mon, "No active jobs\n"); 1066 return; 1067 } 1068 1069 while (list) { 1070 if (strcmp(list->value->type, "stream") == 0) { 1071 monitor_printf(mon, "Streaming device %s: Completed %" PRId64 1072 " of %" PRId64 " bytes, speed limit %" PRId64 1073 " bytes/s\n", 1074 list->value->device, 1075 list->value->offset, 1076 list->value->len, 1077 list->value->speed); 1078 } else { 1079 monitor_printf(mon, "Type %s, device %s: Completed %" PRId64 1080 " of %" PRId64 " bytes, speed limit %" PRId64 1081 " bytes/s\n", 1082 list->value->type, 1083 list->value->device, 1084 list->value->offset, 1085 list->value->len, 1086 list->value->speed); 1087 } 1088 list = list->next; 1089 } 1090 1091 qapi_free_BlockJobInfoList(list); 1092 } 1093 1094 void hmp_info_tpm(Monitor *mon, const QDict *qdict) 1095 { 1096 TPMInfoList *info_list, *info; 1097 Error *err = NULL; 1098 unsigned int c = 0; 1099 TPMPassthroughOptions *tpo; 1100 TPMEmulatorOptions *teo; 1101 1102 info_list = qmp_query_tpm(&err); 1103 if (err) { 1104 monitor_printf(mon, "TPM device not supported\n"); 1105 error_free(err); 1106 return; 1107 } 1108 1109 if (info_list) { 1110 monitor_printf(mon, "TPM device:\n"); 1111 } 1112 1113 for (info = info_list; info; info = info->next) { 1114 TPMInfo *ti = info->value; 1115 monitor_printf(mon, " tpm%d: model=%s\n", 1116 c, TpmModel_str(ti->model)); 1117 1118 monitor_printf(mon, " \\ %s: type=%s", 1119 ti->id, TpmTypeOptionsKind_str(ti->options->type)); 1120 1121 switch (ti->options->type) { 1122 case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH: 1123 tpo = ti->options->u.passthrough.data; 1124 monitor_printf(mon, "%s%s%s%s", 1125 tpo->has_path ? ",path=" : "", 1126 tpo->has_path ? tpo->path : "", 1127 tpo->has_cancel_path ? ",cancel-path=" : "", 1128 tpo->has_cancel_path ? tpo->cancel_path : ""); 1129 break; 1130 case TPM_TYPE_OPTIONS_KIND_EMULATOR: 1131 teo = ti->options->u.emulator.data; 1132 monitor_printf(mon, ",chardev=%s", teo->chardev); 1133 break; 1134 case TPM_TYPE_OPTIONS_KIND__MAX: 1135 break; 1136 } 1137 monitor_printf(mon, "\n"); 1138 c++; 1139 } 1140 qapi_free_TPMInfoList(info_list); 1141 } 1142 1143 void hmp_quit(Monitor *mon, const QDict *qdict) 1144 { 1145 monitor_suspend(mon); 1146 qmp_quit(NULL); 1147 } 1148 1149 void hmp_stop(Monitor *mon, const QDict *qdict) 1150 { 1151 qmp_stop(NULL); 1152 } 1153 1154 void hmp_sync_profile(Monitor *mon, const QDict *qdict) 1155 { 1156 const char *op = qdict_get_try_str(qdict, "op"); 1157 1158 if (op == NULL) { 1159 bool on = qsp_is_enabled(); 1160 1161 monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off"); 1162 return; 1163 } 1164 if (!strcmp(op, "on")) { 1165 qsp_enable(); 1166 } else if (!strcmp(op, "off")) { 1167 qsp_disable(); 1168 } else if (!strcmp(op, "reset")) { 1169 qsp_reset(); 1170 } else { 1171 Error *err = NULL; 1172 1173 error_setg(&err, QERR_INVALID_PARAMETER, op); 1174 hmp_handle_error(mon, err); 1175 } 1176 } 1177 1178 void hmp_system_reset(Monitor *mon, const QDict *qdict) 1179 { 1180 qmp_system_reset(NULL); 1181 } 1182 1183 void hmp_system_powerdown(Monitor *mon, const QDict *qdict) 1184 { 1185 qmp_system_powerdown(NULL); 1186 } 1187 1188 void hmp_exit_preconfig(Monitor *mon, const QDict *qdict) 1189 { 1190 Error *err = NULL; 1191 1192 qmp_x_exit_preconfig(&err); 1193 hmp_handle_error(mon, err); 1194 } 1195 1196 void hmp_cpu(Monitor *mon, const QDict *qdict) 1197 { 1198 int64_t cpu_index; 1199 1200 /* XXX: drop the monitor_set_cpu() usage when all HMP commands that 1201 use it are converted to the QAPI */ 1202 cpu_index = qdict_get_int(qdict, "index"); 1203 if (monitor_set_cpu(cpu_index) < 0) { 1204 monitor_printf(mon, "invalid CPU index\n"); 1205 } 1206 } 1207 1208 void hmp_memsave(Monitor *mon, const QDict *qdict) 1209 { 1210 uint32_t size = qdict_get_int(qdict, "size"); 1211 const char *filename = qdict_get_str(qdict, "filename"); 1212 uint64_t addr = qdict_get_int(qdict, "val"); 1213 Error *err = NULL; 1214 int cpu_index = monitor_get_cpu_index(); 1215 1216 if (cpu_index < 0) { 1217 monitor_printf(mon, "No CPU available\n"); 1218 return; 1219 } 1220 1221 qmp_memsave(addr, size, filename, true, cpu_index, &err); 1222 hmp_handle_error(mon, err); 1223 } 1224 1225 void hmp_pmemsave(Monitor *mon, const QDict *qdict) 1226 { 1227 uint32_t size = qdict_get_int(qdict, "size"); 1228 const char *filename = qdict_get_str(qdict, "filename"); 1229 uint64_t addr = qdict_get_int(qdict, "val"); 1230 Error *err = NULL; 1231 1232 qmp_pmemsave(addr, size, filename, &err); 1233 hmp_handle_error(mon, err); 1234 } 1235 1236 void hmp_ringbuf_write(Monitor *mon, const QDict *qdict) 1237 { 1238 const char *chardev = qdict_get_str(qdict, "device"); 1239 const char *data = qdict_get_str(qdict, "data"); 1240 Error *err = NULL; 1241 1242 qmp_ringbuf_write(chardev, data, false, 0, &err); 1243 1244 hmp_handle_error(mon, err); 1245 } 1246 1247 void hmp_ringbuf_read(Monitor *mon, const QDict *qdict) 1248 { 1249 uint32_t size = qdict_get_int(qdict, "size"); 1250 const char *chardev = qdict_get_str(qdict, "device"); 1251 char *data; 1252 Error *err = NULL; 1253 int i; 1254 1255 data = qmp_ringbuf_read(chardev, size, false, 0, &err); 1256 if (err) { 1257 hmp_handle_error(mon, err); 1258 return; 1259 } 1260 1261 for (i = 0; data[i]; i++) { 1262 unsigned char ch = data[i]; 1263 1264 if (ch == '\\') { 1265 monitor_printf(mon, "\\\\"); 1266 } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) { 1267 monitor_printf(mon, "\\u%04X", ch); 1268 } else { 1269 monitor_printf(mon, "%c", ch); 1270 } 1271 1272 } 1273 monitor_printf(mon, "\n"); 1274 g_free(data); 1275 } 1276 1277 void hmp_cont(Monitor *mon, const QDict *qdict) 1278 { 1279 Error *err = NULL; 1280 1281 qmp_cont(&err); 1282 hmp_handle_error(mon, err); 1283 } 1284 1285 void hmp_system_wakeup(Monitor *mon, const QDict *qdict) 1286 { 1287 Error *err = NULL; 1288 1289 qmp_system_wakeup(&err); 1290 hmp_handle_error(mon, err); 1291 } 1292 1293 void hmp_nmi(Monitor *mon, const QDict *qdict) 1294 { 1295 Error *err = NULL; 1296 1297 qmp_inject_nmi(&err); 1298 hmp_handle_error(mon, err); 1299 } 1300 1301 void hmp_set_link(Monitor *mon, const QDict *qdict) 1302 { 1303 const char *name = qdict_get_str(qdict, "name"); 1304 bool up = qdict_get_bool(qdict, "up"); 1305 Error *err = NULL; 1306 1307 qmp_set_link(name, up, &err); 1308 hmp_handle_error(mon, err); 1309 } 1310 1311 void hmp_block_passwd(Monitor *mon, const QDict *qdict) 1312 { 1313 const char *device = qdict_get_str(qdict, "device"); 1314 const char *password = qdict_get_str(qdict, "password"); 1315 Error *err = NULL; 1316 1317 qmp_block_passwd(true, device, false, NULL, password, &err); 1318 hmp_handle_error(mon, err); 1319 } 1320 1321 void hmp_balloon(Monitor *mon, const QDict *qdict) 1322 { 1323 int64_t value = qdict_get_int(qdict, "value"); 1324 Error *err = NULL; 1325 1326 qmp_balloon(value, &err); 1327 hmp_handle_error(mon, err); 1328 } 1329 1330 void hmp_block_resize(Monitor *mon, const QDict *qdict) 1331 { 1332 const char *device = qdict_get_str(qdict, "device"); 1333 int64_t size = qdict_get_int(qdict, "size"); 1334 Error *err = NULL; 1335 1336 qmp_block_resize(true, device, false, NULL, size, &err); 1337 hmp_handle_error(mon, err); 1338 } 1339 1340 void hmp_drive_mirror(Monitor *mon, const QDict *qdict) 1341 { 1342 const char *filename = qdict_get_str(qdict, "target"); 1343 const char *format = qdict_get_try_str(qdict, "format"); 1344 bool reuse = qdict_get_try_bool(qdict, "reuse", false); 1345 bool full = qdict_get_try_bool(qdict, "full", false); 1346 Error *err = NULL; 1347 DriveMirror mirror = { 1348 .device = (char *)qdict_get_str(qdict, "device"), 1349 .target = (char *)filename, 1350 .has_format = !!format, 1351 .format = (char *)format, 1352 .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP, 1353 .has_mode = true, 1354 .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS, 1355 .unmap = true, 1356 }; 1357 1358 if (!filename) { 1359 error_setg(&err, QERR_MISSING_PARAMETER, "target"); 1360 hmp_handle_error(mon, err); 1361 return; 1362 } 1363 qmp_drive_mirror(&mirror, &err); 1364 hmp_handle_error(mon, err); 1365 } 1366 1367 void hmp_drive_backup(Monitor *mon, const QDict *qdict) 1368 { 1369 const char *device = qdict_get_str(qdict, "device"); 1370 const char *filename = qdict_get_str(qdict, "target"); 1371 const char *format = qdict_get_try_str(qdict, "format"); 1372 bool reuse = qdict_get_try_bool(qdict, "reuse", false); 1373 bool full = qdict_get_try_bool(qdict, "full", false); 1374 bool compress = qdict_get_try_bool(qdict, "compress", false); 1375 Error *err = NULL; 1376 DriveBackup backup = { 1377 .device = (char *)device, 1378 .target = (char *)filename, 1379 .has_format = !!format, 1380 .format = (char *)format, 1381 .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP, 1382 .has_mode = true, 1383 .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS, 1384 .has_compress = !!compress, 1385 .compress = compress, 1386 }; 1387 1388 if (!filename) { 1389 error_setg(&err, QERR_MISSING_PARAMETER, "target"); 1390 hmp_handle_error(mon, err); 1391 return; 1392 } 1393 1394 qmp_drive_backup(&backup, &err); 1395 hmp_handle_error(mon, err); 1396 } 1397 1398 void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict) 1399 { 1400 const char *device = qdict_get_str(qdict, "device"); 1401 const char *filename = qdict_get_try_str(qdict, "snapshot-file"); 1402 const char *format = qdict_get_try_str(qdict, "format"); 1403 bool reuse = qdict_get_try_bool(qdict, "reuse", false); 1404 enum NewImageMode mode; 1405 Error *err = NULL; 1406 1407 if (!filename) { 1408 /* In the future, if 'snapshot-file' is not specified, the snapshot 1409 will be taken internally. Today it's actually required. */ 1410 error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file"); 1411 hmp_handle_error(mon, err); 1412 return; 1413 } 1414 1415 mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS; 1416 qmp_blockdev_snapshot_sync(true, device, false, NULL, 1417 filename, false, NULL, 1418 !!format, format, 1419 true, mode, &err); 1420 hmp_handle_error(mon, err); 1421 } 1422 1423 void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict) 1424 { 1425 const char *device = qdict_get_str(qdict, "device"); 1426 const char *name = qdict_get_str(qdict, "name"); 1427 Error *err = NULL; 1428 1429 qmp_blockdev_snapshot_internal_sync(device, name, &err); 1430 hmp_handle_error(mon, err); 1431 } 1432 1433 void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict) 1434 { 1435 const char *device = qdict_get_str(qdict, "device"); 1436 const char *name = qdict_get_str(qdict, "name"); 1437 const char *id = qdict_get_try_str(qdict, "id"); 1438 Error *err = NULL; 1439 1440 qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id, 1441 true, name, &err); 1442 hmp_handle_error(mon, err); 1443 } 1444 1445 void hmp_loadvm(Monitor *mon, const QDict *qdict) 1446 { 1447 int saved_vm_running = runstate_is_running(); 1448 const char *name = qdict_get_str(qdict, "name"); 1449 Error *err = NULL; 1450 1451 vm_stop(RUN_STATE_RESTORE_VM); 1452 1453 if (load_snapshot(name, &err) == 0 && saved_vm_running) { 1454 vm_start(); 1455 } 1456 hmp_handle_error(mon, err); 1457 } 1458 1459 void hmp_savevm(Monitor *mon, const QDict *qdict) 1460 { 1461 Error *err = NULL; 1462 1463 save_snapshot(qdict_get_try_str(qdict, "name"), &err); 1464 hmp_handle_error(mon, err); 1465 } 1466 1467 void hmp_delvm(Monitor *mon, const QDict *qdict) 1468 { 1469 BlockDriverState *bs; 1470 Error *err = NULL; 1471 const char *name = qdict_get_str(qdict, "name"); 1472 1473 if (bdrv_all_delete_snapshot(name, &bs, &err) < 0) { 1474 error_prepend(&err, 1475 "deleting snapshot on device '%s': ", 1476 bdrv_get_device_name(bs)); 1477 } 1478 hmp_handle_error(mon, err); 1479 } 1480 1481 void hmp_info_snapshots(Monitor *mon, const QDict *qdict) 1482 { 1483 BlockDriverState *bs, *bs1; 1484 BdrvNextIterator it1; 1485 QEMUSnapshotInfo *sn_tab, *sn; 1486 bool no_snapshot = true; 1487 int nb_sns, i; 1488 int total; 1489 int *global_snapshots; 1490 AioContext *aio_context; 1491 1492 typedef struct SnapshotEntry { 1493 QEMUSnapshotInfo sn; 1494 QTAILQ_ENTRY(SnapshotEntry) next; 1495 } SnapshotEntry; 1496 1497 typedef struct ImageEntry { 1498 const char *imagename; 1499 QTAILQ_ENTRY(ImageEntry) next; 1500 QTAILQ_HEAD(, SnapshotEntry) snapshots; 1501 } ImageEntry; 1502 1503 QTAILQ_HEAD(, ImageEntry) image_list = 1504 QTAILQ_HEAD_INITIALIZER(image_list); 1505 1506 ImageEntry *image_entry, *next_ie; 1507 SnapshotEntry *snapshot_entry; 1508 1509 bs = bdrv_all_find_vmstate_bs(); 1510 if (!bs) { 1511 monitor_printf(mon, "No available block device supports snapshots\n"); 1512 return; 1513 } 1514 aio_context = bdrv_get_aio_context(bs); 1515 1516 aio_context_acquire(aio_context); 1517 nb_sns = bdrv_snapshot_list(bs, &sn_tab); 1518 aio_context_release(aio_context); 1519 1520 if (nb_sns < 0) { 1521 monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns); 1522 return; 1523 } 1524 1525 for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) { 1526 int bs1_nb_sns = 0; 1527 ImageEntry *ie; 1528 SnapshotEntry *se; 1529 AioContext *ctx = bdrv_get_aio_context(bs1); 1530 1531 aio_context_acquire(ctx); 1532 if (bdrv_can_snapshot(bs1)) { 1533 sn = NULL; 1534 bs1_nb_sns = bdrv_snapshot_list(bs1, &sn); 1535 if (bs1_nb_sns > 0) { 1536 no_snapshot = false; 1537 ie = g_new0(ImageEntry, 1); 1538 ie->imagename = bdrv_get_device_name(bs1); 1539 QTAILQ_INIT(&ie->snapshots); 1540 QTAILQ_INSERT_TAIL(&image_list, ie, next); 1541 for (i = 0; i < bs1_nb_sns; i++) { 1542 se = g_new0(SnapshotEntry, 1); 1543 se->sn = sn[i]; 1544 QTAILQ_INSERT_TAIL(&ie->snapshots, se, next); 1545 } 1546 } 1547 g_free(sn); 1548 } 1549 aio_context_release(ctx); 1550 } 1551 1552 if (no_snapshot) { 1553 monitor_printf(mon, "There is no snapshot available.\n"); 1554 return; 1555 } 1556 1557 global_snapshots = g_new0(int, nb_sns); 1558 total = 0; 1559 for (i = 0; i < nb_sns; i++) { 1560 SnapshotEntry *next_sn; 1561 if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) { 1562 global_snapshots[total] = i; 1563 total++; 1564 QTAILQ_FOREACH(image_entry, &image_list, next) { 1565 QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, 1566 next, next_sn) { 1567 if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) { 1568 QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry, 1569 next); 1570 g_free(snapshot_entry); 1571 } 1572 } 1573 } 1574 } 1575 } 1576 1577 monitor_printf(mon, "List of snapshots present on all disks:\n"); 1578 1579 if (total > 0) { 1580 bdrv_snapshot_dump(NULL); 1581 monitor_printf(mon, "\n"); 1582 for (i = 0; i < total; i++) { 1583 sn = &sn_tab[global_snapshots[i]]; 1584 /* The ID is not guaranteed to be the same on all images, so 1585 * overwrite it. 1586 */ 1587 pstrcpy(sn->id_str, sizeof(sn->id_str), "--"); 1588 bdrv_snapshot_dump(sn); 1589 monitor_printf(mon, "\n"); 1590 } 1591 } else { 1592 monitor_printf(mon, "None\n"); 1593 } 1594 1595 QTAILQ_FOREACH(image_entry, &image_list, next) { 1596 if (QTAILQ_EMPTY(&image_entry->snapshots)) { 1597 continue; 1598 } 1599 monitor_printf(mon, 1600 "\nList of partial (non-loadable) snapshots on '%s':\n", 1601 image_entry->imagename); 1602 bdrv_snapshot_dump(NULL); 1603 monitor_printf(mon, "\n"); 1604 QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) { 1605 bdrv_snapshot_dump(&snapshot_entry->sn); 1606 monitor_printf(mon, "\n"); 1607 } 1608 } 1609 1610 QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) { 1611 SnapshotEntry *next_sn; 1612 QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next, 1613 next_sn) { 1614 g_free(snapshot_entry); 1615 } 1616 g_free(image_entry); 1617 } 1618 g_free(sn_tab); 1619 g_free(global_snapshots); 1620 1621 } 1622 1623 void hmp_announce_self(Monitor *mon, const QDict *qdict) 1624 { 1625 const char *interfaces_str = qdict_get_try_str(qdict, "interfaces"); 1626 const char *id = qdict_get_try_str(qdict, "id"); 1627 AnnounceParameters *params = QAPI_CLONE(AnnounceParameters, 1628 migrate_announce_params()); 1629 1630 qapi_free_strList(params->interfaces); 1631 params->interfaces = strList_from_comma_list(interfaces_str); 1632 params->has_interfaces = params->interfaces != NULL; 1633 params->id = g_strdup(id); 1634 params->has_id = !!params->id; 1635 qmp_announce_self(params, NULL); 1636 qapi_free_AnnounceParameters(params); 1637 } 1638 1639 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict) 1640 { 1641 qmp_migrate_cancel(NULL); 1642 } 1643 1644 void hmp_migrate_continue(Monitor *mon, const QDict *qdict) 1645 { 1646 Error *err = NULL; 1647 const char *state = qdict_get_str(qdict, "state"); 1648 int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err); 1649 1650 if (val >= 0) { 1651 qmp_migrate_continue(val, &err); 1652 } 1653 1654 hmp_handle_error(mon, err); 1655 } 1656 1657 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict) 1658 { 1659 Error *err = NULL; 1660 const char *uri = qdict_get_str(qdict, "uri"); 1661 1662 qmp_migrate_incoming(uri, &err); 1663 1664 hmp_handle_error(mon, err); 1665 } 1666 1667 void hmp_migrate_recover(Monitor *mon, const QDict *qdict) 1668 { 1669 Error *err = NULL; 1670 const char *uri = qdict_get_str(qdict, "uri"); 1671 1672 qmp_migrate_recover(uri, &err); 1673 1674 hmp_handle_error(mon, err); 1675 } 1676 1677 void hmp_migrate_pause(Monitor *mon, const QDict *qdict) 1678 { 1679 Error *err = NULL; 1680 1681 qmp_migrate_pause(&err); 1682 1683 hmp_handle_error(mon, err); 1684 } 1685 1686 /* Kept for backwards compatibility */ 1687 void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict) 1688 { 1689 double value = qdict_get_double(qdict, "value"); 1690 qmp_migrate_set_downtime(value, NULL); 1691 } 1692 1693 void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict) 1694 { 1695 int64_t value = qdict_get_int(qdict, "value"); 1696 Error *err = NULL; 1697 1698 qmp_migrate_set_cache_size(value, &err); 1699 hmp_handle_error(mon, err); 1700 } 1701 1702 /* Kept for backwards compatibility */ 1703 void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict) 1704 { 1705 int64_t value = qdict_get_int(qdict, "value"); 1706 qmp_migrate_set_speed(value, NULL); 1707 } 1708 1709 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) 1710 { 1711 const char *cap = qdict_get_str(qdict, "capability"); 1712 bool state = qdict_get_bool(qdict, "state"); 1713 Error *err = NULL; 1714 MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps)); 1715 int val; 1716 1717 val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err); 1718 if (val < 0) { 1719 goto end; 1720 } 1721 1722 caps->value = g_malloc0(sizeof(*caps->value)); 1723 caps->value->capability = val; 1724 caps->value->state = state; 1725 caps->next = NULL; 1726 qmp_migrate_set_capabilities(caps, &err); 1727 1728 end: 1729 qapi_free_MigrationCapabilityStatusList(caps); 1730 hmp_handle_error(mon, err); 1731 } 1732 1733 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) 1734 { 1735 const char *param = qdict_get_str(qdict, "parameter"); 1736 const char *valuestr = qdict_get_str(qdict, "value"); 1737 Visitor *v = string_input_visitor_new(valuestr); 1738 MigrateSetParameters *p = g_new0(MigrateSetParameters, 1); 1739 uint64_t valuebw = 0; 1740 uint64_t cache_size; 1741 Error *err = NULL; 1742 int val, ret; 1743 1744 val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err); 1745 if (val < 0) { 1746 goto cleanup; 1747 } 1748 1749 switch (val) { 1750 case MIGRATION_PARAMETER_COMPRESS_LEVEL: 1751 p->has_compress_level = true; 1752 visit_type_int(v, param, &p->compress_level, &err); 1753 break; 1754 case MIGRATION_PARAMETER_COMPRESS_THREADS: 1755 p->has_compress_threads = true; 1756 visit_type_int(v, param, &p->compress_threads, &err); 1757 break; 1758 case MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD: 1759 p->has_compress_wait_thread = true; 1760 visit_type_bool(v, param, &p->compress_wait_thread, &err); 1761 break; 1762 case MIGRATION_PARAMETER_DECOMPRESS_THREADS: 1763 p->has_decompress_threads = true; 1764 visit_type_int(v, param, &p->decompress_threads, &err); 1765 break; 1766 case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL: 1767 p->has_cpu_throttle_initial = true; 1768 visit_type_int(v, param, &p->cpu_throttle_initial, &err); 1769 break; 1770 case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT: 1771 p->has_cpu_throttle_increment = true; 1772 visit_type_int(v, param, &p->cpu_throttle_increment, &err); 1773 break; 1774 case MIGRATION_PARAMETER_MAX_CPU_THROTTLE: 1775 p->has_max_cpu_throttle = true; 1776 visit_type_int(v, param, &p->max_cpu_throttle, &err); 1777 break; 1778 case MIGRATION_PARAMETER_TLS_CREDS: 1779 p->has_tls_creds = true; 1780 p->tls_creds = g_new0(StrOrNull, 1); 1781 p->tls_creds->type = QTYPE_QSTRING; 1782 visit_type_str(v, param, &p->tls_creds->u.s, &err); 1783 break; 1784 case MIGRATION_PARAMETER_TLS_HOSTNAME: 1785 p->has_tls_hostname = true; 1786 p->tls_hostname = g_new0(StrOrNull, 1); 1787 p->tls_hostname->type = QTYPE_QSTRING; 1788 visit_type_str(v, param, &p->tls_hostname->u.s, &err); 1789 break; 1790 case MIGRATION_PARAMETER_TLS_AUTHZ: 1791 p->has_tls_authz = true; 1792 p->tls_authz = g_new0(StrOrNull, 1); 1793 p->tls_authz->type = QTYPE_QSTRING; 1794 visit_type_str(v, param, &p->tls_authz->u.s, &err); 1795 break; 1796 case MIGRATION_PARAMETER_MAX_BANDWIDTH: 1797 p->has_max_bandwidth = true; 1798 /* 1799 * Can't use visit_type_size() here, because it 1800 * defaults to Bytes rather than Mebibytes. 1801 */ 1802 ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw); 1803 if (ret < 0 || valuebw > INT64_MAX 1804 || (size_t)valuebw != valuebw) { 1805 error_setg(&err, "Invalid size %s", valuestr); 1806 break; 1807 } 1808 p->max_bandwidth = valuebw; 1809 break; 1810 case MIGRATION_PARAMETER_DOWNTIME_LIMIT: 1811 p->has_downtime_limit = true; 1812 visit_type_int(v, param, &p->downtime_limit, &err); 1813 break; 1814 case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY: 1815 p->has_x_checkpoint_delay = true; 1816 visit_type_int(v, param, &p->x_checkpoint_delay, &err); 1817 break; 1818 case MIGRATION_PARAMETER_BLOCK_INCREMENTAL: 1819 p->has_block_incremental = true; 1820 visit_type_bool(v, param, &p->block_incremental, &err); 1821 break; 1822 case MIGRATION_PARAMETER_MULTIFD_CHANNELS: 1823 p->has_multifd_channels = true; 1824 visit_type_int(v, param, &p->multifd_channels, &err); 1825 break; 1826 case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE: 1827 p->has_xbzrle_cache_size = true; 1828 visit_type_size(v, param, &cache_size, &err); 1829 if (err) { 1830 break; 1831 } 1832 if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) { 1833 error_setg(&err, "Invalid size %s", valuestr); 1834 break; 1835 } 1836 p->xbzrle_cache_size = cache_size; 1837 break; 1838 case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH: 1839 p->has_max_postcopy_bandwidth = true; 1840 visit_type_size(v, param, &p->max_postcopy_bandwidth, &err); 1841 break; 1842 case MIGRATION_PARAMETER_ANNOUNCE_INITIAL: 1843 p->has_announce_initial = true; 1844 visit_type_size(v, param, &p->announce_initial, &err); 1845 break; 1846 case MIGRATION_PARAMETER_ANNOUNCE_MAX: 1847 p->has_announce_max = true; 1848 visit_type_size(v, param, &p->announce_max, &err); 1849 break; 1850 case MIGRATION_PARAMETER_ANNOUNCE_ROUNDS: 1851 p->has_announce_rounds = true; 1852 visit_type_size(v, param, &p->announce_rounds, &err); 1853 break; 1854 case MIGRATION_PARAMETER_ANNOUNCE_STEP: 1855 p->has_announce_step = true; 1856 visit_type_size(v, param, &p->announce_step, &err); 1857 break; 1858 default: 1859 assert(0); 1860 } 1861 1862 if (err) { 1863 goto cleanup; 1864 } 1865 1866 qmp_migrate_set_parameters(p, &err); 1867 1868 cleanup: 1869 qapi_free_MigrateSetParameters(p); 1870 visit_free(v); 1871 hmp_handle_error(mon, err); 1872 } 1873 1874 void hmp_client_migrate_info(Monitor *mon, const QDict *qdict) 1875 { 1876 Error *err = NULL; 1877 const char *protocol = qdict_get_str(qdict, "protocol"); 1878 const char *hostname = qdict_get_str(qdict, "hostname"); 1879 bool has_port = qdict_haskey(qdict, "port"); 1880 int port = qdict_get_try_int(qdict, "port", -1); 1881 bool has_tls_port = qdict_haskey(qdict, "tls-port"); 1882 int tls_port = qdict_get_try_int(qdict, "tls-port", -1); 1883 const char *cert_subject = qdict_get_try_str(qdict, "cert-subject"); 1884 1885 qmp_client_migrate_info(protocol, hostname, 1886 has_port, port, has_tls_port, tls_port, 1887 !!cert_subject, cert_subject, &err); 1888 hmp_handle_error(mon, err); 1889 } 1890 1891 void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict) 1892 { 1893 Error *err = NULL; 1894 qmp_migrate_start_postcopy(&err); 1895 hmp_handle_error(mon, err); 1896 } 1897 1898 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict) 1899 { 1900 Error *err = NULL; 1901 1902 qmp_x_colo_lost_heartbeat(&err); 1903 hmp_handle_error(mon, err); 1904 } 1905 1906 void hmp_set_password(Monitor *mon, const QDict *qdict) 1907 { 1908 const char *protocol = qdict_get_str(qdict, "protocol"); 1909 const char *password = qdict_get_str(qdict, "password"); 1910 const char *connected = qdict_get_try_str(qdict, "connected"); 1911 Error *err = NULL; 1912 1913 qmp_set_password(protocol, password, !!connected, connected, &err); 1914 hmp_handle_error(mon, err); 1915 } 1916 1917 void hmp_expire_password(Monitor *mon, const QDict *qdict) 1918 { 1919 const char *protocol = qdict_get_str(qdict, "protocol"); 1920 const char *whenstr = qdict_get_str(qdict, "time"); 1921 Error *err = NULL; 1922 1923 qmp_expire_password(protocol, whenstr, &err); 1924 hmp_handle_error(mon, err); 1925 } 1926 1927 void hmp_eject(Monitor *mon, const QDict *qdict) 1928 { 1929 bool force = qdict_get_try_bool(qdict, "force", false); 1930 const char *device = qdict_get_str(qdict, "device"); 1931 Error *err = NULL; 1932 1933 qmp_eject(true, device, false, NULL, true, force, &err); 1934 hmp_handle_error(mon, err); 1935 } 1936 1937 #ifdef CONFIG_VNC 1938 static void hmp_change_read_arg(void *opaque, const char *password, 1939 void *readline_opaque) 1940 { 1941 qmp_change_vnc_password(password, NULL); 1942 monitor_read_command(opaque, 1); 1943 } 1944 #endif 1945 1946 void hmp_change(Monitor *mon, const QDict *qdict) 1947 { 1948 const char *device = qdict_get_str(qdict, "device"); 1949 const char *target = qdict_get_str(qdict, "target"); 1950 const char *arg = qdict_get_try_str(qdict, "arg"); 1951 const char *read_only = qdict_get_try_str(qdict, "read-only-mode"); 1952 BlockdevChangeReadOnlyMode read_only_mode = 0; 1953 Error *err = NULL; 1954 1955 #ifdef CONFIG_VNC 1956 if (strcmp(device, "vnc") == 0) { 1957 if (read_only) { 1958 monitor_printf(mon, 1959 "Parameter 'read-only-mode' is invalid for VNC\n"); 1960 return; 1961 } 1962 if (strcmp(target, "passwd") == 0 || 1963 strcmp(target, "password") == 0) { 1964 if (!arg) { 1965 MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common); 1966 monitor_read_password(hmp_mon, hmp_change_read_arg, NULL); 1967 return; 1968 } 1969 } 1970 qmp_change("vnc", target, !!arg, arg, &err); 1971 } else 1972 #endif 1973 { 1974 if (read_only) { 1975 read_only_mode = 1976 qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup, 1977 read_only, 1978 BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err); 1979 if (err) { 1980 hmp_handle_error(mon, err); 1981 return; 1982 } 1983 } 1984 1985 qmp_blockdev_change_medium(true, device, false, NULL, target, 1986 !!arg, arg, !!read_only, read_only_mode, 1987 &err); 1988 } 1989 1990 hmp_handle_error(mon, err); 1991 } 1992 1993 void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict) 1994 { 1995 Error *err = NULL; 1996 char *device = (char *) qdict_get_str(qdict, "device"); 1997 BlockIOThrottle throttle = { 1998 .bps = qdict_get_int(qdict, "bps"), 1999 .bps_rd = qdict_get_int(qdict, "bps_rd"), 2000 .bps_wr = qdict_get_int(qdict, "bps_wr"), 2001 .iops = qdict_get_int(qdict, "iops"), 2002 .iops_rd = qdict_get_int(qdict, "iops_rd"), 2003 .iops_wr = qdict_get_int(qdict, "iops_wr"), 2004 }; 2005 2006 /* qmp_block_set_io_throttle has separate parameters for the 2007 * (deprecated) block device name and the qdev ID but the HMP 2008 * version has only one, so we must decide which one to pass. */ 2009 if (blk_by_name(device)) { 2010 throttle.has_device = true; 2011 throttle.device = device; 2012 } else { 2013 throttle.has_id = true; 2014 throttle.id = device; 2015 } 2016 2017 qmp_block_set_io_throttle(&throttle, &err); 2018 hmp_handle_error(mon, err); 2019 } 2020 2021 void hmp_block_stream(Monitor *mon, const QDict *qdict) 2022 { 2023 Error *error = NULL; 2024 const char *device = qdict_get_str(qdict, "device"); 2025 const char *base = qdict_get_try_str(qdict, "base"); 2026 int64_t speed = qdict_get_try_int(qdict, "speed", 0); 2027 2028 qmp_block_stream(true, device, device, base != NULL, base, false, NULL, 2029 false, NULL, qdict_haskey(qdict, "speed"), speed, true, 2030 BLOCKDEV_ON_ERROR_REPORT, false, false, false, false, 2031 &error); 2032 2033 hmp_handle_error(mon, error); 2034 } 2035 2036 void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict) 2037 { 2038 Error *error = NULL; 2039 const char *device = qdict_get_str(qdict, "device"); 2040 int64_t value = qdict_get_int(qdict, "speed"); 2041 2042 qmp_block_job_set_speed(device, value, &error); 2043 2044 hmp_handle_error(mon, error); 2045 } 2046 2047 void hmp_block_job_cancel(Monitor *mon, const QDict *qdict) 2048 { 2049 Error *error = NULL; 2050 const char *device = qdict_get_str(qdict, "device"); 2051 bool force = qdict_get_try_bool(qdict, "force", false); 2052 2053 qmp_block_job_cancel(device, true, force, &error); 2054 2055 hmp_handle_error(mon, error); 2056 } 2057 2058 void hmp_block_job_pause(Monitor *mon, const QDict *qdict) 2059 { 2060 Error *error = NULL; 2061 const char *device = qdict_get_str(qdict, "device"); 2062 2063 qmp_block_job_pause(device, &error); 2064 2065 hmp_handle_error(mon, error); 2066 } 2067 2068 void hmp_block_job_resume(Monitor *mon, const QDict *qdict) 2069 { 2070 Error *error = NULL; 2071 const char *device = qdict_get_str(qdict, "device"); 2072 2073 qmp_block_job_resume(device, &error); 2074 2075 hmp_handle_error(mon, error); 2076 } 2077 2078 void hmp_block_job_complete(Monitor *mon, const QDict *qdict) 2079 { 2080 Error *error = NULL; 2081 const char *device = qdict_get_str(qdict, "device"); 2082 2083 qmp_block_job_complete(device, &error); 2084 2085 hmp_handle_error(mon, error); 2086 } 2087 2088 typedef struct HMPMigrationStatus 2089 { 2090 QEMUTimer *timer; 2091 Monitor *mon; 2092 bool is_block_migration; 2093 } HMPMigrationStatus; 2094 2095 static void hmp_migrate_status_cb(void *opaque) 2096 { 2097 HMPMigrationStatus *status = opaque; 2098 MigrationInfo *info; 2099 2100 info = qmp_query_migrate(NULL); 2101 if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE || 2102 info->status == MIGRATION_STATUS_SETUP) { 2103 if (info->has_disk) { 2104 int progress; 2105 2106 if (info->disk->remaining) { 2107 progress = info->disk->transferred * 100 / info->disk->total; 2108 } else { 2109 progress = 100; 2110 } 2111 2112 monitor_printf(status->mon, "Completed %d %%\r", progress); 2113 monitor_flush(status->mon); 2114 } 2115 2116 timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000); 2117 } else { 2118 if (status->is_block_migration) { 2119 monitor_printf(status->mon, "\n"); 2120 } 2121 if (info->has_error_desc) { 2122 error_report("%s", info->error_desc); 2123 } 2124 monitor_resume(status->mon); 2125 timer_del(status->timer); 2126 timer_free(status->timer); 2127 g_free(status); 2128 } 2129 2130 qapi_free_MigrationInfo(info); 2131 } 2132 2133 void hmp_migrate(Monitor *mon, const QDict *qdict) 2134 { 2135 bool detach = qdict_get_try_bool(qdict, "detach", false); 2136 bool blk = qdict_get_try_bool(qdict, "blk", false); 2137 bool inc = qdict_get_try_bool(qdict, "inc", false); 2138 bool resume = qdict_get_try_bool(qdict, "resume", false); 2139 const char *uri = qdict_get_str(qdict, "uri"); 2140 Error *err = NULL; 2141 2142 qmp_migrate(uri, !!blk, blk, !!inc, inc, 2143 false, false, true, resume, &err); 2144 if (err) { 2145 hmp_handle_error(mon, err); 2146 return; 2147 } 2148 2149 if (!detach) { 2150 HMPMigrationStatus *status; 2151 2152 if (monitor_suspend(mon) < 0) { 2153 monitor_printf(mon, "terminal does not allow synchronous " 2154 "migration, continuing detached\n"); 2155 return; 2156 } 2157 2158 status = g_malloc0(sizeof(*status)); 2159 status->mon = mon; 2160 status->is_block_migration = blk || inc; 2161 status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb, 2162 status); 2163 timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME)); 2164 } 2165 } 2166 2167 void hmp_netdev_add(Monitor *mon, const QDict *qdict) 2168 { 2169 Error *err = NULL; 2170 QemuOpts *opts; 2171 2172 opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err); 2173 if (err) { 2174 goto out; 2175 } 2176 2177 netdev_add(opts, &err); 2178 if (err) { 2179 qemu_opts_del(opts); 2180 } 2181 2182 out: 2183 hmp_handle_error(mon, err); 2184 } 2185 2186 void hmp_netdev_del(Monitor *mon, const QDict *qdict) 2187 { 2188 const char *id = qdict_get_str(qdict, "id"); 2189 Error *err = NULL; 2190 2191 qmp_netdev_del(id, &err); 2192 hmp_handle_error(mon, err); 2193 } 2194 2195 void hmp_object_add(Monitor *mon, const QDict *qdict) 2196 { 2197 Error *err = NULL; 2198 QemuOpts *opts; 2199 Object *obj = NULL; 2200 2201 opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err); 2202 if (err) { 2203 hmp_handle_error(mon, err); 2204 return; 2205 } 2206 2207 obj = user_creatable_add_opts(opts, &err); 2208 qemu_opts_del(opts); 2209 2210 if (err) { 2211 hmp_handle_error(mon, err); 2212 } 2213 if (obj) { 2214 object_unref(obj); 2215 } 2216 } 2217 2218 void hmp_getfd(Monitor *mon, const QDict *qdict) 2219 { 2220 const char *fdname = qdict_get_str(qdict, "fdname"); 2221 Error *err = NULL; 2222 2223 qmp_getfd(fdname, &err); 2224 hmp_handle_error(mon, err); 2225 } 2226 2227 void hmp_closefd(Monitor *mon, const QDict *qdict) 2228 { 2229 const char *fdname = qdict_get_str(qdict, "fdname"); 2230 Error *err = NULL; 2231 2232 qmp_closefd(fdname, &err); 2233 hmp_handle_error(mon, err); 2234 } 2235 2236 void hmp_sendkey(Monitor *mon, const QDict *qdict) 2237 { 2238 const char *keys = qdict_get_str(qdict, "keys"); 2239 KeyValueList *keylist, *head = NULL, *tmp = NULL; 2240 int has_hold_time = qdict_haskey(qdict, "hold-time"); 2241 int hold_time = qdict_get_try_int(qdict, "hold-time", -1); 2242 Error *err = NULL; 2243 const char *separator; 2244 int keyname_len; 2245 2246 while (1) { 2247 separator = qemu_strchrnul(keys, '-'); 2248 keyname_len = separator - keys; 2249 2250 /* Be compatible with old interface, convert user inputted "<" */ 2251 if (keys[0] == '<' && keyname_len == 1) { 2252 keys = "less"; 2253 keyname_len = 4; 2254 } 2255 2256 keylist = g_malloc0(sizeof(*keylist)); 2257 keylist->value = g_malloc0(sizeof(*keylist->value)); 2258 2259 if (!head) { 2260 head = keylist; 2261 } 2262 if (tmp) { 2263 tmp->next = keylist; 2264 } 2265 tmp = keylist; 2266 2267 if (strstart(keys, "0x", NULL)) { 2268 char *endp; 2269 int value = strtoul(keys, &endp, 0); 2270 assert(endp <= keys + keyname_len); 2271 if (endp != keys + keyname_len) { 2272 goto err_out; 2273 } 2274 keylist->value->type = KEY_VALUE_KIND_NUMBER; 2275 keylist->value->u.number.data = value; 2276 } else { 2277 int idx = index_from_key(keys, keyname_len); 2278 if (idx == Q_KEY_CODE__MAX) { 2279 goto err_out; 2280 } 2281 keylist->value->type = KEY_VALUE_KIND_QCODE; 2282 keylist->value->u.qcode.data = idx; 2283 } 2284 2285 if (!*separator) { 2286 break; 2287 } 2288 keys = separator + 1; 2289 } 2290 2291 qmp_send_key(head, has_hold_time, hold_time, &err); 2292 hmp_handle_error(mon, err); 2293 2294 out: 2295 qapi_free_KeyValueList(head); 2296 return; 2297 2298 err_out: 2299 monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys); 2300 goto out; 2301 } 2302 2303 void hmp_screendump(Monitor *mon, const QDict *qdict) 2304 { 2305 const char *filename = qdict_get_str(qdict, "filename"); 2306 const char *id = qdict_get_try_str(qdict, "device"); 2307 int64_t head = qdict_get_try_int(qdict, "head", 0); 2308 Error *err = NULL; 2309 2310 qmp_screendump(filename, id != NULL, id, id != NULL, head, &err); 2311 hmp_handle_error(mon, err); 2312 } 2313 2314 void hmp_nbd_server_start(Monitor *mon, const QDict *qdict) 2315 { 2316 const char *uri = qdict_get_str(qdict, "uri"); 2317 bool writable = qdict_get_try_bool(qdict, "writable", false); 2318 bool all = qdict_get_try_bool(qdict, "all", false); 2319 Error *local_err = NULL; 2320 BlockInfoList *block_list, *info; 2321 SocketAddress *addr; 2322 2323 if (writable && !all) { 2324 error_setg(&local_err, "-w only valid together with -a"); 2325 goto exit; 2326 } 2327 2328 /* First check if the address is valid and start the server. */ 2329 addr = socket_parse(uri, &local_err); 2330 if (local_err != NULL) { 2331 goto exit; 2332 } 2333 2334 nbd_server_start(addr, NULL, NULL, &local_err); 2335 qapi_free_SocketAddress(addr); 2336 if (local_err != NULL) { 2337 goto exit; 2338 } 2339 2340 if (!all) { 2341 return; 2342 } 2343 2344 /* Then try adding all block devices. If one fails, close all and 2345 * exit. 2346 */ 2347 block_list = qmp_query_block(NULL); 2348 2349 for (info = block_list; info; info = info->next) { 2350 if (!info->value->has_inserted) { 2351 continue; 2352 } 2353 2354 qmp_nbd_server_add(info->value->device, false, NULL, 2355 true, writable, false, NULL, &local_err); 2356 2357 if (local_err != NULL) { 2358 qmp_nbd_server_stop(NULL); 2359 break; 2360 } 2361 } 2362 2363 qapi_free_BlockInfoList(block_list); 2364 2365 exit: 2366 hmp_handle_error(mon, local_err); 2367 } 2368 2369 void hmp_nbd_server_add(Monitor *mon, const QDict *qdict) 2370 { 2371 const char *device = qdict_get_str(qdict, "device"); 2372 const char *name = qdict_get_try_str(qdict, "name"); 2373 bool writable = qdict_get_try_bool(qdict, "writable", false); 2374 Error *local_err = NULL; 2375 2376 qmp_nbd_server_add(device, !!name, name, true, writable, 2377 false, NULL, &local_err); 2378 hmp_handle_error(mon, local_err); 2379 } 2380 2381 void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict) 2382 { 2383 const char *name = qdict_get_str(qdict, "name"); 2384 bool force = qdict_get_try_bool(qdict, "force", false); 2385 Error *err = NULL; 2386 2387 /* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */ 2388 qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, &err); 2389 hmp_handle_error(mon, err); 2390 } 2391 2392 void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict) 2393 { 2394 Error *err = NULL; 2395 2396 qmp_nbd_server_stop(&err); 2397 hmp_handle_error(mon, err); 2398 } 2399 2400 void hmp_chardev_add(Monitor *mon, const QDict *qdict) 2401 { 2402 const char *args = qdict_get_str(qdict, "args"); 2403 Error *err = NULL; 2404 QemuOpts *opts; 2405 2406 opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, true); 2407 if (opts == NULL) { 2408 error_setg(&err, "Parsing chardev args failed"); 2409 } else { 2410 qemu_chr_new_from_opts(opts, NULL, &err); 2411 qemu_opts_del(opts); 2412 } 2413 hmp_handle_error(mon, err); 2414 } 2415 2416 void hmp_chardev_change(Monitor *mon, const QDict *qdict) 2417 { 2418 const char *args = qdict_get_str(qdict, "args"); 2419 const char *id; 2420 Error *err = NULL; 2421 ChardevBackend *backend = NULL; 2422 ChardevReturn *ret = NULL; 2423 QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, 2424 true); 2425 if (!opts) { 2426 error_setg(&err, "Parsing chardev args failed"); 2427 goto end; 2428 } 2429 2430 id = qdict_get_str(qdict, "id"); 2431 if (qemu_opts_id(opts)) { 2432 error_setg(&err, "Unexpected 'id' parameter"); 2433 goto end; 2434 } 2435 2436 backend = qemu_chr_parse_opts(opts, &err); 2437 if (!backend) { 2438 goto end; 2439 } 2440 2441 ret = qmp_chardev_change(id, backend, &err); 2442 2443 end: 2444 qapi_free_ChardevReturn(ret); 2445 qapi_free_ChardevBackend(backend); 2446 qemu_opts_del(opts); 2447 hmp_handle_error(mon, err); 2448 } 2449 2450 void hmp_chardev_remove(Monitor *mon, const QDict *qdict) 2451 { 2452 Error *local_err = NULL; 2453 2454 qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err); 2455 hmp_handle_error(mon, local_err); 2456 } 2457 2458 void hmp_chardev_send_break(Monitor *mon, const QDict *qdict) 2459 { 2460 Error *local_err = NULL; 2461 2462 qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err); 2463 hmp_handle_error(mon, local_err); 2464 } 2465 2466 void hmp_qemu_io(Monitor *mon, const QDict *qdict) 2467 { 2468 BlockBackend *blk; 2469 BlockBackend *local_blk = NULL; 2470 bool qdev = qdict_get_try_bool(qdict, "qdev", false); 2471 const char* device = qdict_get_str(qdict, "device"); 2472 const char* command = qdict_get_str(qdict, "command"); 2473 Error *err = NULL; 2474 int ret; 2475 2476 if (qdev) { 2477 blk = blk_by_qdev_id(device, &err); 2478 if (!blk) { 2479 goto fail; 2480 } 2481 } else { 2482 blk = blk_by_name(device); 2483 if (!blk) { 2484 BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err); 2485 if (bs) { 2486 blk = local_blk = blk_new(bdrv_get_aio_context(bs), 2487 0, BLK_PERM_ALL); 2488 ret = blk_insert_bs(blk, bs, &err); 2489 if (ret < 0) { 2490 goto fail; 2491 } 2492 } else { 2493 goto fail; 2494 } 2495 } 2496 } 2497 2498 /* 2499 * Notably absent: Proper permission management. This is sad, but it seems 2500 * almost impossible to achieve without changing the semantics and thereby 2501 * limiting the use cases of the qemu-io HMP command. 2502 * 2503 * In an ideal world we would unconditionally create a new BlockBackend for 2504 * qemuio_command(), but we have commands like 'reopen' and want them to 2505 * take effect on the exact BlockBackend whose name the user passed instead 2506 * of just on a temporary copy of it. 2507 * 2508 * Another problem is that deleting the temporary BlockBackend involves 2509 * draining all requests on it first, but some qemu-iotests cases want to 2510 * issue multiple aio_read/write requests and expect them to complete in 2511 * the background while the monitor has already returned. 2512 * 2513 * This is also what prevents us from saving the original permissions and 2514 * restoring them later: We can't revoke permissions until all requests 2515 * have completed, and we don't know when that is nor can we really let 2516 * anything else run before we have revoken them to avoid race conditions. 2517 * 2518 * What happens now is that command() in qemu-io-cmds.c can extend the 2519 * permissions if necessary for the qemu-io command. And they simply stay 2520 * extended, possibly resulting in a read-only guest device keeping write 2521 * permissions. Ugly, but it appears to be the lesser evil. 2522 */ 2523 qemuio_command(blk, command); 2524 2525 fail: 2526 blk_unref(local_blk); 2527 hmp_handle_error(mon, err); 2528 } 2529 2530 void hmp_object_del(Monitor *mon, const QDict *qdict) 2531 { 2532 const char *id = qdict_get_str(qdict, "id"); 2533 Error *err = NULL; 2534 2535 user_creatable_del(id, &err); 2536 hmp_handle_error(mon, err); 2537 } 2538 2539 void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) 2540 { 2541 Error *err = NULL; 2542 MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err); 2543 MemoryDeviceInfoList *info; 2544 VirtioPMEMDeviceInfo *vpi; 2545 MemoryDeviceInfo *value; 2546 PCDIMMDeviceInfo *di; 2547 2548 for (info = info_list; info; info = info->next) { 2549 value = info->value; 2550 2551 if (value) { 2552 switch (value->type) { 2553 case MEMORY_DEVICE_INFO_KIND_DIMM: 2554 case MEMORY_DEVICE_INFO_KIND_NVDIMM: 2555 di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ? 2556 value->u.dimm.data : value->u.nvdimm.data; 2557 monitor_printf(mon, "Memory device [%s]: \"%s\"\n", 2558 MemoryDeviceInfoKind_str(value->type), 2559 di->id ? di->id : ""); 2560 monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); 2561 monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); 2562 monitor_printf(mon, " node: %" PRId64 "\n", di->node); 2563 monitor_printf(mon, " size: %" PRIu64 "\n", di->size); 2564 monitor_printf(mon, " memdev: %s\n", di->memdev); 2565 monitor_printf(mon, " hotplugged: %s\n", 2566 di->hotplugged ? "true" : "false"); 2567 monitor_printf(mon, " hotpluggable: %s\n", 2568 di->hotpluggable ? "true" : "false"); 2569 break; 2570 case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM: 2571 vpi = value->u.virtio_pmem.data; 2572 monitor_printf(mon, "Memory device [%s]: \"%s\"\n", 2573 MemoryDeviceInfoKind_str(value->type), 2574 vpi->id ? vpi->id : ""); 2575 monitor_printf(mon, " memaddr: 0x%" PRIx64 "\n", vpi->memaddr); 2576 monitor_printf(mon, " size: %" PRIu64 "\n", vpi->size); 2577 monitor_printf(mon, " memdev: %s\n", vpi->memdev); 2578 break; 2579 default: 2580 g_assert_not_reached(); 2581 } 2582 } 2583 } 2584 2585 qapi_free_MemoryDeviceInfoList(info_list); 2586 hmp_handle_error(mon, err); 2587 } 2588 2589 void hmp_info_iothreads(Monitor *mon, const QDict *qdict) 2590 { 2591 IOThreadInfoList *info_list = qmp_query_iothreads(NULL); 2592 IOThreadInfoList *info; 2593 IOThreadInfo *value; 2594 2595 for (info = info_list; info; info = info->next) { 2596 value = info->value; 2597 monitor_printf(mon, "%s:\n", value->id); 2598 monitor_printf(mon, " thread_id=%" PRId64 "\n", value->thread_id); 2599 monitor_printf(mon, " poll-max-ns=%" PRId64 "\n", value->poll_max_ns); 2600 monitor_printf(mon, " poll-grow=%" PRId64 "\n", value->poll_grow); 2601 monitor_printf(mon, " poll-shrink=%" PRId64 "\n", value->poll_shrink); 2602 } 2603 2604 qapi_free_IOThreadInfoList(info_list); 2605 } 2606 2607 void hmp_rocker(Monitor *mon, const QDict *qdict) 2608 { 2609 const char *name = qdict_get_str(qdict, "name"); 2610 RockerSwitch *rocker; 2611 Error *err = NULL; 2612 2613 rocker = qmp_query_rocker(name, &err); 2614 if (err != NULL) { 2615 hmp_handle_error(mon, err); 2616 return; 2617 } 2618 2619 monitor_printf(mon, "name: %s\n", rocker->name); 2620 monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id); 2621 monitor_printf(mon, "ports: %d\n", rocker->ports); 2622 2623 qapi_free_RockerSwitch(rocker); 2624 } 2625 2626 void hmp_rocker_ports(Monitor *mon, const QDict *qdict) 2627 { 2628 RockerPortList *list, *port; 2629 const char *name = qdict_get_str(qdict, "name"); 2630 Error *err = NULL; 2631 2632 list = qmp_query_rocker_ports(name, &err); 2633 if (err != NULL) { 2634 hmp_handle_error(mon, err); 2635 return; 2636 } 2637 2638 monitor_printf(mon, " ena/ speed/ auto\n"); 2639 monitor_printf(mon, " port link duplex neg?\n"); 2640 2641 for (port = list; port; port = port->next) { 2642 monitor_printf(mon, "%10s %-4s %-3s %2s %-3s\n", 2643 port->value->name, 2644 port->value->enabled ? port->value->link_up ? 2645 "up" : "down" : "!ena", 2646 port->value->speed == 10000 ? "10G" : "??", 2647 port->value->duplex ? "FD" : "HD", 2648 port->value->autoneg ? "Yes" : "No"); 2649 } 2650 2651 qapi_free_RockerPortList(list); 2652 } 2653 2654 void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict) 2655 { 2656 RockerOfDpaFlowList *list, *info; 2657 const char *name = qdict_get_str(qdict, "name"); 2658 uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1); 2659 Error *err = NULL; 2660 2661 list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err); 2662 if (err != NULL) { 2663 hmp_handle_error(mon, err); 2664 return; 2665 } 2666 2667 monitor_printf(mon, "prio tbl hits key(mask) --> actions\n"); 2668 2669 for (info = list; info; info = info->next) { 2670 RockerOfDpaFlow *flow = info->value; 2671 RockerOfDpaFlowKey *key = flow->key; 2672 RockerOfDpaFlowMask *mask = flow->mask; 2673 RockerOfDpaFlowAction *action = flow->action; 2674 2675 if (flow->hits) { 2676 monitor_printf(mon, "%-4d %-3d %-4" PRIu64, 2677 key->priority, key->tbl_id, flow->hits); 2678 } else { 2679 monitor_printf(mon, "%-4d %-3d ", 2680 key->priority, key->tbl_id); 2681 } 2682 2683 if (key->has_in_pport) { 2684 monitor_printf(mon, " pport %d", key->in_pport); 2685 if (mask->has_in_pport) { 2686 monitor_printf(mon, "(0x%x)", mask->in_pport); 2687 } 2688 } 2689 2690 if (key->has_vlan_id) { 2691 monitor_printf(mon, " vlan %d", 2692 key->vlan_id & VLAN_VID_MASK); 2693 if (mask->has_vlan_id) { 2694 monitor_printf(mon, "(0x%x)", mask->vlan_id); 2695 } 2696 } 2697 2698 if (key->has_tunnel_id) { 2699 monitor_printf(mon, " tunnel %d", key->tunnel_id); 2700 if (mask->has_tunnel_id) { 2701 monitor_printf(mon, "(0x%x)", mask->tunnel_id); 2702 } 2703 } 2704 2705 if (key->has_eth_type) { 2706 switch (key->eth_type) { 2707 case 0x0806: 2708 monitor_printf(mon, " ARP"); 2709 break; 2710 case 0x0800: 2711 monitor_printf(mon, " IP"); 2712 break; 2713 case 0x86dd: 2714 monitor_printf(mon, " IPv6"); 2715 break; 2716 case 0x8809: 2717 monitor_printf(mon, " LACP"); 2718 break; 2719 case 0x88cc: 2720 monitor_printf(mon, " LLDP"); 2721 break; 2722 default: 2723 monitor_printf(mon, " eth type 0x%04x", key->eth_type); 2724 break; 2725 } 2726 } 2727 2728 if (key->has_eth_src) { 2729 if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) && 2730 (mask->has_eth_src) && 2731 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) { 2732 monitor_printf(mon, " src <any mcast/bcast>"); 2733 } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) && 2734 (mask->has_eth_src) && 2735 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) { 2736 monitor_printf(mon, " src <any ucast>"); 2737 } else { 2738 monitor_printf(mon, " src %s", key->eth_src); 2739 if (mask->has_eth_src) { 2740 monitor_printf(mon, "(%s)", mask->eth_src); 2741 } 2742 } 2743 } 2744 2745 if (key->has_eth_dst) { 2746 if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) && 2747 (mask->has_eth_dst) && 2748 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) { 2749 monitor_printf(mon, " dst <any mcast/bcast>"); 2750 } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) && 2751 (mask->has_eth_dst) && 2752 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) { 2753 monitor_printf(mon, " dst <any ucast>"); 2754 } else { 2755 monitor_printf(mon, " dst %s", key->eth_dst); 2756 if (mask->has_eth_dst) { 2757 monitor_printf(mon, "(%s)", mask->eth_dst); 2758 } 2759 } 2760 } 2761 2762 if (key->has_ip_proto) { 2763 monitor_printf(mon, " proto %d", key->ip_proto); 2764 if (mask->has_ip_proto) { 2765 monitor_printf(mon, "(0x%x)", mask->ip_proto); 2766 } 2767 } 2768 2769 if (key->has_ip_tos) { 2770 monitor_printf(mon, " TOS %d", key->ip_tos); 2771 if (mask->has_ip_tos) { 2772 monitor_printf(mon, "(0x%x)", mask->ip_tos); 2773 } 2774 } 2775 2776 if (key->has_ip_dst) { 2777 monitor_printf(mon, " dst %s", key->ip_dst); 2778 } 2779 2780 if (action->has_goto_tbl || action->has_group_id || 2781 action->has_new_vlan_id) { 2782 monitor_printf(mon, " -->"); 2783 } 2784 2785 if (action->has_new_vlan_id) { 2786 monitor_printf(mon, " apply new vlan %d", 2787 ntohs(action->new_vlan_id)); 2788 } 2789 2790 if (action->has_group_id) { 2791 monitor_printf(mon, " write group 0x%08x", action->group_id); 2792 } 2793 2794 if (action->has_goto_tbl) { 2795 monitor_printf(mon, " goto tbl %d", action->goto_tbl); 2796 } 2797 2798 monitor_printf(mon, "\n"); 2799 } 2800 2801 qapi_free_RockerOfDpaFlowList(list); 2802 } 2803 2804 void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict) 2805 { 2806 RockerOfDpaGroupList *list, *g; 2807 const char *name = qdict_get_str(qdict, "name"); 2808 uint8_t type = qdict_get_try_int(qdict, "type", 9); 2809 Error *err = NULL; 2810 bool set = false; 2811 2812 list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err); 2813 if (err != NULL) { 2814 hmp_handle_error(mon, err); 2815 return; 2816 } 2817 2818 monitor_printf(mon, "id (decode) --> buckets\n"); 2819 2820 for (g = list; g; g = g->next) { 2821 RockerOfDpaGroup *group = g->value; 2822 2823 monitor_printf(mon, "0x%08x", group->id); 2824 2825 monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" : 2826 group->type == 1 ? "L2 rewrite" : 2827 group->type == 2 ? "L3 unicast" : 2828 group->type == 3 ? "L2 multicast" : 2829 group->type == 4 ? "L2 flood" : 2830 group->type == 5 ? "L3 interface" : 2831 group->type == 6 ? "L3 multicast" : 2832 group->type == 7 ? "L3 ECMP" : 2833 group->type == 8 ? "L2 overlay" : 2834 "unknown"); 2835 2836 if (group->has_vlan_id) { 2837 monitor_printf(mon, " vlan %d", group->vlan_id); 2838 } 2839 2840 if (group->has_pport) { 2841 monitor_printf(mon, " pport %d", group->pport); 2842 } 2843 2844 if (group->has_index) { 2845 monitor_printf(mon, " index %d", group->index); 2846 } 2847 2848 monitor_printf(mon, ") -->"); 2849 2850 if (group->has_set_vlan_id && group->set_vlan_id) { 2851 set = true; 2852 monitor_printf(mon, " set vlan %d", 2853 group->set_vlan_id & VLAN_VID_MASK); 2854 } 2855 2856 if (group->has_set_eth_src) { 2857 if (!set) { 2858 set = true; 2859 monitor_printf(mon, " set"); 2860 } 2861 monitor_printf(mon, " src %s", group->set_eth_src); 2862 } 2863 2864 if (group->has_set_eth_dst) { 2865 if (!set) { 2866 set = true; 2867 monitor_printf(mon, " set"); 2868 } 2869 monitor_printf(mon, " dst %s", group->set_eth_dst); 2870 } 2871 2872 set = false; 2873 2874 if (group->has_ttl_check && group->ttl_check) { 2875 monitor_printf(mon, " check TTL"); 2876 } 2877 2878 if (group->has_group_id && group->group_id) { 2879 monitor_printf(mon, " group id 0x%08x", group->group_id); 2880 } 2881 2882 if (group->has_pop_vlan && group->pop_vlan) { 2883 monitor_printf(mon, " pop vlan"); 2884 } 2885 2886 if (group->has_out_pport) { 2887 monitor_printf(mon, " out pport %d", group->out_pport); 2888 } 2889 2890 if (group->has_group_ids) { 2891 struct uint32List *id; 2892 2893 monitor_printf(mon, " groups ["); 2894 for (id = group->group_ids; id; id = id->next) { 2895 monitor_printf(mon, "0x%08x", id->value); 2896 if (id->next) { 2897 monitor_printf(mon, ","); 2898 } 2899 } 2900 monitor_printf(mon, "]"); 2901 } 2902 2903 monitor_printf(mon, "\n"); 2904 } 2905 2906 qapi_free_RockerOfDpaGroupList(list); 2907 } 2908 2909 void hmp_info_ramblock(Monitor *mon, const QDict *qdict) 2910 { 2911 ram_block_dump(mon); 2912 } 2913 2914 void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict) 2915 { 2916 Error *err = NULL; 2917 GuidInfo *info = qmp_query_vm_generation_id(&err); 2918 if (info) { 2919 monitor_printf(mon, "%s\n", info->guid); 2920 } 2921 hmp_handle_error(mon, err); 2922 qapi_free_GuidInfo(info); 2923 } 2924 2925 void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict) 2926 { 2927 Error *err = NULL; 2928 MemoryInfo *info = qmp_query_memory_size_summary(&err); 2929 if (info) { 2930 monitor_printf(mon, "base memory: %" PRIu64 "\n", 2931 info->base_memory); 2932 2933 if (info->has_plugged_memory) { 2934 monitor_printf(mon, "plugged memory: %" PRIu64 "\n", 2935 info->plugged_memory); 2936 } 2937 2938 qapi_free_MemoryInfo(info); 2939 } 2940 hmp_handle_error(mon, err); 2941 } 2942