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