xref: /openbmc/qemu/migration/options.c (revision f9436522c8dd35a51f6d796501de7fd4d4928481)
11f0776f1SJuan Quintela /*
21f0776f1SJuan Quintela  * QEMU migration capabilities
31f0776f1SJuan Quintela  *
41f0776f1SJuan Quintela  * Copyright (c) 2012-2023 Red Hat Inc
51f0776f1SJuan Quintela  *
61f0776f1SJuan Quintela  * Authors:
71f0776f1SJuan Quintela  *   Orit Wasserman <owasserm@redhat.com>
81f0776f1SJuan Quintela  *   Juan Quintela <quintela@redhat.com>
91f0776f1SJuan Quintela  *
101f0776f1SJuan Quintela  * This work is licensed under the terms of the GNU GPL, version 2 or later.
111f0776f1SJuan Quintela  * See the COPYING file in the top-level directory.
121f0776f1SJuan Quintela  */
131f0776f1SJuan Quintela 
141f0776f1SJuan Quintela #include "qemu/osdep.h"
1509d6c965SJuan Quintela #include "exec/target_page.h"
169c894df3SJuan Quintela #include "qapi/clone-visitor.h"
1777608706SJuan Quintela #include "qapi/error.h"
184d0c6b69SJuan Quintela #include "qapi/qapi-commands-migration.h"
199c894df3SJuan Quintela #include "qapi/qapi-visit-migration.h"
20f80196b7SJuan Quintela #include "qapi/qmp/qerror.h"
2109d6c965SJuan Quintela #include "qapi/qmp/qnull.h"
2277608706SJuan Quintela #include "sysemu/runstate.h"
2309d6c965SJuan Quintela #include "migration/colo.h"
242682c4eeSJuan Quintela #include "migration/misc.h"
251f0776f1SJuan Quintela #include "migration.h"
2609d6c965SJuan Quintela #include "qemu-file.h"
2777608706SJuan Quintela #include "ram.h"
281f0776f1SJuan Quintela #include "options.h"
291f0776f1SJuan Quintela 
3009d6c965SJuan Quintela /* Maximum migrate downtime set to 2000 seconds */
3109d6c965SJuan Quintela #define MAX_MIGRATE_DOWNTIME_SECONDS 2000
3209d6c965SJuan Quintela #define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000)
3309d6c965SJuan Quintela 
34*f9436522SJuan Quintela #define MAX_THROTTLE  (128 << 20)      /* Migration transfer speed throttling */
35*f9436522SJuan Quintela 
36*f9436522SJuan Quintela /* Time in milliseconds we are allowed to stop the source,
37*f9436522SJuan Quintela  * for sending the last part */
38*f9436522SJuan Quintela #define DEFAULT_MIGRATE_SET_DOWNTIME 300
39*f9436522SJuan Quintela 
40*f9436522SJuan Quintela /* Default compression thread count */
41*f9436522SJuan Quintela #define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
42*f9436522SJuan Quintela /* Default decompression thread count, usually decompression is at
43*f9436522SJuan Quintela  * least 4 times as fast as compression.*/
44*f9436522SJuan Quintela #define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2
45*f9436522SJuan Quintela /*0: means nocompress, 1: best speed, ... 9: best compress ratio */
46*f9436522SJuan Quintela #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1
47*f9436522SJuan Quintela /* Define default autoconverge cpu throttle migration parameters */
48*f9436522SJuan Quintela #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50
49*f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
50*f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
51*f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99
52*f9436522SJuan Quintela 
53*f9436522SJuan Quintela /* Migration XBZRLE default cache size */
54*f9436522SJuan Quintela #define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024)
55*f9436522SJuan Quintela 
56*f9436522SJuan Quintela /* The delay time (in ms) between two COLO checkpoints */
57*f9436522SJuan Quintela #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100)
58*f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
59*f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE
60*f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 9: best compress ratio */
61*f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1
62*f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 20: best compress ratio */
63*f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1
64*f9436522SJuan Quintela 
65*f9436522SJuan Quintela /* Background transfer rate for postcopy, 0 means unlimited, note
66*f9436522SJuan Quintela  * that page requests can still exceed this limit.
67*f9436522SJuan Quintela  */
68*f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0
69*f9436522SJuan Quintela 
70*f9436522SJuan Quintela /*
71*f9436522SJuan Quintela  * Parameters for self_announce_delay giving a stream of RARP/ARP
72*f9436522SJuan Quintela  * packets after migration.
73*f9436522SJuan Quintela  */
74*f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_INITIAL  50
75*f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_MAX     550
76*f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS    5
77*f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_STEP    100
78*f9436522SJuan Quintela 
79*f9436522SJuan Quintela #define DEFINE_PROP_MIG_CAP(name, x)             \
80*f9436522SJuan Quintela     DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false)
81*f9436522SJuan Quintela 
82*f9436522SJuan Quintela Property migration_properties[] = {
83*f9436522SJuan Quintela     DEFINE_PROP_BOOL("store-global-state", MigrationState,
84*f9436522SJuan Quintela                      store_global_state, true),
85*f9436522SJuan Quintela     DEFINE_PROP_BOOL("send-configuration", MigrationState,
86*f9436522SJuan Quintela                      send_configuration, true),
87*f9436522SJuan Quintela     DEFINE_PROP_BOOL("send-section-footer", MigrationState,
88*f9436522SJuan Quintela                      send_section_footer, true),
89*f9436522SJuan Quintela     DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
90*f9436522SJuan Quintela                       decompress_error_check, true),
91*f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
92*f9436522SJuan Quintela                       clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
93*f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
94*f9436522SJuan Quintela                      preempt_pre_7_2, false),
95*f9436522SJuan Quintela 
96*f9436522SJuan Quintela     /* Migration parameters */
97*f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-compress-level", MigrationState,
98*f9436522SJuan Quintela                       parameters.compress_level,
99*f9436522SJuan Quintela                       DEFAULT_MIGRATE_COMPRESS_LEVEL),
100*f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-compress-threads", MigrationState,
101*f9436522SJuan Quintela                       parameters.compress_threads,
102*f9436522SJuan Quintela                       DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT),
103*f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState,
104*f9436522SJuan Quintela                       parameters.compress_wait_thread, true),
105*f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-decompress-threads", MigrationState,
106*f9436522SJuan Quintela                       parameters.decompress_threads,
107*f9436522SJuan Quintela                       DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT),
108*f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState,
109*f9436522SJuan Quintela                       parameters.throttle_trigger_threshold,
110*f9436522SJuan Quintela                       DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
111*f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState,
112*f9436522SJuan Quintela                       parameters.cpu_throttle_initial,
113*f9436522SJuan Quintela                       DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL),
114*f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState,
115*f9436522SJuan Quintela                       parameters.cpu_throttle_increment,
116*f9436522SJuan Quintela                       DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
117*f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState,
118*f9436522SJuan Quintela                       parameters.cpu_throttle_tailslow, false),
119*f9436522SJuan Quintela     DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState,
120*f9436522SJuan Quintela                       parameters.max_bandwidth, MAX_THROTTLE),
121*f9436522SJuan Quintela     DEFINE_PROP_UINT64("x-downtime-limit", MigrationState,
122*f9436522SJuan Quintela                       parameters.downtime_limit,
123*f9436522SJuan Quintela                       DEFAULT_MIGRATE_SET_DOWNTIME),
124*f9436522SJuan Quintela     DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
125*f9436522SJuan Quintela                       parameters.x_checkpoint_delay,
126*f9436522SJuan Quintela                       DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
127*f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-channels", MigrationState,
128*f9436522SJuan Quintela                       parameters.multifd_channels,
129*f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_CHANNELS),
130*f9436522SJuan Quintela     DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState,
131*f9436522SJuan Quintela                       parameters.multifd_compression,
132*f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_COMPRESSION),
133*f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState,
134*f9436522SJuan Quintela                       parameters.multifd_zlib_level,
135*f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL),
136*f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState,
137*f9436522SJuan Quintela                       parameters.multifd_zstd_level,
138*f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL),
139*f9436522SJuan Quintela     DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
140*f9436522SJuan Quintela                       parameters.xbzrle_cache_size,
141*f9436522SJuan Quintela                       DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
142*f9436522SJuan Quintela     DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState,
143*f9436522SJuan Quintela                       parameters.max_postcopy_bandwidth,
144*f9436522SJuan Quintela                       DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH),
145*f9436522SJuan Quintela     DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState,
146*f9436522SJuan Quintela                       parameters.max_cpu_throttle,
147*f9436522SJuan Quintela                       DEFAULT_MIGRATE_MAX_CPU_THROTTLE),
148*f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-initial", MigrationState,
149*f9436522SJuan Quintela                       parameters.announce_initial,
150*f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_INITIAL),
151*f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-max", MigrationState,
152*f9436522SJuan Quintela                       parameters.announce_max,
153*f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_MAX),
154*f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-rounds", MigrationState,
155*f9436522SJuan Quintela                       parameters.announce_rounds,
156*f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_ROUNDS),
157*f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-step", MigrationState,
158*f9436522SJuan Quintela                       parameters.announce_step,
159*f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_STEP),
160*f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds),
161*f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname),
162*f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz),
163*f9436522SJuan Quintela 
164*f9436522SJuan Quintela     /* Migration capabilities */
165*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
166*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL),
167*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE),
168*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS),
169*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS),
170*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS),
171*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM),
172*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-postcopy-preempt",
173*f9436522SJuan Quintela                         MIGRATION_CAPABILITY_POSTCOPY_PREEMPT),
174*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO),
175*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
176*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
177*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH),
178*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
179*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-background-snapshot",
180*f9436522SJuan Quintela             MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
181*f9436522SJuan Quintela #ifdef CONFIG_LINUX
182*f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-zero-copy-send",
183*f9436522SJuan Quintela             MIGRATION_CAPABILITY_ZERO_COPY_SEND),
184*f9436522SJuan Quintela #endif
185*f9436522SJuan Quintela 
186*f9436522SJuan Quintela     DEFINE_PROP_END_OF_LIST(),
187*f9436522SJuan Quintela };
188*f9436522SJuan Quintela 
1891f0776f1SJuan Quintela bool migrate_auto_converge(void)
1901f0776f1SJuan Quintela {
1918f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1921f0776f1SJuan Quintela 
1931f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
1941f0776f1SJuan Quintela }
1951f0776f1SJuan Quintela 
1961f0776f1SJuan Quintela bool migrate_background_snapshot(void)
1971f0776f1SJuan Quintela {
1988f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1991f0776f1SJuan Quintela 
2001f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
2011f0776f1SJuan Quintela }
2021f0776f1SJuan Quintela 
2039d4b1e5fSJuan Quintela bool migrate_block(void)
2049d4b1e5fSJuan Quintela {
2058f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2069d4b1e5fSJuan Quintela 
2079d4b1e5fSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BLOCK];
2089d4b1e5fSJuan Quintela }
2099d4b1e5fSJuan Quintela 
2105e804644SJuan Quintela bool migrate_colo(void)
2115e804644SJuan Quintela {
2125e804644SJuan Quintela     MigrationState *s = migrate_get_current();
2138f9c5327SJuan Quintela 
2145e804644SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
2155e804644SJuan Quintela }
2165e804644SJuan Quintela 
217a7a94d14SJuan Quintela bool migrate_compress(void)
218a7a94d14SJuan Quintela {
2198f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
220a7a94d14SJuan Quintela 
221a7a94d14SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
222a7a94d14SJuan Quintela }
223a7a94d14SJuan Quintela 
2241f0776f1SJuan Quintela bool migrate_dirty_bitmaps(void)
2251f0776f1SJuan Quintela {
2268f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2271f0776f1SJuan Quintela 
2281f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
2291f0776f1SJuan Quintela }
2301f0776f1SJuan Quintela 
231b890902cSJuan Quintela bool migrate_events(void)
232b890902cSJuan Quintela {
2338f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
234b890902cSJuan Quintela 
235b890902cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
236b890902cSJuan Quintela }
237b890902cSJuan Quintela 
2381f0776f1SJuan Quintela bool migrate_ignore_shared(void)
2391f0776f1SJuan Quintela {
2408f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2411f0776f1SJuan Quintela 
2421f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
2431f0776f1SJuan Quintela }
2441f0776f1SJuan Quintela 
2451f0776f1SJuan Quintela bool migrate_late_block_activate(void)
2461f0776f1SJuan Quintela {
2478f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2481f0776f1SJuan Quintela 
2491f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
2501f0776f1SJuan Quintela }
2511f0776f1SJuan Quintela 
25251b07548SJuan Quintela bool migrate_multifd(void)
25351b07548SJuan Quintela {
2548f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
25551b07548SJuan Quintela 
25651b07548SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
25751b07548SJuan Quintela }
25851b07548SJuan Quintela 
2591f0776f1SJuan Quintela bool migrate_pause_before_switchover(void)
2601f0776f1SJuan Quintela {
2618f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2621f0776f1SJuan Quintela 
2631f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
2641f0776f1SJuan Quintela }
2651f0776f1SJuan Quintela 
2661f0776f1SJuan Quintela bool migrate_postcopy_blocktime(void)
2671f0776f1SJuan Quintela {
2688f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2691f0776f1SJuan Quintela 
2701f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
2711f0776f1SJuan Quintela }
2721f0776f1SJuan Quintela 
2731f0776f1SJuan Quintela bool migrate_postcopy_preempt(void)
2741f0776f1SJuan Quintela {
2758f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2761f0776f1SJuan Quintela 
2771f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
2781f0776f1SJuan Quintela }
2791f0776f1SJuan Quintela 
2801f0776f1SJuan Quintela bool migrate_postcopy_ram(void)
2811f0776f1SJuan Quintela {
2828f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2831f0776f1SJuan Quintela 
2841f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
2851f0776f1SJuan Quintela }
2861f0776f1SJuan Quintela 
28717cba690SJuan Quintela bool migrate_rdma_pin_all(void)
28817cba690SJuan Quintela {
28917cba690SJuan Quintela     MigrationState *s = migrate_get_current();
29017cba690SJuan Quintela 
29117cba690SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
29217cba690SJuan Quintela }
29317cba690SJuan Quintela 
2941f0776f1SJuan Quintela bool migrate_release_ram(void)
2951f0776f1SJuan Quintela {
2968f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2971f0776f1SJuan Quintela 
2981f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
2991f0776f1SJuan Quintela }
3001f0776f1SJuan Quintela 
30138ad1110SJuan Quintela bool migrate_return_path(void)
30238ad1110SJuan Quintela {
3038f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
30438ad1110SJuan Quintela 
30538ad1110SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
30638ad1110SJuan Quintela }
30738ad1110SJuan Quintela 
3081f0776f1SJuan Quintela bool migrate_validate_uuid(void)
3091f0776f1SJuan Quintela {
3108f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3111f0776f1SJuan Quintela 
3121f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
3131f0776f1SJuan Quintela }
3141f0776f1SJuan Quintela 
31587dca0c9SJuan Quintela bool migrate_xbzrle(void)
31687dca0c9SJuan Quintela {
3178f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
31887dca0c9SJuan Quintela 
31987dca0c9SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
32087dca0c9SJuan Quintela }
32187dca0c9SJuan Quintela 
3221f0776f1SJuan Quintela bool migrate_zero_blocks(void)
3231f0776f1SJuan Quintela {
3248f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3251f0776f1SJuan Quintela 
3261f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
3271f0776f1SJuan Quintela }
328b4bc342cSJuan Quintela 
329b4bc342cSJuan Quintela bool migrate_zero_copy_send(void)
330b4bc342cSJuan Quintela {
3318f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
332b4bc342cSJuan Quintela 
333b4bc342cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
334b4bc342cSJuan Quintela }
335f774fde5SJuan Quintela 
336f774fde5SJuan Quintela /* pseudo capabilities */
337f774fde5SJuan Quintela 
338f774fde5SJuan Quintela bool migrate_postcopy(void)
339f774fde5SJuan Quintela {
340f774fde5SJuan Quintela     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
341f774fde5SJuan Quintela }
342f774fde5SJuan Quintela 
34310d4703bSJuan Quintela bool migrate_tls(void)
34410d4703bSJuan Quintela {
3458f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
34610d4703bSJuan Quintela 
34710d4703bSJuan Quintela     return s->parameters.tls_creds && *s->parameters.tls_creds;
34810d4703bSJuan Quintela }
34910d4703bSJuan Quintela 
35077608706SJuan Quintela typedef enum WriteTrackingSupport {
35177608706SJuan Quintela     WT_SUPPORT_UNKNOWN = 0,
35277608706SJuan Quintela     WT_SUPPORT_ABSENT,
35377608706SJuan Quintela     WT_SUPPORT_AVAILABLE,
35477608706SJuan Quintela     WT_SUPPORT_COMPATIBLE
35577608706SJuan Quintela } WriteTrackingSupport;
35677608706SJuan Quintela 
35777608706SJuan Quintela static
35877608706SJuan Quintela WriteTrackingSupport migrate_query_write_tracking(void)
35977608706SJuan Quintela {
36077608706SJuan Quintela     /* Check if kernel supports required UFFD features */
36177608706SJuan Quintela     if (!ram_write_tracking_available()) {
36277608706SJuan Quintela         return WT_SUPPORT_ABSENT;
36377608706SJuan Quintela     }
36477608706SJuan Quintela     /*
36577608706SJuan Quintela      * Check if current memory configuration is
36677608706SJuan Quintela      * compatible with required UFFD features.
36777608706SJuan Quintela      */
36877608706SJuan Quintela     if (!ram_write_tracking_compatible()) {
36977608706SJuan Quintela         return WT_SUPPORT_AVAILABLE;
37077608706SJuan Quintela     }
37177608706SJuan Quintela 
37277608706SJuan Quintela     return WT_SUPPORT_COMPATIBLE;
37377608706SJuan Quintela }
37477608706SJuan Quintela 
37577608706SJuan Quintela /* Migration capabilities set */
37677608706SJuan Quintela struct MigrateCapsSet {
37777608706SJuan Quintela     int size;                       /* Capability set size */
37877608706SJuan Quintela     MigrationCapability caps[];     /* Variadic array of capabilities */
37977608706SJuan Quintela };
38077608706SJuan Quintela typedef struct MigrateCapsSet MigrateCapsSet;
38177608706SJuan Quintela 
38277608706SJuan Quintela /* Define and initialize MigrateCapsSet */
38377608706SJuan Quintela #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
38477608706SJuan Quintela     MigrateCapsSet _name = {    \
38577608706SJuan Quintela         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
38677608706SJuan Quintela         .caps = { __VA_ARGS__ } \
38777608706SJuan Quintela     }
38877608706SJuan Quintela 
38977608706SJuan Quintela /* Background-snapshot compatibility check list */
39077608706SJuan Quintela static const
39177608706SJuan Quintela INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
39277608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_RAM,
39377608706SJuan Quintela     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
39477608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
39577608706SJuan Quintela     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
39677608706SJuan Quintela     MIGRATION_CAPABILITY_RETURN_PATH,
39777608706SJuan Quintela     MIGRATION_CAPABILITY_MULTIFD,
39877608706SJuan Quintela     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
39977608706SJuan Quintela     MIGRATION_CAPABILITY_AUTO_CONVERGE,
40077608706SJuan Quintela     MIGRATION_CAPABILITY_RELEASE_RAM,
40177608706SJuan Quintela     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
40277608706SJuan Quintela     MIGRATION_CAPABILITY_COMPRESS,
40377608706SJuan Quintela     MIGRATION_CAPABILITY_XBZRLE,
40477608706SJuan Quintela     MIGRATION_CAPABILITY_X_COLO,
40577608706SJuan Quintela     MIGRATION_CAPABILITY_VALIDATE_UUID,
40677608706SJuan Quintela     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
40777608706SJuan Quintela 
40877608706SJuan Quintela /**
40977608706SJuan Quintela  * @migration_caps_check - check capability compatibility
41077608706SJuan Quintela  *
41177608706SJuan Quintela  * @old_caps: old capability list
41277608706SJuan Quintela  * @new_caps: new capability list
41377608706SJuan Quintela  * @errp: set *errp if the check failed, with reason
41477608706SJuan Quintela  *
41577608706SJuan Quintela  * Returns true if check passed, otherwise false.
41677608706SJuan Quintela  */
41777608706SJuan Quintela bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
41877608706SJuan Quintela {
41977608706SJuan Quintela     MigrationIncomingState *mis = migration_incoming_get_current();
42077608706SJuan Quintela 
42174c38cf7SPeter Xu     ERRP_GUARD();
42277608706SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
42377608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BLOCK]) {
42477608706SJuan Quintela         error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) "
42577608706SJuan Quintela                    "block migration");
42677608706SJuan Quintela         error_append_hint(errp, "Use drive_mirror+NBD instead.\n");
42777608706SJuan Quintela         return false;
42877608706SJuan Quintela     }
42977608706SJuan Quintela #endif
43077608706SJuan Quintela 
43177608706SJuan Quintela #ifndef CONFIG_REPLICATION
43277608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
43377608706SJuan Quintela         error_setg(errp, "QEMU compiled without replication module"
43477608706SJuan Quintela                    " can't enable COLO");
43577608706SJuan Quintela         error_append_hint(errp, "Please enable replication before COLO.\n");
43677608706SJuan Quintela         return false;
43777608706SJuan Quintela     }
43877608706SJuan Quintela #endif
43977608706SJuan Quintela 
44077608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
44177608706SJuan Quintela         /* This check is reasonably expensive, so only when it's being
44277608706SJuan Quintela          * set the first time, also it's only the destination that needs
44377608706SJuan Quintela          * special support.
44477608706SJuan Quintela          */
44577608706SJuan Quintela         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
44677608706SJuan Quintela             runstate_check(RUN_STATE_INMIGRATE) &&
44774c38cf7SPeter Xu             !postcopy_ram_supported_by_host(mis, errp)) {
44874c38cf7SPeter Xu             error_prepend(errp, "Postcopy is not supported: ");
44977608706SJuan Quintela             return false;
45077608706SJuan Quintela         }
45177608706SJuan Quintela 
45277608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
45377608706SJuan Quintela             error_setg(errp, "Postcopy is not compatible with ignore-shared");
45477608706SJuan Quintela             return false;
45577608706SJuan Quintela         }
456b405dfffSLeonardo Bras 
457b405dfffSLeonardo Bras         if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
458b405dfffSLeonardo Bras             error_setg(errp, "Postcopy is not yet compatible with multifd");
459b405dfffSLeonardo Bras             return false;
460b405dfffSLeonardo Bras         }
46177608706SJuan Quintela     }
46277608706SJuan Quintela 
46377608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
46477608706SJuan Quintela         WriteTrackingSupport wt_support;
46577608706SJuan Quintela         int idx;
46677608706SJuan Quintela         /*
46777608706SJuan Quintela          * Check if 'background-snapshot' capability is supported by
46877608706SJuan Quintela          * host kernel and compatible with guest memory configuration.
46977608706SJuan Quintela          */
47077608706SJuan Quintela         wt_support = migrate_query_write_tracking();
47177608706SJuan Quintela         if (wt_support < WT_SUPPORT_AVAILABLE) {
47277608706SJuan Quintela             error_setg(errp, "Background-snapshot is not supported by host kernel");
47377608706SJuan Quintela             return false;
47477608706SJuan Quintela         }
47577608706SJuan Quintela         if (wt_support < WT_SUPPORT_COMPATIBLE) {
47677608706SJuan Quintela             error_setg(errp, "Background-snapshot is not compatible "
47777608706SJuan Quintela                     "with guest memory configuration");
47877608706SJuan Quintela             return false;
47977608706SJuan Quintela         }
48077608706SJuan Quintela 
48177608706SJuan Quintela         /*
48277608706SJuan Quintela          * Check if there are any migration capabilities
48377608706SJuan Quintela          * incompatible with 'background-snapshot'.
48477608706SJuan Quintela          */
48577608706SJuan Quintela         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
48677608706SJuan Quintela             int incomp_cap = check_caps_background_snapshot.caps[idx];
48777608706SJuan Quintela             if (new_caps[incomp_cap]) {
48877608706SJuan Quintela                 error_setg(errp,
48977608706SJuan Quintela                         "Background-snapshot is not compatible with %s",
49077608706SJuan Quintela                         MigrationCapability_str(incomp_cap));
49177608706SJuan Quintela                 return false;
49277608706SJuan Quintela             }
49377608706SJuan Quintela         }
49477608706SJuan Quintela     }
49577608706SJuan Quintela 
49677608706SJuan Quintela #ifdef CONFIG_LINUX
49777608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
49877608706SJuan Quintela         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
49977608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_COMPRESS] ||
50077608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
50177608706SJuan Quintela          migrate_multifd_compression() ||
50210d4703bSJuan Quintela          migrate_tls())) {
50377608706SJuan Quintela         error_setg(errp,
50477608706SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
50577608706SJuan Quintela         return false;
50677608706SJuan Quintela     }
50777608706SJuan Quintela #else
50877608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
50977608706SJuan Quintela         error_setg(errp,
51077608706SJuan Quintela                    "Zero copy currently only available on Linux");
51177608706SJuan Quintela         return false;
51277608706SJuan Quintela     }
51377608706SJuan Quintela #endif
51477608706SJuan Quintela 
51577608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
51677608706SJuan Quintela         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
51777608706SJuan Quintela             error_setg(errp, "Postcopy preempt requires postcopy-ram");
51877608706SJuan Quintela             return false;
51977608706SJuan Quintela         }
52077608706SJuan Quintela 
52177608706SJuan Quintela         /*
52277608706SJuan Quintela          * Preempt mode requires urgent pages to be sent in separate
52377608706SJuan Quintela          * channel, OTOH compression logic will disorder all pages into
52477608706SJuan Quintela          * different compression channels, which is not compatible with the
52577608706SJuan Quintela          * preempt assumptions on channel assignments.
52677608706SJuan Quintela          */
52777608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
52877608706SJuan Quintela             error_setg(errp, "Postcopy preempt not compatible with compress");
52977608706SJuan Quintela             return false;
53077608706SJuan Quintela         }
53177608706SJuan Quintela     }
53277608706SJuan Quintela 
53377608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
53477608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
53577608706SJuan Quintela             error_setg(errp, "Multifd is not compatible with compress");
53677608706SJuan Quintela             return false;
53777608706SJuan Quintela         }
53877608706SJuan Quintela     }
53977608706SJuan Quintela 
54077608706SJuan Quintela     return true;
54177608706SJuan Quintela }
5424d0c6b69SJuan Quintela 
543f80196b7SJuan Quintela bool migrate_cap_set(int cap, bool value, Error **errp)
544f80196b7SJuan Quintela {
545f80196b7SJuan Quintela     MigrationState *s = migrate_get_current();
546f80196b7SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
547f80196b7SJuan Quintela 
548f80196b7SJuan Quintela     if (migration_is_running(s->state)) {
549f80196b7SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
550f80196b7SJuan Quintela         return false;
551f80196b7SJuan Quintela     }
552f80196b7SJuan Quintela 
553f80196b7SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
554f80196b7SJuan Quintela     new_caps[cap] = value;
555f80196b7SJuan Quintela 
556f80196b7SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
557f80196b7SJuan Quintela         return false;
558f80196b7SJuan Quintela     }
559f80196b7SJuan Quintela     s->capabilities[cap] = value;
560f80196b7SJuan Quintela     return true;
561f80196b7SJuan Quintela }
562f80196b7SJuan Quintela 
5634d0c6b69SJuan Quintela MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
5644d0c6b69SJuan Quintela {
5654d0c6b69SJuan Quintela     MigrationCapabilityStatusList *head = NULL, **tail = &head;
5664d0c6b69SJuan Quintela     MigrationCapabilityStatus *caps;
5674d0c6b69SJuan Quintela     MigrationState *s = migrate_get_current();
5684d0c6b69SJuan Quintela     int i;
5694d0c6b69SJuan Quintela 
5704d0c6b69SJuan Quintela     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
5714d0c6b69SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
5724d0c6b69SJuan Quintela         if (i == MIGRATION_CAPABILITY_BLOCK) {
5734d0c6b69SJuan Quintela             continue;
5744d0c6b69SJuan Quintela         }
5754d0c6b69SJuan Quintela #endif
5764d0c6b69SJuan Quintela         caps = g_malloc0(sizeof(*caps));
5774d0c6b69SJuan Quintela         caps->capability = i;
5784d0c6b69SJuan Quintela         caps->state = s->capabilities[i];
5794d0c6b69SJuan Quintela         QAPI_LIST_APPEND(tail, caps);
5804d0c6b69SJuan Quintela     }
5814d0c6b69SJuan Quintela 
5824d0c6b69SJuan Quintela     return head;
5834d0c6b69SJuan Quintela }
58445c1de13SJuan Quintela 
58545c1de13SJuan Quintela void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
58645c1de13SJuan Quintela                                   Error **errp)
58745c1de13SJuan Quintela {
58845c1de13SJuan Quintela     MigrationState *s = migrate_get_current();
58945c1de13SJuan Quintela     MigrationCapabilityStatusList *cap;
59045c1de13SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
59145c1de13SJuan Quintela 
59245c1de13SJuan Quintela     if (migration_is_running(s->state)) {
59345c1de13SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
59445c1de13SJuan Quintela         return;
59545c1de13SJuan Quintela     }
59645c1de13SJuan Quintela 
59745c1de13SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
59845c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
59945c1de13SJuan Quintela         new_caps[cap->value->capability] = cap->value->state;
60045c1de13SJuan Quintela     }
60145c1de13SJuan Quintela 
60245c1de13SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
60345c1de13SJuan Quintela         return;
60445c1de13SJuan Quintela     }
60545c1de13SJuan Quintela 
60645c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
60745c1de13SJuan Quintela         s->capabilities[cap->value->capability] = cap->value->state;
60845c1de13SJuan Quintela     }
60945c1de13SJuan Quintela }
6101dfc4b9eSJuan Quintela 
6111dfc4b9eSJuan Quintela /* parameters */
6121dfc4b9eSJuan Quintela 
613b804b35bSJuan Quintela const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
614b804b35bSJuan Quintela {
615b804b35bSJuan Quintela     MigrationState *s = migrate_get_current();
616b804b35bSJuan Quintela 
617b804b35bSJuan Quintela     return s->parameters.block_bitmap_mapping;
618b804b35bSJuan Quintela }
619b804b35bSJuan Quintela 
6206f8be708SJuan Quintela bool migrate_block_incremental(void)
6216f8be708SJuan Quintela {
6228f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6236f8be708SJuan Quintela 
6246f8be708SJuan Quintela     return s->parameters.block_incremental;
6256f8be708SJuan Quintela }
6266f8be708SJuan Quintela 
627f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void)
628f94a858fSJuan Quintela {
6298f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
630f94a858fSJuan Quintela 
631f94a858fSJuan Quintela     return s->parameters.x_checkpoint_delay;
632f94a858fSJuan Quintela }
633f94a858fSJuan Quintela 
6341dfc4b9eSJuan Quintela int migrate_compress_level(void)
6351dfc4b9eSJuan Quintela {
6368f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6371dfc4b9eSJuan Quintela 
6381dfc4b9eSJuan Quintela     return s->parameters.compress_level;
6391dfc4b9eSJuan Quintela }
6401dfc4b9eSJuan Quintela 
6411dfc4b9eSJuan Quintela int migrate_compress_threads(void)
6421dfc4b9eSJuan Quintela {
6438f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6441dfc4b9eSJuan Quintela 
6451dfc4b9eSJuan Quintela     return s->parameters.compress_threads;
6461dfc4b9eSJuan Quintela }
6471dfc4b9eSJuan Quintela 
6481dfc4b9eSJuan Quintela int migrate_compress_wait_thread(void)
6491dfc4b9eSJuan Quintela {
6508f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6511dfc4b9eSJuan Quintela 
6521dfc4b9eSJuan Quintela     return s->parameters.compress_wait_thread;
6531dfc4b9eSJuan Quintela }
6541dfc4b9eSJuan Quintela 
6559605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void)
6569605c2acSJuan Quintela {
6578f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6589605c2acSJuan Quintela 
6599605c2acSJuan Quintela     return s->parameters.cpu_throttle_increment;
6609605c2acSJuan Quintela }
6619605c2acSJuan Quintela 
6622a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void)
6632a8ec380SJuan Quintela {
6648f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6652a8ec380SJuan Quintela 
6662a8ec380SJuan Quintela     return s->parameters.cpu_throttle_initial;
6672a8ec380SJuan Quintela }
6682a8ec380SJuan Quintela 
669873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void)
670873f674cSJuan Quintela {
6718f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
672873f674cSJuan Quintela 
673873f674cSJuan Quintela     return s->parameters.cpu_throttle_tailslow;
674873f674cSJuan Quintela }
675873f674cSJuan Quintela 
6761dfc4b9eSJuan Quintela int migrate_decompress_threads(void)
6771dfc4b9eSJuan Quintela {
6788f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6791dfc4b9eSJuan Quintela 
6801dfc4b9eSJuan Quintela     return s->parameters.decompress_threads;
6811dfc4b9eSJuan Quintela }
6821dfc4b9eSJuan Quintela 
683f5da8ba4SJuan Quintela uint64_t migrate_downtime_limit(void)
684f5da8ba4SJuan Quintela {
685f5da8ba4SJuan Quintela     MigrationState *s = migrate_get_current();
686f5da8ba4SJuan Quintela 
687f5da8ba4SJuan Quintela     return s->parameters.downtime_limit;
688f5da8ba4SJuan Quintela }
689f5da8ba4SJuan Quintela 
69024155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void)
69124155bd0SJuan Quintela {
6928f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
69324155bd0SJuan Quintela 
69424155bd0SJuan Quintela     return s->parameters.max_cpu_throttle;
69524155bd0SJuan Quintela }
69624155bd0SJuan Quintela 
6979c894df3SJuan Quintela uint64_t migrate_max_bandwidth(void)
6989c894df3SJuan Quintela {
6998f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7009c894df3SJuan Quintela 
7019c894df3SJuan Quintela     return s->parameters.max_bandwidth;
7029c894df3SJuan Quintela }
7039c894df3SJuan Quintela 
7041dfc4b9eSJuan Quintela int64_t migrate_max_postcopy_bandwidth(void)
7051dfc4b9eSJuan Quintela {
7068f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7071dfc4b9eSJuan Quintela 
7081dfc4b9eSJuan Quintela     return s->parameters.max_postcopy_bandwidth;
7091dfc4b9eSJuan Quintela }
7101dfc4b9eSJuan Quintela 
7111dfc4b9eSJuan Quintela int migrate_multifd_channels(void)
7121dfc4b9eSJuan Quintela {
7138f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7141dfc4b9eSJuan Quintela 
7151dfc4b9eSJuan Quintela     return s->parameters.multifd_channels;
7161dfc4b9eSJuan Quintela }
7171dfc4b9eSJuan Quintela 
7181dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void)
7191dfc4b9eSJuan Quintela {
7208f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7211dfc4b9eSJuan Quintela 
7221dfc4b9eSJuan Quintela     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
7231dfc4b9eSJuan Quintela     return s->parameters.multifd_compression;
7241dfc4b9eSJuan Quintela }
7251dfc4b9eSJuan Quintela 
7261dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void)
7271dfc4b9eSJuan Quintela {
7288f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7291dfc4b9eSJuan Quintela 
7301dfc4b9eSJuan Quintela     return s->parameters.multifd_zlib_level;
7311dfc4b9eSJuan Quintela }
7321dfc4b9eSJuan Quintela 
7331dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void)
7341dfc4b9eSJuan Quintela {
7358f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7361dfc4b9eSJuan Quintela 
7371dfc4b9eSJuan Quintela     return s->parameters.multifd_zstd_level;
7381dfc4b9eSJuan Quintela }
7391dfc4b9eSJuan Quintela 
7406499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void)
7416499efdbSJuan Quintela {
7428f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7436499efdbSJuan Quintela 
7446499efdbSJuan Quintela     return s->parameters.throttle_trigger_threshold;
7456499efdbSJuan Quintela }
7466499efdbSJuan Quintela 
7472eb0308bSJuan Quintela const char *migrate_tls_authz(void)
7482eb0308bSJuan Quintela {
7492eb0308bSJuan Quintela     MigrationState *s = migrate_get_current();
7502eb0308bSJuan Quintela 
7512eb0308bSJuan Quintela     return s->parameters.tls_authz;
7522eb0308bSJuan Quintela }
7532eb0308bSJuan Quintela 
754d5c3e195SJuan Quintela const char *migrate_tls_creds(void)
755d5c3e195SJuan Quintela {
756d5c3e195SJuan Quintela     MigrationState *s = migrate_get_current();
757d5c3e195SJuan Quintela 
758d5c3e195SJuan Quintela     return s->parameters.tls_creds;
759d5c3e195SJuan Quintela }
760d5c3e195SJuan Quintela 
7611f2f366cSJuan Quintela const char *migrate_tls_hostname(void)
7621f2f366cSJuan Quintela {
7631f2f366cSJuan Quintela     MigrationState *s = migrate_get_current();
7641f2f366cSJuan Quintela 
7651f2f366cSJuan Quintela     return s->parameters.tls_hostname;
7661f2f366cSJuan Quintela }
7671f2f366cSJuan Quintela 
7681dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void)
7691dfc4b9eSJuan Quintela {
7708f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7711dfc4b9eSJuan Quintela 
7721dfc4b9eSJuan Quintela     return s->parameters.xbzrle_cache_size;
7731dfc4b9eSJuan Quintela }
7742682c4eeSJuan Quintela 
77587c22901SJuan Quintela /* parameter setters */
77687c22901SJuan Quintela 
77787c22901SJuan Quintela void migrate_set_block_incremental(bool value)
77887c22901SJuan Quintela {
77987c22901SJuan Quintela     MigrationState *s = migrate_get_current();
78087c22901SJuan Quintela 
78187c22901SJuan Quintela     s->parameters.block_incremental = value;
78287c22901SJuan Quintela }
78387c22901SJuan Quintela 
7842682c4eeSJuan Quintela /* parameters helpers */
7852682c4eeSJuan Quintela 
786b1a87956SJuan Quintela void block_cleanup_parameters(void)
787b7b73122SJuan Quintela {
788b1a87956SJuan Quintela     MigrationState *s = migrate_get_current();
789b1a87956SJuan Quintela 
790b7b73122SJuan Quintela     if (s->must_remove_block_options) {
791b7b73122SJuan Quintela         /* setting to false can never fail */
792b7b73122SJuan Quintela         migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort);
793b7b73122SJuan Quintela         migrate_set_block_incremental(false);
794b7b73122SJuan Quintela         s->must_remove_block_options = false;
795b7b73122SJuan Quintela     }
796b7b73122SJuan Quintela }
797b7b73122SJuan Quintela 
7982682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void)
7992682c4eeSJuan Quintela {
8002682c4eeSJuan Quintela     static AnnounceParameters ap;
8012682c4eeSJuan Quintela 
8022682c4eeSJuan Quintela     MigrationState *s = migrate_get_current();
8032682c4eeSJuan Quintela 
8042682c4eeSJuan Quintela     ap.initial = s->parameters.announce_initial;
8052682c4eeSJuan Quintela     ap.max = s->parameters.announce_max;
8062682c4eeSJuan Quintela     ap.rounds = s->parameters.announce_rounds;
8072682c4eeSJuan Quintela     ap.step = s->parameters.announce_step;
8082682c4eeSJuan Quintela 
8092682c4eeSJuan Quintela     return &ap;
8102682c4eeSJuan Quintela }
8119c894df3SJuan Quintela 
8129c894df3SJuan Quintela MigrationParameters *qmp_query_migrate_parameters(Error **errp)
8139c894df3SJuan Quintela {
8149c894df3SJuan Quintela     MigrationParameters *params;
8159c894df3SJuan Quintela     MigrationState *s = migrate_get_current();
8169c894df3SJuan Quintela 
8179c894df3SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
8189c894df3SJuan Quintela     params = g_malloc0(sizeof(*params));
8199c894df3SJuan Quintela     params->has_compress_level = true;
8209c894df3SJuan Quintela     params->compress_level = s->parameters.compress_level;
8219c894df3SJuan Quintela     params->has_compress_threads = true;
8229c894df3SJuan Quintela     params->compress_threads = s->parameters.compress_threads;
8239c894df3SJuan Quintela     params->has_compress_wait_thread = true;
8249c894df3SJuan Quintela     params->compress_wait_thread = s->parameters.compress_wait_thread;
8259c894df3SJuan Quintela     params->has_decompress_threads = true;
8269c894df3SJuan Quintela     params->decompress_threads = s->parameters.decompress_threads;
8279c894df3SJuan Quintela     params->has_throttle_trigger_threshold = true;
8289c894df3SJuan Quintela     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
8299c894df3SJuan Quintela     params->has_cpu_throttle_initial = true;
8309c894df3SJuan Quintela     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
8319c894df3SJuan Quintela     params->has_cpu_throttle_increment = true;
8329c894df3SJuan Quintela     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
8339c894df3SJuan Quintela     params->has_cpu_throttle_tailslow = true;
8349c894df3SJuan Quintela     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
8359c894df3SJuan Quintela     params->tls_creds = g_strdup(s->parameters.tls_creds);
8369c894df3SJuan Quintela     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
8379c894df3SJuan Quintela     params->tls_authz = g_strdup(s->parameters.tls_authz ?
8389c894df3SJuan Quintela                                  s->parameters.tls_authz : "");
8399c894df3SJuan Quintela     params->has_max_bandwidth = true;
8409c894df3SJuan Quintela     params->max_bandwidth = s->parameters.max_bandwidth;
8419c894df3SJuan Quintela     params->has_downtime_limit = true;
8429c894df3SJuan Quintela     params->downtime_limit = s->parameters.downtime_limit;
8439c894df3SJuan Quintela     params->has_x_checkpoint_delay = true;
8449c894df3SJuan Quintela     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
8459c894df3SJuan Quintela     params->has_block_incremental = true;
8469c894df3SJuan Quintela     params->block_incremental = s->parameters.block_incremental;
8479c894df3SJuan Quintela     params->has_multifd_channels = true;
8489c894df3SJuan Quintela     params->multifd_channels = s->parameters.multifd_channels;
8499c894df3SJuan Quintela     params->has_multifd_compression = true;
8509c894df3SJuan Quintela     params->multifd_compression = s->parameters.multifd_compression;
8519c894df3SJuan Quintela     params->has_multifd_zlib_level = true;
8529c894df3SJuan Quintela     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
8539c894df3SJuan Quintela     params->has_multifd_zstd_level = true;
8549c894df3SJuan Quintela     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
8559c894df3SJuan Quintela     params->has_xbzrle_cache_size = true;
8569c894df3SJuan Quintela     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
8579c894df3SJuan Quintela     params->has_max_postcopy_bandwidth = true;
8589c894df3SJuan Quintela     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
8599c894df3SJuan Quintela     params->has_max_cpu_throttle = true;
8609c894df3SJuan Quintela     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
8619c894df3SJuan Quintela     params->has_announce_initial = true;
8629c894df3SJuan Quintela     params->announce_initial = s->parameters.announce_initial;
8639c894df3SJuan Quintela     params->has_announce_max = true;
8649c894df3SJuan Quintela     params->announce_max = s->parameters.announce_max;
8659c894df3SJuan Quintela     params->has_announce_rounds = true;
8669c894df3SJuan Quintela     params->announce_rounds = s->parameters.announce_rounds;
8679c894df3SJuan Quintela     params->has_announce_step = true;
8689c894df3SJuan Quintela     params->announce_step = s->parameters.announce_step;
8699c894df3SJuan Quintela 
8709c894df3SJuan Quintela     if (s->parameters.has_block_bitmap_mapping) {
8719c894df3SJuan Quintela         params->has_block_bitmap_mapping = true;
8729c894df3SJuan Quintela         params->block_bitmap_mapping =
8739c894df3SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
8749c894df3SJuan Quintela                        s->parameters.block_bitmap_mapping);
8759c894df3SJuan Quintela     }
8769c894df3SJuan Quintela 
8779c894df3SJuan Quintela     return params;
8789c894df3SJuan Quintela }
87909d6c965SJuan Quintela 
88061a174e2SJuan Quintela void migrate_params_init(MigrationParameters *params)
88161a174e2SJuan Quintela {
88261a174e2SJuan Quintela     params->tls_hostname = g_strdup("");
88361a174e2SJuan Quintela     params->tls_creds = g_strdup("");
88461a174e2SJuan Quintela 
88561a174e2SJuan Quintela     /* Set has_* up only for parameter checks */
88661a174e2SJuan Quintela     params->has_compress_level = true;
88761a174e2SJuan Quintela     params->has_compress_threads = true;
88861a174e2SJuan Quintela     params->has_compress_wait_thread = true;
88961a174e2SJuan Quintela     params->has_decompress_threads = true;
89061a174e2SJuan Quintela     params->has_throttle_trigger_threshold = true;
89161a174e2SJuan Quintela     params->has_cpu_throttle_initial = true;
89261a174e2SJuan Quintela     params->has_cpu_throttle_increment = true;
89361a174e2SJuan Quintela     params->has_cpu_throttle_tailslow = true;
89461a174e2SJuan Quintela     params->has_max_bandwidth = true;
89561a174e2SJuan Quintela     params->has_downtime_limit = true;
89661a174e2SJuan Quintela     params->has_x_checkpoint_delay = true;
89761a174e2SJuan Quintela     params->has_block_incremental = true;
89861a174e2SJuan Quintela     params->has_multifd_channels = true;
89961a174e2SJuan Quintela     params->has_multifd_compression = true;
90061a174e2SJuan Quintela     params->has_multifd_zlib_level = true;
90161a174e2SJuan Quintela     params->has_multifd_zstd_level = true;
90261a174e2SJuan Quintela     params->has_xbzrle_cache_size = true;
90361a174e2SJuan Quintela     params->has_max_postcopy_bandwidth = true;
90461a174e2SJuan Quintela     params->has_max_cpu_throttle = true;
90561a174e2SJuan Quintela     params->has_announce_initial = true;
90661a174e2SJuan Quintela     params->has_announce_max = true;
90761a174e2SJuan Quintela     params->has_announce_rounds = true;
90861a174e2SJuan Quintela     params->has_announce_step = true;
90961a174e2SJuan Quintela }
91061a174e2SJuan Quintela 
91109d6c965SJuan Quintela /*
91209d6c965SJuan Quintela  * Check whether the parameters are valid. Error will be put into errp
91309d6c965SJuan Quintela  * (if provided). Return true if valid, otherwise false.
91409d6c965SJuan Quintela  */
91509d6c965SJuan Quintela bool migrate_params_check(MigrationParameters *params, Error **errp)
91609d6c965SJuan Quintela {
91709d6c965SJuan Quintela     if (params->has_compress_level &&
91809d6c965SJuan Quintela         (params->compress_level > 9)) {
91909d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",
92009d6c965SJuan Quintela                    "a value between 0 and 9");
92109d6c965SJuan Quintela         return false;
92209d6c965SJuan Quintela     }
92309d6c965SJuan Quintela 
92409d6c965SJuan Quintela     if (params->has_compress_threads && (params->compress_threads < 1)) {
92509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
92609d6c965SJuan Quintela                    "compress_threads",
92709d6c965SJuan Quintela                    "a value between 1 and 255");
92809d6c965SJuan Quintela         return false;
92909d6c965SJuan Quintela     }
93009d6c965SJuan Quintela 
93109d6c965SJuan Quintela     if (params->has_decompress_threads && (params->decompress_threads < 1)) {
93209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
93309d6c965SJuan Quintela                    "decompress_threads",
93409d6c965SJuan Quintela                    "a value between 1 and 255");
93509d6c965SJuan Quintela         return false;
93609d6c965SJuan Quintela     }
93709d6c965SJuan Quintela 
93809d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold &&
93909d6c965SJuan Quintela         (params->throttle_trigger_threshold < 1 ||
94009d6c965SJuan Quintela          params->throttle_trigger_threshold > 100)) {
94109d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
94209d6c965SJuan Quintela                    "throttle_trigger_threshold",
94309d6c965SJuan Quintela                    "an integer in the range of 1 to 100");
94409d6c965SJuan Quintela         return false;
94509d6c965SJuan Quintela     }
94609d6c965SJuan Quintela 
94709d6c965SJuan Quintela     if (params->has_cpu_throttle_initial &&
94809d6c965SJuan Quintela         (params->cpu_throttle_initial < 1 ||
94909d6c965SJuan Quintela          params->cpu_throttle_initial > 99)) {
95009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
95109d6c965SJuan Quintela                    "cpu_throttle_initial",
95209d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
95309d6c965SJuan Quintela         return false;
95409d6c965SJuan Quintela     }
95509d6c965SJuan Quintela 
95609d6c965SJuan Quintela     if (params->has_cpu_throttle_increment &&
95709d6c965SJuan Quintela         (params->cpu_throttle_increment < 1 ||
95809d6c965SJuan Quintela          params->cpu_throttle_increment > 99)) {
95909d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
96009d6c965SJuan Quintela                    "cpu_throttle_increment",
96109d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
96209d6c965SJuan Quintela         return false;
96309d6c965SJuan Quintela     }
96409d6c965SJuan Quintela 
96509d6c965SJuan Quintela     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
96609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
96709d6c965SJuan Quintela                    "max_bandwidth",
96809d6c965SJuan Quintela                    "an integer in the range of 0 to "stringify(SIZE_MAX)
96909d6c965SJuan Quintela                    " bytes/second");
97009d6c965SJuan Quintela         return false;
97109d6c965SJuan Quintela     }
97209d6c965SJuan Quintela 
97309d6c965SJuan Quintela     if (params->has_downtime_limit &&
97409d6c965SJuan Quintela         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
97509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
97609d6c965SJuan Quintela                    "downtime_limit",
97709d6c965SJuan Quintela                    "an integer in the range of 0 to "
97809d6c965SJuan Quintela                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
97909d6c965SJuan Quintela         return false;
98009d6c965SJuan Quintela     }
98109d6c965SJuan Quintela 
98209d6c965SJuan Quintela     /* x_checkpoint_delay is now always positive */
98309d6c965SJuan Quintela 
98409d6c965SJuan Quintela     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
98509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
98609d6c965SJuan Quintela                    "multifd_channels",
98709d6c965SJuan Quintela                    "a value between 1 and 255");
98809d6c965SJuan Quintela         return false;
98909d6c965SJuan Quintela     }
99009d6c965SJuan Quintela 
99109d6c965SJuan Quintela     if (params->has_multifd_zlib_level &&
99209d6c965SJuan Quintela         (params->multifd_zlib_level > 9)) {
99309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
99409d6c965SJuan Quintela                    "a value between 0 and 9");
99509d6c965SJuan Quintela         return false;
99609d6c965SJuan Quintela     }
99709d6c965SJuan Quintela 
99809d6c965SJuan Quintela     if (params->has_multifd_zstd_level &&
99909d6c965SJuan Quintela         (params->multifd_zstd_level > 20)) {
100009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
100109d6c965SJuan Quintela                    "a value between 0 and 20");
100209d6c965SJuan Quintela         return false;
100309d6c965SJuan Quintela     }
100409d6c965SJuan Quintela 
100509d6c965SJuan Quintela     if (params->has_xbzrle_cache_size &&
100609d6c965SJuan Quintela         (params->xbzrle_cache_size < qemu_target_page_size() ||
100709d6c965SJuan Quintela          !is_power_of_2(params->xbzrle_cache_size))) {
100809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
100909d6c965SJuan Quintela                    "xbzrle_cache_size",
101009d6c965SJuan Quintela                    "a power of two no less than the target page size");
101109d6c965SJuan Quintela         return false;
101209d6c965SJuan Quintela     }
101309d6c965SJuan Quintela 
101409d6c965SJuan Quintela     if (params->has_max_cpu_throttle &&
101509d6c965SJuan Quintela         (params->max_cpu_throttle < params->cpu_throttle_initial ||
101609d6c965SJuan Quintela          params->max_cpu_throttle > 99)) {
101709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
101809d6c965SJuan Quintela                    "max_cpu_throttle",
101909d6c965SJuan Quintela                    "an integer in the range of cpu_throttle_initial to 99");
102009d6c965SJuan Quintela         return false;
102109d6c965SJuan Quintela     }
102209d6c965SJuan Quintela 
102309d6c965SJuan Quintela     if (params->has_announce_initial &&
102409d6c965SJuan Quintela         params->announce_initial > 100000) {
102509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
102609d6c965SJuan Quintela                    "announce_initial",
102709d6c965SJuan Quintela                    "a value between 0 and 100000");
102809d6c965SJuan Quintela         return false;
102909d6c965SJuan Quintela     }
103009d6c965SJuan Quintela     if (params->has_announce_max &&
103109d6c965SJuan Quintela         params->announce_max > 100000) {
103209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
103309d6c965SJuan Quintela                    "announce_max",
103409d6c965SJuan Quintela                    "a value between 0 and 100000");
103509d6c965SJuan Quintela        return false;
103609d6c965SJuan Quintela     }
103709d6c965SJuan Quintela     if (params->has_announce_rounds &&
103809d6c965SJuan Quintela         params->announce_rounds > 1000) {
103909d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
104009d6c965SJuan Quintela                    "announce_rounds",
104109d6c965SJuan Quintela                    "a value between 0 and 1000");
104209d6c965SJuan Quintela        return false;
104309d6c965SJuan Quintela     }
104409d6c965SJuan Quintela     if (params->has_announce_step &&
104509d6c965SJuan Quintela         (params->announce_step < 1 ||
104609d6c965SJuan Quintela         params->announce_step > 10000)) {
104709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
104809d6c965SJuan Quintela                    "announce_step",
104909d6c965SJuan Quintela                    "a value between 0 and 10000");
105009d6c965SJuan Quintela        return false;
105109d6c965SJuan Quintela     }
105209d6c965SJuan Quintela 
105309d6c965SJuan Quintela     if (params->has_block_bitmap_mapping &&
105409d6c965SJuan Quintela         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
105509d6c965SJuan Quintela         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
105609d6c965SJuan Quintela         return false;
105709d6c965SJuan Quintela     }
105809d6c965SJuan Quintela 
105909d6c965SJuan Quintela #ifdef CONFIG_LINUX
106009d6c965SJuan Quintela     if (migrate_zero_copy_send() &&
106109d6c965SJuan Quintela         ((params->has_multifd_compression && params->multifd_compression) ||
106209d6c965SJuan Quintela          (params->tls_creds && *params->tls_creds))) {
106309d6c965SJuan Quintela         error_setg(errp,
106409d6c965SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
106509d6c965SJuan Quintela         return false;
106609d6c965SJuan Quintela     }
106709d6c965SJuan Quintela #endif
106809d6c965SJuan Quintela 
106909d6c965SJuan Quintela     return true;
107009d6c965SJuan Quintela }
107109d6c965SJuan Quintela 
107209d6c965SJuan Quintela static void migrate_params_test_apply(MigrateSetParameters *params,
107309d6c965SJuan Quintela                                       MigrationParameters *dest)
107409d6c965SJuan Quintela {
107509d6c965SJuan Quintela     *dest = migrate_get_current()->parameters;
107609d6c965SJuan Quintela 
107709d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
107809d6c965SJuan Quintela 
107909d6c965SJuan Quintela     if (params->has_compress_level) {
108009d6c965SJuan Quintela         dest->compress_level = params->compress_level;
108109d6c965SJuan Quintela     }
108209d6c965SJuan Quintela 
108309d6c965SJuan Quintela     if (params->has_compress_threads) {
108409d6c965SJuan Quintela         dest->compress_threads = params->compress_threads;
108509d6c965SJuan Quintela     }
108609d6c965SJuan Quintela 
108709d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
108809d6c965SJuan Quintela         dest->compress_wait_thread = params->compress_wait_thread;
108909d6c965SJuan Quintela     }
109009d6c965SJuan Quintela 
109109d6c965SJuan Quintela     if (params->has_decompress_threads) {
109209d6c965SJuan Quintela         dest->decompress_threads = params->decompress_threads;
109309d6c965SJuan Quintela     }
109409d6c965SJuan Quintela 
109509d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
109609d6c965SJuan Quintela         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
109709d6c965SJuan Quintela     }
109809d6c965SJuan Quintela 
109909d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
110009d6c965SJuan Quintela         dest->cpu_throttle_initial = params->cpu_throttle_initial;
110109d6c965SJuan Quintela     }
110209d6c965SJuan Quintela 
110309d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
110409d6c965SJuan Quintela         dest->cpu_throttle_increment = params->cpu_throttle_increment;
110509d6c965SJuan Quintela     }
110609d6c965SJuan Quintela 
110709d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
110809d6c965SJuan Quintela         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
110909d6c965SJuan Quintela     }
111009d6c965SJuan Quintela 
111109d6c965SJuan Quintela     if (params->tls_creds) {
111209d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
111309d6c965SJuan Quintela         dest->tls_creds = params->tls_creds->u.s;
111409d6c965SJuan Quintela     }
111509d6c965SJuan Quintela 
111609d6c965SJuan Quintela     if (params->tls_hostname) {
111709d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
111809d6c965SJuan Quintela         dest->tls_hostname = params->tls_hostname->u.s;
111909d6c965SJuan Quintela     }
112009d6c965SJuan Quintela 
112109d6c965SJuan Quintela     if (params->has_max_bandwidth) {
112209d6c965SJuan Quintela         dest->max_bandwidth = params->max_bandwidth;
112309d6c965SJuan Quintela     }
112409d6c965SJuan Quintela 
112509d6c965SJuan Quintela     if (params->has_downtime_limit) {
112609d6c965SJuan Quintela         dest->downtime_limit = params->downtime_limit;
112709d6c965SJuan Quintela     }
112809d6c965SJuan Quintela 
112909d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
113009d6c965SJuan Quintela         dest->x_checkpoint_delay = params->x_checkpoint_delay;
113109d6c965SJuan Quintela     }
113209d6c965SJuan Quintela 
113309d6c965SJuan Quintela     if (params->has_block_incremental) {
113409d6c965SJuan Quintela         dest->block_incremental = params->block_incremental;
113509d6c965SJuan Quintela     }
113609d6c965SJuan Quintela     if (params->has_multifd_channels) {
113709d6c965SJuan Quintela         dest->multifd_channels = params->multifd_channels;
113809d6c965SJuan Quintela     }
113909d6c965SJuan Quintela     if (params->has_multifd_compression) {
114009d6c965SJuan Quintela         dest->multifd_compression = params->multifd_compression;
114109d6c965SJuan Quintela     }
114209d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
114309d6c965SJuan Quintela         dest->xbzrle_cache_size = params->xbzrle_cache_size;
114409d6c965SJuan Quintela     }
114509d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
114609d6c965SJuan Quintela         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
114709d6c965SJuan Quintela     }
114809d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
114909d6c965SJuan Quintela         dest->max_cpu_throttle = params->max_cpu_throttle;
115009d6c965SJuan Quintela     }
115109d6c965SJuan Quintela     if (params->has_announce_initial) {
115209d6c965SJuan Quintela         dest->announce_initial = params->announce_initial;
115309d6c965SJuan Quintela     }
115409d6c965SJuan Quintela     if (params->has_announce_max) {
115509d6c965SJuan Quintela         dest->announce_max = params->announce_max;
115609d6c965SJuan Quintela     }
115709d6c965SJuan Quintela     if (params->has_announce_rounds) {
115809d6c965SJuan Quintela         dest->announce_rounds = params->announce_rounds;
115909d6c965SJuan Quintela     }
116009d6c965SJuan Quintela     if (params->has_announce_step) {
116109d6c965SJuan Quintela         dest->announce_step = params->announce_step;
116209d6c965SJuan Quintela     }
116309d6c965SJuan Quintela 
116409d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
116509d6c965SJuan Quintela         dest->has_block_bitmap_mapping = true;
116609d6c965SJuan Quintela         dest->block_bitmap_mapping = params->block_bitmap_mapping;
116709d6c965SJuan Quintela     }
116809d6c965SJuan Quintela }
116909d6c965SJuan Quintela 
117009d6c965SJuan Quintela static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
117109d6c965SJuan Quintela {
117209d6c965SJuan Quintela     MigrationState *s = migrate_get_current();
117309d6c965SJuan Quintela 
117409d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
117509d6c965SJuan Quintela 
117609d6c965SJuan Quintela     if (params->has_compress_level) {
117709d6c965SJuan Quintela         s->parameters.compress_level = params->compress_level;
117809d6c965SJuan Quintela     }
117909d6c965SJuan Quintela 
118009d6c965SJuan Quintela     if (params->has_compress_threads) {
118109d6c965SJuan Quintela         s->parameters.compress_threads = params->compress_threads;
118209d6c965SJuan Quintela     }
118309d6c965SJuan Quintela 
118409d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
118509d6c965SJuan Quintela         s->parameters.compress_wait_thread = params->compress_wait_thread;
118609d6c965SJuan Quintela     }
118709d6c965SJuan Quintela 
118809d6c965SJuan Quintela     if (params->has_decompress_threads) {
118909d6c965SJuan Quintela         s->parameters.decompress_threads = params->decompress_threads;
119009d6c965SJuan Quintela     }
119109d6c965SJuan Quintela 
119209d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
119309d6c965SJuan Quintela         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
119409d6c965SJuan Quintela     }
119509d6c965SJuan Quintela 
119609d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
119709d6c965SJuan Quintela         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
119809d6c965SJuan Quintela     }
119909d6c965SJuan Quintela 
120009d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
120109d6c965SJuan Quintela         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
120209d6c965SJuan Quintela     }
120309d6c965SJuan Quintela 
120409d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
120509d6c965SJuan Quintela         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
120609d6c965SJuan Quintela     }
120709d6c965SJuan Quintela 
120809d6c965SJuan Quintela     if (params->tls_creds) {
120909d6c965SJuan Quintela         g_free(s->parameters.tls_creds);
121009d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
121109d6c965SJuan Quintela         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
121209d6c965SJuan Quintela     }
121309d6c965SJuan Quintela 
121409d6c965SJuan Quintela     if (params->tls_hostname) {
121509d6c965SJuan Quintela         g_free(s->parameters.tls_hostname);
121609d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
121709d6c965SJuan Quintela         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
121809d6c965SJuan Quintela     }
121909d6c965SJuan Quintela 
122009d6c965SJuan Quintela     if (params->tls_authz) {
122109d6c965SJuan Quintela         g_free(s->parameters.tls_authz);
122209d6c965SJuan Quintela         assert(params->tls_authz->type == QTYPE_QSTRING);
122309d6c965SJuan Quintela         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
122409d6c965SJuan Quintela     }
122509d6c965SJuan Quintela 
122609d6c965SJuan Quintela     if (params->has_max_bandwidth) {
122709d6c965SJuan Quintela         s->parameters.max_bandwidth = params->max_bandwidth;
122809d6c965SJuan Quintela         if (s->to_dst_file && !migration_in_postcopy()) {
122909d6c965SJuan Quintela             qemu_file_set_rate_limit(s->to_dst_file,
123009d6c965SJuan Quintela                                 s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
123109d6c965SJuan Quintela         }
123209d6c965SJuan Quintela     }
123309d6c965SJuan Quintela 
123409d6c965SJuan Quintela     if (params->has_downtime_limit) {
123509d6c965SJuan Quintela         s->parameters.downtime_limit = params->downtime_limit;
123609d6c965SJuan Quintela     }
123709d6c965SJuan Quintela 
123809d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
123909d6c965SJuan Quintela         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
124009d6c965SJuan Quintela         if (migration_in_colo_state()) {
124109d6c965SJuan Quintela             colo_checkpoint_notify(s);
124209d6c965SJuan Quintela         }
124309d6c965SJuan Quintela     }
124409d6c965SJuan Quintela 
124509d6c965SJuan Quintela     if (params->has_block_incremental) {
124609d6c965SJuan Quintela         s->parameters.block_incremental = params->block_incremental;
124709d6c965SJuan Quintela     }
124809d6c965SJuan Quintela     if (params->has_multifd_channels) {
124909d6c965SJuan Quintela         s->parameters.multifd_channels = params->multifd_channels;
125009d6c965SJuan Quintela     }
125109d6c965SJuan Quintela     if (params->has_multifd_compression) {
125209d6c965SJuan Quintela         s->parameters.multifd_compression = params->multifd_compression;
125309d6c965SJuan Quintela     }
125409d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
125509d6c965SJuan Quintela         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
125609d6c965SJuan Quintela         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
125709d6c965SJuan Quintela     }
125809d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
125909d6c965SJuan Quintela         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
126009d6c965SJuan Quintela         if (s->to_dst_file && migration_in_postcopy()) {
126109d6c965SJuan Quintela             qemu_file_set_rate_limit(s->to_dst_file,
126209d6c965SJuan Quintela                     s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO);
126309d6c965SJuan Quintela         }
126409d6c965SJuan Quintela     }
126509d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
126609d6c965SJuan Quintela         s->parameters.max_cpu_throttle = params->max_cpu_throttle;
126709d6c965SJuan Quintela     }
126809d6c965SJuan Quintela     if (params->has_announce_initial) {
126909d6c965SJuan Quintela         s->parameters.announce_initial = params->announce_initial;
127009d6c965SJuan Quintela     }
127109d6c965SJuan Quintela     if (params->has_announce_max) {
127209d6c965SJuan Quintela         s->parameters.announce_max = params->announce_max;
127309d6c965SJuan Quintela     }
127409d6c965SJuan Quintela     if (params->has_announce_rounds) {
127509d6c965SJuan Quintela         s->parameters.announce_rounds = params->announce_rounds;
127609d6c965SJuan Quintela     }
127709d6c965SJuan Quintela     if (params->has_announce_step) {
127809d6c965SJuan Quintela         s->parameters.announce_step = params->announce_step;
127909d6c965SJuan Quintela     }
128009d6c965SJuan Quintela 
128109d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
128209d6c965SJuan Quintela         qapi_free_BitmapMigrationNodeAliasList(
128309d6c965SJuan Quintela             s->parameters.block_bitmap_mapping);
128409d6c965SJuan Quintela 
128509d6c965SJuan Quintela         s->parameters.has_block_bitmap_mapping = true;
128609d6c965SJuan Quintela         s->parameters.block_bitmap_mapping =
128709d6c965SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
128809d6c965SJuan Quintela                        params->block_bitmap_mapping);
128909d6c965SJuan Quintela     }
129009d6c965SJuan Quintela }
129109d6c965SJuan Quintela 
129209d6c965SJuan Quintela void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
129309d6c965SJuan Quintela {
129409d6c965SJuan Quintela     MigrationParameters tmp;
129509d6c965SJuan Quintela 
129609d6c965SJuan Quintela     /* TODO Rewrite "" to null instead */
129709d6c965SJuan Quintela     if (params->tls_creds
129809d6c965SJuan Quintela         && params->tls_creds->type == QTYPE_QNULL) {
129909d6c965SJuan Quintela         qobject_unref(params->tls_creds->u.n);
130009d6c965SJuan Quintela         params->tls_creds->type = QTYPE_QSTRING;
130109d6c965SJuan Quintela         params->tls_creds->u.s = strdup("");
130209d6c965SJuan Quintela     }
130309d6c965SJuan Quintela     /* TODO Rewrite "" to null instead */
130409d6c965SJuan Quintela     if (params->tls_hostname
130509d6c965SJuan Quintela         && params->tls_hostname->type == QTYPE_QNULL) {
130609d6c965SJuan Quintela         qobject_unref(params->tls_hostname->u.n);
130709d6c965SJuan Quintela         params->tls_hostname->type = QTYPE_QSTRING;
130809d6c965SJuan Quintela         params->tls_hostname->u.s = strdup("");
130909d6c965SJuan Quintela     }
131009d6c965SJuan Quintela 
131109d6c965SJuan Quintela     migrate_params_test_apply(params, &tmp);
131209d6c965SJuan Quintela 
131309d6c965SJuan Quintela     if (!migrate_params_check(&tmp, errp)) {
131409d6c965SJuan Quintela         /* Invalid parameter */
131509d6c965SJuan Quintela         return;
131609d6c965SJuan Quintela     }
131709d6c965SJuan Quintela 
131809d6c965SJuan Quintela     migrate_params_apply(params, errp);
131909d6c965SJuan Quintela }
1320