xref: /openbmc/qemu/migration/options.c (revision 86c6eb1f39cbb7eb0467c114469e98ef699fb515)
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 /* Define default autoconverge cpu throttle migration parameters */
44f9436522SJuan Quintela #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50
45f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
46f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
47f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99
48f9436522SJuan Quintela 
49f9436522SJuan Quintela /* Migration XBZRLE default cache size */
50f9436522SJuan Quintela #define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024)
51f9436522SJuan Quintela 
52f9436522SJuan Quintela /* The delay time (in ms) between two COLO checkpoints */
53f9436522SJuan Quintela #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100)
54f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
55f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE
56f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 9: best compress ratio */
57f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1
58*86c6eb1fSBryan Zhang /*
59*86c6eb1fSBryan Zhang  * 1: best speed, ... 9: best compress ratio
60*86c6eb1fSBryan Zhang  * There is some nuance here. Refer to QATzip documentation to understand
61*86c6eb1fSBryan Zhang  * the mapping of QATzip levels to standard deflate levels.
62*86c6eb1fSBryan Zhang  */
63*86c6eb1fSBryan Zhang #define DEFAULT_MIGRATE_MULTIFD_QATZIP_LEVEL 1
64*86c6eb1fSBryan Zhang 
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),
9577c259a4SJuan Quintela     DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
96294e5a40SJuan Quintela                       multifd_flush_after_each_section, false),
97f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
98f9436522SJuan Quintela                       clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
99f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
100f9436522SJuan Quintela                      preempt_pre_7_2, false),
101f9436522SJuan Quintela 
102f9436522SJuan Quintela     /* Migration parameters */
103f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState,
104f9436522SJuan Quintela                       parameters.throttle_trigger_threshold,
105f9436522SJuan Quintela                       DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
106f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState,
107f9436522SJuan Quintela                       parameters.cpu_throttle_initial,
108f9436522SJuan Quintela                       DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL),
109f9436522SJuan Quintela     DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState,
110f9436522SJuan Quintela                       parameters.cpu_throttle_increment,
111f9436522SJuan Quintela                       DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
112f9436522SJuan Quintela     DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState,
113f9436522SJuan Quintela                       parameters.cpu_throttle_tailslow, false),
114f9436522SJuan Quintela     DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState,
115f9436522SJuan Quintela                       parameters.max_bandwidth, MAX_THROTTLE),
1168b239597SPeter Xu     DEFINE_PROP_SIZE("avail-switchover-bandwidth", MigrationState,
1178b239597SPeter Xu                       parameters.avail_switchover_bandwidth, 0),
118f9436522SJuan Quintela     DEFINE_PROP_UINT64("x-downtime-limit", MigrationState,
119f9436522SJuan Quintela                       parameters.downtime_limit,
120f9436522SJuan Quintela                       DEFAULT_MIGRATE_SET_DOWNTIME),
121f9436522SJuan Quintela     DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
122f9436522SJuan Quintela                       parameters.x_checkpoint_delay,
123f9436522SJuan Quintela                       DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
124f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-channels", MigrationState,
125f9436522SJuan Quintela                       parameters.multifd_channels,
126f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_CHANNELS),
127f9436522SJuan Quintela     DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState,
128f9436522SJuan Quintela                       parameters.multifd_compression,
129f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_COMPRESSION),
130f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState,
131f9436522SJuan Quintela                       parameters.multifd_zlib_level,
132f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL),
133*86c6eb1fSBryan Zhang     DEFINE_PROP_UINT8("multifd-qatzip-level", MigrationState,
134*86c6eb1fSBryan Zhang                       parameters.multifd_qatzip_level,
135*86c6eb1fSBryan Zhang                       DEFAULT_MIGRATE_MULTIFD_QATZIP_LEVEL),
136f9436522SJuan Quintela     DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState,
137f9436522SJuan Quintela                       parameters.multifd_zstd_level,
138f9436522SJuan Quintela                       DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL),
139f9436522SJuan Quintela     DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
140f9436522SJuan Quintela                       parameters.xbzrle_cache_size,
141f9436522SJuan Quintela                       DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
142f9436522SJuan Quintela     DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState,
143f9436522SJuan Quintela                       parameters.max_postcopy_bandwidth,
144f9436522SJuan Quintela                       DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH),
145f9436522SJuan Quintela     DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState,
146f9436522SJuan Quintela                       parameters.max_cpu_throttle,
147f9436522SJuan Quintela                       DEFAULT_MIGRATE_MAX_CPU_THROTTLE),
148f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-initial", MigrationState,
149f9436522SJuan Quintela                       parameters.announce_initial,
150f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_INITIAL),
151f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-max", MigrationState,
152f9436522SJuan Quintela                       parameters.announce_max,
153f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_MAX),
154f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-rounds", MigrationState,
155f9436522SJuan Quintela                       parameters.announce_rounds,
156f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_ROUNDS),
157f9436522SJuan Quintela     DEFINE_PROP_SIZE("announce-step", MigrationState,
158f9436522SJuan Quintela                       parameters.announce_step,
159f9436522SJuan Quintela                       DEFAULT_MIGRATE_ANNOUNCE_STEP),
160f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds),
161f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname),
162f9436522SJuan Quintela     DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz),
1634d807857SHyman Huang(黄勇)     DEFINE_PROP_UINT64("x-vcpu-dirty-limit-period", MigrationState,
1644d807857SHyman Huang(黄勇)                        parameters.x_vcpu_dirty_limit_period,
1654d807857SHyman Huang(黄勇)                        DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD),
16609f9ec99SHyman Huang(黄勇)     DEFINE_PROP_UINT64("vcpu-dirty-limit", MigrationState,
16709f9ec99SHyman Huang(黄勇)                        parameters.vcpu_dirty_limit,
16809f9ec99SHyman Huang(黄勇)                        DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT),
169eea1e5c9SSteve Sistare     DEFINE_PROP_MIG_MODE("mode", MigrationState,
170eea1e5c9SSteve Sistare                       parameters.mode,
171eea1e5c9SSteve Sistare                       MIG_MODE_NORMAL),
1725fdbb1dfSHao Xiang     DEFINE_PROP_ZERO_PAGE_DETECTION("zero-page-detection", MigrationState,
1735fdbb1dfSHao Xiang                        parameters.zero_page_detection,
17470c25c92SHao Xiang                        ZERO_PAGE_DETECTION_MULTIFD),
175f9436522SJuan Quintela 
176f9436522SJuan Quintela     /* Migration capabilities */
177f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
178f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL),
179f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE),
180f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS),
181f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS),
182f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM),
183f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-postcopy-preempt",
184f9436522SJuan Quintela                         MIGRATION_CAPABILITY_POSTCOPY_PREEMPT),
185f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO),
186f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
187f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH),
188f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
189f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-background-snapshot",
190f9436522SJuan Quintela             MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
191f9436522SJuan Quintela #ifdef CONFIG_LINUX
192f9436522SJuan Quintela     DEFINE_PROP_MIG_CAP("x-zero-copy-send",
193f9436522SJuan Quintela             MIGRATION_CAPABILITY_ZERO_COPY_SEND),
194f9436522SJuan Quintela #endif
1956574232fSAvihai Horon     DEFINE_PROP_MIG_CAP("x-switchover-ack",
1966574232fSAvihai Horon                         MIGRATION_CAPABILITY_SWITCHOVER_ACK),
197dc623955SHyman Huang(黄勇)     DEFINE_PROP_MIG_CAP("x-dirty-limit", MIGRATION_CAPABILITY_DIRTY_LIMIT),
1984ed49febSFabiano Rosas     DEFINE_PROP_MIG_CAP("mapped-ram", MIGRATION_CAPABILITY_MAPPED_RAM),
199f9436522SJuan Quintela     DEFINE_PROP_END_OF_LIST(),
200f9436522SJuan Quintela };
201f9436522SJuan Quintela 
2021f0776f1SJuan Quintela bool migrate_auto_converge(void)
2031f0776f1SJuan Quintela {
2048f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2051f0776f1SJuan Quintela 
2061f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
2071f0776f1SJuan Quintela }
2081f0776f1SJuan Quintela 
2091f0776f1SJuan Quintela bool migrate_background_snapshot(void)
2101f0776f1SJuan Quintela {
2118f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2121f0776f1SJuan Quintela 
2131f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
2141f0776f1SJuan Quintela }
2151f0776f1SJuan Quintela 
2165e804644SJuan Quintela bool migrate_colo(void)
2175e804644SJuan Quintela {
2185e804644SJuan Quintela     MigrationState *s = migrate_get_current();
2198f9c5327SJuan Quintela 
2205e804644SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
2215e804644SJuan Quintela }
2225e804644SJuan Quintela 
2231f0776f1SJuan Quintela bool migrate_dirty_bitmaps(void)
2241f0776f1SJuan Quintela {
2258f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2261f0776f1SJuan Quintela 
2271f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
2281f0776f1SJuan Quintela }
2291f0776f1SJuan Quintela 
230dc623955SHyman Huang(黄勇) bool migrate_dirty_limit(void)
231dc623955SHyman Huang(黄勇) {
232dc623955SHyman Huang(黄勇)     MigrationState *s = migrate_get_current();
233dc623955SHyman Huang(黄勇) 
234dc623955SHyman Huang(黄勇)     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_LIMIT];
235dc623955SHyman Huang(黄勇) }
236dc623955SHyman Huang(黄勇) 
237b890902cSJuan Quintela bool migrate_events(void)
238b890902cSJuan Quintela {
2398f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
240b890902cSJuan Quintela 
241b890902cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
242b890902cSJuan Quintela }
243b890902cSJuan Quintela 
2444ed49febSFabiano Rosas bool migrate_mapped_ram(void)
2454ed49febSFabiano Rosas {
2464ed49febSFabiano Rosas     MigrationState *s = migrate_get_current();
2474ed49febSFabiano Rosas 
2484ed49febSFabiano Rosas     return s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM];
2494ed49febSFabiano Rosas }
2504ed49febSFabiano Rosas 
2511f0776f1SJuan Quintela bool migrate_ignore_shared(void)
2521f0776f1SJuan Quintela {
2538f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2541f0776f1SJuan Quintela 
2551f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
2561f0776f1SJuan Quintela }
2571f0776f1SJuan Quintela 
2581f0776f1SJuan Quintela bool migrate_late_block_activate(void)
2591f0776f1SJuan Quintela {
2608f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2611f0776f1SJuan Quintela 
2621f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
2631f0776f1SJuan Quintela }
2641f0776f1SJuan Quintela 
26551b07548SJuan Quintela bool migrate_multifd(void)
26651b07548SJuan Quintela {
2678f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
26851b07548SJuan Quintela 
26951b07548SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
27051b07548SJuan Quintela }
27151b07548SJuan Quintela 
2721f0776f1SJuan Quintela bool migrate_pause_before_switchover(void)
2731f0776f1SJuan Quintela {
2748f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2751f0776f1SJuan Quintela 
2761f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
2771f0776f1SJuan Quintela }
2781f0776f1SJuan Quintela 
2791f0776f1SJuan Quintela bool migrate_postcopy_blocktime(void)
2801f0776f1SJuan Quintela {
2818f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2821f0776f1SJuan Quintela 
2831f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
2841f0776f1SJuan Quintela }
2851f0776f1SJuan Quintela 
2861f0776f1SJuan Quintela bool migrate_postcopy_preempt(void)
2871f0776f1SJuan Quintela {
2888f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2891f0776f1SJuan Quintela 
2901f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
2911f0776f1SJuan Quintela }
2921f0776f1SJuan Quintela 
2931f0776f1SJuan Quintela bool migrate_postcopy_ram(void)
2941f0776f1SJuan Quintela {
2958f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
2961f0776f1SJuan Quintela 
2971f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
2981f0776f1SJuan Quintela }
2991f0776f1SJuan Quintela 
30017cba690SJuan Quintela bool migrate_rdma_pin_all(void)
30117cba690SJuan Quintela {
30217cba690SJuan Quintela     MigrationState *s = migrate_get_current();
30317cba690SJuan Quintela 
30417cba690SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
30517cba690SJuan Quintela }
30617cba690SJuan Quintela 
3071f0776f1SJuan Quintela bool migrate_release_ram(void)
3081f0776f1SJuan Quintela {
3098f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3101f0776f1SJuan Quintela 
3111f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
3121f0776f1SJuan Quintela }
3131f0776f1SJuan Quintela 
31438ad1110SJuan Quintela bool migrate_return_path(void)
31538ad1110SJuan Quintela {
3168f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
31738ad1110SJuan Quintela 
31838ad1110SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
31938ad1110SJuan Quintela }
32038ad1110SJuan Quintela 
3216574232fSAvihai Horon bool migrate_switchover_ack(void)
3226574232fSAvihai Horon {
3236574232fSAvihai Horon     MigrationState *s = migrate_get_current();
3246574232fSAvihai Horon 
3256574232fSAvihai Horon     return s->capabilities[MIGRATION_CAPABILITY_SWITCHOVER_ACK];
3266574232fSAvihai Horon }
3276574232fSAvihai Horon 
3281f0776f1SJuan Quintela bool migrate_validate_uuid(void)
3291f0776f1SJuan Quintela {
3308f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3311f0776f1SJuan Quintela 
3321f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
3331f0776f1SJuan Quintela }
3341f0776f1SJuan Quintela 
33587dca0c9SJuan Quintela bool migrate_xbzrle(void)
33687dca0c9SJuan Quintela {
3378f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
33887dca0c9SJuan Quintela 
33987dca0c9SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
34087dca0c9SJuan Quintela }
34187dca0c9SJuan Quintela 
3421f0776f1SJuan Quintela bool migrate_zero_blocks(void)
3431f0776f1SJuan Quintela {
3448f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
3451f0776f1SJuan Quintela 
3461f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
3471f0776f1SJuan Quintela }
348b4bc342cSJuan Quintela 
349b4bc342cSJuan Quintela bool migrate_zero_copy_send(void)
350b4bc342cSJuan Quintela {
3518f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
352b4bc342cSJuan Quintela 
353b4bc342cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
354b4bc342cSJuan Quintela }
355f774fde5SJuan Quintela 
356f774fde5SJuan Quintela /* pseudo capabilities */
357f774fde5SJuan Quintela 
35877c259a4SJuan Quintela bool migrate_multifd_flush_after_each_section(void)
35977c259a4SJuan Quintela {
36077c259a4SJuan Quintela     MigrationState *s = migrate_get_current();
36177c259a4SJuan Quintela 
362294e5a40SJuan Quintela     return s->multifd_flush_after_each_section;
36377c259a4SJuan Quintela }
36477c259a4SJuan Quintela 
365f774fde5SJuan Quintela bool migrate_postcopy(void)
366f774fde5SJuan Quintela {
367f774fde5SJuan Quintela     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
368f774fde5SJuan Quintela }
369f774fde5SJuan Quintela 
37027fd25b0SJuan Quintela bool migrate_rdma(void)
37127fd25b0SJuan Quintela {
37227fd25b0SJuan Quintela     MigrationState *s = migrate_get_current();
37327fd25b0SJuan Quintela 
37427fd25b0SJuan Quintela     return s->rdma_migration;
37527fd25b0SJuan Quintela }
37627fd25b0SJuan Quintela 
37710d4703bSJuan Quintela bool migrate_tls(void)
37810d4703bSJuan Quintela {
3798f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
38010d4703bSJuan Quintela 
38110d4703bSJuan Quintela     return s->parameters.tls_creds && *s->parameters.tls_creds;
38210d4703bSJuan Quintela }
38310d4703bSJuan Quintela 
38477608706SJuan Quintela typedef enum WriteTrackingSupport {
38577608706SJuan Quintela     WT_SUPPORT_UNKNOWN = 0,
38677608706SJuan Quintela     WT_SUPPORT_ABSENT,
38777608706SJuan Quintela     WT_SUPPORT_AVAILABLE,
38877608706SJuan Quintela     WT_SUPPORT_COMPATIBLE
38977608706SJuan Quintela } WriteTrackingSupport;
39077608706SJuan Quintela 
39177608706SJuan Quintela static
39277608706SJuan Quintela WriteTrackingSupport migrate_query_write_tracking(void)
39377608706SJuan Quintela {
39477608706SJuan Quintela     /* Check if kernel supports required UFFD features */
39577608706SJuan Quintela     if (!ram_write_tracking_available()) {
39677608706SJuan Quintela         return WT_SUPPORT_ABSENT;
39777608706SJuan Quintela     }
39877608706SJuan Quintela     /*
39977608706SJuan Quintela      * Check if current memory configuration is
40077608706SJuan Quintela      * compatible with required UFFD features.
40177608706SJuan Quintela      */
40277608706SJuan Quintela     if (!ram_write_tracking_compatible()) {
40377608706SJuan Quintela         return WT_SUPPORT_AVAILABLE;
40477608706SJuan Quintela     }
40577608706SJuan Quintela 
40677608706SJuan Quintela     return WT_SUPPORT_COMPATIBLE;
40777608706SJuan Quintela }
40877608706SJuan Quintela 
40977608706SJuan Quintela /* Migration capabilities set */
41077608706SJuan Quintela struct MigrateCapsSet {
41177608706SJuan Quintela     int size;                       /* Capability set size */
41277608706SJuan Quintela     MigrationCapability caps[];     /* Variadic array of capabilities */
41377608706SJuan Quintela };
41477608706SJuan Quintela typedef struct MigrateCapsSet MigrateCapsSet;
41577608706SJuan Quintela 
41677608706SJuan Quintela /* Define and initialize MigrateCapsSet */
41777608706SJuan Quintela #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
41877608706SJuan Quintela     MigrateCapsSet _name = {    \
41977608706SJuan Quintela         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
42077608706SJuan Quintela         .caps = { __VA_ARGS__ } \
42177608706SJuan Quintela     }
42277608706SJuan Quintela 
42377608706SJuan Quintela /* Background-snapshot compatibility check list */
42477608706SJuan Quintela static const
42577608706SJuan Quintela INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
42677608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_RAM,
42777608706SJuan Quintela     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
42877608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
42977608706SJuan Quintela     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
43077608706SJuan Quintela     MIGRATION_CAPABILITY_RETURN_PATH,
43177608706SJuan Quintela     MIGRATION_CAPABILITY_MULTIFD,
43277608706SJuan Quintela     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
43377608706SJuan Quintela     MIGRATION_CAPABILITY_AUTO_CONVERGE,
43477608706SJuan Quintela     MIGRATION_CAPABILITY_RELEASE_RAM,
43577608706SJuan Quintela     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
43677608706SJuan Quintela     MIGRATION_CAPABILITY_XBZRLE,
43777608706SJuan Quintela     MIGRATION_CAPABILITY_X_COLO,
43877608706SJuan Quintela     MIGRATION_CAPABILITY_VALIDATE_UUID,
43977608706SJuan Quintela     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
44077608706SJuan Quintela 
44182137e6cSWei Wang static bool migrate_incoming_started(void)
44282137e6cSWei Wang {
44382137e6cSWei Wang     return !!migration_incoming_get_current()->transport_data;
44482137e6cSWei Wang }
44582137e6cSWei Wang 
44677608706SJuan Quintela /**
44777608706SJuan Quintela  * @migration_caps_check - check capability compatibility
44877608706SJuan Quintela  *
44977608706SJuan Quintela  * @old_caps: old capability list
45077608706SJuan Quintela  * @new_caps: new capability list
45177608706SJuan Quintela  * @errp: set *errp if the check failed, with reason
45277608706SJuan Quintela  *
45377608706SJuan Quintela  * Returns true if check passed, otherwise false.
45477608706SJuan Quintela  */
45577608706SJuan Quintela bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
45677608706SJuan Quintela {
45746ff64a8SZhao Liu     ERRP_GUARD();
45877608706SJuan Quintela     MigrationIncomingState *mis = migration_incoming_get_current();
45977608706SJuan Quintela 
46077608706SJuan Quintela #ifndef CONFIG_REPLICATION
46177608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
46277608706SJuan Quintela         error_setg(errp, "QEMU compiled without replication module"
46377608706SJuan Quintela                    " can't enable COLO");
46477608706SJuan Quintela         error_append_hint(errp, "Please enable replication before COLO.\n");
46577608706SJuan Quintela         return false;
46677608706SJuan Quintela     }
46777608706SJuan Quintela #endif
46877608706SJuan Quintela 
46977608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
47077608706SJuan Quintela         /* This check is reasonably expensive, so only when it's being
47177608706SJuan Quintela          * set the first time, also it's only the destination that needs
47277608706SJuan Quintela          * special support.
47377608706SJuan Quintela          */
47477608706SJuan Quintela         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
47577608706SJuan Quintela             runstate_check(RUN_STATE_INMIGRATE) &&
47674c38cf7SPeter Xu             !postcopy_ram_supported_by_host(mis, errp)) {
47774c38cf7SPeter Xu             error_prepend(errp, "Postcopy is not supported: ");
47877608706SJuan Quintela             return false;
47977608706SJuan Quintela         }
48077608706SJuan Quintela 
48177608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
48277608706SJuan Quintela             error_setg(errp, "Postcopy is not compatible with ignore-shared");
48377608706SJuan Quintela             return false;
48477608706SJuan Quintela         }
485b405dfffSLeonardo Bras 
486b405dfffSLeonardo Bras         if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
487b405dfffSLeonardo Bras             error_setg(errp, "Postcopy is not yet compatible with multifd");
488b405dfffSLeonardo Bras             return false;
489b405dfffSLeonardo Bras         }
49077608706SJuan Quintela     }
49177608706SJuan Quintela 
49277608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
49377608706SJuan Quintela         WriteTrackingSupport wt_support;
49477608706SJuan Quintela         int idx;
49577608706SJuan Quintela         /*
49677608706SJuan Quintela          * Check if 'background-snapshot' capability is supported by
49777608706SJuan Quintela          * host kernel and compatible with guest memory configuration.
49877608706SJuan Quintela          */
49977608706SJuan Quintela         wt_support = migrate_query_write_tracking();
50077608706SJuan Quintela         if (wt_support < WT_SUPPORT_AVAILABLE) {
50177608706SJuan Quintela             error_setg(errp, "Background-snapshot is not supported by host kernel");
50277608706SJuan Quintela             return false;
50377608706SJuan Quintela         }
50477608706SJuan Quintela         if (wt_support < WT_SUPPORT_COMPATIBLE) {
50577608706SJuan Quintela             error_setg(errp, "Background-snapshot is not compatible "
50677608706SJuan Quintela                     "with guest memory configuration");
50777608706SJuan Quintela             return false;
50877608706SJuan Quintela         }
50977608706SJuan Quintela 
51077608706SJuan Quintela         /*
51177608706SJuan Quintela          * Check if there are any migration capabilities
51277608706SJuan Quintela          * incompatible with 'background-snapshot'.
51377608706SJuan Quintela          */
51477608706SJuan Quintela         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
51577608706SJuan Quintela             int incomp_cap = check_caps_background_snapshot.caps[idx];
51677608706SJuan Quintela             if (new_caps[incomp_cap]) {
51777608706SJuan Quintela                 error_setg(errp,
51877608706SJuan Quintela                         "Background-snapshot is not compatible with %s",
51977608706SJuan Quintela                         MigrationCapability_str(incomp_cap));
52077608706SJuan Quintela                 return false;
52177608706SJuan Quintela             }
52277608706SJuan Quintela         }
52377608706SJuan Quintela     }
52477608706SJuan Quintela 
52577608706SJuan Quintela #ifdef CONFIG_LINUX
52677608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
52777608706SJuan Quintela         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
52877608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
52977608706SJuan Quintela          migrate_multifd_compression() ||
53010d4703bSJuan Quintela          migrate_tls())) {
53177608706SJuan Quintela         error_setg(errp,
53277608706SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
53377608706SJuan Quintela         return false;
53477608706SJuan Quintela     }
53577608706SJuan Quintela #else
53677608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
53777608706SJuan Quintela         error_setg(errp,
53877608706SJuan Quintela                    "Zero copy currently only available on Linux");
53977608706SJuan Quintela         return false;
54077608706SJuan Quintela     }
54177608706SJuan Quintela #endif
54277608706SJuan Quintela 
54377608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
54477608706SJuan Quintela         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
54577608706SJuan Quintela             error_setg(errp, "Postcopy preempt requires postcopy-ram");
54677608706SJuan Quintela             return false;
54777608706SJuan Quintela         }
54877608706SJuan Quintela 
54982137e6cSWei Wang         if (migrate_incoming_started()) {
55082137e6cSWei Wang             error_setg(errp,
55182137e6cSWei Wang                        "Postcopy preempt must be set before incoming starts");
55282137e6cSWei Wang             return false;
55382137e6cSWei Wang         }
55477608706SJuan Quintela     }
55577608706SJuan Quintela 
55677608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
55782137e6cSWei Wang         if (migrate_incoming_started()) {
55882137e6cSWei Wang             error_setg(errp, "Multifd must be set before incoming starts");
55982137e6cSWei Wang             return false;
56082137e6cSWei Wang         }
56177608706SJuan Quintela     }
56277608706SJuan Quintela 
5636574232fSAvihai Horon     if (new_caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK]) {
5646574232fSAvihai Horon         if (!new_caps[MIGRATION_CAPABILITY_RETURN_PATH]) {
5656574232fSAvihai Horon             error_setg(errp, "Capability 'switchover-ack' requires capability "
5666574232fSAvihai Horon                              "'return-path'");
5676574232fSAvihai Horon             return false;
5686574232fSAvihai Horon         }
5696574232fSAvihai Horon     }
570dc623955SHyman Huang(黄勇)     if (new_caps[MIGRATION_CAPABILITY_DIRTY_LIMIT]) {
571dc623955SHyman Huang(黄勇)         if (new_caps[MIGRATION_CAPABILITY_AUTO_CONVERGE]) {
572dc623955SHyman Huang(黄勇)             error_setg(errp, "dirty-limit conflicts with auto-converge"
573dc623955SHyman Huang(黄勇)                        " either of then available currently");
574dc623955SHyman Huang(黄勇)             return false;
575dc623955SHyman Huang(黄勇)         }
576dc623955SHyman Huang(黄勇) 
577dc623955SHyman Huang(黄勇)         if (!kvm_enabled() || !kvm_dirty_ring_enabled()) {
578dc623955SHyman Huang(黄勇)             error_setg(errp, "dirty-limit requires KVM with accelerator"
579dc623955SHyman Huang(黄勇)                    " property 'dirty-ring-size' set");
580dc623955SHyman Huang(黄勇)             return false;
581dc623955SHyman Huang(黄勇)         }
582dc623955SHyman Huang(黄勇)     }
5836574232fSAvihai Horon 
584d869f629SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
585d869f629SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
586d869f629SJuan Quintela             error_setg(errp, "Multifd is not compatible with xbzrle");
587d869f629SJuan Quintela             return false;
588d869f629SJuan Quintela         }
589d869f629SJuan Quintela     }
590d869f629SJuan Quintela 
5914ed49febSFabiano Rosas     if (new_caps[MIGRATION_CAPABILITY_MAPPED_RAM]) {
5924ed49febSFabiano Rosas         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
5934ed49febSFabiano Rosas             error_setg(errp,
5944ed49febSFabiano Rosas                        "Mapped-ram migration is incompatible with xbzrle");
5954ed49febSFabiano Rosas             return false;
5964ed49febSFabiano Rosas         }
5974ed49febSFabiano Rosas 
5984ed49febSFabiano Rosas         if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
5994ed49febSFabiano Rosas             error_setg(errp,
6004ed49febSFabiano Rosas                        "Mapped-ram migration is incompatible with postcopy");
6014ed49febSFabiano Rosas             return false;
6024ed49febSFabiano Rosas         }
6034ed49febSFabiano Rosas     }
6044ed49febSFabiano Rosas 
60577608706SJuan Quintela     return true;
60677608706SJuan Quintela }
6074d0c6b69SJuan Quintela 
608f80196b7SJuan Quintela bool migrate_cap_set(int cap, bool value, Error **errp)
609f80196b7SJuan Quintela {
610f80196b7SJuan Quintela     MigrationState *s = migrate_get_current();
611f80196b7SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
612f80196b7SJuan Quintela 
613aeaafb1eSSteve Sistare     if (migration_is_running()) {
61400580786SPhilippe Mathieu-Daudé         error_setg(errp, "There's a migration process in progress");
615f80196b7SJuan Quintela         return false;
616f80196b7SJuan Quintela     }
617f80196b7SJuan Quintela 
618f80196b7SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
619f80196b7SJuan Quintela     new_caps[cap] = value;
620f80196b7SJuan Quintela 
621f80196b7SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
622f80196b7SJuan Quintela         return false;
623f80196b7SJuan Quintela     }
624f80196b7SJuan Quintela     s->capabilities[cap] = value;
625f80196b7SJuan Quintela     return true;
626f80196b7SJuan Quintela }
627f80196b7SJuan Quintela 
6284d0c6b69SJuan Quintela MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
6294d0c6b69SJuan Quintela {
6304d0c6b69SJuan Quintela     MigrationCapabilityStatusList *head = NULL, **tail = &head;
6314d0c6b69SJuan Quintela     MigrationCapabilityStatus *caps;
6324d0c6b69SJuan Quintela     MigrationState *s = migrate_get_current();
6334d0c6b69SJuan Quintela     int i;
6344d0c6b69SJuan Quintela 
6354d0c6b69SJuan Quintela     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
6364d0c6b69SJuan Quintela         caps = g_malloc0(sizeof(*caps));
6374d0c6b69SJuan Quintela         caps->capability = i;
6384d0c6b69SJuan Quintela         caps->state = s->capabilities[i];
6394d0c6b69SJuan Quintela         QAPI_LIST_APPEND(tail, caps);
6404d0c6b69SJuan Quintela     }
6414d0c6b69SJuan Quintela 
6424d0c6b69SJuan Quintela     return head;
6434d0c6b69SJuan Quintela }
64445c1de13SJuan Quintela 
64545c1de13SJuan Quintela void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
64645c1de13SJuan Quintela                                   Error **errp)
64745c1de13SJuan Quintela {
64845c1de13SJuan Quintela     MigrationState *s = migrate_get_current();
64945c1de13SJuan Quintela     MigrationCapabilityStatusList *cap;
65045c1de13SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
65145c1de13SJuan Quintela 
652aeaafb1eSSteve Sistare     if (migration_is_running() || migration_in_colo_state()) {
65300580786SPhilippe Mathieu-Daudé         error_setg(errp, "There's a migration process in progress");
65445c1de13SJuan Quintela         return;
65545c1de13SJuan Quintela     }
65645c1de13SJuan Quintela 
65745c1de13SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
65845c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
65945c1de13SJuan Quintela         new_caps[cap->value->capability] = cap->value->state;
66045c1de13SJuan Quintela     }
66145c1de13SJuan Quintela 
66245c1de13SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
66345c1de13SJuan Quintela         return;
66445c1de13SJuan Quintela     }
66545c1de13SJuan Quintela 
66645c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
66745c1de13SJuan Quintela         s->capabilities[cap->value->capability] = cap->value->state;
66845c1de13SJuan Quintela     }
66945c1de13SJuan Quintela }
6701dfc4b9eSJuan Quintela 
6711dfc4b9eSJuan Quintela /* parameters */
6721dfc4b9eSJuan Quintela 
673b804b35bSJuan Quintela const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
674b804b35bSJuan Quintela {
675b804b35bSJuan Quintela     MigrationState *s = migrate_get_current();
676b804b35bSJuan Quintela 
677b804b35bSJuan Quintela     return s->parameters.block_bitmap_mapping;
678b804b35bSJuan Quintela }
679b804b35bSJuan Quintela 
6803cba22c9SJuan Quintela bool migrate_has_block_bitmap_mapping(void)
6813cba22c9SJuan Quintela {
6823cba22c9SJuan Quintela     MigrationState *s = migrate_get_current();
6833cba22c9SJuan Quintela 
6843cba22c9SJuan Quintela     return s->parameters.has_block_bitmap_mapping;
6853cba22c9SJuan Quintela }
6863cba22c9SJuan Quintela 
687f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void)
688f94a858fSJuan Quintela {
6898f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
690f94a858fSJuan Quintela 
691f94a858fSJuan Quintela     return s->parameters.x_checkpoint_delay;
692f94a858fSJuan Quintela }
693f94a858fSJuan Quintela 
6949605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void)
6959605c2acSJuan Quintela {
6968f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6979605c2acSJuan Quintela 
6989605c2acSJuan Quintela     return s->parameters.cpu_throttle_increment;
6999605c2acSJuan Quintela }
7009605c2acSJuan Quintela 
7012a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void)
7022a8ec380SJuan Quintela {
7038f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7042a8ec380SJuan Quintela 
7052a8ec380SJuan Quintela     return s->parameters.cpu_throttle_initial;
7062a8ec380SJuan Quintela }
7072a8ec380SJuan Quintela 
708873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void)
709873f674cSJuan Quintela {
7108f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
711873f674cSJuan Quintela 
712873f674cSJuan Quintela     return s->parameters.cpu_throttle_tailslow;
713873f674cSJuan Quintela }
714873f674cSJuan Quintela 
715b43b61d5SFabiano Rosas bool migrate_direct_io(void)
716b43b61d5SFabiano Rosas {
717b43b61d5SFabiano Rosas     MigrationState *s = migrate_get_current();
718b43b61d5SFabiano Rosas 
719b43b61d5SFabiano Rosas     /*
720b43b61d5SFabiano Rosas      * O_DIRECT is only supported with mapped-ram and multifd.
721b43b61d5SFabiano Rosas      *
722b43b61d5SFabiano Rosas      * mapped-ram is needed because filesystems impose restrictions on
723b43b61d5SFabiano Rosas      * O_DIRECT IO alignment (see MAPPED_RAM_FILE_OFFSET_ALIGNMENT).
724b43b61d5SFabiano Rosas      *
725b43b61d5SFabiano Rosas      * multifd is needed to keep the unaligned portion of the stream
726b43b61d5SFabiano Rosas      * isolated to the main migration thread while multifd channels
727b43b61d5SFabiano Rosas      * process the aligned data with O_DIRECT enabled.
728b43b61d5SFabiano Rosas      */
729b43b61d5SFabiano Rosas     return s->parameters.direct_io &&
730b43b61d5SFabiano Rosas         s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM] &&
731b43b61d5SFabiano Rosas         s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
732b43b61d5SFabiano Rosas }
733b43b61d5SFabiano Rosas 
734f5da8ba4SJuan Quintela uint64_t migrate_downtime_limit(void)
735f5da8ba4SJuan Quintela {
736f5da8ba4SJuan Quintela     MigrationState *s = migrate_get_current();
737f5da8ba4SJuan Quintela 
738f5da8ba4SJuan Quintela     return s->parameters.downtime_limit;
739f5da8ba4SJuan Quintela }
740f5da8ba4SJuan Quintela 
74124155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void)
74224155bd0SJuan Quintela {
7438f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
74424155bd0SJuan Quintela 
74524155bd0SJuan Quintela     return s->parameters.max_cpu_throttle;
74624155bd0SJuan Quintela }
74724155bd0SJuan Quintela 
7489c894df3SJuan Quintela uint64_t migrate_max_bandwidth(void)
7499c894df3SJuan Quintela {
7508f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7519c894df3SJuan Quintela 
7529c894df3SJuan Quintela     return s->parameters.max_bandwidth;
7539c894df3SJuan Quintela }
7549c894df3SJuan Quintela 
7558b239597SPeter Xu uint64_t migrate_avail_switchover_bandwidth(void)
7568b239597SPeter Xu {
7578b239597SPeter Xu     MigrationState *s = migrate_get_current();
7588b239597SPeter Xu 
7598b239597SPeter Xu     return s->parameters.avail_switchover_bandwidth;
7608b239597SPeter Xu }
7618b239597SPeter Xu 
76252033349SJuan Quintela uint64_t migrate_max_postcopy_bandwidth(void)
7631dfc4b9eSJuan Quintela {
7648f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7651dfc4b9eSJuan Quintela 
7661dfc4b9eSJuan Quintela     return s->parameters.max_postcopy_bandwidth;
7671dfc4b9eSJuan Quintela }
7681dfc4b9eSJuan Quintela 
769eea1e5c9SSteve Sistare MigMode migrate_mode(void)
770eea1e5c9SSteve Sistare {
771eea1e5c9SSteve Sistare     MigrationState *s = migrate_get_current();
772b12635ffSSteve Sistare     MigMode mode = s->parameters.mode;
773eea1e5c9SSteve Sistare 
774b12635ffSSteve Sistare     assert(mode >= 0 && mode < MIG_MODE__MAX);
775b12635ffSSteve Sistare     return mode;
776eea1e5c9SSteve Sistare }
777eea1e5c9SSteve Sistare 
7781dfc4b9eSJuan Quintela int migrate_multifd_channels(void)
7791dfc4b9eSJuan Quintela {
7808f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7811dfc4b9eSJuan Quintela 
7821dfc4b9eSJuan Quintela     return s->parameters.multifd_channels;
7831dfc4b9eSJuan Quintela }
7841dfc4b9eSJuan Quintela 
7851dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void)
7861dfc4b9eSJuan Quintela {
7878f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7881dfc4b9eSJuan Quintela 
7891dfc4b9eSJuan Quintela     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
7901dfc4b9eSJuan Quintela     return s->parameters.multifd_compression;
7911dfc4b9eSJuan Quintela }
7921dfc4b9eSJuan Quintela 
7931dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void)
7941dfc4b9eSJuan Quintela {
7958f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
7961dfc4b9eSJuan Quintela 
7971dfc4b9eSJuan Quintela     return s->parameters.multifd_zlib_level;
7981dfc4b9eSJuan Quintela }
7991dfc4b9eSJuan Quintela 
800*86c6eb1fSBryan Zhang int migrate_multifd_qatzip_level(void)
801*86c6eb1fSBryan Zhang {
802*86c6eb1fSBryan Zhang     MigrationState *s = migrate_get_current();
803*86c6eb1fSBryan Zhang 
804*86c6eb1fSBryan Zhang     return s->parameters.multifd_qatzip_level;
805*86c6eb1fSBryan Zhang }
806*86c6eb1fSBryan Zhang 
8071dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void)
8081dfc4b9eSJuan Quintela {
8098f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8101dfc4b9eSJuan Quintela 
8111dfc4b9eSJuan Quintela     return s->parameters.multifd_zstd_level;
8121dfc4b9eSJuan Quintela }
8131dfc4b9eSJuan Quintela 
8146499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void)
8156499efdbSJuan Quintela {
8168f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8176499efdbSJuan Quintela 
8186499efdbSJuan Quintela     return s->parameters.throttle_trigger_threshold;
8196499efdbSJuan Quintela }
8206499efdbSJuan Quintela 
8212eb0308bSJuan Quintela const char *migrate_tls_authz(void)
8222eb0308bSJuan Quintela {
8232eb0308bSJuan Quintela     MigrationState *s = migrate_get_current();
8242eb0308bSJuan Quintela 
8252eb0308bSJuan Quintela     return s->parameters.tls_authz;
8262eb0308bSJuan Quintela }
8272eb0308bSJuan Quintela 
828d5c3e195SJuan Quintela const char *migrate_tls_creds(void)
829d5c3e195SJuan Quintela {
830d5c3e195SJuan Quintela     MigrationState *s = migrate_get_current();
831d5c3e195SJuan Quintela 
832d5c3e195SJuan Quintela     return s->parameters.tls_creds;
833d5c3e195SJuan Quintela }
834d5c3e195SJuan Quintela 
8351f2f366cSJuan Quintela const char *migrate_tls_hostname(void)
8361f2f366cSJuan Quintela {
8371f2f366cSJuan Quintela     MigrationState *s = migrate_get_current();
8381f2f366cSJuan Quintela 
8391f2f366cSJuan Quintela     return s->parameters.tls_hostname;
8401f2f366cSJuan Quintela }
8411f2f366cSJuan Quintela 
842714f3312SSteve Sistare uint64_t migrate_vcpu_dirty_limit_period(void)
843714f3312SSteve Sistare {
844714f3312SSteve Sistare     MigrationState *s = migrate_get_current();
845714f3312SSteve Sistare 
846714f3312SSteve Sistare     return s->parameters.x_vcpu_dirty_limit_period;
847714f3312SSteve Sistare }
848714f3312SSteve Sistare 
8491dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void)
8501dfc4b9eSJuan Quintela {
8518f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
8521dfc4b9eSJuan Quintela 
8531dfc4b9eSJuan Quintela     return s->parameters.xbzrle_cache_size;
8541dfc4b9eSJuan Quintela }
8552682c4eeSJuan Quintela 
8565fdbb1dfSHao Xiang ZeroPageDetection migrate_zero_page_detection(void)
8575fdbb1dfSHao Xiang {
8585fdbb1dfSHao Xiang     MigrationState *s = migrate_get_current();
8595fdbb1dfSHao Xiang 
8605fdbb1dfSHao Xiang     return s->parameters.zero_page_detection;
8615fdbb1dfSHao Xiang }
8625fdbb1dfSHao Xiang 
8632682c4eeSJuan Quintela /* parameters helpers */
8642682c4eeSJuan Quintela 
8652682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void)
8662682c4eeSJuan Quintela {
8672682c4eeSJuan Quintela     static AnnounceParameters ap;
8682682c4eeSJuan Quintela 
8692682c4eeSJuan Quintela     MigrationState *s = migrate_get_current();
8702682c4eeSJuan Quintela 
8712682c4eeSJuan Quintela     ap.initial = s->parameters.announce_initial;
8722682c4eeSJuan Quintela     ap.max = s->parameters.announce_max;
8732682c4eeSJuan Quintela     ap.rounds = s->parameters.announce_rounds;
8742682c4eeSJuan Quintela     ap.step = s->parameters.announce_step;
8752682c4eeSJuan Quintela 
8762682c4eeSJuan Quintela     return &ap;
8772682c4eeSJuan Quintela }
8789c894df3SJuan Quintela 
8799c894df3SJuan Quintela MigrationParameters *qmp_query_migrate_parameters(Error **errp)
8809c894df3SJuan Quintela {
8819c894df3SJuan Quintela     MigrationParameters *params;
8829c894df3SJuan Quintela     MigrationState *s = migrate_get_current();
8839c894df3SJuan Quintela 
8849c894df3SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
8859c894df3SJuan Quintela     params = g_malloc0(sizeof(*params));
8869c894df3SJuan Quintela     params->has_throttle_trigger_threshold = true;
8879c894df3SJuan Quintela     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
8889c894df3SJuan Quintela     params->has_cpu_throttle_initial = true;
8899c894df3SJuan Quintela     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
8909c894df3SJuan Quintela     params->has_cpu_throttle_increment = true;
8919c894df3SJuan Quintela     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
8929c894df3SJuan Quintela     params->has_cpu_throttle_tailslow = true;
8939c894df3SJuan Quintela     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
8949c894df3SJuan Quintela     params->tls_creds = g_strdup(s->parameters.tls_creds);
8959c894df3SJuan Quintela     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
8969c894df3SJuan Quintela     params->tls_authz = g_strdup(s->parameters.tls_authz ?
8979c894df3SJuan Quintela                                  s->parameters.tls_authz : "");
8989c894df3SJuan Quintela     params->has_max_bandwidth = true;
8999c894df3SJuan Quintela     params->max_bandwidth = s->parameters.max_bandwidth;
9008b239597SPeter Xu     params->has_avail_switchover_bandwidth = true;
9018b239597SPeter Xu     params->avail_switchover_bandwidth = s->parameters.avail_switchover_bandwidth;
9029c894df3SJuan Quintela     params->has_downtime_limit = true;
9039c894df3SJuan Quintela     params->downtime_limit = s->parameters.downtime_limit;
9049c894df3SJuan Quintela     params->has_x_checkpoint_delay = true;
9059c894df3SJuan Quintela     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
9069c894df3SJuan Quintela     params->has_multifd_channels = true;
9079c894df3SJuan Quintela     params->multifd_channels = s->parameters.multifd_channels;
9089c894df3SJuan Quintela     params->has_multifd_compression = true;
9099c894df3SJuan Quintela     params->multifd_compression = s->parameters.multifd_compression;
9109c894df3SJuan Quintela     params->has_multifd_zlib_level = true;
9119c894df3SJuan Quintela     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
912*86c6eb1fSBryan Zhang     params->has_multifd_qatzip_level = true;
913*86c6eb1fSBryan Zhang     params->multifd_qatzip_level = s->parameters.multifd_qatzip_level;
9149c894df3SJuan Quintela     params->has_multifd_zstd_level = true;
9159c894df3SJuan Quintela     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
9169c894df3SJuan Quintela     params->has_xbzrle_cache_size = true;
9179c894df3SJuan Quintela     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
9189c894df3SJuan Quintela     params->has_max_postcopy_bandwidth = true;
9199c894df3SJuan Quintela     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
9209c894df3SJuan Quintela     params->has_max_cpu_throttle = true;
9219c894df3SJuan Quintela     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
9229c894df3SJuan Quintela     params->has_announce_initial = true;
9239c894df3SJuan Quintela     params->announce_initial = s->parameters.announce_initial;
9249c894df3SJuan Quintela     params->has_announce_max = true;
9259c894df3SJuan Quintela     params->announce_max = s->parameters.announce_max;
9269c894df3SJuan Quintela     params->has_announce_rounds = true;
9279c894df3SJuan Quintela     params->announce_rounds = s->parameters.announce_rounds;
9289c894df3SJuan Quintela     params->has_announce_step = true;
9299c894df3SJuan Quintela     params->announce_step = s->parameters.announce_step;
9309c894df3SJuan Quintela 
9319c894df3SJuan Quintela     if (s->parameters.has_block_bitmap_mapping) {
9329c894df3SJuan Quintela         params->has_block_bitmap_mapping = true;
9339c894df3SJuan Quintela         params->block_bitmap_mapping =
9349c894df3SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
9359c894df3SJuan Quintela                        s->parameters.block_bitmap_mapping);
9369c894df3SJuan Quintela     }
9379c894df3SJuan Quintela 
9384d807857SHyman Huang(黄勇)     params->has_x_vcpu_dirty_limit_period = true;
9394d807857SHyman Huang(黄勇)     params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period;
94009f9ec99SHyman Huang(黄勇)     params->has_vcpu_dirty_limit = true;
94109f9ec99SHyman Huang(黄勇)     params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit;
942eea1e5c9SSteve Sistare     params->has_mode = true;
943eea1e5c9SSteve Sistare     params->mode = s->parameters.mode;
9445fdbb1dfSHao Xiang     params->has_zero_page_detection = true;
9455fdbb1dfSHao Xiang     params->zero_page_detection = s->parameters.zero_page_detection;
946b43b61d5SFabiano Rosas     params->has_direct_io = true;
947b43b61d5SFabiano Rosas     params->direct_io = s->parameters.direct_io;
9484d807857SHyman Huang(黄勇) 
9499c894df3SJuan Quintela     return params;
9509c894df3SJuan Quintela }
95109d6c965SJuan Quintela 
95261a174e2SJuan Quintela void migrate_params_init(MigrationParameters *params)
95361a174e2SJuan Quintela {
95461a174e2SJuan Quintela     params->tls_hostname = g_strdup("");
95561a174e2SJuan Quintela     params->tls_creds = g_strdup("");
95661a174e2SJuan Quintela 
95761a174e2SJuan Quintela     /* Set has_* up only for parameter checks */
95861a174e2SJuan Quintela     params->has_throttle_trigger_threshold = true;
95961a174e2SJuan Quintela     params->has_cpu_throttle_initial = true;
96061a174e2SJuan Quintela     params->has_cpu_throttle_increment = true;
96161a174e2SJuan Quintela     params->has_cpu_throttle_tailslow = true;
96261a174e2SJuan Quintela     params->has_max_bandwidth = true;
96361a174e2SJuan Quintela     params->has_downtime_limit = true;
96461a174e2SJuan Quintela     params->has_x_checkpoint_delay = true;
96561a174e2SJuan Quintela     params->has_multifd_channels = true;
96661a174e2SJuan Quintela     params->has_multifd_compression = true;
96761a174e2SJuan Quintela     params->has_multifd_zlib_level = true;
968*86c6eb1fSBryan Zhang     params->has_multifd_qatzip_level = true;
96961a174e2SJuan Quintela     params->has_multifd_zstd_level = true;
97061a174e2SJuan Quintela     params->has_xbzrle_cache_size = true;
97161a174e2SJuan Quintela     params->has_max_postcopy_bandwidth = true;
97261a174e2SJuan Quintela     params->has_max_cpu_throttle = true;
97361a174e2SJuan Quintela     params->has_announce_initial = true;
97461a174e2SJuan Quintela     params->has_announce_max = true;
97561a174e2SJuan Quintela     params->has_announce_rounds = true;
97661a174e2SJuan Quintela     params->has_announce_step = true;
9774d807857SHyman Huang(黄勇)     params->has_x_vcpu_dirty_limit_period = true;
97809f9ec99SHyman Huang(黄勇)     params->has_vcpu_dirty_limit = true;
979eea1e5c9SSteve Sistare     params->has_mode = true;
9805fdbb1dfSHao Xiang     params->has_zero_page_detection = true;
981b43b61d5SFabiano Rosas     params->has_direct_io = true;
98261a174e2SJuan Quintela }
98361a174e2SJuan Quintela 
98409d6c965SJuan Quintela /*
98509d6c965SJuan Quintela  * Check whether the parameters are valid. Error will be put into errp
98609d6c965SJuan Quintela  * (if provided). Return true if valid, otherwise false.
98709d6c965SJuan Quintela  */
98809d6c965SJuan Quintela bool migrate_params_check(MigrationParameters *params, Error **errp)
98909d6c965SJuan Quintela {
99035e83a9fSZhao Liu     ERRP_GUARD();
99135e83a9fSZhao Liu 
99209d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold &&
99309d6c965SJuan Quintela         (params->throttle_trigger_threshold < 1 ||
99409d6c965SJuan Quintela          params->throttle_trigger_threshold > 100)) {
99509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
99609d6c965SJuan Quintela                    "throttle_trigger_threshold",
99709d6c965SJuan Quintela                    "an integer in the range of 1 to 100");
99809d6c965SJuan Quintela         return false;
99909d6c965SJuan Quintela     }
100009d6c965SJuan Quintela 
100109d6c965SJuan Quintela     if (params->has_cpu_throttle_initial &&
100209d6c965SJuan Quintela         (params->cpu_throttle_initial < 1 ||
100309d6c965SJuan Quintela          params->cpu_throttle_initial > 99)) {
100409d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
100509d6c965SJuan Quintela                    "cpu_throttle_initial",
100609d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
100709d6c965SJuan Quintela         return false;
100809d6c965SJuan Quintela     }
100909d6c965SJuan Quintela 
101009d6c965SJuan Quintela     if (params->has_cpu_throttle_increment &&
101109d6c965SJuan Quintela         (params->cpu_throttle_increment < 1 ||
101209d6c965SJuan Quintela          params->cpu_throttle_increment > 99)) {
101309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
101409d6c965SJuan Quintela                    "cpu_throttle_increment",
101509d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
101609d6c965SJuan Quintela         return false;
101709d6c965SJuan Quintela     }
101809d6c965SJuan Quintela 
101909d6c965SJuan Quintela     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
102009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
102109d6c965SJuan Quintela                    "max_bandwidth",
102209d6c965SJuan Quintela                    "an integer in the range of 0 to "stringify(SIZE_MAX)
102309d6c965SJuan Quintela                    " bytes/second");
102409d6c965SJuan Quintela         return false;
102509d6c965SJuan Quintela     }
102609d6c965SJuan Quintela 
10278b239597SPeter Xu     if (params->has_avail_switchover_bandwidth &&
10288b239597SPeter Xu         (params->avail_switchover_bandwidth > SIZE_MAX)) {
10298b239597SPeter Xu         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
10308b239597SPeter Xu                    "avail_switchover_bandwidth",
10318b239597SPeter Xu                    "an integer in the range of 0 to "stringify(SIZE_MAX)
10328b239597SPeter Xu                    " bytes/second");
10338b239597SPeter Xu         return false;
10348b239597SPeter Xu     }
10358b239597SPeter Xu 
103609d6c965SJuan Quintela     if (params->has_downtime_limit &&
103709d6c965SJuan Quintela         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
103809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
103909d6c965SJuan Quintela                    "downtime_limit",
104009d6c965SJuan Quintela                    "an integer in the range of 0 to "
104109d6c965SJuan Quintela                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
104209d6c965SJuan Quintela         return false;
104309d6c965SJuan Quintela     }
104409d6c965SJuan Quintela 
104509d6c965SJuan Quintela     /* x_checkpoint_delay is now always positive */
104609d6c965SJuan Quintela 
104709d6c965SJuan Quintela     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
104809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
104909d6c965SJuan Quintela                    "multifd_channels",
105009d6c965SJuan Quintela                    "a value between 1 and 255");
105109d6c965SJuan Quintela         return false;
105209d6c965SJuan Quintela     }
105309d6c965SJuan Quintela 
105409d6c965SJuan Quintela     if (params->has_multifd_zlib_level &&
105509d6c965SJuan Quintela         (params->multifd_zlib_level > 9)) {
105609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
105709d6c965SJuan Quintela                    "a value between 0 and 9");
105809d6c965SJuan Quintela         return false;
105909d6c965SJuan Quintela     }
106009d6c965SJuan Quintela 
1061*86c6eb1fSBryan Zhang     if (params->has_multifd_qatzip_level &&
1062*86c6eb1fSBryan Zhang         ((params->multifd_qatzip_level > 9) ||
1063*86c6eb1fSBryan Zhang         (params->multifd_qatzip_level < 1))) {
1064*86c6eb1fSBryan Zhang         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_qatzip_level",
1065*86c6eb1fSBryan Zhang                    "a value between 1 and 9");
1066*86c6eb1fSBryan Zhang         return false;
1067*86c6eb1fSBryan Zhang     }
1068*86c6eb1fSBryan Zhang 
106909d6c965SJuan Quintela     if (params->has_multifd_zstd_level &&
107009d6c965SJuan Quintela         (params->multifd_zstd_level > 20)) {
107109d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
107209d6c965SJuan Quintela                    "a value between 0 and 20");
107309d6c965SJuan Quintela         return false;
107409d6c965SJuan Quintela     }
107509d6c965SJuan Quintela 
107609d6c965SJuan Quintela     if (params->has_xbzrle_cache_size &&
107709d6c965SJuan Quintela         (params->xbzrle_cache_size < qemu_target_page_size() ||
107809d6c965SJuan Quintela          !is_power_of_2(params->xbzrle_cache_size))) {
107909d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
108009d6c965SJuan Quintela                    "xbzrle_cache_size",
108109d6c965SJuan Quintela                    "a power of two no less than the target page size");
108209d6c965SJuan Quintela         return false;
108309d6c965SJuan Quintela     }
108409d6c965SJuan Quintela 
108509d6c965SJuan Quintela     if (params->has_max_cpu_throttle &&
108609d6c965SJuan Quintela         (params->max_cpu_throttle < params->cpu_throttle_initial ||
108709d6c965SJuan Quintela          params->max_cpu_throttle > 99)) {
108809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
108909d6c965SJuan Quintela                    "max_cpu_throttle",
109009d6c965SJuan Quintela                    "an integer in the range of cpu_throttle_initial to 99");
109109d6c965SJuan Quintela         return false;
109209d6c965SJuan Quintela     }
109309d6c965SJuan Quintela 
109409d6c965SJuan Quintela     if (params->has_announce_initial &&
109509d6c965SJuan Quintela         params->announce_initial > 100000) {
109609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
109709d6c965SJuan Quintela                    "announce_initial",
109809d6c965SJuan Quintela                    "a value between 0 and 100000");
109909d6c965SJuan Quintela         return false;
110009d6c965SJuan Quintela     }
110109d6c965SJuan Quintela     if (params->has_announce_max &&
110209d6c965SJuan Quintela         params->announce_max > 100000) {
110309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
110409d6c965SJuan Quintela                    "announce_max",
110509d6c965SJuan Quintela                    "a value between 0 and 100000");
110609d6c965SJuan Quintela        return false;
110709d6c965SJuan Quintela     }
110809d6c965SJuan Quintela     if (params->has_announce_rounds &&
110909d6c965SJuan Quintela         params->announce_rounds > 1000) {
111009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
111109d6c965SJuan Quintela                    "announce_rounds",
111209d6c965SJuan Quintela                    "a value between 0 and 1000");
111309d6c965SJuan Quintela        return false;
111409d6c965SJuan Quintela     }
111509d6c965SJuan Quintela     if (params->has_announce_step &&
111609d6c965SJuan Quintela         (params->announce_step < 1 ||
111709d6c965SJuan Quintela         params->announce_step > 10000)) {
111809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
111909d6c965SJuan Quintela                    "announce_step",
112009d6c965SJuan Quintela                    "a value between 0 and 10000");
112109d6c965SJuan Quintela        return false;
112209d6c965SJuan Quintela     }
112309d6c965SJuan Quintela 
112409d6c965SJuan Quintela     if (params->has_block_bitmap_mapping &&
112509d6c965SJuan Quintela         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
112609d6c965SJuan Quintela         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
112709d6c965SJuan Quintela         return false;
112809d6c965SJuan Quintela     }
112909d6c965SJuan Quintela 
113009d6c965SJuan Quintela #ifdef CONFIG_LINUX
113109d6c965SJuan Quintela     if (migrate_zero_copy_send() &&
113209d6c965SJuan Quintela         ((params->has_multifd_compression && params->multifd_compression) ||
113309d6c965SJuan Quintela          (params->tls_creds && *params->tls_creds))) {
113409d6c965SJuan Quintela         error_setg(errp,
113509d6c965SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
113609d6c965SJuan Quintela         return false;
113709d6c965SJuan Quintela     }
113809d6c965SJuan Quintela #endif
113909d6c965SJuan Quintela 
1140f427d90bSFabiano Rosas     if (migrate_mapped_ram() &&
1141f427d90bSFabiano Rosas         (migrate_multifd_compression() || migrate_tls())) {
1142f427d90bSFabiano Rosas         error_setg(errp,
1143f427d90bSFabiano Rosas                    "Mapped-ram only available for non-compressed non-TLS multifd migration");
1144f427d90bSFabiano Rosas         return false;
1145f427d90bSFabiano Rosas     }
1146f427d90bSFabiano Rosas 
11474d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period &&
11484d807857SHyman Huang(黄勇)         (params->x_vcpu_dirty_limit_period < 1 ||
11494d807857SHyman Huang(黄勇)          params->x_vcpu_dirty_limit_period > 1000)) {
11504d807857SHyman Huang(黄勇)         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
11514d807857SHyman Huang(黄勇)                    "x-vcpu-dirty-limit-period",
11524d807857SHyman Huang(黄勇)                    "a value between 1 and 1000");
11534d807857SHyman Huang(黄勇)         return false;
11544d807857SHyman Huang(黄勇)     }
11554d807857SHyman Huang(黄勇) 
115609f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit &&
115709f9ec99SHyman Huang(黄勇)         (params->vcpu_dirty_limit < 1)) {
115845d19d93SPhilippe Mathieu-Daudé         error_setg(errp,
115945d19d93SPhilippe Mathieu-Daudé                    "Parameter 'vcpu_dirty_limit' must be greater than 1 MB/s");
116009f9ec99SHyman Huang(黄勇)         return false;
116109f9ec99SHyman Huang(黄勇)     }
116209f9ec99SHyman Huang(黄勇) 
1163b43b61d5SFabiano Rosas     if (params->has_direct_io && params->direct_io && !qemu_has_direct_io()) {
1164b43b61d5SFabiano Rosas         error_setg(errp, "No build-time support for direct-io");
1165b43b61d5SFabiano Rosas         return false;
1166b43b61d5SFabiano Rosas     }
1167b43b61d5SFabiano Rosas 
116809d6c965SJuan Quintela     return true;
116909d6c965SJuan Quintela }
117009d6c965SJuan Quintela 
117109d6c965SJuan Quintela static void migrate_params_test_apply(MigrateSetParameters *params,
117209d6c965SJuan Quintela                                       MigrationParameters *dest)
117309d6c965SJuan Quintela {
117409d6c965SJuan Quintela     *dest = migrate_get_current()->parameters;
117509d6c965SJuan Quintela 
117609d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
117709d6c965SJuan Quintela 
117809d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
117909d6c965SJuan Quintela         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
118009d6c965SJuan Quintela     }
118109d6c965SJuan Quintela 
118209d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
118309d6c965SJuan Quintela         dest->cpu_throttle_initial = params->cpu_throttle_initial;
118409d6c965SJuan Quintela     }
118509d6c965SJuan Quintela 
118609d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
118709d6c965SJuan Quintela         dest->cpu_throttle_increment = params->cpu_throttle_increment;
118809d6c965SJuan Quintela     }
118909d6c965SJuan Quintela 
119009d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
119109d6c965SJuan Quintela         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
119209d6c965SJuan Quintela     }
119309d6c965SJuan Quintela 
119409d6c965SJuan Quintela     if (params->tls_creds) {
119509d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
119609d6c965SJuan Quintela         dest->tls_creds = params->tls_creds->u.s;
119709d6c965SJuan Quintela     }
119809d6c965SJuan Quintela 
119909d6c965SJuan Quintela     if (params->tls_hostname) {
120009d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
120109d6c965SJuan Quintela         dest->tls_hostname = params->tls_hostname->u.s;
120209d6c965SJuan Quintela     }
120309d6c965SJuan Quintela 
120409d6c965SJuan Quintela     if (params->has_max_bandwidth) {
120509d6c965SJuan Quintela         dest->max_bandwidth = params->max_bandwidth;
120609d6c965SJuan Quintela     }
120709d6c965SJuan Quintela 
12088b239597SPeter Xu     if (params->has_avail_switchover_bandwidth) {
12098b239597SPeter Xu         dest->avail_switchover_bandwidth = params->avail_switchover_bandwidth;
12108b239597SPeter Xu     }
12118b239597SPeter Xu 
121209d6c965SJuan Quintela     if (params->has_downtime_limit) {
121309d6c965SJuan Quintela         dest->downtime_limit = params->downtime_limit;
121409d6c965SJuan Quintela     }
121509d6c965SJuan Quintela 
121609d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
121709d6c965SJuan Quintela         dest->x_checkpoint_delay = params->x_checkpoint_delay;
121809d6c965SJuan Quintela     }
121909d6c965SJuan Quintela 
122009d6c965SJuan Quintela     if (params->has_multifd_channels) {
122109d6c965SJuan Quintela         dest->multifd_channels = params->multifd_channels;
122209d6c965SJuan Quintela     }
122309d6c965SJuan Quintela     if (params->has_multifd_compression) {
122409d6c965SJuan Quintela         dest->multifd_compression = params->multifd_compression;
122509d6c965SJuan Quintela     }
1226*86c6eb1fSBryan Zhang     if (params->has_multifd_qatzip_level) {
1227*86c6eb1fSBryan Zhang         dest->multifd_qatzip_level = params->multifd_qatzip_level;
1228*86c6eb1fSBryan Zhang     }
1229b4014a2bSBryan Zhang     if (params->has_multifd_zlib_level) {
1230b4014a2bSBryan Zhang         dest->multifd_zlib_level = params->multifd_zlib_level;
1231b4014a2bSBryan Zhang     }
1232b4014a2bSBryan Zhang     if (params->has_multifd_zstd_level) {
1233b4014a2bSBryan Zhang         dest->multifd_zstd_level = params->multifd_zstd_level;
1234b4014a2bSBryan Zhang     }
123509d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
123609d6c965SJuan Quintela         dest->xbzrle_cache_size = params->xbzrle_cache_size;
123709d6c965SJuan Quintela     }
123809d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
123909d6c965SJuan Quintela         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
124009d6c965SJuan Quintela     }
124109d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
124209d6c965SJuan Quintela         dest->max_cpu_throttle = params->max_cpu_throttle;
124309d6c965SJuan Quintela     }
124409d6c965SJuan Quintela     if (params->has_announce_initial) {
124509d6c965SJuan Quintela         dest->announce_initial = params->announce_initial;
124609d6c965SJuan Quintela     }
124709d6c965SJuan Quintela     if (params->has_announce_max) {
124809d6c965SJuan Quintela         dest->announce_max = params->announce_max;
124909d6c965SJuan Quintela     }
125009d6c965SJuan Quintela     if (params->has_announce_rounds) {
125109d6c965SJuan Quintela         dest->announce_rounds = params->announce_rounds;
125209d6c965SJuan Quintela     }
125309d6c965SJuan Quintela     if (params->has_announce_step) {
125409d6c965SJuan Quintela         dest->announce_step = params->announce_step;
125509d6c965SJuan Quintela     }
125609d6c965SJuan Quintela 
125709d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
125809d6c965SJuan Quintela         dest->has_block_bitmap_mapping = true;
125909d6c965SJuan Quintela         dest->block_bitmap_mapping = params->block_bitmap_mapping;
126009d6c965SJuan Quintela     }
12614d807857SHyman Huang(黄勇) 
12624d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period) {
12634d807857SHyman Huang(黄勇)         dest->x_vcpu_dirty_limit_period =
12644d807857SHyman Huang(黄勇)             params->x_vcpu_dirty_limit_period;
12654d807857SHyman Huang(黄勇)     }
126609f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit) {
126709f9ec99SHyman Huang(黄勇)         dest->vcpu_dirty_limit = params->vcpu_dirty_limit;
126809f9ec99SHyman Huang(黄勇)     }
1269eea1e5c9SSteve Sistare 
1270eea1e5c9SSteve Sistare     if (params->has_mode) {
1271eea1e5c9SSteve Sistare         dest->mode = params->mode;
1272eea1e5c9SSteve Sistare     }
12735fdbb1dfSHao Xiang 
12745fdbb1dfSHao Xiang     if (params->has_zero_page_detection) {
12755fdbb1dfSHao Xiang         dest->zero_page_detection = params->zero_page_detection;
12765fdbb1dfSHao Xiang     }
1277b43b61d5SFabiano Rosas 
1278b43b61d5SFabiano Rosas     if (params->has_direct_io) {
1279b43b61d5SFabiano Rosas         dest->direct_io = params->direct_io;
1280b43b61d5SFabiano Rosas     }
128109d6c965SJuan Quintela }
128209d6c965SJuan Quintela 
128309d6c965SJuan Quintela static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
128409d6c965SJuan Quintela {
128509d6c965SJuan Quintela     MigrationState *s = migrate_get_current();
128609d6c965SJuan Quintela 
128709d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
128809d6c965SJuan Quintela 
128909d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
129009d6c965SJuan Quintela         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
129109d6c965SJuan Quintela     }
129209d6c965SJuan Quintela 
129309d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
129409d6c965SJuan Quintela         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
129509d6c965SJuan Quintela     }
129609d6c965SJuan Quintela 
129709d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
129809d6c965SJuan Quintela         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
129909d6c965SJuan Quintela     }
130009d6c965SJuan Quintela 
130109d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
130209d6c965SJuan Quintela         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
130309d6c965SJuan Quintela     }
130409d6c965SJuan Quintela 
130509d6c965SJuan Quintela     if (params->tls_creds) {
130609d6c965SJuan Quintela         g_free(s->parameters.tls_creds);
130709d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
130809d6c965SJuan Quintela         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
130909d6c965SJuan Quintela     }
131009d6c965SJuan Quintela 
131109d6c965SJuan Quintela     if (params->tls_hostname) {
131209d6c965SJuan Quintela         g_free(s->parameters.tls_hostname);
131309d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
131409d6c965SJuan Quintela         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
131509d6c965SJuan Quintela     }
131609d6c965SJuan Quintela 
131709d6c965SJuan Quintela     if (params->tls_authz) {
131809d6c965SJuan Quintela         g_free(s->parameters.tls_authz);
131909d6c965SJuan Quintela         assert(params->tls_authz->type == QTYPE_QSTRING);
132009d6c965SJuan Quintela         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
132109d6c965SJuan Quintela     }
132209d6c965SJuan Quintela 
132309d6c965SJuan Quintela     if (params->has_max_bandwidth) {
132409d6c965SJuan Quintela         s->parameters.max_bandwidth = params->max_bandwidth;
132509d6c965SJuan Quintela         if (s->to_dst_file && !migration_in_postcopy()) {
1326e1fde0e0SJuan Quintela             migration_rate_set(s->parameters.max_bandwidth);
132709d6c965SJuan Quintela         }
132809d6c965SJuan Quintela     }
132909d6c965SJuan Quintela 
13308b239597SPeter Xu     if (params->has_avail_switchover_bandwidth) {
13318b239597SPeter Xu         s->parameters.avail_switchover_bandwidth = params->avail_switchover_bandwidth;
13328b239597SPeter Xu     }
13338b239597SPeter Xu 
133409d6c965SJuan Quintela     if (params->has_downtime_limit) {
133509d6c965SJuan Quintela         s->parameters.downtime_limit = params->downtime_limit;
133609d6c965SJuan Quintela     }
133709d6c965SJuan Quintela 
133809d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
133909d6c965SJuan Quintela         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
13404332ffcdSVladimir Sementsov-Ogievskiy         colo_checkpoint_delay_set();
134109d6c965SJuan Quintela     }
134209d6c965SJuan Quintela 
134309d6c965SJuan Quintela     if (params->has_multifd_channels) {
134409d6c965SJuan Quintela         s->parameters.multifd_channels = params->multifd_channels;
134509d6c965SJuan Quintela     }
134609d6c965SJuan Quintela     if (params->has_multifd_compression) {
134709d6c965SJuan Quintela         s->parameters.multifd_compression = params->multifd_compression;
134809d6c965SJuan Quintela     }
1349*86c6eb1fSBryan Zhang     if (params->has_multifd_qatzip_level) {
1350*86c6eb1fSBryan Zhang         s->parameters.multifd_qatzip_level = params->multifd_qatzip_level;
1351*86c6eb1fSBryan Zhang     }
1352b4014a2bSBryan Zhang     if (params->has_multifd_zlib_level) {
1353b4014a2bSBryan Zhang         s->parameters.multifd_zlib_level = params->multifd_zlib_level;
1354b4014a2bSBryan Zhang     }
1355b4014a2bSBryan Zhang     if (params->has_multifd_zstd_level) {
1356b4014a2bSBryan Zhang         s->parameters.multifd_zstd_level = params->multifd_zstd_level;
1357b4014a2bSBryan Zhang     }
135809d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
135909d6c965SJuan Quintela         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
136009d6c965SJuan Quintela         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
136109d6c965SJuan Quintela     }
136209d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
136309d6c965SJuan Quintela         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
136409d6c965SJuan Quintela         if (s->to_dst_file && migration_in_postcopy()) {
1365e1fde0e0SJuan Quintela             migration_rate_set(s->parameters.max_postcopy_bandwidth);
136609d6c965SJuan Quintela         }
136709d6c965SJuan Quintela     }
136809d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
136909d6c965SJuan Quintela         s->parameters.max_cpu_throttle = params->max_cpu_throttle;
137009d6c965SJuan Quintela     }
137109d6c965SJuan Quintela     if (params->has_announce_initial) {
137209d6c965SJuan Quintela         s->parameters.announce_initial = params->announce_initial;
137309d6c965SJuan Quintela     }
137409d6c965SJuan Quintela     if (params->has_announce_max) {
137509d6c965SJuan Quintela         s->parameters.announce_max = params->announce_max;
137609d6c965SJuan Quintela     }
137709d6c965SJuan Quintela     if (params->has_announce_rounds) {
137809d6c965SJuan Quintela         s->parameters.announce_rounds = params->announce_rounds;
137909d6c965SJuan Quintela     }
138009d6c965SJuan Quintela     if (params->has_announce_step) {
138109d6c965SJuan Quintela         s->parameters.announce_step = params->announce_step;
138209d6c965SJuan Quintela     }
138309d6c965SJuan Quintela 
138409d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
138509d6c965SJuan Quintela         qapi_free_BitmapMigrationNodeAliasList(
138609d6c965SJuan Quintela             s->parameters.block_bitmap_mapping);
138709d6c965SJuan Quintela 
138809d6c965SJuan Quintela         s->parameters.has_block_bitmap_mapping = true;
138909d6c965SJuan Quintela         s->parameters.block_bitmap_mapping =
139009d6c965SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
139109d6c965SJuan Quintela                        params->block_bitmap_mapping);
139209d6c965SJuan Quintela     }
13934d807857SHyman Huang(黄勇) 
13944d807857SHyman Huang(黄勇)     if (params->has_x_vcpu_dirty_limit_period) {
13954d807857SHyman Huang(黄勇)         s->parameters.x_vcpu_dirty_limit_period =
13964d807857SHyman Huang(黄勇)             params->x_vcpu_dirty_limit_period;
13974d807857SHyman Huang(黄勇)     }
139809f9ec99SHyman Huang(黄勇)     if (params->has_vcpu_dirty_limit) {
139909f9ec99SHyman Huang(黄勇)         s->parameters.vcpu_dirty_limit = params->vcpu_dirty_limit;
140009f9ec99SHyman Huang(黄勇)     }
1401eea1e5c9SSteve Sistare 
1402eea1e5c9SSteve Sistare     if (params->has_mode) {
1403eea1e5c9SSteve Sistare         s->parameters.mode = params->mode;
1404eea1e5c9SSteve Sistare     }
14055fdbb1dfSHao Xiang 
14065fdbb1dfSHao Xiang     if (params->has_zero_page_detection) {
14075fdbb1dfSHao Xiang         s->parameters.zero_page_detection = params->zero_page_detection;
14085fdbb1dfSHao Xiang     }
1409b43b61d5SFabiano Rosas 
1410b43b61d5SFabiano Rosas     if (params->has_direct_io) {
1411b43b61d5SFabiano Rosas         s->parameters.direct_io = params->direct_io;
1412b43b61d5SFabiano Rosas     }
141309d6c965SJuan Quintela }
141409d6c965SJuan Quintela 
141509d6c965SJuan Quintela void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
141609d6c965SJuan Quintela {
141709d6c965SJuan Quintela     MigrationParameters tmp;
141809d6c965SJuan Quintela 
141986dec715SPeter Xu     /* TODO Rewrite "" to null instead for all three tls_* parameters */
142009d6c965SJuan Quintela     if (params->tls_creds
142109d6c965SJuan Quintela         && params->tls_creds->type == QTYPE_QNULL) {
142209d6c965SJuan Quintela         qobject_unref(params->tls_creds->u.n);
142309d6c965SJuan Quintela         params->tls_creds->type = QTYPE_QSTRING;
142409d6c965SJuan Quintela         params->tls_creds->u.s = strdup("");
142509d6c965SJuan Quintela     }
142609d6c965SJuan Quintela     if (params->tls_hostname
142709d6c965SJuan Quintela         && params->tls_hostname->type == QTYPE_QNULL) {
142809d6c965SJuan Quintela         qobject_unref(params->tls_hostname->u.n);
142909d6c965SJuan Quintela         params->tls_hostname->type = QTYPE_QSTRING;
143009d6c965SJuan Quintela         params->tls_hostname->u.s = strdup("");
143109d6c965SJuan Quintela     }
143286dec715SPeter Xu     if (params->tls_authz
143386dec715SPeter Xu         && params->tls_authz->type == QTYPE_QNULL) {
143486dec715SPeter Xu         qobject_unref(params->tls_authz->u.n);
143586dec715SPeter Xu         params->tls_authz->type = QTYPE_QSTRING;
143686dec715SPeter Xu         params->tls_authz->u.s = strdup("");
143786dec715SPeter Xu     }
143809d6c965SJuan Quintela 
143909d6c965SJuan Quintela     migrate_params_test_apply(params, &tmp);
144009d6c965SJuan Quintela 
144109d6c965SJuan Quintela     if (!migrate_params_check(&tmp, errp)) {
144209d6c965SJuan Quintela         /* Invalid parameter */
144309d6c965SJuan Quintela         return;
144409d6c965SJuan Quintela     }
144509d6c965SJuan Quintela 
144609d6c965SJuan Quintela     migrate_params_apply(params, errp);
144709d6c965SJuan Quintela }
1448