qemu/hmp.c
<<
>>
Prefs
   1/*
   2 * Human Monitor Interface
   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 "hmp.h"
  18#include "net/net.h"
  19#include "net/eth.h"
  20#include "sysemu/char.h"
  21#include "sysemu/block-backend.h"
  22#include "qemu/option.h"
  23#include "qemu/timer.h"
  24#include "qmp-commands.h"
  25#include "qemu/sockets.h"
  26#include "monitor/monitor.h"
  27#include "monitor/qdev.h"
  28#include "qapi/opts-visitor.h"
  29#include "qapi/qmp/qerror.h"
  30#include "qapi/string-output-visitor.h"
  31#include "qapi/util.h"
  32#include "qapi-visit.h"
  33#include "qom/object_interfaces.h"
  34#include "ui/console.h"
  35#include "block/qapi.h"
  36#include "qemu-io.h"
  37#include "qemu/cutils.h"
  38
  39#ifdef CONFIG_SPICE
  40#include <spice/enums.h>
  41#endif
  42
  43static void hmp_handle_error(Monitor *mon, Error **errp)
  44{
  45    assert(errp);
  46    if (*errp) {
  47        error_report_err(*errp);
  48    }
  49}
  50
  51void hmp_info_name(Monitor *mon, const QDict *qdict)
  52{
  53    NameInfo *info;
  54
  55    info = qmp_query_name(NULL);
  56    if (info->has_name) {
  57        monitor_printf(mon, "%s\n", info->name);
  58    }
  59    qapi_free_NameInfo(info);
  60}
  61
  62void hmp_info_version(Monitor *mon, const QDict *qdict)
  63{
  64    VersionInfo *info;
  65
  66    info = qmp_query_version(NULL);
  67
  68    monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
  69                   info->qemu->major, info->qemu->minor, info->qemu->micro,
  70                   info->package);
  71
  72    qapi_free_VersionInfo(info);
  73}
  74
  75void hmp_info_kvm(Monitor *mon, const QDict *qdict)
  76{
  77    KvmInfo *info;
  78
  79    info = qmp_query_kvm(NULL);
  80    monitor_printf(mon, "kvm support: ");
  81    if (info->present) {
  82        monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
  83    } else {
  84        monitor_printf(mon, "not compiled\n");
  85    }
  86
  87    qapi_free_KvmInfo(info);
  88}
  89
  90void hmp_info_status(Monitor *mon, const QDict *qdict)
  91{
  92    StatusInfo *info;
  93
  94    info = qmp_query_status(NULL);
  95
  96    monitor_printf(mon, "VM status: %s%s",
  97                   info->running ? "running" : "paused",
  98                   info->singlestep ? " (single step mode)" : "");
  99
 100    if (!info->running && info->status != RUN_STATE_PAUSED) {
 101        monitor_printf(mon, " (%s)", RunState_lookup[info->status]);
 102    }
 103
 104    monitor_printf(mon, "\n");
 105
 106    qapi_free_StatusInfo(info);
 107}
 108
 109void hmp_info_uuid(Monitor *mon, const QDict *qdict)
 110{
 111    UuidInfo *info;
 112
 113    info = qmp_query_uuid(NULL);
 114    monitor_printf(mon, "%s\n", info->UUID);
 115    qapi_free_UuidInfo(info);
 116}
 117
 118void hmp_info_chardev(Monitor *mon, const QDict *qdict)
 119{
 120    ChardevInfoList *char_info, *info;
 121
 122    char_info = qmp_query_chardev(NULL);
 123    for (info = char_info; info; info = info->next) {
 124        monitor_printf(mon, "%s: filename=%s\n", info->value->label,
 125                                                 info->value->filename);
 126    }
 127
 128    qapi_free_ChardevInfoList(char_info);
 129}
 130
 131void hmp_info_mice(Monitor *mon, const QDict *qdict)
 132{
 133    MouseInfoList *mice_list, *mouse;
 134
 135    mice_list = qmp_query_mice(NULL);
 136    if (!mice_list) {
 137        monitor_printf(mon, "No mouse devices connected\n");
 138        return;
 139    }
 140
 141    for (mouse = mice_list; mouse; mouse = mouse->next) {
 142        monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
 143                       mouse->value->current ? '*' : ' ',
 144                       mouse->value->index, mouse->value->name,
 145                       mouse->value->absolute ? " (absolute)" : "");
 146    }
 147
 148    qapi_free_MouseInfoList(mice_list);
 149}
 150
 151void hmp_info_migrate(Monitor *mon, const QDict *qdict)
 152{
 153    MigrationInfo *info;
 154    MigrationCapabilityStatusList *caps, *cap;
 155
 156    info = qmp_query_migrate(NULL);
 157    caps = qmp_query_migrate_capabilities(NULL);
 158
 159    /* do not display parameters during setup */
 160    if (info->has_status && caps) {
 161        monitor_printf(mon, "capabilities: ");
 162        for (cap = caps; cap; cap = cap->next) {
 163            monitor_printf(mon, "%s: %s ",
 164                           MigrationCapability_lookup[cap->value->capability],
 165                           cap->value->state ? "on" : "off");
 166        }
 167        monitor_printf(mon, "\n");
 168    }
 169
 170    if (info->has_status) {
 171        monitor_printf(mon, "Migration status: %s\n",
 172                       MigrationStatus_lookup[info->status]);
 173        monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
 174                       info->total_time);
 175        if (info->has_expected_downtime) {
 176            monitor_printf(mon, "expected downtime: %" PRIu64 " milliseconds\n",
 177                           info->expected_downtime);
 178        }
 179        if (info->has_downtime) {
 180            monitor_printf(mon, "downtime: %" PRIu64 " milliseconds\n",
 181                           info->downtime);
 182        }
 183        if (info->has_setup_time) {
 184            monitor_printf(mon, "setup: %" PRIu64 " milliseconds\n",
 185                           info->setup_time);
 186        }
 187    }
 188
 189    if (info->has_ram) {
 190        monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n",
 191                       info->ram->transferred >> 10);
 192        monitor_printf(mon, "throughput: %0.2f mbps\n",
 193                       info->ram->mbps);
 194        monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n",
 195                       info->ram->remaining >> 10);
 196        monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n",
 197                       info->ram->total >> 10);
 198        monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
 199                       info->ram->duplicate);
 200        monitor_printf(mon, "skipped: %" PRIu64 " pages\n",
 201                       info->ram->skipped);
 202        monitor_printf(mon, "normal: %" PRIu64 " pages\n",
 203                       info->ram->normal);
 204        monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
 205                       info->ram->normal_bytes >> 10);
 206        monitor_printf(mon, "dirty sync count: %" PRIu64 "\n",
 207                       info->ram->dirty_sync_count);
 208        if (info->ram->dirty_pages_rate) {
 209            monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
 210                           info->ram->dirty_pages_rate);
 211        }
 212    }
 213
 214    if (info->has_disk) {
 215        monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n",
 216                       info->disk->transferred >> 10);
 217        monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n",
 218                       info->disk->remaining >> 10);
 219        monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n",
 220                       info->disk->total >> 10);
 221    }
 222
 223    if (info->has_xbzrle_cache) {
 224        monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
 225                       info->xbzrle_cache->cache_size);
 226        monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
 227                       info->xbzrle_cache->bytes >> 10);
 228        monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
 229                       info->xbzrle_cache->pages);
 230        monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
 231                       info->xbzrle_cache->cache_miss);
 232        monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
 233                       info->xbzrle_cache->cache_miss_rate);
 234        monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
 235                       info->xbzrle_cache->overflow);
 236    }
 237
 238    if (info->has_x_cpu_throttle_percentage) {
 239        monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n",
 240                       info->x_cpu_throttle_percentage);
 241    }
 242
 243    qapi_free_MigrationInfo(info);
 244    qapi_free_MigrationCapabilityStatusList(caps);
 245}
 246
 247void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
 248{
 249    MigrationCapabilityStatusList *caps, *cap;
 250
 251    caps = qmp_query_migrate_capabilities(NULL);
 252
 253    if (caps) {
 254        monitor_printf(mon, "capabilities: ");
 255        for (cap = caps; cap; cap = cap->next) {
 256            monitor_printf(mon, "%s: %s ",
 257                           MigrationCapability_lookup[cap->value->capability],
 258                           cap->value->state ? "on" : "off");
 259        }
 260        monitor_printf(mon, "\n");
 261    }
 262
 263    qapi_free_MigrationCapabilityStatusList(caps);
 264}
 265
 266void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
 267{
 268    MigrationParameters *params;
 269
 270    params = qmp_query_migrate_parameters(NULL);
 271
 272    if (params) {
 273        monitor_printf(mon, "parameters:");
 274        monitor_printf(mon, " %s: %" PRId64,
 275            MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_LEVEL],
 276            params->compress_level);
 277        monitor_printf(mon, " %s: %" PRId64,
 278            MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_THREADS],
 279            params->compress_threads);
 280        monitor_printf(mon, " %s: %" PRId64,
 281            MigrationParameter_lookup[MIGRATION_PARAMETER_DECOMPRESS_THREADS],
 282            params->decompress_threads);
 283        monitor_printf(mon, " %s: %" PRId64,
 284            MigrationParameter_lookup[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL],
 285            params->x_cpu_throttle_initial);
 286        monitor_printf(mon, " %s: %" PRId64,
 287            MigrationParameter_lookup[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT],
 288            params->x_cpu_throttle_increment);
 289        monitor_printf(mon, "\n");
 290    }
 291
 292    qapi_free_MigrationParameters(params);
 293}
 294
 295void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
 296{
 297    monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n",
 298                   qmp_query_migrate_cache_size(NULL) >> 10);
 299}
 300
 301void hmp_info_cpus(Monitor *mon, const QDict *qdict)
 302{
 303    CpuInfoList *cpu_list, *cpu;
 304
 305    cpu_list = qmp_query_cpus(NULL);
 306
 307    for (cpu = cpu_list; cpu; cpu = cpu->next) {
 308        int active = ' ';
 309
 310        if (cpu->value->CPU == monitor_get_cpu_index()) {
 311            active = '*';
 312        }
 313
 314        monitor_printf(mon, "%c CPU #%" PRId64 ":", active, cpu->value->CPU);
 315
 316        switch (cpu->value->arch) {
 317        case CPU_INFO_ARCH_X86:
 318            monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->u.x86.pc);
 319            break;
 320        case CPU_INFO_ARCH_PPC:
 321            monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->u.ppc.nip);
 322            break;
 323        case CPU_INFO_ARCH_SPARC:
 324            monitor_printf(mon, " pc=0x%016" PRIx64,
 325                           cpu->value->u.q_sparc.pc);
 326            monitor_printf(mon, " npc=0x%016" PRIx64,
 327                           cpu->value->u.q_sparc.npc);
 328            break;
 329        case CPU_INFO_ARCH_MIPS:
 330            monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.q_mips.PC);
 331            break;
 332        case CPU_INFO_ARCH_TRICORE:
 333            monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.tricore.PC);
 334            break;
 335        default:
 336            break;
 337        }
 338
 339        if (cpu->value->halted) {
 340            monitor_printf(mon, " (halted)");
 341        }
 342
 343        monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id);
 344    }
 345
 346    qapi_free_CpuInfoList(cpu_list);
 347}
 348
 349static void print_block_info(Monitor *mon, BlockInfo *info,
 350                             BlockDeviceInfo *inserted, bool verbose)
 351{
 352    ImageInfo *image_info;
 353
 354    assert(!info || !info->has_inserted || info->inserted == inserted);
 355
 356    if (info) {
 357        monitor_printf(mon, "%s", info->device);
 358        if (inserted && inserted->has_node_name) {
 359            monitor_printf(mon, " (%s)", inserted->node_name);
 360        }
 361    } else {
 362        assert(inserted);
 363        monitor_printf(mon, "%s",
 364                       inserted->has_node_name
 365                       ? inserted->node_name
 366                       : "<anonymous>");
 367    }
 368
 369    if (inserted) {
 370        monitor_printf(mon, ": %s (%s%s%s)\n",
 371                       inserted->file,
 372                       inserted->drv,
 373                       inserted->ro ? ", read-only" : "",
 374                       inserted->encrypted ? ", encrypted" : "");
 375    } else {
 376        monitor_printf(mon, ": [not inserted]\n");
 377    }
 378
 379    if (info) {
 380        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
 381            monitor_printf(mon, "    I/O status:       %s\n",
 382                           BlockDeviceIoStatus_lookup[info->io_status]);
 383        }
 384
 385        if (info->removable) {
 386            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
 387                           info->locked ? "" : "not ",
 388                           info->tray_open ? "open" : "closed");
 389        }
 390    }
 391
 392
 393    if (!inserted) {
 394        return;
 395    }
 396
 397    monitor_printf(mon, "    Cache mode:       %s%s%s\n",
 398                   inserted->cache->writeback ? "writeback" : "writethrough",
 399                   inserted->cache->direct ? ", direct" : "",
 400                   inserted->cache->no_flush ? ", ignore flushes" : "");
 401
 402    if (inserted->has_backing_file) {
 403        monitor_printf(mon,
 404                       "    Backing file:     %s "
 405                       "(chain depth: %" PRId64 ")\n",
 406                       inserted->backing_file,
 407                       inserted->backing_file_depth);
 408    }
 409
 410    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
 411        monitor_printf(mon, "    Detect zeroes:    %s\n",
 412                       BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]);
 413    }
 414
 415    if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
 416        inserted->iops || inserted->iops_rd || inserted->iops_wr)
 417    {
 418        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
 419                        " bps_rd=%" PRId64  " bps_wr=%" PRId64
 420                        " bps_max=%" PRId64
 421                        " bps_rd_max=%" PRId64
 422                        " bps_wr_max=%" PRId64
 423                        " iops=%" PRId64 " iops_rd=%" PRId64
 424                        " iops_wr=%" PRId64
 425                        " iops_max=%" PRId64
 426                        " iops_rd_max=%" PRId64
 427                        " iops_wr_max=%" PRId64
 428                        " iops_size=%" PRId64
 429                        " group=%s\n",
 430                        inserted->bps,
 431                        inserted->bps_rd,
 432                        inserted->bps_wr,
 433                        inserted->bps_max,
 434                        inserted->bps_rd_max,
 435                        inserted->bps_wr_max,
 436                        inserted->iops,
 437                        inserted->iops_rd,
 438                        inserted->iops_wr,
 439                        inserted->iops_max,
 440                        inserted->iops_rd_max,
 441                        inserted->iops_wr_max,
 442                        inserted->iops_size,
 443                        inserted->group);
 444    }
 445
 446    if (verbose) {
 447        monitor_printf(mon, "\nImages:\n");
 448        image_info = inserted->image;
 449        while (1) {
 450                bdrv_image_info_dump((fprintf_function)monitor_printf,
 451                                     mon, image_info);
 452            if (image_info->has_backing_image) {
 453                image_info = image_info->backing_image;
 454            } else {
 455                break;
 456            }
 457        }
 458    }
 459}
 460
 461void hmp_info_block(Monitor *mon, const QDict *qdict)
 462{
 463    BlockInfoList *block_list, *info;
 464    BlockDeviceInfoList *blockdev_list, *blockdev;
 465    const char *device = qdict_get_try_str(qdict, "device");
 466    bool verbose = qdict_get_try_bool(qdict, "verbose", false);
 467    bool nodes = qdict_get_try_bool(qdict, "nodes", false);
 468    bool printed = false;
 469
 470    /* Print BlockBackend information */
 471    if (!nodes) {
 472        block_list = qmp_query_block(NULL);
 473    } else {
 474        block_list = NULL;
 475    }
 476
 477    for (info = block_list; info; info = info->next) {
 478        if (device && strcmp(device, info->value->device)) {
 479            continue;
 480        }
 481
 482        if (info != block_list) {
 483            monitor_printf(mon, "\n");
 484        }
 485
 486        print_block_info(mon, info->value, info->value->has_inserted
 487                                           ? info->value->inserted : NULL,
 488                         verbose);
 489        printed = true;
 490    }
 491
 492    qapi_free_BlockInfoList(block_list);
 493
 494    if ((!device && !nodes) || printed) {
 495        return;
 496    }
 497
 498    /* Print node information */
 499    blockdev_list = qmp_query_named_block_nodes(NULL);
 500    for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
 501        assert(blockdev->value->has_node_name);
 502        if (device && strcmp(device, blockdev->value->node_name)) {
 503            continue;
 504        }
 505
 506        if (blockdev != blockdev_list) {
 507            monitor_printf(mon, "\n");
 508        }
 509
 510        print_block_info(mon, NULL, blockdev->value, verbose);
 511    }
 512    qapi_free_BlockDeviceInfoList(blockdev_list);
 513}
 514
 515void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
 516{
 517    BlockStatsList *stats_list, *stats;
 518
 519    stats_list = qmp_query_blockstats(false, false, NULL);
 520
 521    for (stats = stats_list; stats; stats = stats->next) {
 522        if (!stats->value->has_device) {
 523            continue;
 524        }
 525
 526        monitor_printf(mon, "%s:", stats->value->device);
 527        monitor_printf(mon, " rd_bytes=%" PRId64
 528                       " wr_bytes=%" PRId64
 529                       " rd_operations=%" PRId64
 530                       " wr_operations=%" PRId64
 531                       " flush_operations=%" PRId64
 532                       " wr_total_time_ns=%" PRId64
 533                       " rd_total_time_ns=%" PRId64
 534                       " flush_total_time_ns=%" PRId64
 535                       " rd_merged=%" PRId64
 536                       " wr_merged=%" PRId64
 537                       " idle_time_ns=%" PRId64
 538                       "\n",
 539                       stats->value->stats->rd_bytes,
 540                       stats->value->stats->wr_bytes,
 541                       stats->value->stats->rd_operations,
 542                       stats->value->stats->wr_operations,
 543                       stats->value->stats->flush_operations,
 544                       stats->value->stats->wr_total_time_ns,
 545                       stats->value->stats->rd_total_time_ns,
 546                       stats->value->stats->flush_total_time_ns,
 547                       stats->value->stats->rd_merged,
 548                       stats->value->stats->wr_merged,
 549                       stats->value->stats->idle_time_ns);
 550    }
 551
 552    qapi_free_BlockStatsList(stats_list);
 553}
 554
 555void hmp_info_vnc(Monitor *mon, const QDict *qdict)
 556{
 557    VncInfo *info;
 558    Error *err = NULL;
 559    VncClientInfoList *client;
 560
 561    info = qmp_query_vnc(&err);
 562    if (err) {
 563        error_report_err(err);
 564        return;
 565    }
 566
 567    if (!info->enabled) {
 568        monitor_printf(mon, "Server: disabled\n");
 569        goto out;
 570    }
 571
 572    monitor_printf(mon, "Server:\n");
 573    if (info->has_host && info->has_service) {
 574        monitor_printf(mon, "     address: %s:%s\n", info->host, info->service);
 575    }
 576    if (info->has_auth) {
 577        monitor_printf(mon, "        auth: %s\n", info->auth);
 578    }
 579
 580    if (!info->has_clients || info->clients == NULL) {
 581        monitor_printf(mon, "Client: none\n");
 582    } else {
 583        for (client = info->clients; client; client = client->next) {
 584            monitor_printf(mon, "Client:\n");
 585            monitor_printf(mon, "     address: %s:%s\n",
 586                           client->value->host,
 587                           client->value->service);
 588            monitor_printf(mon, "  x509_dname: %s\n",
 589                           client->value->x509_dname ?
 590                           client->value->x509_dname : "none");
 591            monitor_printf(mon, "    username: %s\n",
 592                           client->value->has_sasl_username ?
 593                           client->value->sasl_username : "none");
 594        }
 595    }
 596
 597out:
 598    qapi_free_VncInfo(info);
 599}
 600
 601#ifdef CONFIG_SPICE
 602void hmp_info_spice(Monitor *mon, const QDict *qdict)
 603{
 604    SpiceChannelList *chan;
 605    SpiceInfo *info;
 606    const char *channel_name;
 607    const char * const channel_names[] = {
 608        [SPICE_CHANNEL_MAIN] = "main",
 609        [SPICE_CHANNEL_DISPLAY] = "display",
 610        [SPICE_CHANNEL_INPUTS] = "inputs",
 611        [SPICE_CHANNEL_CURSOR] = "cursor",
 612        [SPICE_CHANNEL_PLAYBACK] = "playback",
 613        [SPICE_CHANNEL_RECORD] = "record",
 614        [SPICE_CHANNEL_TUNNEL] = "tunnel",
 615        [SPICE_CHANNEL_SMARTCARD] = "smartcard",
 616        [SPICE_CHANNEL_USBREDIR] = "usbredir",
 617        [SPICE_CHANNEL_PORT] = "port",
 618#if 0
 619        /* minimum spice-protocol is 0.12.3, webdav was added in 0.12.7,
 620         * no easy way to #ifdef (SPICE_CHANNEL_* is a enum).  Disable
 621         * as quick fix for build failures with older versions. */
 622        [SPICE_CHANNEL_WEBDAV] = "webdav",
 623#endif
 624    };
 625
 626    info = qmp_query_spice(NULL);
 627
 628    if (!info->enabled) {
 629        monitor_printf(mon, "Server: disabled\n");
 630        goto out;
 631    }
 632
 633    monitor_printf(mon, "Server:\n");
 634    if (info->has_port) {
 635        monitor_printf(mon, "     address: %s:%" PRId64 "\n",
 636                       info->host, info->port);
 637    }
 638    if (info->has_tls_port) {
 639        monitor_printf(mon, "     address: %s:%" PRId64 " [tls]\n",
 640                       info->host, info->tls_port);
 641    }
 642    monitor_printf(mon, "    migrated: %s\n",
 643                   info->migrated ? "true" : "false");
 644    monitor_printf(mon, "        auth: %s\n", info->auth);
 645    monitor_printf(mon, "    compiled: %s\n", info->compiled_version);
 646    monitor_printf(mon, "  mouse-mode: %s\n",
 647                   SpiceQueryMouseMode_lookup[info->mouse_mode]);
 648
 649    if (!info->has_channels || info->channels == NULL) {
 650        monitor_printf(mon, "Channels: none\n");
 651    } else {
 652        for (chan = info->channels; chan; chan = chan->next) {
 653            monitor_printf(mon, "Channel:\n");
 654            monitor_printf(mon, "     address: %s:%s%s\n",
 655                           chan->value->host, chan->value->port,
 656                           chan->value->tls ? " [tls]" : "");
 657            monitor_printf(mon, "     session: %" PRId64 "\n",
 658                           chan->value->connection_id);
 659            monitor_printf(mon, "     channel: %" PRId64 ":%" PRId64 "\n",
 660                           chan->value->channel_type, chan->value->channel_id);
 661
 662            channel_name = "unknown";
 663            if (chan->value->channel_type > 0 &&
 664                chan->value->channel_type < ARRAY_SIZE(channel_names) &&
 665                channel_names[chan->value->channel_type]) {
 666                channel_name = channel_names[chan->value->channel_type];
 667            }
 668
 669            monitor_printf(mon, "     channel name: %s\n", channel_name);
 670        }
 671    }
 672
 673out:
 674    qapi_free_SpiceInfo(info);
 675}
 676#endif
 677
 678void hmp_info_balloon(Monitor *mon, const QDict *qdict)
 679{
 680    BalloonInfo *info;
 681    Error *err = NULL;
 682
 683    info = qmp_query_balloon(&err);
 684    if (err) {
 685        error_report_err(err);
 686        return;
 687    }
 688
 689    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
 690
 691    qapi_free_BalloonInfo(info);
 692}
 693
 694static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
 695{
 696    PciMemoryRegionList *region;
 697
 698    monitor_printf(mon, "  Bus %2" PRId64 ", ", dev->bus);
 699    monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n",
 700                   dev->slot, dev->function);
 701    monitor_printf(mon, "    ");
 702
 703    if (dev->class_info->has_desc) {
 704        monitor_printf(mon, "%s", dev->class_info->desc);
 705    } else {
 706        monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class);
 707    }
 708
 709    monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
 710                   dev->id->vendor, dev->id->device);
 711
 712    if (dev->has_irq) {
 713        monitor_printf(mon, "      IRQ %" PRId64 ".\n", dev->irq);
 714    }
 715
 716    if (dev->has_pci_bridge) {
 717        monitor_printf(mon, "      BUS %" PRId64 ".\n",
 718                       dev->pci_bridge->bus->number);
 719        monitor_printf(mon, "      secondary bus %" PRId64 ".\n",
 720                       dev->pci_bridge->bus->secondary);
 721        monitor_printf(mon, "      subordinate bus %" PRId64 ".\n",
 722                       dev->pci_bridge->bus->subordinate);
 723
 724        monitor_printf(mon, "      IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n",
 725                       dev->pci_bridge->bus->io_range->base,
 726                       dev->pci_bridge->bus->io_range->limit);
 727
 728        monitor_printf(mon,
 729                       "      memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
 730                       dev->pci_bridge->bus->memory_range->base,
 731                       dev->pci_bridge->bus->memory_range->limit);
 732
 733        monitor_printf(mon, "      prefetchable memory range "
 734                       "[0x%08"PRIx64", 0x%08"PRIx64"]\n",
 735                       dev->pci_bridge->bus->prefetchable_range->base,
 736                       dev->pci_bridge->bus->prefetchable_range->limit);
 737    }
 738
 739    for (region = dev->regions; region; region = region->next) {
 740        uint64_t addr, size;
 741
 742        addr = region->value->address;
 743        size = region->value->size;
 744
 745        monitor_printf(mon, "      BAR%" PRId64 ": ", region->value->bar);
 746
 747        if (!strcmp(region->value->type, "io")) {
 748            monitor_printf(mon, "I/O at 0x%04" PRIx64
 749                                " [0x%04" PRIx64 "].\n",
 750                           addr, addr + size - 1);
 751        } else {
 752            monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64
 753                               " [0x%08" PRIx64 "].\n",
 754                           region->value->mem_type_64 ? 64 : 32,
 755                           region->value->prefetch ? " prefetchable" : "",
 756                           addr, addr + size - 1);
 757        }
 758    }
 759
 760    monitor_printf(mon, "      id \"%s\"\n", dev->qdev_id);
 761
 762    if (dev->has_pci_bridge) {
 763        if (dev->pci_bridge->has_devices) {
 764            PciDeviceInfoList *cdev;
 765            for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) {
 766                hmp_info_pci_device(mon, cdev->value);
 767            }
 768        }
 769    }
 770}
 771
 772void hmp_info_pci(Monitor *mon, const QDict *qdict)
 773{
 774    PciInfoList *info_list, *info;
 775    Error *err = NULL;
 776
 777    info_list = qmp_query_pci(&err);
 778    if (err) {
 779        monitor_printf(mon, "PCI devices not supported\n");
 780        error_free(err);
 781        return;
 782    }
 783
 784    for (info = info_list; info; info = info->next) {
 785        PciDeviceInfoList *dev;
 786
 787        for (dev = info->value->devices; dev; dev = dev->next) {
 788            hmp_info_pci_device(mon, dev->value);
 789        }
 790    }
 791
 792    qapi_free_PciInfoList(info_list);
 793}
 794
 795void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
 796{
 797    BlockJobInfoList *list;
 798    Error *err = NULL;
 799
 800    list = qmp_query_block_jobs(&err);
 801    assert(!err);
 802
 803    if (!list) {
 804        monitor_printf(mon, "No active jobs\n");
 805        return;
 806    }
 807
 808    while (list) {
 809        if (strcmp(list->value->type, "stream") == 0) {
 810            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
 811                           " of %" PRId64 " bytes, speed limit %" PRId64
 812                           " bytes/s\n",
 813                           list->value->device,
 814                           list->value->offset,
 815                           list->value->len,
 816                           list->value->speed);
 817        } else {
 818            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
 819                           " of %" PRId64 " bytes, speed limit %" PRId64
 820                           " bytes/s\n",
 821                           list->value->type,
 822                           list->value->device,
 823                           list->value->offset,
 824                           list->value->len,
 825                           list->value->speed);
 826        }
 827        list = list->next;
 828    }
 829
 830    qapi_free_BlockJobInfoList(list);
 831}
 832
 833void hmp_info_tpm(Monitor *mon, const QDict *qdict)
 834{
 835    TPMInfoList *info_list, *info;
 836    Error *err = NULL;
 837    unsigned int c = 0;
 838    TPMPassthroughOptions *tpo;
 839
 840    info_list = qmp_query_tpm(&err);
 841    if (err) {
 842        monitor_printf(mon, "TPM device not supported\n");
 843        error_free(err);
 844        return;
 845    }
 846
 847    if (info_list) {
 848        monitor_printf(mon, "TPM device:\n");
 849    }
 850
 851    for (info = info_list; info; info = info->next) {
 852        TPMInfo *ti = info->value;
 853        monitor_printf(mon, " tpm%d: model=%s\n",
 854                       c, TpmModel_lookup[ti->model]);
 855
 856        monitor_printf(mon, "  \\ %s: type=%s",
 857                       ti->id, TpmTypeOptionsKind_lookup[ti->options->type]);
 858
 859        switch (ti->options->type) {
 860        case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
 861            tpo = ti->options->u.passthrough.data;
 862            monitor_printf(mon, "%s%s%s%s",
 863                           tpo->has_path ? ",path=" : "",
 864                           tpo->has_path ? tpo->path : "",
 865                           tpo->has_cancel_path ? ",cancel-path=" : "",
 866                           tpo->has_cancel_path ? tpo->cancel_path : "");
 867            break;
 868        case TPM_TYPE_OPTIONS_KIND__MAX:
 869            break;
 870        }
 871        monitor_printf(mon, "\n");
 872        c++;
 873    }
 874    qapi_free_TPMInfoList(info_list);
 875}
 876
 877void hmp_quit(Monitor *mon, const QDict *qdict)
 878{
 879    monitor_suspend(mon);
 880    qmp_quit(NULL);
 881}
 882
 883void hmp_stop(Monitor *mon, const QDict *qdict)
 884{
 885    qmp_stop(NULL);
 886}
 887
 888void hmp_system_reset(Monitor *mon, const QDict *qdict)
 889{
 890    qmp_system_reset(NULL);
 891}
 892
 893void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
 894{
 895    qmp_system_powerdown(NULL);
 896}
 897
 898void hmp_cpu(Monitor *mon, const QDict *qdict)
 899{
 900    int64_t cpu_index;
 901
 902    /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
 903            use it are converted to the QAPI */
 904    cpu_index = qdict_get_int(qdict, "index");
 905    if (monitor_set_cpu(cpu_index) < 0) {
 906        monitor_printf(mon, "invalid CPU index\n");
 907    }
 908}
 909
 910void hmp_memsave(Monitor *mon, const QDict *qdict)
 911{
 912    uint32_t size = qdict_get_int(qdict, "size");
 913    const char *filename = qdict_get_str(qdict, "filename");
 914    uint64_t addr = qdict_get_int(qdict, "val");
 915    Error *err = NULL;
 916
 917    qmp_memsave(addr, size, filename, true, monitor_get_cpu_index(), &err);
 918    hmp_handle_error(mon, &err);
 919}
 920
 921void hmp_pmemsave(Monitor *mon, const QDict *qdict)
 922{
 923    uint32_t size = qdict_get_int(qdict, "size");
 924    const char *filename = qdict_get_str(qdict, "filename");
 925    uint64_t addr = qdict_get_int(qdict, "val");
 926    Error *err = NULL;
 927
 928    qmp_pmemsave(addr, size, filename, &err);
 929    hmp_handle_error(mon, &err);
 930}
 931
 932void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
 933{
 934    const char *chardev = qdict_get_str(qdict, "device");
 935    const char *data = qdict_get_str(qdict, "data");
 936    Error *err = NULL;
 937
 938    qmp_ringbuf_write(chardev, data, false, 0, &err);
 939
 940    hmp_handle_error(mon, &err);
 941}
 942
 943void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
 944{
 945    uint32_t size = qdict_get_int(qdict, "size");
 946    const char *chardev = qdict_get_str(qdict, "device");
 947    char *data;
 948    Error *err = NULL;
 949    int i;
 950
 951    data = qmp_ringbuf_read(chardev, size, false, 0, &err);
 952    if (err) {
 953        error_report_err(err);
 954        return;
 955    }
 956
 957    for (i = 0; data[i]; i++) {
 958        unsigned char ch = data[i];
 959
 960        if (ch == '\\') {
 961            monitor_printf(mon, "\\\\");
 962        } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) {
 963            monitor_printf(mon, "\\u%04X", ch);
 964        } else {
 965            monitor_printf(mon, "%c", ch);
 966        }
 967
 968    }
 969    monitor_printf(mon, "\n");
 970    g_free(data);
 971}
 972
 973static void hmp_cont_cb(void *opaque, int err)
 974{
 975    if (!err) {
 976        qmp_cont(NULL);
 977    }
 978}
 979
 980static bool key_is_missing(const BlockInfo *bdev)
 981{
 982    return (bdev->inserted && bdev->inserted->encryption_key_missing);
 983}
 984
 985void hmp_cont(Monitor *mon, const QDict *qdict)
 986{
 987    BlockInfoList *bdev_list, *bdev;
 988    Error *err = NULL;
 989
 990    bdev_list = qmp_query_block(NULL);
 991    for (bdev = bdev_list; bdev; bdev = bdev->next) {
 992        if (key_is_missing(bdev->value)) {
 993            monitor_read_block_device_key(mon, bdev->value->device,
 994                                          hmp_cont_cb, NULL);
 995            goto out;
 996        }
 997    }
 998
 999    qmp_cont(&err);
1000    hmp_handle_error(mon, &err);
1001
1002out:
1003    qapi_free_BlockInfoList(bdev_list);
1004}
1005
1006void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
1007{
1008    qmp_system_wakeup(NULL);
1009}
1010
1011void hmp_nmi(Monitor *mon, const QDict *qdict)
1012{
1013    Error *err = NULL;
1014
1015    qmp_inject_nmi(&err);
1016    hmp_handle_error(mon, &err);
1017}
1018
1019void hmp_set_link(Monitor *mon, const QDict *qdict)
1020{
1021    const char *name = qdict_get_str(qdict, "name");
1022    bool up = qdict_get_bool(qdict, "up");
1023    Error *err = NULL;
1024
1025    qmp_set_link(name, up, &err);
1026    hmp_handle_error(mon, &err);
1027}
1028
1029void hmp_block_passwd(Monitor *mon, const QDict *qdict)
1030{
1031    const char *device = qdict_get_str(qdict, "device");
1032    const char *password = qdict_get_str(qdict, "password");
1033    Error *err = NULL;
1034
1035    qmp_block_passwd(true, device, false, NULL, password, &err);
1036    hmp_handle_error(mon, &err);
1037}
1038
1039void hmp_balloon(Monitor *mon, const QDict *qdict)
1040{
1041    int64_t value = qdict_get_int(qdict, "value");
1042    Error *err = NULL;
1043
1044    qmp_balloon(value, &err);
1045    if (err) {
1046        error_report_err(err);
1047    }
1048}
1049
1050void hmp_block_resize(Monitor *mon, const QDict *qdict)
1051{
1052    const char *device = qdict_get_str(qdict, "device");
1053    int64_t size = qdict_get_int(qdict, "size");
1054    Error *err = NULL;
1055
1056    qmp_block_resize(true, device, false, NULL, size, &err);
1057    hmp_handle_error(mon, &err);
1058}
1059
1060void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
1061{
1062    const char *device = qdict_get_str(qdict, "device");
1063    const char *filename = qdict_get_str(qdict, "target");
1064    const char *format = qdict_get_try_str(qdict, "format");
1065    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
1066    bool full = qdict_get_try_bool(qdict, "full", false);
1067    enum NewImageMode mode;
1068    Error *err = NULL;
1069
1070    if (!filename) {
1071        error_setg(&err, QERR_MISSING_PARAMETER, "target");
1072        hmp_handle_error(mon, &err);
1073        return;
1074    }
1075
1076    if (reuse) {
1077        mode = NEW_IMAGE_MODE_EXISTING;
1078    } else {
1079        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
1080    }
1081
1082    qmp_drive_mirror(device, filename, !!format, format,
1083                     false, NULL, false, NULL,
1084                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
1085                     true, mode, false, 0, false, 0, false, 0,
1086                     false, 0, false, 0, false, true, &err);
1087    hmp_handle_error(mon, &err);
1088}
1089
1090void hmp_drive_backup(Monitor *mon, const QDict *qdict)
1091{
1092    const char *device = qdict_get_str(qdict, "device");
1093    const char *filename = qdict_get_str(qdict, "target");
1094    const char *format = qdict_get_try_str(qdict, "format");
1095    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
1096    bool full = qdict_get_try_bool(qdict, "full", false);
1097    enum NewImageMode mode;
1098    Error *err = NULL;
1099
1100    if (!filename) {
1101        error_setg(&err, QERR_MISSING_PARAMETER, "target");
1102        hmp_handle_error(mon, &err);
1103        return;
1104    }
1105
1106    if (reuse) {
1107        mode = NEW_IMAGE_MODE_EXISTING;
1108    } else {
1109        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
1110    }
1111
1112    qmp_drive_backup(device, filename, !!format, format,
1113                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
1114                     true, mode, false, 0, false, NULL,
1115                     false, 0, false, 0, &err);
1116    hmp_handle_error(mon, &err);
1117}
1118
1119void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
1120{
1121    const char *device = qdict_get_str(qdict, "device");
1122    const char *filename = qdict_get_try_str(qdict, "snapshot-file");
1123    const char *format = qdict_get_try_str(qdict, "format");
1124    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
1125    enum NewImageMode mode;
1126    Error *err = NULL;
1127
1128    if (!filename) {
1129        /* In the future, if 'snapshot-file' is not specified, the snapshot
1130           will be taken internally. Today it's actually required. */
1131        error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file");
1132        hmp_handle_error(mon, &err);
1133        return;
1134    }
1135
1136    mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
1137    qmp_blockdev_snapshot_sync(true, device, false, NULL,
1138                               filename, false, NULL,
1139                               !!format, format,
1140                               true, mode, &err);
1141    hmp_handle_error(mon, &err);
1142}
1143
1144void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
1145{
1146    const char *device = qdict_get_str(qdict, "device");
1147    const char *name = qdict_get_str(qdict, "name");
1148    Error *err = NULL;
1149
1150    qmp_blockdev_snapshot_internal_sync(device, name, &err);
1151    hmp_handle_error(mon, &err);
1152}
1153
1154void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
1155{
1156    const char *device = qdict_get_str(qdict, "device");
1157    const char *name = qdict_get_str(qdict, "name");
1158    const char *id = qdict_get_try_str(qdict, "id");
1159    Error *err = NULL;
1160
1161    qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
1162                                               true, name, &err);
1163    hmp_handle_error(mon, &err);
1164}
1165
1166void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
1167{
1168    qmp_migrate_cancel(NULL);
1169}
1170
1171void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
1172{
1173    Error *err = NULL;
1174    const char *uri = qdict_get_str(qdict, "uri");
1175
1176    qmp_migrate_incoming(uri, &err);
1177
1178    hmp_handle_error(mon, &err);
1179}
1180
1181void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
1182{
1183    double value = qdict_get_double(qdict, "value");
1184    qmp_migrate_set_downtime(value, NULL);
1185}
1186
1187void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
1188{
1189    int64_t value = qdict_get_int(qdict, "value");
1190    Error *err = NULL;
1191
1192    qmp_migrate_set_cache_size(value, &err);
1193    if (err) {
1194        error_report_err(err);
1195        return;
1196    }
1197}
1198
1199void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
1200{
1201    int64_t value = qdict_get_int(qdict, "value");
1202    qmp_migrate_set_speed(value, NULL);
1203}
1204
1205void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
1206{
1207    const char *cap = qdict_get_str(qdict, "capability");
1208    bool state = qdict_get_bool(qdict, "state");
1209    Error *err = NULL;
1210    MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
1211    int i;
1212
1213    for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
1214        if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
1215            caps->value = g_malloc0(sizeof(*caps->value));
1216            caps->value->capability = i;
1217            caps->value->state = state;
1218            caps->next = NULL;
1219            qmp_migrate_set_capabilities(caps, &err);
1220            break;
1221        }
1222    }
1223
1224    if (i == MIGRATION_CAPABILITY__MAX) {
1225        error_setg(&err, QERR_INVALID_PARAMETER, cap);
1226    }
1227
1228    qapi_free_MigrationCapabilityStatusList(caps);
1229
1230    if (err) {
1231        error_report_err(err);
1232    }
1233}
1234
1235void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
1236{
1237    const char *param = qdict_get_str(qdict, "parameter");
1238    int value = qdict_get_int(qdict, "value");
1239    Error *err = NULL;
1240    bool has_compress_level = false;
1241    bool has_compress_threads = false;
1242    bool has_decompress_threads = false;
1243    bool has_x_cpu_throttle_initial = false;
1244    bool has_x_cpu_throttle_increment = false;
1245    int i;
1246
1247    for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) {
1248        if (strcmp(param, MigrationParameter_lookup[i]) == 0) {
1249            switch (i) {
1250            case MIGRATION_PARAMETER_COMPRESS_LEVEL:
1251                has_compress_level = true;
1252                break;
1253            case MIGRATION_PARAMETER_COMPRESS_THREADS:
1254                has_compress_threads = true;
1255                break;
1256            case MIGRATION_PARAMETER_DECOMPRESS_THREADS:
1257                has_decompress_threads = true;
1258                break;
1259            case MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL:
1260                has_x_cpu_throttle_initial = true;
1261                break;
1262            case MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT:
1263                has_x_cpu_throttle_increment = true;
1264                break;
1265            }
1266            qmp_migrate_set_parameters(has_compress_level, value,
1267                                       has_compress_threads, value,
1268                                       has_decompress_threads, value,
1269                                       has_x_cpu_throttle_initial, value,
1270                                       has_x_cpu_throttle_increment, value,
1271                                       &err);
1272            break;
1273        }
1274    }
1275
1276    if (i == MIGRATION_PARAMETER__MAX) {
1277        error_setg(&err, QERR_INVALID_PARAMETER, param);
1278    }
1279
1280    if (err) {
1281        error_report_err(err);
1282    }
1283}
1284
1285void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
1286{
1287    Error *err = NULL;
1288    const char *protocol = qdict_get_str(qdict, "protocol");
1289    const char *hostname = qdict_get_str(qdict, "hostname");
1290    bool has_port        = qdict_haskey(qdict, "port");
1291    int port             = qdict_get_try_int(qdict, "port", -1);
1292    bool has_tls_port    = qdict_haskey(qdict, "tls-port");
1293    int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
1294    const char *cert_subject = qdict_get_try_str(qdict, "cert-subject");
1295
1296    qmp_client_migrate_info(protocol, hostname,
1297                            has_port, port, has_tls_port, tls_port,
1298                            !!cert_subject, cert_subject, &err);
1299    hmp_handle_error(mon, &err);
1300}
1301
1302void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
1303{
1304    Error *err = NULL;
1305    qmp_migrate_start_postcopy(&err);
1306    hmp_handle_error(mon, &err);
1307}
1308
1309void hmp_set_password(Monitor *mon, const QDict *qdict)
1310{
1311    const char *protocol  = qdict_get_str(qdict, "protocol");
1312    const char *password  = qdict_get_str(qdict, "password");
1313    const char *connected = qdict_get_try_str(qdict, "connected");
1314    Error *err = NULL;
1315
1316    qmp_set_password(protocol, password, !!connected, connected, &err);
1317    hmp_handle_error(mon, &err);
1318}
1319
1320void hmp_expire_password(Monitor *mon, const QDict *qdict)
1321{
1322    const char *protocol  = qdict_get_str(qdict, "protocol");
1323    const char *whenstr = qdict_get_str(qdict, "time");
1324    Error *err = NULL;
1325
1326    qmp_expire_password(protocol, whenstr, &err);
1327    hmp_handle_error(mon, &err);
1328}
1329
1330void hmp_eject(Monitor *mon, const QDict *qdict)
1331{
1332    bool force = qdict_get_try_bool(qdict, "force", false);
1333    const char *device = qdict_get_str(qdict, "device");
1334    Error *err = NULL;
1335
1336    qmp_eject(device, true, force, &err);
1337    hmp_handle_error(mon, &err);
1338}
1339
1340static void hmp_change_read_arg(void *opaque, const char *password,
1341                                void *readline_opaque)
1342{
1343    qmp_change_vnc_password(password, NULL);
1344    monitor_read_command(opaque, 1);
1345}
1346
1347void hmp_change(Monitor *mon, const QDict *qdict)
1348{
1349    const char *device = qdict_get_str(qdict, "device");
1350    const char *target = qdict_get_str(qdict, "target");
1351    const char *arg = qdict_get_try_str(qdict, "arg");
1352    const char *read_only = qdict_get_try_str(qdict, "read-only-mode");
1353    BlockdevChangeReadOnlyMode read_only_mode = 0;
1354    Error *err = NULL;
1355
1356    if (strcmp(device, "vnc") == 0) {
1357        if (read_only) {
1358            monitor_printf(mon,
1359                           "Parameter 'read-only-mode' is invalid for VNC\n");
1360            return;
1361        }
1362        if (strcmp(target, "passwd") == 0 ||
1363            strcmp(target, "password") == 0) {
1364            if (!arg) {
1365                monitor_read_password(mon, hmp_change_read_arg, NULL);
1366                return;
1367            }
1368        }
1369        qmp_change("vnc", target, !!arg, arg, &err);
1370    } else {
1371        if (read_only) {
1372            read_only_mode =
1373                qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup,
1374                                read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE__MAX,
1375                                BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err);
1376            if (err) {
1377                hmp_handle_error(mon, &err);
1378                return;
1379            }
1380        }
1381
1382        qmp_blockdev_change_medium(device, target, !!arg, arg,
1383                                   !!read_only, read_only_mode, &err);
1384        if (err &&
1385            error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
1386            error_free(err);
1387            monitor_read_block_device_key(mon, device, NULL, NULL);
1388            return;
1389        }
1390    }
1391
1392    hmp_handle_error(mon, &err);
1393}
1394
1395void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
1396{
1397    Error *err = NULL;
1398
1399    qmp_block_set_io_throttle(qdict_get_str(qdict, "device"),
1400                              qdict_get_int(qdict, "bps"),
1401                              qdict_get_int(qdict, "bps_rd"),
1402                              qdict_get_int(qdict, "bps_wr"),
1403                              qdict_get_int(qdict, "iops"),
1404                              qdict_get_int(qdict, "iops_rd"),
1405                              qdict_get_int(qdict, "iops_wr"),
1406                              false, /* no burst max via HMP */
1407                              0,
1408                              false,
1409                              0,
1410                              false,
1411                              0,
1412                              false,
1413                              0,
1414                              false,
1415                              0,
1416                              false,
1417                              0,
1418                              false, /* no burst length via HMP */
1419                              0,
1420                              false,
1421                              0,
1422                              false,
1423                              0,
1424                              false,
1425                              0,
1426                              false,
1427                              0,
1428                              false,
1429                              0,
1430                              false, /* No default I/O size */
1431                              0,
1432                              false,
1433                              NULL, &err);
1434    hmp_handle_error(mon, &err);
1435}
1436
1437void hmp_block_stream(Monitor *mon, const QDict *qdict)
1438{
1439    Error *error = NULL;
1440    const char *device = qdict_get_str(qdict, "device");
1441    const char *base = qdict_get_try_str(qdict, "base");
1442    int64_t speed = qdict_get_try_int(qdict, "speed", 0);
1443
1444    qmp_block_stream(device, base != NULL, base, false, NULL,
1445                     qdict_haskey(qdict, "speed"), speed,
1446                     true, BLOCKDEV_ON_ERROR_REPORT, &error);
1447
1448    hmp_handle_error(mon, &error);
1449}
1450
1451void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
1452{
1453    Error *error = NULL;
1454    const char *device = qdict_get_str(qdict, "device");
1455    int64_t value = qdict_get_int(qdict, "speed");
1456
1457    qmp_block_job_set_speed(device, value, &error);
1458
1459    hmp_handle_error(mon, &error);
1460}
1461
1462void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
1463{
1464    Error *error = NULL;
1465    const char *device = qdict_get_str(qdict, "device");
1466    bool force = qdict_get_try_bool(qdict, "force", false);
1467
1468    qmp_block_job_cancel(device, true, force, &error);
1469
1470    hmp_handle_error(mon, &error);
1471}
1472
1473void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
1474{
1475    Error *error = NULL;
1476    const char *device = qdict_get_str(qdict, "device");
1477
1478    qmp_block_job_pause(device, &error);
1479
1480    hmp_handle_error(mon, &error);
1481}
1482
1483void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
1484{
1485    Error *error = NULL;
1486    const char *device = qdict_get_str(qdict, "device");
1487
1488    qmp_block_job_resume(device, &error);
1489
1490    hmp_handle_error(mon, &error);
1491}
1492
1493void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
1494{
1495    Error *error = NULL;
1496    const char *device = qdict_get_str(qdict, "device");
1497
1498    qmp_block_job_complete(device, &error);
1499
1500    hmp_handle_error(mon, &error);
1501}
1502
1503typedef struct HMPMigrationStatus
1504{
1505    QEMUTimer *timer;
1506    Monitor *mon;
1507    bool is_block_migration;
1508} HMPMigrationStatus;
1509
1510static void hmp_migrate_status_cb(void *opaque)
1511{
1512    HMPMigrationStatus *status = opaque;
1513    MigrationInfo *info;
1514
1515    info = qmp_query_migrate(NULL);
1516    if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
1517        info->status == MIGRATION_STATUS_SETUP) {
1518        if (info->has_disk) {
1519            int progress;
1520
1521            if (info->disk->remaining) {
1522                progress = info->disk->transferred * 100 / info->disk->total;
1523            } else {
1524                progress = 100;
1525            }
1526
1527            monitor_printf(status->mon, "Completed %d %%\r", progress);
1528            monitor_flush(status->mon);
1529        }
1530
1531        timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
1532    } else {
1533        if (status->is_block_migration) {
1534            monitor_printf(status->mon, "\n");
1535        }
1536        monitor_resume(status->mon);
1537        timer_del(status->timer);
1538        g_free(status);
1539    }
1540
1541    qapi_free_MigrationInfo(info);
1542}
1543
1544void hmp_migrate(Monitor *mon, const QDict *qdict)
1545{
1546    bool detach = qdict_get_try_bool(qdict, "detach", false);
1547    bool blk = qdict_get_try_bool(qdict, "blk", false);
1548    bool inc = qdict_get_try_bool(qdict, "inc", false);
1549    const char *uri = qdict_get_str(qdict, "uri");
1550    Error *err = NULL;
1551
1552    qmp_migrate(uri, !!blk, blk, !!inc, inc, false, false, &err);
1553    if (err) {
1554        error_report_err(err);
1555        return;
1556    }
1557
1558    if (!detach) {
1559        HMPMigrationStatus *status;
1560
1561        if (monitor_suspend(mon) < 0) {
1562            monitor_printf(mon, "terminal does not allow synchronous "
1563                           "migration, continuing detached\n");
1564            return;
1565        }
1566
1567        status = g_malloc0(sizeof(*status));
1568        status->mon = mon;
1569        status->is_block_migration = blk || inc;
1570        status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
1571                                          status);
1572        timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
1573    }
1574}
1575
1576void hmp_device_add(Monitor *mon, const QDict *qdict)
1577{
1578    Error *err = NULL;
1579
1580    qmp_device_add((QDict *)qdict, NULL, &err);
1581    hmp_handle_error(mon, &err);
1582}
1583
1584void hmp_device_del(Monitor *mon, const QDict *qdict)
1585{
1586    const char *id = qdict_get_str(qdict, "id");
1587    Error *err = NULL;
1588
1589    qmp_device_del(id, &err);
1590    hmp_handle_error(mon, &err);
1591}
1592
1593void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
1594{
1595    Error *err = NULL;
1596    bool paging = qdict_get_try_bool(qdict, "paging", false);
1597    bool zlib = qdict_get_try_bool(qdict, "zlib", false);
1598    bool lzo = qdict_get_try_bool(qdict, "lzo", false);
1599    bool snappy = qdict_get_try_bool(qdict, "snappy", false);
1600    const char *file = qdict_get_str(qdict, "filename");
1601    bool has_begin = qdict_haskey(qdict, "begin");
1602    bool has_length = qdict_haskey(qdict, "length");
1603    bool has_detach = qdict_haskey(qdict, "detach");
1604    int64_t begin = 0;
1605    int64_t length = 0;
1606    bool detach = false;
1607    enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
1608    char *prot;
1609
1610    if (zlib + lzo + snappy > 1) {
1611        error_setg(&err, "only one of '-z|-l|-s' can be set");
1612        hmp_handle_error(mon, &err);
1613        return;
1614    }
1615
1616    if (zlib) {
1617        dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
1618    }
1619
1620    if (lzo) {
1621        dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
1622    }
1623
1624    if (snappy) {
1625        dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
1626    }
1627
1628    if (has_begin) {
1629        begin = qdict_get_int(qdict, "begin");
1630    }
1631    if (has_length) {
1632        length = qdict_get_int(qdict, "length");
1633    }
1634    if (has_detach) {
1635        detach = qdict_get_bool(qdict, "detach");
1636    }
1637
1638    prot = g_strconcat("file:", file, NULL);
1639
1640    qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin,
1641                          has_length, length, true, dump_format, &err);
1642    hmp_handle_error(mon, &err);
1643    g_free(prot);
1644}
1645
1646void hmp_netdev_add(Monitor *mon, const QDict *qdict)
1647{
1648    Error *err = NULL;
1649    QemuOpts *opts;
1650
1651    opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
1652    if (err) {
1653        goto out;
1654    }
1655
1656    netdev_add(opts, &err);
1657    if (err) {
1658        qemu_opts_del(opts);
1659    }
1660
1661out:
1662    hmp_handle_error(mon, &err);
1663}
1664
1665void hmp_netdev_del(Monitor *mon, const QDict *qdict)
1666{
1667    const char *id = qdict_get_str(qdict, "id");
1668    Error *err = NULL;
1669
1670    qmp_netdev_del(id, &err);
1671    hmp_handle_error(mon, &err);
1672}
1673
1674void hmp_object_add(Monitor *mon, const QDict *qdict)
1675{
1676    Error *err = NULL;
1677    QemuOpts *opts;
1678    OptsVisitor *ov;
1679    Object *obj = NULL;
1680
1681    opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
1682    if (err) {
1683        hmp_handle_error(mon, &err);
1684        return;
1685    }
1686
1687    ov = opts_visitor_new(opts);
1688    obj = user_creatable_add(qdict, opts_get_visitor(ov), &err);
1689    opts_visitor_cleanup(ov);
1690    qemu_opts_del(opts);
1691
1692    if (err) {
1693        hmp_handle_error(mon, &err);
1694    }
1695    if (obj) {
1696        object_unref(obj);
1697    }
1698}
1699
1700void hmp_getfd(Monitor *mon, const QDict *qdict)
1701{
1702    const char *fdname = qdict_get_str(qdict, "fdname");
1703    Error *err = NULL;
1704
1705    qmp_getfd(fdname, &err);
1706    hmp_handle_error(mon, &err);
1707}
1708
1709void hmp_closefd(Monitor *mon, const QDict *qdict)
1710{
1711    const char *fdname = qdict_get_str(qdict, "fdname");
1712    Error *err = NULL;
1713
1714    qmp_closefd(fdname, &err);
1715    hmp_handle_error(mon, &err);
1716}
1717
1718void hmp_sendkey(Monitor *mon, const QDict *qdict)
1719{
1720    const char *keys = qdict_get_str(qdict, "keys");
1721    KeyValueList *keylist, *head = NULL, *tmp = NULL;
1722    int has_hold_time = qdict_haskey(qdict, "hold-time");
1723    int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
1724    Error *err = NULL;
1725    char *separator;
1726    int keyname_len;
1727
1728    while (1) {
1729        separator = strchr(keys, '-');
1730        keyname_len = separator ? separator - keys : strlen(keys);
1731
1732        /* Be compatible with old interface, convert user inputted "<" */
1733        if (keys[0] == '<' && keyname_len == 1) {
1734            keys = "less";
1735            keyname_len = 4;
1736        }
1737
1738        keylist = g_malloc0(sizeof(*keylist));
1739        keylist->value = g_malloc0(sizeof(*keylist->value));
1740
1741        if (!head) {
1742            head = keylist;
1743        }
1744        if (tmp) {
1745            tmp->next = keylist;
1746        }
1747        tmp = keylist;
1748
1749        if (strstart(keys, "0x", NULL)) {
1750            char *endp;
1751            int value = strtoul(keys, &endp, 0);
1752            assert(endp <= keys + keyname_len);
1753            if (endp != keys + keyname_len) {
1754                goto err_out;
1755            }
1756            keylist->value->type = KEY_VALUE_KIND_NUMBER;
1757            keylist->value->u.number.data = value;
1758        } else {
1759            int idx = index_from_key(keys, keyname_len);
1760            if (idx == Q_KEY_CODE__MAX) {
1761                goto err_out;
1762            }
1763            keylist->value->type = KEY_VALUE_KIND_QCODE;
1764            keylist->value->u.qcode.data = idx;
1765        }
1766
1767        if (!separator) {
1768            break;
1769        }
1770        keys = separator + 1;
1771    }
1772
1773    qmp_send_key(head, has_hold_time, hold_time, &err);
1774    hmp_handle_error(mon, &err);
1775
1776out:
1777    qapi_free_KeyValueList(head);
1778    return;
1779
1780err_out:
1781    monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
1782    goto out;
1783}
1784
1785void hmp_screendump(Monitor *mon, const QDict *qdict)
1786{
1787    const char *filename = qdict_get_str(qdict, "filename");
1788    Error *err = NULL;
1789
1790    qmp_screendump(filename, &err);
1791    hmp_handle_error(mon, &err);
1792}
1793
1794void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
1795{
1796    const char *uri = qdict_get_str(qdict, "uri");
1797    bool writable = qdict_get_try_bool(qdict, "writable", false);
1798    bool all = qdict_get_try_bool(qdict, "all", false);
1799    Error *local_err = NULL;
1800    BlockInfoList *block_list, *info;
1801    SocketAddress *addr;
1802
1803    if (writable && !all) {
1804        error_setg(&local_err, "-w only valid together with -a");
1805        goto exit;
1806    }
1807
1808    /* First check if the address is valid and start the server.  */
1809    addr = socket_parse(uri, &local_err);
1810    if (local_err != NULL) {
1811        goto exit;
1812    }
1813
1814    qmp_nbd_server_start(addr, false, NULL, &local_err);
1815    qapi_free_SocketAddress(addr);
1816    if (local_err != NULL) {
1817        goto exit;
1818    }
1819
1820    if (!all) {
1821        return;
1822    }
1823
1824    /* Then try adding all block devices.  If one fails, close all and
1825     * exit.
1826     */
1827    block_list = qmp_query_block(NULL);
1828
1829    for (info = block_list; info; info = info->next) {
1830        if (!info->value->has_inserted) {
1831            continue;
1832        }
1833
1834        qmp_nbd_server_add(info->value->device, true, writable, &local_err);
1835
1836        if (local_err != NULL) {
1837            qmp_nbd_server_stop(NULL);
1838            break;
1839        }
1840    }
1841
1842    qapi_free_BlockInfoList(block_list);
1843
1844exit:
1845    hmp_handle_error(mon, &local_err);
1846}
1847
1848void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
1849{
1850    const char *device = qdict_get_str(qdict, "device");
1851    bool writable = qdict_get_try_bool(qdict, "writable", false);
1852    Error *local_err = NULL;
1853
1854    qmp_nbd_server_add(device, true, writable, &local_err);
1855
1856    if (local_err != NULL) {
1857        hmp_handle_error(mon, &local_err);
1858    }
1859}
1860
1861void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
1862{
1863    Error *err = NULL;
1864
1865    qmp_nbd_server_stop(&err);
1866    hmp_handle_error(mon, &err);
1867}
1868
1869void hmp_cpu_add(Monitor *mon, const QDict *qdict)
1870{
1871    int cpuid;
1872    Error *err = NULL;
1873
1874    cpuid = qdict_get_int(qdict, "id");
1875    qmp_cpu_add(cpuid, &err);
1876    hmp_handle_error(mon, &err);
1877}
1878
1879void hmp_chardev_add(Monitor *mon, const QDict *qdict)
1880{
1881    const char *args = qdict_get_str(qdict, "args");
1882    Error *err = NULL;
1883    QemuOpts *opts;
1884
1885    opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, true);
1886    if (opts == NULL) {
1887        error_setg(&err, "Parsing chardev args failed");
1888    } else {
1889        qemu_chr_new_from_opts(opts, NULL, &err);
1890    }
1891    hmp_handle_error(mon, &err);
1892}
1893
1894void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
1895{
1896    Error *local_err = NULL;
1897
1898    qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
1899    hmp_handle_error(mon, &local_err);
1900}
1901
1902void hmp_qemu_io(Monitor *mon, const QDict *qdict)
1903{
1904    BlockBackend *blk;
1905    const char* device = qdict_get_str(qdict, "device");
1906    const char* command = qdict_get_str(qdict, "command");
1907    Error *err = NULL;
1908
1909    blk = blk_by_name(device);
1910    if (blk) {
1911        qemuio_command(blk, command);
1912    } else {
1913        error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
1914                  "Device '%s' not found", device);
1915    }
1916
1917    hmp_handle_error(mon, &err);
1918}
1919
1920void hmp_object_del(Monitor *mon, const QDict *qdict)
1921{
1922    const char *id = qdict_get_str(qdict, "id");
1923    Error *err = NULL;
1924
1925    user_creatable_del(id, &err);
1926    hmp_handle_error(mon, &err);
1927}
1928
1929void hmp_info_memdev(Monitor *mon, const QDict *qdict)
1930{
1931    Error *err = NULL;
1932    MemdevList *memdev_list = qmp_query_memdev(&err);
1933    MemdevList *m = memdev_list;
1934    StringOutputVisitor *ov;
1935    char *str;
1936    int i = 0;
1937
1938
1939    while (m) {
1940        ov = string_output_visitor_new(false);
1941        visit_type_uint16List(string_output_get_visitor(ov), NULL,
1942                              &m->value->host_nodes, NULL);
1943        monitor_printf(mon, "memory backend: %d\n", i);
1944        monitor_printf(mon, "  size:  %" PRId64 "\n", m->value->size);
1945        monitor_printf(mon, "  merge: %s\n",
1946                       m->value->merge ? "true" : "false");
1947        monitor_printf(mon, "  dump: %s\n",
1948                       m->value->dump ? "true" : "false");
1949        monitor_printf(mon, "  prealloc: %s\n",
1950                       m->value->prealloc ? "true" : "false");
1951        monitor_printf(mon, "  policy: %s\n",
1952                       HostMemPolicy_lookup[m->value->policy]);
1953        str = string_output_get_string(ov);
1954        monitor_printf(mon, "  host nodes: %s\n", str);
1955
1956        g_free(str);
1957        string_output_visitor_cleanup(ov);
1958        m = m->next;
1959        i++;
1960    }
1961
1962    monitor_printf(mon, "\n");
1963
1964    qapi_free_MemdevList(memdev_list);
1965}
1966
1967void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
1968{
1969    Error *err = NULL;
1970    MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
1971    MemoryDeviceInfoList *info;
1972    MemoryDeviceInfo *value;
1973    PCDIMMDeviceInfo *di;
1974
1975    for (info = info_list; info; info = info->next) {
1976        value = info->value;
1977
1978        if (value) {
1979            switch (value->type) {
1980            case MEMORY_DEVICE_INFO_KIND_DIMM:
1981                di = value->u.dimm.data;
1982
1983                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1984                               MemoryDeviceInfoKind_lookup[value->type],
1985                               di->id ? di->id : "");
1986                monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", di->addr);
1987                monitor_printf(mon, "  slot: %" PRId64 "\n", di->slot);
1988                monitor_printf(mon, "  node: %" PRId64 "\n", di->node);
1989                monitor_printf(mon, "  size: %" PRIu64 "\n", di->size);
1990                monitor_printf(mon, "  memdev: %s\n", di->memdev);
1991                monitor_printf(mon, "  hotplugged: %s\n",
1992                               di->hotplugged ? "true" : "false");
1993                monitor_printf(mon, "  hotpluggable: %s\n",
1994                               di->hotpluggable ? "true" : "false");
1995                break;
1996            default:
1997                break;
1998            }
1999        }
2000    }
2001
2002    qapi_free_MemoryDeviceInfoList(info_list);
2003}
2004
2005void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
2006{
2007    IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
2008    IOThreadInfoList *info;
2009
2010    for (info = info_list; info; info = info->next) {
2011        monitor_printf(mon, "%s: thread_id=%" PRId64 "\n",
2012                       info->value->id, info->value->thread_id);
2013    }
2014
2015    qapi_free_IOThreadInfoList(info_list);
2016}
2017
2018void hmp_qom_list(Monitor *mon, const QDict *qdict)
2019{
2020    const char *path = qdict_get_try_str(qdict, "path");
2021    ObjectPropertyInfoList *list;
2022    Error *err = NULL;
2023
2024    if (path == NULL) {
2025        monitor_printf(mon, "/\n");
2026        return;
2027    }
2028
2029    list = qmp_qom_list(path, &err);
2030    if (err == NULL) {
2031        ObjectPropertyInfoList *start = list;
2032        while (list != NULL) {
2033            ObjectPropertyInfo *value = list->value;
2034
2035            monitor_printf(mon, "%s (%s)\n",
2036                           value->name, value->type);
2037            list = list->next;
2038        }
2039        qapi_free_ObjectPropertyInfoList(start);
2040    }
2041    hmp_handle_error(mon, &err);
2042}
2043
2044void hmp_qom_set(Monitor *mon, const QDict *qdict)
2045{
2046    const char *path = qdict_get_str(qdict, "path");
2047    const char *property = qdict_get_str(qdict, "property");
2048    const char *value = qdict_get_str(qdict, "value");
2049    Error *err = NULL;
2050    bool ambiguous = false;
2051    Object *obj;
2052
2053    obj = object_resolve_path(path, &ambiguous);
2054    if (obj == NULL) {
2055        error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
2056                  "Device '%s' not found", path);
2057    } else {
2058        if (ambiguous) {
2059            monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path);
2060        }
2061        object_property_parse(obj, value, property, &err);
2062    }
2063    hmp_handle_error(mon, &err);
2064}
2065
2066void hmp_rocker(Monitor *mon, const QDict *qdict)
2067{
2068    const char *name = qdict_get_str(qdict, "name");
2069    RockerSwitch *rocker;
2070    Error *err = NULL;
2071
2072    rocker = qmp_query_rocker(name, &err);
2073    if (err != NULL) {
2074        hmp_handle_error(mon, &err);
2075        return;
2076    }
2077
2078    monitor_printf(mon, "name: %s\n", rocker->name);
2079    monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id);
2080    monitor_printf(mon, "ports: %d\n", rocker->ports);
2081
2082    qapi_free_RockerSwitch(rocker);
2083}
2084
2085void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
2086{
2087    RockerPortList *list, *port;
2088    const char *name = qdict_get_str(qdict, "name");
2089    Error *err = NULL;
2090
2091    list = qmp_query_rocker_ports(name, &err);
2092    if (err != NULL) {
2093        hmp_handle_error(mon, &err);
2094        return;
2095    }
2096
2097    monitor_printf(mon, "            ena/    speed/ auto\n");
2098    monitor_printf(mon, "      port  link    duplex neg?\n");
2099
2100    for (port = list; port; port = port->next) {
2101        monitor_printf(mon, "%10s  %-4s   %-3s  %2s  %-3s\n",
2102                       port->value->name,
2103                       port->value->enabled ? port->value->link_up ?
2104                       "up" : "down" : "!ena",
2105                       port->value->speed == 10000 ? "10G" : "??",
2106                       port->value->duplex ? "FD" : "HD",
2107                       port->value->autoneg ? "Yes" : "No");
2108    }
2109
2110    qapi_free_RockerPortList(list);
2111}
2112
2113void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
2114{
2115    RockerOfDpaFlowList *list, *info;
2116    const char *name = qdict_get_str(qdict, "name");
2117    uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
2118    Error *err = NULL;
2119
2120    list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err);
2121    if (err != NULL) {
2122        hmp_handle_error(mon, &err);
2123        return;
2124    }
2125
2126    monitor_printf(mon, "prio tbl hits key(mask) --> actions\n");
2127
2128    for (info = list; info; info = info->next) {
2129        RockerOfDpaFlow *flow = info->value;
2130        RockerOfDpaFlowKey *key = flow->key;
2131        RockerOfDpaFlowMask *mask = flow->mask;
2132        RockerOfDpaFlowAction *action = flow->action;
2133
2134        if (flow->hits) {
2135            monitor_printf(mon, "%-4d %-3d %-4" PRIu64,
2136                           key->priority, key->tbl_id, flow->hits);
2137        } else {
2138            monitor_printf(mon, "%-4d %-3d     ",
2139                           key->priority, key->tbl_id);
2140        }
2141
2142        if (key->has_in_pport) {
2143            monitor_printf(mon, " pport %d", key->in_pport);
2144            if (mask->has_in_pport) {
2145                monitor_printf(mon, "(0x%x)", mask->in_pport);
2146            }
2147        }
2148
2149        if (key->has_vlan_id) {
2150            monitor_printf(mon, " vlan %d",
2151                           key->vlan_id & VLAN_VID_MASK);
2152            if (mask->has_vlan_id) {
2153                monitor_printf(mon, "(0x%x)", mask->vlan_id);
2154            }
2155        }
2156
2157        if (key->has_tunnel_id) {
2158            monitor_printf(mon, " tunnel %d", key->tunnel_id);
2159            if (mask->has_tunnel_id) {
2160                monitor_printf(mon, "(0x%x)", mask->tunnel_id);
2161            }
2162        }
2163
2164        if (key->has_eth_type) {
2165            switch (key->eth_type) {
2166            case 0x0806:
2167                monitor_printf(mon, " ARP");
2168                break;
2169            case 0x0800:
2170                monitor_printf(mon, " IP");
2171                break;
2172            case 0x86dd:
2173                monitor_printf(mon, " IPv6");
2174                break;
2175            case 0x8809:
2176                monitor_printf(mon, " LACP");
2177                break;
2178            case 0x88cc:
2179                monitor_printf(mon, " LLDP");
2180                break;
2181            default:
2182                monitor_printf(mon, " eth type 0x%04x", key->eth_type);
2183                break;
2184            }
2185        }
2186
2187        if (key->has_eth_src) {
2188            if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
2189                (mask->has_eth_src) &&
2190                (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
2191                monitor_printf(mon, " src <any mcast/bcast>");
2192            } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
2193                (mask->has_eth_src) &&
2194                (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
2195                monitor_printf(mon, " src <any ucast>");
2196            } else {
2197                monitor_printf(mon, " src %s", key->eth_src);
2198                if (mask->has_eth_src) {
2199                    monitor_printf(mon, "(%s)", mask->eth_src);
2200                }
2201            }
2202        }
2203
2204        if (key->has_eth_dst) {
2205            if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
2206                (mask->has_eth_dst) &&
2207                (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
2208                monitor_printf(mon, " dst <any mcast/bcast>");
2209            } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) &&
2210                (mask->has_eth_dst) &&
2211                (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
2212                monitor_printf(mon, " dst <any ucast>");
2213            } else {
2214                monitor_printf(mon, " dst %s", key->eth_dst);
2215                if (mask->has_eth_dst) {
2216                    monitor_printf(mon, "(%s)", mask->eth_dst);
2217                }
2218            }
2219        }
2220
2221        if (key->has_ip_proto) {
2222            monitor_printf(mon, " proto %d", key->ip_proto);
2223            if (mask->has_ip_proto) {
2224                monitor_printf(mon, "(0x%x)", mask->ip_proto);
2225            }
2226        }
2227
2228        if (key->has_ip_tos) {
2229            monitor_printf(mon, " TOS %d", key->ip_tos);
2230            if (mask->has_ip_tos) {
2231                monitor_printf(mon, "(0x%x)", mask->ip_tos);
2232            }
2233        }
2234
2235        if (key->has_ip_dst) {
2236            monitor_printf(mon, " dst %s", key->ip_dst);
2237        }
2238
2239        if (action->has_goto_tbl || action->has_group_id ||
2240            action->has_new_vlan_id) {
2241            monitor_printf(mon, " -->");
2242        }
2243
2244        if (action->has_new_vlan_id) {
2245            monitor_printf(mon, " apply new vlan %d",
2246                           ntohs(action->new_vlan_id));
2247        }
2248
2249        if (action->has_group_id) {
2250            monitor_printf(mon, " write group 0x%08x", action->group_id);
2251        }
2252
2253        if (action->has_goto_tbl) {
2254            monitor_printf(mon, " goto tbl %d", action->goto_tbl);
2255        }
2256
2257        monitor_printf(mon, "\n");
2258    }
2259
2260    qapi_free_RockerOfDpaFlowList(list);
2261}
2262
2263void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
2264{
2265    RockerOfDpaGroupList *list, *g;
2266    const char *name = qdict_get_str(qdict, "name");
2267    uint8_t type = qdict_get_try_int(qdict, "type", 9);
2268    Error *err = NULL;
2269    bool set = false;
2270
2271    list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err);
2272    if (err != NULL) {
2273        hmp_handle_error(mon, &err);
2274        return;
2275    }
2276
2277    monitor_printf(mon, "id (decode) --> buckets\n");
2278
2279    for (g = list; g; g = g->next) {
2280        RockerOfDpaGroup *group = g->value;
2281
2282        monitor_printf(mon, "0x%08x", group->id);
2283
2284        monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" :
2285                                         group->type == 1 ? "L2 rewrite" :
2286                                         group->type == 2 ? "L3 unicast" :
2287                                         group->type == 3 ? "L2 multicast" :
2288                                         group->type == 4 ? "L2 flood" :
2289                                         group->type == 5 ? "L3 interface" :
2290                                         group->type == 6 ? "L3 multicast" :
2291                                         group->type == 7 ? "L3 ECMP" :
2292                                         group->type == 8 ? "L2 overlay" :
2293                                         "unknown");
2294
2295        if (group->has_vlan_id) {
2296            monitor_printf(mon, " vlan %d", group->vlan_id);
2297        }
2298
2299        if (group->has_pport) {
2300            monitor_printf(mon, " pport %d", group->pport);
2301        }
2302
2303        if (group->has_index) {
2304            monitor_printf(mon, " index %d", group->index);
2305        }
2306
2307        monitor_printf(mon, ") -->");
2308
2309        if (group->has_set_vlan_id && group->set_vlan_id) {
2310            set = true;
2311            monitor_printf(mon, " set vlan %d",
2312                           group->set_vlan_id & VLAN_VID_MASK);
2313        }
2314
2315        if (group->has_set_eth_src) {
2316            if (!set) {
2317                set = true;
2318                monitor_printf(mon, " set");
2319            }
2320            monitor_printf(mon, " src %s", group->set_eth_src);
2321        }
2322
2323        if (group->has_set_eth_dst) {
2324            if (!set) {
2325                set = true;
2326                monitor_printf(mon, " set");
2327            }
2328            monitor_printf(mon, " dst %s", group->set_eth_dst);
2329        }
2330
2331        set = false;
2332
2333        if (group->has_ttl_check && group->ttl_check) {
2334            monitor_printf(mon, " check TTL");
2335        }
2336
2337        if (group->has_group_id && group->group_id) {
2338            monitor_printf(mon, " group id 0x%08x", group->group_id);
2339        }
2340
2341        if (group->has_pop_vlan && group->pop_vlan) {
2342            monitor_printf(mon, " pop vlan");
2343        }
2344
2345        if (group->has_out_pport) {
2346            monitor_printf(mon, " out pport %d", group->out_pport);
2347        }
2348
2349        if (group->has_group_ids) {
2350            struct uint32List *id;
2351
2352            monitor_printf(mon, " groups [");
2353            for (id = group->group_ids; id; id = id->next) {
2354                monitor_printf(mon, "0x%08x", id->value);
2355                if (id->next) {
2356                    monitor_printf(mon, ",");
2357                }
2358            }
2359            monitor_printf(mon, "]");
2360        }
2361
2362        monitor_printf(mon, "\n");
2363    }
2364
2365    qapi_free_RockerOfDpaGroupList(list);
2366}
2367
2368void hmp_info_dump(Monitor *mon, const QDict *qdict)
2369{
2370    DumpQueryResult *result = qmp_query_dump(NULL);
2371
2372    assert(result && result->status < DUMP_STATUS__MAX);
2373    monitor_printf(mon, "Status: %s\n", DumpStatus_lookup[result->status]);
2374
2375    if (result->status == DUMP_STATUS_ACTIVE) {
2376        float percent = 0;
2377        assert(result->total != 0);
2378        percent = 100.0 * result->completed / result->total;
2379        monitor_printf(mon, "Finished: %.2f %%\n", percent);
2380    }
2381
2382    qapi_free_DumpQueryResult(result);
2383}
2384