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