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" 301f0776f1SJuan Quintela 3109d6c965SJuan Quintela /* Maximum migrate downtime set to 2000 seconds */ 3209d6c965SJuan Quintela #define MAX_MIGRATE_DOWNTIME_SECONDS 2000 3309d6c965SJuan Quintela #define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000) 3409d6c965SJuan Quintela 35f9436522SJuan Quintela #define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */ 36f9436522SJuan Quintela 37f9436522SJuan Quintela /* Time in milliseconds we are allowed to stop the source, 38f9436522SJuan Quintela * for sending the last part */ 39f9436522SJuan Quintela #define DEFAULT_MIGRATE_SET_DOWNTIME 300 40f9436522SJuan Quintela 41f9436522SJuan Quintela /* Default compression thread count */ 42f9436522SJuan Quintela #define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8 43f9436522SJuan Quintela /* Default decompression thread count, usually decompression is at 44f9436522SJuan Quintela * least 4 times as fast as compression.*/ 45f9436522SJuan Quintela #define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2 46f9436522SJuan Quintela /*0: means nocompress, 1: best speed, ... 9: best compress ratio */ 47f9436522SJuan Quintela #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1 48f9436522SJuan Quintela /* Define default autoconverge cpu throttle migration parameters */ 49f9436522SJuan Quintela #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50 50f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20 51f9436522SJuan Quintela #define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10 52f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99 53f9436522SJuan Quintela 54f9436522SJuan Quintela /* Migration XBZRLE default cache size */ 55f9436522SJuan Quintela #define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024) 56f9436522SJuan Quintela 57f9436522SJuan Quintela /* The delay time (in ms) between two COLO checkpoints */ 58f9436522SJuan Quintela #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100) 59f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2 60f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE 61f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 9: best compress ratio */ 62f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1 63f9436522SJuan Quintela /* 0: means nocompress, 1: best speed, ... 20: best compress ratio */ 64f9436522SJuan Quintela #define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1 65f9436522SJuan Quintela 66f9436522SJuan Quintela /* Background transfer rate for postcopy, 0 means unlimited, note 67f9436522SJuan Quintela * that page requests can still exceed this limit. 68f9436522SJuan Quintela */ 69f9436522SJuan Quintela #define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0 70f9436522SJuan Quintela 71f9436522SJuan Quintela /* 72f9436522SJuan Quintela * Parameters for self_announce_delay giving a stream of RARP/ARP 73f9436522SJuan Quintela * packets after migration. 74f9436522SJuan Quintela */ 75f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_INITIAL 50 76f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_MAX 550 77f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS 5 78f9436522SJuan Quintela #define DEFAULT_MIGRATE_ANNOUNCE_STEP 100 79f9436522SJuan Quintela 80f9436522SJuan Quintela #define DEFINE_PROP_MIG_CAP(name, x) \ 81f9436522SJuan Quintela DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false) 82f9436522SJuan Quintela 834d807857SHyman Huang(黄勇) #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD 1000 /* milliseconds */ 84*09f9ec99SHyman Huang(黄勇) #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT 1 /* MB/s */ 854d807857SHyman Huang(黄勇) 86f9436522SJuan Quintela Property migration_properties[] = { 87f9436522SJuan Quintela DEFINE_PROP_BOOL("store-global-state", MigrationState, 88f9436522SJuan Quintela store_global_state, true), 89f9436522SJuan Quintela DEFINE_PROP_BOOL("send-configuration", MigrationState, 90f9436522SJuan Quintela send_configuration, true), 91f9436522SJuan Quintela DEFINE_PROP_BOOL("send-section-footer", MigrationState, 92f9436522SJuan Quintela send_section_footer, true), 93f9436522SJuan Quintela DEFINE_PROP_BOOL("decompress-error-check", MigrationState, 94f9436522SJuan Quintela decompress_error_check, 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-compress-level", MigrationState, 104f9436522SJuan Quintela parameters.compress_level, 105f9436522SJuan Quintela DEFAULT_MIGRATE_COMPRESS_LEVEL), 106f9436522SJuan Quintela DEFINE_PROP_UINT8("x-compress-threads", MigrationState, 107f9436522SJuan Quintela parameters.compress_threads, 108f9436522SJuan Quintela DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT), 109f9436522SJuan Quintela DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState, 110f9436522SJuan Quintela parameters.compress_wait_thread, true), 111f9436522SJuan Quintela DEFINE_PROP_UINT8("x-decompress-threads", MigrationState, 112f9436522SJuan Quintela parameters.decompress_threads, 113f9436522SJuan Quintela DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT), 114f9436522SJuan Quintela DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState, 115f9436522SJuan Quintela parameters.throttle_trigger_threshold, 116f9436522SJuan Quintela DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD), 117f9436522SJuan Quintela DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState, 118f9436522SJuan Quintela parameters.cpu_throttle_initial, 119f9436522SJuan Quintela DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL), 120f9436522SJuan Quintela DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState, 121f9436522SJuan Quintela parameters.cpu_throttle_increment, 122f9436522SJuan Quintela DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT), 123f9436522SJuan Quintela DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState, 124f9436522SJuan Quintela parameters.cpu_throttle_tailslow, false), 125f9436522SJuan Quintela DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState, 126f9436522SJuan Quintela parameters.max_bandwidth, MAX_THROTTLE), 127f9436522SJuan Quintela DEFINE_PROP_UINT64("x-downtime-limit", MigrationState, 128f9436522SJuan Quintela parameters.downtime_limit, 129f9436522SJuan Quintela DEFAULT_MIGRATE_SET_DOWNTIME), 130f9436522SJuan Quintela DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState, 131f9436522SJuan Quintela parameters.x_checkpoint_delay, 132f9436522SJuan Quintela DEFAULT_MIGRATE_X_CHECKPOINT_DELAY), 133f9436522SJuan Quintela DEFINE_PROP_UINT8("multifd-channels", MigrationState, 134f9436522SJuan Quintela parameters.multifd_channels, 135f9436522SJuan Quintela DEFAULT_MIGRATE_MULTIFD_CHANNELS), 136f9436522SJuan Quintela DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState, 137f9436522SJuan Quintela parameters.multifd_compression, 138f9436522SJuan Quintela DEFAULT_MIGRATE_MULTIFD_COMPRESSION), 139f9436522SJuan Quintela DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState, 140f9436522SJuan Quintela parameters.multifd_zlib_level, 141f9436522SJuan Quintela DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL), 142f9436522SJuan Quintela DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState, 143f9436522SJuan Quintela parameters.multifd_zstd_level, 144f9436522SJuan Quintela DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL), 145f9436522SJuan Quintela DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState, 146f9436522SJuan Quintela parameters.xbzrle_cache_size, 147f9436522SJuan Quintela DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE), 148f9436522SJuan Quintela DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState, 149f9436522SJuan Quintela parameters.max_postcopy_bandwidth, 150f9436522SJuan Quintela DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH), 151f9436522SJuan Quintela DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState, 152f9436522SJuan Quintela parameters.max_cpu_throttle, 153f9436522SJuan Quintela DEFAULT_MIGRATE_MAX_CPU_THROTTLE), 154f9436522SJuan Quintela DEFINE_PROP_SIZE("announce-initial", MigrationState, 155f9436522SJuan Quintela parameters.announce_initial, 156f9436522SJuan Quintela DEFAULT_MIGRATE_ANNOUNCE_INITIAL), 157f9436522SJuan Quintela DEFINE_PROP_SIZE("announce-max", MigrationState, 158f9436522SJuan Quintela parameters.announce_max, 159f9436522SJuan Quintela DEFAULT_MIGRATE_ANNOUNCE_MAX), 160f9436522SJuan Quintela DEFINE_PROP_SIZE("announce-rounds", MigrationState, 161f9436522SJuan Quintela parameters.announce_rounds, 162f9436522SJuan Quintela DEFAULT_MIGRATE_ANNOUNCE_ROUNDS), 163f9436522SJuan Quintela DEFINE_PROP_SIZE("announce-step", MigrationState, 164f9436522SJuan Quintela parameters.announce_step, 165f9436522SJuan Quintela DEFAULT_MIGRATE_ANNOUNCE_STEP), 166f9436522SJuan Quintela DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds), 167f9436522SJuan Quintela DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname), 168f9436522SJuan Quintela DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz), 1694d807857SHyman Huang(黄勇) DEFINE_PROP_UINT64("x-vcpu-dirty-limit-period", MigrationState, 1704d807857SHyman Huang(黄勇) parameters.x_vcpu_dirty_limit_period, 1714d807857SHyman Huang(黄勇) DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD), 172*09f9ec99SHyman Huang(黄勇) DEFINE_PROP_UINT64("vcpu-dirty-limit", MigrationState, 173*09f9ec99SHyman Huang(黄勇) parameters.vcpu_dirty_limit, 174*09f9ec99SHyman Huang(黄勇) DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT), 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-compress", MIGRATION_CAPABILITY_COMPRESS), 182f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS), 183f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM), 184f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-postcopy-preempt", 185f9436522SJuan Quintela MIGRATION_CAPABILITY_POSTCOPY_PREEMPT), 186f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO), 187f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM), 188f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK), 189f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH), 190f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD), 191f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-background-snapshot", 192f9436522SJuan Quintela MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT), 193f9436522SJuan Quintela #ifdef CONFIG_LINUX 194f9436522SJuan Quintela DEFINE_PROP_MIG_CAP("x-zero-copy-send", 195f9436522SJuan Quintela MIGRATION_CAPABILITY_ZERO_COPY_SEND), 196f9436522SJuan Quintela #endif 1976574232fSAvihai Horon DEFINE_PROP_MIG_CAP("x-switchover-ack", 1986574232fSAvihai Horon MIGRATION_CAPABILITY_SWITCHOVER_ACK), 199f9436522SJuan Quintela 200f9436522SJuan Quintela DEFINE_PROP_END_OF_LIST(), 201f9436522SJuan Quintela }; 202f9436522SJuan Quintela 2031f0776f1SJuan Quintela bool migrate_auto_converge(void) 2041f0776f1SJuan Quintela { 2058f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2061f0776f1SJuan Quintela 2071f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE]; 2081f0776f1SJuan Quintela } 2091f0776f1SJuan Quintela 2101f0776f1SJuan Quintela bool migrate_background_snapshot(void) 2111f0776f1SJuan Quintela { 2128f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2131f0776f1SJuan Quintela 2141f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; 2151f0776f1SJuan Quintela } 2161f0776f1SJuan Quintela 2179d4b1e5fSJuan Quintela bool migrate_block(void) 2189d4b1e5fSJuan Quintela { 2198f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2209d4b1e5fSJuan Quintela 2219d4b1e5fSJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_BLOCK]; 2229d4b1e5fSJuan Quintela } 2239d4b1e5fSJuan Quintela 2245e804644SJuan Quintela bool migrate_colo(void) 2255e804644SJuan Quintela { 2265e804644SJuan Quintela MigrationState *s = migrate_get_current(); 2278f9c5327SJuan Quintela 2285e804644SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_X_COLO]; 2295e804644SJuan Quintela } 2305e804644SJuan Quintela 231a7a94d14SJuan Quintela bool migrate_compress(void) 232a7a94d14SJuan Quintela { 2338f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 234a7a94d14SJuan Quintela 235a7a94d14SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_COMPRESS]; 236a7a94d14SJuan Quintela } 237a7a94d14SJuan Quintela 2381f0776f1SJuan Quintela bool migrate_dirty_bitmaps(void) 2391f0776f1SJuan Quintela { 2408f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2411f0776f1SJuan Quintela 2421f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; 2431f0776f1SJuan Quintela } 2441f0776f1SJuan Quintela 245b890902cSJuan Quintela bool migrate_events(void) 246b890902cSJuan Quintela { 2478f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 248b890902cSJuan Quintela 249b890902cSJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_EVENTS]; 250b890902cSJuan Quintela } 251b890902cSJuan Quintela 2521f0776f1SJuan Quintela bool migrate_ignore_shared(void) 2531f0776f1SJuan Quintela { 2548f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2551f0776f1SJuan Quintela 2561f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED]; 2571f0776f1SJuan Quintela } 2581f0776f1SJuan Quintela 2591f0776f1SJuan Quintela bool migrate_late_block_activate(void) 2601f0776f1SJuan Quintela { 2618f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2621f0776f1SJuan Quintela 2631f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; 2641f0776f1SJuan Quintela } 2651f0776f1SJuan Quintela 26651b07548SJuan Quintela bool migrate_multifd(void) 26751b07548SJuan Quintela { 2688f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 26951b07548SJuan Quintela 27051b07548SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_MULTIFD]; 27151b07548SJuan Quintela } 27251b07548SJuan Quintela 2731f0776f1SJuan Quintela bool migrate_pause_before_switchover(void) 2741f0776f1SJuan Quintela { 2758f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2761f0776f1SJuan Quintela 2771f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER]; 2781f0776f1SJuan Quintela } 2791f0776f1SJuan Quintela 2801f0776f1SJuan Quintela bool migrate_postcopy_blocktime(void) 2811f0776f1SJuan Quintela { 2828f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2831f0776f1SJuan Quintela 2841f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME]; 2851f0776f1SJuan Quintela } 2861f0776f1SJuan Quintela 2871f0776f1SJuan Quintela bool migrate_postcopy_preempt(void) 2881f0776f1SJuan Quintela { 2898f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2901f0776f1SJuan Quintela 2911f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]; 2921f0776f1SJuan Quintela } 2931f0776f1SJuan Quintela 2941f0776f1SJuan Quintela bool migrate_postcopy_ram(void) 2951f0776f1SJuan Quintela { 2968f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 2971f0776f1SJuan Quintela 2981f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; 2991f0776f1SJuan Quintela } 3001f0776f1SJuan Quintela 30117cba690SJuan Quintela bool migrate_rdma_pin_all(void) 30217cba690SJuan Quintela { 30317cba690SJuan Quintela MigrationState *s = migrate_get_current(); 30417cba690SJuan Quintela 30517cba690SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL]; 30617cba690SJuan Quintela } 30717cba690SJuan Quintela 3081f0776f1SJuan Quintela bool migrate_release_ram(void) 3091f0776f1SJuan Quintela { 3108f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 3111f0776f1SJuan Quintela 3121f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; 3131f0776f1SJuan Quintela } 3141f0776f1SJuan Quintela 31538ad1110SJuan Quintela bool migrate_return_path(void) 31638ad1110SJuan Quintela { 3178f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 31838ad1110SJuan Quintela 31938ad1110SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH]; 32038ad1110SJuan Quintela } 32138ad1110SJuan Quintela 3226574232fSAvihai Horon bool migrate_switchover_ack(void) 3236574232fSAvihai Horon { 3246574232fSAvihai Horon MigrationState *s = migrate_get_current(); 3256574232fSAvihai Horon 3266574232fSAvihai Horon return s->capabilities[MIGRATION_CAPABILITY_SWITCHOVER_ACK]; 3276574232fSAvihai Horon } 3286574232fSAvihai Horon 3291f0776f1SJuan Quintela bool migrate_validate_uuid(void) 3301f0776f1SJuan Quintela { 3318f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 3321f0776f1SJuan Quintela 3331f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; 3341f0776f1SJuan Quintela } 3351f0776f1SJuan Quintela 33687dca0c9SJuan Quintela bool migrate_xbzrle(void) 33787dca0c9SJuan Quintela { 3388f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 33987dca0c9SJuan Quintela 34087dca0c9SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_XBZRLE]; 34187dca0c9SJuan Quintela } 34287dca0c9SJuan Quintela 3431f0776f1SJuan Quintela bool migrate_zero_blocks(void) 3441f0776f1SJuan Quintela { 3458f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 3461f0776f1SJuan Quintela 3471f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; 3481f0776f1SJuan Quintela } 349b4bc342cSJuan Quintela 350b4bc342cSJuan Quintela bool migrate_zero_copy_send(void) 351b4bc342cSJuan Quintela { 3528f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 353b4bc342cSJuan Quintela 354b4bc342cSJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; 355b4bc342cSJuan Quintela } 356f774fde5SJuan Quintela 357f774fde5SJuan Quintela /* pseudo capabilities */ 358f774fde5SJuan Quintela 35977c259a4SJuan Quintela bool migrate_multifd_flush_after_each_section(void) 36077c259a4SJuan Quintela { 36177c259a4SJuan Quintela MigrationState *s = migrate_get_current(); 36277c259a4SJuan Quintela 363294e5a40SJuan Quintela return s->multifd_flush_after_each_section; 36477c259a4SJuan Quintela } 36577c259a4SJuan Quintela 366f774fde5SJuan Quintela bool migrate_postcopy(void) 367f774fde5SJuan Quintela { 368f774fde5SJuan Quintela return migrate_postcopy_ram() || migrate_dirty_bitmaps(); 369f774fde5SJuan Quintela } 370f774fde5SJuan Quintela 37110d4703bSJuan Quintela bool migrate_tls(void) 37210d4703bSJuan Quintela { 3738f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 37410d4703bSJuan Quintela 37510d4703bSJuan Quintela return s->parameters.tls_creds && *s->parameters.tls_creds; 37610d4703bSJuan Quintela } 37710d4703bSJuan Quintela 37877608706SJuan Quintela typedef enum WriteTrackingSupport { 37977608706SJuan Quintela WT_SUPPORT_UNKNOWN = 0, 38077608706SJuan Quintela WT_SUPPORT_ABSENT, 38177608706SJuan Quintela WT_SUPPORT_AVAILABLE, 38277608706SJuan Quintela WT_SUPPORT_COMPATIBLE 38377608706SJuan Quintela } WriteTrackingSupport; 38477608706SJuan Quintela 38577608706SJuan Quintela static 38677608706SJuan Quintela WriteTrackingSupport migrate_query_write_tracking(void) 38777608706SJuan Quintela { 38877608706SJuan Quintela /* Check if kernel supports required UFFD features */ 38977608706SJuan Quintela if (!ram_write_tracking_available()) { 39077608706SJuan Quintela return WT_SUPPORT_ABSENT; 39177608706SJuan Quintela } 39277608706SJuan Quintela /* 39377608706SJuan Quintela * Check if current memory configuration is 39477608706SJuan Quintela * compatible with required UFFD features. 39577608706SJuan Quintela */ 39677608706SJuan Quintela if (!ram_write_tracking_compatible()) { 39777608706SJuan Quintela return WT_SUPPORT_AVAILABLE; 39877608706SJuan Quintela } 39977608706SJuan Quintela 40077608706SJuan Quintela return WT_SUPPORT_COMPATIBLE; 40177608706SJuan Quintela } 40277608706SJuan Quintela 40377608706SJuan Quintela /* Migration capabilities set */ 40477608706SJuan Quintela struct MigrateCapsSet { 40577608706SJuan Quintela int size; /* Capability set size */ 40677608706SJuan Quintela MigrationCapability caps[]; /* Variadic array of capabilities */ 40777608706SJuan Quintela }; 40877608706SJuan Quintela typedef struct MigrateCapsSet MigrateCapsSet; 40977608706SJuan Quintela 41077608706SJuan Quintela /* Define and initialize MigrateCapsSet */ 41177608706SJuan Quintela #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...) \ 41277608706SJuan Quintela MigrateCapsSet _name = { \ 41377608706SJuan Quintela .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \ 41477608706SJuan Quintela .caps = { __VA_ARGS__ } \ 41577608706SJuan Quintela } 41677608706SJuan Quintela 41777608706SJuan Quintela /* Background-snapshot compatibility check list */ 41877608706SJuan Quintela static const 41977608706SJuan Quintela INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot, 42077608706SJuan Quintela MIGRATION_CAPABILITY_POSTCOPY_RAM, 42177608706SJuan Quintela MIGRATION_CAPABILITY_DIRTY_BITMAPS, 42277608706SJuan Quintela MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME, 42377608706SJuan Quintela MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE, 42477608706SJuan Quintela MIGRATION_CAPABILITY_RETURN_PATH, 42577608706SJuan Quintela MIGRATION_CAPABILITY_MULTIFD, 42677608706SJuan Quintela MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER, 42777608706SJuan Quintela MIGRATION_CAPABILITY_AUTO_CONVERGE, 42877608706SJuan Quintela MIGRATION_CAPABILITY_RELEASE_RAM, 42977608706SJuan Quintela MIGRATION_CAPABILITY_RDMA_PIN_ALL, 43077608706SJuan Quintela MIGRATION_CAPABILITY_COMPRESS, 43177608706SJuan Quintela MIGRATION_CAPABILITY_XBZRLE, 43277608706SJuan Quintela MIGRATION_CAPABILITY_X_COLO, 43377608706SJuan Quintela MIGRATION_CAPABILITY_VALIDATE_UUID, 43477608706SJuan Quintela MIGRATION_CAPABILITY_ZERO_COPY_SEND); 43577608706SJuan Quintela 43677608706SJuan Quintela /** 43777608706SJuan Quintela * @migration_caps_check - check capability compatibility 43877608706SJuan Quintela * 43977608706SJuan Quintela * @old_caps: old capability list 44077608706SJuan Quintela * @new_caps: new capability list 44177608706SJuan Quintela * @errp: set *errp if the check failed, with reason 44277608706SJuan Quintela * 44377608706SJuan Quintela * Returns true if check passed, otherwise false. 44477608706SJuan Quintela */ 44577608706SJuan Quintela bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) 44677608706SJuan Quintela { 44777608706SJuan Quintela MigrationIncomingState *mis = migration_incoming_get_current(); 44877608706SJuan Quintela 44974c38cf7SPeter Xu ERRP_GUARD(); 45077608706SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION 45177608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_BLOCK]) { 45277608706SJuan Quintela error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) " 45377608706SJuan Quintela "block migration"); 45477608706SJuan Quintela error_append_hint(errp, "Use drive_mirror+NBD instead.\n"); 45577608706SJuan Quintela return false; 45677608706SJuan Quintela } 45777608706SJuan Quintela #endif 45877608706SJuan Quintela 45977608706SJuan Quintela #ifndef CONFIG_REPLICATION 46077608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_X_COLO]) { 46177608706SJuan Quintela error_setg(errp, "QEMU compiled without replication module" 46277608706SJuan Quintela " can't enable COLO"); 46377608706SJuan Quintela error_append_hint(errp, "Please enable replication before COLO.\n"); 46477608706SJuan Quintela return false; 46577608706SJuan Quintela } 46677608706SJuan Quintela #endif 46777608706SJuan Quintela 46877608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { 46977608706SJuan Quintela /* This check is reasonably expensive, so only when it's being 47077608706SJuan Quintela * set the first time, also it's only the destination that needs 47177608706SJuan Quintela * special support. 47277608706SJuan Quintela */ 47377608706SJuan Quintela if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] && 47477608706SJuan Quintela runstate_check(RUN_STATE_INMIGRATE) && 47574c38cf7SPeter Xu !postcopy_ram_supported_by_host(mis, errp)) { 47674c38cf7SPeter Xu error_prepend(errp, "Postcopy is not supported: "); 47777608706SJuan Quintela return false; 47877608706SJuan Quintela } 47977608706SJuan Quintela 48077608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) { 48177608706SJuan Quintela error_setg(errp, "Postcopy is not compatible with ignore-shared"); 48277608706SJuan Quintela return false; 48377608706SJuan Quintela } 484b405dfffSLeonardo Bras 485b405dfffSLeonardo Bras if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { 486b405dfffSLeonardo Bras error_setg(errp, "Postcopy is not yet compatible with multifd"); 487b405dfffSLeonardo Bras return false; 488b405dfffSLeonardo Bras } 48977608706SJuan Quintela } 49077608706SJuan Quintela 49177608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) { 49277608706SJuan Quintela WriteTrackingSupport wt_support; 49377608706SJuan Quintela int idx; 49477608706SJuan Quintela /* 49577608706SJuan Quintela * Check if 'background-snapshot' capability is supported by 49677608706SJuan Quintela * host kernel and compatible with guest memory configuration. 49777608706SJuan Quintela */ 49877608706SJuan Quintela wt_support = migrate_query_write_tracking(); 49977608706SJuan Quintela if (wt_support < WT_SUPPORT_AVAILABLE) { 50077608706SJuan Quintela error_setg(errp, "Background-snapshot is not supported by host kernel"); 50177608706SJuan Quintela return false; 50277608706SJuan Quintela } 50377608706SJuan Quintela if (wt_support < WT_SUPPORT_COMPATIBLE) { 50477608706SJuan Quintela error_setg(errp, "Background-snapshot is not compatible " 50577608706SJuan Quintela "with guest memory configuration"); 50677608706SJuan Quintela return false; 50777608706SJuan Quintela } 50877608706SJuan Quintela 50977608706SJuan Quintela /* 51077608706SJuan Quintela * Check if there are any migration capabilities 51177608706SJuan Quintela * incompatible with 'background-snapshot'. 51277608706SJuan Quintela */ 51377608706SJuan Quintela for (idx = 0; idx < check_caps_background_snapshot.size; idx++) { 51477608706SJuan Quintela int incomp_cap = check_caps_background_snapshot.caps[idx]; 51577608706SJuan Quintela if (new_caps[incomp_cap]) { 51677608706SJuan Quintela error_setg(errp, 51777608706SJuan Quintela "Background-snapshot is not compatible with %s", 51877608706SJuan Quintela MigrationCapability_str(incomp_cap)); 51977608706SJuan Quintela return false; 52077608706SJuan Quintela } 52177608706SJuan Quintela } 52277608706SJuan Quintela } 52377608706SJuan Quintela 52477608706SJuan Quintela #ifdef CONFIG_LINUX 52577608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] && 52677608706SJuan Quintela (!new_caps[MIGRATION_CAPABILITY_MULTIFD] || 52777608706SJuan Quintela new_caps[MIGRATION_CAPABILITY_COMPRESS] || 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 54977608706SJuan Quintela /* 55077608706SJuan Quintela * Preempt mode requires urgent pages to be sent in separate 55177608706SJuan Quintela * channel, OTOH compression logic will disorder all pages into 55277608706SJuan Quintela * different compression channels, which is not compatible with the 55377608706SJuan Quintela * preempt assumptions on channel assignments. 55477608706SJuan Quintela */ 55577608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { 55677608706SJuan Quintela error_setg(errp, "Postcopy preempt not compatible with compress"); 55777608706SJuan Quintela return false; 55877608706SJuan Quintela } 55977608706SJuan Quintela } 56077608706SJuan Quintela 56177608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { 56277608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { 56377608706SJuan Quintela error_setg(errp, "Multifd is not compatible with compress"); 56477608706SJuan Quintela return false; 56577608706SJuan Quintela } 56677608706SJuan Quintela } 56777608706SJuan Quintela 5686574232fSAvihai Horon if (new_caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK]) { 5696574232fSAvihai Horon if (!new_caps[MIGRATION_CAPABILITY_RETURN_PATH]) { 5706574232fSAvihai Horon error_setg(errp, "Capability 'switchover-ack' requires capability " 5716574232fSAvihai Horon "'return-path'"); 5726574232fSAvihai Horon return false; 5736574232fSAvihai Horon } 5746574232fSAvihai Horon } 5756574232fSAvihai Horon 57677608706SJuan Quintela return true; 57777608706SJuan Quintela } 5784d0c6b69SJuan Quintela 579f80196b7SJuan Quintela bool migrate_cap_set(int cap, bool value, Error **errp) 580f80196b7SJuan Quintela { 581f80196b7SJuan Quintela MigrationState *s = migrate_get_current(); 582f80196b7SJuan Quintela bool new_caps[MIGRATION_CAPABILITY__MAX]; 583f80196b7SJuan Quintela 584f80196b7SJuan Quintela if (migration_is_running(s->state)) { 585f80196b7SJuan Quintela error_setg(errp, QERR_MIGRATION_ACTIVE); 586f80196b7SJuan Quintela return false; 587f80196b7SJuan Quintela } 588f80196b7SJuan Quintela 589f80196b7SJuan Quintela memcpy(new_caps, s->capabilities, sizeof(new_caps)); 590f80196b7SJuan Quintela new_caps[cap] = value; 591f80196b7SJuan Quintela 592f80196b7SJuan Quintela if (!migrate_caps_check(s->capabilities, new_caps, errp)) { 593f80196b7SJuan Quintela return false; 594f80196b7SJuan Quintela } 595f80196b7SJuan Quintela s->capabilities[cap] = value; 596f80196b7SJuan Quintela return true; 597f80196b7SJuan Quintela } 598f80196b7SJuan Quintela 5994d0c6b69SJuan Quintela MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) 6004d0c6b69SJuan Quintela { 6014d0c6b69SJuan Quintela MigrationCapabilityStatusList *head = NULL, **tail = &head; 6024d0c6b69SJuan Quintela MigrationCapabilityStatus *caps; 6034d0c6b69SJuan Quintela MigrationState *s = migrate_get_current(); 6044d0c6b69SJuan Quintela int i; 6054d0c6b69SJuan Quintela 6064d0c6b69SJuan Quintela for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { 6074d0c6b69SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION 6084d0c6b69SJuan Quintela if (i == MIGRATION_CAPABILITY_BLOCK) { 6094d0c6b69SJuan Quintela continue; 6104d0c6b69SJuan Quintela } 6114d0c6b69SJuan Quintela #endif 6124d0c6b69SJuan Quintela caps = g_malloc0(sizeof(*caps)); 6134d0c6b69SJuan Quintela caps->capability = i; 6144d0c6b69SJuan Quintela caps->state = s->capabilities[i]; 6154d0c6b69SJuan Quintela QAPI_LIST_APPEND(tail, caps); 6164d0c6b69SJuan Quintela } 6174d0c6b69SJuan Quintela 6184d0c6b69SJuan Quintela return head; 6194d0c6b69SJuan Quintela } 62045c1de13SJuan Quintela 62145c1de13SJuan Quintela void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, 62245c1de13SJuan Quintela Error **errp) 62345c1de13SJuan Quintela { 62445c1de13SJuan Quintela MigrationState *s = migrate_get_current(); 62545c1de13SJuan Quintela MigrationCapabilityStatusList *cap; 62645c1de13SJuan Quintela bool new_caps[MIGRATION_CAPABILITY__MAX]; 62745c1de13SJuan Quintela 628d70178a8SVladimir Sementsov-Ogievskiy if (migration_is_running(s->state) || migration_in_colo_state()) { 62945c1de13SJuan Quintela error_setg(errp, QERR_MIGRATION_ACTIVE); 63045c1de13SJuan Quintela return; 63145c1de13SJuan Quintela } 63245c1de13SJuan Quintela 63345c1de13SJuan Quintela memcpy(new_caps, s->capabilities, sizeof(new_caps)); 63445c1de13SJuan Quintela for (cap = params; cap; cap = cap->next) { 63545c1de13SJuan Quintela new_caps[cap->value->capability] = cap->value->state; 63645c1de13SJuan Quintela } 63745c1de13SJuan Quintela 63845c1de13SJuan Quintela if (!migrate_caps_check(s->capabilities, new_caps, errp)) { 63945c1de13SJuan Quintela return; 64045c1de13SJuan Quintela } 64145c1de13SJuan Quintela 64245c1de13SJuan Quintela for (cap = params; cap; cap = cap->next) { 64345c1de13SJuan Quintela s->capabilities[cap->value->capability] = cap->value->state; 64445c1de13SJuan Quintela } 64545c1de13SJuan Quintela } 6461dfc4b9eSJuan Quintela 6471dfc4b9eSJuan Quintela /* parameters */ 6481dfc4b9eSJuan Quintela 649b804b35bSJuan Quintela const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void) 650b804b35bSJuan Quintela { 651b804b35bSJuan Quintela MigrationState *s = migrate_get_current(); 652b804b35bSJuan Quintela 653b804b35bSJuan Quintela return s->parameters.block_bitmap_mapping; 654b804b35bSJuan Quintela } 655b804b35bSJuan Quintela 6563cba22c9SJuan Quintela bool migrate_has_block_bitmap_mapping(void) 6573cba22c9SJuan Quintela { 6583cba22c9SJuan Quintela MigrationState *s = migrate_get_current(); 6593cba22c9SJuan Quintela 6603cba22c9SJuan Quintela return s->parameters.has_block_bitmap_mapping; 6613cba22c9SJuan Quintela } 6623cba22c9SJuan Quintela 6636f8be708SJuan Quintela bool migrate_block_incremental(void) 6646f8be708SJuan Quintela { 6658f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 6666f8be708SJuan Quintela 6676f8be708SJuan Quintela return s->parameters.block_incremental; 6686f8be708SJuan Quintela } 6696f8be708SJuan Quintela 670f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void) 671f94a858fSJuan Quintela { 6728f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 673f94a858fSJuan Quintela 674f94a858fSJuan Quintela return s->parameters.x_checkpoint_delay; 675f94a858fSJuan Quintela } 676f94a858fSJuan Quintela 6771dfc4b9eSJuan Quintela int migrate_compress_level(void) 6781dfc4b9eSJuan Quintela { 6798f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 6801dfc4b9eSJuan Quintela 6811dfc4b9eSJuan Quintela return s->parameters.compress_level; 6821dfc4b9eSJuan Quintela } 6831dfc4b9eSJuan Quintela 6841dfc4b9eSJuan Quintela int migrate_compress_threads(void) 6851dfc4b9eSJuan Quintela { 6868f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 6871dfc4b9eSJuan Quintela 6881dfc4b9eSJuan Quintela return s->parameters.compress_threads; 6891dfc4b9eSJuan Quintela } 6901dfc4b9eSJuan Quintela 6911dfc4b9eSJuan Quintela int migrate_compress_wait_thread(void) 6921dfc4b9eSJuan Quintela { 6938f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 6941dfc4b9eSJuan Quintela 6951dfc4b9eSJuan Quintela return s->parameters.compress_wait_thread; 6961dfc4b9eSJuan Quintela } 6971dfc4b9eSJuan Quintela 6989605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void) 6999605c2acSJuan Quintela { 7008f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7019605c2acSJuan Quintela 7029605c2acSJuan Quintela return s->parameters.cpu_throttle_increment; 7039605c2acSJuan Quintela } 7049605c2acSJuan Quintela 7052a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void) 7062a8ec380SJuan Quintela { 7078f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7082a8ec380SJuan Quintela 7092a8ec380SJuan Quintela return s->parameters.cpu_throttle_initial; 7102a8ec380SJuan Quintela } 7112a8ec380SJuan Quintela 712873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void) 713873f674cSJuan Quintela { 7148f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 715873f674cSJuan Quintela 716873f674cSJuan Quintela return s->parameters.cpu_throttle_tailslow; 717873f674cSJuan Quintela } 718873f674cSJuan Quintela 7191dfc4b9eSJuan Quintela int migrate_decompress_threads(void) 7201dfc4b9eSJuan Quintela { 7218f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7221dfc4b9eSJuan Quintela 7231dfc4b9eSJuan Quintela return s->parameters.decompress_threads; 7241dfc4b9eSJuan Quintela } 7251dfc4b9eSJuan Quintela 726f5da8ba4SJuan Quintela uint64_t migrate_downtime_limit(void) 727f5da8ba4SJuan Quintela { 728f5da8ba4SJuan Quintela MigrationState *s = migrate_get_current(); 729f5da8ba4SJuan Quintela 730f5da8ba4SJuan Quintela return s->parameters.downtime_limit; 731f5da8ba4SJuan Quintela } 732f5da8ba4SJuan Quintela 73324155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void) 73424155bd0SJuan Quintela { 7358f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 73624155bd0SJuan Quintela 73724155bd0SJuan Quintela return s->parameters.max_cpu_throttle; 73824155bd0SJuan Quintela } 73924155bd0SJuan Quintela 7409c894df3SJuan Quintela uint64_t migrate_max_bandwidth(void) 7419c894df3SJuan Quintela { 7428f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7439c894df3SJuan Quintela 7449c894df3SJuan Quintela return s->parameters.max_bandwidth; 7459c894df3SJuan Quintela } 7469c894df3SJuan Quintela 74752033349SJuan Quintela uint64_t migrate_max_postcopy_bandwidth(void) 7481dfc4b9eSJuan Quintela { 7498f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7501dfc4b9eSJuan Quintela 7511dfc4b9eSJuan Quintela return s->parameters.max_postcopy_bandwidth; 7521dfc4b9eSJuan Quintela } 7531dfc4b9eSJuan Quintela 7541dfc4b9eSJuan Quintela int migrate_multifd_channels(void) 7551dfc4b9eSJuan Quintela { 7568f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7571dfc4b9eSJuan Quintela 7581dfc4b9eSJuan Quintela return s->parameters.multifd_channels; 7591dfc4b9eSJuan Quintela } 7601dfc4b9eSJuan Quintela 7611dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void) 7621dfc4b9eSJuan Quintela { 7638f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7641dfc4b9eSJuan Quintela 7651dfc4b9eSJuan Quintela assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX); 7661dfc4b9eSJuan Quintela return s->parameters.multifd_compression; 7671dfc4b9eSJuan Quintela } 7681dfc4b9eSJuan Quintela 7691dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void) 7701dfc4b9eSJuan Quintela { 7718f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7721dfc4b9eSJuan Quintela 7731dfc4b9eSJuan Quintela return s->parameters.multifd_zlib_level; 7741dfc4b9eSJuan Quintela } 7751dfc4b9eSJuan Quintela 7761dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void) 7771dfc4b9eSJuan Quintela { 7788f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7791dfc4b9eSJuan Quintela 7801dfc4b9eSJuan Quintela return s->parameters.multifd_zstd_level; 7811dfc4b9eSJuan Quintela } 7821dfc4b9eSJuan Quintela 7836499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void) 7846499efdbSJuan Quintela { 7858f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 7866499efdbSJuan Quintela 7876499efdbSJuan Quintela return s->parameters.throttle_trigger_threshold; 7886499efdbSJuan Quintela } 7896499efdbSJuan Quintela 7902eb0308bSJuan Quintela const char *migrate_tls_authz(void) 7912eb0308bSJuan Quintela { 7922eb0308bSJuan Quintela MigrationState *s = migrate_get_current(); 7932eb0308bSJuan Quintela 7942eb0308bSJuan Quintela return s->parameters.tls_authz; 7952eb0308bSJuan Quintela } 7962eb0308bSJuan Quintela 797d5c3e195SJuan Quintela const char *migrate_tls_creds(void) 798d5c3e195SJuan Quintela { 799d5c3e195SJuan Quintela MigrationState *s = migrate_get_current(); 800d5c3e195SJuan Quintela 801d5c3e195SJuan Quintela return s->parameters.tls_creds; 802d5c3e195SJuan Quintela } 803d5c3e195SJuan Quintela 8041f2f366cSJuan Quintela const char *migrate_tls_hostname(void) 8051f2f366cSJuan Quintela { 8061f2f366cSJuan Quintela MigrationState *s = migrate_get_current(); 8071f2f366cSJuan Quintela 8081f2f366cSJuan Quintela return s->parameters.tls_hostname; 8091f2f366cSJuan Quintela } 8101f2f366cSJuan Quintela 8111dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void) 8121dfc4b9eSJuan Quintela { 8138f9c5327SJuan Quintela MigrationState *s = migrate_get_current(); 8141dfc4b9eSJuan Quintela 8151dfc4b9eSJuan Quintela return s->parameters.xbzrle_cache_size; 8161dfc4b9eSJuan Quintela } 8172682c4eeSJuan Quintela 81887c22901SJuan Quintela /* parameter setters */ 81987c22901SJuan Quintela 82087c22901SJuan Quintela void migrate_set_block_incremental(bool value) 82187c22901SJuan Quintela { 82287c22901SJuan Quintela MigrationState *s = migrate_get_current(); 82387c22901SJuan Quintela 82487c22901SJuan Quintela s->parameters.block_incremental = value; 82587c22901SJuan Quintela } 82687c22901SJuan Quintela 8272682c4eeSJuan Quintela /* parameters helpers */ 8282682c4eeSJuan Quintela 829b1a87956SJuan Quintela void block_cleanup_parameters(void) 830b7b73122SJuan Quintela { 831b1a87956SJuan Quintela MigrationState *s = migrate_get_current(); 832b1a87956SJuan Quintela 833b7b73122SJuan Quintela if (s->must_remove_block_options) { 834b7b73122SJuan Quintela /* setting to false can never fail */ 835b7b73122SJuan Quintela migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort); 836b7b73122SJuan Quintela migrate_set_block_incremental(false); 837b7b73122SJuan Quintela s->must_remove_block_options = false; 838b7b73122SJuan Quintela } 839b7b73122SJuan Quintela } 840b7b73122SJuan Quintela 8412682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void) 8422682c4eeSJuan Quintela { 8432682c4eeSJuan Quintela static AnnounceParameters ap; 8442682c4eeSJuan Quintela 8452682c4eeSJuan Quintela MigrationState *s = migrate_get_current(); 8462682c4eeSJuan Quintela 8472682c4eeSJuan Quintela ap.initial = s->parameters.announce_initial; 8482682c4eeSJuan Quintela ap.max = s->parameters.announce_max; 8492682c4eeSJuan Quintela ap.rounds = s->parameters.announce_rounds; 8502682c4eeSJuan Quintela ap.step = s->parameters.announce_step; 8512682c4eeSJuan Quintela 8522682c4eeSJuan Quintela return ≈ 8532682c4eeSJuan Quintela } 8549c894df3SJuan Quintela 8559c894df3SJuan Quintela MigrationParameters *qmp_query_migrate_parameters(Error **errp) 8569c894df3SJuan Quintela { 8579c894df3SJuan Quintela MigrationParameters *params; 8589c894df3SJuan Quintela MigrationState *s = migrate_get_current(); 8599c894df3SJuan Quintela 8609c894df3SJuan Quintela /* TODO use QAPI_CLONE() instead of duplicating it inline */ 8619c894df3SJuan Quintela params = g_malloc0(sizeof(*params)); 8629c894df3SJuan Quintela params->has_compress_level = true; 8639c894df3SJuan Quintela params->compress_level = s->parameters.compress_level; 8649c894df3SJuan Quintela params->has_compress_threads = true; 8659c894df3SJuan Quintela params->compress_threads = s->parameters.compress_threads; 8669c894df3SJuan Quintela params->has_compress_wait_thread = true; 8679c894df3SJuan Quintela params->compress_wait_thread = s->parameters.compress_wait_thread; 8689c894df3SJuan Quintela params->has_decompress_threads = true; 8699c894df3SJuan Quintela params->decompress_threads = s->parameters.decompress_threads; 8709c894df3SJuan Quintela params->has_throttle_trigger_threshold = true; 8719c894df3SJuan Quintela params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; 8729c894df3SJuan Quintela params->has_cpu_throttle_initial = true; 8739c894df3SJuan Quintela params->cpu_throttle_initial = s->parameters.cpu_throttle_initial; 8749c894df3SJuan Quintela params->has_cpu_throttle_increment = true; 8759c894df3SJuan Quintela params->cpu_throttle_increment = s->parameters.cpu_throttle_increment; 8769c894df3SJuan Quintela params->has_cpu_throttle_tailslow = true; 8779c894df3SJuan Quintela params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow; 8789c894df3SJuan Quintela params->tls_creds = g_strdup(s->parameters.tls_creds); 8799c894df3SJuan Quintela params->tls_hostname = g_strdup(s->parameters.tls_hostname); 8809c894df3SJuan Quintela params->tls_authz = g_strdup(s->parameters.tls_authz ? 8819c894df3SJuan Quintela s->parameters.tls_authz : ""); 8829c894df3SJuan Quintela params->has_max_bandwidth = true; 8839c894df3SJuan Quintela params->max_bandwidth = s->parameters.max_bandwidth; 8849c894df3SJuan Quintela params->has_downtime_limit = true; 8859c894df3SJuan Quintela params->downtime_limit = s->parameters.downtime_limit; 8869c894df3SJuan Quintela params->has_x_checkpoint_delay = true; 8879c894df3SJuan Quintela params->x_checkpoint_delay = s->parameters.x_checkpoint_delay; 8889c894df3SJuan Quintela params->has_block_incremental = true; 8899c894df3SJuan Quintela params->block_incremental = s->parameters.block_incremental; 8909c894df3SJuan Quintela params->has_multifd_channels = true; 8919c894df3SJuan Quintela params->multifd_channels = s->parameters.multifd_channels; 8929c894df3SJuan Quintela params->has_multifd_compression = true; 8939c894df3SJuan Quintela params->multifd_compression = s->parameters.multifd_compression; 8949c894df3SJuan Quintela params->has_multifd_zlib_level = true; 8959c894df3SJuan Quintela params->multifd_zlib_level = s->parameters.multifd_zlib_level; 8969c894df3SJuan Quintela params->has_multifd_zstd_level = true; 8979c894df3SJuan Quintela params->multifd_zstd_level = s->parameters.multifd_zstd_level; 8989c894df3SJuan Quintela params->has_xbzrle_cache_size = true; 8999c894df3SJuan Quintela params->xbzrle_cache_size = s->parameters.xbzrle_cache_size; 9009c894df3SJuan Quintela params->has_max_postcopy_bandwidth = true; 9019c894df3SJuan Quintela params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth; 9029c894df3SJuan Quintela params->has_max_cpu_throttle = true; 9039c894df3SJuan Quintela params->max_cpu_throttle = s->parameters.max_cpu_throttle; 9049c894df3SJuan Quintela params->has_announce_initial = true; 9059c894df3SJuan Quintela params->announce_initial = s->parameters.announce_initial; 9069c894df3SJuan Quintela params->has_announce_max = true; 9079c894df3SJuan Quintela params->announce_max = s->parameters.announce_max; 9089c894df3SJuan Quintela params->has_announce_rounds = true; 9099c894df3SJuan Quintela params->announce_rounds = s->parameters.announce_rounds; 9109c894df3SJuan Quintela params->has_announce_step = true; 9119c894df3SJuan Quintela params->announce_step = s->parameters.announce_step; 9129c894df3SJuan Quintela 9139c894df3SJuan Quintela if (s->parameters.has_block_bitmap_mapping) { 9149c894df3SJuan Quintela params->has_block_bitmap_mapping = true; 9159c894df3SJuan Quintela params->block_bitmap_mapping = 9169c894df3SJuan Quintela QAPI_CLONE(BitmapMigrationNodeAliasList, 9179c894df3SJuan Quintela s->parameters.block_bitmap_mapping); 9189c894df3SJuan Quintela } 9199c894df3SJuan Quintela 9204d807857SHyman Huang(黄勇) params->has_x_vcpu_dirty_limit_period = true; 9214d807857SHyman Huang(黄勇) params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period; 922*09f9ec99SHyman Huang(黄勇) params->has_vcpu_dirty_limit = true; 923*09f9ec99SHyman Huang(黄勇) params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit; 9244d807857SHyman Huang(黄勇) 9259c894df3SJuan Quintela return params; 9269c894df3SJuan Quintela } 92709d6c965SJuan Quintela 92861a174e2SJuan Quintela void migrate_params_init(MigrationParameters *params) 92961a174e2SJuan Quintela { 93061a174e2SJuan Quintela params->tls_hostname = g_strdup(""); 93161a174e2SJuan Quintela params->tls_creds = g_strdup(""); 93261a174e2SJuan Quintela 93361a174e2SJuan Quintela /* Set has_* up only for parameter checks */ 93461a174e2SJuan Quintela params->has_compress_level = true; 93561a174e2SJuan Quintela params->has_compress_threads = true; 93661a174e2SJuan Quintela params->has_compress_wait_thread = true; 93761a174e2SJuan Quintela params->has_decompress_threads = true; 93861a174e2SJuan Quintela params->has_throttle_trigger_threshold = true; 93961a174e2SJuan Quintela params->has_cpu_throttle_initial = true; 94061a174e2SJuan Quintela params->has_cpu_throttle_increment = true; 94161a174e2SJuan Quintela params->has_cpu_throttle_tailslow = true; 94261a174e2SJuan Quintela params->has_max_bandwidth = true; 94361a174e2SJuan Quintela params->has_downtime_limit = true; 94461a174e2SJuan Quintela params->has_x_checkpoint_delay = true; 94561a174e2SJuan Quintela params->has_block_incremental = true; 94661a174e2SJuan Quintela params->has_multifd_channels = true; 94761a174e2SJuan Quintela params->has_multifd_compression = true; 94861a174e2SJuan Quintela params->has_multifd_zlib_level = true; 94961a174e2SJuan Quintela params->has_multifd_zstd_level = true; 95061a174e2SJuan Quintela params->has_xbzrle_cache_size = true; 95161a174e2SJuan Quintela params->has_max_postcopy_bandwidth = true; 95261a174e2SJuan Quintela params->has_max_cpu_throttle = true; 95361a174e2SJuan Quintela params->has_announce_initial = true; 95461a174e2SJuan Quintela params->has_announce_max = true; 95561a174e2SJuan Quintela params->has_announce_rounds = true; 95661a174e2SJuan Quintela params->has_announce_step = true; 9574d807857SHyman Huang(黄勇) params->has_x_vcpu_dirty_limit_period = true; 958*09f9ec99SHyman Huang(黄勇) params->has_vcpu_dirty_limit = true; 95961a174e2SJuan Quintela } 96061a174e2SJuan Quintela 96109d6c965SJuan Quintela /* 96209d6c965SJuan Quintela * Check whether the parameters are valid. Error will be put into errp 96309d6c965SJuan Quintela * (if provided). Return true if valid, otherwise false. 96409d6c965SJuan Quintela */ 96509d6c965SJuan Quintela bool migrate_params_check(MigrationParameters *params, Error **errp) 96609d6c965SJuan Quintela { 96709d6c965SJuan Quintela if (params->has_compress_level && 96809d6c965SJuan Quintela (params->compress_level > 9)) { 96909d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", 97009d6c965SJuan Quintela "a value between 0 and 9"); 97109d6c965SJuan Quintela return false; 97209d6c965SJuan Quintela } 97309d6c965SJuan Quintela 97409d6c965SJuan Quintela if (params->has_compress_threads && (params->compress_threads < 1)) { 97509d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 97609d6c965SJuan Quintela "compress_threads", 97709d6c965SJuan Quintela "a value between 1 and 255"); 97809d6c965SJuan Quintela return false; 97909d6c965SJuan Quintela } 98009d6c965SJuan Quintela 98109d6c965SJuan Quintela if (params->has_decompress_threads && (params->decompress_threads < 1)) { 98209d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 98309d6c965SJuan Quintela "decompress_threads", 98409d6c965SJuan Quintela "a value between 1 and 255"); 98509d6c965SJuan Quintela return false; 98609d6c965SJuan Quintela } 98709d6c965SJuan Quintela 98809d6c965SJuan Quintela if (params->has_throttle_trigger_threshold && 98909d6c965SJuan Quintela (params->throttle_trigger_threshold < 1 || 99009d6c965SJuan Quintela params->throttle_trigger_threshold > 100)) { 99109d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 99209d6c965SJuan Quintela "throttle_trigger_threshold", 99309d6c965SJuan Quintela "an integer in the range of 1 to 100"); 99409d6c965SJuan Quintela return false; 99509d6c965SJuan Quintela } 99609d6c965SJuan Quintela 99709d6c965SJuan Quintela if (params->has_cpu_throttle_initial && 99809d6c965SJuan Quintela (params->cpu_throttle_initial < 1 || 99909d6c965SJuan Quintela params->cpu_throttle_initial > 99)) { 100009d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 100109d6c965SJuan Quintela "cpu_throttle_initial", 100209d6c965SJuan Quintela "an integer in the range of 1 to 99"); 100309d6c965SJuan Quintela return false; 100409d6c965SJuan Quintela } 100509d6c965SJuan Quintela 100609d6c965SJuan Quintela if (params->has_cpu_throttle_increment && 100709d6c965SJuan Quintela (params->cpu_throttle_increment < 1 || 100809d6c965SJuan Quintela params->cpu_throttle_increment > 99)) { 100909d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 101009d6c965SJuan Quintela "cpu_throttle_increment", 101109d6c965SJuan Quintela "an integer in the range of 1 to 99"); 101209d6c965SJuan Quintela return false; 101309d6c965SJuan Quintela } 101409d6c965SJuan Quintela 101509d6c965SJuan Quintela if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { 101609d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 101709d6c965SJuan Quintela "max_bandwidth", 101809d6c965SJuan Quintela "an integer in the range of 0 to "stringify(SIZE_MAX) 101909d6c965SJuan Quintela " bytes/second"); 102009d6c965SJuan Quintela return false; 102109d6c965SJuan Quintela } 102209d6c965SJuan Quintela 102309d6c965SJuan Quintela if (params->has_downtime_limit && 102409d6c965SJuan Quintela (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { 102509d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 102609d6c965SJuan Quintela "downtime_limit", 102709d6c965SJuan Quintela "an integer in the range of 0 to " 102809d6c965SJuan Quintela stringify(MAX_MIGRATE_DOWNTIME)" ms"); 102909d6c965SJuan Quintela return false; 103009d6c965SJuan Quintela } 103109d6c965SJuan Quintela 103209d6c965SJuan Quintela /* x_checkpoint_delay is now always positive */ 103309d6c965SJuan Quintela 103409d6c965SJuan Quintela if (params->has_multifd_channels && (params->multifd_channels < 1)) { 103509d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 103609d6c965SJuan Quintela "multifd_channels", 103709d6c965SJuan Quintela "a value between 1 and 255"); 103809d6c965SJuan Quintela return false; 103909d6c965SJuan Quintela } 104009d6c965SJuan Quintela 104109d6c965SJuan Quintela if (params->has_multifd_zlib_level && 104209d6c965SJuan Quintela (params->multifd_zlib_level > 9)) { 104309d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level", 104409d6c965SJuan Quintela "a value between 0 and 9"); 104509d6c965SJuan Quintela return false; 104609d6c965SJuan Quintela } 104709d6c965SJuan Quintela 104809d6c965SJuan Quintela if (params->has_multifd_zstd_level && 104909d6c965SJuan Quintela (params->multifd_zstd_level > 20)) { 105009d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level", 105109d6c965SJuan Quintela "a value between 0 and 20"); 105209d6c965SJuan Quintela return false; 105309d6c965SJuan Quintela } 105409d6c965SJuan Quintela 105509d6c965SJuan Quintela if (params->has_xbzrle_cache_size && 105609d6c965SJuan Quintela (params->xbzrle_cache_size < qemu_target_page_size() || 105709d6c965SJuan Quintela !is_power_of_2(params->xbzrle_cache_size))) { 105809d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 105909d6c965SJuan Quintela "xbzrle_cache_size", 106009d6c965SJuan Quintela "a power of two no less than the target page size"); 106109d6c965SJuan Quintela return false; 106209d6c965SJuan Quintela } 106309d6c965SJuan Quintela 106409d6c965SJuan Quintela if (params->has_max_cpu_throttle && 106509d6c965SJuan Quintela (params->max_cpu_throttle < params->cpu_throttle_initial || 106609d6c965SJuan Quintela params->max_cpu_throttle > 99)) { 106709d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 106809d6c965SJuan Quintela "max_cpu_throttle", 106909d6c965SJuan Quintela "an integer in the range of cpu_throttle_initial to 99"); 107009d6c965SJuan Quintela return false; 107109d6c965SJuan Quintela } 107209d6c965SJuan Quintela 107309d6c965SJuan Quintela if (params->has_announce_initial && 107409d6c965SJuan Quintela params->announce_initial > 100000) { 107509d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 107609d6c965SJuan Quintela "announce_initial", 107709d6c965SJuan Quintela "a value between 0 and 100000"); 107809d6c965SJuan Quintela return false; 107909d6c965SJuan Quintela } 108009d6c965SJuan Quintela if (params->has_announce_max && 108109d6c965SJuan Quintela params->announce_max > 100000) { 108209d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 108309d6c965SJuan Quintela "announce_max", 108409d6c965SJuan Quintela "a value between 0 and 100000"); 108509d6c965SJuan Quintela return false; 108609d6c965SJuan Quintela } 108709d6c965SJuan Quintela if (params->has_announce_rounds && 108809d6c965SJuan Quintela params->announce_rounds > 1000) { 108909d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 109009d6c965SJuan Quintela "announce_rounds", 109109d6c965SJuan Quintela "a value between 0 and 1000"); 109209d6c965SJuan Quintela return false; 109309d6c965SJuan Quintela } 109409d6c965SJuan Quintela if (params->has_announce_step && 109509d6c965SJuan Quintela (params->announce_step < 1 || 109609d6c965SJuan Quintela params->announce_step > 10000)) { 109709d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 109809d6c965SJuan Quintela "announce_step", 109909d6c965SJuan Quintela "a value between 0 and 10000"); 110009d6c965SJuan Quintela return false; 110109d6c965SJuan Quintela } 110209d6c965SJuan Quintela 110309d6c965SJuan Quintela if (params->has_block_bitmap_mapping && 110409d6c965SJuan Quintela !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) { 110509d6c965SJuan Quintela error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: "); 110609d6c965SJuan Quintela return false; 110709d6c965SJuan Quintela } 110809d6c965SJuan Quintela 110909d6c965SJuan Quintela #ifdef CONFIG_LINUX 111009d6c965SJuan Quintela if (migrate_zero_copy_send() && 111109d6c965SJuan Quintela ((params->has_multifd_compression && params->multifd_compression) || 111209d6c965SJuan Quintela (params->tls_creds && *params->tls_creds))) { 111309d6c965SJuan Quintela error_setg(errp, 111409d6c965SJuan Quintela "Zero copy only available for non-compressed non-TLS multifd migration"); 111509d6c965SJuan Quintela return false; 111609d6c965SJuan Quintela } 111709d6c965SJuan Quintela #endif 111809d6c965SJuan Quintela 11194d807857SHyman Huang(黄勇) if (params->has_x_vcpu_dirty_limit_period && 11204d807857SHyman Huang(黄勇) (params->x_vcpu_dirty_limit_period < 1 || 11214d807857SHyman Huang(黄勇) params->x_vcpu_dirty_limit_period > 1000)) { 11224d807857SHyman Huang(黄勇) error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 11234d807857SHyman Huang(黄勇) "x-vcpu-dirty-limit-period", 11244d807857SHyman Huang(黄勇) "a value between 1 and 1000"); 11254d807857SHyman Huang(黄勇) return false; 11264d807857SHyman Huang(黄勇) } 11274d807857SHyman Huang(黄勇) 1128*09f9ec99SHyman Huang(黄勇) if (params->has_vcpu_dirty_limit && 1129*09f9ec99SHyman Huang(黄勇) (params->vcpu_dirty_limit < 1)) { 1130*09f9ec99SHyman Huang(黄勇) error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 1131*09f9ec99SHyman Huang(黄勇) "vcpu_dirty_limit", 1132*09f9ec99SHyman Huang(黄勇) "is invalid, it must greater then 1 MB/s"); 1133*09f9ec99SHyman Huang(黄勇) return false; 1134*09f9ec99SHyman Huang(黄勇) } 1135*09f9ec99SHyman Huang(黄勇) 113609d6c965SJuan Quintela return true; 113709d6c965SJuan Quintela } 113809d6c965SJuan Quintela 113909d6c965SJuan Quintela static void migrate_params_test_apply(MigrateSetParameters *params, 114009d6c965SJuan Quintela MigrationParameters *dest) 114109d6c965SJuan Quintela { 114209d6c965SJuan Quintela *dest = migrate_get_current()->parameters; 114309d6c965SJuan Quintela 114409d6c965SJuan Quintela /* TODO use QAPI_CLONE() instead of duplicating it inline */ 114509d6c965SJuan Quintela 114609d6c965SJuan Quintela if (params->has_compress_level) { 114709d6c965SJuan Quintela dest->compress_level = params->compress_level; 114809d6c965SJuan Quintela } 114909d6c965SJuan Quintela 115009d6c965SJuan Quintela if (params->has_compress_threads) { 115109d6c965SJuan Quintela dest->compress_threads = params->compress_threads; 115209d6c965SJuan Quintela } 115309d6c965SJuan Quintela 115409d6c965SJuan Quintela if (params->has_compress_wait_thread) { 115509d6c965SJuan Quintela dest->compress_wait_thread = params->compress_wait_thread; 115609d6c965SJuan Quintela } 115709d6c965SJuan Quintela 115809d6c965SJuan Quintela if (params->has_decompress_threads) { 115909d6c965SJuan Quintela dest->decompress_threads = params->decompress_threads; 116009d6c965SJuan Quintela } 116109d6c965SJuan Quintela 116209d6c965SJuan Quintela if (params->has_throttle_trigger_threshold) { 116309d6c965SJuan Quintela dest->throttle_trigger_threshold = params->throttle_trigger_threshold; 116409d6c965SJuan Quintela } 116509d6c965SJuan Quintela 116609d6c965SJuan Quintela if (params->has_cpu_throttle_initial) { 116709d6c965SJuan Quintela dest->cpu_throttle_initial = params->cpu_throttle_initial; 116809d6c965SJuan Quintela } 116909d6c965SJuan Quintela 117009d6c965SJuan Quintela if (params->has_cpu_throttle_increment) { 117109d6c965SJuan Quintela dest->cpu_throttle_increment = params->cpu_throttle_increment; 117209d6c965SJuan Quintela } 117309d6c965SJuan Quintela 117409d6c965SJuan Quintela if (params->has_cpu_throttle_tailslow) { 117509d6c965SJuan Quintela dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow; 117609d6c965SJuan Quintela } 117709d6c965SJuan Quintela 117809d6c965SJuan Quintela if (params->tls_creds) { 117909d6c965SJuan Quintela assert(params->tls_creds->type == QTYPE_QSTRING); 118009d6c965SJuan Quintela dest->tls_creds = params->tls_creds->u.s; 118109d6c965SJuan Quintela } 118209d6c965SJuan Quintela 118309d6c965SJuan Quintela if (params->tls_hostname) { 118409d6c965SJuan Quintela assert(params->tls_hostname->type == QTYPE_QSTRING); 118509d6c965SJuan Quintela dest->tls_hostname = params->tls_hostname->u.s; 118609d6c965SJuan Quintela } 118709d6c965SJuan Quintela 118809d6c965SJuan Quintela if (params->has_max_bandwidth) { 118909d6c965SJuan Quintela dest->max_bandwidth = params->max_bandwidth; 119009d6c965SJuan Quintela } 119109d6c965SJuan Quintela 119209d6c965SJuan Quintela if (params->has_downtime_limit) { 119309d6c965SJuan Quintela dest->downtime_limit = params->downtime_limit; 119409d6c965SJuan Quintela } 119509d6c965SJuan Quintela 119609d6c965SJuan Quintela if (params->has_x_checkpoint_delay) { 119709d6c965SJuan Quintela dest->x_checkpoint_delay = params->x_checkpoint_delay; 119809d6c965SJuan Quintela } 119909d6c965SJuan Quintela 120009d6c965SJuan Quintela if (params->has_block_incremental) { 120109d6c965SJuan Quintela dest->block_incremental = params->block_incremental; 120209d6c965SJuan Quintela } 120309d6c965SJuan Quintela if (params->has_multifd_channels) { 120409d6c965SJuan Quintela dest->multifd_channels = params->multifd_channels; 120509d6c965SJuan Quintela } 120609d6c965SJuan Quintela if (params->has_multifd_compression) { 120709d6c965SJuan Quintela dest->multifd_compression = params->multifd_compression; 120809d6c965SJuan Quintela } 120909d6c965SJuan Quintela if (params->has_xbzrle_cache_size) { 121009d6c965SJuan Quintela dest->xbzrle_cache_size = params->xbzrle_cache_size; 121109d6c965SJuan Quintela } 121209d6c965SJuan Quintela if (params->has_max_postcopy_bandwidth) { 121309d6c965SJuan Quintela dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth; 121409d6c965SJuan Quintela } 121509d6c965SJuan Quintela if (params->has_max_cpu_throttle) { 121609d6c965SJuan Quintela dest->max_cpu_throttle = params->max_cpu_throttle; 121709d6c965SJuan Quintela } 121809d6c965SJuan Quintela if (params->has_announce_initial) { 121909d6c965SJuan Quintela dest->announce_initial = params->announce_initial; 122009d6c965SJuan Quintela } 122109d6c965SJuan Quintela if (params->has_announce_max) { 122209d6c965SJuan Quintela dest->announce_max = params->announce_max; 122309d6c965SJuan Quintela } 122409d6c965SJuan Quintela if (params->has_announce_rounds) { 122509d6c965SJuan Quintela dest->announce_rounds = params->announce_rounds; 122609d6c965SJuan Quintela } 122709d6c965SJuan Quintela if (params->has_announce_step) { 122809d6c965SJuan Quintela dest->announce_step = params->announce_step; 122909d6c965SJuan Quintela } 123009d6c965SJuan Quintela 123109d6c965SJuan Quintela if (params->has_block_bitmap_mapping) { 123209d6c965SJuan Quintela dest->has_block_bitmap_mapping = true; 123309d6c965SJuan Quintela dest->block_bitmap_mapping = params->block_bitmap_mapping; 123409d6c965SJuan Quintela } 12354d807857SHyman Huang(黄勇) 12364d807857SHyman Huang(黄勇) if (params->has_x_vcpu_dirty_limit_period) { 12374d807857SHyman Huang(黄勇) dest->x_vcpu_dirty_limit_period = 12384d807857SHyman Huang(黄勇) params->x_vcpu_dirty_limit_period; 12394d807857SHyman Huang(黄勇) } 1240*09f9ec99SHyman Huang(黄勇) if (params->has_vcpu_dirty_limit) { 1241*09f9ec99SHyman Huang(黄勇) dest->vcpu_dirty_limit = params->vcpu_dirty_limit; 1242*09f9ec99SHyman Huang(黄勇) } 124309d6c965SJuan Quintela } 124409d6c965SJuan Quintela 124509d6c965SJuan Quintela static void migrate_params_apply(MigrateSetParameters *params, Error **errp) 124609d6c965SJuan Quintela { 124709d6c965SJuan Quintela MigrationState *s = migrate_get_current(); 124809d6c965SJuan Quintela 124909d6c965SJuan Quintela /* TODO use QAPI_CLONE() instead of duplicating it inline */ 125009d6c965SJuan Quintela 125109d6c965SJuan Quintela if (params->has_compress_level) { 125209d6c965SJuan Quintela s->parameters.compress_level = params->compress_level; 125309d6c965SJuan Quintela } 125409d6c965SJuan Quintela 125509d6c965SJuan Quintela if (params->has_compress_threads) { 125609d6c965SJuan Quintela s->parameters.compress_threads = params->compress_threads; 125709d6c965SJuan Quintela } 125809d6c965SJuan Quintela 125909d6c965SJuan Quintela if (params->has_compress_wait_thread) { 126009d6c965SJuan Quintela s->parameters.compress_wait_thread = params->compress_wait_thread; 126109d6c965SJuan Quintela } 126209d6c965SJuan Quintela 126309d6c965SJuan Quintela if (params->has_decompress_threads) { 126409d6c965SJuan Quintela s->parameters.decompress_threads = params->decompress_threads; 126509d6c965SJuan Quintela } 126609d6c965SJuan Quintela 126709d6c965SJuan Quintela if (params->has_throttle_trigger_threshold) { 126809d6c965SJuan Quintela s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; 126909d6c965SJuan Quintela } 127009d6c965SJuan Quintela 127109d6c965SJuan Quintela if (params->has_cpu_throttle_initial) { 127209d6c965SJuan Quintela s->parameters.cpu_throttle_initial = params->cpu_throttle_initial; 127309d6c965SJuan Quintela } 127409d6c965SJuan Quintela 127509d6c965SJuan Quintela if (params->has_cpu_throttle_increment) { 127609d6c965SJuan Quintela s->parameters.cpu_throttle_increment = params->cpu_throttle_increment; 127709d6c965SJuan Quintela } 127809d6c965SJuan Quintela 127909d6c965SJuan Quintela if (params->has_cpu_throttle_tailslow) { 128009d6c965SJuan Quintela s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow; 128109d6c965SJuan Quintela } 128209d6c965SJuan Quintela 128309d6c965SJuan Quintela if (params->tls_creds) { 128409d6c965SJuan Quintela g_free(s->parameters.tls_creds); 128509d6c965SJuan Quintela assert(params->tls_creds->type == QTYPE_QSTRING); 128609d6c965SJuan Quintela s->parameters.tls_creds = g_strdup(params->tls_creds->u.s); 128709d6c965SJuan Quintela } 128809d6c965SJuan Quintela 128909d6c965SJuan Quintela if (params->tls_hostname) { 129009d6c965SJuan Quintela g_free(s->parameters.tls_hostname); 129109d6c965SJuan Quintela assert(params->tls_hostname->type == QTYPE_QSTRING); 129209d6c965SJuan Quintela s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); 129309d6c965SJuan Quintela } 129409d6c965SJuan Quintela 129509d6c965SJuan Quintela if (params->tls_authz) { 129609d6c965SJuan Quintela g_free(s->parameters.tls_authz); 129709d6c965SJuan Quintela assert(params->tls_authz->type == QTYPE_QSTRING); 129809d6c965SJuan Quintela s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); 129909d6c965SJuan Quintela } 130009d6c965SJuan Quintela 130109d6c965SJuan Quintela if (params->has_max_bandwidth) { 130209d6c965SJuan Quintela s->parameters.max_bandwidth = params->max_bandwidth; 130309d6c965SJuan Quintela if (s->to_dst_file && !migration_in_postcopy()) { 1304e1fde0e0SJuan Quintela migration_rate_set(s->parameters.max_bandwidth); 130509d6c965SJuan Quintela } 130609d6c965SJuan Quintela } 130709d6c965SJuan Quintela 130809d6c965SJuan Quintela if (params->has_downtime_limit) { 130909d6c965SJuan Quintela s->parameters.downtime_limit = params->downtime_limit; 131009d6c965SJuan Quintela } 131109d6c965SJuan Quintela 131209d6c965SJuan Quintela if (params->has_x_checkpoint_delay) { 131309d6c965SJuan Quintela s->parameters.x_checkpoint_delay = params->x_checkpoint_delay; 13144332ffcdSVladimir Sementsov-Ogievskiy colo_checkpoint_delay_set(); 131509d6c965SJuan Quintela } 131609d6c965SJuan Quintela 131709d6c965SJuan Quintela if (params->has_block_incremental) { 131809d6c965SJuan Quintela s->parameters.block_incremental = params->block_incremental; 131909d6c965SJuan Quintela } 132009d6c965SJuan Quintela if (params->has_multifd_channels) { 132109d6c965SJuan Quintela s->parameters.multifd_channels = params->multifd_channels; 132209d6c965SJuan Quintela } 132309d6c965SJuan Quintela if (params->has_multifd_compression) { 132409d6c965SJuan Quintela s->parameters.multifd_compression = params->multifd_compression; 132509d6c965SJuan Quintela } 132609d6c965SJuan Quintela if (params->has_xbzrle_cache_size) { 132709d6c965SJuan Quintela s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; 132809d6c965SJuan Quintela xbzrle_cache_resize(params->xbzrle_cache_size, errp); 132909d6c965SJuan Quintela } 133009d6c965SJuan Quintela if (params->has_max_postcopy_bandwidth) { 133109d6c965SJuan Quintela s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; 133209d6c965SJuan Quintela if (s->to_dst_file && migration_in_postcopy()) { 1333e1fde0e0SJuan Quintela migration_rate_set(s->parameters.max_postcopy_bandwidth); 133409d6c965SJuan Quintela } 133509d6c965SJuan Quintela } 133609d6c965SJuan Quintela if (params->has_max_cpu_throttle) { 133709d6c965SJuan Quintela s->parameters.max_cpu_throttle = params->max_cpu_throttle; 133809d6c965SJuan Quintela } 133909d6c965SJuan Quintela if (params->has_announce_initial) { 134009d6c965SJuan Quintela s->parameters.announce_initial = params->announce_initial; 134109d6c965SJuan Quintela } 134209d6c965SJuan Quintela if (params->has_announce_max) { 134309d6c965SJuan Quintela s->parameters.announce_max = params->announce_max; 134409d6c965SJuan Quintela } 134509d6c965SJuan Quintela if (params->has_announce_rounds) { 134609d6c965SJuan Quintela s->parameters.announce_rounds = params->announce_rounds; 134709d6c965SJuan Quintela } 134809d6c965SJuan Quintela if (params->has_announce_step) { 134909d6c965SJuan Quintela s->parameters.announce_step = params->announce_step; 135009d6c965SJuan Quintela } 135109d6c965SJuan Quintela 135209d6c965SJuan Quintela if (params->has_block_bitmap_mapping) { 135309d6c965SJuan Quintela qapi_free_BitmapMigrationNodeAliasList( 135409d6c965SJuan Quintela s->parameters.block_bitmap_mapping); 135509d6c965SJuan Quintela 135609d6c965SJuan Quintela s->parameters.has_block_bitmap_mapping = true; 135709d6c965SJuan Quintela s->parameters.block_bitmap_mapping = 135809d6c965SJuan Quintela QAPI_CLONE(BitmapMigrationNodeAliasList, 135909d6c965SJuan Quintela params->block_bitmap_mapping); 136009d6c965SJuan Quintela } 13614d807857SHyman Huang(黄勇) 13624d807857SHyman Huang(黄勇) if (params->has_x_vcpu_dirty_limit_period) { 13634d807857SHyman Huang(黄勇) s->parameters.x_vcpu_dirty_limit_period = 13644d807857SHyman Huang(黄勇) params->x_vcpu_dirty_limit_period; 13654d807857SHyman Huang(黄勇) } 1366*09f9ec99SHyman Huang(黄勇) if (params->has_vcpu_dirty_limit) { 1367*09f9ec99SHyman Huang(黄勇) s->parameters.vcpu_dirty_limit = params->vcpu_dirty_limit; 1368*09f9ec99SHyman Huang(黄勇) } 136909d6c965SJuan Quintela } 137009d6c965SJuan Quintela 137109d6c965SJuan Quintela void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) 137209d6c965SJuan Quintela { 137309d6c965SJuan Quintela MigrationParameters tmp; 137409d6c965SJuan Quintela 137509d6c965SJuan Quintela /* TODO Rewrite "" to null instead */ 137609d6c965SJuan Quintela if (params->tls_creds 137709d6c965SJuan Quintela && params->tls_creds->type == QTYPE_QNULL) { 137809d6c965SJuan Quintela qobject_unref(params->tls_creds->u.n); 137909d6c965SJuan Quintela params->tls_creds->type = QTYPE_QSTRING; 138009d6c965SJuan Quintela params->tls_creds->u.s = strdup(""); 138109d6c965SJuan Quintela } 138209d6c965SJuan Quintela /* TODO Rewrite "" to null instead */ 138309d6c965SJuan Quintela if (params->tls_hostname 138409d6c965SJuan Quintela && params->tls_hostname->type == QTYPE_QNULL) { 138509d6c965SJuan Quintela qobject_unref(params->tls_hostname->u.n); 138609d6c965SJuan Quintela params->tls_hostname->type = QTYPE_QSTRING; 138709d6c965SJuan Quintela params->tls_hostname->u.s = strdup(""); 138809d6c965SJuan Quintela } 138909d6c965SJuan Quintela 139009d6c965SJuan Quintela migrate_params_test_apply(params, &tmp); 139109d6c965SJuan Quintela 139209d6c965SJuan Quintela if (!migrate_params_check(&tmp, errp)) { 139309d6c965SJuan Quintela /* Invalid parameter */ 139409d6c965SJuan Quintela return; 139509d6c965SJuan Quintela } 139609d6c965SJuan Quintela 139709d6c965SJuan Quintela migrate_params_apply(params, errp); 139809d6c965SJuan Quintela } 1399