qemu/migration/migration-hmp-cmds.c
<<
>>
Prefs
   1/*
   2 * HMP commands related to migration
   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 "block/qapi.h"
  18#include "migration/snapshot.h"
  19#include "monitor/hmp.h"
  20#include "monitor/monitor.h"
  21#include "qapi/error.h"
  22#include "qapi/qapi-commands-migration.h"
  23#include "qapi/qapi-visit-migration.h"
  24#include "qobject/qdict.h"
  25#include "qapi/string-input-visitor.h"
  26#include "qapi/string-output-visitor.h"
  27#include "qemu/cutils.h"
  28#include "qemu/error-report.h"
  29#include "qemu/sockets.h"
  30#include "system/runstate.h"
  31#include "ui/qemu-spice.h"
  32#include "system/system.h"
  33#include "options.h"
  34#include "migration.h"
  35
  36static void migration_global_dump(Monitor *mon)
  37{
  38    MigrationState *ms = migrate_get_current();
  39
  40    monitor_printf(mon, "Globals:\n");
  41    monitor_printf(mon, "  store-global-state: %s\n",
  42                   ms->store_global_state ? "on" : "off");
  43    monitor_printf(mon, "  only-migratable: %s\n",
  44                   only_migratable ? "on" : "off");
  45    monitor_printf(mon, "  send-configuration: %s\n",
  46                   ms->send_configuration ? "on" : "off");
  47    monitor_printf(mon, "  send-section-footer: %s\n",
  48                   ms->send_section_footer ? "on" : "off");
  49    monitor_printf(mon, "  send-switchover-start: %s\n",
  50                   ms->send_switchover_start ? "on" : "off");
  51    monitor_printf(mon, "  clear-bitmap-shift: %u\n",
  52                   ms->clear_bitmap_shift);
  53}
  54
  55static const gchar *format_time_str(uint64_t us)
  56{
  57    const char *units[] = {"us", "ms", "sec"};
  58    int index = 0;
  59
  60    while (us >= 1000 && index + 1 < ARRAY_SIZE(units)) {
  61        us /= 1000;
  62        index++;
  63    }
  64
  65    return g_strdup_printf("%"PRIu64" %s", us, units[index]);
  66}
  67
  68static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info)
  69{
  70    if (info->has_postcopy_blocktime) {
  71        monitor_printf(mon, "Postcopy Blocktime (ms): %" PRIu32 "\n",
  72                       info->postcopy_blocktime);
  73    }
  74
  75    if (info->has_postcopy_vcpu_blocktime) {
  76        uint32List *item = info->postcopy_vcpu_blocktime;
  77        const char *sep = "";
  78        int count = 0;
  79
  80        monitor_printf(mon, "Postcopy vCPU Blocktime (ms):\n [");
  81
  82        while (item) {
  83            monitor_printf(mon, "%s%"PRIu32, sep, item->value);
  84            item = item->next;
  85            /* Each line 10 vcpu results, newline if there's more */
  86            sep = ((++count % 10 == 0) && item) ? ",\n  " : ", ";
  87        }
  88        monitor_printf(mon, "]\n");
  89    }
  90
  91    if (info->has_postcopy_latency) {
  92        monitor_printf(mon, "Postcopy Latency (ns): %" PRIu64 "\n",
  93                       info->postcopy_latency);
  94    }
  95
  96    if (info->has_postcopy_non_vcpu_latency) {
  97        monitor_printf(mon, "Postcopy non-vCPU Latencies (ns): %" PRIu64 "\n",
  98                       info->postcopy_non_vcpu_latency);
  99    }
 100
 101    if (info->has_postcopy_vcpu_latency) {
 102        uint64List *item = info->postcopy_vcpu_latency;
 103        const char *sep = "";
 104        int count = 0;
 105
 106        monitor_printf(mon, "Postcopy vCPU Latencies (ns):\n [");
 107
 108        while (item) {
 109            monitor_printf(mon, "%s%"PRIu64, sep, item->value);
 110            item = item->next;
 111            /* Each line 10 vcpu results, newline if there's more */
 112            sep = ((++count % 10 == 0) && item) ? ",\n  " : ", ";
 113        }
 114        monitor_printf(mon, "]\n");
 115    }
 116
 117    if (info->has_postcopy_latency_dist) {
 118        uint64List *item = info->postcopy_latency_dist;
 119        int count = 0;
 120
 121        monitor_printf(mon, "Postcopy Latency Distribution:\n");
 122
 123        while (item) {
 124            g_autofree const gchar *from = format_time_str(1UL << count);
 125            g_autofree const gchar *to = format_time_str(1UL << (count + 1));
 126
 127            monitor_printf(mon, "  [ %8s - %8s ]: %10"PRIu64"\n",
 128                           from, to, item->value);
 129            item = item->next;
 130            count++;
 131        }
 132    }
 133}
 134
 135void hmp_info_migrate(Monitor *mon, const QDict *qdict)
 136{
 137    bool show_all = qdict_get_try_bool(qdict, "all", false);
 138    MigrationInfo *info;
 139
 140    info = qmp_query_migrate(NULL);
 141
 142    if (info->blocked_reasons) {
 143        strList *reasons = info->blocked_reasons;
 144        monitor_printf(mon, "Outgoing migration blocked:\n");
 145        while (reasons) {
 146            monitor_printf(mon, "  %s\n", reasons->value);
 147            reasons = reasons->next;
 148        }
 149    }
 150
 151    if (info->has_status) {
 152        monitor_printf(mon, "Status: \t\t%s",
 153                       MigrationStatus_str(info->status));
 154        if ((info->status == MIGRATION_STATUS_FAILED ||
 155             info->status == MIGRATION_STATUS_POSTCOPY_PAUSED) &&
 156            info->error_desc) {
 157            monitor_printf(mon, " (%s)\n", info->error_desc);
 158        } else {
 159            monitor_printf(mon, "\n");
 160        }
 161
 162        if (info->total_time) {
 163            monitor_printf(mon, "Time (ms): \t\ttotal=%" PRIu64,
 164                           info->total_time);
 165            if (info->has_setup_time) {
 166                monitor_printf(mon, ", setup=%" PRIu64,
 167                               info->setup_time);
 168            }
 169            if (info->has_expected_downtime) {
 170                monitor_printf(mon, ", exp_down=%" PRIu64,
 171                               info->expected_downtime);
 172            }
 173            if (info->has_downtime) {
 174                monitor_printf(mon, ", down=%" PRIu64,
 175                               info->downtime);
 176            }
 177            monitor_printf(mon, "\n");
 178        }
 179    }
 180
 181    if (info->has_socket_address) {
 182        SocketAddressList *addr;
 183
 184        monitor_printf(mon, "Sockets: [\n");
 185
 186        for (addr = info->socket_address; addr; addr = addr->next) {
 187            char *s = socket_uri(addr->value);
 188            monitor_printf(mon, "\t%s\n", s);
 189            g_free(s);
 190        }
 191        monitor_printf(mon, "]\n");
 192    }
 193
 194    if (info->ram) {
 195        g_autofree char *str_psize = size_to_str(info->ram->page_size);
 196        g_autofree char *str_total = size_to_str(info->ram->total);
 197        g_autofree char *str_transferred = size_to_str(info->ram->transferred);
 198        g_autofree char *str_remaining = size_to_str(info->ram->remaining);
 199        g_autofree char *str_precopy = size_to_str(info->ram->precopy_bytes);
 200        g_autofree char *str_multifd = size_to_str(info->ram->multifd_bytes);
 201        g_autofree char *str_postcopy = size_to_str(info->ram->postcopy_bytes);
 202
 203        monitor_printf(mon, "RAM info:\n");
 204        monitor_printf(mon, "  Throughput (Mbps): \t%0.2f\n",
 205                       info->ram->mbps);
 206        monitor_printf(mon, "  Sizes: \t\tpagesize=%s, total=%s\n",
 207                       str_psize, str_total);
 208        monitor_printf(mon, "  Transfers: \t\ttransferred=%s, remain=%s\n",
 209                       str_transferred, str_remaining);
 210        monitor_printf(mon, "    Channels: \t\tprecopy=%s, "
 211                       "multifd=%s, postcopy=%s",
 212                       str_precopy, str_multifd, str_postcopy);
 213
 214        if (info->vfio) {
 215            g_autofree char *str_vfio = size_to_str(info->vfio->transferred);
 216
 217            monitor_printf(mon, ", vfio=%s", str_vfio);
 218        }
 219        monitor_printf(mon, "\n");
 220
 221        monitor_printf(mon, "    Page Types: \tnormal=%" PRIu64
 222                       ", zero=%" PRIu64 "\n",
 223                       info->ram->normal, info->ram->duplicate);
 224        monitor_printf(mon, "  Page Rates (pps): \ttransfer=%" PRIu64,
 225                       info->ram->pages_per_second);
 226        if (info->ram->dirty_pages_rate) {
 227            monitor_printf(mon, ", dirty=%" PRIu64,
 228                           info->ram->dirty_pages_rate);
 229        }
 230        monitor_printf(mon, "\n");
 231
 232        monitor_printf(mon, "  Others: \t\tdirty_syncs=%" PRIu64,
 233                       info->ram->dirty_sync_count);
 234        if (info->ram->postcopy_requests) {
 235            monitor_printf(mon, ", postcopy_req=%" PRIu64,
 236                           info->ram->postcopy_requests);
 237        }
 238        if (info->ram->downtime_bytes) {
 239            monitor_printf(mon, ", downtime_bytes=%" PRIu64,
 240                           info->ram->downtime_bytes);
 241        }
 242        if (info->ram->dirty_sync_missed_zero_copy) {
 243            monitor_printf(mon, ", zerocopy_fallbacks=%" PRIu64,
 244                           info->ram->dirty_sync_missed_zero_copy);
 245        }
 246        monitor_printf(mon, "\n");
 247    }
 248
 249    if (!show_all) {
 250        goto out;
 251    }
 252
 253    migration_global_dump(mon);
 254
 255    if (info->xbzrle_cache) {
 256        monitor_printf(mon, "XBZRLE: size=%" PRIu64
 257                       ", transferred=%" PRIu64
 258                       ", pages=%" PRIu64
 259                       ", miss=%" PRIu64 "\n"
 260                       "  miss_rate=%0.2f"
 261                       ", encode_rate=%0.2f"
 262                       ", overflow=%" PRIu64 "\n",
 263                       info->xbzrle_cache->cache_size,
 264                       info->xbzrle_cache->bytes,
 265                       info->xbzrle_cache->pages,
 266                       info->xbzrle_cache->cache_miss,
 267                       info->xbzrle_cache->cache_miss_rate,
 268                       info->xbzrle_cache->encoding_rate,
 269                       info->xbzrle_cache->overflow);
 270    }
 271
 272    if (info->has_cpu_throttle_percentage) {
 273        monitor_printf(mon, "CPU Throttle (%%): %" PRIu64 "\n",
 274                       info->cpu_throttle_percentage);
 275    }
 276
 277    if (info->has_dirty_limit_throttle_time_per_round) {
 278        monitor_printf(mon, "Dirty-limit Throttle (us): %" PRIu64 "\n",
 279                       info->dirty_limit_throttle_time_per_round);
 280    }
 281
 282    if (info->has_dirty_limit_ring_full_time) {
 283        monitor_printf(mon, "Dirty-limit Ring Full (us): %" PRIu64 "\n",
 284                       info->dirty_limit_ring_full_time);
 285    }
 286
 287    migration_dump_blocktime(mon, info);
 288out:
 289    qapi_free_MigrationInfo(info);
 290}
 291
 292void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
 293{
 294    MigrationCapabilityStatusList *caps, *cap;
 295
 296    caps = qmp_query_migrate_capabilities(NULL);
 297
 298    if (caps) {
 299        for (cap = caps; cap; cap = cap->next) {
 300            monitor_printf(mon, "%s: %s\n",
 301                           MigrationCapability_str(cap->value->capability),
 302                           cap->value->state ? "on" : "off");
 303        }
 304    }
 305
 306    qapi_free_MigrationCapabilityStatusList(caps);
 307}
 308
 309void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
 310{
 311    MigrationParameters *params;
 312
 313    params = qmp_query_migrate_parameters(NULL);
 314
 315    if (params) {
 316        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
 317            MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL),
 318            params->announce_initial);
 319        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
 320            MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX),
 321            params->announce_max);
 322        monitor_printf(mon, "%s: %" PRIu64 "\n",
 323            MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS),
 324            params->announce_rounds);
 325        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
 326            MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP),
 327            params->announce_step);
 328        assert(params->has_throttle_trigger_threshold);
 329        monitor_printf(mon, "%s: %u\n",
 330            MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD),
 331            params->throttle_trigger_threshold);
 332        assert(params->has_cpu_throttle_initial);
 333        monitor_printf(mon, "%s: %u\n",
 334            MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL),
 335            params->cpu_throttle_initial);
 336        assert(params->has_cpu_throttle_increment);
 337        monitor_printf(mon, "%s: %u\n",
 338            MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT),
 339            params->cpu_throttle_increment);
 340        assert(params->has_cpu_throttle_tailslow);
 341        monitor_printf(mon, "%s: %s\n",
 342            MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW),
 343            params->cpu_throttle_tailslow ? "on" : "off");
 344        assert(params->has_max_cpu_throttle);
 345        monitor_printf(mon, "%s: %u\n",
 346            MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE),
 347            params->max_cpu_throttle);
 348        assert(params->tls_creds);
 349        monitor_printf(mon, "%s: '%s'\n",
 350            MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS),
 351            params->tls_creds);
 352        assert(params->tls_hostname);
 353        monitor_printf(mon, "%s: '%s'\n",
 354            MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME),
 355            params->tls_hostname);
 356        assert(params->has_max_bandwidth);
 357        monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
 358            MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
 359            params->max_bandwidth);
 360        assert(params->has_avail_switchover_bandwidth);
 361        monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
 362            MigrationParameter_str(MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH),
 363            params->avail_switchover_bandwidth);
 364        assert(params->has_downtime_limit);
 365        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
 366            MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
 367            params->downtime_limit);
 368        assert(params->has_x_checkpoint_delay);
 369        monitor_printf(mon, "%s: %u ms\n",
 370            MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
 371            params->x_checkpoint_delay);
 372        monitor_printf(mon, "%s: %u\n",
 373            MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
 374            params->multifd_channels);
 375        monitor_printf(mon, "%s: %s\n",
 376            MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
 377            MultiFDCompression_str(params->multifd_compression));
 378        assert(params->has_zero_page_detection);
 379        monitor_printf(mon, "%s: %s\n",
 380            MigrationParameter_str(MIGRATION_PARAMETER_ZERO_PAGE_DETECTION),
 381            qapi_enum_lookup(&ZeroPageDetection_lookup,
 382                params->zero_page_detection));
 383        monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
 384            MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
 385            params->xbzrle_cache_size);
 386        monitor_printf(mon, "%s: %" PRIu64 "\n",
 387            MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
 388            params->max_postcopy_bandwidth);
 389        monitor_printf(mon, "%s: '%s'\n",
 390            MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
 391            params->tls_authz);
 392
 393        if (params->has_block_bitmap_mapping) {
 394            const BitmapMigrationNodeAliasList *bmnal;
 395
 396            monitor_printf(mon, "%s:\n",
 397                           MigrationParameter_str(
 398                               MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
 399
 400            for (bmnal = params->block_bitmap_mapping;
 401                 bmnal;
 402                 bmnal = bmnal->next)
 403            {
 404                const BitmapMigrationNodeAlias *bmna = bmnal->value;
 405                const BitmapMigrationBitmapAliasList *bmbal;
 406
 407                monitor_printf(mon, "  '%s' -> '%s'\n",
 408                               bmna->node_name, bmna->alias);
 409
 410                for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
 411                    const BitmapMigrationBitmapAlias *bmba = bmbal->value;
 412
 413                    monitor_printf(mon, "    '%s' -> '%s'\n",
 414                                   bmba->name, bmba->alias);
 415                }
 416            }
 417        }
 418
 419        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
 420        MigrationParameter_str(MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD),
 421        params->x_vcpu_dirty_limit_period);
 422
 423        monitor_printf(mon, "%s: %" PRIu64 " MB/s\n",
 424            MigrationParameter_str(MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT),
 425            params->vcpu_dirty_limit);
 426
 427        assert(params->has_mode);
 428        monitor_printf(mon, "%s: %s\n",
 429            MigrationParameter_str(MIGRATION_PARAMETER_MODE),
 430            qapi_enum_lookup(&MigMode_lookup, params->mode));
 431
 432        if (params->has_direct_io) {
 433            monitor_printf(mon, "%s: %s\n",
 434                           MigrationParameter_str(
 435                               MIGRATION_PARAMETER_DIRECT_IO),
 436                           params->direct_io ? "on" : "off");
 437        }
 438    }
 439
 440    qapi_free_MigrationParameters(params);
 441}
 442
 443void hmp_loadvm(Monitor *mon, const QDict *qdict)
 444{
 445    RunState saved_state = runstate_get();
 446
 447    const char *name = qdict_get_str(qdict, "name");
 448    Error *err = NULL;
 449
 450    vm_stop(RUN_STATE_RESTORE_VM);
 451
 452    if (load_snapshot(name, NULL, false, NULL, &err)) {
 453        load_snapshot_resume(saved_state);
 454    }
 455
 456    hmp_handle_error(mon, err);
 457}
 458
 459void hmp_savevm(Monitor *mon, const QDict *qdict)
 460{
 461    Error *err = NULL;
 462
 463    save_snapshot(qdict_get_try_str(qdict, "name"),
 464                  true, NULL, false, NULL, &err);
 465    hmp_handle_error(mon, err);
 466}
 467
 468void hmp_delvm(Monitor *mon, const QDict *qdict)
 469{
 470    Error *err = NULL;
 471    const char *name = qdict_get_str(qdict, "name");
 472
 473    delete_snapshot(name, false, NULL, &err);
 474    hmp_handle_error(mon, err);
 475}
 476
 477void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
 478{
 479    qmp_migrate_cancel(NULL);
 480}
 481
 482void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
 483{
 484    Error *err = NULL;
 485    const char *state = qdict_get_str(qdict, "state");
 486    int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
 487
 488    if (val >= 0) {
 489        qmp_migrate_continue(val, &err);
 490    }
 491
 492    hmp_handle_error(mon, err);
 493}
 494
 495void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
 496{
 497    Error *err = NULL;
 498    const char *uri = qdict_get_str(qdict, "uri");
 499    MigrationChannelList *caps = NULL;
 500    g_autoptr(MigrationChannel) channel = NULL;
 501
 502    if (!migrate_uri_parse(uri, &channel, &err)) {
 503        goto end;
 504    }
 505    QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
 506
 507    qmp_migrate_incoming(NULL, true, caps, true, false, &err);
 508    qapi_free_MigrationChannelList(caps);
 509
 510end:
 511    hmp_handle_error(mon, err);
 512}
 513
 514void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
 515{
 516    Error *err = NULL;
 517    const char *uri = qdict_get_str(qdict, "uri");
 518
 519    qmp_migrate_recover(uri, &err);
 520
 521    hmp_handle_error(mon, err);
 522}
 523
 524void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
 525{
 526    Error *err = NULL;
 527
 528    qmp_migrate_pause(&err);
 529
 530    hmp_handle_error(mon, err);
 531}
 532
 533
 534void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
 535{
 536    const char *cap = qdict_get_str(qdict, "capability");
 537    bool state = qdict_get_bool(qdict, "state");
 538    Error *err = NULL;
 539    MigrationCapabilityStatusList *caps = NULL;
 540    MigrationCapabilityStatus *value;
 541    int val;
 542
 543    val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
 544    if (val < 0) {
 545        goto end;
 546    }
 547
 548    value = g_malloc0(sizeof(*value));
 549    value->capability = val;
 550    value->state = state;
 551    QAPI_LIST_PREPEND(caps, value);
 552    qmp_migrate_set_capabilities(caps, &err);
 553    qapi_free_MigrationCapabilityStatusList(caps);
 554
 555end:
 556    hmp_handle_error(mon, err);
 557}
 558
 559void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
 560{
 561    const char *param = qdict_get_str(qdict, "parameter");
 562    const char *valuestr = qdict_get_str(qdict, "value");
 563    Visitor *v = string_input_visitor_new(valuestr);
 564    MigrateSetParameters *p = g_new0(MigrateSetParameters, 1);
 565    uint64_t valuebw = 0;
 566    uint64_t cache_size;
 567    Error *err = NULL;
 568    int val, ret;
 569
 570    val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err);
 571    if (val < 0) {
 572        goto cleanup;
 573    }
 574
 575    switch (val) {
 576    case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD:
 577        p->has_throttle_trigger_threshold = true;
 578        visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err);
 579        break;
 580    case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL:
 581        p->has_cpu_throttle_initial = true;
 582        visit_type_uint8(v, param, &p->cpu_throttle_initial, &err);
 583        break;
 584    case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
 585        p->has_cpu_throttle_increment = true;
 586        visit_type_uint8(v, param, &p->cpu_throttle_increment, &err);
 587        break;
 588    case MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW:
 589        p->has_cpu_throttle_tailslow = true;
 590        visit_type_bool(v, param, &p->cpu_throttle_tailslow, &err);
 591        break;
 592    case MIGRATION_PARAMETER_MAX_CPU_THROTTLE:
 593        p->has_max_cpu_throttle = true;
 594        visit_type_uint8(v, param, &p->max_cpu_throttle, &err);
 595        break;
 596    case MIGRATION_PARAMETER_TLS_CREDS:
 597        p->tls_creds = g_new0(StrOrNull, 1);
 598        p->tls_creds->type = QTYPE_QSTRING;
 599        visit_type_str(v, param, &p->tls_creds->u.s, &err);
 600        break;
 601    case MIGRATION_PARAMETER_TLS_HOSTNAME:
 602        p->tls_hostname = g_new0(StrOrNull, 1);
 603        p->tls_hostname->type = QTYPE_QSTRING;
 604        visit_type_str(v, param, &p->tls_hostname->u.s, &err);
 605        break;
 606    case MIGRATION_PARAMETER_TLS_AUTHZ:
 607        p->tls_authz = g_new0(StrOrNull, 1);
 608        p->tls_authz->type = QTYPE_QSTRING;
 609        visit_type_str(v, param, &p->tls_authz->u.s, &err);
 610        break;
 611    case MIGRATION_PARAMETER_MAX_BANDWIDTH:
 612        p->has_max_bandwidth = true;
 613        /*
 614         * Can't use visit_type_size() here, because it
 615         * defaults to Bytes rather than Mebibytes.
 616         */
 617        ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
 618        if (ret < 0 || valuebw > INT64_MAX
 619            || (size_t)valuebw != valuebw) {
 620            error_setg(&err, "Invalid size %s", valuestr);
 621            break;
 622        }
 623        p->max_bandwidth = valuebw;
 624        break;
 625    case MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH:
 626        p->has_avail_switchover_bandwidth = true;
 627        ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
 628        if (ret < 0 || valuebw > INT64_MAX
 629            || (size_t)valuebw != valuebw) {
 630            error_setg(&err, "Invalid size %s", valuestr);
 631            break;
 632        }
 633        p->avail_switchover_bandwidth = valuebw;
 634        break;
 635    case MIGRATION_PARAMETER_DOWNTIME_LIMIT:
 636        p->has_downtime_limit = true;
 637        visit_type_size(v, param, &p->downtime_limit, &err);
 638        break;
 639    case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY:
 640        p->has_x_checkpoint_delay = true;
 641        visit_type_uint32(v, param, &p->x_checkpoint_delay, &err);
 642        break;
 643    case MIGRATION_PARAMETER_MULTIFD_CHANNELS:
 644        p->has_multifd_channels = true;
 645        visit_type_uint8(v, param, &p->multifd_channels, &err);
 646        break;
 647    case MIGRATION_PARAMETER_MULTIFD_COMPRESSION:
 648        p->has_multifd_compression = true;
 649        visit_type_MultiFDCompression(v, param, &p->multifd_compression,
 650                                      &err);
 651        break;
 652    case MIGRATION_PARAMETER_MULTIFD_ZLIB_LEVEL:
 653        p->has_multifd_zlib_level = true;
 654        visit_type_uint8(v, param, &p->multifd_zlib_level, &err);
 655        break;
 656    case MIGRATION_PARAMETER_MULTIFD_QATZIP_LEVEL:
 657        p->has_multifd_qatzip_level = true;
 658        visit_type_uint8(v, param, &p->multifd_qatzip_level, &err);
 659        break;
 660    case MIGRATION_PARAMETER_MULTIFD_ZSTD_LEVEL:
 661        p->has_multifd_zstd_level = true;
 662        visit_type_uint8(v, param, &p->multifd_zstd_level, &err);
 663        break;
 664    case MIGRATION_PARAMETER_ZERO_PAGE_DETECTION:
 665        p->has_zero_page_detection = true;
 666        visit_type_ZeroPageDetection(v, param, &p->zero_page_detection, &err);
 667        break;
 668    case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
 669        p->has_xbzrle_cache_size = true;
 670        if (!visit_type_size(v, param, &cache_size, &err)) {
 671            break;
 672        }
 673        if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) {
 674            error_setg(&err, "Invalid size %s", valuestr);
 675            break;
 676        }
 677        p->xbzrle_cache_size = cache_size;
 678        break;
 679    case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH:
 680        p->has_max_postcopy_bandwidth = true;
 681        visit_type_size(v, param, &p->max_postcopy_bandwidth, &err);
 682        break;
 683    case MIGRATION_PARAMETER_ANNOUNCE_INITIAL:
 684        p->has_announce_initial = true;
 685        visit_type_size(v, param, &p->announce_initial, &err);
 686        break;
 687    case MIGRATION_PARAMETER_ANNOUNCE_MAX:
 688        p->has_announce_max = true;
 689        visit_type_size(v, param, &p->announce_max, &err);
 690        break;
 691    case MIGRATION_PARAMETER_ANNOUNCE_ROUNDS:
 692        p->has_announce_rounds = true;
 693        visit_type_size(v, param, &p->announce_rounds, &err);
 694        break;
 695    case MIGRATION_PARAMETER_ANNOUNCE_STEP:
 696        p->has_announce_step = true;
 697        visit_type_size(v, param, &p->announce_step, &err);
 698        break;
 699    case MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING:
 700        error_setg(&err, "The block-bitmap-mapping parameter can only be set "
 701                   "through QMP");
 702        break;
 703    case MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD:
 704        p->has_x_vcpu_dirty_limit_period = true;
 705        visit_type_size(v, param, &p->x_vcpu_dirty_limit_period, &err);
 706        break;
 707    case MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT:
 708        p->has_vcpu_dirty_limit = true;
 709        visit_type_size(v, param, &p->vcpu_dirty_limit, &err);
 710        break;
 711    case MIGRATION_PARAMETER_MODE:
 712        p->has_mode = true;
 713        visit_type_MigMode(v, param, &p->mode, &err);
 714        break;
 715    case MIGRATION_PARAMETER_DIRECT_IO:
 716        p->has_direct_io = true;
 717        visit_type_bool(v, param, &p->direct_io, &err);
 718        break;
 719    default:
 720        g_assert_not_reached();
 721    }
 722
 723    if (err) {
 724        goto cleanup;
 725    }
 726
 727    qmp_migrate_set_parameters(p, &err);
 728
 729 cleanup:
 730    qapi_free_MigrateSetParameters(p);
 731    visit_free(v);
 732    hmp_handle_error(mon, err);
 733}
 734
 735void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
 736{
 737    Error *err = NULL;
 738    qmp_migrate_start_postcopy(&err);
 739    hmp_handle_error(mon, err);
 740}
 741
 742#ifdef CONFIG_REPLICATION
 743void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
 744{
 745    Error *err = NULL;
 746
 747    qmp_x_colo_lost_heartbeat(&err);
 748    hmp_handle_error(mon, err);
 749}
 750#endif
 751
 752typedef struct HMPMigrationStatus {
 753    QEMUTimer *timer;
 754    Monitor *mon;
 755} HMPMigrationStatus;
 756
 757static void hmp_migrate_status_cb(void *opaque)
 758{
 759    HMPMigrationStatus *status = opaque;
 760    MigrationInfo *info;
 761
 762    info = qmp_query_migrate(NULL);
 763    if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
 764        info->status == MIGRATION_STATUS_SETUP) {
 765        timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
 766    } else {
 767        if (info->error_desc) {
 768            error_report("%s", info->error_desc);
 769        }
 770        monitor_resume(status->mon);
 771        timer_free(status->timer);
 772        g_free(status);
 773    }
 774
 775    qapi_free_MigrationInfo(info);
 776}
 777
 778void hmp_migrate(Monitor *mon, const QDict *qdict)
 779{
 780    bool detach = qdict_get_try_bool(qdict, "detach", false);
 781    bool resume = qdict_get_try_bool(qdict, "resume", false);
 782    const char *uri = qdict_get_str(qdict, "uri");
 783    Error *err = NULL;
 784    g_autoptr(MigrationChannelList) caps = NULL;
 785    g_autoptr(MigrationChannel) channel = NULL;
 786
 787    if (!migrate_uri_parse(uri, &channel, &err)) {
 788        hmp_handle_error(mon, err);
 789        return;
 790    }
 791    QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
 792
 793    qmp_migrate(NULL, true, caps, false, false, true, resume, &err);
 794    if (hmp_handle_error(mon, err)) {
 795        return;
 796    }
 797
 798    if (!detach) {
 799        HMPMigrationStatus *status;
 800
 801        if (monitor_suspend(mon) < 0) {
 802            monitor_printf(mon, "terminal does not allow synchronous "
 803                           "migration, continuing detached\n");
 804            return;
 805        }
 806
 807        status = g_malloc0(sizeof(*status));
 808        status->mon = mon;
 809        status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
 810                                          status);
 811        timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
 812    }
 813}
 814
 815void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
 816                                       const char *str)
 817{
 818    size_t len;
 819
 820    len = strlen(str);
 821    readline_set_completion_index(rs, len);
 822    if (nb_args == 2) {
 823        int i;
 824        for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
 825            readline_add_completion_of(rs, str, MigrationCapability_str(i));
 826        }
 827    } else if (nb_args == 3) {
 828        readline_add_completion_of(rs, str, "on");
 829        readline_add_completion_of(rs, str, "off");
 830    }
 831}
 832
 833void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
 834                                      const char *str)
 835{
 836    size_t len;
 837
 838    len = strlen(str);
 839    readline_set_completion_index(rs, len);
 840    if (nb_args == 2) {
 841        int i;
 842        for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) {
 843            readline_add_completion_of(rs, str, MigrationParameter_str(i));
 844        }
 845    }
 846}
 847
 848static void vm_completion(ReadLineState *rs, const char *str)
 849{
 850    size_t len;
 851    BlockDriverState *bs;
 852    BdrvNextIterator it;
 853
 854    GRAPH_RDLOCK_GUARD_MAINLOOP();
 855
 856    len = strlen(str);
 857    readline_set_completion_index(rs, len);
 858
 859    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
 860        SnapshotInfoList *snapshots, *snapshot;
 861        bool ok = false;
 862
 863        if (bdrv_can_snapshot(bs)) {
 864            ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0;
 865        }
 866        if (!ok) {
 867            continue;
 868        }
 869
 870        snapshot = snapshots;
 871        while (snapshot) {
 872            readline_add_completion_of(rs, str, snapshot->value->name);
 873            readline_add_completion_of(rs, str, snapshot->value->id);
 874            snapshot = snapshot->next;
 875        }
 876        qapi_free_SnapshotInfoList(snapshots);
 877    }
 878
 879}
 880
 881void delvm_completion(ReadLineState *rs, int nb_args, const char *str)
 882{
 883    if (nb_args == 2) {
 884        vm_completion(rs, str);
 885    }
 886}
 887
 888void loadvm_completion(ReadLineState *rs, int nb_args, const char *str)
 889{
 890    if (nb_args == 2) {
 891        vm_completion(rs, str);
 892    }
 893}
 894