xref: /qemu/migration/options.c (revision 6ff5da16000f908140723e164d33a0b51a6c4162)
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("x-colo", MIGRATION_CAPABILITY_X_COLO),
191     DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
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_MIG_CAP("mapped-ram", MIGRATION_CAPABILITY_MAPPED_RAM),
204 };
205 const size_t migration_properties_count = ARRAY_SIZE(migration_properties);
206 
207 bool migrate_auto_converge(void)
208 {
209     MigrationState *s = migrate_get_current();
210 
211     return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
212 }
213 
214 bool migrate_send_switchover_start(void)
215 {
216     MigrationState *s = migrate_get_current();
217 
218     return s->send_switchover_start;
219 }
220 
221 bool migrate_background_snapshot(void)
222 {
223     MigrationState *s = migrate_get_current();
224 
225     return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
226 }
227 
228 bool migrate_colo(void)
229 {
230     MigrationState *s = migrate_get_current();
231 
232     return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
233 }
234 
235 bool migrate_dirty_bitmaps(void)
236 {
237     MigrationState *s = migrate_get_current();
238 
239     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
240 }
241 
242 bool migrate_dirty_limit(void)
243 {
244     MigrationState *s = migrate_get_current();
245 
246     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_LIMIT];
247 }
248 
249 bool migrate_events(void)
250 {
251     MigrationState *s = migrate_get_current();
252 
253     return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
254 }
255 
256 bool migrate_mapped_ram(void)
257 {
258     MigrationState *s = migrate_get_current();
259 
260     return s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM];
261 }
262 
263 bool migrate_ignore_shared(void)
264 {
265     MigrationState *s = migrate_get_current();
266 
267     return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
268 }
269 
270 bool migrate_late_block_activate(void)
271 {
272     MigrationState *s = migrate_get_current();
273 
274     return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
275 }
276 
277 bool migrate_multifd(void)
278 {
279     MigrationState *s = migrate_get_current();
280 
281     return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
282 }
283 
284 bool migrate_pause_before_switchover(void)
285 {
286     MigrationState *s = migrate_get_current();
287 
288     return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
289 }
290 
291 bool migrate_postcopy_blocktime(void)
292 {
293     MigrationState *s = migrate_get_current();
294 
295     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
296 }
297 
298 bool migrate_postcopy_preempt(void)
299 {
300     MigrationState *s = migrate_get_current();
301 
302     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
303 }
304 
305 bool migrate_postcopy_ram(void)
306 {
307     MigrationState *s = migrate_get_current();
308 
309     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
310 }
311 
312 bool migrate_rdma_pin_all(void)
313 {
314     MigrationState *s = migrate_get_current();
315 
316     return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
317 }
318 
319 bool migrate_release_ram(void)
320 {
321     MigrationState *s = migrate_get_current();
322 
323     return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
324 }
325 
326 bool migrate_return_path(void)
327 {
328     MigrationState *s = migrate_get_current();
329 
330     return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
331 }
332 
333 bool migrate_switchover_ack(void)
334 {
335     MigrationState *s = migrate_get_current();
336 
337     return s->capabilities[MIGRATION_CAPABILITY_SWITCHOVER_ACK];
338 }
339 
340 bool migrate_validate_uuid(void)
341 {
342     MigrationState *s = migrate_get_current();
343 
344     return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
345 }
346 
347 bool migrate_xbzrle(void)
348 {
349     MigrationState *s = migrate_get_current();
350 
351     return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
352 }
353 
354 bool migrate_zero_copy_send(void)
355 {
356     MigrationState *s = migrate_get_current();
357 
358     return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
359 }
360 
361 /* pseudo capabilities */
362 
363 bool migrate_multifd_flush_after_each_section(void)
364 {
365     MigrationState *s = migrate_get_current();
366 
367     return s->multifd_flush_after_each_section;
368 }
369 
370 bool migrate_postcopy(void)
371 {
372     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
373 }
374 
375 bool migrate_rdma(void)
376 {
377     MigrationState *s = migrate_get_current();
378 
379     return s->rdma_migration;
380 }
381 
382 bool migrate_tls(void)
383 {
384     MigrationState *s = migrate_get_current();
385 
386     return s->parameters.tls_creds && *s->parameters.tls_creds;
387 }
388 
389 typedef enum WriteTrackingSupport {
390     WT_SUPPORT_UNKNOWN = 0,
391     WT_SUPPORT_ABSENT,
392     WT_SUPPORT_AVAILABLE,
393     WT_SUPPORT_COMPATIBLE
394 } WriteTrackingSupport;
395 
396 static
397 WriteTrackingSupport migrate_query_write_tracking(void)
398 {
399     /* Check if kernel supports required UFFD features */
400     if (!ram_write_tracking_available()) {
401         return WT_SUPPORT_ABSENT;
402     }
403     /*
404      * Check if current memory configuration is
405      * compatible with required UFFD features.
406      */
407     if (!ram_write_tracking_compatible()) {
408         return WT_SUPPORT_AVAILABLE;
409     }
410 
411     return WT_SUPPORT_COMPATIBLE;
412 }
413 
414 /* Migration capabilities set */
415 struct MigrateCapsSet {
416     int size;                       /* Capability set size */
417     MigrationCapability caps[];     /* Variadic array of capabilities */
418 };
419 typedef struct MigrateCapsSet MigrateCapsSet;
420 
421 /* Define and initialize MigrateCapsSet */
422 #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
423     MigrateCapsSet _name = {    \
424         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
425         .caps = { __VA_ARGS__ } \
426     }
427 
428 /* Background-snapshot compatibility check list */
429 static const
430 INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
431     MIGRATION_CAPABILITY_POSTCOPY_RAM,
432     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
433     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
434     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
435     MIGRATION_CAPABILITY_RETURN_PATH,
436     MIGRATION_CAPABILITY_MULTIFD,
437     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
438     MIGRATION_CAPABILITY_AUTO_CONVERGE,
439     MIGRATION_CAPABILITY_RELEASE_RAM,
440     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
441     MIGRATION_CAPABILITY_XBZRLE,
442     MIGRATION_CAPABILITY_X_COLO,
443     MIGRATION_CAPABILITY_VALIDATE_UUID,
444     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
445 
446 static bool migrate_incoming_started(void)
447 {
448     return !!migration_incoming_get_current()->transport_data;
449 }
450 
451 /**
452  * @migration_caps_check - check capability compatibility
453  *
454  * @old_caps: old capability list
455  * @new_caps: new capability list
456  * @errp: set *errp if the check failed, with reason
457  *
458  * Returns true if check passed, otherwise false.
459  */
460 bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
461 {
462     ERRP_GUARD();
463     MigrationIncomingState *mis = migration_incoming_get_current();
464 
465     if (new_caps[MIGRATION_CAPABILITY_ZERO_BLOCKS]) {
466         warn_report("zero-blocks capability is deprecated");
467     }
468 
469 #ifndef CONFIG_REPLICATION
470     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
471         error_setg(errp, "QEMU compiled without replication module"
472                    " can't enable COLO");
473         error_append_hint(errp, "Please enable replication before COLO.\n");
474         return false;
475     }
476 #endif
477 
478     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
479         /* This check is reasonably expensive, so only when it's being
480          * set the first time, also it's only the destination that needs
481          * special support.
482          */
483         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
484             runstate_check(RUN_STATE_INMIGRATE) &&
485             !postcopy_ram_supported_by_host(mis, errp)) {
486             error_prepend(errp, "Postcopy is not supported: ");
487             return false;
488         }
489 
490         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
491             error_setg(errp, "Postcopy is not compatible with ignore-shared");
492             return false;
493         }
494 
495         if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
496             error_setg(errp, "Postcopy is not yet compatible with multifd");
497             return false;
498         }
499     }
500 
501     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
502         WriteTrackingSupport wt_support;
503         int idx;
504         /*
505          * Check if 'background-snapshot' capability is supported by
506          * host kernel and compatible with guest memory configuration.
507          */
508         wt_support = migrate_query_write_tracking();
509         if (wt_support < WT_SUPPORT_AVAILABLE) {
510             error_setg(errp, "Background-snapshot is not supported by host kernel");
511             return false;
512         }
513         if (wt_support < WT_SUPPORT_COMPATIBLE) {
514             error_setg(errp, "Background-snapshot is not compatible "
515                     "with guest memory configuration");
516             return false;
517         }
518 
519         /*
520          * Check if there are any migration capabilities
521          * incompatible with 'background-snapshot'.
522          */
523         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
524             int incomp_cap = check_caps_background_snapshot.caps[idx];
525             if (new_caps[incomp_cap]) {
526                 error_setg(errp,
527                         "Background-snapshot is not compatible with %s",
528                         MigrationCapability_str(incomp_cap));
529                 return false;
530             }
531         }
532     }
533 
534 #ifdef CONFIG_LINUX
535     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
536         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
537          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
538          migrate_multifd_compression() ||
539          migrate_tls())) {
540         error_setg(errp,
541                    "Zero copy only available for non-compressed non-TLS multifd migration");
542         return false;
543     }
544 #else
545     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
546         error_setg(errp,
547                    "Zero copy currently only available on Linux");
548         return false;
549     }
550 #endif
551 
552     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
553         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
554             error_setg(errp, "Postcopy preempt requires postcopy-ram");
555             return false;
556         }
557 
558         if (migrate_incoming_started()) {
559             error_setg(errp,
560                        "Postcopy preempt must be set before incoming starts");
561             return false;
562         }
563     }
564 
565     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
566         if (migrate_incoming_started()) {
567             error_setg(errp, "Multifd must be set before incoming starts");
568             return false;
569         }
570     }
571 
572     if (new_caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK]) {
573         if (!new_caps[MIGRATION_CAPABILITY_RETURN_PATH]) {
574             error_setg(errp, "Capability 'switchover-ack' requires capability "
575                              "'return-path'");
576             return false;
577         }
578     }
579     if (new_caps[MIGRATION_CAPABILITY_DIRTY_LIMIT]) {
580         if (new_caps[MIGRATION_CAPABILITY_AUTO_CONVERGE]) {
581             error_setg(errp, "dirty-limit conflicts with auto-converge"
582                        " either of then available currently");
583             return false;
584         }
585 
586         if (!kvm_enabled() || !kvm_dirty_ring_enabled()) {
587             error_setg(errp, "dirty-limit requires KVM with accelerator"
588                    " property 'dirty-ring-size' set");
589             return false;
590         }
591     }
592 
593     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
594         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
595             error_setg(errp, "Multifd is not compatible with xbzrle");
596             return false;
597         }
598     }
599 
600     if (new_caps[MIGRATION_CAPABILITY_MAPPED_RAM]) {
601         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
602             error_setg(errp,
603                        "Mapped-ram migration is incompatible with xbzrle");
604             return false;
605         }
606 
607         if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
608             error_setg(errp,
609                        "Mapped-ram migration is incompatible with postcopy");
610             return false;
611         }
612     }
613 
614     return true;
615 }
616 
617 MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
618 {
619     MigrationCapabilityStatusList *head = NULL, **tail = &head;
620     MigrationCapabilityStatus *caps;
621     MigrationState *s = migrate_get_current();
622     int i;
623 
624     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
625         caps = g_malloc0(sizeof(*caps));
626         caps->capability = i;
627         caps->state = s->capabilities[i];
628         QAPI_LIST_APPEND(tail, caps);
629     }
630 
631     return head;
632 }
633 
634 void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
635                                   Error **errp)
636 {
637     MigrationState *s = migrate_get_current();
638     MigrationCapabilityStatusList *cap;
639     bool new_caps[MIGRATION_CAPABILITY__MAX];
640 
641     if (migration_is_running() || migration_in_colo_state()) {
642         error_setg(errp, "There's a migration process in progress");
643         return;
644     }
645 
646     memcpy(new_caps, s->capabilities, sizeof(new_caps));
647     for (cap = params; cap; cap = cap->next) {
648         new_caps[cap->value->capability] = cap->value->state;
649     }
650 
651     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
652         return;
653     }
654 
655     for (cap = params; cap; cap = cap->next) {
656         s->capabilities[cap->value->capability] = cap->value->state;
657     }
658 }
659 
660 /* parameters */
661 
662 const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
663 {
664     MigrationState *s = migrate_get_current();
665 
666     return s->parameters.block_bitmap_mapping;
667 }
668 
669 bool migrate_has_block_bitmap_mapping(void)
670 {
671     MigrationState *s = migrate_get_current();
672 
673     return s->parameters.has_block_bitmap_mapping;
674 }
675 
676 uint32_t migrate_checkpoint_delay(void)
677 {
678     MigrationState *s = migrate_get_current();
679 
680     return s->parameters.x_checkpoint_delay;
681 }
682 
683 uint8_t migrate_cpu_throttle_increment(void)
684 {
685     MigrationState *s = migrate_get_current();
686 
687     return s->parameters.cpu_throttle_increment;
688 }
689 
690 uint8_t migrate_cpu_throttle_initial(void)
691 {
692     MigrationState *s = migrate_get_current();
693 
694     return s->parameters.cpu_throttle_initial;
695 }
696 
697 bool migrate_cpu_throttle_tailslow(void)
698 {
699     MigrationState *s = migrate_get_current();
700 
701     return s->parameters.cpu_throttle_tailslow;
702 }
703 
704 bool migrate_direct_io(void)
705 {
706     MigrationState *s = migrate_get_current();
707 
708     /*
709      * O_DIRECT is only supported with mapped-ram and multifd.
710      *
711      * mapped-ram is needed because filesystems impose restrictions on
712      * O_DIRECT IO alignment (see MAPPED_RAM_FILE_OFFSET_ALIGNMENT).
713      *
714      * multifd is needed to keep the unaligned portion of the stream
715      * isolated to the main migration thread while multifd channels
716      * process the aligned data with O_DIRECT enabled.
717      */
718     return s->parameters.direct_io &&
719         s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM] &&
720         s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
721 }
722 
723 uint64_t migrate_downtime_limit(void)
724 {
725     MigrationState *s = migrate_get_current();
726 
727     return s->parameters.downtime_limit;
728 }
729 
730 uint8_t migrate_max_cpu_throttle(void)
731 {
732     MigrationState *s = migrate_get_current();
733 
734     return s->parameters.max_cpu_throttle;
735 }
736 
737 uint64_t migrate_max_bandwidth(void)
738 {
739     MigrationState *s = migrate_get_current();
740 
741     return s->parameters.max_bandwidth;
742 }
743 
744 uint64_t migrate_avail_switchover_bandwidth(void)
745 {
746     MigrationState *s = migrate_get_current();
747 
748     return s->parameters.avail_switchover_bandwidth;
749 }
750 
751 uint64_t migrate_max_postcopy_bandwidth(void)
752 {
753     MigrationState *s = migrate_get_current();
754 
755     return s->parameters.max_postcopy_bandwidth;
756 }
757 
758 MigMode migrate_mode(void)
759 {
760     MigMode mode = cpr_get_incoming_mode();
761 
762     if (mode == MIG_MODE_NONE) {
763         mode = migrate_get_current()->parameters.mode;
764     }
765 
766     assert(mode >= 0 && mode < MIG_MODE__MAX);
767     return mode;
768 }
769 
770 int migrate_multifd_channels(void)
771 {
772     MigrationState *s = migrate_get_current();
773 
774     return s->parameters.multifd_channels;
775 }
776 
777 MultiFDCompression migrate_multifd_compression(void)
778 {
779     MigrationState *s = migrate_get_current();
780 
781     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
782     return s->parameters.multifd_compression;
783 }
784 
785 int migrate_multifd_zlib_level(void)
786 {
787     MigrationState *s = migrate_get_current();
788 
789     return s->parameters.multifd_zlib_level;
790 }
791 
792 int migrate_multifd_qatzip_level(void)
793 {
794     MigrationState *s = migrate_get_current();
795 
796     return s->parameters.multifd_qatzip_level;
797 }
798 
799 int migrate_multifd_zstd_level(void)
800 {
801     MigrationState *s = migrate_get_current();
802 
803     return s->parameters.multifd_zstd_level;
804 }
805 
806 uint8_t migrate_throttle_trigger_threshold(void)
807 {
808     MigrationState *s = migrate_get_current();
809 
810     return s->parameters.throttle_trigger_threshold;
811 }
812 
813 const char *migrate_tls_authz(void)
814 {
815     MigrationState *s = migrate_get_current();
816 
817     return s->parameters.tls_authz;
818 }
819 
820 const char *migrate_tls_creds(void)
821 {
822     MigrationState *s = migrate_get_current();
823 
824     return s->parameters.tls_creds;
825 }
826 
827 const char *migrate_tls_hostname(void)
828 {
829     MigrationState *s = migrate_get_current();
830 
831     return s->parameters.tls_hostname;
832 }
833 
834 uint64_t migrate_vcpu_dirty_limit_period(void)
835 {
836     MigrationState *s = migrate_get_current();
837 
838     return s->parameters.x_vcpu_dirty_limit_period;
839 }
840 
841 uint64_t migrate_xbzrle_cache_size(void)
842 {
843     MigrationState *s = migrate_get_current();
844 
845     return s->parameters.xbzrle_cache_size;
846 }
847 
848 ZeroPageDetection migrate_zero_page_detection(void)
849 {
850     MigrationState *s = migrate_get_current();
851 
852     return s->parameters.zero_page_detection;
853 }
854 
855 /* parameters helpers */
856 
857 AnnounceParameters *migrate_announce_params(void)
858 {
859     static AnnounceParameters ap;
860 
861     MigrationState *s = migrate_get_current();
862 
863     ap.initial = s->parameters.announce_initial;
864     ap.max = s->parameters.announce_max;
865     ap.rounds = s->parameters.announce_rounds;
866     ap.step = s->parameters.announce_step;
867 
868     return &ap;
869 }
870 
871 MigrationParameters *qmp_query_migrate_parameters(Error **errp)
872 {
873     MigrationParameters *params;
874     MigrationState *s = migrate_get_current();
875 
876     /* TODO use QAPI_CLONE() instead of duplicating it inline */
877     params = g_malloc0(sizeof(*params));
878     params->has_throttle_trigger_threshold = true;
879     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
880     params->has_cpu_throttle_initial = true;
881     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
882     params->has_cpu_throttle_increment = true;
883     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
884     params->has_cpu_throttle_tailslow = true;
885     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
886     params->tls_creds = g_strdup(s->parameters.tls_creds);
887     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
888     params->tls_authz = g_strdup(s->parameters.tls_authz ?
889                                  s->parameters.tls_authz : "");
890     params->has_max_bandwidth = true;
891     params->max_bandwidth = s->parameters.max_bandwidth;
892     params->has_avail_switchover_bandwidth = true;
893     params->avail_switchover_bandwidth = s->parameters.avail_switchover_bandwidth;
894     params->has_downtime_limit = true;
895     params->downtime_limit = s->parameters.downtime_limit;
896     params->has_x_checkpoint_delay = true;
897     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
898     params->has_multifd_channels = true;
899     params->multifd_channels = s->parameters.multifd_channels;
900     params->has_multifd_compression = true;
901     params->multifd_compression = s->parameters.multifd_compression;
902     params->has_multifd_zlib_level = true;
903     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
904     params->has_multifd_qatzip_level = true;
905     params->multifd_qatzip_level = s->parameters.multifd_qatzip_level;
906     params->has_multifd_zstd_level = true;
907     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
908     params->has_xbzrle_cache_size = true;
909     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
910     params->has_max_postcopy_bandwidth = true;
911     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
912     params->has_max_cpu_throttle = true;
913     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
914     params->has_announce_initial = true;
915     params->announce_initial = s->parameters.announce_initial;
916     params->has_announce_max = true;
917     params->announce_max = s->parameters.announce_max;
918     params->has_announce_rounds = true;
919     params->announce_rounds = s->parameters.announce_rounds;
920     params->has_announce_step = true;
921     params->announce_step = s->parameters.announce_step;
922 
923     if (s->parameters.has_block_bitmap_mapping) {
924         params->has_block_bitmap_mapping = true;
925         params->block_bitmap_mapping =
926             QAPI_CLONE(BitmapMigrationNodeAliasList,
927                        s->parameters.block_bitmap_mapping);
928     }
929 
930     params->has_x_vcpu_dirty_limit_period = true;
931     params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period;
932     params->has_vcpu_dirty_limit = true;
933     params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit;
934     params->has_mode = true;
935     params->mode = s->parameters.mode;
936     params->has_zero_page_detection = true;
937     params->zero_page_detection = s->parameters.zero_page_detection;
938     params->has_direct_io = true;
939     params->direct_io = s->parameters.direct_io;
940 
941     return params;
942 }
943 
944 void migrate_params_init(MigrationParameters *params)
945 {
946     params->tls_hostname = g_strdup("");
947     params->tls_creds = g_strdup("");
948 
949     /* Set has_* up only for parameter checks */
950     params->has_throttle_trigger_threshold = true;
951     params->has_cpu_throttle_initial = true;
952     params->has_cpu_throttle_increment = true;
953     params->has_cpu_throttle_tailslow = true;
954     params->has_max_bandwidth = true;
955     params->has_downtime_limit = true;
956     params->has_x_checkpoint_delay = true;
957     params->has_multifd_channels = true;
958     params->has_multifd_compression = true;
959     params->has_multifd_zlib_level = true;
960     params->has_multifd_qatzip_level = true;
961     params->has_multifd_zstd_level = true;
962     params->has_xbzrle_cache_size = true;
963     params->has_max_postcopy_bandwidth = true;
964     params->has_max_cpu_throttle = true;
965     params->has_announce_initial = true;
966     params->has_announce_max = true;
967     params->has_announce_rounds = true;
968     params->has_announce_step = true;
969     params->has_x_vcpu_dirty_limit_period = true;
970     params->has_vcpu_dirty_limit = true;
971     params->has_mode = true;
972     params->has_zero_page_detection = true;
973     params->has_direct_io = true;
974 }
975 
976 /*
977  * Check whether the parameters are valid. Error will be put into errp
978  * (if provided). Return true if valid, otherwise false.
979  */
980 bool migrate_params_check(MigrationParameters *params, Error **errp)
981 {
982     ERRP_GUARD();
983 
984     if (params->has_throttle_trigger_threshold &&
985         (params->throttle_trigger_threshold < 1 ||
986          params->throttle_trigger_threshold > 100)) {
987         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
988                    "throttle_trigger_threshold",
989                    "an integer in the range of 1 to 100");
990         return false;
991     }
992 
993     if (params->has_cpu_throttle_initial &&
994         (params->cpu_throttle_initial < 1 ||
995          params->cpu_throttle_initial > 99)) {
996         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
997                    "cpu_throttle_initial",
998                    "an integer in the range of 1 to 99");
999         return false;
1000     }
1001 
1002     if (params->has_cpu_throttle_increment &&
1003         (params->cpu_throttle_increment < 1 ||
1004          params->cpu_throttle_increment > 99)) {
1005         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1006                    "cpu_throttle_increment",
1007                    "an integer in the range of 1 to 99");
1008         return false;
1009     }
1010 
1011     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
1012         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1013                    "max_bandwidth",
1014                    "an integer in the range of 0 to "stringify(SIZE_MAX)
1015                    " bytes/second");
1016         return false;
1017     }
1018 
1019     if (params->has_avail_switchover_bandwidth &&
1020         (params->avail_switchover_bandwidth > SIZE_MAX)) {
1021         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1022                    "avail_switchover_bandwidth",
1023                    "an integer in the range of 0 to "stringify(SIZE_MAX)
1024                    " bytes/second");
1025         return false;
1026     }
1027 
1028     if (params->has_downtime_limit &&
1029         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
1030         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1031                    "downtime_limit",
1032                    "an integer in the range of 0 to "
1033                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
1034         return false;
1035     }
1036 
1037     /* x_checkpoint_delay is now always positive */
1038 
1039     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
1040         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1041                    "multifd_channels",
1042                    "a value between 1 and 255");
1043         return false;
1044     }
1045 
1046     if (params->has_multifd_zlib_level &&
1047         (params->multifd_zlib_level > 9)) {
1048         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
1049                    "a value between 0 and 9");
1050         return false;
1051     }
1052 
1053     if (params->has_multifd_qatzip_level &&
1054         ((params->multifd_qatzip_level > 9) ||
1055         (params->multifd_qatzip_level < 1))) {
1056         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_qatzip_level",
1057                    "a value between 1 and 9");
1058         return false;
1059     }
1060 
1061     if (params->has_multifd_zstd_level &&
1062         (params->multifd_zstd_level > 20)) {
1063         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
1064                    "a value between 0 and 20");
1065         return false;
1066     }
1067 
1068     if (params->has_xbzrle_cache_size &&
1069         (params->xbzrle_cache_size < qemu_target_page_size() ||
1070          !is_power_of_2(params->xbzrle_cache_size))) {
1071         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1072                    "xbzrle_cache_size",
1073                    "a power of two no less than the target page size");
1074         return false;
1075     }
1076 
1077     if (params->has_max_cpu_throttle &&
1078         (params->max_cpu_throttle < params->cpu_throttle_initial ||
1079          params->max_cpu_throttle > 99)) {
1080         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1081                    "max_cpu_throttle",
1082                    "an integer in the range of cpu_throttle_initial to 99");
1083         return false;
1084     }
1085 
1086     if (params->has_announce_initial &&
1087         params->announce_initial > 100000) {
1088         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1089                    "announce_initial",
1090                    "a value between 0 and 100000");
1091         return false;
1092     }
1093     if (params->has_announce_max &&
1094         params->announce_max > 100000) {
1095         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1096                    "announce_max",
1097                    "a value between 0 and 100000");
1098        return false;
1099     }
1100     if (params->has_announce_rounds &&
1101         params->announce_rounds > 1000) {
1102         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1103                    "announce_rounds",
1104                    "a value between 0 and 1000");
1105        return false;
1106     }
1107     if (params->has_announce_step &&
1108         (params->announce_step < 1 ||
1109         params->announce_step > 10000)) {
1110         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1111                    "announce_step",
1112                    "a value between 0 and 10000");
1113        return false;
1114     }
1115 
1116     if (params->has_block_bitmap_mapping &&
1117         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
1118         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
1119         return false;
1120     }
1121 
1122 #ifdef CONFIG_LINUX
1123     if (migrate_zero_copy_send() &&
1124         ((params->has_multifd_compression && params->multifd_compression) ||
1125          (params->tls_creds && *params->tls_creds))) {
1126         error_setg(errp,
1127                    "Zero copy only available for non-compressed non-TLS multifd migration");
1128         return false;
1129     }
1130 #endif
1131 
1132     if (migrate_mapped_ram() &&
1133         (migrate_multifd_compression() || migrate_tls())) {
1134         error_setg(errp,
1135                    "Mapped-ram only available for non-compressed non-TLS multifd migration");
1136         return false;
1137     }
1138 
1139     if (params->has_x_vcpu_dirty_limit_period &&
1140         (params->x_vcpu_dirty_limit_period < 1 ||
1141          params->x_vcpu_dirty_limit_period > 1000)) {
1142         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1143                    "x-vcpu-dirty-limit-period",
1144                    "a value between 1 and 1000");
1145         return false;
1146     }
1147 
1148     if (params->has_vcpu_dirty_limit &&
1149         (params->vcpu_dirty_limit < 1)) {
1150         error_setg(errp,
1151                    "Parameter 'vcpu_dirty_limit' must be greater than 1 MB/s");
1152         return false;
1153     }
1154 
1155     if (params->has_direct_io && params->direct_io && !qemu_has_direct_io()) {
1156         error_setg(errp, "No build-time support for direct-io");
1157         return false;
1158     }
1159 
1160     return true;
1161 }
1162 
1163 static void migrate_params_test_apply(MigrateSetParameters *params,
1164                                       MigrationParameters *dest)
1165 {
1166     *dest = migrate_get_current()->parameters;
1167 
1168     /* TODO use QAPI_CLONE() instead of duplicating it inline */
1169 
1170     if (params->has_throttle_trigger_threshold) {
1171         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
1172     }
1173 
1174     if (params->has_cpu_throttle_initial) {
1175         dest->cpu_throttle_initial = params->cpu_throttle_initial;
1176     }
1177 
1178     if (params->has_cpu_throttle_increment) {
1179         dest->cpu_throttle_increment = params->cpu_throttle_increment;
1180     }
1181 
1182     if (params->has_cpu_throttle_tailslow) {
1183         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
1184     }
1185 
1186     if (params->tls_creds) {
1187         assert(params->tls_creds->type == QTYPE_QSTRING);
1188         dest->tls_creds = params->tls_creds->u.s;
1189     }
1190 
1191     if (params->tls_hostname) {
1192         assert(params->tls_hostname->type == QTYPE_QSTRING);
1193         dest->tls_hostname = params->tls_hostname->u.s;
1194     }
1195 
1196     if (params->has_max_bandwidth) {
1197         dest->max_bandwidth = params->max_bandwidth;
1198     }
1199 
1200     if (params->has_avail_switchover_bandwidth) {
1201         dest->avail_switchover_bandwidth = params->avail_switchover_bandwidth;
1202     }
1203 
1204     if (params->has_downtime_limit) {
1205         dest->downtime_limit = params->downtime_limit;
1206     }
1207 
1208     if (params->has_x_checkpoint_delay) {
1209         dest->x_checkpoint_delay = params->x_checkpoint_delay;
1210     }
1211 
1212     if (params->has_multifd_channels) {
1213         dest->multifd_channels = params->multifd_channels;
1214     }
1215     if (params->has_multifd_compression) {
1216         dest->multifd_compression = params->multifd_compression;
1217     }
1218     if (params->has_multifd_qatzip_level) {
1219         dest->multifd_qatzip_level = params->multifd_qatzip_level;
1220     }
1221     if (params->has_multifd_zlib_level) {
1222         dest->multifd_zlib_level = params->multifd_zlib_level;
1223     }
1224     if (params->has_multifd_zstd_level) {
1225         dest->multifd_zstd_level = params->multifd_zstd_level;
1226     }
1227     if (params->has_xbzrle_cache_size) {
1228         dest->xbzrle_cache_size = params->xbzrle_cache_size;
1229     }
1230     if (params->has_max_postcopy_bandwidth) {
1231         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
1232     }
1233     if (params->has_max_cpu_throttle) {
1234         dest->max_cpu_throttle = params->max_cpu_throttle;
1235     }
1236     if (params->has_announce_initial) {
1237         dest->announce_initial = params->announce_initial;
1238     }
1239     if (params->has_announce_max) {
1240         dest->announce_max = params->announce_max;
1241     }
1242     if (params->has_announce_rounds) {
1243         dest->announce_rounds = params->announce_rounds;
1244     }
1245     if (params->has_announce_step) {
1246         dest->announce_step = params->announce_step;
1247     }
1248 
1249     if (params->has_block_bitmap_mapping) {
1250         dest->has_block_bitmap_mapping = true;
1251         dest->block_bitmap_mapping = params->block_bitmap_mapping;
1252     }
1253 
1254     if (params->has_x_vcpu_dirty_limit_period) {
1255         dest->x_vcpu_dirty_limit_period =
1256             params->x_vcpu_dirty_limit_period;
1257     }
1258     if (params->has_vcpu_dirty_limit) {
1259         dest->vcpu_dirty_limit = params->vcpu_dirty_limit;
1260     }
1261 
1262     if (params->has_mode) {
1263         dest->mode = params->mode;
1264     }
1265 
1266     if (params->has_zero_page_detection) {
1267         dest->zero_page_detection = params->zero_page_detection;
1268     }
1269 
1270     if (params->has_direct_io) {
1271         dest->direct_io = params->direct_io;
1272     }
1273 }
1274 
1275 static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
1276 {
1277     MigrationState *s = migrate_get_current();
1278 
1279     /* TODO use QAPI_CLONE() instead of duplicating it inline */
1280 
1281     if (params->has_throttle_trigger_threshold) {
1282         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
1283     }
1284 
1285     if (params->has_cpu_throttle_initial) {
1286         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
1287     }
1288 
1289     if (params->has_cpu_throttle_increment) {
1290         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
1291     }
1292 
1293     if (params->has_cpu_throttle_tailslow) {
1294         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
1295     }
1296 
1297     if (params->tls_creds) {
1298         g_free(s->parameters.tls_creds);
1299         assert(params->tls_creds->type == QTYPE_QSTRING);
1300         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
1301     }
1302 
1303     if (params->tls_hostname) {
1304         g_free(s->parameters.tls_hostname);
1305         assert(params->tls_hostname->type == QTYPE_QSTRING);
1306         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
1307     }
1308 
1309     if (params->tls_authz) {
1310         g_free(s->parameters.tls_authz);
1311         assert(params->tls_authz->type == QTYPE_QSTRING);
1312         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
1313     }
1314 
1315     if (params->has_max_bandwidth) {
1316         s->parameters.max_bandwidth = params->max_bandwidth;
1317         if (s->to_dst_file && !migration_in_postcopy()) {
1318             migration_rate_set(s->parameters.max_bandwidth);
1319         }
1320     }
1321 
1322     if (params->has_avail_switchover_bandwidth) {
1323         s->parameters.avail_switchover_bandwidth = params->avail_switchover_bandwidth;
1324     }
1325 
1326     if (params->has_downtime_limit) {
1327         s->parameters.downtime_limit = params->downtime_limit;
1328     }
1329 
1330     if (params->has_x_checkpoint_delay) {
1331         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
1332         colo_checkpoint_delay_set();
1333     }
1334 
1335     if (params->has_multifd_channels) {
1336         s->parameters.multifd_channels = params->multifd_channels;
1337     }
1338     if (params->has_multifd_compression) {
1339         s->parameters.multifd_compression = params->multifd_compression;
1340     }
1341     if (params->has_multifd_qatzip_level) {
1342         s->parameters.multifd_qatzip_level = params->multifd_qatzip_level;
1343     }
1344     if (params->has_multifd_zlib_level) {
1345         s->parameters.multifd_zlib_level = params->multifd_zlib_level;
1346     }
1347     if (params->has_multifd_zstd_level) {
1348         s->parameters.multifd_zstd_level = params->multifd_zstd_level;
1349     }
1350     if (params->has_xbzrle_cache_size) {
1351         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
1352         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
1353     }
1354     if (params->has_max_postcopy_bandwidth) {
1355         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
1356         if (s->to_dst_file && migration_in_postcopy()) {
1357             migration_rate_set(s->parameters.max_postcopy_bandwidth);
1358         }
1359     }
1360     if (params->has_max_cpu_throttle) {
1361         s->parameters.max_cpu_throttle = params->max_cpu_throttle;
1362     }
1363     if (params->has_announce_initial) {
1364         s->parameters.announce_initial = params->announce_initial;
1365     }
1366     if (params->has_announce_max) {
1367         s->parameters.announce_max = params->announce_max;
1368     }
1369     if (params->has_announce_rounds) {
1370         s->parameters.announce_rounds = params->announce_rounds;
1371     }
1372     if (params->has_announce_step) {
1373         s->parameters.announce_step = params->announce_step;
1374     }
1375 
1376     if (params->has_block_bitmap_mapping) {
1377         qapi_free_BitmapMigrationNodeAliasList(
1378             s->parameters.block_bitmap_mapping);
1379 
1380         s->parameters.has_block_bitmap_mapping = true;
1381         s->parameters.block_bitmap_mapping =
1382             QAPI_CLONE(BitmapMigrationNodeAliasList,
1383                        params->block_bitmap_mapping);
1384     }
1385 
1386     if (params->has_x_vcpu_dirty_limit_period) {
1387         s->parameters.x_vcpu_dirty_limit_period =
1388             params->x_vcpu_dirty_limit_period;
1389     }
1390     if (params->has_vcpu_dirty_limit) {
1391         s->parameters.vcpu_dirty_limit = params->vcpu_dirty_limit;
1392     }
1393 
1394     if (params->has_mode) {
1395         s->parameters.mode = params->mode;
1396     }
1397 
1398     if (params->has_zero_page_detection) {
1399         s->parameters.zero_page_detection = params->zero_page_detection;
1400     }
1401 
1402     if (params->has_direct_io) {
1403         s->parameters.direct_io = params->direct_io;
1404     }
1405 }
1406 
1407 void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
1408 {
1409     MigrationParameters tmp;
1410 
1411     /* TODO Rewrite "" to null instead for all three tls_* parameters */
1412     if (params->tls_creds
1413         && params->tls_creds->type == QTYPE_QNULL) {
1414         qobject_unref(params->tls_creds->u.n);
1415         params->tls_creds->type = QTYPE_QSTRING;
1416         params->tls_creds->u.s = strdup("");
1417     }
1418     if (params->tls_hostname
1419         && params->tls_hostname->type == QTYPE_QNULL) {
1420         qobject_unref(params->tls_hostname->u.n);
1421         params->tls_hostname->type = QTYPE_QSTRING;
1422         params->tls_hostname->u.s = strdup("");
1423     }
1424     if (params->tls_authz
1425         && params->tls_authz->type == QTYPE_QNULL) {
1426         qobject_unref(params->tls_authz->u.n);
1427         params->tls_authz->type = QTYPE_QSTRING;
1428         params->tls_authz->u.s = strdup("");
1429     }
1430 
1431     migrate_params_test_apply(params, &tmp);
1432 
1433     if (!migrate_params_check(&tmp, errp)) {
1434         /* Invalid parameter */
1435         return;
1436     }
1437 
1438     migrate_params_apply(params, errp);
1439 }
1440