xref: /openbmc/qemu/migration/options.c (revision 5fdbb1dfccfd59661c95cae760b8e276c5b8e65c)
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"
1566db46caSJuan Quintela #include "qemu/error-report.h"
1609d6c965SJuan Quintela #include "exec/target_page.h"
179c894df3SJuan Quintela #include "qapi/clone-visitor.h"
1877608706SJuan Quintela #include "qapi/error.h"
194d0c6b69SJuan Quintela #include "qapi/qapi-commands-migration.h"
209c894df3SJuan Quintela #include "qapi/qapi-visit-migration.h"
21f80196b7SJuan Quintela #include "qapi/qmp/qerror.h"
2209d6c965SJuan Quintela #include "qapi/qmp/qnull.h"
2377608706SJuan Quintela #include "sysemu/runstate.h"
2409d6c965SJuan Quintela #include "migration/colo.h"
252682c4eeSJuan Quintela #include "migration/misc.h"
261f0776f1SJuan Quintela #include "migration.h"
27e1fde0e0SJuan Quintela #include "migration-stats.h"
2809d6c965SJuan Quintela #include "qemu-file.h"
2977608706SJuan Quintela #include "ram.h"
301f0776f1SJuan Quintela #include "options.h"
31dc623955SHyman Huang(黄勇) #include "sysemu/kvm.h"
321f0776f1SJuan Quintela 
3309d6c965SJuan Quintela /* Maximum migrate downtime set to 2000 seconds */
3409d6c965SJuan Quintela #define MAX_MIGRATE_DOWNTIME_SECONDS 2000
3509d6c965SJuan Quintela #define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000)
3609d6c965SJuan Quintela 
37f9436522SJuan Quintela #define MAX_THROTTLE  (128 << 20)      /* Migration transfer speed throttling */
38f9436522SJuan Quintela 
39f9436522SJuan Quintela /* Time in milliseconds we are allowed to stop the source,
40f9436522SJuan Quintela  * for sending the last part */
41f9436522SJuan Quintela #define DEFAULT_MIGRATE_SET_DOWNTIME 300
42f9436522SJuan Quintela 
43f9436522SJuan Quintela /* Default compression thread count */
44f9436522SJuan Quintela #define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
45f9436522SJuan Quintela /* Default decompression thread count, usually decompression is at
46f9436522SJuan Quintela  * least 4 times as fast as compression.*/
47f9436522SJuan Quintela #define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2
48f9436522SJuan Quintela /*0: means nocompress, 1: best speed, ... 9: best compress ratio */
49f9436522SJuan Quintela #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1
50f9436522SJuan Quintela /* Define default autoconverge cpu throttle migration parameters */
51f9436522SJuan Quintela #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50
52f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
53f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
54f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99
55f9436522SJuan Quintela 
56f9436522SJuan Quintela /* Migration XBZRLE default cache size */
57f9436522SJuan Quintela #define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024)
58f9436522SJuan Quintela 
59f9436522SJuan Quintela /* The delay time (in ms) between two COLO checkpoints */
60f9436522SJuan Quintela #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100)
61f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
62f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE
63f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 9: best compress ratio */
64f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1
65f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 20: best compress ratio */
66f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1
67f9436522SJuan Quintela 
68f9436522SJuan Quintela /* Background transfer rate for postcopy, 0 means unlimited, note
69f9436522SJuan Quintela  * that page requests can still exceed this limit.
70f9436522SJuan Quintela  */
71f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0
72f9436522SJuan Quintela 
73f9436522SJuan Quintela /*
74f9436522SJuan Quintela  * Parameters for self_announce_delay giving a stream of RARP/ARP
75f9436522SJuan Quintela  * packets after migration.
76f9436522SJuan Quintela  */
77f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_INITIAL  50
78f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_MAX     550
79f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS    5
80f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_STEP    100
81f9436522SJuan Quintela 
82f9436522SJuan Quintela #define DEFINE_PROP_MIG_CAP(name, x)             \
83f9436522SJuan Quintela     DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false)
84f9436522SJuan Quintela 
854d807857SHyman Huang(黄勇) #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD     1000    /* milliseconds */
8609f9ec99SHyman Huang(黄勇) #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT            1       /* MB/s */
874d807857SHyman Huang(黄勇) 
88f9436522SJuan Quintela Property migration_properties[] = {
89f9436522SJuan Quintela     DEFINE_PROP_BOOL("store-global-state", MigrationState,
90f9436522SJuan Quintela                      store_global_state, true),
91f9436522SJuan Quintela     DEFINE_PROP_BOOL("send-configuration", MigrationState,
92f9436522SJuan Quintela                      send_configuration, true),
93f9436522SJuan Quintela     DEFINE_PROP_BOOL("send-section-footer", MigrationState,
94f9436522SJuan Quintela                      send_section_footer, true),
95f9436522SJuan Quintela     DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
96f9436522SJuan Quintela                       decompress_error_check, true),
9777c259a4SJuan Quintela     DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
98294e5a40SJuan Quintela                       multifd_flush_after_each_section, false),
99f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
100f9436522SJuan Quintela                       clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
101f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
102f9436522SJuan Quintela                      preempt_pre_7_2, false),
103f9436522SJuan Quintela 
104f9436522SJuan Quintela     /* Migration parameters */
105f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-compress-level", MigrationState,
106f9436522SJuan Quintela                       parameters.compress_level,
107f9436522SJuan Quintela                       DEFAULT_MIGRATE_COMPRESS_LEVEL),
108f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-compress-threads", MigrationState,
109f9436522SJuan Quintela                       parameters.compress_threads,
110f9436522SJuan Quintela                       DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT),
111f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState,
112f9436522SJuan Quintela                       parameters.compress_wait_thread, true),
113f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-decompress-threads", MigrationState,
114f9436522SJuan Quintela                       parameters.decompress_threads,
115f9436522SJuan Quintela                       DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT),
116f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState,
117f9436522SJuan Quintela                       parameters.throttle_trigger_threshold,
118f9436522SJuan Quintela                       DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
119f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState,
120f9436522SJuan Quintela                       parameters.cpu_throttle_initial,
121f9436522SJuan Quintela                       DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL),
122f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState,
123f9436522SJuan Quintela                       parameters.cpu_throttle_increment,
124f9436522SJuan Quintela                       DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
125f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState,
126f9436522SJuan Quintela                       parameters.cpu_throttle_tailslow, false),
127f9436522SJuan Quintela     DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState,
128f9436522SJuan Quintela                       parameters.max_bandwidth, MAX_THROTTLE),
1298b239597SPeter Xu     DEFINE_PROP_SIZE("avail-switchover-bandwidth", MigrationState,
1308b239597SPeter Xu                       parameters.avail_switchover_bandwidth, 0),
131f9436522SJuan Quintela     DEFINE_PROP_UINT64("x-downtime-limit", MigrationState,
132f9436522SJuan Quintela                       parameters.downtime_limit,
133f9436522SJuan Quintela                       DEFAULT_MIGRATE_SET_DOWNTIME),
134f9436522SJuan Quintela     DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
135f9436522SJuan Quintela                       parameters.x_checkpoint_delay,
136f9436522SJuan Quintela                       DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
137f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-channels", MigrationState,
138f9436522SJuan Quintela                       parameters.multifd_channels,
139f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_CHANNELS),
140f9436522SJuan Quintela     DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState,
141f9436522SJuan Quintela                       parameters.multifd_compression,
142f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_COMPRESSION),
143f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState,
144f9436522SJuan Quintela                       parameters.multifd_zlib_level,
145f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL),
146f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState,
147f9436522SJuan Quintela                       parameters.multifd_zstd_level,
148f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL),
149f9436522SJuan Quintela     DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
150f9436522SJuan Quintela                       parameters.xbzrle_cache_size,
151f9436522SJuan Quintela                       DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
152f9436522SJuan Quintela     DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState,
153f9436522SJuan Quintela                       parameters.max_postcopy_bandwidth,
154f9436522SJuan Quintela                       DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH),
155f9436522SJuan Quintela     DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState,
156f9436522SJuan Quintela                       parameters.max_cpu_throttle,
157f9436522SJuan Quintela                       DEFAULT_MIGRATE_MAX_CPU_THROTTLE),
158f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-initial", MigrationState,
159f9436522SJuan Quintela                       parameters.announce_initial,
160f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_INITIAL),
161f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-max", MigrationState,
162f9436522SJuan Quintela                       parameters.announce_max,
163f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_MAX),
164f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-rounds", MigrationState,
165f9436522SJuan Quintela                       parameters.announce_rounds,
166f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_ROUNDS),
167f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-step", MigrationState,
168f9436522SJuan Quintela                       parameters.announce_step,
169f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_STEP),
170f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds),
171f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname),
172f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz),
1734d807857SHyman Huang(黄勇)     DEFINE_PROP_UINT64("x-vcpu-dirty-limit-period", MigrationState,
1744d807857SHyman Huang(黄勇)                        parameters.x_vcpu_dirty_limit_period,
1754d807857SHyman Huang(黄勇)                        DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD),
17609f9ec99SHyman Huang(黄勇)     DEFINE_PROP_UINT64("vcpu-dirty-limit", MigrationState,
17709f9ec99SHyman Huang(黄勇)                        parameters.vcpu_dirty_limit,
17809f9ec99SHyman Huang(黄勇)                        DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT),
179eea1e5c9SSteve Sistare     DEFINE_PROP_MIG_MODE("mode", MigrationState,
180eea1e5c9SSteve Sistare                       parameters.mode,
181eea1e5c9SSteve Sistare                       MIG_MODE_NORMAL),
182*5fdbb1dfSHao Xiang     DEFINE_PROP_ZERO_PAGE_DETECTION("zero-page-detection", MigrationState,
183*5fdbb1dfSHao Xiang                        parameters.zero_page_detection,
184*5fdbb1dfSHao Xiang                        ZERO_PAGE_DETECTION_LEGACY),
185f9436522SJuan Quintela 
186f9436522SJuan Quintela     /* Migration capabilities */
187f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
188f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL),
189f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE),
190f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS),
191f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS),
192f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS),
193f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM),
194f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-postcopy-preempt",
195f9436522SJuan Quintela                         MIGRATION_CAPABILITY_POSTCOPY_PREEMPT),
196f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO),
197f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
198f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
199f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH),
200f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
201f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-background-snapshot",
202f9436522SJuan Quintela             MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
203f9436522SJuan Quintela #ifdef CONFIG_LINUX
204f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-zero-copy-send",
205f9436522SJuan Quintela             MIGRATION_CAPABILITY_ZERO_COPY_SEND),
206f9436522SJuan Quintela #endif
2076574232fSAvihai Horon     DEFINE_PROP_MIG_CAP("x-switchover-ack",
2086574232fSAvihai Horon                         MIGRATION_CAPABILITY_SWITCHOVER_ACK),
209dc623955SHyman Huang(黄勇)     DEFINE_PROP_MIG_CAP("x-dirty-limit", MIGRATION_CAPABILITY_DIRTY_LIMIT),
2104ed49febSFabiano Rosas     DEFINE_PROP_MIG_CAP("mapped-ram", MIGRATION_CAPABILITY_MAPPED_RAM),
211f9436522SJuan Quintela     DEFINE_PROP_END_OF_LIST(),
212f9436522SJuan Quintela };
213f9436522SJuan Quintela 
2141f0776f1SJuan Quintela bool migrate_auto_converge(void)
2151f0776f1SJuan Quintela {
2168f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2171f0776f1SJuan Quintela 
2181f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
2191f0776f1SJuan Quintela }
2201f0776f1SJuan Quintela 
2211f0776f1SJuan Quintela bool migrate_background_snapshot(void)
2221f0776f1SJuan Quintela {
2238f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2241f0776f1SJuan Quintela 
2251f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
2261f0776f1SJuan Quintela }
2271f0776f1SJuan Quintela 
2289d4b1e5fSJuan Quintela bool migrate_block(void)
2299d4b1e5fSJuan Quintela {
2308f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2319d4b1e5fSJuan Quintela 
2329d4b1e5fSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BLOCK];
2339d4b1e5fSJuan Quintela }
2349d4b1e5fSJuan Quintela 
2355e804644SJuan Quintela bool migrate_colo(void)
2365e804644SJuan Quintela {
2375e804644SJuan Quintela     MigrationState *s = migrate_get_current();
2388f9c5327SJuan Quintela 
2395e804644SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
2405e804644SJuan Quintela }
2415e804644SJuan Quintela 
242a7a94d14SJuan Quintela bool migrate_compress(void)
243a7a94d14SJuan Quintela {
2448f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
245a7a94d14SJuan Quintela 
246a7a94d14SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
247a7a94d14SJuan Quintela }
248a7a94d14SJuan Quintela 
2491f0776f1SJuan Quintela bool migrate_dirty_bitmaps(void)
2501f0776f1SJuan Quintela {
2518f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2521f0776f1SJuan Quintela 
2531f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
2541f0776f1SJuan Quintela }
2551f0776f1SJuan Quintela 
256dc623955SHyman Huang(黄勇) bool migrate_dirty_limit(void)
257dc623955SHyman Huang(黄勇) {
258dc623955SHyman Huang(黄勇)     MigrationState *s = migrate_get_current();
259dc623955SHyman Huang(黄勇) 
260dc623955SHyman Huang(黄勇)     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_LIMIT];
261dc623955SHyman Huang(黄勇) }
262dc623955SHyman Huang(黄勇) 
263b890902cSJuan Quintela bool migrate_events(void)
264b890902cSJuan Quintela {
2658f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
266b890902cSJuan Quintela 
267b890902cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
268b890902cSJuan Quintela }
269b890902cSJuan Quintela 
2704ed49febSFabiano Rosas bool migrate_mapped_ram(void)
2714ed49febSFabiano Rosas {
2724ed49febSFabiano Rosas     MigrationState *s = migrate_get_current();
2734ed49febSFabiano Rosas 
2744ed49febSFabiano Rosas     return s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM];
2754ed49febSFabiano Rosas }
2764ed49febSFabiano Rosas 
2771f0776f1SJuan Quintela bool migrate_ignore_shared(void)
2781f0776f1SJuan Quintela {
2798f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2801f0776f1SJuan Quintela 
2811f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
2821f0776f1SJuan Quintela }
2831f0776f1SJuan Quintela 
2841f0776f1SJuan Quintela bool migrate_late_block_activate(void)
2851f0776f1SJuan Quintela {
2868f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2871f0776f1SJuan Quintela 
2881f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
2891f0776f1SJuan Quintela }
2901f0776f1SJuan Quintela 
29151b07548SJuan Quintela bool migrate_multifd(void)
29251b07548SJuan Quintela {
2938f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
29451b07548SJuan Quintela 
29551b07548SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
29651b07548SJuan Quintela }
29751b07548SJuan Quintela 
2981f0776f1SJuan Quintela bool migrate_pause_before_switchover(void)
2991f0776f1SJuan Quintela {
3008f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3011f0776f1SJuan Quintela 
3021f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
3031f0776f1SJuan Quintela }
3041f0776f1SJuan Quintela 
3051f0776f1SJuan Quintela bool migrate_postcopy_blocktime(void)
3061f0776f1SJuan Quintela {
3078f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3081f0776f1SJuan Quintela 
3091f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
3101f0776f1SJuan Quintela }
3111f0776f1SJuan Quintela 
3121f0776f1SJuan Quintela bool migrate_postcopy_preempt(void)
3131f0776f1SJuan Quintela {
3148f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3151f0776f1SJuan Quintela 
3161f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
3171f0776f1SJuan Quintela }
3181f0776f1SJuan Quintela 
3191f0776f1SJuan Quintela bool migrate_postcopy_ram(void)
3201f0776f1SJuan Quintela {
3218f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3221f0776f1SJuan Quintela 
3231f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
3241f0776f1SJuan Quintela }
3251f0776f1SJuan Quintela 
32617cba690SJuan Quintela bool migrate_rdma_pin_all(void)
32717cba690SJuan Quintela {
32817cba690SJuan Quintela     MigrationState *s = migrate_get_current();
32917cba690SJuan Quintela 
33017cba690SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
33117cba690SJuan Quintela }
33217cba690SJuan Quintela 
3331f0776f1SJuan Quintela bool migrate_release_ram(void)
3341f0776f1SJuan Quintela {
3358f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3361f0776f1SJuan Quintela 
3371f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
3381f0776f1SJuan Quintela }
3391f0776f1SJuan Quintela 
34038ad1110SJuan Quintela bool migrate_return_path(void)
34138ad1110SJuan Quintela {
3428f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
34338ad1110SJuan Quintela 
34438ad1110SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
34538ad1110SJuan Quintela }
34638ad1110SJuan Quintela 
3476574232fSAvihai Horon bool migrate_switchover_ack(void)
3486574232fSAvihai Horon {
3496574232fSAvihai Horon     MigrationState *s = migrate_get_current();
3506574232fSAvihai Horon 
3516574232fSAvihai Horon     return s->capabilities[MIGRATION_CAPABILITY_SWITCHOVER_ACK];
3526574232fSAvihai Horon }
3536574232fSAvihai Horon 
3541f0776f1SJuan Quintela bool migrate_validate_uuid(void)
3551f0776f1SJuan Quintela {
3568f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3571f0776f1SJuan Quintela 
3581f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
3591f0776f1SJuan Quintela }
3601f0776f1SJuan Quintela 
36187dca0c9SJuan Quintela bool migrate_xbzrle(void)
36287dca0c9SJuan Quintela {
3638f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
36487dca0c9SJuan Quintela 
36587dca0c9SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
36687dca0c9SJuan Quintela }
36787dca0c9SJuan Quintela 
3681f0776f1SJuan Quintela bool migrate_zero_blocks(void)
3691f0776f1SJuan Quintela {
3708f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3711f0776f1SJuan Quintela 
3721f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
3731f0776f1SJuan Quintela }
374b4bc342cSJuan Quintela 
375b4bc342cSJuan Quintela bool migrate_zero_copy_send(void)
376b4bc342cSJuan Quintela {
3778f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
378b4bc342cSJuan Quintela 
379b4bc342cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
380b4bc342cSJuan Quintela }
381f774fde5SJuan Quintela 
382f774fde5SJuan Quintela /* pseudo capabilities */
383f774fde5SJuan Quintela 
38477c259a4SJuan Quintela bool migrate_multifd_flush_after_each_section(void)
38577c259a4SJuan Quintela {
38677c259a4SJuan Quintela     MigrationState *s = migrate_get_current();
38777c259a4SJuan Quintela 
388294e5a40SJuan Quintela     return s->multifd_flush_after_each_section;
38977c259a4SJuan Quintela }
39077c259a4SJuan Quintela 
391f774fde5SJuan Quintela bool migrate_postcopy(void)
392f774fde5SJuan Quintela {
393f774fde5SJuan Quintela     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
394f774fde5SJuan Quintela }
395f774fde5SJuan Quintela 
39627fd25b0SJuan Quintela bool migrate_rdma(void)
39727fd25b0SJuan Quintela {
39827fd25b0SJuan Quintela     MigrationState *s = migrate_get_current();
39927fd25b0SJuan Quintela 
40027fd25b0SJuan Quintela     return s->rdma_migration;
40127fd25b0SJuan Quintela }
40227fd25b0SJuan Quintela 
40310d4703bSJuan Quintela bool migrate_tls(void)
40410d4703bSJuan Quintela {
4058f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
40610d4703bSJuan Quintela 
40710d4703bSJuan Quintela     return s->parameters.tls_creds && *s->parameters.tls_creds;
40810d4703bSJuan Quintela }
40910d4703bSJuan Quintela 
41077608706SJuan Quintela typedef enum WriteTrackingSupport {
41177608706SJuan Quintela     WT_SUPPORT_UNKNOWN = 0,
41277608706SJuan Quintela     WT_SUPPORT_ABSENT,
41377608706SJuan Quintela     WT_SUPPORT_AVAILABLE,
41477608706SJuan Quintela     WT_SUPPORT_COMPATIBLE
41577608706SJuan Quintela } WriteTrackingSupport;
41677608706SJuan Quintela 
41777608706SJuan Quintela static
41877608706SJuan Quintela WriteTrackingSupport migrate_query_write_tracking(void)
41977608706SJuan Quintela {
42077608706SJuan Quintela     /* Check if kernel supports required UFFD features */
42177608706SJuan Quintela     if (!ram_write_tracking_available()) {
42277608706SJuan Quintela         return WT_SUPPORT_ABSENT;
42377608706SJuan Quintela     }
42477608706SJuan Quintela     /*
42577608706SJuan Quintela      * Check if current memory configuration is
42677608706SJuan Quintela      * compatible with required UFFD features.
42777608706SJuan Quintela      */
42877608706SJuan Quintela     if (!ram_write_tracking_compatible()) {
42977608706SJuan Quintela         return WT_SUPPORT_AVAILABLE;
43077608706SJuan Quintela     }
43177608706SJuan Quintela 
43277608706SJuan Quintela     return WT_SUPPORT_COMPATIBLE;
43377608706SJuan Quintela }
43477608706SJuan Quintela 
43577608706SJuan Quintela /* Migration capabilities set */
43677608706SJuan Quintela struct MigrateCapsSet {
43777608706SJuan Quintela     int size;                       /* Capability set size */
43877608706SJuan Quintela     MigrationCapability caps[];     /* Variadic array of capabilities */
43977608706SJuan Quintela };
44077608706SJuan Quintela typedef struct MigrateCapsSet MigrateCapsSet;
44177608706SJuan Quintela 
44277608706SJuan Quintela /* Define and initialize MigrateCapsSet */
44377608706SJuan Quintela #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
44477608706SJuan Quintela     MigrateCapsSet _name = {    \
44577608706SJuan Quintela         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
44677608706SJuan Quintela         .caps = { __VA_ARGS__ } \
44777608706SJuan Quintela     }
44877608706SJuan Quintela 
44977608706SJuan Quintela /* Background-snapshot compatibility check list */
45077608706SJuan Quintela static const
45177608706SJuan Quintela INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
45277608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_RAM,
45377608706SJuan Quintela     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
45477608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
45577608706SJuan Quintela     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
45677608706SJuan Quintela     MIGRATION_CAPABILITY_RETURN_PATH,
45777608706SJuan Quintela     MIGRATION_CAPABILITY_MULTIFD,
45877608706SJuan Quintela     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
45977608706SJuan Quintela     MIGRATION_CAPABILITY_AUTO_CONVERGE,
46077608706SJuan Quintela     MIGRATION_CAPABILITY_RELEASE_RAM,
46177608706SJuan Quintela     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
46277608706SJuan Quintela     MIGRATION_CAPABILITY_COMPRESS,
46377608706SJuan Quintela     MIGRATION_CAPABILITY_XBZRLE,
46477608706SJuan Quintela     MIGRATION_CAPABILITY_X_COLO,
46577608706SJuan Quintela     MIGRATION_CAPABILITY_VALIDATE_UUID,
46677608706SJuan Quintela     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
46777608706SJuan Quintela 
46882137e6cSWei Wang static bool migrate_incoming_started(void)
46982137e6cSWei Wang {
47082137e6cSWei Wang     return !!migration_incoming_get_current()->transport_data;
47182137e6cSWei Wang }
47282137e6cSWei Wang 
47377608706SJuan Quintela /**
47477608706SJuan Quintela  * @migration_caps_check - check capability compatibility
47577608706SJuan Quintela  *
47677608706SJuan Quintela  * @old_caps: old capability list
47777608706SJuan Quintela  * @new_caps: new capability list
47877608706SJuan Quintela  * @errp: set *errp if the check failed, with reason
47977608706SJuan Quintela  *
48077608706SJuan Quintela  * Returns true if check passed, otherwise false.
48177608706SJuan Quintela  */
48277608706SJuan Quintela bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
48377608706SJuan Quintela {
48477608706SJuan Quintela     MigrationIncomingState *mis = migration_incoming_get_current();
48577608706SJuan Quintela 
48674c38cf7SPeter Xu     ERRP_GUARD();
48777608706SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
48877608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BLOCK]) {
48977608706SJuan Quintela         error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) "
49077608706SJuan Quintela                    "block migration");
49166db46caSJuan Quintela         error_append_hint(errp, "Use blockdev-mirror with NBD instead.\n");
49277608706SJuan Quintela         return false;
49377608706SJuan Quintela     }
49477608706SJuan Quintela #endif
49566db46caSJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BLOCK]) {
49666db46caSJuan Quintela         warn_report("block migration is deprecated;"
49766db46caSJuan Quintela                     " use blockdev-mirror with NBD instead");
49866db46caSJuan Quintela     }
49977608706SJuan Quintela 
500864128dfSJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
501864128dfSJuan Quintela         warn_report("old compression method is deprecated;"
502864128dfSJuan Quintela                     " use multifd compression methods instead");
503864128dfSJuan Quintela     }
504864128dfSJuan Quintela 
50577608706SJuan Quintela #ifndef CONFIG_REPLICATION
50677608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
50777608706SJuan Quintela         error_setg(errp, "QEMU compiled without replication module"
50877608706SJuan Quintela                    " can't enable COLO");
50977608706SJuan Quintela         error_append_hint(errp, "Please enable replication before COLO.\n");
51077608706SJuan Quintela         return false;
51177608706SJuan Quintela     }
51277608706SJuan Quintela #endif
51377608706SJuan Quintela 
51477608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
51577608706SJuan Quintela         /* This check is reasonably expensive, so only when it's being
51677608706SJuan Quintela          * set the first time, also it's only the destination that needs
51777608706SJuan Quintela          * special support.
51877608706SJuan Quintela          */
51977608706SJuan Quintela         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
52077608706SJuan Quintela             runstate_check(RUN_STATE_INMIGRATE) &&
52174c38cf7SPeter Xu             !postcopy_ram_supported_by_host(mis, errp)) {
52274c38cf7SPeter Xu             error_prepend(errp, "Postcopy is not supported: ");
52377608706SJuan Quintela             return false;
52477608706SJuan Quintela         }
52577608706SJuan Quintela 
52677608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
52777608706SJuan Quintela             error_setg(errp, "Postcopy is not compatible with ignore-shared");
52877608706SJuan Quintela             return false;
52977608706SJuan Quintela         }
530b405dfffSLeonardo Bras 
531b405dfffSLeonardo Bras         if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
532b405dfffSLeonardo Bras             error_setg(errp, "Postcopy is not yet compatible with multifd");
533b405dfffSLeonardo Bras             return false;
534b405dfffSLeonardo Bras         }
53577608706SJuan Quintela     }
53677608706SJuan Quintela 
53777608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
53877608706SJuan Quintela         WriteTrackingSupport wt_support;
53977608706SJuan Quintela         int idx;
54077608706SJuan Quintela         /*
54177608706SJuan Quintela          * Check if 'background-snapshot' capability is supported by
54277608706SJuan Quintela          * host kernel and compatible with guest memory configuration.
54377608706SJuan Quintela          */
54477608706SJuan Quintela         wt_support = migrate_query_write_tracking();
54577608706SJuan Quintela         if (wt_support < WT_SUPPORT_AVAILABLE) {
54677608706SJuan Quintela             error_setg(errp, "Background-snapshot is not supported by host kernel");
54777608706SJuan Quintela             return false;
54877608706SJuan Quintela         }
54977608706SJuan Quintela         if (wt_support < WT_SUPPORT_COMPATIBLE) {
55077608706SJuan Quintela             error_setg(errp, "Background-snapshot is not compatible "
55177608706SJuan Quintela                     "with guest memory configuration");
55277608706SJuan Quintela             return false;
55377608706SJuan Quintela         }
55477608706SJuan Quintela 
55577608706SJuan Quintela         /*
55677608706SJuan Quintela          * Check if there are any migration capabilities
55777608706SJuan Quintela          * incompatible with 'background-snapshot'.
55877608706SJuan Quintela          */
55977608706SJuan Quintela         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
56077608706SJuan Quintela             int incomp_cap = check_caps_background_snapshot.caps[idx];
56177608706SJuan Quintela             if (new_caps[incomp_cap]) {
56277608706SJuan Quintela                 error_setg(errp,
56377608706SJuan Quintela                         "Background-snapshot is not compatible with %s",
56477608706SJuan Quintela                         MigrationCapability_str(incomp_cap));
56577608706SJuan Quintela                 return false;
56677608706SJuan Quintela             }
56777608706SJuan Quintela         }
56877608706SJuan Quintela     }
56977608706SJuan Quintela 
57077608706SJuan Quintela #ifdef CONFIG_LINUX
57177608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
57277608706SJuan Quintela         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
57377608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_COMPRESS] ||
57477608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
57577608706SJuan Quintela          migrate_multifd_compression() ||
57610d4703bSJuan Quintela          migrate_tls())) {
57777608706SJuan Quintela         error_setg(errp,
57877608706SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
57977608706SJuan Quintela         return false;
58077608706SJuan Quintela     }
58177608706SJuan Quintela #else
58277608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
58377608706SJuan Quintela         error_setg(errp,
58477608706SJuan Quintela                    "Zero copy currently only available on Linux");
58577608706SJuan Quintela         return false;
58677608706SJuan Quintela     }
58777608706SJuan Quintela #endif
58877608706SJuan Quintela 
58977608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
59077608706SJuan Quintela         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
59177608706SJuan Quintela             error_setg(errp, "Postcopy preempt requires postcopy-ram");
59277608706SJuan Quintela             return false;
59377608706SJuan Quintela         }
59477608706SJuan Quintela 
59577608706SJuan Quintela         /*
59677608706SJuan Quintela          * Preempt mode requires urgent pages to be sent in separate
59777608706SJuan Quintela          * channel, OTOH compression logic will disorder all pages into
59877608706SJuan Quintela          * different compression channels, which is not compatible with the
59977608706SJuan Quintela          * preempt assumptions on channel assignments.
60077608706SJuan Quintela          */
60177608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
60277608706SJuan Quintela             error_setg(errp, "Postcopy preempt not compatible with compress");
60377608706SJuan Quintela             return false;
60477608706SJuan Quintela         }
60582137e6cSWei Wang 
60682137e6cSWei Wang         if (migrate_incoming_started()) {
60782137e6cSWei Wang             error_setg(errp,
60882137e6cSWei Wang                        "Postcopy preempt must be set before incoming starts");
60982137e6cSWei Wang             return false;
61082137e6cSWei Wang         }
61177608706SJuan Quintela     }
61277608706SJuan Quintela 
61377608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
61477608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
61577608706SJuan Quintela             error_setg(errp, "Multifd is not compatible with compress");
61677608706SJuan Quintela             return false;
61777608706SJuan Quintela         }
61882137e6cSWei Wang         if (migrate_incoming_started()) {
61982137e6cSWei Wang             error_setg(errp, "Multifd must be set before incoming starts");
62082137e6cSWei Wang             return false;
62182137e6cSWei Wang         }
62277608706SJuan Quintela     }
62377608706SJuan Quintela 
6246574232fSAvihai Horon     if (new_caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK]) {
6256574232fSAvihai Horon         if (!new_caps[MIGRATION_CAPABILITY_RETURN_PATH]) {
6266574232fSAvihai Horon             error_setg(errp, "Capability 'switchover-ack' requires capability "
6276574232fSAvihai Horon                              "'return-path'");
6286574232fSAvihai Horon             return false;
6296574232fSAvihai Horon         }
6306574232fSAvihai Horon     }
631dc623955SHyman Huang(黄勇)     if (new_caps[MIGRATION_CAPABILITY_DIRTY_LIMIT]) {
632dc623955SHyman Huang(黄勇)         if (new_caps[MIGRATION_CAPABILITY_AUTO_CONVERGE]) {
633dc623955SHyman Huang(黄勇)             error_setg(errp, "dirty-limit conflicts with auto-converge"
634dc623955SHyman Huang(黄勇)                        " either of then available currently");
635dc623955SHyman Huang(黄勇)             return false;
636dc623955SHyman Huang(黄勇)         }
637dc623955SHyman Huang(黄勇) 
638dc623955SHyman Huang(黄勇)         if (!kvm_enabled() || !kvm_dirty_ring_enabled()) {
639dc623955SHyman Huang(黄勇)             error_setg(errp, "dirty-limit requires KVM with accelerator"
640dc623955SHyman Huang(黄勇)                    " property 'dirty-ring-size' set");
641dc623955SHyman Huang(黄勇)             return false;
642dc623955SHyman Huang(黄勇)         }
643dc623955SHyman Huang(黄勇)     }
6446574232fSAvihai Horon 
645d869f629SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
646d869f629SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
647d869f629SJuan Quintela             error_setg(errp, "Multifd is not compatible with xbzrle");
648d869f629SJuan Quintela             return false;
649d869f629SJuan Quintela         }
650d869f629SJuan Quintela     }
651d869f629SJuan Quintela 
6520e195629SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
6530e195629SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
6540e195629SJuan Quintela             error_setg(errp, "Compression is not compatible with xbzrle");
6550e195629SJuan Quintela             return false;
6560e195629SJuan Quintela         }
6570e195629SJuan Quintela     }
6580e195629SJuan Quintela 
6594ed49febSFabiano Rosas     if (new_caps[MIGRATION_CAPABILITY_MAPPED_RAM]) {
6604ed49febSFabiano Rosas         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
6614ed49febSFabiano Rosas             error_setg(errp,
6624ed49febSFabiano Rosas                        "Mapped-ram migration is incompatible with xbzrle");
6634ed49febSFabiano Rosas             return false;
6644ed49febSFabiano Rosas         }
6654ed49febSFabiano Rosas 
6664ed49febSFabiano Rosas         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
6674ed49febSFabiano Rosas             error_setg(errp,
6684ed49febSFabiano Rosas                        "Mapped-ram migration is incompatible with compression");
6694ed49febSFabiano Rosas             return false;
6704ed49febSFabiano Rosas         }
6714ed49febSFabiano Rosas 
6724ed49febSFabiano Rosas         if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
6734ed49febSFabiano Rosas             error_setg(errp,
6744ed49febSFabiano Rosas                        "Mapped-ram migration is incompatible with postcopy");
6754ed49febSFabiano Rosas             return false;
6764ed49febSFabiano Rosas         }
6774ed49febSFabiano Rosas     }
6784ed49febSFabiano Rosas 
67977608706SJuan Quintela     return true;
68077608706SJuan Quintela }
6814d0c6b69SJuan Quintela 
682f80196b7SJuan Quintela bool migrate_cap_set(int cap, bool value, Error **errp)
683f80196b7SJuan Quintela {
684f80196b7SJuan Quintela     MigrationState *s = migrate_get_current();
685f80196b7SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
686f80196b7SJuan Quintela 
687aeaafb1eSSteve Sistare     if (migration_is_running()) {
688f80196b7SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
689f80196b7SJuan Quintela         return false;
690f80196b7SJuan Quintela     }
691f80196b7SJuan Quintela 
692f80196b7SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
693f80196b7SJuan Quintela     new_caps[cap] = value;
694f80196b7SJuan Quintela 
695f80196b7SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
696f80196b7SJuan Quintela         return false;
697f80196b7SJuan Quintela     }
698f80196b7SJuan Quintela     s->capabilities[cap] = value;
699f80196b7SJuan Quintela     return true;
700f80196b7SJuan Quintela }
701f80196b7SJuan Quintela 
7024d0c6b69SJuan Quintela MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
7034d0c6b69SJuan Quintela {
7044d0c6b69SJuan Quintela     MigrationCapabilityStatusList *head = NULL, **tail = &head;
7054d0c6b69SJuan Quintela     MigrationCapabilityStatus *caps;
7064d0c6b69SJuan Quintela     MigrationState *s = migrate_get_current();
7074d0c6b69SJuan Quintela     int i;
7084d0c6b69SJuan Quintela 
7094d0c6b69SJuan Quintela     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
7104d0c6b69SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
7114d0c6b69SJuan Quintela         if (i == MIGRATION_CAPABILITY_BLOCK) {
7124d0c6b69SJuan Quintela             continue;
7134d0c6b69SJuan Quintela         }
7144d0c6b69SJuan Quintela #endif
7154d0c6b69SJuan Quintela         caps = g_malloc0(sizeof(*caps));
7164d0c6b69SJuan Quintela         caps->capability = i;
7174d0c6b69SJuan Quintela         caps->state = s->capabilities[i];
7184d0c6b69SJuan Quintela         QAPI_LIST_APPEND(tail, caps);
7194d0c6b69SJuan Quintela     }
7204d0c6b69SJuan Quintela 
7214d0c6b69SJuan Quintela     return head;
7224d0c6b69SJuan Quintela }
72345c1de13SJuan Quintela 
72445c1de13SJuan Quintela void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
72545c1de13SJuan Quintela                                   Error **errp)
72645c1de13SJuan Quintela {
72745c1de13SJuan Quintela     MigrationState *s = migrate_get_current();
72845c1de13SJuan Quintela     MigrationCapabilityStatusList *cap;
72945c1de13SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
73045c1de13SJuan Quintela 
731aeaafb1eSSteve Sistare     if (migration_is_running() || migration_in_colo_state()) {
73245c1de13SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
73345c1de13SJuan Quintela         return;
73445c1de13SJuan Quintela     }
73545c1de13SJuan Quintela 
73645c1de13SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
73745c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
73845c1de13SJuan Quintela         new_caps[cap->value->capability] = cap->value->state;
73945c1de13SJuan Quintela     }
74045c1de13SJuan Quintela 
74145c1de13SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
74245c1de13SJuan Quintela         return;
74345c1de13SJuan Quintela     }
74445c1de13SJuan Quintela 
74545c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
74645c1de13SJuan Quintela         s->capabilities[cap->value->capability] = cap->value->state;
74745c1de13SJuan Quintela     }
74845c1de13SJuan Quintela }
7491dfc4b9eSJuan Quintela 
7501dfc4b9eSJuan Quintela /* parameters */
7511dfc4b9eSJuan Quintela 
752b804b35bSJuan Quintela const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
753b804b35bSJuan Quintela {
754b804b35bSJuan Quintela     MigrationState *s = migrate_get_current();
755b804b35bSJuan Quintela 
756b804b35bSJuan Quintela     return s->parameters.block_bitmap_mapping;
757b804b35bSJuan Quintela }
758b804b35bSJuan Quintela 
7593cba22c9SJuan Quintela bool migrate_has_block_bitmap_mapping(void)
7603cba22c9SJuan Quintela {
7613cba22c9SJuan Quintela     MigrationState *s = migrate_get_current();
7623cba22c9SJuan Quintela 
7633cba22c9SJuan Quintela     return s->parameters.has_block_bitmap_mapping;
7643cba22c9SJuan Quintela }
7653cba22c9SJuan Quintela 
7666f8be708SJuan Quintela bool migrate_block_incremental(void)
7676f8be708SJuan Quintela {
7688f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7696f8be708SJuan Quintela 
7706f8be708SJuan Quintela     return s->parameters.block_incremental;
7716f8be708SJuan Quintela }
7726f8be708SJuan Quintela 
773f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void)
774f94a858fSJuan Quintela {
7758f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
776f94a858fSJuan Quintela 
777f94a858fSJuan Quintela     return s->parameters.x_checkpoint_delay;
778f94a858fSJuan Quintela }
779f94a858fSJuan Quintela 
7801dfc4b9eSJuan Quintela int migrate_compress_level(void)
7811dfc4b9eSJuan Quintela {
7828f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7831dfc4b9eSJuan Quintela 
7841dfc4b9eSJuan Quintela     return s->parameters.compress_level;
7851dfc4b9eSJuan Quintela }
7861dfc4b9eSJuan Quintela 
7871dfc4b9eSJuan Quintela int migrate_compress_threads(void)
7881dfc4b9eSJuan Quintela {
7898f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7901dfc4b9eSJuan Quintela 
7911dfc4b9eSJuan Quintela     return s->parameters.compress_threads;
7921dfc4b9eSJuan Quintela }
7931dfc4b9eSJuan Quintela 
7941dfc4b9eSJuan Quintela int migrate_compress_wait_thread(void)
7951dfc4b9eSJuan Quintela {
7968f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7971dfc4b9eSJuan Quintela 
7981dfc4b9eSJuan Quintela     return s->parameters.compress_wait_thread;
7991dfc4b9eSJuan Quintela }
8001dfc4b9eSJuan Quintela 
8019605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void)
8029605c2acSJuan Quintela {
8038f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8049605c2acSJuan Quintela 
8059605c2acSJuan Quintela     return s->parameters.cpu_throttle_increment;
8069605c2acSJuan Quintela }
8079605c2acSJuan Quintela 
8082a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void)
8092a8ec380SJuan Quintela {
8108f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8112a8ec380SJuan Quintela 
8122a8ec380SJuan Quintela     return s->parameters.cpu_throttle_initial;
8132a8ec380SJuan Quintela }
8142a8ec380SJuan Quintela 
815873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void)
816873f674cSJuan Quintela {
8178f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
818873f674cSJuan Quintela 
819873f674cSJuan Quintela     return s->parameters.cpu_throttle_tailslow;
820873f674cSJuan Quintela }
821873f674cSJuan Quintela 
8221dfc4b9eSJuan Quintela int migrate_decompress_threads(void)
8231dfc4b9eSJuan Quintela {
8248f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8251dfc4b9eSJuan Quintela 
8261dfc4b9eSJuan Quintela     return s->parameters.decompress_threads;
8271dfc4b9eSJuan Quintela }
8281dfc4b9eSJuan Quintela 
829f5da8ba4SJuan Quintela uint64_t migrate_downtime_limit(void)
830f5da8ba4SJuan Quintela {
831f5da8ba4SJuan Quintela     MigrationState *s = migrate_get_current();
832f5da8ba4SJuan Quintela 
833f5da8ba4SJuan Quintela     return s->parameters.downtime_limit;
834f5da8ba4SJuan Quintela }
835f5da8ba4SJuan Quintela 
83624155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void)
83724155bd0SJuan Quintela {
8388f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
83924155bd0SJuan Quintela 
84024155bd0SJuan Quintela     return s->parameters.max_cpu_throttle;
84124155bd0SJuan Quintela }
84224155bd0SJuan Quintela 
8439c894df3SJuan Quintela uint64_t migrate_max_bandwidth(void)
8449c894df3SJuan Quintela {
8458f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8469c894df3SJuan Quintela 
8479c894df3SJuan Quintela     return s->parameters.max_bandwidth;
8489c894df3SJuan Quintela }
8499c894df3SJuan Quintela 
8508b239597SPeter Xu uint64_t migrate_avail_switchover_bandwidth(void)
8518b239597SPeter Xu {
8528b239597SPeter Xu     MigrationState *s = migrate_get_current();
8538b239597SPeter Xu 
8548b239597SPeter Xu     return s->parameters.avail_switchover_bandwidth;
8558b239597SPeter Xu }
8568b239597SPeter Xu 
85752033349SJuan Quintela uint64_t migrate_max_postcopy_bandwidth(void)
8581dfc4b9eSJuan Quintela {
8598f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8601dfc4b9eSJuan Quintela 
8611dfc4b9eSJuan Quintela     return s->parameters.max_postcopy_bandwidth;
8621dfc4b9eSJuan Quintela }
8631dfc4b9eSJuan Quintela 
864eea1e5c9SSteve Sistare MigMode migrate_mode(void)
865eea1e5c9SSteve Sistare {
866eea1e5c9SSteve Sistare     MigrationState *s = migrate_get_current();
867b12635ffSSteve Sistare     MigMode mode = s->parameters.mode;
868eea1e5c9SSteve Sistare 
869b12635ffSSteve Sistare     assert(mode >= 0 && mode < MIG_MODE__MAX);
870b12635ffSSteve Sistare     return mode;
871eea1e5c9SSteve Sistare }
872eea1e5c9SSteve Sistare 
8731dfc4b9eSJuan Quintela int migrate_multifd_channels(void)
8741dfc4b9eSJuan Quintela {
8758f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8761dfc4b9eSJuan Quintela 
8771dfc4b9eSJuan Quintela     return s->parameters.multifd_channels;
8781dfc4b9eSJuan Quintela }
8791dfc4b9eSJuan Quintela 
8801dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void)
8811dfc4b9eSJuan Quintela {
8828f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8831dfc4b9eSJuan Quintela 
8841dfc4b9eSJuan Quintela     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
8851dfc4b9eSJuan Quintela     return s->parameters.multifd_compression;
8861dfc4b9eSJuan Quintela }
8871dfc4b9eSJuan Quintela 
8881dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void)
8891dfc4b9eSJuan Quintela {
8908f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8911dfc4b9eSJuan Quintela 
8921dfc4b9eSJuan Quintela     return s->parameters.multifd_zlib_level;
8931dfc4b9eSJuan Quintela }
8941dfc4b9eSJuan Quintela 
8951dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void)
8961dfc4b9eSJuan Quintela {
8978f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8981dfc4b9eSJuan Quintela 
8991dfc4b9eSJuan Quintela     return s->parameters.multifd_zstd_level;
9001dfc4b9eSJuan Quintela }
9011dfc4b9eSJuan Quintela 
9026499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void)
9036499efdbSJuan Quintela {
9048f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
9056499efdbSJuan Quintela 
9066499efdbSJuan Quintela     return s->parameters.throttle_trigger_threshold;
9076499efdbSJuan Quintela }
9086499efdbSJuan Quintela 
9092eb0308bSJuan Quintela const char *migrate_tls_authz(void)
9102eb0308bSJuan Quintela {
9112eb0308bSJuan Quintela     MigrationState *s = migrate_get_current();
9122eb0308bSJuan Quintela 
9132eb0308bSJuan Quintela     return s->parameters.tls_authz;
9142eb0308bSJuan Quintela }
9152eb0308bSJuan Quintela 
916d5c3e195SJuan Quintela const char *migrate_tls_creds(void)
917d5c3e195SJuan Quintela {
918d5c3e195SJuan Quintela     MigrationState *s = migrate_get_current();
919d5c3e195SJuan Quintela 
920d5c3e195SJuan Quintela     return s->parameters.tls_creds;
921d5c3e195SJuan Quintela }
922d5c3e195SJuan Quintela 
9231f2f366cSJuan Quintela const char *migrate_tls_hostname(void)
9241f2f366cSJuan Quintela {
9251f2f366cSJuan Quintela     MigrationState *s = migrate_get_current();
9261f2f366cSJuan Quintela 
9271f2f366cSJuan Quintela     return s->parameters.tls_hostname;
9281f2f366cSJuan Quintela }
9291f2f366cSJuan Quintela 
930714f3312SSteve Sistare uint64_t migrate_vcpu_dirty_limit_period(void)
931714f3312SSteve Sistare {
932714f3312SSteve Sistare     MigrationState *s = migrate_get_current();
933714f3312SSteve Sistare 
934714f3312SSteve Sistare     return s->parameters.x_vcpu_dirty_limit_period;
935714f3312SSteve Sistare }
936714f3312SSteve Sistare 
9371dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void)
9381dfc4b9eSJuan Quintela {
9398f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
9401dfc4b9eSJuan Quintela 
9411dfc4b9eSJuan Quintela     return s->parameters.xbzrle_cache_size;
9421dfc4b9eSJuan Quintela }
9432682c4eeSJuan Quintela 
944*5fdbb1dfSHao Xiang ZeroPageDetection migrate_zero_page_detection(void)
945*5fdbb1dfSHao Xiang {
946*5fdbb1dfSHao Xiang     MigrationState *s = migrate_get_current();
947*5fdbb1dfSHao Xiang 
948*5fdbb1dfSHao Xiang     return s->parameters.zero_page_detection;
949*5fdbb1dfSHao Xiang }
950*5fdbb1dfSHao Xiang 
95187c22901SJuan Quintela /* parameter setters */
95287c22901SJuan Quintela 
95387c22901SJuan Quintela void migrate_set_block_incremental(bool value)
95487c22901SJuan Quintela {
95587c22901SJuan Quintela     MigrationState *s = migrate_get_current();
95687c22901SJuan Quintela 
95787c22901SJuan Quintela     s->parameters.block_incremental = value;
95887c22901SJuan Quintela }
95987c22901SJuan Quintela 
9602682c4eeSJuan Quintela /* parameters helpers */
9612682c4eeSJuan Quintela 
962b1a87956SJuan Quintela void block_cleanup_parameters(void)
963b7b73122SJuan Quintela {
964b1a87956SJuan Quintela     MigrationState *s = migrate_get_current();
965b1a87956SJuan Quintela 
966b7b73122SJuan Quintela     if (s->must_remove_block_options) {
967b7b73122SJuan Quintela         /* setting to false can never fail */
968b7b73122SJuan Quintela         migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort);
969b7b73122SJuan Quintela         migrate_set_block_incremental(false);
970b7b73122SJuan Quintela         s->must_remove_block_options = false;
971b7b73122SJuan Quintela     }
972b7b73122SJuan Quintela }
973b7b73122SJuan Quintela 
9742682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void)
9752682c4eeSJuan Quintela {
9762682c4eeSJuan Quintela     static AnnounceParameters ap;
9772682c4eeSJuan Quintela 
9782682c4eeSJuan Quintela     MigrationState *s = migrate_get_current();
9792682c4eeSJuan Quintela 
9802682c4eeSJuan Quintela     ap.initial = s->parameters.announce_initial;
9812682c4eeSJuan Quintela     ap.max = s->parameters.announce_max;
9822682c4eeSJuan Quintela     ap.rounds = s->parameters.announce_rounds;
9832682c4eeSJuan Quintela     ap.step = s->parameters.announce_step;
9842682c4eeSJuan Quintela 
9852682c4eeSJuan Quintela     return &ap;
9862682c4eeSJuan Quintela }
9879c894df3SJuan Quintela 
9889c894df3SJuan Quintela MigrationParameters *qmp_query_migrate_parameters(Error **errp)
9899c894df3SJuan Quintela {
9909c894df3SJuan Quintela     MigrationParameters *params;
9919c894df3SJuan Quintela     MigrationState *s = migrate_get_current();
9929c894df3SJuan Quintela 
9939c894df3SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
9949c894df3SJuan Quintela     params = g_malloc0(sizeof(*params));
9959c894df3SJuan Quintela     params->has_compress_level = true;
9969c894df3SJuan Quintela     params->compress_level = s->parameters.compress_level;
9979c894df3SJuan Quintela     params->has_compress_threads = true;
9989c894df3SJuan Quintela     params->compress_threads = s->parameters.compress_threads;
9999c894df3SJuan Quintela     params->has_compress_wait_thread = true;
10009c894df3SJuan Quintela     params->compress_wait_thread = s->parameters.compress_wait_thread;
10019c894df3SJuan Quintela     params->has_decompress_threads = true;
10029c894df3SJuan Quintela     params->decompress_threads = s->parameters.decompress_threads;
10039c894df3SJuan Quintela     params->has_throttle_trigger_threshold = true;
10049c894df3SJuan Quintela     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
10059c894df3SJuan Quintela     params->has_cpu_throttle_initial = true;
10069c894df3SJuan Quintela     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
10079c894df3SJuan Quintela     params->has_cpu_throttle_increment = true;
10089c894df3SJuan Quintela     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
10099c894df3SJuan Quintela     params->has_cpu_throttle_tailslow = true;
10109c894df3SJuan Quintela     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
10119c894df3SJuan Quintela     params->tls_creds = g_strdup(s->parameters.tls_creds);
10129c894df3SJuan Quintela     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
10139c894df3SJuan Quintela     params->tls_authz = g_strdup(s->parameters.tls_authz ?
10149c894df3SJuan Quintela                                  s->parameters.tls_authz : "");
10159c894df3SJuan Quintela     params->has_max_bandwidth = true;
10169c894df3SJuan Quintela     params->max_bandwidth = s->parameters.max_bandwidth;
10178b239597SPeter Xu     params->has_avail_switchover_bandwidth = true;
10188b239597SPeter Xu     params->avail_switchover_bandwidth = s->parameters.avail_switchover_bandwidth;
10199c894df3SJuan Quintela     params->has_downtime_limit = true;
10209c894df3SJuan Quintela     params->downtime_limit = s->parameters.downtime_limit;
10219c894df3SJuan Quintela     params->has_x_checkpoint_delay = true;
10229c894df3SJuan Quintela     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
10239c894df3SJuan Quintela     params->has_block_incremental = true;
10249c894df3SJuan Quintela     params->block_incremental = s->parameters.block_incremental;
10259c894df3SJuan Quintela     params->has_multifd_channels = true;
10269c894df3SJuan Quintela     params->multifd_channels = s->parameters.multifd_channels;
10279c894df3SJuan Quintela     params->has_multifd_compression = true;
10289c894df3SJuan Quintela     params->multifd_compression = s->parameters.multifd_compression;
10299c894df3SJuan Quintela     params->has_multifd_zlib_level = true;
10309c894df3SJuan Quintela     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
10319c894df3SJuan Quintela     params->has_multifd_zstd_level = true;
10329c894df3SJuan Quintela     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
10339c894df3SJuan Quintela     params->has_xbzrle_cache_size = true;
10349c894df3SJuan Quintela     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
10359c894df3SJuan Quintela     params->has_max_postcopy_bandwidth = true;
10369c894df3SJuan Quintela     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
10379c894df3SJuan Quintela     params->has_max_cpu_throttle = true;
10389c894df3SJuan Quintela     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
10399c894df3SJuan Quintela     params->has_announce_initial = true;
10409c894df3SJuan Quintela     params->announce_initial = s->parameters.announce_initial;
10419c894df3SJuan Quintela     params->has_announce_max = true;
10429c894df3SJuan Quintela     params->announce_max = s->parameters.announce_max;
10439c894df3SJuan Quintela     params->has_announce_rounds = true;
10449c894df3SJuan Quintela     params->announce_rounds = s->parameters.announce_rounds;
10459c894df3SJuan Quintela     params->has_announce_step = true;
10469c894df3SJuan Quintela     params->announce_step = s->parameters.announce_step;
10479c894df3SJuan Quintela 
10489c894df3SJuan Quintela     if (s->parameters.has_block_bitmap_mapping) {
10499c894df3SJuan Quintela         params->has_block_bitmap_mapping = true;
10509c894df3SJuan Quintela         params->block_bitmap_mapping =
10519c894df3SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
10529c894df3SJuan Quintela                        s->parameters.block_bitmap_mapping);
10539c894df3SJuan Quintela     }
10549c894df3SJuan Quintela 
10554d807857SHyman Huang(黄勇)     params->has_x_vcpu_dirty_limit_period = true;
10564d807857SHyman Huang(黄勇)     params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period;
105709f9ec99SHyman Huang(黄勇)     params->has_vcpu_dirty_limit = true;
105809f9ec99SHyman Huang(黄勇)     params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit;
1059eea1e5c9SSteve Sistare     params->has_mode = true;
1060eea1e5c9SSteve Sistare     params->mode = s->parameters.mode;
1061*5fdbb1dfSHao Xiang     params->has_zero_page_detection = true;
1062*5fdbb1dfSHao Xiang     params->zero_page_detection = s->parameters.zero_page_detection;
10634d807857SHyman Huang(黄勇) 
10649c894df3SJuan Quintela     return params;
10659c894df3SJuan Quintela }
106609d6c965SJuan Quintela 
106761a174e2SJuan Quintela void migrate_params_init(MigrationParameters *params)
106861a174e2SJuan Quintela {
106961a174e2SJuan Quintela     params->tls_hostname = g_strdup("");
107061a174e2SJuan Quintela     params->tls_creds = g_strdup("");
107161a174e2SJuan Quintela 
107261a174e2SJuan Quintela     /* Set has_* up only for parameter checks */
107361a174e2SJuan Quintela     params->has_compress_level = true;
107461a174e2SJuan Quintela     params->has_compress_threads = true;
107561a174e2SJuan Quintela     params->has_compress_wait_thread = true;
107661a174e2SJuan Quintela     params->has_decompress_threads = true;
107761a174e2SJuan Quintela     params->has_throttle_trigger_threshold = true;
107861a174e2SJuan Quintela     params->has_cpu_throttle_initial = true;
107961a174e2SJuan Quintela     params->has_cpu_throttle_increment = true;
108061a174e2SJuan Quintela     params->has_cpu_throttle_tailslow = true;
108161a174e2SJuan Quintela     params->has_max_bandwidth = true;
108261a174e2SJuan Quintela     params->has_downtime_limit = true;
108361a174e2SJuan Quintela     params->has_x_checkpoint_delay = true;
108461a174e2SJuan Quintela     params->has_block_incremental = true;
108561a174e2SJuan Quintela     params->has_multifd_channels = true;
108661a174e2SJuan Quintela     params->has_multifd_compression = true;
108761a174e2SJuan Quintela     params->has_multifd_zlib_level = true;
108861a174e2SJuan Quintela     params->has_multifd_zstd_level = true;
108961a174e2SJuan Quintela     params->has_xbzrle_cache_size = true;
109061a174e2SJuan Quintela     params->has_max_postcopy_bandwidth = true;
109161a174e2SJuan Quintela     params->has_max_cpu_throttle = true;
109261a174e2SJuan Quintela     params->has_announce_initial = true;
109361a174e2SJuan Quintela     params->has_announce_max = true;
109461a174e2SJuan Quintela     params->has_announce_rounds = true;
109561a174e2SJuan Quintela     params->has_announce_step = true;
10964d807857SHyman Huang(黄勇)     params->has_x_vcpu_dirty_limit_period = true;
109709f9ec99SHyman Huang(黄勇)     params->has_vcpu_dirty_limit = true;
1098eea1e5c9SSteve Sistare     params->has_mode = true;
1099*5fdbb1dfSHao Xiang     params->has_zero_page_detection = true;
110061a174e2SJuan Quintela }
110161a174e2SJuan Quintela 
110209d6c965SJuan Quintela /*
110309d6c965SJuan Quintela  * Check whether the parameters are valid. Error will be put into errp
110409d6c965SJuan Quintela  * (if provided). Return true if valid, otherwise false.
110509d6c965SJuan Quintela  */
110609d6c965SJuan Quintela bool migrate_params_check(MigrationParameters *params, Error **errp)
110709d6c965SJuan Quintela {
110809d6c965SJuan Quintela     if (params->has_compress_level &&
110909d6c965SJuan Quintela         (params->compress_level > 9)) {
111009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",
111109d6c965SJuan Quintela                    "a value between 0 and 9");
111209d6c965SJuan Quintela         return false;
111309d6c965SJuan Quintela     }
111409d6c965SJuan Quintela 
111509d6c965SJuan Quintela     if (params->has_compress_threads && (params->compress_threads < 1)) {
111609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
111709d6c965SJuan Quintela                    "compress_threads",
111809d6c965SJuan Quintela                    "a value between 1 and 255");
111909d6c965SJuan Quintela         return false;
112009d6c965SJuan Quintela     }
112109d6c965SJuan Quintela 
112209d6c965SJuan Quintela     if (params->has_decompress_threads && (params->decompress_threads < 1)) {
112309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
112409d6c965SJuan Quintela                    "decompress_threads",
112509d6c965SJuan Quintela                    "a value between 1 and 255");
112609d6c965SJuan Quintela         return false;
112709d6c965SJuan Quintela     }
112809d6c965SJuan Quintela 
112909d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold &&
113009d6c965SJuan Quintela         (params->throttle_trigger_threshold < 1 ||
113109d6c965SJuan Quintela          params->throttle_trigger_threshold > 100)) {
113209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
113309d6c965SJuan Quintela                    "throttle_trigger_threshold",
113409d6c965SJuan Quintela                    "an integer in the range of 1 to 100");
113509d6c965SJuan Quintela         return false;
113609d6c965SJuan Quintela     }
113709d6c965SJuan Quintela 
113809d6c965SJuan Quintela     if (params->has_cpu_throttle_initial &&
113909d6c965SJuan Quintela         (params->cpu_throttle_initial < 1 ||
114009d6c965SJuan Quintela          params->cpu_throttle_initial > 99)) {
114109d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
114209d6c965SJuan Quintela                    "cpu_throttle_initial",
114309d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
114409d6c965SJuan Quintela         return false;
114509d6c965SJuan Quintela     }
114609d6c965SJuan Quintela 
114709d6c965SJuan Quintela     if (params->has_cpu_throttle_increment &&
114809d6c965SJuan Quintela         (params->cpu_throttle_increment < 1 ||
114909d6c965SJuan Quintela          params->cpu_throttle_increment > 99)) {
115009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
115109d6c965SJuan Quintela                    "cpu_throttle_increment",
115209d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
115309d6c965SJuan Quintela         return false;
115409d6c965SJuan Quintela     }
115509d6c965SJuan Quintela 
115609d6c965SJuan Quintela     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
115709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
115809d6c965SJuan Quintela                    "max_bandwidth",
115909d6c965SJuan Quintela                    "an integer in the range of 0 to "stringify(SIZE_MAX)
116009d6c965SJuan Quintela                    " bytes/second");
116109d6c965SJuan Quintela         return false;
116209d6c965SJuan Quintela     }
116309d6c965SJuan Quintela 
11648b239597SPeter Xu     if (params->has_avail_switchover_bandwidth &&
11658b239597SPeter Xu         (params->avail_switchover_bandwidth > SIZE_MAX)) {
11668b239597SPeter Xu         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
11678b239597SPeter Xu                    "avail_switchover_bandwidth",
11688b239597SPeter Xu                    "an integer in the range of 0 to "stringify(SIZE_MAX)
11698b239597SPeter Xu                    " bytes/second");
11708b239597SPeter Xu         return false;
11718b239597SPeter Xu     }
11728b239597SPeter Xu 
117309d6c965SJuan Quintela     if (params->has_downtime_limit &&
117409d6c965SJuan Quintela         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
117509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
117609d6c965SJuan Quintela                    "downtime_limit",
117709d6c965SJuan Quintela                    "an integer in the range of 0 to "
117809d6c965SJuan Quintela                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
117909d6c965SJuan Quintela         return false;
118009d6c965SJuan Quintela     }
118109d6c965SJuan Quintela 
118209d6c965SJuan Quintela     /* x_checkpoint_delay is now always positive */
118309d6c965SJuan Quintela 
118409d6c965SJuan Quintela     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
118509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
118609d6c965SJuan Quintela                    "multifd_channels",
118709d6c965SJuan Quintela                    "a value between 1 and 255");
118809d6c965SJuan Quintela         return false;
118909d6c965SJuan Quintela     }
119009d6c965SJuan Quintela 
119109d6c965SJuan Quintela     if (params->has_multifd_zlib_level &&
119209d6c965SJuan Quintela         (params->multifd_zlib_level > 9)) {
119309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
119409d6c965SJuan Quintela                    "a value between 0 and 9");
119509d6c965SJuan Quintela         return false;
119609d6c965SJuan Quintela     }
119709d6c965SJuan Quintela 
119809d6c965SJuan Quintela     if (params->has_multifd_zstd_level &&
119909d6c965SJuan Quintela         (params->multifd_zstd_level > 20)) {
120009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
120109d6c965SJuan Quintela                    "a value between 0 and 20");
120209d6c965SJuan Quintela         return false;
120309d6c965SJuan Quintela     }
120409d6c965SJuan Quintela 
120509d6c965SJuan Quintela     if (params->has_xbzrle_cache_size &&
120609d6c965SJuan Quintela         (params->xbzrle_cache_size < qemu_target_page_size() ||
120709d6c965SJuan Quintela          !is_power_of_2(params->xbzrle_cache_size))) {
120809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
120909d6c965SJuan Quintela                    "xbzrle_cache_size",
121009d6c965SJuan Quintela                    "a power of two no less than the target page size");
121109d6c965SJuan Quintela         return false;
121209d6c965SJuan Quintela     }
121309d6c965SJuan Quintela 
121409d6c965SJuan Quintela     if (params->has_max_cpu_throttle &&
121509d6c965SJuan Quintela         (params->max_cpu_throttle < params->cpu_throttle_initial ||
121609d6c965SJuan Quintela          params->max_cpu_throttle > 99)) {
121709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
121809d6c965SJuan Quintela                    "max_cpu_throttle",
121909d6c965SJuan Quintela                    "an integer in the range of cpu_throttle_initial to 99");
122009d6c965SJuan Quintela         return false;
122109d6c965SJuan Quintela     }
122209d6c965SJuan Quintela 
122309d6c965SJuan Quintela     if (params->has_announce_initial &&
122409d6c965SJuan Quintela         params->announce_initial > 100000) {
122509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
122609d6c965SJuan Quintela                    "announce_initial",
122709d6c965SJuan Quintela                    "a value between 0 and 100000");
122809d6c965SJuan Quintela         return false;
122909d6c965SJuan Quintela     }
123009d6c965SJuan Quintela     if (params->has_announce_max &&
123109d6c965SJuan Quintela         params->announce_max > 100000) {
123209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
123309d6c965SJuan Quintela                    "announce_max",
123409d6c965SJuan Quintela                    "a value between 0 and 100000");
123509d6c965SJuan Quintela        return false;
123609d6c965SJuan Quintela     }
123709d6c965SJuan Quintela     if (params->has_announce_rounds &&
123809d6c965SJuan Quintela         params->announce_rounds > 1000) {
123909d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
124009d6c965SJuan Quintela                    "announce_rounds",
124109d6c965SJuan Quintela                    "a value between 0 and 1000");
124209d6c965SJuan Quintela        return false;
124309d6c965SJuan Quintela     }
124409d6c965SJuan Quintela     if (params->has_announce_step &&
124509d6c965SJuan Quintela         (params->announce_step < 1 ||
124609d6c965SJuan Quintela         params->announce_step > 10000)) {
124709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
124809d6c965SJuan Quintela                    "announce_step",
124909d6c965SJuan Quintela                    "a value between 0 and 10000");
125009d6c965SJuan Quintela        return false;
125109d6c965SJuan Quintela     }
125209d6c965SJuan Quintela 
125309d6c965SJuan Quintela     if (params->has_block_bitmap_mapping &&
125409d6c965SJuan Quintela         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
125509d6c965SJuan Quintela         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
125609d6c965SJuan Quintela         return false;
125709d6c965SJuan Quintela     }
125809d6c965SJuan Quintela 
125909d6c965SJuan Quintela #ifdef CONFIG_LINUX
126009d6c965SJuan Quintela     if (migrate_zero_copy_send() &&
126109d6c965SJuan Quintela         ((params->has_multifd_compression && params->multifd_compression) ||
126209d6c965SJuan Quintela          (params->tls_creds && *params->tls_creds))) {
126309d6c965SJuan Quintela         error_setg(errp,
126409d6c965SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
126509d6c965SJuan Quintela         return false;
126609d6c965SJuan Quintela     }
126709d6c965SJuan Quintela #endif
126809d6c965SJuan Quintela 
1269f427d90bSFabiano Rosas     if (migrate_mapped_ram() &&
1270f427d90bSFabiano Rosas         (migrate_multifd_compression() || migrate_tls())) {
1271f427d90bSFabiano Rosas         error_setg(errp,
1272f427d90bSFabiano Rosas                    "Mapped-ram only available for non-compressed non-TLS multifd migration");
1273f427d90bSFabiano Rosas         return false;
1274f427d90bSFabiano Rosas     }
1275f427d90bSFabiano Rosas 
12764d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period &&
12774d807857SHyman Huang(黄勇)         (params->x_vcpu_dirty_limit_period < 1 ||
12784d807857SHyman Huang(黄勇)          params->x_vcpu_dirty_limit_period > 1000)) {
12794d807857SHyman Huang(黄勇)         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
12804d807857SHyman Huang(黄勇)                    "x-vcpu-dirty-limit-period",
12814d807857SHyman Huang(黄勇)                    "a value between 1 and 1000");
12824d807857SHyman Huang(黄勇)         return false;
12834d807857SHyman Huang(黄勇)     }
12844d807857SHyman Huang(黄勇) 
128509f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit &&
128609f9ec99SHyman Huang(黄勇)         (params->vcpu_dirty_limit < 1)) {
128709f9ec99SHyman Huang(黄勇)         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
128809f9ec99SHyman Huang(黄勇)                    "vcpu_dirty_limit",
128909f9ec99SHyman Huang(黄勇)                    "is invalid, it must greater then 1 MB/s");
129009f9ec99SHyman Huang(黄勇)         return false;
129109f9ec99SHyman Huang(黄勇)     }
129209f9ec99SHyman Huang(黄勇) 
129309d6c965SJuan Quintela     return true;
129409d6c965SJuan Quintela }
129509d6c965SJuan Quintela 
129609d6c965SJuan Quintela static void migrate_params_test_apply(MigrateSetParameters *params,
129709d6c965SJuan Quintela                                       MigrationParameters *dest)
129809d6c965SJuan Quintela {
129909d6c965SJuan Quintela     *dest = migrate_get_current()->parameters;
130009d6c965SJuan Quintela 
130109d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
130209d6c965SJuan Quintela 
130309d6c965SJuan Quintela     if (params->has_compress_level) {
130409d6c965SJuan Quintela         dest->compress_level = params->compress_level;
130509d6c965SJuan Quintela     }
130609d6c965SJuan Quintela 
130709d6c965SJuan Quintela     if (params->has_compress_threads) {
130809d6c965SJuan Quintela         dest->compress_threads = params->compress_threads;
130909d6c965SJuan Quintela     }
131009d6c965SJuan Quintela 
131109d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
131209d6c965SJuan Quintela         dest->compress_wait_thread = params->compress_wait_thread;
131309d6c965SJuan Quintela     }
131409d6c965SJuan Quintela 
131509d6c965SJuan Quintela     if (params->has_decompress_threads) {
131609d6c965SJuan Quintela         dest->decompress_threads = params->decompress_threads;
131709d6c965SJuan Quintela     }
131809d6c965SJuan Quintela 
131909d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
132009d6c965SJuan Quintela         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
132109d6c965SJuan Quintela     }
132209d6c965SJuan Quintela 
132309d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
132409d6c965SJuan Quintela         dest->cpu_throttle_initial = params->cpu_throttle_initial;
132509d6c965SJuan Quintela     }
132609d6c965SJuan Quintela 
132709d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
132809d6c965SJuan Quintela         dest->cpu_throttle_increment = params->cpu_throttle_increment;
132909d6c965SJuan Quintela     }
133009d6c965SJuan Quintela 
133109d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
133209d6c965SJuan Quintela         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
133309d6c965SJuan Quintela     }
133409d6c965SJuan Quintela 
133509d6c965SJuan Quintela     if (params->tls_creds) {
133609d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
133709d6c965SJuan Quintela         dest->tls_creds = params->tls_creds->u.s;
133809d6c965SJuan Quintela     }
133909d6c965SJuan Quintela 
134009d6c965SJuan Quintela     if (params->tls_hostname) {
134109d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
134209d6c965SJuan Quintela         dest->tls_hostname = params->tls_hostname->u.s;
134309d6c965SJuan Quintela     }
134409d6c965SJuan Quintela 
134509d6c965SJuan Quintela     if (params->has_max_bandwidth) {
134609d6c965SJuan Quintela         dest->max_bandwidth = params->max_bandwidth;
134709d6c965SJuan Quintela     }
134809d6c965SJuan Quintela 
13498b239597SPeter Xu     if (params->has_avail_switchover_bandwidth) {
13508b239597SPeter Xu         dest->avail_switchover_bandwidth = params->avail_switchover_bandwidth;
13518b239597SPeter Xu     }
13528b239597SPeter Xu 
135309d6c965SJuan Quintela     if (params->has_downtime_limit) {
135409d6c965SJuan Quintela         dest->downtime_limit = params->downtime_limit;
135509d6c965SJuan Quintela     }
135609d6c965SJuan Quintela 
135709d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
135809d6c965SJuan Quintela         dest->x_checkpoint_delay = params->x_checkpoint_delay;
135909d6c965SJuan Quintela     }
136009d6c965SJuan Quintela 
136109d6c965SJuan Quintela     if (params->has_block_incremental) {
136209d6c965SJuan Quintela         dest->block_incremental = params->block_incremental;
136309d6c965SJuan Quintela     }
136409d6c965SJuan Quintela     if (params->has_multifd_channels) {
136509d6c965SJuan Quintela         dest->multifd_channels = params->multifd_channels;
136609d6c965SJuan Quintela     }
136709d6c965SJuan Quintela     if (params->has_multifd_compression) {
136809d6c965SJuan Quintela         dest->multifd_compression = params->multifd_compression;
136909d6c965SJuan Quintela     }
1370b4014a2bSBryan Zhang     if (params->has_multifd_zlib_level) {
1371b4014a2bSBryan Zhang         dest->multifd_zlib_level = params->multifd_zlib_level;
1372b4014a2bSBryan Zhang     }
1373b4014a2bSBryan Zhang     if (params->has_multifd_zstd_level) {
1374b4014a2bSBryan Zhang         dest->multifd_zstd_level = params->multifd_zstd_level;
1375b4014a2bSBryan Zhang     }
137609d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
137709d6c965SJuan Quintela         dest->xbzrle_cache_size = params->xbzrle_cache_size;
137809d6c965SJuan Quintela     }
137909d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
138009d6c965SJuan Quintela         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
138109d6c965SJuan Quintela     }
138209d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
138309d6c965SJuan Quintela         dest->max_cpu_throttle = params->max_cpu_throttle;
138409d6c965SJuan Quintela     }
138509d6c965SJuan Quintela     if (params->has_announce_initial) {
138609d6c965SJuan Quintela         dest->announce_initial = params->announce_initial;
138709d6c965SJuan Quintela     }
138809d6c965SJuan Quintela     if (params->has_announce_max) {
138909d6c965SJuan Quintela         dest->announce_max = params->announce_max;
139009d6c965SJuan Quintela     }
139109d6c965SJuan Quintela     if (params->has_announce_rounds) {
139209d6c965SJuan Quintela         dest->announce_rounds = params->announce_rounds;
139309d6c965SJuan Quintela     }
139409d6c965SJuan Quintela     if (params->has_announce_step) {
139509d6c965SJuan Quintela         dest->announce_step = params->announce_step;
139609d6c965SJuan Quintela     }
139709d6c965SJuan Quintela 
139809d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
139909d6c965SJuan Quintela         dest->has_block_bitmap_mapping = true;
140009d6c965SJuan Quintela         dest->block_bitmap_mapping = params->block_bitmap_mapping;
140109d6c965SJuan Quintela     }
14024d807857SHyman Huang(黄勇) 
14034d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period) {
14044d807857SHyman Huang(黄勇)         dest->x_vcpu_dirty_limit_period =
14054d807857SHyman Huang(黄勇)             params->x_vcpu_dirty_limit_period;
14064d807857SHyman Huang(黄勇)     }
140709f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit) {
140809f9ec99SHyman Huang(黄勇)         dest->vcpu_dirty_limit = params->vcpu_dirty_limit;
140909f9ec99SHyman Huang(黄勇)     }
1410eea1e5c9SSteve Sistare 
1411eea1e5c9SSteve Sistare     if (params->has_mode) {
1412eea1e5c9SSteve Sistare         dest->mode = params->mode;
1413eea1e5c9SSteve Sistare     }
1414*5fdbb1dfSHao Xiang 
1415*5fdbb1dfSHao Xiang     if (params->has_zero_page_detection) {
1416*5fdbb1dfSHao Xiang         dest->zero_page_detection = params->zero_page_detection;
1417*5fdbb1dfSHao Xiang     }
141809d6c965SJuan Quintela }
141909d6c965SJuan Quintela 
142009d6c965SJuan Quintela static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
142109d6c965SJuan Quintela {
142209d6c965SJuan Quintela     MigrationState *s = migrate_get_current();
142309d6c965SJuan Quintela 
142409d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
142509d6c965SJuan Quintela 
142609d6c965SJuan Quintela     if (params->has_compress_level) {
1427864128dfSJuan Quintela         warn_report("old compression is deprecated;"
1428864128dfSJuan Quintela                     " use multifd compression methods instead");
142909d6c965SJuan Quintela         s->parameters.compress_level = params->compress_level;
143009d6c965SJuan Quintela     }
143109d6c965SJuan Quintela 
143209d6c965SJuan Quintela     if (params->has_compress_threads) {
1433864128dfSJuan Quintela         warn_report("old compression is deprecated;"
1434864128dfSJuan Quintela                     " use multifd compression methods instead");
143509d6c965SJuan Quintela         s->parameters.compress_threads = params->compress_threads;
143609d6c965SJuan Quintela     }
143709d6c965SJuan Quintela 
143809d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
1439864128dfSJuan Quintela         warn_report("old compression is deprecated;"
1440864128dfSJuan Quintela                     " use multifd compression methods instead");
144109d6c965SJuan Quintela         s->parameters.compress_wait_thread = params->compress_wait_thread;
144209d6c965SJuan Quintela     }
144309d6c965SJuan Quintela 
144409d6c965SJuan Quintela     if (params->has_decompress_threads) {
1445864128dfSJuan Quintela         warn_report("old compression is deprecated;"
1446864128dfSJuan Quintela                     " use multifd compression methods instead");
144709d6c965SJuan Quintela         s->parameters.decompress_threads = params->decompress_threads;
144809d6c965SJuan Quintela     }
144909d6c965SJuan Quintela 
145009d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
145109d6c965SJuan Quintela         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
145209d6c965SJuan Quintela     }
145309d6c965SJuan Quintela 
145409d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
145509d6c965SJuan Quintela         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
145609d6c965SJuan Quintela     }
145709d6c965SJuan Quintela 
145809d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
145909d6c965SJuan Quintela         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
146009d6c965SJuan Quintela     }
146109d6c965SJuan Quintela 
146209d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
146309d6c965SJuan Quintela         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
146409d6c965SJuan Quintela     }
146509d6c965SJuan Quintela 
146609d6c965SJuan Quintela     if (params->tls_creds) {
146709d6c965SJuan Quintela         g_free(s->parameters.tls_creds);
146809d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
146909d6c965SJuan Quintela         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
147009d6c965SJuan Quintela     }
147109d6c965SJuan Quintela 
147209d6c965SJuan Quintela     if (params->tls_hostname) {
147309d6c965SJuan Quintela         g_free(s->parameters.tls_hostname);
147409d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
147509d6c965SJuan Quintela         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
147609d6c965SJuan Quintela     }
147709d6c965SJuan Quintela 
147809d6c965SJuan Quintela     if (params->tls_authz) {
147909d6c965SJuan Quintela         g_free(s->parameters.tls_authz);
148009d6c965SJuan Quintela         assert(params->tls_authz->type == QTYPE_QSTRING);
148109d6c965SJuan Quintela         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
148209d6c965SJuan Quintela     }
148309d6c965SJuan Quintela 
148409d6c965SJuan Quintela     if (params->has_max_bandwidth) {
148509d6c965SJuan Quintela         s->parameters.max_bandwidth = params->max_bandwidth;
148609d6c965SJuan Quintela         if (s->to_dst_file && !migration_in_postcopy()) {
1487e1fde0e0SJuan Quintela             migration_rate_set(s->parameters.max_bandwidth);
148809d6c965SJuan Quintela         }
148909d6c965SJuan Quintela     }
149009d6c965SJuan Quintela 
14918b239597SPeter Xu     if (params->has_avail_switchover_bandwidth) {
14928b239597SPeter Xu         s->parameters.avail_switchover_bandwidth = params->avail_switchover_bandwidth;
14938b239597SPeter Xu     }
14948b239597SPeter Xu 
149509d6c965SJuan Quintela     if (params->has_downtime_limit) {
149609d6c965SJuan Quintela         s->parameters.downtime_limit = params->downtime_limit;
149709d6c965SJuan Quintela     }
149809d6c965SJuan Quintela 
149909d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
150009d6c965SJuan Quintela         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
15014332ffcdSVladimir Sementsov-Ogievskiy         colo_checkpoint_delay_set();
150209d6c965SJuan Quintela     }
150309d6c965SJuan Quintela 
150409d6c965SJuan Quintela     if (params->has_block_incremental) {
150566db46caSJuan Quintela         warn_report("block migration is deprecated;"
150666db46caSJuan Quintela                     " use blockdev-mirror with NBD instead");
150709d6c965SJuan Quintela         s->parameters.block_incremental = params->block_incremental;
150809d6c965SJuan Quintela     }
150909d6c965SJuan Quintela     if (params->has_multifd_channels) {
151009d6c965SJuan Quintela         s->parameters.multifd_channels = params->multifd_channels;
151109d6c965SJuan Quintela     }
151209d6c965SJuan Quintela     if (params->has_multifd_compression) {
151309d6c965SJuan Quintela         s->parameters.multifd_compression = params->multifd_compression;
151409d6c965SJuan Quintela     }
1515b4014a2bSBryan Zhang     if (params->has_multifd_zlib_level) {
1516b4014a2bSBryan Zhang         s->parameters.multifd_zlib_level = params->multifd_zlib_level;
1517b4014a2bSBryan Zhang     }
1518b4014a2bSBryan Zhang     if (params->has_multifd_zstd_level) {
1519b4014a2bSBryan Zhang         s->parameters.multifd_zstd_level = params->multifd_zstd_level;
1520b4014a2bSBryan Zhang     }
152109d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
152209d6c965SJuan Quintela         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
152309d6c965SJuan Quintela         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
152409d6c965SJuan Quintela     }
152509d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
152609d6c965SJuan Quintela         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
152709d6c965SJuan Quintela         if (s->to_dst_file && migration_in_postcopy()) {
1528e1fde0e0SJuan Quintela             migration_rate_set(s->parameters.max_postcopy_bandwidth);
152909d6c965SJuan Quintela         }
153009d6c965SJuan Quintela     }
153109d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
153209d6c965SJuan Quintela         s->parameters.max_cpu_throttle = params->max_cpu_throttle;
153309d6c965SJuan Quintela     }
153409d6c965SJuan Quintela     if (params->has_announce_initial) {
153509d6c965SJuan Quintela         s->parameters.announce_initial = params->announce_initial;
153609d6c965SJuan Quintela     }
153709d6c965SJuan Quintela     if (params->has_announce_max) {
153809d6c965SJuan Quintela         s->parameters.announce_max = params->announce_max;
153909d6c965SJuan Quintela     }
154009d6c965SJuan Quintela     if (params->has_announce_rounds) {
154109d6c965SJuan Quintela         s->parameters.announce_rounds = params->announce_rounds;
154209d6c965SJuan Quintela     }
154309d6c965SJuan Quintela     if (params->has_announce_step) {
154409d6c965SJuan Quintela         s->parameters.announce_step = params->announce_step;
154509d6c965SJuan Quintela     }
154609d6c965SJuan Quintela 
154709d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
154809d6c965SJuan Quintela         qapi_free_BitmapMigrationNodeAliasList(
154909d6c965SJuan Quintela             s->parameters.block_bitmap_mapping);
155009d6c965SJuan Quintela 
155109d6c965SJuan Quintela         s->parameters.has_block_bitmap_mapping = true;
155209d6c965SJuan Quintela         s->parameters.block_bitmap_mapping =
155309d6c965SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
155409d6c965SJuan Quintela                        params->block_bitmap_mapping);
155509d6c965SJuan Quintela     }
15564d807857SHyman Huang(黄勇) 
15574d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period) {
15584d807857SHyman Huang(黄勇)         s->parameters.x_vcpu_dirty_limit_period =
15594d807857SHyman Huang(黄勇)             params->x_vcpu_dirty_limit_period;
15604d807857SHyman Huang(黄勇)     }
156109f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit) {
156209f9ec99SHyman Huang(黄勇)         s->parameters.vcpu_dirty_limit = params->vcpu_dirty_limit;
156309f9ec99SHyman Huang(黄勇)     }
1564eea1e5c9SSteve Sistare 
1565eea1e5c9SSteve Sistare     if (params->has_mode) {
1566eea1e5c9SSteve Sistare         s->parameters.mode = params->mode;
1567eea1e5c9SSteve Sistare     }
1568*5fdbb1dfSHao Xiang 
1569*5fdbb1dfSHao Xiang     if (params->has_zero_page_detection) {
1570*5fdbb1dfSHao Xiang         s->parameters.zero_page_detection = params->zero_page_detection;
1571*5fdbb1dfSHao Xiang     }
157209d6c965SJuan Quintela }
157309d6c965SJuan Quintela 
157409d6c965SJuan Quintela void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
157509d6c965SJuan Quintela {
157609d6c965SJuan Quintela     MigrationParameters tmp;
157709d6c965SJuan Quintela 
157886dec715SPeter Xu     /* TODO Rewrite "" to null instead for all three tls_* parameters */
157909d6c965SJuan Quintela     if (params->tls_creds
158009d6c965SJuan Quintela         && params->tls_creds->type == QTYPE_QNULL) {
158109d6c965SJuan Quintela         qobject_unref(params->tls_creds->u.n);
158209d6c965SJuan Quintela         params->tls_creds->type = QTYPE_QSTRING;
158309d6c965SJuan Quintela         params->tls_creds->u.s = strdup("");
158409d6c965SJuan Quintela     }
158509d6c965SJuan Quintela     if (params->tls_hostname
158609d6c965SJuan Quintela         && params->tls_hostname->type == QTYPE_QNULL) {
158709d6c965SJuan Quintela         qobject_unref(params->tls_hostname->u.n);
158809d6c965SJuan Quintela         params->tls_hostname->type = QTYPE_QSTRING;
158909d6c965SJuan Quintela         params->tls_hostname->u.s = strdup("");
159009d6c965SJuan Quintela     }
159186dec715SPeter Xu     if (params->tls_authz
159286dec715SPeter Xu         && params->tls_authz->type == QTYPE_QNULL) {
159386dec715SPeter Xu         qobject_unref(params->tls_authz->u.n);
159486dec715SPeter Xu         params->tls_authz->type = QTYPE_QSTRING;
159586dec715SPeter Xu         params->tls_authz->u.s = strdup("");
159686dec715SPeter Xu     }
159709d6c965SJuan Quintela 
159809d6c965SJuan Quintela     migrate_params_test_apply(params, &tmp);
159909d6c965SJuan Quintela 
160009d6c965SJuan Quintela     if (!migrate_params_check(&tmp, errp)) {
160109d6c965SJuan Quintela         /* Invalid parameter */
160209d6c965SJuan Quintela         return;
160309d6c965SJuan Quintela     }
160409d6c965SJuan Quintela 
160509d6c965SJuan Quintela     migrate_params_apply(params, errp);
160609d6c965SJuan Quintela }
1607