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