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