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