1 /* 2 * QEMU migration capabilities 3 * 4 * Copyright (c) 2012-2023 Red Hat Inc 5 * 6 * Authors: 7 * Orit Wasserman <owasserm@redhat.com> 8 * Juan Quintela <quintela@redhat.com> 9 * 10 * This work is licensed under the terms of the GNU GPL, version 2 or later. 11 * See the COPYING file in the top-level directory. 12 */ 13 14 #include "qemu/osdep.h" 15 #include "exec/target_page.h" 16 #include "qapi/clone-visitor.h" 17 #include "qapi/error.h" 18 #include "qapi/qapi-commands-migration.h" 19 #include "qapi/qapi-visit-migration.h" 20 #include "qapi/qmp/qerror.h" 21 #include "qapi/qmp/qnull.h" 22 #include "sysemu/runstate.h" 23 #include "migration/colo.h" 24 #include "migration/misc.h" 25 #include "migration.h" 26 #include "qemu-file.h" 27 #include "ram.h" 28 #include "options.h" 29 30 /* Maximum migrate downtime set to 2000 seconds */ 31 #define MAX_MIGRATE_DOWNTIME_SECONDS 2000 32 #define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000) 33 34 #define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */ 35 36 /* Time in milliseconds we are allowed to stop the source, 37 * for sending the last part */ 38 #define DEFAULT_MIGRATE_SET_DOWNTIME 300 39 40 /* Default compression thread count */ 41 #define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8 42 /* Default decompression thread count, usually decompression is at 43 * least 4 times as fast as compression.*/ 44 #define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2 45 /*0: means nocompress, 1: best speed, ... 9: best compress ratio */ 46 #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1 47 /* Define default autoconverge cpu throttle migration parameters */ 48 #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50 49 #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20 50 #define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10 51 #define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99 52 53 /* Migration XBZRLE default cache size */ 54 #define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024) 55 56 /* The delay time (in ms) between two COLO checkpoints */ 57 #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100) 58 #define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2 59 #define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE 60 /* 0: means nocompress, 1: best speed, ... 9: best compress ratio */ 61 #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1 62 /* 0: means nocompress, 1: best speed, ... 20: best compress ratio */ 63 #define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1 64 65 /* Background transfer rate for postcopy, 0 means unlimited, note 66 * that page requests can still exceed this limit. 67 */ 68 #define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0 69 70 /* 71 * Parameters for self_announce_delay giving a stream of RARP/ARP 72 * packets after migration. 73 */ 74 #define DEFAULT_MIGRATE_ANNOUNCE_INITIAL 50 75 #define DEFAULT_MIGRATE_ANNOUNCE_MAX 550 76 #define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS 5 77 #define DEFAULT_MIGRATE_ANNOUNCE_STEP 100 78 79 #define DEFINE_PROP_MIG_CAP(name, x) \ 80 DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false) 81 82 Property migration_properties[] = { 83 DEFINE_PROP_BOOL("store-global-state", MigrationState, 84 store_global_state, true), 85 DEFINE_PROP_BOOL("send-configuration", MigrationState, 86 send_configuration, true), 87 DEFINE_PROP_BOOL("send-section-footer", MigrationState, 88 send_section_footer, true), 89 DEFINE_PROP_BOOL("decompress-error-check", MigrationState, 90 decompress_error_check, true), 91 DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState, 92 multifd_flush_after_each_section, false), 93 DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState, 94 clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT), 95 DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState, 96 preempt_pre_7_2, false), 97 98 /* Migration parameters */ 99 DEFINE_PROP_UINT8("x-compress-level", MigrationState, 100 parameters.compress_level, 101 DEFAULT_MIGRATE_COMPRESS_LEVEL), 102 DEFINE_PROP_UINT8("x-compress-threads", MigrationState, 103 parameters.compress_threads, 104 DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT), 105 DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState, 106 parameters.compress_wait_thread, true), 107 DEFINE_PROP_UINT8("x-decompress-threads", MigrationState, 108 parameters.decompress_threads, 109 DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT), 110 DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState, 111 parameters.throttle_trigger_threshold, 112 DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD), 113 DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState, 114 parameters.cpu_throttle_initial, 115 DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL), 116 DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState, 117 parameters.cpu_throttle_increment, 118 DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT), 119 DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState, 120 parameters.cpu_throttle_tailslow, false), 121 DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState, 122 parameters.max_bandwidth, MAX_THROTTLE), 123 DEFINE_PROP_UINT64("x-downtime-limit", MigrationState, 124 parameters.downtime_limit, 125 DEFAULT_MIGRATE_SET_DOWNTIME), 126 DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState, 127 parameters.x_checkpoint_delay, 128 DEFAULT_MIGRATE_X_CHECKPOINT_DELAY), 129 DEFINE_PROP_UINT8("multifd-channels", MigrationState, 130 parameters.multifd_channels, 131 DEFAULT_MIGRATE_MULTIFD_CHANNELS), 132 DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState, 133 parameters.multifd_compression, 134 DEFAULT_MIGRATE_MULTIFD_COMPRESSION), 135 DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState, 136 parameters.multifd_zlib_level, 137 DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL), 138 DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState, 139 parameters.multifd_zstd_level, 140 DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL), 141 DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState, 142 parameters.xbzrle_cache_size, 143 DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE), 144 DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState, 145 parameters.max_postcopy_bandwidth, 146 DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH), 147 DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState, 148 parameters.max_cpu_throttle, 149 DEFAULT_MIGRATE_MAX_CPU_THROTTLE), 150 DEFINE_PROP_SIZE("announce-initial", MigrationState, 151 parameters.announce_initial, 152 DEFAULT_MIGRATE_ANNOUNCE_INITIAL), 153 DEFINE_PROP_SIZE("announce-max", MigrationState, 154 parameters.announce_max, 155 DEFAULT_MIGRATE_ANNOUNCE_MAX), 156 DEFINE_PROP_SIZE("announce-rounds", MigrationState, 157 parameters.announce_rounds, 158 DEFAULT_MIGRATE_ANNOUNCE_ROUNDS), 159 DEFINE_PROP_SIZE("announce-step", MigrationState, 160 parameters.announce_step, 161 DEFAULT_MIGRATE_ANNOUNCE_STEP), 162 DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds), 163 DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname), 164 DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz), 165 166 /* Migration capabilities */ 167 DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE), 168 DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL), 169 DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE), 170 DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS), 171 DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS), 172 DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS), 173 DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM), 174 DEFINE_PROP_MIG_CAP("x-postcopy-preempt", 175 MIGRATION_CAPABILITY_POSTCOPY_PREEMPT), 176 DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO), 177 DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM), 178 DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK), 179 DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH), 180 DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD), 181 DEFINE_PROP_MIG_CAP("x-background-snapshot", 182 MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT), 183 #ifdef CONFIG_LINUX 184 DEFINE_PROP_MIG_CAP("x-zero-copy-send", 185 MIGRATION_CAPABILITY_ZERO_COPY_SEND), 186 #endif 187 188 DEFINE_PROP_END_OF_LIST(), 189 }; 190 191 bool migrate_auto_converge(void) 192 { 193 MigrationState *s = migrate_get_current(); 194 195 return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE]; 196 } 197 198 bool migrate_background_snapshot(void) 199 { 200 MigrationState *s = migrate_get_current(); 201 202 return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; 203 } 204 205 bool migrate_block(void) 206 { 207 MigrationState *s = migrate_get_current(); 208 209 return s->capabilities[MIGRATION_CAPABILITY_BLOCK]; 210 } 211 212 bool migrate_colo(void) 213 { 214 MigrationState *s = migrate_get_current(); 215 216 return s->capabilities[MIGRATION_CAPABILITY_X_COLO]; 217 } 218 219 bool migrate_compress(void) 220 { 221 MigrationState *s = migrate_get_current(); 222 223 return s->capabilities[MIGRATION_CAPABILITY_COMPRESS]; 224 } 225 226 bool migrate_dirty_bitmaps(void) 227 { 228 MigrationState *s = migrate_get_current(); 229 230 return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; 231 } 232 233 bool migrate_events(void) 234 { 235 MigrationState *s = migrate_get_current(); 236 237 return s->capabilities[MIGRATION_CAPABILITY_EVENTS]; 238 } 239 240 bool migrate_ignore_shared(void) 241 { 242 MigrationState *s = migrate_get_current(); 243 244 return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED]; 245 } 246 247 bool migrate_late_block_activate(void) 248 { 249 MigrationState *s = migrate_get_current(); 250 251 return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; 252 } 253 254 bool migrate_multifd(void) 255 { 256 MigrationState *s = migrate_get_current(); 257 258 return s->capabilities[MIGRATION_CAPABILITY_MULTIFD]; 259 } 260 261 bool migrate_pause_before_switchover(void) 262 { 263 MigrationState *s = migrate_get_current(); 264 265 return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER]; 266 } 267 268 bool migrate_postcopy_blocktime(void) 269 { 270 MigrationState *s = migrate_get_current(); 271 272 return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME]; 273 } 274 275 bool migrate_postcopy_preempt(void) 276 { 277 MigrationState *s = migrate_get_current(); 278 279 return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]; 280 } 281 282 bool migrate_postcopy_ram(void) 283 { 284 MigrationState *s = migrate_get_current(); 285 286 return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; 287 } 288 289 bool migrate_rdma_pin_all(void) 290 { 291 MigrationState *s = migrate_get_current(); 292 293 return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL]; 294 } 295 296 bool migrate_release_ram(void) 297 { 298 MigrationState *s = migrate_get_current(); 299 300 return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; 301 } 302 303 bool migrate_return_path(void) 304 { 305 MigrationState *s = migrate_get_current(); 306 307 return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH]; 308 } 309 310 bool migrate_validate_uuid(void) 311 { 312 MigrationState *s = migrate_get_current(); 313 314 return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; 315 } 316 317 bool migrate_xbzrle(void) 318 { 319 MigrationState *s = migrate_get_current(); 320 321 return s->capabilities[MIGRATION_CAPABILITY_XBZRLE]; 322 } 323 324 bool migrate_zero_blocks(void) 325 { 326 MigrationState *s = migrate_get_current(); 327 328 return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; 329 } 330 331 bool migrate_zero_copy_send(void) 332 { 333 MigrationState *s = migrate_get_current(); 334 335 return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; 336 } 337 338 /* pseudo capabilities */ 339 340 bool migrate_multifd_flush_after_each_section(void) 341 { 342 MigrationState *s = migrate_get_current(); 343 344 return s->multifd_flush_after_each_section; 345 } 346 347 bool migrate_postcopy(void) 348 { 349 return migrate_postcopy_ram() || migrate_dirty_bitmaps(); 350 } 351 352 bool migrate_tls(void) 353 { 354 MigrationState *s = migrate_get_current(); 355 356 return s->parameters.tls_creds && *s->parameters.tls_creds; 357 } 358 359 typedef enum WriteTrackingSupport { 360 WT_SUPPORT_UNKNOWN = 0, 361 WT_SUPPORT_ABSENT, 362 WT_SUPPORT_AVAILABLE, 363 WT_SUPPORT_COMPATIBLE 364 } WriteTrackingSupport; 365 366 static 367 WriteTrackingSupport migrate_query_write_tracking(void) 368 { 369 /* Check if kernel supports required UFFD features */ 370 if (!ram_write_tracking_available()) { 371 return WT_SUPPORT_ABSENT; 372 } 373 /* 374 * Check if current memory configuration is 375 * compatible with required UFFD features. 376 */ 377 if (!ram_write_tracking_compatible()) { 378 return WT_SUPPORT_AVAILABLE; 379 } 380 381 return WT_SUPPORT_COMPATIBLE; 382 } 383 384 /* Migration capabilities set */ 385 struct MigrateCapsSet { 386 int size; /* Capability set size */ 387 MigrationCapability caps[]; /* Variadic array of capabilities */ 388 }; 389 typedef struct MigrateCapsSet MigrateCapsSet; 390 391 /* Define and initialize MigrateCapsSet */ 392 #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...) \ 393 MigrateCapsSet _name = { \ 394 .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \ 395 .caps = { __VA_ARGS__ } \ 396 } 397 398 /* Background-snapshot compatibility check list */ 399 static const 400 INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot, 401 MIGRATION_CAPABILITY_POSTCOPY_RAM, 402 MIGRATION_CAPABILITY_DIRTY_BITMAPS, 403 MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME, 404 MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE, 405 MIGRATION_CAPABILITY_RETURN_PATH, 406 MIGRATION_CAPABILITY_MULTIFD, 407 MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER, 408 MIGRATION_CAPABILITY_AUTO_CONVERGE, 409 MIGRATION_CAPABILITY_RELEASE_RAM, 410 MIGRATION_CAPABILITY_RDMA_PIN_ALL, 411 MIGRATION_CAPABILITY_COMPRESS, 412 MIGRATION_CAPABILITY_XBZRLE, 413 MIGRATION_CAPABILITY_X_COLO, 414 MIGRATION_CAPABILITY_VALIDATE_UUID, 415 MIGRATION_CAPABILITY_ZERO_COPY_SEND); 416 417 /** 418 * @migration_caps_check - check capability compatibility 419 * 420 * @old_caps: old capability list 421 * @new_caps: new capability list 422 * @errp: set *errp if the check failed, with reason 423 * 424 * Returns true if check passed, otherwise false. 425 */ 426 bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) 427 { 428 MigrationIncomingState *mis = migration_incoming_get_current(); 429 430 ERRP_GUARD(); 431 #ifndef CONFIG_LIVE_BLOCK_MIGRATION 432 if (new_caps[MIGRATION_CAPABILITY_BLOCK]) { 433 error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) " 434 "block migration"); 435 error_append_hint(errp, "Use drive_mirror+NBD instead.\n"); 436 return false; 437 } 438 #endif 439 440 #ifndef CONFIG_REPLICATION 441 if (new_caps[MIGRATION_CAPABILITY_X_COLO]) { 442 error_setg(errp, "QEMU compiled without replication module" 443 " can't enable COLO"); 444 error_append_hint(errp, "Please enable replication before COLO.\n"); 445 return false; 446 } 447 #endif 448 449 if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { 450 /* This check is reasonably expensive, so only when it's being 451 * set the first time, also it's only the destination that needs 452 * special support. 453 */ 454 if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] && 455 runstate_check(RUN_STATE_INMIGRATE) && 456 !postcopy_ram_supported_by_host(mis, errp)) { 457 error_prepend(errp, "Postcopy is not supported: "); 458 return false; 459 } 460 461 if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) { 462 error_setg(errp, "Postcopy is not compatible with ignore-shared"); 463 return false; 464 } 465 466 if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { 467 error_setg(errp, "Postcopy is not yet compatible with multifd"); 468 return false; 469 } 470 } 471 472 if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) { 473 WriteTrackingSupport wt_support; 474 int idx; 475 /* 476 * Check if 'background-snapshot' capability is supported by 477 * host kernel and compatible with guest memory configuration. 478 */ 479 wt_support = migrate_query_write_tracking(); 480 if (wt_support < WT_SUPPORT_AVAILABLE) { 481 error_setg(errp, "Background-snapshot is not supported by host kernel"); 482 return false; 483 } 484 if (wt_support < WT_SUPPORT_COMPATIBLE) { 485 error_setg(errp, "Background-snapshot is not compatible " 486 "with guest memory configuration"); 487 return false; 488 } 489 490 /* 491 * Check if there are any migration capabilities 492 * incompatible with 'background-snapshot'. 493 */ 494 for (idx = 0; idx < check_caps_background_snapshot.size; idx++) { 495 int incomp_cap = check_caps_background_snapshot.caps[idx]; 496 if (new_caps[incomp_cap]) { 497 error_setg(errp, 498 "Background-snapshot is not compatible with %s", 499 MigrationCapability_str(incomp_cap)); 500 return false; 501 } 502 } 503 } 504 505 #ifdef CONFIG_LINUX 506 if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] && 507 (!new_caps[MIGRATION_CAPABILITY_MULTIFD] || 508 new_caps[MIGRATION_CAPABILITY_COMPRESS] || 509 new_caps[MIGRATION_CAPABILITY_XBZRLE] || 510 migrate_multifd_compression() || 511 migrate_tls())) { 512 error_setg(errp, 513 "Zero copy only available for non-compressed non-TLS multifd migration"); 514 return false; 515 } 516 #else 517 if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) { 518 error_setg(errp, 519 "Zero copy currently only available on Linux"); 520 return false; 521 } 522 #endif 523 524 if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) { 525 if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { 526 error_setg(errp, "Postcopy preempt requires postcopy-ram"); 527 return false; 528 } 529 530 /* 531 * Preempt mode requires urgent pages to be sent in separate 532 * channel, OTOH compression logic will disorder all pages into 533 * different compression channels, which is not compatible with the 534 * preempt assumptions on channel assignments. 535 */ 536 if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { 537 error_setg(errp, "Postcopy preempt not compatible with compress"); 538 return false; 539 } 540 } 541 542 if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { 543 if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { 544 error_setg(errp, "Multifd is not compatible with compress"); 545 return false; 546 } 547 } 548 549 return true; 550 } 551 552 bool migrate_cap_set(int cap, bool value, Error **errp) 553 { 554 MigrationState *s = migrate_get_current(); 555 bool new_caps[MIGRATION_CAPABILITY__MAX]; 556 557 if (migration_is_running(s->state)) { 558 error_setg(errp, QERR_MIGRATION_ACTIVE); 559 return false; 560 } 561 562 memcpy(new_caps, s->capabilities, sizeof(new_caps)); 563 new_caps[cap] = value; 564 565 if (!migrate_caps_check(s->capabilities, new_caps, errp)) { 566 return false; 567 } 568 s->capabilities[cap] = value; 569 return true; 570 } 571 572 MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) 573 { 574 MigrationCapabilityStatusList *head = NULL, **tail = &head; 575 MigrationCapabilityStatus *caps; 576 MigrationState *s = migrate_get_current(); 577 int i; 578 579 for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { 580 #ifndef CONFIG_LIVE_BLOCK_MIGRATION 581 if (i == MIGRATION_CAPABILITY_BLOCK) { 582 continue; 583 } 584 #endif 585 caps = g_malloc0(sizeof(*caps)); 586 caps->capability = i; 587 caps->state = s->capabilities[i]; 588 QAPI_LIST_APPEND(tail, caps); 589 } 590 591 return head; 592 } 593 594 void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, 595 Error **errp) 596 { 597 MigrationState *s = migrate_get_current(); 598 MigrationCapabilityStatusList *cap; 599 bool new_caps[MIGRATION_CAPABILITY__MAX]; 600 601 if (migration_is_running(s->state) || migration_in_colo_state()) { 602 error_setg(errp, QERR_MIGRATION_ACTIVE); 603 return; 604 } 605 606 memcpy(new_caps, s->capabilities, sizeof(new_caps)); 607 for (cap = params; cap; cap = cap->next) { 608 new_caps[cap->value->capability] = cap->value->state; 609 } 610 611 if (!migrate_caps_check(s->capabilities, new_caps, errp)) { 612 return; 613 } 614 615 for (cap = params; cap; cap = cap->next) { 616 s->capabilities[cap->value->capability] = cap->value->state; 617 } 618 } 619 620 /* parameters */ 621 622 const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void) 623 { 624 MigrationState *s = migrate_get_current(); 625 626 return s->parameters.block_bitmap_mapping; 627 } 628 629 bool migrate_has_block_bitmap_mapping(void) 630 { 631 MigrationState *s = migrate_get_current(); 632 633 return s->parameters.has_block_bitmap_mapping; 634 } 635 636 bool migrate_block_incremental(void) 637 { 638 MigrationState *s = migrate_get_current(); 639 640 return s->parameters.block_incremental; 641 } 642 643 uint32_t migrate_checkpoint_delay(void) 644 { 645 MigrationState *s = migrate_get_current(); 646 647 return s->parameters.x_checkpoint_delay; 648 } 649 650 int migrate_compress_level(void) 651 { 652 MigrationState *s = migrate_get_current(); 653 654 return s->parameters.compress_level; 655 } 656 657 int migrate_compress_threads(void) 658 { 659 MigrationState *s = migrate_get_current(); 660 661 return s->parameters.compress_threads; 662 } 663 664 int migrate_compress_wait_thread(void) 665 { 666 MigrationState *s = migrate_get_current(); 667 668 return s->parameters.compress_wait_thread; 669 } 670 671 uint8_t migrate_cpu_throttle_increment(void) 672 { 673 MigrationState *s = migrate_get_current(); 674 675 return s->parameters.cpu_throttle_increment; 676 } 677 678 uint8_t migrate_cpu_throttle_initial(void) 679 { 680 MigrationState *s = migrate_get_current(); 681 682 return s->parameters.cpu_throttle_initial; 683 } 684 685 bool migrate_cpu_throttle_tailslow(void) 686 { 687 MigrationState *s = migrate_get_current(); 688 689 return s->parameters.cpu_throttle_tailslow; 690 } 691 692 int migrate_decompress_threads(void) 693 { 694 MigrationState *s = migrate_get_current(); 695 696 return s->parameters.decompress_threads; 697 } 698 699 uint64_t migrate_downtime_limit(void) 700 { 701 MigrationState *s = migrate_get_current(); 702 703 return s->parameters.downtime_limit; 704 } 705 706 uint8_t migrate_max_cpu_throttle(void) 707 { 708 MigrationState *s = migrate_get_current(); 709 710 return s->parameters.max_cpu_throttle; 711 } 712 713 uint64_t migrate_max_bandwidth(void) 714 { 715 MigrationState *s = migrate_get_current(); 716 717 return s->parameters.max_bandwidth; 718 } 719 720 uint64_t migrate_max_postcopy_bandwidth(void) 721 { 722 MigrationState *s = migrate_get_current(); 723 724 return s->parameters.max_postcopy_bandwidth; 725 } 726 727 int migrate_multifd_channels(void) 728 { 729 MigrationState *s = migrate_get_current(); 730 731 return s->parameters.multifd_channels; 732 } 733 734 MultiFDCompression migrate_multifd_compression(void) 735 { 736 MigrationState *s = migrate_get_current(); 737 738 assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX); 739 return s->parameters.multifd_compression; 740 } 741 742 int migrate_multifd_zlib_level(void) 743 { 744 MigrationState *s = migrate_get_current(); 745 746 return s->parameters.multifd_zlib_level; 747 } 748 749 int migrate_multifd_zstd_level(void) 750 { 751 MigrationState *s = migrate_get_current(); 752 753 return s->parameters.multifd_zstd_level; 754 } 755 756 uint8_t migrate_throttle_trigger_threshold(void) 757 { 758 MigrationState *s = migrate_get_current(); 759 760 return s->parameters.throttle_trigger_threshold; 761 } 762 763 const char *migrate_tls_authz(void) 764 { 765 MigrationState *s = migrate_get_current(); 766 767 return s->parameters.tls_authz; 768 } 769 770 const char *migrate_tls_creds(void) 771 { 772 MigrationState *s = migrate_get_current(); 773 774 return s->parameters.tls_creds; 775 } 776 777 const char *migrate_tls_hostname(void) 778 { 779 MigrationState *s = migrate_get_current(); 780 781 return s->parameters.tls_hostname; 782 } 783 784 uint64_t migrate_xbzrle_cache_size(void) 785 { 786 MigrationState *s = migrate_get_current(); 787 788 return s->parameters.xbzrle_cache_size; 789 } 790 791 /* parameter setters */ 792 793 void migrate_set_block_incremental(bool value) 794 { 795 MigrationState *s = migrate_get_current(); 796 797 s->parameters.block_incremental = value; 798 } 799 800 /* parameters helpers */ 801 802 void block_cleanup_parameters(void) 803 { 804 MigrationState *s = migrate_get_current(); 805 806 if (s->must_remove_block_options) { 807 /* setting to false can never fail */ 808 migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort); 809 migrate_set_block_incremental(false); 810 s->must_remove_block_options = false; 811 } 812 } 813 814 AnnounceParameters *migrate_announce_params(void) 815 { 816 static AnnounceParameters ap; 817 818 MigrationState *s = migrate_get_current(); 819 820 ap.initial = s->parameters.announce_initial; 821 ap.max = s->parameters.announce_max; 822 ap.rounds = s->parameters.announce_rounds; 823 ap.step = s->parameters.announce_step; 824 825 return ≈ 826 } 827 828 MigrationParameters *qmp_query_migrate_parameters(Error **errp) 829 { 830 MigrationParameters *params; 831 MigrationState *s = migrate_get_current(); 832 833 /* TODO use QAPI_CLONE() instead of duplicating it inline */ 834 params = g_malloc0(sizeof(*params)); 835 params->has_compress_level = true; 836 params->compress_level = s->parameters.compress_level; 837 params->has_compress_threads = true; 838 params->compress_threads = s->parameters.compress_threads; 839 params->has_compress_wait_thread = true; 840 params->compress_wait_thread = s->parameters.compress_wait_thread; 841 params->has_decompress_threads = true; 842 params->decompress_threads = s->parameters.decompress_threads; 843 params->has_throttle_trigger_threshold = true; 844 params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; 845 params->has_cpu_throttle_initial = true; 846 params->cpu_throttle_initial = s->parameters.cpu_throttle_initial; 847 params->has_cpu_throttle_increment = true; 848 params->cpu_throttle_increment = s->parameters.cpu_throttle_increment; 849 params->has_cpu_throttle_tailslow = true; 850 params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow; 851 params->tls_creds = g_strdup(s->parameters.tls_creds); 852 params->tls_hostname = g_strdup(s->parameters.tls_hostname); 853 params->tls_authz = g_strdup(s->parameters.tls_authz ? 854 s->parameters.tls_authz : ""); 855 params->has_max_bandwidth = true; 856 params->max_bandwidth = s->parameters.max_bandwidth; 857 params->has_downtime_limit = true; 858 params->downtime_limit = s->parameters.downtime_limit; 859 params->has_x_checkpoint_delay = true; 860 params->x_checkpoint_delay = s->parameters.x_checkpoint_delay; 861 params->has_block_incremental = true; 862 params->block_incremental = s->parameters.block_incremental; 863 params->has_multifd_channels = true; 864 params->multifd_channels = s->parameters.multifd_channels; 865 params->has_multifd_compression = true; 866 params->multifd_compression = s->parameters.multifd_compression; 867 params->has_multifd_zlib_level = true; 868 params->multifd_zlib_level = s->parameters.multifd_zlib_level; 869 params->has_multifd_zstd_level = true; 870 params->multifd_zstd_level = s->parameters.multifd_zstd_level; 871 params->has_xbzrle_cache_size = true; 872 params->xbzrle_cache_size = s->parameters.xbzrle_cache_size; 873 params->has_max_postcopy_bandwidth = true; 874 params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth; 875 params->has_max_cpu_throttle = true; 876 params->max_cpu_throttle = s->parameters.max_cpu_throttle; 877 params->has_announce_initial = true; 878 params->announce_initial = s->parameters.announce_initial; 879 params->has_announce_max = true; 880 params->announce_max = s->parameters.announce_max; 881 params->has_announce_rounds = true; 882 params->announce_rounds = s->parameters.announce_rounds; 883 params->has_announce_step = true; 884 params->announce_step = s->parameters.announce_step; 885 886 if (s->parameters.has_block_bitmap_mapping) { 887 params->has_block_bitmap_mapping = true; 888 params->block_bitmap_mapping = 889 QAPI_CLONE(BitmapMigrationNodeAliasList, 890 s->parameters.block_bitmap_mapping); 891 } 892 893 return params; 894 } 895 896 void migrate_params_init(MigrationParameters *params) 897 { 898 params->tls_hostname = g_strdup(""); 899 params->tls_creds = g_strdup(""); 900 901 /* Set has_* up only for parameter checks */ 902 params->has_compress_level = true; 903 params->has_compress_threads = true; 904 params->has_compress_wait_thread = true; 905 params->has_decompress_threads = true; 906 params->has_throttle_trigger_threshold = true; 907 params->has_cpu_throttle_initial = true; 908 params->has_cpu_throttle_increment = true; 909 params->has_cpu_throttle_tailslow = true; 910 params->has_max_bandwidth = true; 911 params->has_downtime_limit = true; 912 params->has_x_checkpoint_delay = true; 913 params->has_block_incremental = true; 914 params->has_multifd_channels = true; 915 params->has_multifd_compression = true; 916 params->has_multifd_zlib_level = true; 917 params->has_multifd_zstd_level = true; 918 params->has_xbzrle_cache_size = true; 919 params->has_max_postcopy_bandwidth = true; 920 params->has_max_cpu_throttle = true; 921 params->has_announce_initial = true; 922 params->has_announce_max = true; 923 params->has_announce_rounds = true; 924 params->has_announce_step = true; 925 } 926 927 /* 928 * Check whether the parameters are valid. Error will be put into errp 929 * (if provided). Return true if valid, otherwise false. 930 */ 931 bool migrate_params_check(MigrationParameters *params, Error **errp) 932 { 933 if (params->has_compress_level && 934 (params->compress_level > 9)) { 935 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", 936 "a value between 0 and 9"); 937 return false; 938 } 939 940 if (params->has_compress_threads && (params->compress_threads < 1)) { 941 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 942 "compress_threads", 943 "a value between 1 and 255"); 944 return false; 945 } 946 947 if (params->has_decompress_threads && (params->decompress_threads < 1)) { 948 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 949 "decompress_threads", 950 "a value between 1 and 255"); 951 return false; 952 } 953 954 if (params->has_throttle_trigger_threshold && 955 (params->throttle_trigger_threshold < 1 || 956 params->throttle_trigger_threshold > 100)) { 957 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 958 "throttle_trigger_threshold", 959 "an integer in the range of 1 to 100"); 960 return false; 961 } 962 963 if (params->has_cpu_throttle_initial && 964 (params->cpu_throttle_initial < 1 || 965 params->cpu_throttle_initial > 99)) { 966 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 967 "cpu_throttle_initial", 968 "an integer in the range of 1 to 99"); 969 return false; 970 } 971 972 if (params->has_cpu_throttle_increment && 973 (params->cpu_throttle_increment < 1 || 974 params->cpu_throttle_increment > 99)) { 975 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 976 "cpu_throttle_increment", 977 "an integer in the range of 1 to 99"); 978 return false; 979 } 980 981 if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { 982 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 983 "max_bandwidth", 984 "an integer in the range of 0 to "stringify(SIZE_MAX) 985 " bytes/second"); 986 return false; 987 } 988 989 if (params->has_downtime_limit && 990 (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { 991 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 992 "downtime_limit", 993 "an integer in the range of 0 to " 994 stringify(MAX_MIGRATE_DOWNTIME)" ms"); 995 return false; 996 } 997 998 /* x_checkpoint_delay is now always positive */ 999 1000 if (params->has_multifd_channels && (params->multifd_channels < 1)) { 1001 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1002 "multifd_channels", 1003 "a value between 1 and 255"); 1004 return false; 1005 } 1006 1007 if (params->has_multifd_zlib_level && 1008 (params->multifd_zlib_level > 9)) { 1009 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level", 1010 "a value between 0 and 9"); 1011 return false; 1012 } 1013 1014 if (params->has_multifd_zstd_level && 1015 (params->multifd_zstd_level > 20)) { 1016 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level", 1017 "a value between 0 and 20"); 1018 return false; 1019 } 1020 1021 if (params->has_xbzrle_cache_size && 1022 (params->xbzrle_cache_size < qemu_target_page_size() || 1023 !is_power_of_2(params->xbzrle_cache_size))) { 1024 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1025 "xbzrle_cache_size", 1026 "a power of two no less than the target page size"); 1027 return false; 1028 } 1029 1030 if (params->has_max_cpu_throttle && 1031 (params->max_cpu_throttle < params->cpu_throttle_initial || 1032 params->max_cpu_throttle > 99)) { 1033 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1034 "max_cpu_throttle", 1035 "an integer in the range of cpu_throttle_initial to 99"); 1036 return false; 1037 } 1038 1039 if (params->has_announce_initial && 1040 params->announce_initial > 100000) { 1041 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1042 "announce_initial", 1043 "a value between 0 and 100000"); 1044 return false; 1045 } 1046 if (params->has_announce_max && 1047 params->announce_max > 100000) { 1048 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1049 "announce_max", 1050 "a value between 0 and 100000"); 1051 return false; 1052 } 1053 if (params->has_announce_rounds && 1054 params->announce_rounds > 1000) { 1055 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1056 "announce_rounds", 1057 "a value between 0 and 1000"); 1058 return false; 1059 } 1060 if (params->has_announce_step && 1061 (params->announce_step < 1 || 1062 params->announce_step > 10000)) { 1063 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1064 "announce_step", 1065 "a value between 0 and 10000"); 1066 return false; 1067 } 1068 1069 if (params->has_block_bitmap_mapping && 1070 !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) { 1071 error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: "); 1072 return false; 1073 } 1074 1075 #ifdef CONFIG_LINUX 1076 if (migrate_zero_copy_send() && 1077 ((params->has_multifd_compression && params->multifd_compression) || 1078 (params->tls_creds && *params->tls_creds))) { 1079 error_setg(errp, 1080 "Zero copy only available for non-compressed non-TLS multifd migration"); 1081 return false; 1082 } 1083 #endif 1084 1085 return true; 1086 } 1087 1088 static void migrate_params_test_apply(MigrateSetParameters *params, 1089 MigrationParameters *dest) 1090 { 1091 *dest = migrate_get_current()->parameters; 1092 1093 /* TODO use QAPI_CLONE() instead of duplicating it inline */ 1094 1095 if (params->has_compress_level) { 1096 dest->compress_level = params->compress_level; 1097 } 1098 1099 if (params->has_compress_threads) { 1100 dest->compress_threads = params->compress_threads; 1101 } 1102 1103 if (params->has_compress_wait_thread) { 1104 dest->compress_wait_thread = params->compress_wait_thread; 1105 } 1106 1107 if (params->has_decompress_threads) { 1108 dest->decompress_threads = params->decompress_threads; 1109 } 1110 1111 if (params->has_throttle_trigger_threshold) { 1112 dest->throttle_trigger_threshold = params->throttle_trigger_threshold; 1113 } 1114 1115 if (params->has_cpu_throttle_initial) { 1116 dest->cpu_throttle_initial = params->cpu_throttle_initial; 1117 } 1118 1119 if (params->has_cpu_throttle_increment) { 1120 dest->cpu_throttle_increment = params->cpu_throttle_increment; 1121 } 1122 1123 if (params->has_cpu_throttle_tailslow) { 1124 dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow; 1125 } 1126 1127 if (params->tls_creds) { 1128 assert(params->tls_creds->type == QTYPE_QSTRING); 1129 dest->tls_creds = params->tls_creds->u.s; 1130 } 1131 1132 if (params->tls_hostname) { 1133 assert(params->tls_hostname->type == QTYPE_QSTRING); 1134 dest->tls_hostname = params->tls_hostname->u.s; 1135 } 1136 1137 if (params->has_max_bandwidth) { 1138 dest->max_bandwidth = params->max_bandwidth; 1139 } 1140 1141 if (params->has_downtime_limit) { 1142 dest->downtime_limit = params->downtime_limit; 1143 } 1144 1145 if (params->has_x_checkpoint_delay) { 1146 dest->x_checkpoint_delay = params->x_checkpoint_delay; 1147 } 1148 1149 if (params->has_block_incremental) { 1150 dest->block_incremental = params->block_incremental; 1151 } 1152 if (params->has_multifd_channels) { 1153 dest->multifd_channels = params->multifd_channels; 1154 } 1155 if (params->has_multifd_compression) { 1156 dest->multifd_compression = params->multifd_compression; 1157 } 1158 if (params->has_xbzrle_cache_size) { 1159 dest->xbzrle_cache_size = params->xbzrle_cache_size; 1160 } 1161 if (params->has_max_postcopy_bandwidth) { 1162 dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth; 1163 } 1164 if (params->has_max_cpu_throttle) { 1165 dest->max_cpu_throttle = params->max_cpu_throttle; 1166 } 1167 if (params->has_announce_initial) { 1168 dest->announce_initial = params->announce_initial; 1169 } 1170 if (params->has_announce_max) { 1171 dest->announce_max = params->announce_max; 1172 } 1173 if (params->has_announce_rounds) { 1174 dest->announce_rounds = params->announce_rounds; 1175 } 1176 if (params->has_announce_step) { 1177 dest->announce_step = params->announce_step; 1178 } 1179 1180 if (params->has_block_bitmap_mapping) { 1181 dest->has_block_bitmap_mapping = true; 1182 dest->block_bitmap_mapping = params->block_bitmap_mapping; 1183 } 1184 } 1185 1186 static void migrate_params_apply(MigrateSetParameters *params, Error **errp) 1187 { 1188 MigrationState *s = migrate_get_current(); 1189 1190 /* TODO use QAPI_CLONE() instead of duplicating it inline */ 1191 1192 if (params->has_compress_level) { 1193 s->parameters.compress_level = params->compress_level; 1194 } 1195 1196 if (params->has_compress_threads) { 1197 s->parameters.compress_threads = params->compress_threads; 1198 } 1199 1200 if (params->has_compress_wait_thread) { 1201 s->parameters.compress_wait_thread = params->compress_wait_thread; 1202 } 1203 1204 if (params->has_decompress_threads) { 1205 s->parameters.decompress_threads = params->decompress_threads; 1206 } 1207 1208 if (params->has_throttle_trigger_threshold) { 1209 s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; 1210 } 1211 1212 if (params->has_cpu_throttle_initial) { 1213 s->parameters.cpu_throttle_initial = params->cpu_throttle_initial; 1214 } 1215 1216 if (params->has_cpu_throttle_increment) { 1217 s->parameters.cpu_throttle_increment = params->cpu_throttle_increment; 1218 } 1219 1220 if (params->has_cpu_throttle_tailslow) { 1221 s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow; 1222 } 1223 1224 if (params->tls_creds) { 1225 g_free(s->parameters.tls_creds); 1226 assert(params->tls_creds->type == QTYPE_QSTRING); 1227 s->parameters.tls_creds = g_strdup(params->tls_creds->u.s); 1228 } 1229 1230 if (params->tls_hostname) { 1231 g_free(s->parameters.tls_hostname); 1232 assert(params->tls_hostname->type == QTYPE_QSTRING); 1233 s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); 1234 } 1235 1236 if (params->tls_authz) { 1237 g_free(s->parameters.tls_authz); 1238 assert(params->tls_authz->type == QTYPE_QSTRING); 1239 s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); 1240 } 1241 1242 if (params->has_max_bandwidth) { 1243 s->parameters.max_bandwidth = params->max_bandwidth; 1244 if (s->to_dst_file && !migration_in_postcopy()) { 1245 qemu_file_set_rate_limit(s->to_dst_file, 1246 s->parameters.max_bandwidth); 1247 } 1248 } 1249 1250 if (params->has_downtime_limit) { 1251 s->parameters.downtime_limit = params->downtime_limit; 1252 } 1253 1254 if (params->has_x_checkpoint_delay) { 1255 s->parameters.x_checkpoint_delay = params->x_checkpoint_delay; 1256 colo_checkpoint_delay_set(); 1257 } 1258 1259 if (params->has_block_incremental) { 1260 s->parameters.block_incremental = params->block_incremental; 1261 } 1262 if (params->has_multifd_channels) { 1263 s->parameters.multifd_channels = params->multifd_channels; 1264 } 1265 if (params->has_multifd_compression) { 1266 s->parameters.multifd_compression = params->multifd_compression; 1267 } 1268 if (params->has_xbzrle_cache_size) { 1269 s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; 1270 xbzrle_cache_resize(params->xbzrle_cache_size, errp); 1271 } 1272 if (params->has_max_postcopy_bandwidth) { 1273 s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; 1274 if (s->to_dst_file && migration_in_postcopy()) { 1275 qemu_file_set_rate_limit(s->to_dst_file, 1276 s->parameters.max_postcopy_bandwidth); 1277 } 1278 } 1279 if (params->has_max_cpu_throttle) { 1280 s->parameters.max_cpu_throttle = params->max_cpu_throttle; 1281 } 1282 if (params->has_announce_initial) { 1283 s->parameters.announce_initial = params->announce_initial; 1284 } 1285 if (params->has_announce_max) { 1286 s->parameters.announce_max = params->announce_max; 1287 } 1288 if (params->has_announce_rounds) { 1289 s->parameters.announce_rounds = params->announce_rounds; 1290 } 1291 if (params->has_announce_step) { 1292 s->parameters.announce_step = params->announce_step; 1293 } 1294 1295 if (params->has_block_bitmap_mapping) { 1296 qapi_free_BitmapMigrationNodeAliasList( 1297 s->parameters.block_bitmap_mapping); 1298 1299 s->parameters.has_block_bitmap_mapping = true; 1300 s->parameters.block_bitmap_mapping = 1301 QAPI_CLONE(BitmapMigrationNodeAliasList, 1302 params->block_bitmap_mapping); 1303 } 1304 } 1305 1306 void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) 1307 { 1308 MigrationParameters tmp; 1309 1310 /* TODO Rewrite "" to null instead */ 1311 if (params->tls_creds 1312 && params->tls_creds->type == QTYPE_QNULL) { 1313 qobject_unref(params->tls_creds->u.n); 1314 params->tls_creds->type = QTYPE_QSTRING; 1315 params->tls_creds->u.s = strdup(""); 1316 } 1317 /* TODO Rewrite "" to null instead */ 1318 if (params->tls_hostname 1319 && params->tls_hostname->type == QTYPE_QNULL) { 1320 qobject_unref(params->tls_hostname->u.n); 1321 params->tls_hostname->type = QTYPE_QSTRING; 1322 params->tls_hostname->u.s = strdup(""); 1323 } 1324 1325 migrate_params_test_apply(params, &tmp); 1326 1327 if (!migrate_params_check(&tmp, errp)) { 1328 /* Invalid parameter */ 1329 return; 1330 } 1331 1332 migrate_params_apply(params, errp); 1333 } 1334