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