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