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