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