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