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 "sysemu/runstate.h" 21 #include "qemu/sockets.h" 22 #include "qemu/help_option.h" 23 #include "monitor/monitor.h" 24 #include "qapi/error.h" 25 #include "qapi/clone-visitor.h" 26 #include "qapi/qapi-builtin-visit.h" 27 #include "qapi/qapi-commands-block.h" 28 #include "qapi/qapi-commands-control.h" 29 #include "qapi/qapi-commands-migration.h" 30 #include "qapi/qapi-commands-misc.h" 31 #include "qapi/qapi-commands-net.h" 32 #include "qapi/qapi-commands-rocker.h" 33 #include "qapi/qapi-commands-run-state.h" 34 #include "qapi/qapi-commands-stats.h" 35 #include "qapi/qapi-commands-tpm.h" 36 #include "qapi/qapi-commands-virtio.h" 37 #include "qapi/qapi-visit-net.h" 38 #include "qapi/qapi-visit-migration.h" 39 #include "qapi/qmp/qdict.h" 40 #include "qapi/qmp/qerror.h" 41 #include "qapi/string-input-visitor.h" 42 #include "qapi/string-output-visitor.h" 43 #include "qemu/cutils.h" 44 #include "qemu/error-report.h" 45 #include "hw/core/cpu.h" 46 #include "hw/intc/intc.h" 47 #include "migration/snapshot.h" 48 #include "migration/misc.h" 49 50 bool hmp_handle_error(Monitor *mon, Error *err) 51 { 52 if (err) { 53 error_reportf_err(err, "Error: "); 54 return true; 55 } 56 return false; 57 } 58 59 /* 60 * Produce a strList from a comma separated list. 61 * A NULL or empty input string return NULL. 62 */ 63 static strList *strList_from_comma_list(const char *in) 64 { 65 strList *res = NULL; 66 strList **tail = &res; 67 68 while (in && in[0]) { 69 char *comma = strchr(in, ','); 70 char *value; 71 72 if (comma) { 73 value = g_strndup(in, comma - in); 74 in = comma + 1; /* skip the , */ 75 } else { 76 value = g_strdup(in); 77 in = NULL; 78 } 79 QAPI_LIST_APPEND(tail, value); 80 } 81 82 return res; 83 } 84 85 void hmp_info_name(Monitor *mon, const QDict *qdict) 86 { 87 NameInfo *info; 88 89 info = qmp_query_name(NULL); 90 if (info->name) { 91 monitor_printf(mon, "%s\n", info->name); 92 } 93 qapi_free_NameInfo(info); 94 } 95 96 void hmp_info_version(Monitor *mon, const QDict *qdict) 97 { 98 VersionInfo *info; 99 100 info = qmp_query_version(NULL); 101 102 monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n", 103 info->qemu->major, info->qemu->minor, info->qemu->micro, 104 info->package); 105 106 qapi_free_VersionInfo(info); 107 } 108 109 void hmp_info_status(Monitor *mon, const QDict *qdict) 110 { 111 StatusInfo *info; 112 113 info = qmp_query_status(NULL); 114 115 monitor_printf(mon, "VM status: %s%s", 116 info->running ? "running" : "paused", 117 info->singlestep ? " (single step mode)" : ""); 118 119 if (!info->running && info->status != RUN_STATE_PAUSED) { 120 monitor_printf(mon, " (%s)", RunState_str(info->status)); 121 } 122 123 monitor_printf(mon, "\n"); 124 125 qapi_free_StatusInfo(info); 126 } 127 128 void hmp_info_migrate(Monitor *mon, const QDict *qdict) 129 { 130 MigrationInfo *info; 131 132 info = qmp_query_migrate(NULL); 133 134 migration_global_dump(mon); 135 136 if (info->blocked_reasons) { 137 strList *reasons = info->blocked_reasons; 138 monitor_printf(mon, "Outgoing migration blocked:\n"); 139 while (reasons) { 140 monitor_printf(mon, " %s\n", reasons->value); 141 reasons = reasons->next; 142 } 143 } 144 145 if (info->has_status) { 146 monitor_printf(mon, "Migration status: %s", 147 MigrationStatus_str(info->status)); 148 if (info->status == MIGRATION_STATUS_FAILED && info->error_desc) { 149 monitor_printf(mon, " (%s)\n", info->error_desc); 150 } else { 151 monitor_printf(mon, "\n"); 152 } 153 154 monitor_printf(mon, "total time: %" PRIu64 " ms\n", 155 info->total_time); 156 if (info->has_expected_downtime) { 157 monitor_printf(mon, "expected downtime: %" PRIu64 " ms\n", 158 info->expected_downtime); 159 } 160 if (info->has_downtime) { 161 monitor_printf(mon, "downtime: %" PRIu64 " ms\n", 162 info->downtime); 163 } 164 if (info->has_setup_time) { 165 monitor_printf(mon, "setup: %" PRIu64 " ms\n", 166 info->setup_time); 167 } 168 } 169 170 if (info->ram) { 171 monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", 172 info->ram->transferred >> 10); 173 monitor_printf(mon, "throughput: %0.2f mbps\n", 174 info->ram->mbps); 175 monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", 176 info->ram->remaining >> 10); 177 monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", 178 info->ram->total >> 10); 179 monitor_printf(mon, "duplicate: %" PRIu64 " pages\n", 180 info->ram->duplicate); 181 monitor_printf(mon, "skipped: %" PRIu64 " pages\n", 182 info->ram->skipped); 183 monitor_printf(mon, "normal: %" PRIu64 " pages\n", 184 info->ram->normal); 185 monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n", 186 info->ram->normal_bytes >> 10); 187 monitor_printf(mon, "dirty sync count: %" PRIu64 "\n", 188 info->ram->dirty_sync_count); 189 monitor_printf(mon, "page size: %" PRIu64 " kbytes\n", 190 info->ram->page_size >> 10); 191 monitor_printf(mon, "multifd bytes: %" PRIu64 " kbytes\n", 192 info->ram->multifd_bytes >> 10); 193 monitor_printf(mon, "pages-per-second: %" PRIu64 "\n", 194 info->ram->pages_per_second); 195 196 if (info->ram->dirty_pages_rate) { 197 monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n", 198 info->ram->dirty_pages_rate); 199 } 200 if (info->ram->postcopy_requests) { 201 monitor_printf(mon, "postcopy request count: %" PRIu64 "\n", 202 info->ram->postcopy_requests); 203 } 204 if (info->ram->precopy_bytes) { 205 monitor_printf(mon, "precopy ram: %" PRIu64 " kbytes\n", 206 info->ram->precopy_bytes >> 10); 207 } 208 if (info->ram->downtime_bytes) { 209 monitor_printf(mon, "downtime ram: %" PRIu64 " kbytes\n", 210 info->ram->downtime_bytes >> 10); 211 } 212 if (info->ram->postcopy_bytes) { 213 monitor_printf(mon, "postcopy ram: %" PRIu64 " kbytes\n", 214 info->ram->postcopy_bytes >> 10); 215 } 216 if (info->ram->dirty_sync_missed_zero_copy) { 217 monitor_printf(mon, 218 "Zero-copy-send fallbacks happened: %" PRIu64 " times\n", 219 info->ram->dirty_sync_missed_zero_copy); 220 } 221 } 222 223 if (info->disk) { 224 monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n", 225 info->disk->transferred >> 10); 226 monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n", 227 info->disk->remaining >> 10); 228 monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n", 229 info->disk->total >> 10); 230 } 231 232 if (info->xbzrle_cache) { 233 monitor_printf(mon, "cache size: %" PRIu64 " bytes\n", 234 info->xbzrle_cache->cache_size); 235 monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n", 236 info->xbzrle_cache->bytes >> 10); 237 monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n", 238 info->xbzrle_cache->pages); 239 monitor_printf(mon, "xbzrle cache miss: %" PRIu64 " pages\n", 240 info->xbzrle_cache->cache_miss); 241 monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n", 242 info->xbzrle_cache->cache_miss_rate); 243 monitor_printf(mon, "xbzrle encoding rate: %0.2f\n", 244 info->xbzrle_cache->encoding_rate); 245 monitor_printf(mon, "xbzrle overflow: %" PRIu64 "\n", 246 info->xbzrle_cache->overflow); 247 } 248 249 if (info->compression) { 250 monitor_printf(mon, "compression pages: %" PRIu64 " pages\n", 251 info->compression->pages); 252 monitor_printf(mon, "compression busy: %" PRIu64 "\n", 253 info->compression->busy); 254 monitor_printf(mon, "compression busy rate: %0.2f\n", 255 info->compression->busy_rate); 256 monitor_printf(mon, "compressed size: %" PRIu64 " kbytes\n", 257 info->compression->compressed_size >> 10); 258 monitor_printf(mon, "compression rate: %0.2f\n", 259 info->compression->compression_rate); 260 } 261 262 if (info->has_cpu_throttle_percentage) { 263 monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n", 264 info->cpu_throttle_percentage); 265 } 266 267 if (info->has_postcopy_blocktime) { 268 monitor_printf(mon, "postcopy blocktime: %u\n", 269 info->postcopy_blocktime); 270 } 271 272 if (info->has_postcopy_vcpu_blocktime) { 273 Visitor *v; 274 char *str; 275 v = string_output_visitor_new(false, &str); 276 visit_type_uint32List(v, NULL, &info->postcopy_vcpu_blocktime, 277 &error_abort); 278 visit_complete(v, &str); 279 monitor_printf(mon, "postcopy vcpu blocktime: %s\n", str); 280 g_free(str); 281 visit_free(v); 282 } 283 if (info->has_socket_address) { 284 SocketAddressList *addr; 285 286 monitor_printf(mon, "socket address: [\n"); 287 288 for (addr = info->socket_address; addr; addr = addr->next) { 289 char *s = socket_uri(addr->value); 290 monitor_printf(mon, "\t%s\n", s); 291 g_free(s); 292 } 293 monitor_printf(mon, "]\n"); 294 } 295 296 if (info->vfio) { 297 monitor_printf(mon, "vfio device transferred: %" PRIu64 " kbytes\n", 298 info->vfio->transferred >> 10); 299 } 300 301 qapi_free_MigrationInfo(info); 302 } 303 304 void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict) 305 { 306 MigrationCapabilityStatusList *caps, *cap; 307 308 caps = qmp_query_migrate_capabilities(NULL); 309 310 if (caps) { 311 for (cap = caps; cap; cap = cap->next) { 312 monitor_printf(mon, "%s: %s\n", 313 MigrationCapability_str(cap->value->capability), 314 cap->value->state ? "on" : "off"); 315 } 316 } 317 318 qapi_free_MigrationCapabilityStatusList(caps); 319 } 320 321 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) 322 { 323 MigrationParameters *params; 324 325 params = qmp_query_migrate_parameters(NULL); 326 327 if (params) { 328 monitor_printf(mon, "%s: %" PRIu64 " ms\n", 329 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL), 330 params->announce_initial); 331 monitor_printf(mon, "%s: %" PRIu64 " ms\n", 332 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX), 333 params->announce_max); 334 monitor_printf(mon, "%s: %" PRIu64 "\n", 335 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS), 336 params->announce_rounds); 337 monitor_printf(mon, "%s: %" PRIu64 " ms\n", 338 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP), 339 params->announce_step); 340 assert(params->has_compress_level); 341 monitor_printf(mon, "%s: %u\n", 342 MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_LEVEL), 343 params->compress_level); 344 assert(params->has_compress_threads); 345 monitor_printf(mon, "%s: %u\n", 346 MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_THREADS), 347 params->compress_threads); 348 assert(params->has_compress_wait_thread); 349 monitor_printf(mon, "%s: %s\n", 350 MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD), 351 params->compress_wait_thread ? "on" : "off"); 352 assert(params->has_decompress_threads); 353 monitor_printf(mon, "%s: %u\n", 354 MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS), 355 params->decompress_threads); 356 assert(params->has_throttle_trigger_threshold); 357 monitor_printf(mon, "%s: %u\n", 358 MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD), 359 params->throttle_trigger_threshold); 360 assert(params->has_cpu_throttle_initial); 361 monitor_printf(mon, "%s: %u\n", 362 MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL), 363 params->cpu_throttle_initial); 364 assert(params->has_cpu_throttle_increment); 365 monitor_printf(mon, "%s: %u\n", 366 MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT), 367 params->cpu_throttle_increment); 368 assert(params->has_cpu_throttle_tailslow); 369 monitor_printf(mon, "%s: %s\n", 370 MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW), 371 params->cpu_throttle_tailslow ? "on" : "off"); 372 assert(params->has_max_cpu_throttle); 373 monitor_printf(mon, "%s: %u\n", 374 MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE), 375 params->max_cpu_throttle); 376 assert(params->tls_creds); 377 monitor_printf(mon, "%s: '%s'\n", 378 MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS), 379 params->tls_creds); 380 assert(params->tls_hostname); 381 monitor_printf(mon, "%s: '%s'\n", 382 MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME), 383 params->tls_hostname); 384 assert(params->has_max_bandwidth); 385 monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n", 386 MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH), 387 params->max_bandwidth); 388 assert(params->has_downtime_limit); 389 monitor_printf(mon, "%s: %" PRIu64 " ms\n", 390 MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT), 391 params->downtime_limit); 392 assert(params->has_x_checkpoint_delay); 393 monitor_printf(mon, "%s: %u ms\n", 394 MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY), 395 params->x_checkpoint_delay); 396 assert(params->has_block_incremental); 397 monitor_printf(mon, "%s: %s\n", 398 MigrationParameter_str(MIGRATION_PARAMETER_BLOCK_INCREMENTAL), 399 params->block_incremental ? "on" : "off"); 400 monitor_printf(mon, "%s: %u\n", 401 MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS), 402 params->multifd_channels); 403 monitor_printf(mon, "%s: %s\n", 404 MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION), 405 MultiFDCompression_str(params->multifd_compression)); 406 monitor_printf(mon, "%s: %" PRIu64 " bytes\n", 407 MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE), 408 params->xbzrle_cache_size); 409 monitor_printf(mon, "%s: %" PRIu64 "\n", 410 MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH), 411 params->max_postcopy_bandwidth); 412 monitor_printf(mon, "%s: '%s'\n", 413 MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ), 414 params->tls_authz); 415 416 if (params->has_block_bitmap_mapping) { 417 const BitmapMigrationNodeAliasList *bmnal; 418 419 monitor_printf(mon, "%s:\n", 420 MigrationParameter_str( 421 MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING)); 422 423 for (bmnal = params->block_bitmap_mapping; 424 bmnal; 425 bmnal = bmnal->next) 426 { 427 const BitmapMigrationNodeAlias *bmna = bmnal->value; 428 const BitmapMigrationBitmapAliasList *bmbal; 429 430 monitor_printf(mon, " '%s' -> '%s'\n", 431 bmna->node_name, bmna->alias); 432 433 for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) { 434 const BitmapMigrationBitmapAlias *bmba = bmbal->value; 435 436 monitor_printf(mon, " '%s' -> '%s'\n", 437 bmba->name, bmba->alias); 438 } 439 } 440 } 441 } 442 443 qapi_free_MigrationParameters(params); 444 } 445 446 static int hmp_info_pic_foreach(Object *obj, void *opaque) 447 { 448 InterruptStatsProvider *intc; 449 InterruptStatsProviderClass *k; 450 Monitor *mon = opaque; 451 452 if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) { 453 intc = INTERRUPT_STATS_PROVIDER(obj); 454 k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj); 455 if (k->print_info) { 456 k->print_info(intc, mon); 457 } else { 458 monitor_printf(mon, "Interrupt controller information not available for %s.\n", 459 object_get_typename(obj)); 460 } 461 } 462 463 return 0; 464 } 465 466 void hmp_info_pic(Monitor *mon, const QDict *qdict) 467 { 468 object_child_foreach_recursive(object_get_root(), 469 hmp_info_pic_foreach, mon); 470 } 471 472 void hmp_info_tpm(Monitor *mon, const QDict *qdict) 473 { 474 #ifdef CONFIG_TPM 475 TPMInfoList *info_list, *info; 476 Error *err = NULL; 477 unsigned int c = 0; 478 TPMPassthroughOptions *tpo; 479 TPMEmulatorOptions *teo; 480 481 info_list = qmp_query_tpm(&err); 482 if (err) { 483 monitor_printf(mon, "TPM device not supported\n"); 484 error_free(err); 485 return; 486 } 487 488 if (info_list) { 489 monitor_printf(mon, "TPM device:\n"); 490 } 491 492 for (info = info_list; info; info = info->next) { 493 TPMInfo *ti = info->value; 494 monitor_printf(mon, " tpm%d: model=%s\n", 495 c, TpmModel_str(ti->model)); 496 497 monitor_printf(mon, " \\ %s: type=%s", 498 ti->id, TpmType_str(ti->options->type)); 499 500 switch (ti->options->type) { 501 case TPM_TYPE_PASSTHROUGH: 502 tpo = ti->options->u.passthrough.data; 503 monitor_printf(mon, "%s%s%s%s", 504 tpo->path ? ",path=" : "", 505 tpo->path ?: "", 506 tpo->cancel_path ? ",cancel-path=" : "", 507 tpo->cancel_path ?: ""); 508 break; 509 case TPM_TYPE_EMULATOR: 510 teo = ti->options->u.emulator.data; 511 monitor_printf(mon, ",chardev=%s", teo->chardev); 512 break; 513 case TPM_TYPE__MAX: 514 break; 515 } 516 monitor_printf(mon, "\n"); 517 c++; 518 } 519 qapi_free_TPMInfoList(info_list); 520 #else 521 monitor_printf(mon, "TPM device not supported\n"); 522 #endif /* CONFIG_TPM */ 523 } 524 525 void hmp_quit(Monitor *mon, const QDict *qdict) 526 { 527 monitor_suspend(mon); 528 qmp_quit(NULL); 529 } 530 531 void hmp_stop(Monitor *mon, const QDict *qdict) 532 { 533 qmp_stop(NULL); 534 } 535 536 void hmp_sync_profile(Monitor *mon, const QDict *qdict) 537 { 538 const char *op = qdict_get_try_str(qdict, "op"); 539 540 if (op == NULL) { 541 bool on = qsp_is_enabled(); 542 543 monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off"); 544 return; 545 } 546 if (!strcmp(op, "on")) { 547 qsp_enable(); 548 } else if (!strcmp(op, "off")) { 549 qsp_disable(); 550 } else if (!strcmp(op, "reset")) { 551 qsp_reset(); 552 } else { 553 Error *err = NULL; 554 555 error_setg(&err, QERR_INVALID_PARAMETER, op); 556 hmp_handle_error(mon, err); 557 } 558 } 559 560 void hmp_exit_preconfig(Monitor *mon, const QDict *qdict) 561 { 562 Error *err = NULL; 563 564 qmp_x_exit_preconfig(&err); 565 hmp_handle_error(mon, err); 566 } 567 568 void hmp_cpu(Monitor *mon, const QDict *qdict) 569 { 570 int64_t cpu_index; 571 572 /* XXX: drop the monitor_set_cpu() usage when all HMP commands that 573 use it are converted to the QAPI */ 574 cpu_index = qdict_get_int(qdict, "index"); 575 if (monitor_set_cpu(mon, cpu_index) < 0) { 576 monitor_printf(mon, "invalid CPU index\n"); 577 } 578 } 579 580 void hmp_cont(Monitor *mon, const QDict *qdict) 581 { 582 Error *err = NULL; 583 584 qmp_cont(&err); 585 hmp_handle_error(mon, err); 586 } 587 588 void hmp_set_link(Monitor *mon, const QDict *qdict) 589 { 590 const char *name = qdict_get_str(qdict, "name"); 591 bool up = qdict_get_bool(qdict, "up"); 592 Error *err = NULL; 593 594 qmp_set_link(name, up, &err); 595 hmp_handle_error(mon, err); 596 } 597 598 void hmp_loadvm(Monitor *mon, const QDict *qdict) 599 { 600 int saved_vm_running = runstate_is_running(); 601 const char *name = qdict_get_str(qdict, "name"); 602 Error *err = NULL; 603 604 vm_stop(RUN_STATE_RESTORE_VM); 605 606 if (load_snapshot(name, NULL, false, NULL, &err) && saved_vm_running) { 607 vm_start(); 608 } 609 hmp_handle_error(mon, err); 610 } 611 612 void hmp_savevm(Monitor *mon, const QDict *qdict) 613 { 614 Error *err = NULL; 615 616 save_snapshot(qdict_get_try_str(qdict, "name"), 617 true, NULL, false, NULL, &err); 618 hmp_handle_error(mon, err); 619 } 620 621 void hmp_delvm(Monitor *mon, const QDict *qdict) 622 { 623 Error *err = NULL; 624 const char *name = qdict_get_str(qdict, "name"); 625 626 delete_snapshot(name, false, NULL, &err); 627 hmp_handle_error(mon, err); 628 } 629 630 void hmp_announce_self(Monitor *mon, const QDict *qdict) 631 { 632 const char *interfaces_str = qdict_get_try_str(qdict, "interfaces"); 633 const char *id = qdict_get_try_str(qdict, "id"); 634 AnnounceParameters *params = QAPI_CLONE(AnnounceParameters, 635 migrate_announce_params()); 636 637 qapi_free_strList(params->interfaces); 638 params->interfaces = strList_from_comma_list(interfaces_str); 639 params->has_interfaces = params->interfaces != NULL; 640 params->id = g_strdup(id); 641 qmp_announce_self(params, NULL); 642 qapi_free_AnnounceParameters(params); 643 } 644 645 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict) 646 { 647 qmp_migrate_cancel(NULL); 648 } 649 650 void hmp_migrate_continue(Monitor *mon, const QDict *qdict) 651 { 652 Error *err = NULL; 653 const char *state = qdict_get_str(qdict, "state"); 654 int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err); 655 656 if (val >= 0) { 657 qmp_migrate_continue(val, &err); 658 } 659 660 hmp_handle_error(mon, err); 661 } 662 663 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict) 664 { 665 Error *err = NULL; 666 const char *uri = qdict_get_str(qdict, "uri"); 667 668 qmp_migrate_incoming(uri, &err); 669 670 hmp_handle_error(mon, err); 671 } 672 673 void hmp_migrate_recover(Monitor *mon, const QDict *qdict) 674 { 675 Error *err = NULL; 676 const char *uri = qdict_get_str(qdict, "uri"); 677 678 qmp_migrate_recover(uri, &err); 679 680 hmp_handle_error(mon, err); 681 } 682 683 void hmp_migrate_pause(Monitor *mon, const QDict *qdict) 684 { 685 Error *err = NULL; 686 687 qmp_migrate_pause(&err); 688 689 hmp_handle_error(mon, err); 690 } 691 692 693 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) 694 { 695 const char *cap = qdict_get_str(qdict, "capability"); 696 bool state = qdict_get_bool(qdict, "state"); 697 Error *err = NULL; 698 MigrationCapabilityStatusList *caps = NULL; 699 MigrationCapabilityStatus *value; 700 int val; 701 702 val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err); 703 if (val < 0) { 704 goto end; 705 } 706 707 value = g_malloc0(sizeof(*value)); 708 value->capability = val; 709 value->state = state; 710 QAPI_LIST_PREPEND(caps, value); 711 qmp_migrate_set_capabilities(caps, &err); 712 qapi_free_MigrationCapabilityStatusList(caps); 713 714 end: 715 hmp_handle_error(mon, err); 716 } 717 718 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) 719 { 720 const char *param = qdict_get_str(qdict, "parameter"); 721 const char *valuestr = qdict_get_str(qdict, "value"); 722 Visitor *v = string_input_visitor_new(valuestr); 723 MigrateSetParameters *p = g_new0(MigrateSetParameters, 1); 724 uint64_t valuebw = 0; 725 uint64_t cache_size; 726 Error *err = NULL; 727 int val, ret; 728 729 val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err); 730 if (val < 0) { 731 goto cleanup; 732 } 733 734 switch (val) { 735 case MIGRATION_PARAMETER_COMPRESS_LEVEL: 736 p->has_compress_level = true; 737 visit_type_uint8(v, param, &p->compress_level, &err); 738 break; 739 case MIGRATION_PARAMETER_COMPRESS_THREADS: 740 p->has_compress_threads = true; 741 visit_type_uint8(v, param, &p->compress_threads, &err); 742 break; 743 case MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD: 744 p->has_compress_wait_thread = true; 745 visit_type_bool(v, param, &p->compress_wait_thread, &err); 746 break; 747 case MIGRATION_PARAMETER_DECOMPRESS_THREADS: 748 p->has_decompress_threads = true; 749 visit_type_uint8(v, param, &p->decompress_threads, &err); 750 break; 751 case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD: 752 p->has_throttle_trigger_threshold = true; 753 visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err); 754 break; 755 case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL: 756 p->has_cpu_throttle_initial = true; 757 visit_type_uint8(v, param, &p->cpu_throttle_initial, &err); 758 break; 759 case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT: 760 p->has_cpu_throttle_increment = true; 761 visit_type_uint8(v, param, &p->cpu_throttle_increment, &err); 762 break; 763 case MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW: 764 p->has_cpu_throttle_tailslow = true; 765 visit_type_bool(v, param, &p->cpu_throttle_tailslow, &err); 766 break; 767 case MIGRATION_PARAMETER_MAX_CPU_THROTTLE: 768 p->has_max_cpu_throttle = true; 769 visit_type_uint8(v, param, &p->max_cpu_throttle, &err); 770 break; 771 case MIGRATION_PARAMETER_TLS_CREDS: 772 p->tls_creds = g_new0(StrOrNull, 1); 773 p->tls_creds->type = QTYPE_QSTRING; 774 visit_type_str(v, param, &p->tls_creds->u.s, &err); 775 break; 776 case MIGRATION_PARAMETER_TLS_HOSTNAME: 777 p->tls_hostname = g_new0(StrOrNull, 1); 778 p->tls_hostname->type = QTYPE_QSTRING; 779 visit_type_str(v, param, &p->tls_hostname->u.s, &err); 780 break; 781 case MIGRATION_PARAMETER_TLS_AUTHZ: 782 p->tls_authz = g_new0(StrOrNull, 1); 783 p->tls_authz->type = QTYPE_QSTRING; 784 visit_type_str(v, param, &p->tls_authz->u.s, &err); 785 break; 786 case MIGRATION_PARAMETER_MAX_BANDWIDTH: 787 p->has_max_bandwidth = true; 788 /* 789 * Can't use visit_type_size() here, because it 790 * defaults to Bytes rather than Mebibytes. 791 */ 792 ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw); 793 if (ret < 0 || valuebw > INT64_MAX 794 || (size_t)valuebw != valuebw) { 795 error_setg(&err, "Invalid size %s", valuestr); 796 break; 797 } 798 p->max_bandwidth = valuebw; 799 break; 800 case MIGRATION_PARAMETER_DOWNTIME_LIMIT: 801 p->has_downtime_limit = true; 802 visit_type_size(v, param, &p->downtime_limit, &err); 803 break; 804 case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY: 805 p->has_x_checkpoint_delay = true; 806 visit_type_uint32(v, param, &p->x_checkpoint_delay, &err); 807 break; 808 case MIGRATION_PARAMETER_BLOCK_INCREMENTAL: 809 p->has_block_incremental = true; 810 visit_type_bool(v, param, &p->block_incremental, &err); 811 break; 812 case MIGRATION_PARAMETER_MULTIFD_CHANNELS: 813 p->has_multifd_channels = true; 814 visit_type_uint8(v, param, &p->multifd_channels, &err); 815 break; 816 case MIGRATION_PARAMETER_MULTIFD_COMPRESSION: 817 p->has_multifd_compression = true; 818 visit_type_MultiFDCompression(v, param, &p->multifd_compression, 819 &err); 820 break; 821 case MIGRATION_PARAMETER_MULTIFD_ZLIB_LEVEL: 822 p->has_multifd_zlib_level = true; 823 visit_type_uint8(v, param, &p->multifd_zlib_level, &err); 824 break; 825 case MIGRATION_PARAMETER_MULTIFD_ZSTD_LEVEL: 826 p->has_multifd_zstd_level = true; 827 visit_type_uint8(v, param, &p->multifd_zstd_level, &err); 828 break; 829 case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE: 830 p->has_xbzrle_cache_size = true; 831 if (!visit_type_size(v, param, &cache_size, &err)) { 832 break; 833 } 834 if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) { 835 error_setg(&err, "Invalid size %s", valuestr); 836 break; 837 } 838 p->xbzrle_cache_size = cache_size; 839 break; 840 case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH: 841 p->has_max_postcopy_bandwidth = true; 842 visit_type_size(v, param, &p->max_postcopy_bandwidth, &err); 843 break; 844 case MIGRATION_PARAMETER_ANNOUNCE_INITIAL: 845 p->has_announce_initial = true; 846 visit_type_size(v, param, &p->announce_initial, &err); 847 break; 848 case MIGRATION_PARAMETER_ANNOUNCE_MAX: 849 p->has_announce_max = true; 850 visit_type_size(v, param, &p->announce_max, &err); 851 break; 852 case MIGRATION_PARAMETER_ANNOUNCE_ROUNDS: 853 p->has_announce_rounds = true; 854 visit_type_size(v, param, &p->announce_rounds, &err); 855 break; 856 case MIGRATION_PARAMETER_ANNOUNCE_STEP: 857 p->has_announce_step = true; 858 visit_type_size(v, param, &p->announce_step, &err); 859 break; 860 case MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING: 861 error_setg(&err, "The block-bitmap-mapping parameter can only be set " 862 "through QMP"); 863 break; 864 default: 865 assert(0); 866 } 867 868 if (err) { 869 goto cleanup; 870 } 871 872 qmp_migrate_set_parameters(p, &err); 873 874 cleanup: 875 qapi_free_MigrateSetParameters(p); 876 visit_free(v); 877 hmp_handle_error(mon, err); 878 } 879 880 void hmp_client_migrate_info(Monitor *mon, const QDict *qdict) 881 { 882 Error *err = NULL; 883 const char *protocol = qdict_get_str(qdict, "protocol"); 884 const char *hostname = qdict_get_str(qdict, "hostname"); 885 bool has_port = qdict_haskey(qdict, "port"); 886 int port = qdict_get_try_int(qdict, "port", -1); 887 bool has_tls_port = qdict_haskey(qdict, "tls-port"); 888 int tls_port = qdict_get_try_int(qdict, "tls-port", -1); 889 const char *cert_subject = qdict_get_try_str(qdict, "cert-subject"); 890 891 qmp_client_migrate_info(protocol, hostname, 892 has_port, port, has_tls_port, tls_port, 893 cert_subject, &err); 894 hmp_handle_error(mon, err); 895 } 896 897 void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict) 898 { 899 Error *err = NULL; 900 qmp_migrate_start_postcopy(&err); 901 hmp_handle_error(mon, err); 902 } 903 904 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict) 905 { 906 Error *err = NULL; 907 908 qmp_x_colo_lost_heartbeat(&err); 909 hmp_handle_error(mon, err); 910 } 911 912 void hmp_change(Monitor *mon, const QDict *qdict) 913 { 914 const char *device = qdict_get_str(qdict, "device"); 915 const char *target = qdict_get_str(qdict, "target"); 916 const char *arg = qdict_get_try_str(qdict, "arg"); 917 const char *read_only = qdict_get_try_str(qdict, "read-only-mode"); 918 bool force = qdict_get_try_bool(qdict, "force", false); 919 BlockdevChangeReadOnlyMode read_only_mode = 0; 920 Error *err = NULL; 921 922 #ifdef CONFIG_VNC 923 if (strcmp(device, "vnc") == 0) { 924 hmp_change_vnc(mon, device, target, arg, read_only, force, &err); 925 } else 926 #endif 927 { 928 if (read_only) { 929 read_only_mode = 930 qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup, 931 read_only, 932 BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err); 933 if (err) { 934 goto end; 935 } 936 } 937 938 qmp_blockdev_change_medium(device, NULL, target, arg, true, force, 939 !!read_only, read_only_mode, 940 &err); 941 } 942 943 end: 944 hmp_handle_error(mon, err); 945 } 946 947 typedef struct HMPMigrationStatus { 948 QEMUTimer *timer; 949 Monitor *mon; 950 bool is_block_migration; 951 } HMPMigrationStatus; 952 953 static void hmp_migrate_status_cb(void *opaque) 954 { 955 HMPMigrationStatus *status = opaque; 956 MigrationInfo *info; 957 958 info = qmp_query_migrate(NULL); 959 if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE || 960 info->status == MIGRATION_STATUS_SETUP) { 961 if (info->disk) { 962 int progress; 963 964 if (info->disk->remaining) { 965 progress = info->disk->transferred * 100 / info->disk->total; 966 } else { 967 progress = 100; 968 } 969 970 monitor_printf(status->mon, "Completed %d %%\r", progress); 971 monitor_flush(status->mon); 972 } 973 974 timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000); 975 } else { 976 if (status->is_block_migration) { 977 monitor_printf(status->mon, "\n"); 978 } 979 if (info->error_desc) { 980 error_report("%s", info->error_desc); 981 } 982 monitor_resume(status->mon); 983 timer_free(status->timer); 984 g_free(status); 985 } 986 987 qapi_free_MigrationInfo(info); 988 } 989 990 void hmp_migrate(Monitor *mon, const QDict *qdict) 991 { 992 bool detach = qdict_get_try_bool(qdict, "detach", false); 993 bool blk = qdict_get_try_bool(qdict, "blk", false); 994 bool inc = qdict_get_try_bool(qdict, "inc", false); 995 bool resume = qdict_get_try_bool(qdict, "resume", false); 996 const char *uri = qdict_get_str(qdict, "uri"); 997 Error *err = NULL; 998 999 qmp_migrate(uri, !!blk, blk, !!inc, inc, 1000 false, false, true, resume, &err); 1001 if (hmp_handle_error(mon, err)) { 1002 return; 1003 } 1004 1005 if (!detach) { 1006 HMPMigrationStatus *status; 1007 1008 if (monitor_suspend(mon) < 0) { 1009 monitor_printf(mon, "terminal does not allow synchronous " 1010 "migration, continuing detached\n"); 1011 return; 1012 } 1013 1014 status = g_malloc0(sizeof(*status)); 1015 status->mon = mon; 1016 status->is_block_migration = blk || inc; 1017 status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb, 1018 status); 1019 timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME)); 1020 } 1021 } 1022 1023 void hmp_netdev_add(Monitor *mon, const QDict *qdict) 1024 { 1025 Error *err = NULL; 1026 QemuOpts *opts; 1027 const char *type = qdict_get_try_str(qdict, "type"); 1028 1029 if (type && is_help_option(type)) { 1030 show_netdevs(); 1031 return; 1032 } 1033 opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err); 1034 if (err) { 1035 goto out; 1036 } 1037 1038 netdev_add(opts, &err); 1039 if (err) { 1040 qemu_opts_del(opts); 1041 } 1042 1043 out: 1044 hmp_handle_error(mon, err); 1045 } 1046 1047 void hmp_netdev_del(Monitor *mon, const QDict *qdict) 1048 { 1049 const char *id = qdict_get_str(qdict, "id"); 1050 Error *err = NULL; 1051 1052 qmp_netdev_del(id, &err); 1053 hmp_handle_error(mon, err); 1054 } 1055 1056 void hmp_getfd(Monitor *mon, const QDict *qdict) 1057 { 1058 const char *fdname = qdict_get_str(qdict, "fdname"); 1059 Error *err = NULL; 1060 1061 qmp_getfd(fdname, &err); 1062 hmp_handle_error(mon, err); 1063 } 1064 1065 void hmp_closefd(Monitor *mon, const QDict *qdict) 1066 { 1067 const char *fdname = qdict_get_str(qdict, "fdname"); 1068 Error *err = NULL; 1069 1070 qmp_closefd(fdname, &err); 1071 hmp_handle_error(mon, err); 1072 } 1073 1074 void hmp_info_iothreads(Monitor *mon, const QDict *qdict) 1075 { 1076 IOThreadInfoList *info_list = qmp_query_iothreads(NULL); 1077 IOThreadInfoList *info; 1078 IOThreadInfo *value; 1079 1080 for (info = info_list; info; info = info->next) { 1081 value = info->value; 1082 monitor_printf(mon, "%s:\n", value->id); 1083 monitor_printf(mon, " thread_id=%" PRId64 "\n", value->thread_id); 1084 monitor_printf(mon, " poll-max-ns=%" PRId64 "\n", value->poll_max_ns); 1085 monitor_printf(mon, " poll-grow=%" PRId64 "\n", value->poll_grow); 1086 monitor_printf(mon, " poll-shrink=%" PRId64 "\n", value->poll_shrink); 1087 monitor_printf(mon, " aio-max-batch=%" PRId64 "\n", 1088 value->aio_max_batch); 1089 } 1090 1091 qapi_free_IOThreadInfoList(info_list); 1092 } 1093 1094 void hmp_rocker(Monitor *mon, const QDict *qdict) 1095 { 1096 const char *name = qdict_get_str(qdict, "name"); 1097 RockerSwitch *rocker; 1098 Error *err = NULL; 1099 1100 rocker = qmp_query_rocker(name, &err); 1101 if (hmp_handle_error(mon, err)) { 1102 return; 1103 } 1104 1105 monitor_printf(mon, "name: %s\n", rocker->name); 1106 monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id); 1107 monitor_printf(mon, "ports: %d\n", rocker->ports); 1108 1109 qapi_free_RockerSwitch(rocker); 1110 } 1111 1112 void hmp_rocker_ports(Monitor *mon, const QDict *qdict) 1113 { 1114 RockerPortList *list, *port; 1115 const char *name = qdict_get_str(qdict, "name"); 1116 Error *err = NULL; 1117 1118 list = qmp_query_rocker_ports(name, &err); 1119 if (hmp_handle_error(mon, err)) { 1120 return; 1121 } 1122 1123 monitor_printf(mon, " ena/ speed/ auto\n"); 1124 monitor_printf(mon, " port link duplex neg?\n"); 1125 1126 for (port = list; port; port = port->next) { 1127 monitor_printf(mon, "%10s %-4s %-3s %2s %s\n", 1128 port->value->name, 1129 port->value->enabled ? port->value->link_up ? 1130 "up" : "down" : "!ena", 1131 port->value->speed == 10000 ? "10G" : "??", 1132 port->value->duplex ? "FD" : "HD", 1133 port->value->autoneg ? "Yes" : "No"); 1134 } 1135 1136 qapi_free_RockerPortList(list); 1137 } 1138 1139 void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict) 1140 { 1141 RockerOfDpaFlowList *list, *info; 1142 const char *name = qdict_get_str(qdict, "name"); 1143 uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1); 1144 Error *err = NULL; 1145 1146 list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err); 1147 if (hmp_handle_error(mon, err)) { 1148 return; 1149 } 1150 1151 monitor_printf(mon, "prio tbl hits key(mask) --> actions\n"); 1152 1153 for (info = list; info; info = info->next) { 1154 RockerOfDpaFlow *flow = info->value; 1155 RockerOfDpaFlowKey *key = flow->key; 1156 RockerOfDpaFlowMask *mask = flow->mask; 1157 RockerOfDpaFlowAction *action = flow->action; 1158 1159 if (flow->hits) { 1160 monitor_printf(mon, "%-4d %-3d %-4" PRIu64, 1161 key->priority, key->tbl_id, flow->hits); 1162 } else { 1163 monitor_printf(mon, "%-4d %-3d ", 1164 key->priority, key->tbl_id); 1165 } 1166 1167 if (key->has_in_pport) { 1168 monitor_printf(mon, " pport %d", key->in_pport); 1169 if (mask->has_in_pport) { 1170 monitor_printf(mon, "(0x%x)", mask->in_pport); 1171 } 1172 } 1173 1174 if (key->has_vlan_id) { 1175 monitor_printf(mon, " vlan %d", 1176 key->vlan_id & VLAN_VID_MASK); 1177 if (mask->has_vlan_id) { 1178 monitor_printf(mon, "(0x%x)", mask->vlan_id); 1179 } 1180 } 1181 1182 if (key->has_tunnel_id) { 1183 monitor_printf(mon, " tunnel %d", key->tunnel_id); 1184 if (mask->has_tunnel_id) { 1185 monitor_printf(mon, "(0x%x)", mask->tunnel_id); 1186 } 1187 } 1188 1189 if (key->has_eth_type) { 1190 switch (key->eth_type) { 1191 case 0x0806: 1192 monitor_printf(mon, " ARP"); 1193 break; 1194 case 0x0800: 1195 monitor_printf(mon, " IP"); 1196 break; 1197 case 0x86dd: 1198 monitor_printf(mon, " IPv6"); 1199 break; 1200 case 0x8809: 1201 monitor_printf(mon, " LACP"); 1202 break; 1203 case 0x88cc: 1204 monitor_printf(mon, " LLDP"); 1205 break; 1206 default: 1207 monitor_printf(mon, " eth type 0x%04x", key->eth_type); 1208 break; 1209 } 1210 } 1211 1212 if (key->eth_src) { 1213 if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) && 1214 mask->eth_src && 1215 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) { 1216 monitor_printf(mon, " src <any mcast/bcast>"); 1217 } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) && 1218 mask->eth_src && 1219 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) { 1220 monitor_printf(mon, " src <any ucast>"); 1221 } else { 1222 monitor_printf(mon, " src %s", key->eth_src); 1223 if (mask->eth_src) { 1224 monitor_printf(mon, "(%s)", mask->eth_src); 1225 } 1226 } 1227 } 1228 1229 if (key->eth_dst) { 1230 if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) && 1231 mask->eth_dst && 1232 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) { 1233 monitor_printf(mon, " dst <any mcast/bcast>"); 1234 } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) && 1235 mask->eth_dst && 1236 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) { 1237 monitor_printf(mon, " dst <any ucast>"); 1238 } else { 1239 monitor_printf(mon, " dst %s", key->eth_dst); 1240 if (mask->eth_dst) { 1241 monitor_printf(mon, "(%s)", mask->eth_dst); 1242 } 1243 } 1244 } 1245 1246 if (key->has_ip_proto) { 1247 monitor_printf(mon, " proto %d", key->ip_proto); 1248 if (mask->has_ip_proto) { 1249 monitor_printf(mon, "(0x%x)", mask->ip_proto); 1250 } 1251 } 1252 1253 if (key->has_ip_tos) { 1254 monitor_printf(mon, " TOS %d", key->ip_tos); 1255 if (mask->has_ip_tos) { 1256 monitor_printf(mon, "(0x%x)", mask->ip_tos); 1257 } 1258 } 1259 1260 if (key->ip_dst) { 1261 monitor_printf(mon, " dst %s", key->ip_dst); 1262 } 1263 1264 if (action->has_goto_tbl || action->has_group_id || 1265 action->has_new_vlan_id) { 1266 monitor_printf(mon, " -->"); 1267 } 1268 1269 if (action->has_new_vlan_id) { 1270 monitor_printf(mon, " apply new vlan %d", 1271 ntohs(action->new_vlan_id)); 1272 } 1273 1274 if (action->has_group_id) { 1275 monitor_printf(mon, " write group 0x%08x", action->group_id); 1276 } 1277 1278 if (action->has_goto_tbl) { 1279 monitor_printf(mon, " goto tbl %d", action->goto_tbl); 1280 } 1281 1282 monitor_printf(mon, "\n"); 1283 } 1284 1285 qapi_free_RockerOfDpaFlowList(list); 1286 } 1287 1288 void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict) 1289 { 1290 RockerOfDpaGroupList *list, *g; 1291 const char *name = qdict_get_str(qdict, "name"); 1292 uint8_t type = qdict_get_try_int(qdict, "type", 9); 1293 Error *err = NULL; 1294 1295 list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err); 1296 if (hmp_handle_error(mon, err)) { 1297 return; 1298 } 1299 1300 monitor_printf(mon, "id (decode) --> buckets\n"); 1301 1302 for (g = list; g; g = g->next) { 1303 RockerOfDpaGroup *group = g->value; 1304 bool set = false; 1305 1306 monitor_printf(mon, "0x%08x", group->id); 1307 1308 monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" : 1309 group->type == 1 ? "L2 rewrite" : 1310 group->type == 2 ? "L3 unicast" : 1311 group->type == 3 ? "L2 multicast" : 1312 group->type == 4 ? "L2 flood" : 1313 group->type == 5 ? "L3 interface" : 1314 group->type == 6 ? "L3 multicast" : 1315 group->type == 7 ? "L3 ECMP" : 1316 group->type == 8 ? "L2 overlay" : 1317 "unknown"); 1318 1319 if (group->has_vlan_id) { 1320 monitor_printf(mon, " vlan %d", group->vlan_id); 1321 } 1322 1323 if (group->has_pport) { 1324 monitor_printf(mon, " pport %d", group->pport); 1325 } 1326 1327 if (group->has_index) { 1328 monitor_printf(mon, " index %d", group->index); 1329 } 1330 1331 monitor_printf(mon, ") -->"); 1332 1333 if (group->has_set_vlan_id && group->set_vlan_id) { 1334 set = true; 1335 monitor_printf(mon, " set vlan %d", 1336 group->set_vlan_id & VLAN_VID_MASK); 1337 } 1338 1339 if (group->set_eth_src) { 1340 if (!set) { 1341 set = true; 1342 monitor_printf(mon, " set"); 1343 } 1344 monitor_printf(mon, " src %s", group->set_eth_src); 1345 } 1346 1347 if (group->set_eth_dst) { 1348 if (!set) { 1349 monitor_printf(mon, " set"); 1350 } 1351 monitor_printf(mon, " dst %s", group->set_eth_dst); 1352 } 1353 1354 if (group->has_ttl_check && group->ttl_check) { 1355 monitor_printf(mon, " check TTL"); 1356 } 1357 1358 if (group->has_group_id && group->group_id) { 1359 monitor_printf(mon, " group id 0x%08x", group->group_id); 1360 } 1361 1362 if (group->has_pop_vlan && group->pop_vlan) { 1363 monitor_printf(mon, " pop vlan"); 1364 } 1365 1366 if (group->has_out_pport) { 1367 monitor_printf(mon, " out pport %d", group->out_pport); 1368 } 1369 1370 if (group->has_group_ids) { 1371 struct uint32List *id; 1372 1373 monitor_printf(mon, " groups ["); 1374 for (id = group->group_ids; id; id = id->next) { 1375 monitor_printf(mon, "0x%08x", id->value); 1376 if (id->next) { 1377 monitor_printf(mon, ","); 1378 } 1379 } 1380 monitor_printf(mon, "]"); 1381 } 1382 1383 monitor_printf(mon, "\n"); 1384 } 1385 1386 qapi_free_RockerOfDpaGroupList(list); 1387 } 1388 1389 static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value) 1390 { 1391 const char *unit = NULL; 1392 monitor_printf(mon, " %s (%s%s", value->name, StatsType_str(value->type), 1393 value->has_unit || value->exponent ? ", " : ""); 1394 1395 if (value->has_unit) { 1396 if (value->unit == STATS_UNIT_SECONDS) { 1397 unit = "s"; 1398 } else if (value->unit == STATS_UNIT_BYTES) { 1399 unit = "B"; 1400 } 1401 } 1402 1403 if (unit && value->base == 10 && 1404 value->exponent >= -18 && value->exponent <= 18 && 1405 value->exponent % 3 == 0) { 1406 monitor_puts(mon, si_prefix(value->exponent)); 1407 } else if (unit && value->base == 2 && 1408 value->exponent >= 0 && value->exponent <= 60 && 1409 value->exponent % 10 == 0) { 1410 1411 monitor_puts(mon, iec_binary_prefix(value->exponent)); 1412 } else if (value->exponent) { 1413 /* Use exponential notation and write the unit's English name */ 1414 monitor_printf(mon, "* %d^%d%s", 1415 value->base, value->exponent, 1416 value->has_unit ? " " : ""); 1417 unit = NULL; 1418 } 1419 1420 if (value->has_unit) { 1421 monitor_puts(mon, unit ? unit : StatsUnit_str(value->unit)); 1422 } 1423 1424 /* Print bucket size for linear histograms */ 1425 if (value->type == STATS_TYPE_LINEAR_HISTOGRAM && value->has_bucket_size) { 1426 monitor_printf(mon, ", bucket size=%d", value->bucket_size); 1427 } 1428 monitor_printf(mon, ")"); 1429 } 1430 1431 static StatsSchemaValueList *find_schema_value_list( 1432 StatsSchemaList *list, StatsProvider provider, 1433 StatsTarget target) 1434 { 1435 StatsSchemaList *node; 1436 1437 for (node = list; node; node = node->next) { 1438 if (node->value->provider == provider && 1439 node->value->target == target) { 1440 return node->value->stats; 1441 } 1442 } 1443 return NULL; 1444 } 1445 1446 static void print_stats_results(Monitor *mon, StatsTarget target, 1447 bool show_provider, 1448 StatsResult *result, 1449 StatsSchemaList *schema) 1450 { 1451 /* Find provider schema */ 1452 StatsSchemaValueList *schema_value_list = 1453 find_schema_value_list(schema, result->provider, target); 1454 StatsList *stats_list; 1455 1456 if (!schema_value_list) { 1457 monitor_printf(mon, "failed to find schema list for %s\n", 1458 StatsProvider_str(result->provider)); 1459 return; 1460 } 1461 1462 if (show_provider) { 1463 monitor_printf(mon, "provider: %s\n", 1464 StatsProvider_str(result->provider)); 1465 } 1466 1467 for (stats_list = result->stats; stats_list; 1468 stats_list = stats_list->next, 1469 schema_value_list = schema_value_list->next) { 1470 1471 Stats *stats = stats_list->value; 1472 StatsValue *stats_value = stats->value; 1473 StatsSchemaValue *schema_value = schema_value_list->value; 1474 1475 /* Find schema entry */ 1476 while (!g_str_equal(stats->name, schema_value->name)) { 1477 if (!schema_value_list->next) { 1478 monitor_printf(mon, "failed to find schema entry for %s\n", 1479 stats->name); 1480 return; 1481 } 1482 schema_value_list = schema_value_list->next; 1483 schema_value = schema_value_list->value; 1484 } 1485 1486 print_stats_schema_value(mon, schema_value); 1487 1488 if (stats_value->type == QTYPE_QNUM) { 1489 monitor_printf(mon, ": %" PRId64 "\n", stats_value->u.scalar); 1490 } else if (stats_value->type == QTYPE_QBOOL) { 1491 monitor_printf(mon, ": %s\n", stats_value->u.boolean ? "yes" : "no"); 1492 } else if (stats_value->type == QTYPE_QLIST) { 1493 uint64List *list; 1494 int i; 1495 1496 monitor_printf(mon, ": "); 1497 for (list = stats_value->u.list, i = 1; 1498 list; 1499 list = list->next, i++) { 1500 monitor_printf(mon, "[%d]=%" PRId64 " ", i, list->value); 1501 } 1502 monitor_printf(mon, "\n"); 1503 } 1504 } 1505 } 1506 1507 /* Create the StatsFilter that is needed for an "info stats" invocation. */ 1508 static StatsFilter *stats_filter(StatsTarget target, const char *names, 1509 int cpu_index, StatsProvider provider) 1510 { 1511 StatsFilter *filter = g_malloc0(sizeof(*filter)); 1512 StatsProvider provider_idx; 1513 StatsRequestList *request_list = NULL; 1514 1515 filter->target = target; 1516 switch (target) { 1517 case STATS_TARGET_VM: 1518 break; 1519 case STATS_TARGET_VCPU: 1520 { 1521 strList *vcpu_list = NULL; 1522 CPUState *cpu = qemu_get_cpu(cpu_index); 1523 char *canonical_path = object_get_canonical_path(OBJECT(cpu)); 1524 1525 QAPI_LIST_PREPEND(vcpu_list, canonical_path); 1526 filter->u.vcpu.has_vcpus = true; 1527 filter->u.vcpu.vcpus = vcpu_list; 1528 break; 1529 } 1530 default: 1531 break; 1532 } 1533 1534 if (!names && provider == STATS_PROVIDER__MAX) { 1535 return filter; 1536 } 1537 1538 /* 1539 * "info stats" can only query either one or all the providers. Querying 1540 * by name, but not by provider, requires the creation of one filter per 1541 * provider. 1542 */ 1543 for (provider_idx = 0; provider_idx < STATS_PROVIDER__MAX; provider_idx++) { 1544 if (provider == STATS_PROVIDER__MAX || provider == provider_idx) { 1545 StatsRequest *request = g_new0(StatsRequest, 1); 1546 request->provider = provider_idx; 1547 if (names && !g_str_equal(names, "*")) { 1548 request->has_names = true; 1549 request->names = strList_from_comma_list(names); 1550 } 1551 QAPI_LIST_PREPEND(request_list, request); 1552 } 1553 } 1554 1555 filter->has_providers = true; 1556 filter->providers = request_list; 1557 return filter; 1558 } 1559 1560 void hmp_info_stats(Monitor *mon, const QDict *qdict) 1561 { 1562 const char *target_str = qdict_get_str(qdict, "target"); 1563 const char *provider_str = qdict_get_try_str(qdict, "provider"); 1564 const char *names = qdict_get_try_str(qdict, "names"); 1565 1566 StatsProvider provider = STATS_PROVIDER__MAX; 1567 StatsTarget target; 1568 Error *err = NULL; 1569 g_autoptr(StatsSchemaList) schema = NULL; 1570 g_autoptr(StatsResultList) stats = NULL; 1571 g_autoptr(StatsFilter) filter = NULL; 1572 StatsResultList *entry; 1573 1574 target = qapi_enum_parse(&StatsTarget_lookup, target_str, -1, &err); 1575 if (err) { 1576 monitor_printf(mon, "invalid stats target %s\n", target_str); 1577 goto exit_no_print; 1578 } 1579 if (provider_str) { 1580 provider = qapi_enum_parse(&StatsProvider_lookup, provider_str, -1, &err); 1581 if (err) { 1582 monitor_printf(mon, "invalid stats provider %s\n", provider_str); 1583 goto exit_no_print; 1584 } 1585 } 1586 1587 schema = qmp_query_stats_schemas(provider_str ? true : false, 1588 provider, &err); 1589 if (err) { 1590 goto exit; 1591 } 1592 1593 switch (target) { 1594 case STATS_TARGET_VM: 1595 filter = stats_filter(target, names, -1, provider); 1596 break; 1597 case STATS_TARGET_VCPU: {} 1598 int cpu_index = monitor_get_cpu_index(mon); 1599 filter = stats_filter(target, names, cpu_index, provider); 1600 break; 1601 default: 1602 abort(); 1603 } 1604 1605 stats = qmp_query_stats(filter, &err); 1606 if (err) { 1607 goto exit; 1608 } 1609 for (entry = stats; entry; entry = entry->next) { 1610 print_stats_results(mon, target, provider_str == NULL, entry->value, schema); 1611 } 1612 1613 exit: 1614 if (err) { 1615 monitor_printf(mon, "%s\n", error_get_pretty(err)); 1616 } 1617 exit_no_print: 1618 error_free(err); 1619 } 1620 1621 static void hmp_virtio_dump_protocols(Monitor *mon, 1622 VhostDeviceProtocols *pcol) 1623 { 1624 strList *pcol_list = pcol->protocols; 1625 while (pcol_list) { 1626 monitor_printf(mon, "\t%s", pcol_list->value); 1627 pcol_list = pcol_list->next; 1628 if (pcol_list != NULL) { 1629 monitor_printf(mon, ",\n"); 1630 } 1631 } 1632 monitor_printf(mon, "\n"); 1633 if (pcol->has_unknown_protocols) { 1634 monitor_printf(mon, " unknown-protocols(0x%016"PRIx64")\n", 1635 pcol->unknown_protocols); 1636 } 1637 } 1638 1639 static void hmp_virtio_dump_status(Monitor *mon, 1640 VirtioDeviceStatus *status) 1641 { 1642 strList *status_list = status->statuses; 1643 while (status_list) { 1644 monitor_printf(mon, "\t%s", status_list->value); 1645 status_list = status_list->next; 1646 if (status_list != NULL) { 1647 monitor_printf(mon, ",\n"); 1648 } 1649 } 1650 monitor_printf(mon, "\n"); 1651 if (status->has_unknown_statuses) { 1652 monitor_printf(mon, " unknown-statuses(0x%016"PRIx32")\n", 1653 status->unknown_statuses); 1654 } 1655 } 1656 1657 static void hmp_virtio_dump_features(Monitor *mon, 1658 VirtioDeviceFeatures *features) 1659 { 1660 strList *transport_list = features->transports; 1661 while (transport_list) { 1662 monitor_printf(mon, "\t%s", transport_list->value); 1663 transport_list = transport_list->next; 1664 if (transport_list != NULL) { 1665 monitor_printf(mon, ",\n"); 1666 } 1667 } 1668 1669 monitor_printf(mon, "\n"); 1670 strList *list = features->dev_features; 1671 if (list) { 1672 while (list) { 1673 monitor_printf(mon, "\t%s", list->value); 1674 list = list->next; 1675 if (list != NULL) { 1676 monitor_printf(mon, ",\n"); 1677 } 1678 } 1679 monitor_printf(mon, "\n"); 1680 } 1681 1682 if (features->has_unknown_dev_features) { 1683 monitor_printf(mon, " unknown-features(0x%016"PRIx64")\n", 1684 features->unknown_dev_features); 1685 } 1686 } 1687 1688 void hmp_virtio_query(Monitor *mon, const QDict *qdict) 1689 { 1690 Error *err = NULL; 1691 VirtioInfoList *list = qmp_x_query_virtio(&err); 1692 VirtioInfoList *node; 1693 1694 if (err != NULL) { 1695 hmp_handle_error(mon, err); 1696 return; 1697 } 1698 1699 if (list == NULL) { 1700 monitor_printf(mon, "No VirtIO devices\n"); 1701 return; 1702 } 1703 1704 node = list; 1705 while (node) { 1706 monitor_printf(mon, "%s [%s]\n", node->value->path, 1707 node->value->name); 1708 node = node->next; 1709 } 1710 qapi_free_VirtioInfoList(list); 1711 } 1712 1713 void hmp_virtio_status(Monitor *mon, const QDict *qdict) 1714 { 1715 Error *err = NULL; 1716 const char *path = qdict_get_try_str(qdict, "path"); 1717 VirtioStatus *s = qmp_x_query_virtio_status(path, &err); 1718 1719 if (err != NULL) { 1720 hmp_handle_error(mon, err); 1721 return; 1722 } 1723 1724 monitor_printf(mon, "%s:\n", path); 1725 monitor_printf(mon, " device_name: %s %s\n", 1726 s->name, s->vhost_dev ? "(vhost)" : ""); 1727 monitor_printf(mon, " device_id: %d\n", s->device_id); 1728 monitor_printf(mon, " vhost_started: %s\n", 1729 s->vhost_started ? "true" : "false"); 1730 monitor_printf(mon, " bus_name: %s\n", s->bus_name); 1731 monitor_printf(mon, " broken: %s\n", 1732 s->broken ? "true" : "false"); 1733 monitor_printf(mon, " disabled: %s\n", 1734 s->disabled ? "true" : "false"); 1735 monitor_printf(mon, " disable_legacy_check: %s\n", 1736 s->disable_legacy_check ? "true" : "false"); 1737 monitor_printf(mon, " started: %s\n", 1738 s->started ? "true" : "false"); 1739 monitor_printf(mon, " use_started: %s\n", 1740 s->use_started ? "true" : "false"); 1741 monitor_printf(mon, " start_on_kick: %s\n", 1742 s->start_on_kick ? "true" : "false"); 1743 monitor_printf(mon, " use_guest_notifier_mask: %s\n", 1744 s->use_guest_notifier_mask ? "true" : "false"); 1745 monitor_printf(mon, " vm_running: %s\n", 1746 s->vm_running ? "true" : "false"); 1747 monitor_printf(mon, " num_vqs: %"PRId64"\n", s->num_vqs); 1748 monitor_printf(mon, " queue_sel: %d\n", 1749 s->queue_sel); 1750 monitor_printf(mon, " isr: %d\n", s->isr); 1751 monitor_printf(mon, " endianness: %s\n", 1752 s->device_endian); 1753 monitor_printf(mon, " status:\n"); 1754 hmp_virtio_dump_status(mon, s->status); 1755 monitor_printf(mon, " Guest features:\n"); 1756 hmp_virtio_dump_features(mon, s->guest_features); 1757 monitor_printf(mon, " Host features:\n"); 1758 hmp_virtio_dump_features(mon, s->host_features); 1759 monitor_printf(mon, " Backend features:\n"); 1760 hmp_virtio_dump_features(mon, s->backend_features); 1761 1762 if (s->vhost_dev) { 1763 monitor_printf(mon, " VHost:\n"); 1764 monitor_printf(mon, " nvqs: %d\n", 1765 s->vhost_dev->nvqs); 1766 monitor_printf(mon, " vq_index: %"PRId64"\n", 1767 s->vhost_dev->vq_index); 1768 monitor_printf(mon, " max_queues: %"PRId64"\n", 1769 s->vhost_dev->max_queues); 1770 monitor_printf(mon, " n_mem_sections: %"PRId64"\n", 1771 s->vhost_dev->n_mem_sections); 1772 monitor_printf(mon, " n_tmp_sections: %"PRId64"\n", 1773 s->vhost_dev->n_tmp_sections); 1774 monitor_printf(mon, " backend_cap: %"PRId64"\n", 1775 s->vhost_dev->backend_cap); 1776 monitor_printf(mon, " log_enabled: %s\n", 1777 s->vhost_dev->log_enabled ? "true" : "false"); 1778 monitor_printf(mon, " log_size: %"PRId64"\n", 1779 s->vhost_dev->log_size); 1780 monitor_printf(mon, " Features:\n"); 1781 hmp_virtio_dump_features(mon, s->vhost_dev->features); 1782 monitor_printf(mon, " Acked features:\n"); 1783 hmp_virtio_dump_features(mon, s->vhost_dev->acked_features); 1784 monitor_printf(mon, " Backend features:\n"); 1785 hmp_virtio_dump_features(mon, s->vhost_dev->backend_features); 1786 monitor_printf(mon, " Protocol features:\n"); 1787 hmp_virtio_dump_protocols(mon, s->vhost_dev->protocol_features); 1788 } 1789 1790 qapi_free_VirtioStatus(s); 1791 } 1792 1793 void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict) 1794 { 1795 Error *err = NULL; 1796 const char *path = qdict_get_try_str(qdict, "path"); 1797 int queue = qdict_get_int(qdict, "queue"); 1798 VirtVhostQueueStatus *s = 1799 qmp_x_query_virtio_vhost_queue_status(path, queue, &err); 1800 1801 if (err != NULL) { 1802 hmp_handle_error(mon, err); 1803 return; 1804 } 1805 1806 monitor_printf(mon, "%s:\n", path); 1807 monitor_printf(mon, " device_name: %s (vhost)\n", 1808 s->name); 1809 monitor_printf(mon, " kick: %"PRId64"\n", s->kick); 1810 monitor_printf(mon, " call: %"PRId64"\n", s->call); 1811 monitor_printf(mon, " VRing:\n"); 1812 monitor_printf(mon, " num: %"PRId64"\n", s->num); 1813 monitor_printf(mon, " desc: 0x%016"PRIx64"\n", s->desc); 1814 monitor_printf(mon, " desc_phys: 0x%016"PRIx64"\n", 1815 s->desc_phys); 1816 monitor_printf(mon, " desc_size: %"PRId32"\n", s->desc_size); 1817 monitor_printf(mon, " avail: 0x%016"PRIx64"\n", s->avail); 1818 monitor_printf(mon, " avail_phys: 0x%016"PRIx64"\n", 1819 s->avail_phys); 1820 monitor_printf(mon, " avail_size: %"PRId32"\n", s->avail_size); 1821 monitor_printf(mon, " used: 0x%016"PRIx64"\n", s->used); 1822 monitor_printf(mon, " used_phys: 0x%016"PRIx64"\n", 1823 s->used_phys); 1824 monitor_printf(mon, " used_size: %"PRId32"\n", s->used_size); 1825 1826 qapi_free_VirtVhostQueueStatus(s); 1827 } 1828 1829 void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict) 1830 { 1831 Error *err = NULL; 1832 const char *path = qdict_get_try_str(qdict, "path"); 1833 int queue = qdict_get_int(qdict, "queue"); 1834 VirtQueueStatus *s = qmp_x_query_virtio_queue_status(path, queue, &err); 1835 1836 if (err != NULL) { 1837 hmp_handle_error(mon, err); 1838 return; 1839 } 1840 1841 monitor_printf(mon, "%s:\n", path); 1842 monitor_printf(mon, " device_name: %s\n", s->name); 1843 monitor_printf(mon, " queue_index: %d\n", s->queue_index); 1844 monitor_printf(mon, " inuse: %d\n", s->inuse); 1845 monitor_printf(mon, " used_idx: %d\n", s->used_idx); 1846 monitor_printf(mon, " signalled_used: %d\n", 1847 s->signalled_used); 1848 monitor_printf(mon, " signalled_used_valid: %s\n", 1849 s->signalled_used_valid ? "true" : "false"); 1850 if (s->has_last_avail_idx) { 1851 monitor_printf(mon, " last_avail_idx: %d\n", 1852 s->last_avail_idx); 1853 } 1854 if (s->has_shadow_avail_idx) { 1855 monitor_printf(mon, " shadow_avail_idx: %d\n", 1856 s->shadow_avail_idx); 1857 } 1858 monitor_printf(mon, " VRing:\n"); 1859 monitor_printf(mon, " num: %"PRId32"\n", s->vring_num); 1860 monitor_printf(mon, " num_default: %"PRId32"\n", 1861 s->vring_num_default); 1862 monitor_printf(mon, " align: %"PRId32"\n", 1863 s->vring_align); 1864 monitor_printf(mon, " desc: 0x%016"PRIx64"\n", 1865 s->vring_desc); 1866 monitor_printf(mon, " avail: 0x%016"PRIx64"\n", 1867 s->vring_avail); 1868 monitor_printf(mon, " used: 0x%016"PRIx64"\n", 1869 s->vring_used); 1870 1871 qapi_free_VirtQueueStatus(s); 1872 } 1873 1874 void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict) 1875 { 1876 Error *err = NULL; 1877 const char *path = qdict_get_try_str(qdict, "path"); 1878 int queue = qdict_get_int(qdict, "queue"); 1879 int index = qdict_get_try_int(qdict, "index", -1); 1880 VirtioQueueElement *e; 1881 VirtioRingDescList *list; 1882 1883 e = qmp_x_query_virtio_queue_element(path, queue, index != -1, 1884 index, &err); 1885 if (err != NULL) { 1886 hmp_handle_error(mon, err); 1887 return; 1888 } 1889 1890 monitor_printf(mon, "%s:\n", path); 1891 monitor_printf(mon, " device_name: %s\n", e->name); 1892 monitor_printf(mon, " index: %d\n", e->index); 1893 monitor_printf(mon, " desc:\n"); 1894 monitor_printf(mon, " descs:\n"); 1895 1896 list = e->descs; 1897 while (list) { 1898 monitor_printf(mon, " addr 0x%"PRIx64" len %d", 1899 list->value->addr, list->value->len); 1900 if (list->value->flags) { 1901 strList *flag = list->value->flags; 1902 monitor_printf(mon, " ("); 1903 while (flag) { 1904 monitor_printf(mon, "%s", flag->value); 1905 flag = flag->next; 1906 if (flag) { 1907 monitor_printf(mon, ", "); 1908 } 1909 } 1910 monitor_printf(mon, ")"); 1911 } 1912 list = list->next; 1913 if (list) { 1914 monitor_printf(mon, ",\n"); 1915 } 1916 } 1917 monitor_printf(mon, "\n"); 1918 monitor_printf(mon, " avail:\n"); 1919 monitor_printf(mon, " flags: %d\n", e->avail->flags); 1920 monitor_printf(mon, " idx: %d\n", e->avail->idx); 1921 monitor_printf(mon, " ring: %d\n", e->avail->ring); 1922 monitor_printf(mon, " used:\n"); 1923 monitor_printf(mon, " flags: %d\n", e->used->flags); 1924 monitor_printf(mon, " idx: %d\n", e->used->idx); 1925 1926 qapi_free_VirtioQueueElement(e); 1927 } 1928