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