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