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)) { 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_block_incremental(void) 630 { 631 MigrationState *s = migrate_get_current(); 632 633 return s->parameters.block_incremental; 634 } 635 636 uint32_t migrate_checkpoint_delay(void) 637 { 638 MigrationState *s = migrate_get_current(); 639 640 return s->parameters.x_checkpoint_delay; 641 } 642 643 int migrate_compress_level(void) 644 { 645 MigrationState *s = migrate_get_current(); 646 647 return s->parameters.compress_level; 648 } 649 650 int migrate_compress_threads(void) 651 { 652 MigrationState *s = migrate_get_current(); 653 654 return s->parameters.compress_threads; 655 } 656 657 int migrate_compress_wait_thread(void) 658 { 659 MigrationState *s = migrate_get_current(); 660 661 return s->parameters.compress_wait_thread; 662 } 663 664 uint8_t migrate_cpu_throttle_increment(void) 665 { 666 MigrationState *s = migrate_get_current(); 667 668 return s->parameters.cpu_throttle_increment; 669 } 670 671 uint8_t migrate_cpu_throttle_initial(void) 672 { 673 MigrationState *s = migrate_get_current(); 674 675 return s->parameters.cpu_throttle_initial; 676 } 677 678 bool migrate_cpu_throttle_tailslow(void) 679 { 680 MigrationState *s = migrate_get_current(); 681 682 return s->parameters.cpu_throttle_tailslow; 683 } 684 685 int migrate_decompress_threads(void) 686 { 687 MigrationState *s = migrate_get_current(); 688 689 return s->parameters.decompress_threads; 690 } 691 692 uint64_t migrate_downtime_limit(void) 693 { 694 MigrationState *s = migrate_get_current(); 695 696 return s->parameters.downtime_limit; 697 } 698 699 uint8_t migrate_max_cpu_throttle(void) 700 { 701 MigrationState *s = migrate_get_current(); 702 703 return s->parameters.max_cpu_throttle; 704 } 705 706 uint64_t migrate_max_bandwidth(void) 707 { 708 MigrationState *s = migrate_get_current(); 709 710 return s->parameters.max_bandwidth; 711 } 712 713 int64_t migrate_max_postcopy_bandwidth(void) 714 { 715 MigrationState *s = migrate_get_current(); 716 717 return s->parameters.max_postcopy_bandwidth; 718 } 719 720 int migrate_multifd_channels(void) 721 { 722 MigrationState *s = migrate_get_current(); 723 724 return s->parameters.multifd_channels; 725 } 726 727 MultiFDCompression migrate_multifd_compression(void) 728 { 729 MigrationState *s = migrate_get_current(); 730 731 assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX); 732 return s->parameters.multifd_compression; 733 } 734 735 int migrate_multifd_zlib_level(void) 736 { 737 MigrationState *s = migrate_get_current(); 738 739 return s->parameters.multifd_zlib_level; 740 } 741 742 int migrate_multifd_zstd_level(void) 743 { 744 MigrationState *s = migrate_get_current(); 745 746 return s->parameters.multifd_zstd_level; 747 } 748 749 uint8_t migrate_throttle_trigger_threshold(void) 750 { 751 MigrationState *s = migrate_get_current(); 752 753 return s->parameters.throttle_trigger_threshold; 754 } 755 756 const char *migrate_tls_authz(void) 757 { 758 MigrationState *s = migrate_get_current(); 759 760 return s->parameters.tls_authz; 761 } 762 763 const char *migrate_tls_creds(void) 764 { 765 MigrationState *s = migrate_get_current(); 766 767 return s->parameters.tls_creds; 768 } 769 770 const char *migrate_tls_hostname(void) 771 { 772 MigrationState *s = migrate_get_current(); 773 774 return s->parameters.tls_hostname; 775 } 776 777 uint64_t migrate_xbzrle_cache_size(void) 778 { 779 MigrationState *s = migrate_get_current(); 780 781 return s->parameters.xbzrle_cache_size; 782 } 783 784 /* parameter setters */ 785 786 void migrate_set_block_incremental(bool value) 787 { 788 MigrationState *s = migrate_get_current(); 789 790 s->parameters.block_incremental = value; 791 } 792 793 /* parameters helpers */ 794 795 void block_cleanup_parameters(void) 796 { 797 MigrationState *s = migrate_get_current(); 798 799 if (s->must_remove_block_options) { 800 /* setting to false can never fail */ 801 migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort); 802 migrate_set_block_incremental(false); 803 s->must_remove_block_options = false; 804 } 805 } 806 807 AnnounceParameters *migrate_announce_params(void) 808 { 809 static AnnounceParameters ap; 810 811 MigrationState *s = migrate_get_current(); 812 813 ap.initial = s->parameters.announce_initial; 814 ap.max = s->parameters.announce_max; 815 ap.rounds = s->parameters.announce_rounds; 816 ap.step = s->parameters.announce_step; 817 818 return ≈ 819 } 820 821 MigrationParameters *qmp_query_migrate_parameters(Error **errp) 822 { 823 MigrationParameters *params; 824 MigrationState *s = migrate_get_current(); 825 826 /* TODO use QAPI_CLONE() instead of duplicating it inline */ 827 params = g_malloc0(sizeof(*params)); 828 params->has_compress_level = true; 829 params->compress_level = s->parameters.compress_level; 830 params->has_compress_threads = true; 831 params->compress_threads = s->parameters.compress_threads; 832 params->has_compress_wait_thread = true; 833 params->compress_wait_thread = s->parameters.compress_wait_thread; 834 params->has_decompress_threads = true; 835 params->decompress_threads = s->parameters.decompress_threads; 836 params->has_throttle_trigger_threshold = true; 837 params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; 838 params->has_cpu_throttle_initial = true; 839 params->cpu_throttle_initial = s->parameters.cpu_throttle_initial; 840 params->has_cpu_throttle_increment = true; 841 params->cpu_throttle_increment = s->parameters.cpu_throttle_increment; 842 params->has_cpu_throttle_tailslow = true; 843 params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow; 844 params->tls_creds = g_strdup(s->parameters.tls_creds); 845 params->tls_hostname = g_strdup(s->parameters.tls_hostname); 846 params->tls_authz = g_strdup(s->parameters.tls_authz ? 847 s->parameters.tls_authz : ""); 848 params->has_max_bandwidth = true; 849 params->max_bandwidth = s->parameters.max_bandwidth; 850 params->has_downtime_limit = true; 851 params->downtime_limit = s->parameters.downtime_limit; 852 params->has_x_checkpoint_delay = true; 853 params->x_checkpoint_delay = s->parameters.x_checkpoint_delay; 854 params->has_block_incremental = true; 855 params->block_incremental = s->parameters.block_incremental; 856 params->has_multifd_channels = true; 857 params->multifd_channels = s->parameters.multifd_channels; 858 params->has_multifd_compression = true; 859 params->multifd_compression = s->parameters.multifd_compression; 860 params->has_multifd_zlib_level = true; 861 params->multifd_zlib_level = s->parameters.multifd_zlib_level; 862 params->has_multifd_zstd_level = true; 863 params->multifd_zstd_level = s->parameters.multifd_zstd_level; 864 params->has_xbzrle_cache_size = true; 865 params->xbzrle_cache_size = s->parameters.xbzrle_cache_size; 866 params->has_max_postcopy_bandwidth = true; 867 params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth; 868 params->has_max_cpu_throttle = true; 869 params->max_cpu_throttle = s->parameters.max_cpu_throttle; 870 params->has_announce_initial = true; 871 params->announce_initial = s->parameters.announce_initial; 872 params->has_announce_max = true; 873 params->announce_max = s->parameters.announce_max; 874 params->has_announce_rounds = true; 875 params->announce_rounds = s->parameters.announce_rounds; 876 params->has_announce_step = true; 877 params->announce_step = s->parameters.announce_step; 878 879 if (s->parameters.has_block_bitmap_mapping) { 880 params->has_block_bitmap_mapping = true; 881 params->block_bitmap_mapping = 882 QAPI_CLONE(BitmapMigrationNodeAliasList, 883 s->parameters.block_bitmap_mapping); 884 } 885 886 return params; 887 } 888 889 void migrate_params_init(MigrationParameters *params) 890 { 891 params->tls_hostname = g_strdup(""); 892 params->tls_creds = g_strdup(""); 893 894 /* Set has_* up only for parameter checks */ 895 params->has_compress_level = true; 896 params->has_compress_threads = true; 897 params->has_compress_wait_thread = true; 898 params->has_decompress_threads = true; 899 params->has_throttle_trigger_threshold = true; 900 params->has_cpu_throttle_initial = true; 901 params->has_cpu_throttle_increment = true; 902 params->has_cpu_throttle_tailslow = true; 903 params->has_max_bandwidth = true; 904 params->has_downtime_limit = true; 905 params->has_x_checkpoint_delay = true; 906 params->has_block_incremental = true; 907 params->has_multifd_channels = true; 908 params->has_multifd_compression = true; 909 params->has_multifd_zlib_level = true; 910 params->has_multifd_zstd_level = true; 911 params->has_xbzrle_cache_size = true; 912 params->has_max_postcopy_bandwidth = true; 913 params->has_max_cpu_throttle = true; 914 params->has_announce_initial = true; 915 params->has_announce_max = true; 916 params->has_announce_rounds = true; 917 params->has_announce_step = true; 918 } 919 920 /* 921 * Check whether the parameters are valid. Error will be put into errp 922 * (if provided). Return true if valid, otherwise false. 923 */ 924 bool migrate_params_check(MigrationParameters *params, Error **errp) 925 { 926 if (params->has_compress_level && 927 (params->compress_level > 9)) { 928 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", 929 "a value between 0 and 9"); 930 return false; 931 } 932 933 if (params->has_compress_threads && (params->compress_threads < 1)) { 934 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 935 "compress_threads", 936 "a value between 1 and 255"); 937 return false; 938 } 939 940 if (params->has_decompress_threads && (params->decompress_threads < 1)) { 941 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 942 "decompress_threads", 943 "a value between 1 and 255"); 944 return false; 945 } 946 947 if (params->has_throttle_trigger_threshold && 948 (params->throttle_trigger_threshold < 1 || 949 params->throttle_trigger_threshold > 100)) { 950 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 951 "throttle_trigger_threshold", 952 "an integer in the range of 1 to 100"); 953 return false; 954 } 955 956 if (params->has_cpu_throttle_initial && 957 (params->cpu_throttle_initial < 1 || 958 params->cpu_throttle_initial > 99)) { 959 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 960 "cpu_throttle_initial", 961 "an integer in the range of 1 to 99"); 962 return false; 963 } 964 965 if (params->has_cpu_throttle_increment && 966 (params->cpu_throttle_increment < 1 || 967 params->cpu_throttle_increment > 99)) { 968 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 969 "cpu_throttle_increment", 970 "an integer in the range of 1 to 99"); 971 return false; 972 } 973 974 if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { 975 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 976 "max_bandwidth", 977 "an integer in the range of 0 to "stringify(SIZE_MAX) 978 " bytes/second"); 979 return false; 980 } 981 982 if (params->has_downtime_limit && 983 (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { 984 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 985 "downtime_limit", 986 "an integer in the range of 0 to " 987 stringify(MAX_MIGRATE_DOWNTIME)" ms"); 988 return false; 989 } 990 991 /* x_checkpoint_delay is now always positive */ 992 993 if (params->has_multifd_channels && (params->multifd_channels < 1)) { 994 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 995 "multifd_channels", 996 "a value between 1 and 255"); 997 return false; 998 } 999 1000 if (params->has_multifd_zlib_level && 1001 (params->multifd_zlib_level > 9)) { 1002 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level", 1003 "a value between 0 and 9"); 1004 return false; 1005 } 1006 1007 if (params->has_multifd_zstd_level && 1008 (params->multifd_zstd_level > 20)) { 1009 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level", 1010 "a value between 0 and 20"); 1011 return false; 1012 } 1013 1014 if (params->has_xbzrle_cache_size && 1015 (params->xbzrle_cache_size < qemu_target_page_size() || 1016 !is_power_of_2(params->xbzrle_cache_size))) { 1017 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1018 "xbzrle_cache_size", 1019 "a power of two no less than the target page size"); 1020 return false; 1021 } 1022 1023 if (params->has_max_cpu_throttle && 1024 (params->max_cpu_throttle < params->cpu_throttle_initial || 1025 params->max_cpu_throttle > 99)) { 1026 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1027 "max_cpu_throttle", 1028 "an integer in the range of cpu_throttle_initial to 99"); 1029 return false; 1030 } 1031 1032 if (params->has_announce_initial && 1033 params->announce_initial > 100000) { 1034 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1035 "announce_initial", 1036 "a value between 0 and 100000"); 1037 return false; 1038 } 1039 if (params->has_announce_max && 1040 params->announce_max > 100000) { 1041 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1042 "announce_max", 1043 "a value between 0 and 100000"); 1044 return false; 1045 } 1046 if (params->has_announce_rounds && 1047 params->announce_rounds > 1000) { 1048 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1049 "announce_rounds", 1050 "a value between 0 and 1000"); 1051 return false; 1052 } 1053 if (params->has_announce_step && 1054 (params->announce_step < 1 || 1055 params->announce_step > 10000)) { 1056 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1057 "announce_step", 1058 "a value between 0 and 10000"); 1059 return false; 1060 } 1061 1062 if (params->has_block_bitmap_mapping && 1063 !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) { 1064 error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: "); 1065 return false; 1066 } 1067 1068 #ifdef CONFIG_LINUX 1069 if (migrate_zero_copy_send() && 1070 ((params->has_multifd_compression && params->multifd_compression) || 1071 (params->tls_creds && *params->tls_creds))) { 1072 error_setg(errp, 1073 "Zero copy only available for non-compressed non-TLS multifd migration"); 1074 return false; 1075 } 1076 #endif 1077 1078 return true; 1079 } 1080 1081 static void migrate_params_test_apply(MigrateSetParameters *params, 1082 MigrationParameters *dest) 1083 { 1084 *dest = migrate_get_current()->parameters; 1085 1086 /* TODO use QAPI_CLONE() instead of duplicating it inline */ 1087 1088 if (params->has_compress_level) { 1089 dest->compress_level = params->compress_level; 1090 } 1091 1092 if (params->has_compress_threads) { 1093 dest->compress_threads = params->compress_threads; 1094 } 1095 1096 if (params->has_compress_wait_thread) { 1097 dest->compress_wait_thread = params->compress_wait_thread; 1098 } 1099 1100 if (params->has_decompress_threads) { 1101 dest->decompress_threads = params->decompress_threads; 1102 } 1103 1104 if (params->has_throttle_trigger_threshold) { 1105 dest->throttle_trigger_threshold = params->throttle_trigger_threshold; 1106 } 1107 1108 if (params->has_cpu_throttle_initial) { 1109 dest->cpu_throttle_initial = params->cpu_throttle_initial; 1110 } 1111 1112 if (params->has_cpu_throttle_increment) { 1113 dest->cpu_throttle_increment = params->cpu_throttle_increment; 1114 } 1115 1116 if (params->has_cpu_throttle_tailslow) { 1117 dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow; 1118 } 1119 1120 if (params->tls_creds) { 1121 assert(params->tls_creds->type == QTYPE_QSTRING); 1122 dest->tls_creds = params->tls_creds->u.s; 1123 } 1124 1125 if (params->tls_hostname) { 1126 assert(params->tls_hostname->type == QTYPE_QSTRING); 1127 dest->tls_hostname = params->tls_hostname->u.s; 1128 } 1129 1130 if (params->has_max_bandwidth) { 1131 dest->max_bandwidth = params->max_bandwidth; 1132 } 1133 1134 if (params->has_downtime_limit) { 1135 dest->downtime_limit = params->downtime_limit; 1136 } 1137 1138 if (params->has_x_checkpoint_delay) { 1139 dest->x_checkpoint_delay = params->x_checkpoint_delay; 1140 } 1141 1142 if (params->has_block_incremental) { 1143 dest->block_incremental = params->block_incremental; 1144 } 1145 if (params->has_multifd_channels) { 1146 dest->multifd_channels = params->multifd_channels; 1147 } 1148 if (params->has_multifd_compression) { 1149 dest->multifd_compression = params->multifd_compression; 1150 } 1151 if (params->has_xbzrle_cache_size) { 1152 dest->xbzrle_cache_size = params->xbzrle_cache_size; 1153 } 1154 if (params->has_max_postcopy_bandwidth) { 1155 dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth; 1156 } 1157 if (params->has_max_cpu_throttle) { 1158 dest->max_cpu_throttle = params->max_cpu_throttle; 1159 } 1160 if (params->has_announce_initial) { 1161 dest->announce_initial = params->announce_initial; 1162 } 1163 if (params->has_announce_max) { 1164 dest->announce_max = params->announce_max; 1165 } 1166 if (params->has_announce_rounds) { 1167 dest->announce_rounds = params->announce_rounds; 1168 } 1169 if (params->has_announce_step) { 1170 dest->announce_step = params->announce_step; 1171 } 1172 1173 if (params->has_block_bitmap_mapping) { 1174 dest->has_block_bitmap_mapping = true; 1175 dest->block_bitmap_mapping = params->block_bitmap_mapping; 1176 } 1177 } 1178 1179 static void migrate_params_apply(MigrateSetParameters *params, Error **errp) 1180 { 1181 MigrationState *s = migrate_get_current(); 1182 1183 /* TODO use QAPI_CLONE() instead of duplicating it inline */ 1184 1185 if (params->has_compress_level) { 1186 s->parameters.compress_level = params->compress_level; 1187 } 1188 1189 if (params->has_compress_threads) { 1190 s->parameters.compress_threads = params->compress_threads; 1191 } 1192 1193 if (params->has_compress_wait_thread) { 1194 s->parameters.compress_wait_thread = params->compress_wait_thread; 1195 } 1196 1197 if (params->has_decompress_threads) { 1198 s->parameters.decompress_threads = params->decompress_threads; 1199 } 1200 1201 if (params->has_throttle_trigger_threshold) { 1202 s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; 1203 } 1204 1205 if (params->has_cpu_throttle_initial) { 1206 s->parameters.cpu_throttle_initial = params->cpu_throttle_initial; 1207 } 1208 1209 if (params->has_cpu_throttle_increment) { 1210 s->parameters.cpu_throttle_increment = params->cpu_throttle_increment; 1211 } 1212 1213 if (params->has_cpu_throttle_tailslow) { 1214 s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow; 1215 } 1216 1217 if (params->tls_creds) { 1218 g_free(s->parameters.tls_creds); 1219 assert(params->tls_creds->type == QTYPE_QSTRING); 1220 s->parameters.tls_creds = g_strdup(params->tls_creds->u.s); 1221 } 1222 1223 if (params->tls_hostname) { 1224 g_free(s->parameters.tls_hostname); 1225 assert(params->tls_hostname->type == QTYPE_QSTRING); 1226 s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); 1227 } 1228 1229 if (params->tls_authz) { 1230 g_free(s->parameters.tls_authz); 1231 assert(params->tls_authz->type == QTYPE_QSTRING); 1232 s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); 1233 } 1234 1235 if (params->has_max_bandwidth) { 1236 s->parameters.max_bandwidth = params->max_bandwidth; 1237 if (s->to_dst_file && !migration_in_postcopy()) { 1238 qemu_file_set_rate_limit(s->to_dst_file, 1239 s->parameters.max_bandwidth / XFER_LIMIT_RATIO); 1240 } 1241 } 1242 1243 if (params->has_downtime_limit) { 1244 s->parameters.downtime_limit = params->downtime_limit; 1245 } 1246 1247 if (params->has_x_checkpoint_delay) { 1248 s->parameters.x_checkpoint_delay = params->x_checkpoint_delay; 1249 if (migration_in_colo_state()) { 1250 colo_checkpoint_notify(s); 1251 } 1252 } 1253 1254 if (params->has_block_incremental) { 1255 s->parameters.block_incremental = params->block_incremental; 1256 } 1257 if (params->has_multifd_channels) { 1258 s->parameters.multifd_channels = params->multifd_channels; 1259 } 1260 if (params->has_multifd_compression) { 1261 s->parameters.multifd_compression = params->multifd_compression; 1262 } 1263 if (params->has_xbzrle_cache_size) { 1264 s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; 1265 xbzrle_cache_resize(params->xbzrle_cache_size, errp); 1266 } 1267 if (params->has_max_postcopy_bandwidth) { 1268 s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; 1269 if (s->to_dst_file && migration_in_postcopy()) { 1270 qemu_file_set_rate_limit(s->to_dst_file, 1271 s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO); 1272 } 1273 } 1274 if (params->has_max_cpu_throttle) { 1275 s->parameters.max_cpu_throttle = params->max_cpu_throttle; 1276 } 1277 if (params->has_announce_initial) { 1278 s->parameters.announce_initial = params->announce_initial; 1279 } 1280 if (params->has_announce_max) { 1281 s->parameters.announce_max = params->announce_max; 1282 } 1283 if (params->has_announce_rounds) { 1284 s->parameters.announce_rounds = params->announce_rounds; 1285 } 1286 if (params->has_announce_step) { 1287 s->parameters.announce_step = params->announce_step; 1288 } 1289 1290 if (params->has_block_bitmap_mapping) { 1291 qapi_free_BitmapMigrationNodeAliasList( 1292 s->parameters.block_bitmap_mapping); 1293 1294 s->parameters.has_block_bitmap_mapping = true; 1295 s->parameters.block_bitmap_mapping = 1296 QAPI_CLONE(BitmapMigrationNodeAliasList, 1297 params->block_bitmap_mapping); 1298 } 1299 } 1300 1301 void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) 1302 { 1303 MigrationParameters tmp; 1304 1305 /* TODO Rewrite "" to null instead */ 1306 if (params->tls_creds 1307 && params->tls_creds->type == QTYPE_QNULL) { 1308 qobject_unref(params->tls_creds->u.n); 1309 params->tls_creds->type = QTYPE_QSTRING; 1310 params->tls_creds->u.s = strdup(""); 1311 } 1312 /* TODO Rewrite "" to null instead */ 1313 if (params->tls_hostname 1314 && params->tls_hostname->type == QTYPE_QNULL) { 1315 qobject_unref(params->tls_hostname->u.n); 1316 params->tls_hostname->type = QTYPE_QSTRING; 1317 params->tls_hostname->u.s = strdup(""); 1318 } 1319 1320 migrate_params_test_apply(params, &tmp); 1321 1322 if (!migrate_params_check(&tmp, errp)) { 1323 /* Invalid parameter */ 1324 return; 1325 } 1326 1327 migrate_params_apply(params, errp); 1328 } 1329