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