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 static 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) { 61 us /= 1000; 62 if (++index >= (sizeof(units) - 1)) { 63 break; 64 } 65 } 66 67 return g_strdup_printf("%"PRIu64" %s", us, units[index]); 68 } 69 70 static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info) 71 { 72 if (info->has_postcopy_blocktime) { 73 monitor_printf(mon, "Postcopy Blocktime (ms): %" PRIu32 "\n", 74 info->postcopy_blocktime); 75 } 76 77 if (info->has_postcopy_vcpu_blocktime) { 78 uint32List *item = info->postcopy_vcpu_blocktime; 79 const char *sep = ""; 80 int count = 0; 81 82 monitor_printf(mon, "Postcopy vCPU Blocktime (ms):\n ["); 83 84 while (item) { 85 monitor_printf(mon, "%s%"PRIu32, sep, item->value); 86 item = item->next; 87 /* Each line 10 vcpu results, newline if there's more */ 88 sep = ((++count % 10 == 0) && item) ? ",\n " : ", "; 89 } 90 monitor_printf(mon, "]\n"); 91 } 92 93 if (info->has_postcopy_latency) { 94 monitor_printf(mon, "Postcopy Latency (ns): %" PRIu64 "\n", 95 info->postcopy_latency); 96 } 97 98 if (info->has_postcopy_non_vcpu_latency) { 99 monitor_printf(mon, "Postcopy non-vCPU Latencies (ns): %" PRIu64 "\n", 100 info->postcopy_non_vcpu_latency); 101 } 102 103 if (info->has_postcopy_vcpu_latency) { 104 uint64List *item = info->postcopy_vcpu_latency; 105 const char *sep = ""; 106 int count = 0; 107 108 monitor_printf(mon, "Postcopy vCPU Latencies (ns):\n ["); 109 110 while (item) { 111 monitor_printf(mon, "%s%"PRIu64, sep, item->value); 112 item = item->next; 113 /* Each line 10 vcpu results, newline if there's more */ 114 sep = ((++count % 10 == 0) && item) ? ",\n " : ", "; 115 } 116 monitor_printf(mon, "]\n"); 117 } 118 119 if (info->has_postcopy_latency_dist) { 120 uint64List *item = info->postcopy_latency_dist; 121 int count = 0; 122 123 monitor_printf(mon, "Postcopy Latency Distribution:\n"); 124 125 while (item) { 126 g_autofree const gchar *from = format_time_str(1UL << count); 127 g_autofree const gchar *to = format_time_str(1UL << (count + 1)); 128 129 monitor_printf(mon, " [ %8s - %8s ]: %10"PRIu64"\n", 130 from, to, item->value); 131 item = item->next; 132 count++; 133 } 134 } 135 } 136 137 void hmp_info_migrate(Monitor *mon, const QDict *qdict) 138 { 139 bool show_all = qdict_get_try_bool(qdict, "all", false); 140 MigrationInfo *info; 141 142 info = qmp_query_migrate(NULL); 143 144 if (info->blocked_reasons) { 145 strList *reasons = info->blocked_reasons; 146 monitor_printf(mon, "Outgoing migration blocked:\n"); 147 while (reasons) { 148 monitor_printf(mon, " %s\n", reasons->value); 149 reasons = reasons->next; 150 } 151 } 152 153 if (info->has_status) { 154 monitor_printf(mon, "Status: \t\t%s", 155 MigrationStatus_str(info->status)); 156 if (info->status == MIGRATION_STATUS_FAILED && 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); 288 out: 289 qapi_free_MigrationInfo(info); 290 } 291 292 void 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 309 void 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 443 void 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 459 void 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 468 void 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 477 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict) 478 { 479 qmp_migrate_cancel(NULL); 480 } 481 482 void 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 495 void 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 510 end: 511 hmp_handle_error(mon, err); 512 } 513 514 void 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 524 void 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 534 void 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 555 end: 556 hmp_handle_error(mon, err); 557 } 558 559 void 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 735 void 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 743 void 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 752 typedef struct HMPMigrationStatus { 753 QEMUTimer *timer; 754 Monitor *mon; 755 } HMPMigrationStatus; 756 757 static 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 778 void 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 815 void 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 833 void 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 848 static 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 881 void delvm_completion(ReadLineState *rs, int nb_args, const char *str) 882 { 883 if (nb_args == 2) { 884 vm_completion(rs, str); 885 } 886 } 887 888 void loadvm_completion(ReadLineState *rs, int nb_args, const char *str) 889 { 890 if (nb_args == 2) { 891 vm_completion(rs, str); 892 } 893 } 894