xref: /qemu/migration/options.c (revision 77c259a4cb1c9799754b48f570301ebf1de5ded8)
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, true),
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     /*
345      * Until the patch that remove this comment, we always return that
346      * the property is enabled.
347      */
348     return true || s->multifd_flush_after_each_section;
349 }
350 
351 bool migrate_postcopy(void)
352 {
353     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
354 }
355 
356 bool migrate_tls(void)
357 {
358     MigrationState *s = migrate_get_current();
359 
360     return s->parameters.tls_creds && *s->parameters.tls_creds;
361 }
362 
363 typedef enum WriteTrackingSupport {
364     WT_SUPPORT_UNKNOWN = 0,
365     WT_SUPPORT_ABSENT,
366     WT_SUPPORT_AVAILABLE,
367     WT_SUPPORT_COMPATIBLE
368 } WriteTrackingSupport;
369 
370 static
371 WriteTrackingSupport migrate_query_write_tracking(void)
372 {
373     /* Check if kernel supports required UFFD features */
374     if (!ram_write_tracking_available()) {
375         return WT_SUPPORT_ABSENT;
376     }
377     /*
378      * Check if current memory configuration is
379      * compatible with required UFFD features.
380      */
381     if (!ram_write_tracking_compatible()) {
382         return WT_SUPPORT_AVAILABLE;
383     }
384 
385     return WT_SUPPORT_COMPATIBLE;
386 }
387 
388 /* Migration capabilities set */
389 struct MigrateCapsSet {
390     int size;                       /* Capability set size */
391     MigrationCapability caps[];     /* Variadic array of capabilities */
392 };
393 typedef struct MigrateCapsSet MigrateCapsSet;
394 
395 /* Define and initialize MigrateCapsSet */
396 #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
397     MigrateCapsSet _name = {    \
398         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
399         .caps = { __VA_ARGS__ } \
400     }
401 
402 /* Background-snapshot compatibility check list */
403 static const
404 INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
405     MIGRATION_CAPABILITY_POSTCOPY_RAM,
406     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
407     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
408     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
409     MIGRATION_CAPABILITY_RETURN_PATH,
410     MIGRATION_CAPABILITY_MULTIFD,
411     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
412     MIGRATION_CAPABILITY_AUTO_CONVERGE,
413     MIGRATION_CAPABILITY_RELEASE_RAM,
414     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
415     MIGRATION_CAPABILITY_COMPRESS,
416     MIGRATION_CAPABILITY_XBZRLE,
417     MIGRATION_CAPABILITY_X_COLO,
418     MIGRATION_CAPABILITY_VALIDATE_UUID,
419     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
420 
421 /**
422  * @migration_caps_check - check capability compatibility
423  *
424  * @old_caps: old capability list
425  * @new_caps: new capability list
426  * @errp: set *errp if the check failed, with reason
427  *
428  * Returns true if check passed, otherwise false.
429  */
430 bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
431 {
432     MigrationIncomingState *mis = migration_incoming_get_current();
433 
434     ERRP_GUARD();
435 #ifndef CONFIG_LIVE_BLOCK_MIGRATION
436     if (new_caps[MIGRATION_CAPABILITY_BLOCK]) {
437         error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) "
438                    "block migration");
439         error_append_hint(errp, "Use drive_mirror+NBD instead.\n");
440         return false;
441     }
442 #endif
443 
444 #ifndef CONFIG_REPLICATION
445     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
446         error_setg(errp, "QEMU compiled without replication module"
447                    " can't enable COLO");
448         error_append_hint(errp, "Please enable replication before COLO.\n");
449         return false;
450     }
451 #endif
452 
453     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
454         /* This check is reasonably expensive, so only when it's being
455          * set the first time, also it's only the destination that needs
456          * special support.
457          */
458         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
459             runstate_check(RUN_STATE_INMIGRATE) &&
460             !postcopy_ram_supported_by_host(mis, errp)) {
461             error_prepend(errp, "Postcopy is not supported: ");
462             return false;
463         }
464 
465         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
466             error_setg(errp, "Postcopy is not compatible with ignore-shared");
467             return false;
468         }
469 
470         if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
471             error_setg(errp, "Postcopy is not yet compatible with multifd");
472             return false;
473         }
474     }
475 
476     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
477         WriteTrackingSupport wt_support;
478         int idx;
479         /*
480          * Check if 'background-snapshot' capability is supported by
481          * host kernel and compatible with guest memory configuration.
482          */
483         wt_support = migrate_query_write_tracking();
484         if (wt_support < WT_SUPPORT_AVAILABLE) {
485             error_setg(errp, "Background-snapshot is not supported by host kernel");
486             return false;
487         }
488         if (wt_support < WT_SUPPORT_COMPATIBLE) {
489             error_setg(errp, "Background-snapshot is not compatible "
490                     "with guest memory configuration");
491             return false;
492         }
493 
494         /*
495          * Check if there are any migration capabilities
496          * incompatible with 'background-snapshot'.
497          */
498         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
499             int incomp_cap = check_caps_background_snapshot.caps[idx];
500             if (new_caps[incomp_cap]) {
501                 error_setg(errp,
502                         "Background-snapshot is not compatible with %s",
503                         MigrationCapability_str(incomp_cap));
504                 return false;
505             }
506         }
507     }
508 
509 #ifdef CONFIG_LINUX
510     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
511         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
512          new_caps[MIGRATION_CAPABILITY_COMPRESS] ||
513          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
514          migrate_multifd_compression() ||
515          migrate_tls())) {
516         error_setg(errp,
517                    "Zero copy only available for non-compressed non-TLS multifd migration");
518         return false;
519     }
520 #else
521     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
522         error_setg(errp,
523                    "Zero copy currently only available on Linux");
524         return false;
525     }
526 #endif
527 
528     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
529         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
530             error_setg(errp, "Postcopy preempt requires postcopy-ram");
531             return false;
532         }
533 
534         /*
535          * Preempt mode requires urgent pages to be sent in separate
536          * channel, OTOH compression logic will disorder all pages into
537          * different compression channels, which is not compatible with the
538          * preempt assumptions on channel assignments.
539          */
540         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
541             error_setg(errp, "Postcopy preempt not compatible with compress");
542             return false;
543         }
544     }
545 
546     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
547         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
548             error_setg(errp, "Multifd is not compatible with compress");
549             return false;
550         }
551     }
552 
553     return true;
554 }
555 
556 bool migrate_cap_set(int cap, bool value, Error **errp)
557 {
558     MigrationState *s = migrate_get_current();
559     bool new_caps[MIGRATION_CAPABILITY__MAX];
560 
561     if (migration_is_running(s->state)) {
562         error_setg(errp, QERR_MIGRATION_ACTIVE);
563         return false;
564     }
565 
566     memcpy(new_caps, s->capabilities, sizeof(new_caps));
567     new_caps[cap] = value;
568 
569     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
570         return false;
571     }
572     s->capabilities[cap] = value;
573     return true;
574 }
575 
576 MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
577 {
578     MigrationCapabilityStatusList *head = NULL, **tail = &head;
579     MigrationCapabilityStatus *caps;
580     MigrationState *s = migrate_get_current();
581     int i;
582 
583     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
584 #ifndef CONFIG_LIVE_BLOCK_MIGRATION
585         if (i == MIGRATION_CAPABILITY_BLOCK) {
586             continue;
587         }
588 #endif
589         caps = g_malloc0(sizeof(*caps));
590         caps->capability = i;
591         caps->state = s->capabilities[i];
592         QAPI_LIST_APPEND(tail, caps);
593     }
594 
595     return head;
596 }
597 
598 void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
599                                   Error **errp)
600 {
601     MigrationState *s = migrate_get_current();
602     MigrationCapabilityStatusList *cap;
603     bool new_caps[MIGRATION_CAPABILITY__MAX];
604 
605     if (migration_is_running(s->state)) {
606         error_setg(errp, QERR_MIGRATION_ACTIVE);
607         return;
608     }
609 
610     memcpy(new_caps, s->capabilities, sizeof(new_caps));
611     for (cap = params; cap; cap = cap->next) {
612         new_caps[cap->value->capability] = cap->value->state;
613     }
614 
615     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
616         return;
617     }
618 
619     for (cap = params; cap; cap = cap->next) {
620         s->capabilities[cap->value->capability] = cap->value->state;
621     }
622 }
623 
624 /* parameters */
625 
626 const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
627 {
628     MigrationState *s = migrate_get_current();
629 
630     return s->parameters.block_bitmap_mapping;
631 }
632 
633 bool migrate_block_incremental(void)
634 {
635     MigrationState *s = migrate_get_current();
636 
637     return s->parameters.block_incremental;
638 }
639 
640 uint32_t migrate_checkpoint_delay(void)
641 {
642     MigrationState *s = migrate_get_current();
643 
644     return s->parameters.x_checkpoint_delay;
645 }
646 
647 int migrate_compress_level(void)
648 {
649     MigrationState *s = migrate_get_current();
650 
651     return s->parameters.compress_level;
652 }
653 
654 int migrate_compress_threads(void)
655 {
656     MigrationState *s = migrate_get_current();
657 
658     return s->parameters.compress_threads;
659 }
660 
661 int migrate_compress_wait_thread(void)
662 {
663     MigrationState *s = migrate_get_current();
664 
665     return s->parameters.compress_wait_thread;
666 }
667 
668 uint8_t migrate_cpu_throttle_increment(void)
669 {
670     MigrationState *s = migrate_get_current();
671 
672     return s->parameters.cpu_throttle_increment;
673 }
674 
675 uint8_t migrate_cpu_throttle_initial(void)
676 {
677     MigrationState *s = migrate_get_current();
678 
679     return s->parameters.cpu_throttle_initial;
680 }
681 
682 bool migrate_cpu_throttle_tailslow(void)
683 {
684     MigrationState *s = migrate_get_current();
685 
686     return s->parameters.cpu_throttle_tailslow;
687 }
688 
689 int migrate_decompress_threads(void)
690 {
691     MigrationState *s = migrate_get_current();
692 
693     return s->parameters.decompress_threads;
694 }
695 
696 uint64_t migrate_downtime_limit(void)
697 {
698     MigrationState *s = migrate_get_current();
699 
700     return s->parameters.downtime_limit;
701 }
702 
703 uint8_t migrate_max_cpu_throttle(void)
704 {
705     MigrationState *s = migrate_get_current();
706 
707     return s->parameters.max_cpu_throttle;
708 }
709 
710 uint64_t migrate_max_bandwidth(void)
711 {
712     MigrationState *s = migrate_get_current();
713 
714     return s->parameters.max_bandwidth;
715 }
716 
717 int64_t migrate_max_postcopy_bandwidth(void)
718 {
719     MigrationState *s = migrate_get_current();
720 
721     return s->parameters.max_postcopy_bandwidth;
722 }
723 
724 int migrate_multifd_channels(void)
725 {
726     MigrationState *s = migrate_get_current();
727 
728     return s->parameters.multifd_channels;
729 }
730 
731 MultiFDCompression migrate_multifd_compression(void)
732 {
733     MigrationState *s = migrate_get_current();
734 
735     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
736     return s->parameters.multifd_compression;
737 }
738 
739 int migrate_multifd_zlib_level(void)
740 {
741     MigrationState *s = migrate_get_current();
742 
743     return s->parameters.multifd_zlib_level;
744 }
745 
746 int migrate_multifd_zstd_level(void)
747 {
748     MigrationState *s = migrate_get_current();
749 
750     return s->parameters.multifd_zstd_level;
751 }
752 
753 uint8_t migrate_throttle_trigger_threshold(void)
754 {
755     MigrationState *s = migrate_get_current();
756 
757     return s->parameters.throttle_trigger_threshold;
758 }
759 
760 const char *migrate_tls_authz(void)
761 {
762     MigrationState *s = migrate_get_current();
763 
764     return s->parameters.tls_authz;
765 }
766 
767 const char *migrate_tls_creds(void)
768 {
769     MigrationState *s = migrate_get_current();
770 
771     return s->parameters.tls_creds;
772 }
773 
774 const char *migrate_tls_hostname(void)
775 {
776     MigrationState *s = migrate_get_current();
777 
778     return s->parameters.tls_hostname;
779 }
780 
781 uint64_t migrate_xbzrle_cache_size(void)
782 {
783     MigrationState *s = migrate_get_current();
784 
785     return s->parameters.xbzrle_cache_size;
786 }
787 
788 /* parameter setters */
789 
790 void migrate_set_block_incremental(bool value)
791 {
792     MigrationState *s = migrate_get_current();
793 
794     s->parameters.block_incremental = value;
795 }
796 
797 /* parameters helpers */
798 
799 void block_cleanup_parameters(void)
800 {
801     MigrationState *s = migrate_get_current();
802 
803     if (s->must_remove_block_options) {
804         /* setting to false can never fail */
805         migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort);
806         migrate_set_block_incremental(false);
807         s->must_remove_block_options = false;
808     }
809 }
810 
811 AnnounceParameters *migrate_announce_params(void)
812 {
813     static AnnounceParameters ap;
814 
815     MigrationState *s = migrate_get_current();
816 
817     ap.initial = s->parameters.announce_initial;
818     ap.max = s->parameters.announce_max;
819     ap.rounds = s->parameters.announce_rounds;
820     ap.step = s->parameters.announce_step;
821 
822     return &ap;
823 }
824 
825 MigrationParameters *qmp_query_migrate_parameters(Error **errp)
826 {
827     MigrationParameters *params;
828     MigrationState *s = migrate_get_current();
829 
830     /* TODO use QAPI_CLONE() instead of duplicating it inline */
831     params = g_malloc0(sizeof(*params));
832     params->has_compress_level = true;
833     params->compress_level = s->parameters.compress_level;
834     params->has_compress_threads = true;
835     params->compress_threads = s->parameters.compress_threads;
836     params->has_compress_wait_thread = true;
837     params->compress_wait_thread = s->parameters.compress_wait_thread;
838     params->has_decompress_threads = true;
839     params->decompress_threads = s->parameters.decompress_threads;
840     params->has_throttle_trigger_threshold = true;
841     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
842     params->has_cpu_throttle_initial = true;
843     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
844     params->has_cpu_throttle_increment = true;
845     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
846     params->has_cpu_throttle_tailslow = true;
847     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
848     params->tls_creds = g_strdup(s->parameters.tls_creds);
849     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
850     params->tls_authz = g_strdup(s->parameters.tls_authz ?
851                                  s->parameters.tls_authz : "");
852     params->has_max_bandwidth = true;
853     params->max_bandwidth = s->parameters.max_bandwidth;
854     params->has_downtime_limit = true;
855     params->downtime_limit = s->parameters.downtime_limit;
856     params->has_x_checkpoint_delay = true;
857     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
858     params->has_block_incremental = true;
859     params->block_incremental = s->parameters.block_incremental;
860     params->has_multifd_channels = true;
861     params->multifd_channels = s->parameters.multifd_channels;
862     params->has_multifd_compression = true;
863     params->multifd_compression = s->parameters.multifd_compression;
864     params->has_multifd_zlib_level = true;
865     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
866     params->has_multifd_zstd_level = true;
867     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
868     params->has_xbzrle_cache_size = true;
869     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
870     params->has_max_postcopy_bandwidth = true;
871     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
872     params->has_max_cpu_throttle = true;
873     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
874     params->has_announce_initial = true;
875     params->announce_initial = s->parameters.announce_initial;
876     params->has_announce_max = true;
877     params->announce_max = s->parameters.announce_max;
878     params->has_announce_rounds = true;
879     params->announce_rounds = s->parameters.announce_rounds;
880     params->has_announce_step = true;
881     params->announce_step = s->parameters.announce_step;
882 
883     if (s->parameters.has_block_bitmap_mapping) {
884         params->has_block_bitmap_mapping = true;
885         params->block_bitmap_mapping =
886             QAPI_CLONE(BitmapMigrationNodeAliasList,
887                        s->parameters.block_bitmap_mapping);
888     }
889 
890     return params;
891 }
892 
893 void migrate_params_init(MigrationParameters *params)
894 {
895     params->tls_hostname = g_strdup("");
896     params->tls_creds = g_strdup("");
897 
898     /* Set has_* up only for parameter checks */
899     params->has_compress_level = true;
900     params->has_compress_threads = true;
901     params->has_compress_wait_thread = true;
902     params->has_decompress_threads = true;
903     params->has_throttle_trigger_threshold = true;
904     params->has_cpu_throttle_initial = true;
905     params->has_cpu_throttle_increment = true;
906     params->has_cpu_throttle_tailslow = true;
907     params->has_max_bandwidth = true;
908     params->has_downtime_limit = true;
909     params->has_x_checkpoint_delay = true;
910     params->has_block_incremental = true;
911     params->has_multifd_channels = true;
912     params->has_multifd_compression = true;
913     params->has_multifd_zlib_level = true;
914     params->has_multifd_zstd_level = true;
915     params->has_xbzrle_cache_size = true;
916     params->has_max_postcopy_bandwidth = true;
917     params->has_max_cpu_throttle = true;
918     params->has_announce_initial = true;
919     params->has_announce_max = true;
920     params->has_announce_rounds = true;
921     params->has_announce_step = true;
922 }
923 
924 /*
925  * Check whether the parameters are valid. Error will be put into errp
926  * (if provided). Return true if valid, otherwise false.
927  */
928 bool migrate_params_check(MigrationParameters *params, Error **errp)
929 {
930     if (params->has_compress_level &&
931         (params->compress_level > 9)) {
932         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",
933                    "a value between 0 and 9");
934         return false;
935     }
936 
937     if (params->has_compress_threads && (params->compress_threads < 1)) {
938         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
939                    "compress_threads",
940                    "a value between 1 and 255");
941         return false;
942     }
943 
944     if (params->has_decompress_threads && (params->decompress_threads < 1)) {
945         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
946                    "decompress_threads",
947                    "a value between 1 and 255");
948         return false;
949     }
950 
951     if (params->has_throttle_trigger_threshold &&
952         (params->throttle_trigger_threshold < 1 ||
953          params->throttle_trigger_threshold > 100)) {
954         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
955                    "throttle_trigger_threshold",
956                    "an integer in the range of 1 to 100");
957         return false;
958     }
959 
960     if (params->has_cpu_throttle_initial &&
961         (params->cpu_throttle_initial < 1 ||
962          params->cpu_throttle_initial > 99)) {
963         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
964                    "cpu_throttle_initial",
965                    "an integer in the range of 1 to 99");
966         return false;
967     }
968 
969     if (params->has_cpu_throttle_increment &&
970         (params->cpu_throttle_increment < 1 ||
971          params->cpu_throttle_increment > 99)) {
972         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
973                    "cpu_throttle_increment",
974                    "an integer in the range of 1 to 99");
975         return false;
976     }
977 
978     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
979         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
980                    "max_bandwidth",
981                    "an integer in the range of 0 to "stringify(SIZE_MAX)
982                    " bytes/second");
983         return false;
984     }
985 
986     if (params->has_downtime_limit &&
987         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
988         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
989                    "downtime_limit",
990                    "an integer in the range of 0 to "
991                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
992         return false;
993     }
994 
995     /* x_checkpoint_delay is now always positive */
996 
997     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
998         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
999                    "multifd_channels",
1000                    "a value between 1 and 255");
1001         return false;
1002     }
1003 
1004     if (params->has_multifd_zlib_level &&
1005         (params->multifd_zlib_level > 9)) {
1006         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
1007                    "a value between 0 and 9");
1008         return false;
1009     }
1010 
1011     if (params->has_multifd_zstd_level &&
1012         (params->multifd_zstd_level > 20)) {
1013         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
1014                    "a value between 0 and 20");
1015         return false;
1016     }
1017 
1018     if (params->has_xbzrle_cache_size &&
1019         (params->xbzrle_cache_size < qemu_target_page_size() ||
1020          !is_power_of_2(params->xbzrle_cache_size))) {
1021         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1022                    "xbzrle_cache_size",
1023                    "a power of two no less than the target page size");
1024         return false;
1025     }
1026 
1027     if (params->has_max_cpu_throttle &&
1028         (params->max_cpu_throttle < params->cpu_throttle_initial ||
1029          params->max_cpu_throttle > 99)) {
1030         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1031                    "max_cpu_throttle",
1032                    "an integer in the range of cpu_throttle_initial to 99");
1033         return false;
1034     }
1035 
1036     if (params->has_announce_initial &&
1037         params->announce_initial > 100000) {
1038         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1039                    "announce_initial",
1040                    "a value between 0 and 100000");
1041         return false;
1042     }
1043     if (params->has_announce_max &&
1044         params->announce_max > 100000) {
1045         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1046                    "announce_max",
1047                    "a value between 0 and 100000");
1048        return false;
1049     }
1050     if (params->has_announce_rounds &&
1051         params->announce_rounds > 1000) {
1052         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1053                    "announce_rounds",
1054                    "a value between 0 and 1000");
1055        return false;
1056     }
1057     if (params->has_announce_step &&
1058         (params->announce_step < 1 ||
1059         params->announce_step > 10000)) {
1060         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1061                    "announce_step",
1062                    "a value between 0 and 10000");
1063        return false;
1064     }
1065 
1066     if (params->has_block_bitmap_mapping &&
1067         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
1068         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
1069         return false;
1070     }
1071 
1072 #ifdef CONFIG_LINUX
1073     if (migrate_zero_copy_send() &&
1074         ((params->has_multifd_compression && params->multifd_compression) ||
1075          (params->tls_creds && *params->tls_creds))) {
1076         error_setg(errp,
1077                    "Zero copy only available for non-compressed non-TLS multifd migration");
1078         return false;
1079     }
1080 #endif
1081 
1082     return true;
1083 }
1084 
1085 static void migrate_params_test_apply(MigrateSetParameters *params,
1086                                       MigrationParameters *dest)
1087 {
1088     *dest = migrate_get_current()->parameters;
1089 
1090     /* TODO use QAPI_CLONE() instead of duplicating it inline */
1091 
1092     if (params->has_compress_level) {
1093         dest->compress_level = params->compress_level;
1094     }
1095 
1096     if (params->has_compress_threads) {
1097         dest->compress_threads = params->compress_threads;
1098     }
1099 
1100     if (params->has_compress_wait_thread) {
1101         dest->compress_wait_thread = params->compress_wait_thread;
1102     }
1103 
1104     if (params->has_decompress_threads) {
1105         dest->decompress_threads = params->decompress_threads;
1106     }
1107 
1108     if (params->has_throttle_trigger_threshold) {
1109         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
1110     }
1111 
1112     if (params->has_cpu_throttle_initial) {
1113         dest->cpu_throttle_initial = params->cpu_throttle_initial;
1114     }
1115 
1116     if (params->has_cpu_throttle_increment) {
1117         dest->cpu_throttle_increment = params->cpu_throttle_increment;
1118     }
1119 
1120     if (params->has_cpu_throttle_tailslow) {
1121         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
1122     }
1123 
1124     if (params->tls_creds) {
1125         assert(params->tls_creds->type == QTYPE_QSTRING);
1126         dest->tls_creds = params->tls_creds->u.s;
1127     }
1128 
1129     if (params->tls_hostname) {
1130         assert(params->tls_hostname->type == QTYPE_QSTRING);
1131         dest->tls_hostname = params->tls_hostname->u.s;
1132     }
1133 
1134     if (params->has_max_bandwidth) {
1135         dest->max_bandwidth = params->max_bandwidth;
1136     }
1137 
1138     if (params->has_downtime_limit) {
1139         dest->downtime_limit = params->downtime_limit;
1140     }
1141 
1142     if (params->has_x_checkpoint_delay) {
1143         dest->x_checkpoint_delay = params->x_checkpoint_delay;
1144     }
1145 
1146     if (params->has_block_incremental) {
1147         dest->block_incremental = params->block_incremental;
1148     }
1149     if (params->has_multifd_channels) {
1150         dest->multifd_channels = params->multifd_channels;
1151     }
1152     if (params->has_multifd_compression) {
1153         dest->multifd_compression = params->multifd_compression;
1154     }
1155     if (params->has_xbzrle_cache_size) {
1156         dest->xbzrle_cache_size = params->xbzrle_cache_size;
1157     }
1158     if (params->has_max_postcopy_bandwidth) {
1159         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
1160     }
1161     if (params->has_max_cpu_throttle) {
1162         dest->max_cpu_throttle = params->max_cpu_throttle;
1163     }
1164     if (params->has_announce_initial) {
1165         dest->announce_initial = params->announce_initial;
1166     }
1167     if (params->has_announce_max) {
1168         dest->announce_max = params->announce_max;
1169     }
1170     if (params->has_announce_rounds) {
1171         dest->announce_rounds = params->announce_rounds;
1172     }
1173     if (params->has_announce_step) {
1174         dest->announce_step = params->announce_step;
1175     }
1176 
1177     if (params->has_block_bitmap_mapping) {
1178         dest->has_block_bitmap_mapping = true;
1179         dest->block_bitmap_mapping = params->block_bitmap_mapping;
1180     }
1181 }
1182 
1183 static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
1184 {
1185     MigrationState *s = migrate_get_current();
1186 
1187     /* TODO use QAPI_CLONE() instead of duplicating it inline */
1188 
1189     if (params->has_compress_level) {
1190         s->parameters.compress_level = params->compress_level;
1191     }
1192 
1193     if (params->has_compress_threads) {
1194         s->parameters.compress_threads = params->compress_threads;
1195     }
1196 
1197     if (params->has_compress_wait_thread) {
1198         s->parameters.compress_wait_thread = params->compress_wait_thread;
1199     }
1200 
1201     if (params->has_decompress_threads) {
1202         s->parameters.decompress_threads = params->decompress_threads;
1203     }
1204 
1205     if (params->has_throttle_trigger_threshold) {
1206         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
1207     }
1208 
1209     if (params->has_cpu_throttle_initial) {
1210         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
1211     }
1212 
1213     if (params->has_cpu_throttle_increment) {
1214         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
1215     }
1216 
1217     if (params->has_cpu_throttle_tailslow) {
1218         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
1219     }
1220 
1221     if (params->tls_creds) {
1222         g_free(s->parameters.tls_creds);
1223         assert(params->tls_creds->type == QTYPE_QSTRING);
1224         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
1225     }
1226 
1227     if (params->tls_hostname) {
1228         g_free(s->parameters.tls_hostname);
1229         assert(params->tls_hostname->type == QTYPE_QSTRING);
1230         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
1231     }
1232 
1233     if (params->tls_authz) {
1234         g_free(s->parameters.tls_authz);
1235         assert(params->tls_authz->type == QTYPE_QSTRING);
1236         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
1237     }
1238 
1239     if (params->has_max_bandwidth) {
1240         s->parameters.max_bandwidth = params->max_bandwidth;
1241         if (s->to_dst_file && !migration_in_postcopy()) {
1242             qemu_file_set_rate_limit(s->to_dst_file,
1243                                 s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
1244         }
1245     }
1246 
1247     if (params->has_downtime_limit) {
1248         s->parameters.downtime_limit = params->downtime_limit;
1249     }
1250 
1251     if (params->has_x_checkpoint_delay) {
1252         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
1253         if (migration_in_colo_state()) {
1254             colo_checkpoint_notify(s);
1255         }
1256     }
1257 
1258     if (params->has_block_incremental) {
1259         s->parameters.block_incremental = params->block_incremental;
1260     }
1261     if (params->has_multifd_channels) {
1262         s->parameters.multifd_channels = params->multifd_channels;
1263     }
1264     if (params->has_multifd_compression) {
1265         s->parameters.multifd_compression = params->multifd_compression;
1266     }
1267     if (params->has_xbzrle_cache_size) {
1268         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
1269         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
1270     }
1271     if (params->has_max_postcopy_bandwidth) {
1272         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
1273         if (s->to_dst_file && migration_in_postcopy()) {
1274             qemu_file_set_rate_limit(s->to_dst_file,
1275                     s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO);
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