xref: /openbmc/qemu/migration/options.c (revision 0e195629969125e3a168a7e06e3c49d939c36ead)
11f0776f1SJuan Quintela /*
21f0776f1SJuan Quintela  * QEMU migration capabilities
31f0776f1SJuan Quintela  *
41f0776f1SJuan Quintela  * Copyright (c) 2012-2023 Red Hat Inc
51f0776f1SJuan Quintela  *
61f0776f1SJuan Quintela  * Authors:
71f0776f1SJuan Quintela  *   Orit Wasserman <owasserm@redhat.com>
81f0776f1SJuan Quintela  *   Juan Quintela <quintela@redhat.com>
91f0776f1SJuan Quintela  *
101f0776f1SJuan Quintela  * This work is licensed under the terms of the GNU GPL, version 2 or later.
111f0776f1SJuan Quintela  * See the COPYING file in the top-level directory.
121f0776f1SJuan Quintela  */
131f0776f1SJuan Quintela 
141f0776f1SJuan Quintela #include "qemu/osdep.h"
1509d6c965SJuan Quintela #include "exec/target_page.h"
169c894df3SJuan Quintela #include "qapi/clone-visitor.h"
1777608706SJuan Quintela #include "qapi/error.h"
184d0c6b69SJuan Quintela #include "qapi/qapi-commands-migration.h"
199c894df3SJuan Quintela #include "qapi/qapi-visit-migration.h"
20f80196b7SJuan Quintela #include "qapi/qmp/qerror.h"
2109d6c965SJuan Quintela #include "qapi/qmp/qnull.h"
2277608706SJuan Quintela #include "sysemu/runstate.h"
2309d6c965SJuan Quintela #include "migration/colo.h"
242682c4eeSJuan Quintela #include "migration/misc.h"
251f0776f1SJuan Quintela #include "migration.h"
26e1fde0e0SJuan Quintela #include "migration-stats.h"
2709d6c965SJuan Quintela #include "qemu-file.h"
2877608706SJuan Quintela #include "ram.h"
291f0776f1SJuan Quintela #include "options.h"
30dc623955SHyman Huang(黄勇) #include "sysemu/kvm.h"
311f0776f1SJuan Quintela 
3209d6c965SJuan Quintela /* Maximum migrate downtime set to 2000 seconds */
3309d6c965SJuan Quintela #define MAX_MIGRATE_DOWNTIME_SECONDS 2000
3409d6c965SJuan Quintela #define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000)
3509d6c965SJuan Quintela 
36f9436522SJuan Quintela #define MAX_THROTTLE  (128 << 20)      /* Migration transfer speed throttling */
37f9436522SJuan Quintela 
38f9436522SJuan Quintela /* Time in milliseconds we are allowed to stop the source,
39f9436522SJuan Quintela  * for sending the last part */
40f9436522SJuan Quintela #define DEFAULT_MIGRATE_SET_DOWNTIME 300
41f9436522SJuan Quintela 
42f9436522SJuan Quintela /* Default compression thread count */
43f9436522SJuan Quintela #define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
44f9436522SJuan Quintela /* Default decompression thread count, usually decompression is at
45f9436522SJuan Quintela  * least 4 times as fast as compression.*/
46f9436522SJuan Quintela #define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2
47f9436522SJuan Quintela /*0: means nocompress, 1: best speed, ... 9: best compress ratio */
48f9436522SJuan Quintela #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1
49f9436522SJuan Quintela /* Define default autoconverge cpu throttle migration parameters */
50f9436522SJuan Quintela #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50
51f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
52f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
53f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99
54f9436522SJuan Quintela 
55f9436522SJuan Quintela /* Migration XBZRLE default cache size */
56f9436522SJuan Quintela #define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024)
57f9436522SJuan Quintela 
58f9436522SJuan Quintela /* The delay time (in ms) between two COLO checkpoints */
59f9436522SJuan Quintela #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100)
60f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
61f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE
62f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 9: best compress ratio */
63f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1
64f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 20: best compress ratio */
65f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1
66f9436522SJuan Quintela 
67f9436522SJuan Quintela /* Background transfer rate for postcopy, 0 means unlimited, note
68f9436522SJuan Quintela  * that page requests can still exceed this limit.
69f9436522SJuan Quintela  */
70f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0
71f9436522SJuan Quintela 
72f9436522SJuan Quintela /*
73f9436522SJuan Quintela  * Parameters for self_announce_delay giving a stream of RARP/ARP
74f9436522SJuan Quintela  * packets after migration.
75f9436522SJuan Quintela  */
76f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_INITIAL  50
77f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_MAX     550
78f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS    5
79f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_STEP    100
80f9436522SJuan Quintela 
81f9436522SJuan Quintela #define DEFINE_PROP_MIG_CAP(name, x)             \
82f9436522SJuan Quintela     DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false)
83f9436522SJuan Quintela 
844d807857SHyman Huang(黄勇) #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD     1000    /* milliseconds */
8509f9ec99SHyman Huang(黄勇) #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT            1       /* MB/s */
864d807857SHyman Huang(黄勇) 
87f9436522SJuan Quintela Property migration_properties[] = {
88f9436522SJuan Quintela     DEFINE_PROP_BOOL("store-global-state", MigrationState,
89f9436522SJuan Quintela                      store_global_state, true),
90f9436522SJuan Quintela     DEFINE_PROP_BOOL("send-configuration", MigrationState,
91f9436522SJuan Quintela                      send_configuration, true),
92f9436522SJuan Quintela     DEFINE_PROP_BOOL("send-section-footer", MigrationState,
93f9436522SJuan Quintela                      send_section_footer, true),
94f9436522SJuan Quintela     DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
95f9436522SJuan Quintela                       decompress_error_check, true),
9677c259a4SJuan Quintela     DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
97294e5a40SJuan Quintela                       multifd_flush_after_each_section, false),
98f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
99f9436522SJuan Quintela                       clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
100f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
101f9436522SJuan Quintela                      preempt_pre_7_2, false),
102f9436522SJuan Quintela 
103f9436522SJuan Quintela     /* Migration parameters */
104f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-compress-level", MigrationState,
105f9436522SJuan Quintela                       parameters.compress_level,
106f9436522SJuan Quintela                       DEFAULT_MIGRATE_COMPRESS_LEVEL),
107f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-compress-threads", MigrationState,
108f9436522SJuan Quintela                       parameters.compress_threads,
109f9436522SJuan Quintela                       DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT),
110f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState,
111f9436522SJuan Quintela                       parameters.compress_wait_thread, true),
112f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-decompress-threads", MigrationState,
113f9436522SJuan Quintela                       parameters.decompress_threads,
114f9436522SJuan Quintela                       DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT),
115f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState,
116f9436522SJuan Quintela                       parameters.throttle_trigger_threshold,
117f9436522SJuan Quintela                       DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
118f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState,
119f9436522SJuan Quintela                       parameters.cpu_throttle_initial,
120f9436522SJuan Quintela                       DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL),
121f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState,
122f9436522SJuan Quintela                       parameters.cpu_throttle_increment,
123f9436522SJuan Quintela                       DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
124f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState,
125f9436522SJuan Quintela                       parameters.cpu_throttle_tailslow, false),
126f9436522SJuan Quintela     DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState,
127f9436522SJuan Quintela                       parameters.max_bandwidth, MAX_THROTTLE),
1288b239597SPeter Xu     DEFINE_PROP_SIZE("avail-switchover-bandwidth", MigrationState,
1298b239597SPeter Xu                       parameters.avail_switchover_bandwidth, 0),
130f9436522SJuan Quintela     DEFINE_PROP_UINT64("x-downtime-limit", MigrationState,
131f9436522SJuan Quintela                       parameters.downtime_limit,
132f9436522SJuan Quintela                       DEFAULT_MIGRATE_SET_DOWNTIME),
133f9436522SJuan Quintela     DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
134f9436522SJuan Quintela                       parameters.x_checkpoint_delay,
135f9436522SJuan Quintela                       DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
136f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-channels", MigrationState,
137f9436522SJuan Quintela                       parameters.multifd_channels,
138f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_CHANNELS),
139f9436522SJuan Quintela     DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState,
140f9436522SJuan Quintela                       parameters.multifd_compression,
141f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_COMPRESSION),
142f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState,
143f9436522SJuan Quintela                       parameters.multifd_zlib_level,
144f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL),
145f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState,
146f9436522SJuan Quintela                       parameters.multifd_zstd_level,
147f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL),
148f9436522SJuan Quintela     DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
149f9436522SJuan Quintela                       parameters.xbzrle_cache_size,
150f9436522SJuan Quintela                       DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
151f9436522SJuan Quintela     DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState,
152f9436522SJuan Quintela                       parameters.max_postcopy_bandwidth,
153f9436522SJuan Quintela                       DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH),
154f9436522SJuan Quintela     DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState,
155f9436522SJuan Quintela                       parameters.max_cpu_throttle,
156f9436522SJuan Quintela                       DEFAULT_MIGRATE_MAX_CPU_THROTTLE),
157f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-initial", MigrationState,
158f9436522SJuan Quintela                       parameters.announce_initial,
159f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_INITIAL),
160f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-max", MigrationState,
161f9436522SJuan Quintela                       parameters.announce_max,
162f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_MAX),
163f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-rounds", MigrationState,
164f9436522SJuan Quintela                       parameters.announce_rounds,
165f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_ROUNDS),
166f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-step", MigrationState,
167f9436522SJuan Quintela                       parameters.announce_step,
168f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_STEP),
169f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds),
170f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname),
171f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz),
1724d807857SHyman Huang(黄勇)     DEFINE_PROP_UINT64("x-vcpu-dirty-limit-period", MigrationState,
1734d807857SHyman Huang(黄勇)                        parameters.x_vcpu_dirty_limit_period,
1744d807857SHyman Huang(黄勇)                        DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD),
17509f9ec99SHyman Huang(黄勇)     DEFINE_PROP_UINT64("vcpu-dirty-limit", MigrationState,
17609f9ec99SHyman Huang(黄勇)                        parameters.vcpu_dirty_limit,
17709f9ec99SHyman Huang(黄勇)                        DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT),
178f9436522SJuan Quintela 
179f9436522SJuan Quintela     /* Migration capabilities */
180f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
181f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL),
182f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE),
183f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS),
184f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS),
185f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS),
186f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM),
187f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-postcopy-preempt",
188f9436522SJuan Quintela                         MIGRATION_CAPABILITY_POSTCOPY_PREEMPT),
189f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO),
190f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
191f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
192f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH),
193f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
194f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-background-snapshot",
195f9436522SJuan Quintela             MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
196f9436522SJuan Quintela #ifdef CONFIG_LINUX
197f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-zero-copy-send",
198f9436522SJuan Quintela             MIGRATION_CAPABILITY_ZERO_COPY_SEND),
199f9436522SJuan Quintela #endif
2006574232fSAvihai Horon     DEFINE_PROP_MIG_CAP("x-switchover-ack",
2016574232fSAvihai Horon                         MIGRATION_CAPABILITY_SWITCHOVER_ACK),
202dc623955SHyman Huang(黄勇)     DEFINE_PROP_MIG_CAP("x-dirty-limit", MIGRATION_CAPABILITY_DIRTY_LIMIT),
203f9436522SJuan Quintela     DEFINE_PROP_END_OF_LIST(),
204f9436522SJuan Quintela };
205f9436522SJuan Quintela 
2061f0776f1SJuan Quintela bool migrate_auto_converge(void)
2071f0776f1SJuan Quintela {
2088f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2091f0776f1SJuan Quintela 
2101f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
2111f0776f1SJuan Quintela }
2121f0776f1SJuan Quintela 
2131f0776f1SJuan Quintela bool migrate_background_snapshot(void)
2141f0776f1SJuan Quintela {
2158f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2161f0776f1SJuan Quintela 
2171f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
2181f0776f1SJuan Quintela }
2191f0776f1SJuan Quintela 
2209d4b1e5fSJuan Quintela bool migrate_block(void)
2219d4b1e5fSJuan Quintela {
2228f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2239d4b1e5fSJuan Quintela 
2249d4b1e5fSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BLOCK];
2259d4b1e5fSJuan Quintela }
2269d4b1e5fSJuan Quintela 
2275e804644SJuan Quintela bool migrate_colo(void)
2285e804644SJuan Quintela {
2295e804644SJuan Quintela     MigrationState *s = migrate_get_current();
2308f9c5327SJuan Quintela 
2315e804644SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
2325e804644SJuan Quintela }
2335e804644SJuan Quintela 
234a7a94d14SJuan Quintela bool migrate_compress(void)
235a7a94d14SJuan Quintela {
2368f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
237a7a94d14SJuan Quintela 
238a7a94d14SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
239a7a94d14SJuan Quintela }
240a7a94d14SJuan Quintela 
2411f0776f1SJuan Quintela bool migrate_dirty_bitmaps(void)
2421f0776f1SJuan Quintela {
2438f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2441f0776f1SJuan Quintela 
2451f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
2461f0776f1SJuan Quintela }
2471f0776f1SJuan Quintela 
248dc623955SHyman Huang(黄勇) bool migrate_dirty_limit(void)
249dc623955SHyman Huang(黄勇) {
250dc623955SHyman Huang(黄勇)     MigrationState *s = migrate_get_current();
251dc623955SHyman Huang(黄勇) 
252dc623955SHyman Huang(黄勇)     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_LIMIT];
253dc623955SHyman Huang(黄勇) }
254dc623955SHyman Huang(黄勇) 
255b890902cSJuan Quintela bool migrate_events(void)
256b890902cSJuan Quintela {
2578f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
258b890902cSJuan Quintela 
259b890902cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
260b890902cSJuan Quintela }
261b890902cSJuan Quintela 
2621f0776f1SJuan Quintela bool migrate_ignore_shared(void)
2631f0776f1SJuan Quintela {
2648f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2651f0776f1SJuan Quintela 
2661f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
2671f0776f1SJuan Quintela }
2681f0776f1SJuan Quintela 
2691f0776f1SJuan Quintela bool migrate_late_block_activate(void)
2701f0776f1SJuan Quintela {
2718f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2721f0776f1SJuan Quintela 
2731f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
2741f0776f1SJuan Quintela }
2751f0776f1SJuan Quintela 
27651b07548SJuan Quintela bool migrate_multifd(void)
27751b07548SJuan Quintela {
2788f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
27951b07548SJuan Quintela 
28051b07548SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
28151b07548SJuan Quintela }
28251b07548SJuan Quintela 
2831f0776f1SJuan Quintela bool migrate_pause_before_switchover(void)
2841f0776f1SJuan Quintela {
2858f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2861f0776f1SJuan Quintela 
2871f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
2881f0776f1SJuan Quintela }
2891f0776f1SJuan Quintela 
2901f0776f1SJuan Quintela bool migrate_postcopy_blocktime(void)
2911f0776f1SJuan Quintela {
2928f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2931f0776f1SJuan Quintela 
2941f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
2951f0776f1SJuan Quintela }
2961f0776f1SJuan Quintela 
2971f0776f1SJuan Quintela bool migrate_postcopy_preempt(void)
2981f0776f1SJuan Quintela {
2998f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3001f0776f1SJuan Quintela 
3011f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
3021f0776f1SJuan Quintela }
3031f0776f1SJuan Quintela 
3041f0776f1SJuan Quintela bool migrate_postcopy_ram(void)
3051f0776f1SJuan Quintela {
3068f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3071f0776f1SJuan Quintela 
3081f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
3091f0776f1SJuan Quintela }
3101f0776f1SJuan Quintela 
31117cba690SJuan Quintela bool migrate_rdma_pin_all(void)
31217cba690SJuan Quintela {
31317cba690SJuan Quintela     MigrationState *s = migrate_get_current();
31417cba690SJuan Quintela 
31517cba690SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
31617cba690SJuan Quintela }
31717cba690SJuan Quintela 
3181f0776f1SJuan Quintela bool migrate_release_ram(void)
3191f0776f1SJuan Quintela {
3208f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3211f0776f1SJuan Quintela 
3221f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
3231f0776f1SJuan Quintela }
3241f0776f1SJuan Quintela 
32538ad1110SJuan Quintela bool migrate_return_path(void)
32638ad1110SJuan Quintela {
3278f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
32838ad1110SJuan Quintela 
32938ad1110SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
33038ad1110SJuan Quintela }
33138ad1110SJuan Quintela 
3326574232fSAvihai Horon bool migrate_switchover_ack(void)
3336574232fSAvihai Horon {
3346574232fSAvihai Horon     MigrationState *s = migrate_get_current();
3356574232fSAvihai Horon 
3366574232fSAvihai Horon     return s->capabilities[MIGRATION_CAPABILITY_SWITCHOVER_ACK];
3376574232fSAvihai Horon }
3386574232fSAvihai Horon 
3391f0776f1SJuan Quintela bool migrate_validate_uuid(void)
3401f0776f1SJuan Quintela {
3418f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3421f0776f1SJuan Quintela 
3431f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
3441f0776f1SJuan Quintela }
3451f0776f1SJuan Quintela 
34687dca0c9SJuan Quintela bool migrate_xbzrle(void)
34787dca0c9SJuan Quintela {
3488f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
34987dca0c9SJuan Quintela 
35087dca0c9SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
35187dca0c9SJuan Quintela }
35287dca0c9SJuan Quintela 
3531f0776f1SJuan Quintela bool migrate_zero_blocks(void)
3541f0776f1SJuan Quintela {
3558f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3561f0776f1SJuan Quintela 
3571f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
3581f0776f1SJuan Quintela }
359b4bc342cSJuan Quintela 
360b4bc342cSJuan Quintela bool migrate_zero_copy_send(void)
361b4bc342cSJuan Quintela {
3628f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
363b4bc342cSJuan Quintela 
364b4bc342cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
365b4bc342cSJuan Quintela }
366f774fde5SJuan Quintela 
367f774fde5SJuan Quintela /* pseudo capabilities */
368f774fde5SJuan Quintela 
36977c259a4SJuan Quintela bool migrate_multifd_flush_after_each_section(void)
37077c259a4SJuan Quintela {
37177c259a4SJuan Quintela     MigrationState *s = migrate_get_current();
37277c259a4SJuan Quintela 
373294e5a40SJuan Quintela     return s->multifd_flush_after_each_section;
37477c259a4SJuan Quintela }
37577c259a4SJuan Quintela 
376f774fde5SJuan Quintela bool migrate_postcopy(void)
377f774fde5SJuan Quintela {
378f774fde5SJuan Quintela     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
379f774fde5SJuan Quintela }
380f774fde5SJuan Quintela 
38127fd25b0SJuan Quintela bool migrate_rdma(void)
38227fd25b0SJuan Quintela {
38327fd25b0SJuan Quintela     MigrationState *s = migrate_get_current();
38427fd25b0SJuan Quintela 
38527fd25b0SJuan Quintela     return s->rdma_migration;
38627fd25b0SJuan Quintela }
38727fd25b0SJuan Quintela 
38810d4703bSJuan Quintela bool migrate_tls(void)
38910d4703bSJuan Quintela {
3908f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
39110d4703bSJuan Quintela 
39210d4703bSJuan Quintela     return s->parameters.tls_creds && *s->parameters.tls_creds;
39310d4703bSJuan Quintela }
39410d4703bSJuan Quintela 
39577608706SJuan Quintela typedef enum WriteTrackingSupport {
39677608706SJuan Quintela     WT_SUPPORT_UNKNOWN = 0,
39777608706SJuan Quintela     WT_SUPPORT_ABSENT,
39877608706SJuan Quintela     WT_SUPPORT_AVAILABLE,
39977608706SJuan Quintela     WT_SUPPORT_COMPATIBLE
40077608706SJuan Quintela } WriteTrackingSupport;
40177608706SJuan Quintela 
40277608706SJuan Quintela static
40377608706SJuan Quintela WriteTrackingSupport migrate_query_write_tracking(void)
40477608706SJuan Quintela {
40577608706SJuan Quintela     /* Check if kernel supports required UFFD features */
40677608706SJuan Quintela     if (!ram_write_tracking_available()) {
40777608706SJuan Quintela         return WT_SUPPORT_ABSENT;
40877608706SJuan Quintela     }
40977608706SJuan Quintela     /*
41077608706SJuan Quintela      * Check if current memory configuration is
41177608706SJuan Quintela      * compatible with required UFFD features.
41277608706SJuan Quintela      */
41377608706SJuan Quintela     if (!ram_write_tracking_compatible()) {
41477608706SJuan Quintela         return WT_SUPPORT_AVAILABLE;
41577608706SJuan Quintela     }
41677608706SJuan Quintela 
41777608706SJuan Quintela     return WT_SUPPORT_COMPATIBLE;
41877608706SJuan Quintela }
41977608706SJuan Quintela 
42077608706SJuan Quintela /* Migration capabilities set */
42177608706SJuan Quintela struct MigrateCapsSet {
42277608706SJuan Quintela     int size;                       /* Capability set size */
42377608706SJuan Quintela     MigrationCapability caps[];     /* Variadic array of capabilities */
42477608706SJuan Quintela };
42577608706SJuan Quintela typedef struct MigrateCapsSet MigrateCapsSet;
42677608706SJuan Quintela 
42777608706SJuan Quintela /* Define and initialize MigrateCapsSet */
42877608706SJuan Quintela #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
42977608706SJuan Quintela     MigrateCapsSet _name = {    \
43077608706SJuan Quintela         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
43177608706SJuan Quintela         .caps = { __VA_ARGS__ } \
43277608706SJuan Quintela     }
43377608706SJuan Quintela 
43477608706SJuan Quintela /* Background-snapshot compatibility check list */
43577608706SJuan Quintela static const
43677608706SJuan Quintela INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
43777608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_RAM,
43877608706SJuan Quintela     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
43977608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
44077608706SJuan Quintela     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
44177608706SJuan Quintela     MIGRATION_CAPABILITY_RETURN_PATH,
44277608706SJuan Quintela     MIGRATION_CAPABILITY_MULTIFD,
44377608706SJuan Quintela     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
44477608706SJuan Quintela     MIGRATION_CAPABILITY_AUTO_CONVERGE,
44577608706SJuan Quintela     MIGRATION_CAPABILITY_RELEASE_RAM,
44677608706SJuan Quintela     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
44777608706SJuan Quintela     MIGRATION_CAPABILITY_COMPRESS,
44877608706SJuan Quintela     MIGRATION_CAPABILITY_XBZRLE,
44977608706SJuan Quintela     MIGRATION_CAPABILITY_X_COLO,
45077608706SJuan Quintela     MIGRATION_CAPABILITY_VALIDATE_UUID,
45177608706SJuan Quintela     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
45277608706SJuan Quintela 
45382137e6cSWei Wang static bool migrate_incoming_started(void)
45482137e6cSWei Wang {
45582137e6cSWei Wang     return !!migration_incoming_get_current()->transport_data;
45682137e6cSWei Wang }
45782137e6cSWei Wang 
45877608706SJuan Quintela /**
45977608706SJuan Quintela  * @migration_caps_check - check capability compatibility
46077608706SJuan Quintela  *
46177608706SJuan Quintela  * @old_caps: old capability list
46277608706SJuan Quintela  * @new_caps: new capability list
46377608706SJuan Quintela  * @errp: set *errp if the check failed, with reason
46477608706SJuan Quintela  *
46577608706SJuan Quintela  * Returns true if check passed, otherwise false.
46677608706SJuan Quintela  */
46777608706SJuan Quintela bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
46877608706SJuan Quintela {
46977608706SJuan Quintela     MigrationIncomingState *mis = migration_incoming_get_current();
47077608706SJuan Quintela 
47174c38cf7SPeter Xu     ERRP_GUARD();
47277608706SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
47377608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BLOCK]) {
47477608706SJuan Quintela         error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) "
47577608706SJuan Quintela                    "block migration");
47677608706SJuan Quintela         error_append_hint(errp, "Use drive_mirror+NBD instead.\n");
47777608706SJuan Quintela         return false;
47877608706SJuan Quintela     }
47977608706SJuan Quintela #endif
48077608706SJuan Quintela 
48177608706SJuan Quintela #ifndef CONFIG_REPLICATION
48277608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
48377608706SJuan Quintela         error_setg(errp, "QEMU compiled without replication module"
48477608706SJuan Quintela                    " can't enable COLO");
48577608706SJuan Quintela         error_append_hint(errp, "Please enable replication before COLO.\n");
48677608706SJuan Quintela         return false;
48777608706SJuan Quintela     }
48877608706SJuan Quintela #endif
48977608706SJuan Quintela 
49077608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
49177608706SJuan Quintela         /* This check is reasonably expensive, so only when it's being
49277608706SJuan Quintela          * set the first time, also it's only the destination that needs
49377608706SJuan Quintela          * special support.
49477608706SJuan Quintela          */
49577608706SJuan Quintela         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
49677608706SJuan Quintela             runstate_check(RUN_STATE_INMIGRATE) &&
49774c38cf7SPeter Xu             !postcopy_ram_supported_by_host(mis, errp)) {
49874c38cf7SPeter Xu             error_prepend(errp, "Postcopy is not supported: ");
49977608706SJuan Quintela             return false;
50077608706SJuan Quintela         }
50177608706SJuan Quintela 
50277608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
50377608706SJuan Quintela             error_setg(errp, "Postcopy is not compatible with ignore-shared");
50477608706SJuan Quintela             return false;
50577608706SJuan Quintela         }
506b405dfffSLeonardo Bras 
507b405dfffSLeonardo Bras         if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
508b405dfffSLeonardo Bras             error_setg(errp, "Postcopy is not yet compatible with multifd");
509b405dfffSLeonardo Bras             return false;
510b405dfffSLeonardo Bras         }
51177608706SJuan Quintela     }
51277608706SJuan Quintela 
51377608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
51477608706SJuan Quintela         WriteTrackingSupport wt_support;
51577608706SJuan Quintela         int idx;
51677608706SJuan Quintela         /*
51777608706SJuan Quintela          * Check if 'background-snapshot' capability is supported by
51877608706SJuan Quintela          * host kernel and compatible with guest memory configuration.
51977608706SJuan Quintela          */
52077608706SJuan Quintela         wt_support = migrate_query_write_tracking();
52177608706SJuan Quintela         if (wt_support < WT_SUPPORT_AVAILABLE) {
52277608706SJuan Quintela             error_setg(errp, "Background-snapshot is not supported by host kernel");
52377608706SJuan Quintela             return false;
52477608706SJuan Quintela         }
52577608706SJuan Quintela         if (wt_support < WT_SUPPORT_COMPATIBLE) {
52677608706SJuan Quintela             error_setg(errp, "Background-snapshot is not compatible "
52777608706SJuan Quintela                     "with guest memory configuration");
52877608706SJuan Quintela             return false;
52977608706SJuan Quintela         }
53077608706SJuan Quintela 
53177608706SJuan Quintela         /*
53277608706SJuan Quintela          * Check if there are any migration capabilities
53377608706SJuan Quintela          * incompatible with 'background-snapshot'.
53477608706SJuan Quintela          */
53577608706SJuan Quintela         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
53677608706SJuan Quintela             int incomp_cap = check_caps_background_snapshot.caps[idx];
53777608706SJuan Quintela             if (new_caps[incomp_cap]) {
53877608706SJuan Quintela                 error_setg(errp,
53977608706SJuan Quintela                         "Background-snapshot is not compatible with %s",
54077608706SJuan Quintela                         MigrationCapability_str(incomp_cap));
54177608706SJuan Quintela                 return false;
54277608706SJuan Quintela             }
54377608706SJuan Quintela         }
54477608706SJuan Quintela     }
54577608706SJuan Quintela 
54677608706SJuan Quintela #ifdef CONFIG_LINUX
54777608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
54877608706SJuan Quintela         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
54977608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_COMPRESS] ||
55077608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
55177608706SJuan Quintela          migrate_multifd_compression() ||
55210d4703bSJuan Quintela          migrate_tls())) {
55377608706SJuan Quintela         error_setg(errp,
55477608706SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
55577608706SJuan Quintela         return false;
55677608706SJuan Quintela     }
55777608706SJuan Quintela #else
55877608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
55977608706SJuan Quintela         error_setg(errp,
56077608706SJuan Quintela                    "Zero copy currently only available on Linux");
56177608706SJuan Quintela         return false;
56277608706SJuan Quintela     }
56377608706SJuan Quintela #endif
56477608706SJuan Quintela 
56577608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
56677608706SJuan Quintela         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
56777608706SJuan Quintela             error_setg(errp, "Postcopy preempt requires postcopy-ram");
56877608706SJuan Quintela             return false;
56977608706SJuan Quintela         }
57077608706SJuan Quintela 
57177608706SJuan Quintela         /*
57277608706SJuan Quintela          * Preempt mode requires urgent pages to be sent in separate
57377608706SJuan Quintela          * channel, OTOH compression logic will disorder all pages into
57477608706SJuan Quintela          * different compression channels, which is not compatible with the
57577608706SJuan Quintela          * preempt assumptions on channel assignments.
57677608706SJuan Quintela          */
57777608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
57877608706SJuan Quintela             error_setg(errp, "Postcopy preempt not compatible with compress");
57977608706SJuan Quintela             return false;
58077608706SJuan Quintela         }
58182137e6cSWei Wang 
58282137e6cSWei Wang         if (migrate_incoming_started()) {
58382137e6cSWei Wang             error_setg(errp,
58482137e6cSWei Wang                        "Postcopy preempt must be set before incoming starts");
58582137e6cSWei Wang             return false;
58682137e6cSWei Wang         }
58777608706SJuan Quintela     }
58877608706SJuan Quintela 
58977608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
59077608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
59177608706SJuan Quintela             error_setg(errp, "Multifd is not compatible with compress");
59277608706SJuan Quintela             return false;
59377608706SJuan Quintela         }
59482137e6cSWei Wang         if (migrate_incoming_started()) {
59582137e6cSWei Wang             error_setg(errp, "Multifd must be set before incoming starts");
59682137e6cSWei Wang             return false;
59782137e6cSWei Wang         }
59877608706SJuan Quintela     }
59977608706SJuan Quintela 
6006574232fSAvihai Horon     if (new_caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK]) {
6016574232fSAvihai Horon         if (!new_caps[MIGRATION_CAPABILITY_RETURN_PATH]) {
6026574232fSAvihai Horon             error_setg(errp, "Capability 'switchover-ack' requires capability "
6036574232fSAvihai Horon                              "'return-path'");
6046574232fSAvihai Horon             return false;
6056574232fSAvihai Horon         }
6066574232fSAvihai Horon     }
607dc623955SHyman Huang(黄勇)     if (new_caps[MIGRATION_CAPABILITY_DIRTY_LIMIT]) {
608dc623955SHyman Huang(黄勇)         if (new_caps[MIGRATION_CAPABILITY_AUTO_CONVERGE]) {
609dc623955SHyman Huang(黄勇)             error_setg(errp, "dirty-limit conflicts with auto-converge"
610dc623955SHyman Huang(黄勇)                        " either of then available currently");
611dc623955SHyman Huang(黄勇)             return false;
612dc623955SHyman Huang(黄勇)         }
613dc623955SHyman Huang(黄勇) 
614dc623955SHyman Huang(黄勇)         if (!kvm_enabled() || !kvm_dirty_ring_enabled()) {
615dc623955SHyman Huang(黄勇)             error_setg(errp, "dirty-limit requires KVM with accelerator"
616dc623955SHyman Huang(黄勇)                    " property 'dirty-ring-size' set");
617dc623955SHyman Huang(黄勇)             return false;
618dc623955SHyman Huang(黄勇)         }
619dc623955SHyman Huang(黄勇)     }
6206574232fSAvihai Horon 
621d869f629SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
622d869f629SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
623d869f629SJuan Quintela             error_setg(errp, "Multifd is not compatible with xbzrle");
624d869f629SJuan Quintela             return false;
625d869f629SJuan Quintela         }
626d869f629SJuan Quintela     }
627d869f629SJuan Quintela 
628*0e195629SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
629*0e195629SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
630*0e195629SJuan Quintela             error_setg(errp, "Compression is not compatible with xbzrle");
631*0e195629SJuan Quintela             return false;
632*0e195629SJuan Quintela         }
633*0e195629SJuan Quintela     }
634*0e195629SJuan Quintela 
63577608706SJuan Quintela     return true;
63677608706SJuan Quintela }
6374d0c6b69SJuan Quintela 
638f80196b7SJuan Quintela bool migrate_cap_set(int cap, bool value, Error **errp)
639f80196b7SJuan Quintela {
640f80196b7SJuan Quintela     MigrationState *s = migrate_get_current();
641f80196b7SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
642f80196b7SJuan Quintela 
643f80196b7SJuan Quintela     if (migration_is_running(s->state)) {
644f80196b7SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
645f80196b7SJuan Quintela         return false;
646f80196b7SJuan Quintela     }
647f80196b7SJuan Quintela 
648f80196b7SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
649f80196b7SJuan Quintela     new_caps[cap] = value;
650f80196b7SJuan Quintela 
651f80196b7SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
652f80196b7SJuan Quintela         return false;
653f80196b7SJuan Quintela     }
654f80196b7SJuan Quintela     s->capabilities[cap] = value;
655f80196b7SJuan Quintela     return true;
656f80196b7SJuan Quintela }
657f80196b7SJuan Quintela 
6584d0c6b69SJuan Quintela MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
6594d0c6b69SJuan Quintela {
6604d0c6b69SJuan Quintela     MigrationCapabilityStatusList *head = NULL, **tail = &head;
6614d0c6b69SJuan Quintela     MigrationCapabilityStatus *caps;
6624d0c6b69SJuan Quintela     MigrationState *s = migrate_get_current();
6634d0c6b69SJuan Quintela     int i;
6644d0c6b69SJuan Quintela 
6654d0c6b69SJuan Quintela     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
6664d0c6b69SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
6674d0c6b69SJuan Quintela         if (i == MIGRATION_CAPABILITY_BLOCK) {
6684d0c6b69SJuan Quintela             continue;
6694d0c6b69SJuan Quintela         }
6704d0c6b69SJuan Quintela #endif
6714d0c6b69SJuan Quintela         caps = g_malloc0(sizeof(*caps));
6724d0c6b69SJuan Quintela         caps->capability = i;
6734d0c6b69SJuan Quintela         caps->state = s->capabilities[i];
6744d0c6b69SJuan Quintela         QAPI_LIST_APPEND(tail, caps);
6754d0c6b69SJuan Quintela     }
6764d0c6b69SJuan Quintela 
6774d0c6b69SJuan Quintela     return head;
6784d0c6b69SJuan Quintela }
67945c1de13SJuan Quintela 
68045c1de13SJuan Quintela void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
68145c1de13SJuan Quintela                                   Error **errp)
68245c1de13SJuan Quintela {
68345c1de13SJuan Quintela     MigrationState *s = migrate_get_current();
68445c1de13SJuan Quintela     MigrationCapabilityStatusList *cap;
68545c1de13SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
68645c1de13SJuan Quintela 
687d70178a8SVladimir Sementsov-Ogievskiy     if (migration_is_running(s->state) || migration_in_colo_state()) {
68845c1de13SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
68945c1de13SJuan Quintela         return;
69045c1de13SJuan Quintela     }
69145c1de13SJuan Quintela 
69245c1de13SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
69345c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
69445c1de13SJuan Quintela         new_caps[cap->value->capability] = cap->value->state;
69545c1de13SJuan Quintela     }
69645c1de13SJuan Quintela 
69745c1de13SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
69845c1de13SJuan Quintela         return;
69945c1de13SJuan Quintela     }
70045c1de13SJuan Quintela 
70145c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
70245c1de13SJuan Quintela         s->capabilities[cap->value->capability] = cap->value->state;
70345c1de13SJuan Quintela     }
70445c1de13SJuan Quintela }
7051dfc4b9eSJuan Quintela 
7061dfc4b9eSJuan Quintela /* parameters */
7071dfc4b9eSJuan Quintela 
708b804b35bSJuan Quintela const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
709b804b35bSJuan Quintela {
710b804b35bSJuan Quintela     MigrationState *s = migrate_get_current();
711b804b35bSJuan Quintela 
712b804b35bSJuan Quintela     return s->parameters.block_bitmap_mapping;
713b804b35bSJuan Quintela }
714b804b35bSJuan Quintela 
7153cba22c9SJuan Quintela bool migrate_has_block_bitmap_mapping(void)
7163cba22c9SJuan Quintela {
7173cba22c9SJuan Quintela     MigrationState *s = migrate_get_current();
7183cba22c9SJuan Quintela 
7193cba22c9SJuan Quintela     return s->parameters.has_block_bitmap_mapping;
7203cba22c9SJuan Quintela }
7213cba22c9SJuan Quintela 
7226f8be708SJuan Quintela bool migrate_block_incremental(void)
7236f8be708SJuan Quintela {
7248f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7256f8be708SJuan Quintela 
7266f8be708SJuan Quintela     return s->parameters.block_incremental;
7276f8be708SJuan Quintela }
7286f8be708SJuan Quintela 
729f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void)
730f94a858fSJuan Quintela {
7318f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
732f94a858fSJuan Quintela 
733f94a858fSJuan Quintela     return s->parameters.x_checkpoint_delay;
734f94a858fSJuan Quintela }
735f94a858fSJuan Quintela 
7361dfc4b9eSJuan Quintela int migrate_compress_level(void)
7371dfc4b9eSJuan Quintela {
7388f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7391dfc4b9eSJuan Quintela 
7401dfc4b9eSJuan Quintela     return s->parameters.compress_level;
7411dfc4b9eSJuan Quintela }
7421dfc4b9eSJuan Quintela 
7431dfc4b9eSJuan Quintela int migrate_compress_threads(void)
7441dfc4b9eSJuan Quintela {
7458f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7461dfc4b9eSJuan Quintela 
7471dfc4b9eSJuan Quintela     return s->parameters.compress_threads;
7481dfc4b9eSJuan Quintela }
7491dfc4b9eSJuan Quintela 
7501dfc4b9eSJuan Quintela int migrate_compress_wait_thread(void)
7511dfc4b9eSJuan Quintela {
7528f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7531dfc4b9eSJuan Quintela 
7541dfc4b9eSJuan Quintela     return s->parameters.compress_wait_thread;
7551dfc4b9eSJuan Quintela }
7561dfc4b9eSJuan Quintela 
7579605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void)
7589605c2acSJuan Quintela {
7598f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7609605c2acSJuan Quintela 
7619605c2acSJuan Quintela     return s->parameters.cpu_throttle_increment;
7629605c2acSJuan Quintela }
7639605c2acSJuan Quintela 
7642a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void)
7652a8ec380SJuan Quintela {
7668f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7672a8ec380SJuan Quintela 
7682a8ec380SJuan Quintela     return s->parameters.cpu_throttle_initial;
7692a8ec380SJuan Quintela }
7702a8ec380SJuan Quintela 
771873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void)
772873f674cSJuan Quintela {
7738f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
774873f674cSJuan Quintela 
775873f674cSJuan Quintela     return s->parameters.cpu_throttle_tailslow;
776873f674cSJuan Quintela }
777873f674cSJuan Quintela 
7781dfc4b9eSJuan Quintela int migrate_decompress_threads(void)
7791dfc4b9eSJuan Quintela {
7808f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7811dfc4b9eSJuan Quintela 
7821dfc4b9eSJuan Quintela     return s->parameters.decompress_threads;
7831dfc4b9eSJuan Quintela }
7841dfc4b9eSJuan Quintela 
785f5da8ba4SJuan Quintela uint64_t migrate_downtime_limit(void)
786f5da8ba4SJuan Quintela {
787f5da8ba4SJuan Quintela     MigrationState *s = migrate_get_current();
788f5da8ba4SJuan Quintela 
789f5da8ba4SJuan Quintela     return s->parameters.downtime_limit;
790f5da8ba4SJuan Quintela }
791f5da8ba4SJuan Quintela 
79224155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void)
79324155bd0SJuan Quintela {
7948f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
79524155bd0SJuan Quintela 
79624155bd0SJuan Quintela     return s->parameters.max_cpu_throttle;
79724155bd0SJuan Quintela }
79824155bd0SJuan Quintela 
7999c894df3SJuan Quintela uint64_t migrate_max_bandwidth(void)
8009c894df3SJuan Quintela {
8018f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8029c894df3SJuan Quintela 
8039c894df3SJuan Quintela     return s->parameters.max_bandwidth;
8049c894df3SJuan Quintela }
8059c894df3SJuan Quintela 
8068b239597SPeter Xu uint64_t migrate_avail_switchover_bandwidth(void)
8078b239597SPeter Xu {
8088b239597SPeter Xu     MigrationState *s = migrate_get_current();
8098b239597SPeter Xu 
8108b239597SPeter Xu     return s->parameters.avail_switchover_bandwidth;
8118b239597SPeter Xu }
8128b239597SPeter Xu 
81352033349SJuan Quintela uint64_t migrate_max_postcopy_bandwidth(void)
8141dfc4b9eSJuan Quintela {
8158f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8161dfc4b9eSJuan Quintela 
8171dfc4b9eSJuan Quintela     return s->parameters.max_postcopy_bandwidth;
8181dfc4b9eSJuan Quintela }
8191dfc4b9eSJuan Quintela 
8201dfc4b9eSJuan Quintela int migrate_multifd_channels(void)
8211dfc4b9eSJuan Quintela {
8228f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8231dfc4b9eSJuan Quintela 
8241dfc4b9eSJuan Quintela     return s->parameters.multifd_channels;
8251dfc4b9eSJuan Quintela }
8261dfc4b9eSJuan Quintela 
8271dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void)
8281dfc4b9eSJuan Quintela {
8298f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8301dfc4b9eSJuan Quintela 
8311dfc4b9eSJuan Quintela     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
8321dfc4b9eSJuan Quintela     return s->parameters.multifd_compression;
8331dfc4b9eSJuan Quintela }
8341dfc4b9eSJuan Quintela 
8351dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void)
8361dfc4b9eSJuan Quintela {
8378f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8381dfc4b9eSJuan Quintela 
8391dfc4b9eSJuan Quintela     return s->parameters.multifd_zlib_level;
8401dfc4b9eSJuan Quintela }
8411dfc4b9eSJuan Quintela 
8421dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void)
8431dfc4b9eSJuan Quintela {
8448f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8451dfc4b9eSJuan Quintela 
8461dfc4b9eSJuan Quintela     return s->parameters.multifd_zstd_level;
8471dfc4b9eSJuan Quintela }
8481dfc4b9eSJuan Quintela 
8496499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void)
8506499efdbSJuan Quintela {
8518f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8526499efdbSJuan Quintela 
8536499efdbSJuan Quintela     return s->parameters.throttle_trigger_threshold;
8546499efdbSJuan Quintela }
8556499efdbSJuan Quintela 
8562eb0308bSJuan Quintela const char *migrate_tls_authz(void)
8572eb0308bSJuan Quintela {
8582eb0308bSJuan Quintela     MigrationState *s = migrate_get_current();
8592eb0308bSJuan Quintela 
8602eb0308bSJuan Quintela     return s->parameters.tls_authz;
8612eb0308bSJuan Quintela }
8622eb0308bSJuan Quintela 
863d5c3e195SJuan Quintela const char *migrate_tls_creds(void)
864d5c3e195SJuan Quintela {
865d5c3e195SJuan Quintela     MigrationState *s = migrate_get_current();
866d5c3e195SJuan Quintela 
867d5c3e195SJuan Quintela     return s->parameters.tls_creds;
868d5c3e195SJuan Quintela }
869d5c3e195SJuan Quintela 
8701f2f366cSJuan Quintela const char *migrate_tls_hostname(void)
8711f2f366cSJuan Quintela {
8721f2f366cSJuan Quintela     MigrationState *s = migrate_get_current();
8731f2f366cSJuan Quintela 
8741f2f366cSJuan Quintela     return s->parameters.tls_hostname;
8751f2f366cSJuan Quintela }
8761f2f366cSJuan Quintela 
8771dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void)
8781dfc4b9eSJuan Quintela {
8798f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8801dfc4b9eSJuan Quintela 
8811dfc4b9eSJuan Quintela     return s->parameters.xbzrle_cache_size;
8821dfc4b9eSJuan Quintela }
8832682c4eeSJuan Quintela 
88487c22901SJuan Quintela /* parameter setters */
88587c22901SJuan Quintela 
88687c22901SJuan Quintela void migrate_set_block_incremental(bool value)
88787c22901SJuan Quintela {
88887c22901SJuan Quintela     MigrationState *s = migrate_get_current();
88987c22901SJuan Quintela 
89087c22901SJuan Quintela     s->parameters.block_incremental = value;
89187c22901SJuan Quintela }
89287c22901SJuan Quintela 
8932682c4eeSJuan Quintela /* parameters helpers */
8942682c4eeSJuan Quintela 
895b1a87956SJuan Quintela void block_cleanup_parameters(void)
896b7b73122SJuan Quintela {
897b1a87956SJuan Quintela     MigrationState *s = migrate_get_current();
898b1a87956SJuan Quintela 
899b7b73122SJuan Quintela     if (s->must_remove_block_options) {
900b7b73122SJuan Quintela         /* setting to false can never fail */
901b7b73122SJuan Quintela         migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort);
902b7b73122SJuan Quintela         migrate_set_block_incremental(false);
903b7b73122SJuan Quintela         s->must_remove_block_options = false;
904b7b73122SJuan Quintela     }
905b7b73122SJuan Quintela }
906b7b73122SJuan Quintela 
9072682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void)
9082682c4eeSJuan Quintela {
9092682c4eeSJuan Quintela     static AnnounceParameters ap;
9102682c4eeSJuan Quintela 
9112682c4eeSJuan Quintela     MigrationState *s = migrate_get_current();
9122682c4eeSJuan Quintela 
9132682c4eeSJuan Quintela     ap.initial = s->parameters.announce_initial;
9142682c4eeSJuan Quintela     ap.max = s->parameters.announce_max;
9152682c4eeSJuan Quintela     ap.rounds = s->parameters.announce_rounds;
9162682c4eeSJuan Quintela     ap.step = s->parameters.announce_step;
9172682c4eeSJuan Quintela 
9182682c4eeSJuan Quintela     return &ap;
9192682c4eeSJuan Quintela }
9209c894df3SJuan Quintela 
9219c894df3SJuan Quintela MigrationParameters *qmp_query_migrate_parameters(Error **errp)
9229c894df3SJuan Quintela {
9239c894df3SJuan Quintela     MigrationParameters *params;
9249c894df3SJuan Quintela     MigrationState *s = migrate_get_current();
9259c894df3SJuan Quintela 
9269c894df3SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
9279c894df3SJuan Quintela     params = g_malloc0(sizeof(*params));
9289c894df3SJuan Quintela     params->has_compress_level = true;
9299c894df3SJuan Quintela     params->compress_level = s->parameters.compress_level;
9309c894df3SJuan Quintela     params->has_compress_threads = true;
9319c894df3SJuan Quintela     params->compress_threads = s->parameters.compress_threads;
9329c894df3SJuan Quintela     params->has_compress_wait_thread = true;
9339c894df3SJuan Quintela     params->compress_wait_thread = s->parameters.compress_wait_thread;
9349c894df3SJuan Quintela     params->has_decompress_threads = true;
9359c894df3SJuan Quintela     params->decompress_threads = s->parameters.decompress_threads;
9369c894df3SJuan Quintela     params->has_throttle_trigger_threshold = true;
9379c894df3SJuan Quintela     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
9389c894df3SJuan Quintela     params->has_cpu_throttle_initial = true;
9399c894df3SJuan Quintela     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
9409c894df3SJuan Quintela     params->has_cpu_throttle_increment = true;
9419c894df3SJuan Quintela     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
9429c894df3SJuan Quintela     params->has_cpu_throttle_tailslow = true;
9439c894df3SJuan Quintela     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
9449c894df3SJuan Quintela     params->tls_creds = g_strdup(s->parameters.tls_creds);
9459c894df3SJuan Quintela     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
9469c894df3SJuan Quintela     params->tls_authz = g_strdup(s->parameters.tls_authz ?
9479c894df3SJuan Quintela                                  s->parameters.tls_authz : "");
9489c894df3SJuan Quintela     params->has_max_bandwidth = true;
9499c894df3SJuan Quintela     params->max_bandwidth = s->parameters.max_bandwidth;
9508b239597SPeter Xu     params->has_avail_switchover_bandwidth = true;
9518b239597SPeter Xu     params->avail_switchover_bandwidth = s->parameters.avail_switchover_bandwidth;
9529c894df3SJuan Quintela     params->has_downtime_limit = true;
9539c894df3SJuan Quintela     params->downtime_limit = s->parameters.downtime_limit;
9549c894df3SJuan Quintela     params->has_x_checkpoint_delay = true;
9559c894df3SJuan Quintela     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
9569c894df3SJuan Quintela     params->has_block_incremental = true;
9579c894df3SJuan Quintela     params->block_incremental = s->parameters.block_incremental;
9589c894df3SJuan Quintela     params->has_multifd_channels = true;
9599c894df3SJuan Quintela     params->multifd_channels = s->parameters.multifd_channels;
9609c894df3SJuan Quintela     params->has_multifd_compression = true;
9619c894df3SJuan Quintela     params->multifd_compression = s->parameters.multifd_compression;
9629c894df3SJuan Quintela     params->has_multifd_zlib_level = true;
9639c894df3SJuan Quintela     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
9649c894df3SJuan Quintela     params->has_multifd_zstd_level = true;
9659c894df3SJuan Quintela     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
9669c894df3SJuan Quintela     params->has_xbzrle_cache_size = true;
9679c894df3SJuan Quintela     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
9689c894df3SJuan Quintela     params->has_max_postcopy_bandwidth = true;
9699c894df3SJuan Quintela     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
9709c894df3SJuan Quintela     params->has_max_cpu_throttle = true;
9719c894df3SJuan Quintela     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
9729c894df3SJuan Quintela     params->has_announce_initial = true;
9739c894df3SJuan Quintela     params->announce_initial = s->parameters.announce_initial;
9749c894df3SJuan Quintela     params->has_announce_max = true;
9759c894df3SJuan Quintela     params->announce_max = s->parameters.announce_max;
9769c894df3SJuan Quintela     params->has_announce_rounds = true;
9779c894df3SJuan Quintela     params->announce_rounds = s->parameters.announce_rounds;
9789c894df3SJuan Quintela     params->has_announce_step = true;
9799c894df3SJuan Quintela     params->announce_step = s->parameters.announce_step;
9809c894df3SJuan Quintela 
9819c894df3SJuan Quintela     if (s->parameters.has_block_bitmap_mapping) {
9829c894df3SJuan Quintela         params->has_block_bitmap_mapping = true;
9839c894df3SJuan Quintela         params->block_bitmap_mapping =
9849c894df3SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
9859c894df3SJuan Quintela                        s->parameters.block_bitmap_mapping);
9869c894df3SJuan Quintela     }
9879c894df3SJuan Quintela 
9884d807857SHyman Huang(黄勇)     params->has_x_vcpu_dirty_limit_period = true;
9894d807857SHyman Huang(黄勇)     params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period;
99009f9ec99SHyman Huang(黄勇)     params->has_vcpu_dirty_limit = true;
99109f9ec99SHyman Huang(黄勇)     params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit;
9924d807857SHyman Huang(黄勇) 
9939c894df3SJuan Quintela     return params;
9949c894df3SJuan Quintela }
99509d6c965SJuan Quintela 
99661a174e2SJuan Quintela void migrate_params_init(MigrationParameters *params)
99761a174e2SJuan Quintela {
99861a174e2SJuan Quintela     params->tls_hostname = g_strdup("");
99961a174e2SJuan Quintela     params->tls_creds = g_strdup("");
100061a174e2SJuan Quintela 
100161a174e2SJuan Quintela     /* Set has_* up only for parameter checks */
100261a174e2SJuan Quintela     params->has_compress_level = true;
100361a174e2SJuan Quintela     params->has_compress_threads = true;
100461a174e2SJuan Quintela     params->has_compress_wait_thread = true;
100561a174e2SJuan Quintela     params->has_decompress_threads = true;
100661a174e2SJuan Quintela     params->has_throttle_trigger_threshold = true;
100761a174e2SJuan Quintela     params->has_cpu_throttle_initial = true;
100861a174e2SJuan Quintela     params->has_cpu_throttle_increment = true;
100961a174e2SJuan Quintela     params->has_cpu_throttle_tailslow = true;
101061a174e2SJuan Quintela     params->has_max_bandwidth = true;
101161a174e2SJuan Quintela     params->has_downtime_limit = true;
101261a174e2SJuan Quintela     params->has_x_checkpoint_delay = true;
101361a174e2SJuan Quintela     params->has_block_incremental = true;
101461a174e2SJuan Quintela     params->has_multifd_channels = true;
101561a174e2SJuan Quintela     params->has_multifd_compression = true;
101661a174e2SJuan Quintela     params->has_multifd_zlib_level = true;
101761a174e2SJuan Quintela     params->has_multifd_zstd_level = true;
101861a174e2SJuan Quintela     params->has_xbzrle_cache_size = true;
101961a174e2SJuan Quintela     params->has_max_postcopy_bandwidth = true;
102061a174e2SJuan Quintela     params->has_max_cpu_throttle = true;
102161a174e2SJuan Quintela     params->has_announce_initial = true;
102261a174e2SJuan Quintela     params->has_announce_max = true;
102361a174e2SJuan Quintela     params->has_announce_rounds = true;
102461a174e2SJuan Quintela     params->has_announce_step = true;
10254d807857SHyman Huang(黄勇)     params->has_x_vcpu_dirty_limit_period = true;
102609f9ec99SHyman Huang(黄勇)     params->has_vcpu_dirty_limit = true;
102761a174e2SJuan Quintela }
102861a174e2SJuan Quintela 
102909d6c965SJuan Quintela /*
103009d6c965SJuan Quintela  * Check whether the parameters are valid. Error will be put into errp
103109d6c965SJuan Quintela  * (if provided). Return true if valid, otherwise false.
103209d6c965SJuan Quintela  */
103309d6c965SJuan Quintela bool migrate_params_check(MigrationParameters *params, Error **errp)
103409d6c965SJuan Quintela {
103509d6c965SJuan Quintela     if (params->has_compress_level &&
103609d6c965SJuan Quintela         (params->compress_level > 9)) {
103709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",
103809d6c965SJuan Quintela                    "a value between 0 and 9");
103909d6c965SJuan Quintela         return false;
104009d6c965SJuan Quintela     }
104109d6c965SJuan Quintela 
104209d6c965SJuan Quintela     if (params->has_compress_threads && (params->compress_threads < 1)) {
104309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
104409d6c965SJuan Quintela                    "compress_threads",
104509d6c965SJuan Quintela                    "a value between 1 and 255");
104609d6c965SJuan Quintela         return false;
104709d6c965SJuan Quintela     }
104809d6c965SJuan Quintela 
104909d6c965SJuan Quintela     if (params->has_decompress_threads && (params->decompress_threads < 1)) {
105009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
105109d6c965SJuan Quintela                    "decompress_threads",
105209d6c965SJuan Quintela                    "a value between 1 and 255");
105309d6c965SJuan Quintela         return false;
105409d6c965SJuan Quintela     }
105509d6c965SJuan Quintela 
105609d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold &&
105709d6c965SJuan Quintela         (params->throttle_trigger_threshold < 1 ||
105809d6c965SJuan Quintela          params->throttle_trigger_threshold > 100)) {
105909d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
106009d6c965SJuan Quintela                    "throttle_trigger_threshold",
106109d6c965SJuan Quintela                    "an integer in the range of 1 to 100");
106209d6c965SJuan Quintela         return false;
106309d6c965SJuan Quintela     }
106409d6c965SJuan Quintela 
106509d6c965SJuan Quintela     if (params->has_cpu_throttle_initial &&
106609d6c965SJuan Quintela         (params->cpu_throttle_initial < 1 ||
106709d6c965SJuan Quintela          params->cpu_throttle_initial > 99)) {
106809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
106909d6c965SJuan Quintela                    "cpu_throttle_initial",
107009d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
107109d6c965SJuan Quintela         return false;
107209d6c965SJuan Quintela     }
107309d6c965SJuan Quintela 
107409d6c965SJuan Quintela     if (params->has_cpu_throttle_increment &&
107509d6c965SJuan Quintela         (params->cpu_throttle_increment < 1 ||
107609d6c965SJuan Quintela          params->cpu_throttle_increment > 99)) {
107709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
107809d6c965SJuan Quintela                    "cpu_throttle_increment",
107909d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
108009d6c965SJuan Quintela         return false;
108109d6c965SJuan Quintela     }
108209d6c965SJuan Quintela 
108309d6c965SJuan Quintela     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
108409d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
108509d6c965SJuan Quintela                    "max_bandwidth",
108609d6c965SJuan Quintela                    "an integer in the range of 0 to "stringify(SIZE_MAX)
108709d6c965SJuan Quintela                    " bytes/second");
108809d6c965SJuan Quintela         return false;
108909d6c965SJuan Quintela     }
109009d6c965SJuan Quintela 
10918b239597SPeter Xu     if (params->has_avail_switchover_bandwidth &&
10928b239597SPeter Xu         (params->avail_switchover_bandwidth > SIZE_MAX)) {
10938b239597SPeter Xu         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
10948b239597SPeter Xu                    "avail_switchover_bandwidth",
10958b239597SPeter Xu                    "an integer in the range of 0 to "stringify(SIZE_MAX)
10968b239597SPeter Xu                    " bytes/second");
10978b239597SPeter Xu         return false;
10988b239597SPeter Xu     }
10998b239597SPeter Xu 
110009d6c965SJuan Quintela     if (params->has_downtime_limit &&
110109d6c965SJuan Quintela         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
110209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
110309d6c965SJuan Quintela                    "downtime_limit",
110409d6c965SJuan Quintela                    "an integer in the range of 0 to "
110509d6c965SJuan Quintela                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
110609d6c965SJuan Quintela         return false;
110709d6c965SJuan Quintela     }
110809d6c965SJuan Quintela 
110909d6c965SJuan Quintela     /* x_checkpoint_delay is now always positive */
111009d6c965SJuan Quintela 
111109d6c965SJuan Quintela     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
111209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
111309d6c965SJuan Quintela                    "multifd_channels",
111409d6c965SJuan Quintela                    "a value between 1 and 255");
111509d6c965SJuan Quintela         return false;
111609d6c965SJuan Quintela     }
111709d6c965SJuan Quintela 
111809d6c965SJuan Quintela     if (params->has_multifd_zlib_level &&
111909d6c965SJuan Quintela         (params->multifd_zlib_level > 9)) {
112009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
112109d6c965SJuan Quintela                    "a value between 0 and 9");
112209d6c965SJuan Quintela         return false;
112309d6c965SJuan Quintela     }
112409d6c965SJuan Quintela 
112509d6c965SJuan Quintela     if (params->has_multifd_zstd_level &&
112609d6c965SJuan Quintela         (params->multifd_zstd_level > 20)) {
112709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
112809d6c965SJuan Quintela                    "a value between 0 and 20");
112909d6c965SJuan Quintela         return false;
113009d6c965SJuan Quintela     }
113109d6c965SJuan Quintela 
113209d6c965SJuan Quintela     if (params->has_xbzrle_cache_size &&
113309d6c965SJuan Quintela         (params->xbzrle_cache_size < qemu_target_page_size() ||
113409d6c965SJuan Quintela          !is_power_of_2(params->xbzrle_cache_size))) {
113509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
113609d6c965SJuan Quintela                    "xbzrle_cache_size",
113709d6c965SJuan Quintela                    "a power of two no less than the target page size");
113809d6c965SJuan Quintela         return false;
113909d6c965SJuan Quintela     }
114009d6c965SJuan Quintela 
114109d6c965SJuan Quintela     if (params->has_max_cpu_throttle &&
114209d6c965SJuan Quintela         (params->max_cpu_throttle < params->cpu_throttle_initial ||
114309d6c965SJuan Quintela          params->max_cpu_throttle > 99)) {
114409d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
114509d6c965SJuan Quintela                    "max_cpu_throttle",
114609d6c965SJuan Quintela                    "an integer in the range of cpu_throttle_initial to 99");
114709d6c965SJuan Quintela         return false;
114809d6c965SJuan Quintela     }
114909d6c965SJuan Quintela 
115009d6c965SJuan Quintela     if (params->has_announce_initial &&
115109d6c965SJuan Quintela         params->announce_initial > 100000) {
115209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
115309d6c965SJuan Quintela                    "announce_initial",
115409d6c965SJuan Quintela                    "a value between 0 and 100000");
115509d6c965SJuan Quintela         return false;
115609d6c965SJuan Quintela     }
115709d6c965SJuan Quintela     if (params->has_announce_max &&
115809d6c965SJuan Quintela         params->announce_max > 100000) {
115909d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
116009d6c965SJuan Quintela                    "announce_max",
116109d6c965SJuan Quintela                    "a value between 0 and 100000");
116209d6c965SJuan Quintela        return false;
116309d6c965SJuan Quintela     }
116409d6c965SJuan Quintela     if (params->has_announce_rounds &&
116509d6c965SJuan Quintela         params->announce_rounds > 1000) {
116609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
116709d6c965SJuan Quintela                    "announce_rounds",
116809d6c965SJuan Quintela                    "a value between 0 and 1000");
116909d6c965SJuan Quintela        return false;
117009d6c965SJuan Quintela     }
117109d6c965SJuan Quintela     if (params->has_announce_step &&
117209d6c965SJuan Quintela         (params->announce_step < 1 ||
117309d6c965SJuan Quintela         params->announce_step > 10000)) {
117409d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
117509d6c965SJuan Quintela                    "announce_step",
117609d6c965SJuan Quintela                    "a value between 0 and 10000");
117709d6c965SJuan Quintela        return false;
117809d6c965SJuan Quintela     }
117909d6c965SJuan Quintela 
118009d6c965SJuan Quintela     if (params->has_block_bitmap_mapping &&
118109d6c965SJuan Quintela         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
118209d6c965SJuan Quintela         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
118309d6c965SJuan Quintela         return false;
118409d6c965SJuan Quintela     }
118509d6c965SJuan Quintela 
118609d6c965SJuan Quintela #ifdef CONFIG_LINUX
118709d6c965SJuan Quintela     if (migrate_zero_copy_send() &&
118809d6c965SJuan Quintela         ((params->has_multifd_compression && params->multifd_compression) ||
118909d6c965SJuan Quintela          (params->tls_creds && *params->tls_creds))) {
119009d6c965SJuan Quintela         error_setg(errp,
119109d6c965SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
119209d6c965SJuan Quintela         return false;
119309d6c965SJuan Quintela     }
119409d6c965SJuan Quintela #endif
119509d6c965SJuan Quintela 
11964d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period &&
11974d807857SHyman Huang(黄勇)         (params->x_vcpu_dirty_limit_period < 1 ||
11984d807857SHyman Huang(黄勇)          params->x_vcpu_dirty_limit_period > 1000)) {
11994d807857SHyman Huang(黄勇)         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
12004d807857SHyman Huang(黄勇)                    "x-vcpu-dirty-limit-period",
12014d807857SHyman Huang(黄勇)                    "a value between 1 and 1000");
12024d807857SHyman Huang(黄勇)         return false;
12034d807857SHyman Huang(黄勇)     }
12044d807857SHyman Huang(黄勇) 
120509f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit &&
120609f9ec99SHyman Huang(黄勇)         (params->vcpu_dirty_limit < 1)) {
120709f9ec99SHyman Huang(黄勇)         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
120809f9ec99SHyman Huang(黄勇)                    "vcpu_dirty_limit",
120909f9ec99SHyman Huang(黄勇)                    "is invalid, it must greater then 1 MB/s");
121009f9ec99SHyman Huang(黄勇)         return false;
121109f9ec99SHyman Huang(黄勇)     }
121209f9ec99SHyman Huang(黄勇) 
121309d6c965SJuan Quintela     return true;
121409d6c965SJuan Quintela }
121509d6c965SJuan Quintela 
121609d6c965SJuan Quintela static void migrate_params_test_apply(MigrateSetParameters *params,
121709d6c965SJuan Quintela                                       MigrationParameters *dest)
121809d6c965SJuan Quintela {
121909d6c965SJuan Quintela     *dest = migrate_get_current()->parameters;
122009d6c965SJuan Quintela 
122109d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
122209d6c965SJuan Quintela 
122309d6c965SJuan Quintela     if (params->has_compress_level) {
122409d6c965SJuan Quintela         dest->compress_level = params->compress_level;
122509d6c965SJuan Quintela     }
122609d6c965SJuan Quintela 
122709d6c965SJuan Quintela     if (params->has_compress_threads) {
122809d6c965SJuan Quintela         dest->compress_threads = params->compress_threads;
122909d6c965SJuan Quintela     }
123009d6c965SJuan Quintela 
123109d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
123209d6c965SJuan Quintela         dest->compress_wait_thread = params->compress_wait_thread;
123309d6c965SJuan Quintela     }
123409d6c965SJuan Quintela 
123509d6c965SJuan Quintela     if (params->has_decompress_threads) {
123609d6c965SJuan Quintela         dest->decompress_threads = params->decompress_threads;
123709d6c965SJuan Quintela     }
123809d6c965SJuan Quintela 
123909d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
124009d6c965SJuan Quintela         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
124109d6c965SJuan Quintela     }
124209d6c965SJuan Quintela 
124309d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
124409d6c965SJuan Quintela         dest->cpu_throttle_initial = params->cpu_throttle_initial;
124509d6c965SJuan Quintela     }
124609d6c965SJuan Quintela 
124709d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
124809d6c965SJuan Quintela         dest->cpu_throttle_increment = params->cpu_throttle_increment;
124909d6c965SJuan Quintela     }
125009d6c965SJuan Quintela 
125109d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
125209d6c965SJuan Quintela         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
125309d6c965SJuan Quintela     }
125409d6c965SJuan Quintela 
125509d6c965SJuan Quintela     if (params->tls_creds) {
125609d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
125709d6c965SJuan Quintela         dest->tls_creds = params->tls_creds->u.s;
125809d6c965SJuan Quintela     }
125909d6c965SJuan Quintela 
126009d6c965SJuan Quintela     if (params->tls_hostname) {
126109d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
126209d6c965SJuan Quintela         dest->tls_hostname = params->tls_hostname->u.s;
126309d6c965SJuan Quintela     }
126409d6c965SJuan Quintela 
126509d6c965SJuan Quintela     if (params->has_max_bandwidth) {
126609d6c965SJuan Quintela         dest->max_bandwidth = params->max_bandwidth;
126709d6c965SJuan Quintela     }
126809d6c965SJuan Quintela 
12698b239597SPeter Xu     if (params->has_avail_switchover_bandwidth) {
12708b239597SPeter Xu         dest->avail_switchover_bandwidth = params->avail_switchover_bandwidth;
12718b239597SPeter Xu     }
12728b239597SPeter Xu 
127309d6c965SJuan Quintela     if (params->has_downtime_limit) {
127409d6c965SJuan Quintela         dest->downtime_limit = params->downtime_limit;
127509d6c965SJuan Quintela     }
127609d6c965SJuan Quintela 
127709d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
127809d6c965SJuan Quintela         dest->x_checkpoint_delay = params->x_checkpoint_delay;
127909d6c965SJuan Quintela     }
128009d6c965SJuan Quintela 
128109d6c965SJuan Quintela     if (params->has_block_incremental) {
128209d6c965SJuan Quintela         dest->block_incremental = params->block_incremental;
128309d6c965SJuan Quintela     }
128409d6c965SJuan Quintela     if (params->has_multifd_channels) {
128509d6c965SJuan Quintela         dest->multifd_channels = params->multifd_channels;
128609d6c965SJuan Quintela     }
128709d6c965SJuan Quintela     if (params->has_multifd_compression) {
128809d6c965SJuan Quintela         dest->multifd_compression = params->multifd_compression;
128909d6c965SJuan Quintela     }
129009d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
129109d6c965SJuan Quintela         dest->xbzrle_cache_size = params->xbzrle_cache_size;
129209d6c965SJuan Quintela     }
129309d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
129409d6c965SJuan Quintela         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
129509d6c965SJuan Quintela     }
129609d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
129709d6c965SJuan Quintela         dest->max_cpu_throttle = params->max_cpu_throttle;
129809d6c965SJuan Quintela     }
129909d6c965SJuan Quintela     if (params->has_announce_initial) {
130009d6c965SJuan Quintela         dest->announce_initial = params->announce_initial;
130109d6c965SJuan Quintela     }
130209d6c965SJuan Quintela     if (params->has_announce_max) {
130309d6c965SJuan Quintela         dest->announce_max = params->announce_max;
130409d6c965SJuan Quintela     }
130509d6c965SJuan Quintela     if (params->has_announce_rounds) {
130609d6c965SJuan Quintela         dest->announce_rounds = params->announce_rounds;
130709d6c965SJuan Quintela     }
130809d6c965SJuan Quintela     if (params->has_announce_step) {
130909d6c965SJuan Quintela         dest->announce_step = params->announce_step;
131009d6c965SJuan Quintela     }
131109d6c965SJuan Quintela 
131209d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
131309d6c965SJuan Quintela         dest->has_block_bitmap_mapping = true;
131409d6c965SJuan Quintela         dest->block_bitmap_mapping = params->block_bitmap_mapping;
131509d6c965SJuan Quintela     }
13164d807857SHyman Huang(黄勇) 
13174d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period) {
13184d807857SHyman Huang(黄勇)         dest->x_vcpu_dirty_limit_period =
13194d807857SHyman Huang(黄勇)             params->x_vcpu_dirty_limit_period;
13204d807857SHyman Huang(黄勇)     }
132109f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit) {
132209f9ec99SHyman Huang(黄勇)         dest->vcpu_dirty_limit = params->vcpu_dirty_limit;
132309f9ec99SHyman Huang(黄勇)     }
132409d6c965SJuan Quintela }
132509d6c965SJuan Quintela 
132609d6c965SJuan Quintela static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
132709d6c965SJuan Quintela {
132809d6c965SJuan Quintela     MigrationState *s = migrate_get_current();
132909d6c965SJuan Quintela 
133009d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
133109d6c965SJuan Quintela 
133209d6c965SJuan Quintela     if (params->has_compress_level) {
133309d6c965SJuan Quintela         s->parameters.compress_level = params->compress_level;
133409d6c965SJuan Quintela     }
133509d6c965SJuan Quintela 
133609d6c965SJuan Quintela     if (params->has_compress_threads) {
133709d6c965SJuan Quintela         s->parameters.compress_threads = params->compress_threads;
133809d6c965SJuan Quintela     }
133909d6c965SJuan Quintela 
134009d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
134109d6c965SJuan Quintela         s->parameters.compress_wait_thread = params->compress_wait_thread;
134209d6c965SJuan Quintela     }
134309d6c965SJuan Quintela 
134409d6c965SJuan Quintela     if (params->has_decompress_threads) {
134509d6c965SJuan Quintela         s->parameters.decompress_threads = params->decompress_threads;
134609d6c965SJuan Quintela     }
134709d6c965SJuan Quintela 
134809d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
134909d6c965SJuan Quintela         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
135009d6c965SJuan Quintela     }
135109d6c965SJuan Quintela 
135209d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
135309d6c965SJuan Quintela         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
135409d6c965SJuan Quintela     }
135509d6c965SJuan Quintela 
135609d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
135709d6c965SJuan Quintela         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
135809d6c965SJuan Quintela     }
135909d6c965SJuan Quintela 
136009d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
136109d6c965SJuan Quintela         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
136209d6c965SJuan Quintela     }
136309d6c965SJuan Quintela 
136409d6c965SJuan Quintela     if (params->tls_creds) {
136509d6c965SJuan Quintela         g_free(s->parameters.tls_creds);
136609d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
136709d6c965SJuan Quintela         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
136809d6c965SJuan Quintela     }
136909d6c965SJuan Quintela 
137009d6c965SJuan Quintela     if (params->tls_hostname) {
137109d6c965SJuan Quintela         g_free(s->parameters.tls_hostname);
137209d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
137309d6c965SJuan Quintela         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
137409d6c965SJuan Quintela     }
137509d6c965SJuan Quintela 
137609d6c965SJuan Quintela     if (params->tls_authz) {
137709d6c965SJuan Quintela         g_free(s->parameters.tls_authz);
137809d6c965SJuan Quintela         assert(params->tls_authz->type == QTYPE_QSTRING);
137909d6c965SJuan Quintela         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
138009d6c965SJuan Quintela     }
138109d6c965SJuan Quintela 
138209d6c965SJuan Quintela     if (params->has_max_bandwidth) {
138309d6c965SJuan Quintela         s->parameters.max_bandwidth = params->max_bandwidth;
138409d6c965SJuan Quintela         if (s->to_dst_file && !migration_in_postcopy()) {
1385e1fde0e0SJuan Quintela             migration_rate_set(s->parameters.max_bandwidth);
138609d6c965SJuan Quintela         }
138709d6c965SJuan Quintela     }
138809d6c965SJuan Quintela 
13898b239597SPeter Xu     if (params->has_avail_switchover_bandwidth) {
13908b239597SPeter Xu         s->parameters.avail_switchover_bandwidth = params->avail_switchover_bandwidth;
13918b239597SPeter Xu     }
13928b239597SPeter Xu 
139309d6c965SJuan Quintela     if (params->has_downtime_limit) {
139409d6c965SJuan Quintela         s->parameters.downtime_limit = params->downtime_limit;
139509d6c965SJuan Quintela     }
139609d6c965SJuan Quintela 
139709d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
139809d6c965SJuan Quintela         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
13994332ffcdSVladimir Sementsov-Ogievskiy         colo_checkpoint_delay_set();
140009d6c965SJuan Quintela     }
140109d6c965SJuan Quintela 
140209d6c965SJuan Quintela     if (params->has_block_incremental) {
140309d6c965SJuan Quintela         s->parameters.block_incremental = params->block_incremental;
140409d6c965SJuan Quintela     }
140509d6c965SJuan Quintela     if (params->has_multifd_channels) {
140609d6c965SJuan Quintela         s->parameters.multifd_channels = params->multifd_channels;
140709d6c965SJuan Quintela     }
140809d6c965SJuan Quintela     if (params->has_multifd_compression) {
140909d6c965SJuan Quintela         s->parameters.multifd_compression = params->multifd_compression;
141009d6c965SJuan Quintela     }
141109d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
141209d6c965SJuan Quintela         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
141309d6c965SJuan Quintela         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
141409d6c965SJuan Quintela     }
141509d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
141609d6c965SJuan Quintela         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
141709d6c965SJuan Quintela         if (s->to_dst_file && migration_in_postcopy()) {
1418e1fde0e0SJuan Quintela             migration_rate_set(s->parameters.max_postcopy_bandwidth);
141909d6c965SJuan Quintela         }
142009d6c965SJuan Quintela     }
142109d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
142209d6c965SJuan Quintela         s->parameters.max_cpu_throttle = params->max_cpu_throttle;
142309d6c965SJuan Quintela     }
142409d6c965SJuan Quintela     if (params->has_announce_initial) {
142509d6c965SJuan Quintela         s->parameters.announce_initial = params->announce_initial;
142609d6c965SJuan Quintela     }
142709d6c965SJuan Quintela     if (params->has_announce_max) {
142809d6c965SJuan Quintela         s->parameters.announce_max = params->announce_max;
142909d6c965SJuan Quintela     }
143009d6c965SJuan Quintela     if (params->has_announce_rounds) {
143109d6c965SJuan Quintela         s->parameters.announce_rounds = params->announce_rounds;
143209d6c965SJuan Quintela     }
143309d6c965SJuan Quintela     if (params->has_announce_step) {
143409d6c965SJuan Quintela         s->parameters.announce_step = params->announce_step;
143509d6c965SJuan Quintela     }
143609d6c965SJuan Quintela 
143709d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
143809d6c965SJuan Quintela         qapi_free_BitmapMigrationNodeAliasList(
143909d6c965SJuan Quintela             s->parameters.block_bitmap_mapping);
144009d6c965SJuan Quintela 
144109d6c965SJuan Quintela         s->parameters.has_block_bitmap_mapping = true;
144209d6c965SJuan Quintela         s->parameters.block_bitmap_mapping =
144309d6c965SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
144409d6c965SJuan Quintela                        params->block_bitmap_mapping);
144509d6c965SJuan Quintela     }
14464d807857SHyman Huang(黄勇) 
14474d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period) {
14484d807857SHyman Huang(黄勇)         s->parameters.x_vcpu_dirty_limit_period =
14494d807857SHyman Huang(黄勇)             params->x_vcpu_dirty_limit_period;
14504d807857SHyman Huang(黄勇)     }
145109f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit) {
145209f9ec99SHyman Huang(黄勇)         s->parameters.vcpu_dirty_limit = params->vcpu_dirty_limit;
145309f9ec99SHyman Huang(黄勇)     }
145409d6c965SJuan Quintela }
145509d6c965SJuan Quintela 
145609d6c965SJuan Quintela void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
145709d6c965SJuan Quintela {
145809d6c965SJuan Quintela     MigrationParameters tmp;
145909d6c965SJuan Quintela 
146086dec715SPeter Xu     /* TODO Rewrite "" to null instead for all three tls_* parameters */
146109d6c965SJuan Quintela     if (params->tls_creds
146209d6c965SJuan Quintela         && params->tls_creds->type == QTYPE_QNULL) {
146309d6c965SJuan Quintela         qobject_unref(params->tls_creds->u.n);
146409d6c965SJuan Quintela         params->tls_creds->type = QTYPE_QSTRING;
146509d6c965SJuan Quintela         params->tls_creds->u.s = strdup("");
146609d6c965SJuan Quintela     }
146709d6c965SJuan Quintela     if (params->tls_hostname
146809d6c965SJuan Quintela         && params->tls_hostname->type == QTYPE_QNULL) {
146909d6c965SJuan Quintela         qobject_unref(params->tls_hostname->u.n);
147009d6c965SJuan Quintela         params->tls_hostname->type = QTYPE_QSTRING;
147109d6c965SJuan Quintela         params->tls_hostname->u.s = strdup("");
147209d6c965SJuan Quintela     }
147386dec715SPeter Xu     if (params->tls_authz
147486dec715SPeter Xu         && params->tls_authz->type == QTYPE_QNULL) {
147586dec715SPeter Xu         qobject_unref(params->tls_authz->u.n);
147686dec715SPeter Xu         params->tls_authz->type = QTYPE_QSTRING;
147786dec715SPeter Xu         params->tls_authz->u.s = strdup("");
147886dec715SPeter Xu     }
147909d6c965SJuan Quintela 
148009d6c965SJuan Quintela     migrate_params_test_apply(params, &tmp);
148109d6c965SJuan Quintela 
148209d6c965SJuan Quintela     if (!migrate_params_check(&tmp, errp)) {
148309d6c965SJuan Quintela         /* Invalid parameter */
148409d6c965SJuan Quintela         return;
148509d6c965SJuan Quintela     }
148609d6c965SJuan Quintela 
148709d6c965SJuan Quintela     migrate_params_apply(params, errp);
148809d6c965SJuan Quintela }
1489