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 341f0776f1SJuan Quintela bool migrate_auto_converge(void) 351f0776f1SJuan Quintela { 361f0776f1SJuan Quintela MigrationState *s; 371f0776f1SJuan Quintela 381f0776f1SJuan Quintela s = migrate_get_current(); 391f0776f1SJuan Quintela 401f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE]; 411f0776f1SJuan Quintela } 421f0776f1SJuan Quintela 431f0776f1SJuan Quintela bool migrate_background_snapshot(void) 441f0776f1SJuan Quintela { 451f0776f1SJuan Quintela MigrationState *s; 461f0776f1SJuan Quintela 471f0776f1SJuan Quintela s = migrate_get_current(); 481f0776f1SJuan Quintela 491f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; 501f0776f1SJuan Quintela } 511f0776f1SJuan Quintela 529d4b1e5fSJuan Quintela bool migrate_block(void) 539d4b1e5fSJuan Quintela { 549d4b1e5fSJuan Quintela MigrationState *s; 559d4b1e5fSJuan Quintela 569d4b1e5fSJuan Quintela s = migrate_get_current(); 579d4b1e5fSJuan Quintela 589d4b1e5fSJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_BLOCK]; 599d4b1e5fSJuan Quintela } 609d4b1e5fSJuan Quintela 615e804644SJuan Quintela bool migrate_colo(void) 625e804644SJuan Quintela { 635e804644SJuan Quintela MigrationState *s = migrate_get_current(); 645e804644SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_X_COLO]; 655e804644SJuan Quintela } 665e804644SJuan Quintela 67a7a94d14SJuan Quintela bool migrate_compress(void) 68a7a94d14SJuan Quintela { 69a7a94d14SJuan Quintela MigrationState *s; 70a7a94d14SJuan Quintela 71a7a94d14SJuan Quintela s = migrate_get_current(); 72a7a94d14SJuan Quintela 73a7a94d14SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_COMPRESS]; 74a7a94d14SJuan Quintela } 75a7a94d14SJuan Quintela 761f0776f1SJuan Quintela bool migrate_dirty_bitmaps(void) 771f0776f1SJuan Quintela { 781f0776f1SJuan Quintela MigrationState *s; 791f0776f1SJuan Quintela 801f0776f1SJuan Quintela s = migrate_get_current(); 811f0776f1SJuan Quintela 821f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; 831f0776f1SJuan Quintela } 841f0776f1SJuan Quintela 85b890902cSJuan Quintela bool migrate_events(void) 86b890902cSJuan Quintela { 87b890902cSJuan Quintela MigrationState *s; 88b890902cSJuan Quintela 89b890902cSJuan Quintela s = migrate_get_current(); 90b890902cSJuan Quintela 91b890902cSJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_EVENTS]; 92b890902cSJuan Quintela } 93b890902cSJuan Quintela 941f0776f1SJuan Quintela bool migrate_ignore_shared(void) 951f0776f1SJuan Quintela { 961f0776f1SJuan Quintela MigrationState *s; 971f0776f1SJuan Quintela 981f0776f1SJuan Quintela s = migrate_get_current(); 991f0776f1SJuan Quintela 1001f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED]; 1011f0776f1SJuan Quintela } 1021f0776f1SJuan Quintela 1031f0776f1SJuan Quintela bool migrate_late_block_activate(void) 1041f0776f1SJuan Quintela { 1051f0776f1SJuan Quintela MigrationState *s; 1061f0776f1SJuan Quintela 1071f0776f1SJuan Quintela s = migrate_get_current(); 1081f0776f1SJuan Quintela 1091f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; 1101f0776f1SJuan Quintela } 1111f0776f1SJuan Quintela 11251b07548SJuan Quintela bool migrate_multifd(void) 11351b07548SJuan Quintela { 11451b07548SJuan Quintela MigrationState *s; 11551b07548SJuan Quintela 11651b07548SJuan Quintela s = migrate_get_current(); 11751b07548SJuan Quintela 11851b07548SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_MULTIFD]; 11951b07548SJuan Quintela } 12051b07548SJuan Quintela 1211f0776f1SJuan Quintela bool migrate_pause_before_switchover(void) 1221f0776f1SJuan Quintela { 1231f0776f1SJuan Quintela MigrationState *s; 1241f0776f1SJuan Quintela 1251f0776f1SJuan Quintela s = migrate_get_current(); 1261f0776f1SJuan Quintela 1271f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER]; 1281f0776f1SJuan Quintela } 1291f0776f1SJuan Quintela 1301f0776f1SJuan Quintela bool migrate_postcopy_blocktime(void) 1311f0776f1SJuan Quintela { 1321f0776f1SJuan Quintela MigrationState *s; 1331f0776f1SJuan Quintela 1341f0776f1SJuan Quintela s = migrate_get_current(); 1351f0776f1SJuan Quintela 1361f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME]; 1371f0776f1SJuan Quintela } 1381f0776f1SJuan Quintela 1391f0776f1SJuan Quintela bool migrate_postcopy_preempt(void) 1401f0776f1SJuan Quintela { 1411f0776f1SJuan Quintela MigrationState *s; 1421f0776f1SJuan Quintela 1431f0776f1SJuan Quintela s = migrate_get_current(); 1441f0776f1SJuan Quintela 1451f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]; 1461f0776f1SJuan Quintela } 1471f0776f1SJuan Quintela 1481f0776f1SJuan Quintela bool migrate_postcopy_ram(void) 1491f0776f1SJuan Quintela { 1501f0776f1SJuan Quintela MigrationState *s; 1511f0776f1SJuan Quintela 1521f0776f1SJuan Quintela s = migrate_get_current(); 1531f0776f1SJuan Quintela 1541f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; 1551f0776f1SJuan Quintela } 1561f0776f1SJuan Quintela 15717cba690SJuan Quintela bool migrate_rdma_pin_all(void) 15817cba690SJuan Quintela { 15917cba690SJuan Quintela MigrationState *s = migrate_get_current(); 16017cba690SJuan Quintela 16117cba690SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL]; 16217cba690SJuan Quintela } 16317cba690SJuan Quintela 1641f0776f1SJuan Quintela bool migrate_release_ram(void) 1651f0776f1SJuan Quintela { 1661f0776f1SJuan Quintela MigrationState *s; 1671f0776f1SJuan Quintela 1681f0776f1SJuan Quintela s = migrate_get_current(); 1691f0776f1SJuan Quintela 1701f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; 1711f0776f1SJuan Quintela } 1721f0776f1SJuan Quintela 17338ad1110SJuan Quintela bool migrate_return_path(void) 17438ad1110SJuan Quintela { 17538ad1110SJuan Quintela MigrationState *s; 17638ad1110SJuan Quintela 17738ad1110SJuan Quintela s = migrate_get_current(); 17838ad1110SJuan Quintela 17938ad1110SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH]; 18038ad1110SJuan Quintela } 18138ad1110SJuan Quintela 1821f0776f1SJuan Quintela bool migrate_validate_uuid(void) 1831f0776f1SJuan Quintela { 1841f0776f1SJuan Quintela MigrationState *s; 1851f0776f1SJuan Quintela 1861f0776f1SJuan Quintela s = migrate_get_current(); 1871f0776f1SJuan Quintela 1881f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; 1891f0776f1SJuan Quintela } 1901f0776f1SJuan Quintela 19187dca0c9SJuan Quintela bool migrate_xbzrle(void) 19287dca0c9SJuan Quintela { 19387dca0c9SJuan Quintela MigrationState *s; 19487dca0c9SJuan Quintela 19587dca0c9SJuan Quintela s = migrate_get_current(); 19687dca0c9SJuan Quintela 19787dca0c9SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_XBZRLE]; 19887dca0c9SJuan Quintela } 19987dca0c9SJuan Quintela 2001f0776f1SJuan Quintela bool migrate_zero_blocks(void) 2011f0776f1SJuan Quintela { 2021f0776f1SJuan Quintela MigrationState *s; 2031f0776f1SJuan Quintela 2041f0776f1SJuan Quintela s = migrate_get_current(); 2051f0776f1SJuan Quintela 2061f0776f1SJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; 2071f0776f1SJuan Quintela } 208b4bc342cSJuan Quintela 209b4bc342cSJuan Quintela bool migrate_zero_copy_send(void) 210b4bc342cSJuan Quintela { 211b4bc342cSJuan Quintela MigrationState *s; 212b4bc342cSJuan Quintela 213b4bc342cSJuan Quintela s = migrate_get_current(); 214b4bc342cSJuan Quintela 215b4bc342cSJuan Quintela return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; 216b4bc342cSJuan Quintela } 217f774fde5SJuan Quintela 218f774fde5SJuan Quintela /* pseudo capabilities */ 219f774fde5SJuan Quintela 220f774fde5SJuan Quintela bool migrate_postcopy(void) 221f774fde5SJuan Quintela { 222f774fde5SJuan Quintela return migrate_postcopy_ram() || migrate_dirty_bitmaps(); 223f774fde5SJuan Quintela } 224f774fde5SJuan Quintela 22510d4703bSJuan Quintela bool migrate_tls(void) 22610d4703bSJuan Quintela { 22710d4703bSJuan Quintela MigrationState *s; 22810d4703bSJuan Quintela 22910d4703bSJuan Quintela s = migrate_get_current(); 23010d4703bSJuan Quintela 23110d4703bSJuan Quintela return s->parameters.tls_creds && *s->parameters.tls_creds; 23210d4703bSJuan Quintela } 23310d4703bSJuan Quintela 23477608706SJuan Quintela typedef enum WriteTrackingSupport { 23577608706SJuan Quintela WT_SUPPORT_UNKNOWN = 0, 23677608706SJuan Quintela WT_SUPPORT_ABSENT, 23777608706SJuan Quintela WT_SUPPORT_AVAILABLE, 23877608706SJuan Quintela WT_SUPPORT_COMPATIBLE 23977608706SJuan Quintela } WriteTrackingSupport; 24077608706SJuan Quintela 24177608706SJuan Quintela static 24277608706SJuan Quintela WriteTrackingSupport migrate_query_write_tracking(void) 24377608706SJuan Quintela { 24477608706SJuan Quintela /* Check if kernel supports required UFFD features */ 24577608706SJuan Quintela if (!ram_write_tracking_available()) { 24677608706SJuan Quintela return WT_SUPPORT_ABSENT; 24777608706SJuan Quintela } 24877608706SJuan Quintela /* 24977608706SJuan Quintela * Check if current memory configuration is 25077608706SJuan Quintela * compatible with required UFFD features. 25177608706SJuan Quintela */ 25277608706SJuan Quintela if (!ram_write_tracking_compatible()) { 25377608706SJuan Quintela return WT_SUPPORT_AVAILABLE; 25477608706SJuan Quintela } 25577608706SJuan Quintela 25677608706SJuan Quintela return WT_SUPPORT_COMPATIBLE; 25777608706SJuan Quintela } 25877608706SJuan Quintela 25977608706SJuan Quintela /* Migration capabilities set */ 26077608706SJuan Quintela struct MigrateCapsSet { 26177608706SJuan Quintela int size; /* Capability set size */ 26277608706SJuan Quintela MigrationCapability caps[]; /* Variadic array of capabilities */ 26377608706SJuan Quintela }; 26477608706SJuan Quintela typedef struct MigrateCapsSet MigrateCapsSet; 26577608706SJuan Quintela 26677608706SJuan Quintela /* Define and initialize MigrateCapsSet */ 26777608706SJuan Quintela #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...) \ 26877608706SJuan Quintela MigrateCapsSet _name = { \ 26977608706SJuan Quintela .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \ 27077608706SJuan Quintela .caps = { __VA_ARGS__ } \ 27177608706SJuan Quintela } 27277608706SJuan Quintela 27377608706SJuan Quintela /* Background-snapshot compatibility check list */ 27477608706SJuan Quintela static const 27577608706SJuan Quintela INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot, 27677608706SJuan Quintela MIGRATION_CAPABILITY_POSTCOPY_RAM, 27777608706SJuan Quintela MIGRATION_CAPABILITY_DIRTY_BITMAPS, 27877608706SJuan Quintela MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME, 27977608706SJuan Quintela MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE, 28077608706SJuan Quintela MIGRATION_CAPABILITY_RETURN_PATH, 28177608706SJuan Quintela MIGRATION_CAPABILITY_MULTIFD, 28277608706SJuan Quintela MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER, 28377608706SJuan Quintela MIGRATION_CAPABILITY_AUTO_CONVERGE, 28477608706SJuan Quintela MIGRATION_CAPABILITY_RELEASE_RAM, 28577608706SJuan Quintela MIGRATION_CAPABILITY_RDMA_PIN_ALL, 28677608706SJuan Quintela MIGRATION_CAPABILITY_COMPRESS, 28777608706SJuan Quintela MIGRATION_CAPABILITY_XBZRLE, 28877608706SJuan Quintela MIGRATION_CAPABILITY_X_COLO, 28977608706SJuan Quintela MIGRATION_CAPABILITY_VALIDATE_UUID, 29077608706SJuan Quintela MIGRATION_CAPABILITY_ZERO_COPY_SEND); 29177608706SJuan Quintela 29277608706SJuan Quintela /** 29377608706SJuan Quintela * @migration_caps_check - check capability compatibility 29477608706SJuan Quintela * 29577608706SJuan Quintela * @old_caps: old capability list 29677608706SJuan Quintela * @new_caps: new capability list 29777608706SJuan Quintela * @errp: set *errp if the check failed, with reason 29877608706SJuan Quintela * 29977608706SJuan Quintela * Returns true if check passed, otherwise false. 30077608706SJuan Quintela */ 30177608706SJuan Quintela bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) 30277608706SJuan Quintela { 30377608706SJuan Quintela MigrationIncomingState *mis = migration_incoming_get_current(); 30477608706SJuan Quintela 30574c38cf7SPeter Xu ERRP_GUARD(); 30677608706SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION 30777608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_BLOCK]) { 30877608706SJuan Quintela error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) " 30977608706SJuan Quintela "block migration"); 31077608706SJuan Quintela error_append_hint(errp, "Use drive_mirror+NBD instead.\n"); 31177608706SJuan Quintela return false; 31277608706SJuan Quintela } 31377608706SJuan Quintela #endif 31477608706SJuan Quintela 31577608706SJuan Quintela #ifndef CONFIG_REPLICATION 31677608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_X_COLO]) { 31777608706SJuan Quintela error_setg(errp, "QEMU compiled without replication module" 31877608706SJuan Quintela " can't enable COLO"); 31977608706SJuan Quintela error_append_hint(errp, "Please enable replication before COLO.\n"); 32077608706SJuan Quintela return false; 32177608706SJuan Quintela } 32277608706SJuan Quintela #endif 32377608706SJuan Quintela 32477608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { 32577608706SJuan Quintela /* This check is reasonably expensive, so only when it's being 32677608706SJuan Quintela * set the first time, also it's only the destination that needs 32777608706SJuan Quintela * special support. 32877608706SJuan Quintela */ 32977608706SJuan Quintela if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] && 33077608706SJuan Quintela runstate_check(RUN_STATE_INMIGRATE) && 33174c38cf7SPeter Xu !postcopy_ram_supported_by_host(mis, errp)) { 33274c38cf7SPeter Xu error_prepend(errp, "Postcopy is not supported: "); 33377608706SJuan Quintela return false; 33477608706SJuan Quintela } 33577608706SJuan Quintela 33677608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) { 33777608706SJuan Quintela error_setg(errp, "Postcopy is not compatible with ignore-shared"); 33877608706SJuan Quintela return false; 33977608706SJuan Quintela } 340b405dfffSLeonardo Bras 341b405dfffSLeonardo Bras if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { 342b405dfffSLeonardo Bras error_setg(errp, "Postcopy is not yet compatible with multifd"); 343b405dfffSLeonardo Bras return false; 344b405dfffSLeonardo Bras } 34577608706SJuan Quintela } 34677608706SJuan Quintela 34777608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) { 34877608706SJuan Quintela WriteTrackingSupport wt_support; 34977608706SJuan Quintela int idx; 35077608706SJuan Quintela /* 35177608706SJuan Quintela * Check if 'background-snapshot' capability is supported by 35277608706SJuan Quintela * host kernel and compatible with guest memory configuration. 35377608706SJuan Quintela */ 35477608706SJuan Quintela wt_support = migrate_query_write_tracking(); 35577608706SJuan Quintela if (wt_support < WT_SUPPORT_AVAILABLE) { 35677608706SJuan Quintela error_setg(errp, "Background-snapshot is not supported by host kernel"); 35777608706SJuan Quintela return false; 35877608706SJuan Quintela } 35977608706SJuan Quintela if (wt_support < WT_SUPPORT_COMPATIBLE) { 36077608706SJuan Quintela error_setg(errp, "Background-snapshot is not compatible " 36177608706SJuan Quintela "with guest memory configuration"); 36277608706SJuan Quintela return false; 36377608706SJuan Quintela } 36477608706SJuan Quintela 36577608706SJuan Quintela /* 36677608706SJuan Quintela * Check if there are any migration capabilities 36777608706SJuan Quintela * incompatible with 'background-snapshot'. 36877608706SJuan Quintela */ 36977608706SJuan Quintela for (idx = 0; idx < check_caps_background_snapshot.size; idx++) { 37077608706SJuan Quintela int incomp_cap = check_caps_background_snapshot.caps[idx]; 37177608706SJuan Quintela if (new_caps[incomp_cap]) { 37277608706SJuan Quintela error_setg(errp, 37377608706SJuan Quintela "Background-snapshot is not compatible with %s", 37477608706SJuan Quintela MigrationCapability_str(incomp_cap)); 37577608706SJuan Quintela return false; 37677608706SJuan Quintela } 37777608706SJuan Quintela } 37877608706SJuan Quintela } 37977608706SJuan Quintela 38077608706SJuan Quintela #ifdef CONFIG_LINUX 38177608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] && 38277608706SJuan Quintela (!new_caps[MIGRATION_CAPABILITY_MULTIFD] || 38377608706SJuan Quintela new_caps[MIGRATION_CAPABILITY_COMPRESS] || 38477608706SJuan Quintela new_caps[MIGRATION_CAPABILITY_XBZRLE] || 38577608706SJuan Quintela migrate_multifd_compression() || 38610d4703bSJuan Quintela migrate_tls())) { 38777608706SJuan Quintela error_setg(errp, 38877608706SJuan Quintela "Zero copy only available for non-compressed non-TLS multifd migration"); 38977608706SJuan Quintela return false; 39077608706SJuan Quintela } 39177608706SJuan Quintela #else 39277608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) { 39377608706SJuan Quintela error_setg(errp, 39477608706SJuan Quintela "Zero copy currently only available on Linux"); 39577608706SJuan Quintela return false; 39677608706SJuan Quintela } 39777608706SJuan Quintela #endif 39877608706SJuan Quintela 39977608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) { 40077608706SJuan Quintela if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { 40177608706SJuan Quintela error_setg(errp, "Postcopy preempt requires postcopy-ram"); 40277608706SJuan Quintela return false; 40377608706SJuan Quintela } 40477608706SJuan Quintela 40577608706SJuan Quintela /* 40677608706SJuan Quintela * Preempt mode requires urgent pages to be sent in separate 40777608706SJuan Quintela * channel, OTOH compression logic will disorder all pages into 40877608706SJuan Quintela * different compression channels, which is not compatible with the 40977608706SJuan Quintela * preempt assumptions on channel assignments. 41077608706SJuan Quintela */ 41177608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { 41277608706SJuan Quintela error_setg(errp, "Postcopy preempt not compatible with compress"); 41377608706SJuan Quintela return false; 41477608706SJuan Quintela } 41577608706SJuan Quintela } 41677608706SJuan Quintela 41777608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { 41877608706SJuan Quintela if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { 41977608706SJuan Quintela error_setg(errp, "Multifd is not compatible with compress"); 42077608706SJuan Quintela return false; 42177608706SJuan Quintela } 42277608706SJuan Quintela } 42377608706SJuan Quintela 42477608706SJuan Quintela return true; 42577608706SJuan Quintela } 4264d0c6b69SJuan Quintela 427f80196b7SJuan Quintela bool migrate_cap_set(int cap, bool value, Error **errp) 428f80196b7SJuan Quintela { 429f80196b7SJuan Quintela MigrationState *s = migrate_get_current(); 430f80196b7SJuan Quintela bool new_caps[MIGRATION_CAPABILITY__MAX]; 431f80196b7SJuan Quintela 432f80196b7SJuan Quintela if (migration_is_running(s->state)) { 433f80196b7SJuan Quintela error_setg(errp, QERR_MIGRATION_ACTIVE); 434f80196b7SJuan Quintela return false; 435f80196b7SJuan Quintela } 436f80196b7SJuan Quintela 437f80196b7SJuan Quintela memcpy(new_caps, s->capabilities, sizeof(new_caps)); 438f80196b7SJuan Quintela new_caps[cap] = value; 439f80196b7SJuan Quintela 440f80196b7SJuan Quintela if (!migrate_caps_check(s->capabilities, new_caps, errp)) { 441f80196b7SJuan Quintela return false; 442f80196b7SJuan Quintela } 443f80196b7SJuan Quintela s->capabilities[cap] = value; 444f80196b7SJuan Quintela return true; 445f80196b7SJuan Quintela } 446f80196b7SJuan Quintela 4474d0c6b69SJuan Quintela MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) 4484d0c6b69SJuan Quintela { 4494d0c6b69SJuan Quintela MigrationCapabilityStatusList *head = NULL, **tail = &head; 4504d0c6b69SJuan Quintela MigrationCapabilityStatus *caps; 4514d0c6b69SJuan Quintela MigrationState *s = migrate_get_current(); 4524d0c6b69SJuan Quintela int i; 4534d0c6b69SJuan Quintela 4544d0c6b69SJuan Quintela for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { 4554d0c6b69SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION 4564d0c6b69SJuan Quintela if (i == MIGRATION_CAPABILITY_BLOCK) { 4574d0c6b69SJuan Quintela continue; 4584d0c6b69SJuan Quintela } 4594d0c6b69SJuan Quintela #endif 4604d0c6b69SJuan Quintela caps = g_malloc0(sizeof(*caps)); 4614d0c6b69SJuan Quintela caps->capability = i; 4624d0c6b69SJuan Quintela caps->state = s->capabilities[i]; 4634d0c6b69SJuan Quintela QAPI_LIST_APPEND(tail, caps); 4644d0c6b69SJuan Quintela } 4654d0c6b69SJuan Quintela 4664d0c6b69SJuan Quintela return head; 4674d0c6b69SJuan Quintela } 46845c1de13SJuan Quintela 46945c1de13SJuan Quintela void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, 47045c1de13SJuan Quintela Error **errp) 47145c1de13SJuan Quintela { 47245c1de13SJuan Quintela MigrationState *s = migrate_get_current(); 47345c1de13SJuan Quintela MigrationCapabilityStatusList *cap; 47445c1de13SJuan Quintela bool new_caps[MIGRATION_CAPABILITY__MAX]; 47545c1de13SJuan Quintela 47645c1de13SJuan Quintela if (migration_is_running(s->state)) { 47745c1de13SJuan Quintela error_setg(errp, QERR_MIGRATION_ACTIVE); 47845c1de13SJuan Quintela return; 47945c1de13SJuan Quintela } 48045c1de13SJuan Quintela 48145c1de13SJuan Quintela memcpy(new_caps, s->capabilities, sizeof(new_caps)); 48245c1de13SJuan Quintela for (cap = params; cap; cap = cap->next) { 48345c1de13SJuan Quintela new_caps[cap->value->capability] = cap->value->state; 48445c1de13SJuan Quintela } 48545c1de13SJuan Quintela 48645c1de13SJuan Quintela if (!migrate_caps_check(s->capabilities, new_caps, errp)) { 48745c1de13SJuan Quintela return; 48845c1de13SJuan Quintela } 48945c1de13SJuan Quintela 49045c1de13SJuan Quintela for (cap = params; cap; cap = cap->next) { 49145c1de13SJuan Quintela s->capabilities[cap->value->capability] = cap->value->state; 49245c1de13SJuan Quintela } 49345c1de13SJuan Quintela } 4941dfc4b9eSJuan Quintela 4951dfc4b9eSJuan Quintela /* parameters */ 4961dfc4b9eSJuan Quintela 4976f8be708SJuan Quintela bool migrate_block_incremental(void) 4986f8be708SJuan Quintela { 4996f8be708SJuan Quintela MigrationState *s; 5006f8be708SJuan Quintela 5016f8be708SJuan Quintela s = migrate_get_current(); 5026f8be708SJuan Quintela 5036f8be708SJuan Quintela return s->parameters.block_incremental; 5046f8be708SJuan Quintela } 5056f8be708SJuan Quintela 506f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void) 507f94a858fSJuan Quintela { 508f94a858fSJuan Quintela MigrationState *s; 509f94a858fSJuan Quintela 510f94a858fSJuan Quintela s = migrate_get_current(); 511f94a858fSJuan Quintela 512f94a858fSJuan Quintela return s->parameters.x_checkpoint_delay; 513f94a858fSJuan Quintela } 514f94a858fSJuan Quintela 5151dfc4b9eSJuan Quintela int migrate_compress_level(void) 5161dfc4b9eSJuan Quintela { 5171dfc4b9eSJuan Quintela MigrationState *s; 5181dfc4b9eSJuan Quintela 5191dfc4b9eSJuan Quintela s = migrate_get_current(); 5201dfc4b9eSJuan Quintela 5211dfc4b9eSJuan Quintela return s->parameters.compress_level; 5221dfc4b9eSJuan Quintela } 5231dfc4b9eSJuan Quintela 5241dfc4b9eSJuan Quintela int migrate_compress_threads(void) 5251dfc4b9eSJuan Quintela { 5261dfc4b9eSJuan Quintela MigrationState *s; 5271dfc4b9eSJuan Quintela 5281dfc4b9eSJuan Quintela s = migrate_get_current(); 5291dfc4b9eSJuan Quintela 5301dfc4b9eSJuan Quintela return s->parameters.compress_threads; 5311dfc4b9eSJuan Quintela } 5321dfc4b9eSJuan Quintela 5331dfc4b9eSJuan Quintela int migrate_compress_wait_thread(void) 5341dfc4b9eSJuan Quintela { 5351dfc4b9eSJuan Quintela MigrationState *s; 5361dfc4b9eSJuan Quintela 5371dfc4b9eSJuan Quintela s = migrate_get_current(); 5381dfc4b9eSJuan Quintela 5391dfc4b9eSJuan Quintela return s->parameters.compress_wait_thread; 5401dfc4b9eSJuan Quintela } 5411dfc4b9eSJuan Quintela 5429605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void) 5439605c2acSJuan Quintela { 5449605c2acSJuan Quintela MigrationState *s; 5459605c2acSJuan Quintela 5469605c2acSJuan Quintela s = migrate_get_current(); 5479605c2acSJuan Quintela 5489605c2acSJuan Quintela return s->parameters.cpu_throttle_increment; 5499605c2acSJuan Quintela } 5509605c2acSJuan Quintela 5512a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void) 5522a8ec380SJuan Quintela { 5532a8ec380SJuan Quintela MigrationState *s; 5542a8ec380SJuan Quintela 5552a8ec380SJuan Quintela s = migrate_get_current(); 5562a8ec380SJuan Quintela 5572a8ec380SJuan Quintela return s->parameters.cpu_throttle_initial; 5582a8ec380SJuan Quintela } 5592a8ec380SJuan Quintela 560873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void) 561873f674cSJuan Quintela { 562873f674cSJuan Quintela MigrationState *s; 563873f674cSJuan Quintela 564873f674cSJuan Quintela s = migrate_get_current(); 565873f674cSJuan Quintela 566873f674cSJuan Quintela return s->parameters.cpu_throttle_tailslow; 567873f674cSJuan Quintela } 568873f674cSJuan Quintela 5691dfc4b9eSJuan Quintela int migrate_decompress_threads(void) 5701dfc4b9eSJuan Quintela { 5711dfc4b9eSJuan Quintela MigrationState *s; 5721dfc4b9eSJuan Quintela 5731dfc4b9eSJuan Quintela s = migrate_get_current(); 5741dfc4b9eSJuan Quintela 5751dfc4b9eSJuan Quintela return s->parameters.decompress_threads; 5761dfc4b9eSJuan Quintela } 5771dfc4b9eSJuan Quintela 57824155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void) 57924155bd0SJuan Quintela { 58024155bd0SJuan Quintela MigrationState *s; 58124155bd0SJuan Quintela 58224155bd0SJuan Quintela s = migrate_get_current(); 58324155bd0SJuan Quintela 58424155bd0SJuan Quintela return s->parameters.max_cpu_throttle; 58524155bd0SJuan Quintela } 58624155bd0SJuan Quintela 5879c894df3SJuan Quintela uint64_t migrate_max_bandwidth(void) 5889c894df3SJuan Quintela { 5899c894df3SJuan Quintela MigrationState *s; 5909c894df3SJuan Quintela 5919c894df3SJuan Quintela s = migrate_get_current(); 5929c894df3SJuan Quintela 5939c894df3SJuan Quintela return s->parameters.max_bandwidth; 5949c894df3SJuan Quintela } 5959c894df3SJuan Quintela 5961dfc4b9eSJuan Quintela int64_t migrate_max_postcopy_bandwidth(void) 5971dfc4b9eSJuan Quintela { 5981dfc4b9eSJuan Quintela MigrationState *s; 5991dfc4b9eSJuan Quintela 6001dfc4b9eSJuan Quintela s = migrate_get_current(); 6011dfc4b9eSJuan Quintela 6021dfc4b9eSJuan Quintela return s->parameters.max_postcopy_bandwidth; 6031dfc4b9eSJuan Quintela } 6041dfc4b9eSJuan Quintela 6051dfc4b9eSJuan Quintela int migrate_multifd_channels(void) 6061dfc4b9eSJuan Quintela { 6071dfc4b9eSJuan Quintela MigrationState *s; 6081dfc4b9eSJuan Quintela 6091dfc4b9eSJuan Quintela s = migrate_get_current(); 6101dfc4b9eSJuan Quintela 6111dfc4b9eSJuan Quintela return s->parameters.multifd_channels; 6121dfc4b9eSJuan Quintela } 6131dfc4b9eSJuan Quintela 6141dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void) 6151dfc4b9eSJuan Quintela { 6161dfc4b9eSJuan Quintela MigrationState *s; 6171dfc4b9eSJuan Quintela 6181dfc4b9eSJuan Quintela s = migrate_get_current(); 6191dfc4b9eSJuan Quintela 6201dfc4b9eSJuan Quintela assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX); 6211dfc4b9eSJuan Quintela return s->parameters.multifd_compression; 6221dfc4b9eSJuan Quintela } 6231dfc4b9eSJuan Quintela 6241dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void) 6251dfc4b9eSJuan Quintela { 6261dfc4b9eSJuan Quintela MigrationState *s; 6271dfc4b9eSJuan Quintela 6281dfc4b9eSJuan Quintela s = migrate_get_current(); 6291dfc4b9eSJuan Quintela 6301dfc4b9eSJuan Quintela return s->parameters.multifd_zlib_level; 6311dfc4b9eSJuan Quintela } 6321dfc4b9eSJuan Quintela 6331dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void) 6341dfc4b9eSJuan Quintela { 6351dfc4b9eSJuan Quintela MigrationState *s; 6361dfc4b9eSJuan Quintela 6371dfc4b9eSJuan Quintela s = migrate_get_current(); 6381dfc4b9eSJuan Quintela 6391dfc4b9eSJuan Quintela return s->parameters.multifd_zstd_level; 6401dfc4b9eSJuan Quintela } 6411dfc4b9eSJuan Quintela 6426499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void) 6436499efdbSJuan Quintela { 6446499efdbSJuan Quintela MigrationState *s; 6456499efdbSJuan Quintela 6466499efdbSJuan Quintela s = migrate_get_current(); 6476499efdbSJuan Quintela 6486499efdbSJuan Quintela return s->parameters.throttle_trigger_threshold; 6496499efdbSJuan Quintela } 6506499efdbSJuan Quintela 6511dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void) 6521dfc4b9eSJuan Quintela { 6531dfc4b9eSJuan Quintela MigrationState *s; 6541dfc4b9eSJuan Quintela 6551dfc4b9eSJuan Quintela s = migrate_get_current(); 6561dfc4b9eSJuan Quintela 6571dfc4b9eSJuan Quintela return s->parameters.xbzrle_cache_size; 6581dfc4b9eSJuan Quintela } 6592682c4eeSJuan Quintela 6602682c4eeSJuan Quintela /* parameters helpers */ 6612682c4eeSJuan Quintela 6622682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void) 6632682c4eeSJuan Quintela { 6642682c4eeSJuan Quintela static AnnounceParameters ap; 6652682c4eeSJuan Quintela 6662682c4eeSJuan Quintela MigrationState *s = migrate_get_current(); 6672682c4eeSJuan Quintela 6682682c4eeSJuan Quintela ap.initial = s->parameters.announce_initial; 6692682c4eeSJuan Quintela ap.max = s->parameters.announce_max; 6702682c4eeSJuan Quintela ap.rounds = s->parameters.announce_rounds; 6712682c4eeSJuan Quintela ap.step = s->parameters.announce_step; 6722682c4eeSJuan Quintela 6732682c4eeSJuan Quintela return ≈ 6742682c4eeSJuan Quintela } 6759c894df3SJuan Quintela 6769c894df3SJuan Quintela MigrationParameters *qmp_query_migrate_parameters(Error **errp) 6779c894df3SJuan Quintela { 6789c894df3SJuan Quintela MigrationParameters *params; 6799c894df3SJuan Quintela MigrationState *s = migrate_get_current(); 6809c894df3SJuan Quintela 6819c894df3SJuan Quintela /* TODO use QAPI_CLONE() instead of duplicating it inline */ 6829c894df3SJuan Quintela params = g_malloc0(sizeof(*params)); 6839c894df3SJuan Quintela params->has_compress_level = true; 6849c894df3SJuan Quintela params->compress_level = s->parameters.compress_level; 6859c894df3SJuan Quintela params->has_compress_threads = true; 6869c894df3SJuan Quintela params->compress_threads = s->parameters.compress_threads; 6879c894df3SJuan Quintela params->has_compress_wait_thread = true; 6889c894df3SJuan Quintela params->compress_wait_thread = s->parameters.compress_wait_thread; 6899c894df3SJuan Quintela params->has_decompress_threads = true; 6909c894df3SJuan Quintela params->decompress_threads = s->parameters.decompress_threads; 6919c894df3SJuan Quintela params->has_throttle_trigger_threshold = true; 6929c894df3SJuan Quintela params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; 6939c894df3SJuan Quintela params->has_cpu_throttle_initial = true; 6949c894df3SJuan Quintela params->cpu_throttle_initial = s->parameters.cpu_throttle_initial; 6959c894df3SJuan Quintela params->has_cpu_throttle_increment = true; 6969c894df3SJuan Quintela params->cpu_throttle_increment = s->parameters.cpu_throttle_increment; 6979c894df3SJuan Quintela params->has_cpu_throttle_tailslow = true; 6989c894df3SJuan Quintela params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow; 6999c894df3SJuan Quintela params->tls_creds = g_strdup(s->parameters.tls_creds); 7009c894df3SJuan Quintela params->tls_hostname = g_strdup(s->parameters.tls_hostname); 7019c894df3SJuan Quintela params->tls_authz = g_strdup(s->parameters.tls_authz ? 7029c894df3SJuan Quintela s->parameters.tls_authz : ""); 7039c894df3SJuan Quintela params->has_max_bandwidth = true; 7049c894df3SJuan Quintela params->max_bandwidth = s->parameters.max_bandwidth; 7059c894df3SJuan Quintela params->has_downtime_limit = true; 7069c894df3SJuan Quintela params->downtime_limit = s->parameters.downtime_limit; 7079c894df3SJuan Quintela params->has_x_checkpoint_delay = true; 7089c894df3SJuan Quintela params->x_checkpoint_delay = s->parameters.x_checkpoint_delay; 7099c894df3SJuan Quintela params->has_block_incremental = true; 7109c894df3SJuan Quintela params->block_incremental = s->parameters.block_incremental; 7119c894df3SJuan Quintela params->has_multifd_channels = true; 7129c894df3SJuan Quintela params->multifd_channels = s->parameters.multifd_channels; 7139c894df3SJuan Quintela params->has_multifd_compression = true; 7149c894df3SJuan Quintela params->multifd_compression = s->parameters.multifd_compression; 7159c894df3SJuan Quintela params->has_multifd_zlib_level = true; 7169c894df3SJuan Quintela params->multifd_zlib_level = s->parameters.multifd_zlib_level; 7179c894df3SJuan Quintela params->has_multifd_zstd_level = true; 7189c894df3SJuan Quintela params->multifd_zstd_level = s->parameters.multifd_zstd_level; 7199c894df3SJuan Quintela params->has_xbzrle_cache_size = true; 7209c894df3SJuan Quintela params->xbzrle_cache_size = s->parameters.xbzrle_cache_size; 7219c894df3SJuan Quintela params->has_max_postcopy_bandwidth = true; 7229c894df3SJuan Quintela params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth; 7239c894df3SJuan Quintela params->has_max_cpu_throttle = true; 7249c894df3SJuan Quintela params->max_cpu_throttle = s->parameters.max_cpu_throttle; 7259c894df3SJuan Quintela params->has_announce_initial = true; 7269c894df3SJuan Quintela params->announce_initial = s->parameters.announce_initial; 7279c894df3SJuan Quintela params->has_announce_max = true; 7289c894df3SJuan Quintela params->announce_max = s->parameters.announce_max; 7299c894df3SJuan Quintela params->has_announce_rounds = true; 7309c894df3SJuan Quintela params->announce_rounds = s->parameters.announce_rounds; 7319c894df3SJuan Quintela params->has_announce_step = true; 7329c894df3SJuan Quintela params->announce_step = s->parameters.announce_step; 7339c894df3SJuan Quintela 7349c894df3SJuan Quintela if (s->parameters.has_block_bitmap_mapping) { 7359c894df3SJuan Quintela params->has_block_bitmap_mapping = true; 7369c894df3SJuan Quintela params->block_bitmap_mapping = 7379c894df3SJuan Quintela QAPI_CLONE(BitmapMigrationNodeAliasList, 7389c894df3SJuan Quintela s->parameters.block_bitmap_mapping); 7399c894df3SJuan Quintela } 7409c894df3SJuan Quintela 7419c894df3SJuan Quintela return params; 7429c894df3SJuan Quintela } 74309d6c965SJuan Quintela 744*61a174e2SJuan Quintela void migrate_params_init(MigrationParameters *params) 745*61a174e2SJuan Quintela { 746*61a174e2SJuan Quintela params->tls_hostname = g_strdup(""); 747*61a174e2SJuan Quintela params->tls_creds = g_strdup(""); 748*61a174e2SJuan Quintela 749*61a174e2SJuan Quintela /* Set has_* up only for parameter checks */ 750*61a174e2SJuan Quintela params->has_compress_level = true; 751*61a174e2SJuan Quintela params->has_compress_threads = true; 752*61a174e2SJuan Quintela params->has_compress_wait_thread = true; 753*61a174e2SJuan Quintela params->has_decompress_threads = true; 754*61a174e2SJuan Quintela params->has_throttle_trigger_threshold = true; 755*61a174e2SJuan Quintela params->has_cpu_throttle_initial = true; 756*61a174e2SJuan Quintela params->has_cpu_throttle_increment = true; 757*61a174e2SJuan Quintela params->has_cpu_throttle_tailslow = true; 758*61a174e2SJuan Quintela params->has_max_bandwidth = true; 759*61a174e2SJuan Quintela params->has_downtime_limit = true; 760*61a174e2SJuan Quintela params->has_x_checkpoint_delay = true; 761*61a174e2SJuan Quintela params->has_block_incremental = true; 762*61a174e2SJuan Quintela params->has_multifd_channels = true; 763*61a174e2SJuan Quintela params->has_multifd_compression = true; 764*61a174e2SJuan Quintela params->has_multifd_zlib_level = true; 765*61a174e2SJuan Quintela params->has_multifd_zstd_level = true; 766*61a174e2SJuan Quintela params->has_xbzrle_cache_size = true; 767*61a174e2SJuan Quintela params->has_max_postcopy_bandwidth = true; 768*61a174e2SJuan Quintela params->has_max_cpu_throttle = true; 769*61a174e2SJuan Quintela params->has_announce_initial = true; 770*61a174e2SJuan Quintela params->has_announce_max = true; 771*61a174e2SJuan Quintela params->has_announce_rounds = true; 772*61a174e2SJuan Quintela params->has_announce_step = true; 773*61a174e2SJuan Quintela } 774*61a174e2SJuan Quintela 77509d6c965SJuan Quintela /* 77609d6c965SJuan Quintela * Check whether the parameters are valid. Error will be put into errp 77709d6c965SJuan Quintela * (if provided). Return true if valid, otherwise false. 77809d6c965SJuan Quintela */ 77909d6c965SJuan Quintela bool migrate_params_check(MigrationParameters *params, Error **errp) 78009d6c965SJuan Quintela { 78109d6c965SJuan Quintela if (params->has_compress_level && 78209d6c965SJuan Quintela (params->compress_level > 9)) { 78309d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", 78409d6c965SJuan Quintela "a value between 0 and 9"); 78509d6c965SJuan Quintela return false; 78609d6c965SJuan Quintela } 78709d6c965SJuan Quintela 78809d6c965SJuan Quintela if (params->has_compress_threads && (params->compress_threads < 1)) { 78909d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 79009d6c965SJuan Quintela "compress_threads", 79109d6c965SJuan Quintela "a value between 1 and 255"); 79209d6c965SJuan Quintela return false; 79309d6c965SJuan Quintela } 79409d6c965SJuan Quintela 79509d6c965SJuan Quintela if (params->has_decompress_threads && (params->decompress_threads < 1)) { 79609d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 79709d6c965SJuan Quintela "decompress_threads", 79809d6c965SJuan Quintela "a value between 1 and 255"); 79909d6c965SJuan Quintela return false; 80009d6c965SJuan Quintela } 80109d6c965SJuan Quintela 80209d6c965SJuan Quintela if (params->has_throttle_trigger_threshold && 80309d6c965SJuan Quintela (params->throttle_trigger_threshold < 1 || 80409d6c965SJuan Quintela params->throttle_trigger_threshold > 100)) { 80509d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 80609d6c965SJuan Quintela "throttle_trigger_threshold", 80709d6c965SJuan Quintela "an integer in the range of 1 to 100"); 80809d6c965SJuan Quintela return false; 80909d6c965SJuan Quintela } 81009d6c965SJuan Quintela 81109d6c965SJuan Quintela if (params->has_cpu_throttle_initial && 81209d6c965SJuan Quintela (params->cpu_throttle_initial < 1 || 81309d6c965SJuan Quintela params->cpu_throttle_initial > 99)) { 81409d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 81509d6c965SJuan Quintela "cpu_throttle_initial", 81609d6c965SJuan Quintela "an integer in the range of 1 to 99"); 81709d6c965SJuan Quintela return false; 81809d6c965SJuan Quintela } 81909d6c965SJuan Quintela 82009d6c965SJuan Quintela if (params->has_cpu_throttle_increment && 82109d6c965SJuan Quintela (params->cpu_throttle_increment < 1 || 82209d6c965SJuan Quintela params->cpu_throttle_increment > 99)) { 82309d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 82409d6c965SJuan Quintela "cpu_throttle_increment", 82509d6c965SJuan Quintela "an integer in the range of 1 to 99"); 82609d6c965SJuan Quintela return false; 82709d6c965SJuan Quintela } 82809d6c965SJuan Quintela 82909d6c965SJuan Quintela if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { 83009d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 83109d6c965SJuan Quintela "max_bandwidth", 83209d6c965SJuan Quintela "an integer in the range of 0 to "stringify(SIZE_MAX) 83309d6c965SJuan Quintela " bytes/second"); 83409d6c965SJuan Quintela return false; 83509d6c965SJuan Quintela } 83609d6c965SJuan Quintela 83709d6c965SJuan Quintela if (params->has_downtime_limit && 83809d6c965SJuan Quintela (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { 83909d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 84009d6c965SJuan Quintela "downtime_limit", 84109d6c965SJuan Quintela "an integer in the range of 0 to " 84209d6c965SJuan Quintela stringify(MAX_MIGRATE_DOWNTIME)" ms"); 84309d6c965SJuan Quintela return false; 84409d6c965SJuan Quintela } 84509d6c965SJuan Quintela 84609d6c965SJuan Quintela /* x_checkpoint_delay is now always positive */ 84709d6c965SJuan Quintela 84809d6c965SJuan Quintela if (params->has_multifd_channels && (params->multifd_channels < 1)) { 84909d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 85009d6c965SJuan Quintela "multifd_channels", 85109d6c965SJuan Quintela "a value between 1 and 255"); 85209d6c965SJuan Quintela return false; 85309d6c965SJuan Quintela } 85409d6c965SJuan Quintela 85509d6c965SJuan Quintela if (params->has_multifd_zlib_level && 85609d6c965SJuan Quintela (params->multifd_zlib_level > 9)) { 85709d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level", 85809d6c965SJuan Quintela "a value between 0 and 9"); 85909d6c965SJuan Quintela return false; 86009d6c965SJuan Quintela } 86109d6c965SJuan Quintela 86209d6c965SJuan Quintela if (params->has_multifd_zstd_level && 86309d6c965SJuan Quintela (params->multifd_zstd_level > 20)) { 86409d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level", 86509d6c965SJuan Quintela "a value between 0 and 20"); 86609d6c965SJuan Quintela return false; 86709d6c965SJuan Quintela } 86809d6c965SJuan Quintela 86909d6c965SJuan Quintela if (params->has_xbzrle_cache_size && 87009d6c965SJuan Quintela (params->xbzrle_cache_size < qemu_target_page_size() || 87109d6c965SJuan Quintela !is_power_of_2(params->xbzrle_cache_size))) { 87209d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 87309d6c965SJuan Quintela "xbzrle_cache_size", 87409d6c965SJuan Quintela "a power of two no less than the target page size"); 87509d6c965SJuan Quintela return false; 87609d6c965SJuan Quintela } 87709d6c965SJuan Quintela 87809d6c965SJuan Quintela if (params->has_max_cpu_throttle && 87909d6c965SJuan Quintela (params->max_cpu_throttle < params->cpu_throttle_initial || 88009d6c965SJuan Quintela params->max_cpu_throttle > 99)) { 88109d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 88209d6c965SJuan Quintela "max_cpu_throttle", 88309d6c965SJuan Quintela "an integer in the range of cpu_throttle_initial to 99"); 88409d6c965SJuan Quintela return false; 88509d6c965SJuan Quintela } 88609d6c965SJuan Quintela 88709d6c965SJuan Quintela if (params->has_announce_initial && 88809d6c965SJuan Quintela params->announce_initial > 100000) { 88909d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 89009d6c965SJuan Quintela "announce_initial", 89109d6c965SJuan Quintela "a value between 0 and 100000"); 89209d6c965SJuan Quintela return false; 89309d6c965SJuan Quintela } 89409d6c965SJuan Quintela if (params->has_announce_max && 89509d6c965SJuan Quintela params->announce_max > 100000) { 89609d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 89709d6c965SJuan Quintela "announce_max", 89809d6c965SJuan Quintela "a value between 0 and 100000"); 89909d6c965SJuan Quintela return false; 90009d6c965SJuan Quintela } 90109d6c965SJuan Quintela if (params->has_announce_rounds && 90209d6c965SJuan Quintela params->announce_rounds > 1000) { 90309d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 90409d6c965SJuan Quintela "announce_rounds", 90509d6c965SJuan Quintela "a value between 0 and 1000"); 90609d6c965SJuan Quintela return false; 90709d6c965SJuan Quintela } 90809d6c965SJuan Quintela if (params->has_announce_step && 90909d6c965SJuan Quintela (params->announce_step < 1 || 91009d6c965SJuan Quintela params->announce_step > 10000)) { 91109d6c965SJuan Quintela error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 91209d6c965SJuan Quintela "announce_step", 91309d6c965SJuan Quintela "a value between 0 and 10000"); 91409d6c965SJuan Quintela return false; 91509d6c965SJuan Quintela } 91609d6c965SJuan Quintela 91709d6c965SJuan Quintela if (params->has_block_bitmap_mapping && 91809d6c965SJuan Quintela !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) { 91909d6c965SJuan Quintela error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: "); 92009d6c965SJuan Quintela return false; 92109d6c965SJuan Quintela } 92209d6c965SJuan Quintela 92309d6c965SJuan Quintela #ifdef CONFIG_LINUX 92409d6c965SJuan Quintela if (migrate_zero_copy_send() && 92509d6c965SJuan Quintela ((params->has_multifd_compression && params->multifd_compression) || 92609d6c965SJuan Quintela (params->tls_creds && *params->tls_creds))) { 92709d6c965SJuan Quintela error_setg(errp, 92809d6c965SJuan Quintela "Zero copy only available for non-compressed non-TLS multifd migration"); 92909d6c965SJuan Quintela return false; 93009d6c965SJuan Quintela } 93109d6c965SJuan Quintela #endif 93209d6c965SJuan Quintela 93309d6c965SJuan Quintela return true; 93409d6c965SJuan Quintela } 93509d6c965SJuan Quintela 93609d6c965SJuan Quintela static void migrate_params_test_apply(MigrateSetParameters *params, 93709d6c965SJuan Quintela MigrationParameters *dest) 93809d6c965SJuan Quintela { 93909d6c965SJuan Quintela *dest = migrate_get_current()->parameters; 94009d6c965SJuan Quintela 94109d6c965SJuan Quintela /* TODO use QAPI_CLONE() instead of duplicating it inline */ 94209d6c965SJuan Quintela 94309d6c965SJuan Quintela if (params->has_compress_level) { 94409d6c965SJuan Quintela dest->compress_level = params->compress_level; 94509d6c965SJuan Quintela } 94609d6c965SJuan Quintela 94709d6c965SJuan Quintela if (params->has_compress_threads) { 94809d6c965SJuan Quintela dest->compress_threads = params->compress_threads; 94909d6c965SJuan Quintela } 95009d6c965SJuan Quintela 95109d6c965SJuan Quintela if (params->has_compress_wait_thread) { 95209d6c965SJuan Quintela dest->compress_wait_thread = params->compress_wait_thread; 95309d6c965SJuan Quintela } 95409d6c965SJuan Quintela 95509d6c965SJuan Quintela if (params->has_decompress_threads) { 95609d6c965SJuan Quintela dest->decompress_threads = params->decompress_threads; 95709d6c965SJuan Quintela } 95809d6c965SJuan Quintela 95909d6c965SJuan Quintela if (params->has_throttle_trigger_threshold) { 96009d6c965SJuan Quintela dest->throttle_trigger_threshold = params->throttle_trigger_threshold; 96109d6c965SJuan Quintela } 96209d6c965SJuan Quintela 96309d6c965SJuan Quintela if (params->has_cpu_throttle_initial) { 96409d6c965SJuan Quintela dest->cpu_throttle_initial = params->cpu_throttle_initial; 96509d6c965SJuan Quintela } 96609d6c965SJuan Quintela 96709d6c965SJuan Quintela if (params->has_cpu_throttle_increment) { 96809d6c965SJuan Quintela dest->cpu_throttle_increment = params->cpu_throttle_increment; 96909d6c965SJuan Quintela } 97009d6c965SJuan Quintela 97109d6c965SJuan Quintela if (params->has_cpu_throttle_tailslow) { 97209d6c965SJuan Quintela dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow; 97309d6c965SJuan Quintela } 97409d6c965SJuan Quintela 97509d6c965SJuan Quintela if (params->tls_creds) { 97609d6c965SJuan Quintela assert(params->tls_creds->type == QTYPE_QSTRING); 97709d6c965SJuan Quintela dest->tls_creds = params->tls_creds->u.s; 97809d6c965SJuan Quintela } 97909d6c965SJuan Quintela 98009d6c965SJuan Quintela if (params->tls_hostname) { 98109d6c965SJuan Quintela assert(params->tls_hostname->type == QTYPE_QSTRING); 98209d6c965SJuan Quintela dest->tls_hostname = params->tls_hostname->u.s; 98309d6c965SJuan Quintela } 98409d6c965SJuan Quintela 98509d6c965SJuan Quintela if (params->has_max_bandwidth) { 98609d6c965SJuan Quintela dest->max_bandwidth = params->max_bandwidth; 98709d6c965SJuan Quintela } 98809d6c965SJuan Quintela 98909d6c965SJuan Quintela if (params->has_downtime_limit) { 99009d6c965SJuan Quintela dest->downtime_limit = params->downtime_limit; 99109d6c965SJuan Quintela } 99209d6c965SJuan Quintela 99309d6c965SJuan Quintela if (params->has_x_checkpoint_delay) { 99409d6c965SJuan Quintela dest->x_checkpoint_delay = params->x_checkpoint_delay; 99509d6c965SJuan Quintela } 99609d6c965SJuan Quintela 99709d6c965SJuan Quintela if (params->has_block_incremental) { 99809d6c965SJuan Quintela dest->block_incremental = params->block_incremental; 99909d6c965SJuan Quintela } 100009d6c965SJuan Quintela if (params->has_multifd_channels) { 100109d6c965SJuan Quintela dest->multifd_channels = params->multifd_channels; 100209d6c965SJuan Quintela } 100309d6c965SJuan Quintela if (params->has_multifd_compression) { 100409d6c965SJuan Quintela dest->multifd_compression = params->multifd_compression; 100509d6c965SJuan Quintela } 100609d6c965SJuan Quintela if (params->has_xbzrle_cache_size) { 100709d6c965SJuan Quintela dest->xbzrle_cache_size = params->xbzrle_cache_size; 100809d6c965SJuan Quintela } 100909d6c965SJuan Quintela if (params->has_max_postcopy_bandwidth) { 101009d6c965SJuan Quintela dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth; 101109d6c965SJuan Quintela } 101209d6c965SJuan Quintela if (params->has_max_cpu_throttle) { 101309d6c965SJuan Quintela dest->max_cpu_throttle = params->max_cpu_throttle; 101409d6c965SJuan Quintela } 101509d6c965SJuan Quintela if (params->has_announce_initial) { 101609d6c965SJuan Quintela dest->announce_initial = params->announce_initial; 101709d6c965SJuan Quintela } 101809d6c965SJuan Quintela if (params->has_announce_max) { 101909d6c965SJuan Quintela dest->announce_max = params->announce_max; 102009d6c965SJuan Quintela } 102109d6c965SJuan Quintela if (params->has_announce_rounds) { 102209d6c965SJuan Quintela dest->announce_rounds = params->announce_rounds; 102309d6c965SJuan Quintela } 102409d6c965SJuan Quintela if (params->has_announce_step) { 102509d6c965SJuan Quintela dest->announce_step = params->announce_step; 102609d6c965SJuan Quintela } 102709d6c965SJuan Quintela 102809d6c965SJuan Quintela if (params->has_block_bitmap_mapping) { 102909d6c965SJuan Quintela dest->has_block_bitmap_mapping = true; 103009d6c965SJuan Quintela dest->block_bitmap_mapping = params->block_bitmap_mapping; 103109d6c965SJuan Quintela } 103209d6c965SJuan Quintela } 103309d6c965SJuan Quintela 103409d6c965SJuan Quintela static void migrate_params_apply(MigrateSetParameters *params, Error **errp) 103509d6c965SJuan Quintela { 103609d6c965SJuan Quintela MigrationState *s = migrate_get_current(); 103709d6c965SJuan Quintela 103809d6c965SJuan Quintela /* TODO use QAPI_CLONE() instead of duplicating it inline */ 103909d6c965SJuan Quintela 104009d6c965SJuan Quintela if (params->has_compress_level) { 104109d6c965SJuan Quintela s->parameters.compress_level = params->compress_level; 104209d6c965SJuan Quintela } 104309d6c965SJuan Quintela 104409d6c965SJuan Quintela if (params->has_compress_threads) { 104509d6c965SJuan Quintela s->parameters.compress_threads = params->compress_threads; 104609d6c965SJuan Quintela } 104709d6c965SJuan Quintela 104809d6c965SJuan Quintela if (params->has_compress_wait_thread) { 104909d6c965SJuan Quintela s->parameters.compress_wait_thread = params->compress_wait_thread; 105009d6c965SJuan Quintela } 105109d6c965SJuan Quintela 105209d6c965SJuan Quintela if (params->has_decompress_threads) { 105309d6c965SJuan Quintela s->parameters.decompress_threads = params->decompress_threads; 105409d6c965SJuan Quintela } 105509d6c965SJuan Quintela 105609d6c965SJuan Quintela if (params->has_throttle_trigger_threshold) { 105709d6c965SJuan Quintela s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; 105809d6c965SJuan Quintela } 105909d6c965SJuan Quintela 106009d6c965SJuan Quintela if (params->has_cpu_throttle_initial) { 106109d6c965SJuan Quintela s->parameters.cpu_throttle_initial = params->cpu_throttle_initial; 106209d6c965SJuan Quintela } 106309d6c965SJuan Quintela 106409d6c965SJuan Quintela if (params->has_cpu_throttle_increment) { 106509d6c965SJuan Quintela s->parameters.cpu_throttle_increment = params->cpu_throttle_increment; 106609d6c965SJuan Quintela } 106709d6c965SJuan Quintela 106809d6c965SJuan Quintela if (params->has_cpu_throttle_tailslow) { 106909d6c965SJuan Quintela s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow; 107009d6c965SJuan Quintela } 107109d6c965SJuan Quintela 107209d6c965SJuan Quintela if (params->tls_creds) { 107309d6c965SJuan Quintela g_free(s->parameters.tls_creds); 107409d6c965SJuan Quintela assert(params->tls_creds->type == QTYPE_QSTRING); 107509d6c965SJuan Quintela s->parameters.tls_creds = g_strdup(params->tls_creds->u.s); 107609d6c965SJuan Quintela } 107709d6c965SJuan Quintela 107809d6c965SJuan Quintela if (params->tls_hostname) { 107909d6c965SJuan Quintela g_free(s->parameters.tls_hostname); 108009d6c965SJuan Quintela assert(params->tls_hostname->type == QTYPE_QSTRING); 108109d6c965SJuan Quintela s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); 108209d6c965SJuan Quintela } 108309d6c965SJuan Quintela 108409d6c965SJuan Quintela if (params->tls_authz) { 108509d6c965SJuan Quintela g_free(s->parameters.tls_authz); 108609d6c965SJuan Quintela assert(params->tls_authz->type == QTYPE_QSTRING); 108709d6c965SJuan Quintela s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); 108809d6c965SJuan Quintela } 108909d6c965SJuan Quintela 109009d6c965SJuan Quintela if (params->has_max_bandwidth) { 109109d6c965SJuan Quintela s->parameters.max_bandwidth = params->max_bandwidth; 109209d6c965SJuan Quintela if (s->to_dst_file && !migration_in_postcopy()) { 109309d6c965SJuan Quintela qemu_file_set_rate_limit(s->to_dst_file, 109409d6c965SJuan Quintela s->parameters.max_bandwidth / XFER_LIMIT_RATIO); 109509d6c965SJuan Quintela } 109609d6c965SJuan Quintela } 109709d6c965SJuan Quintela 109809d6c965SJuan Quintela if (params->has_downtime_limit) { 109909d6c965SJuan Quintela s->parameters.downtime_limit = params->downtime_limit; 110009d6c965SJuan Quintela } 110109d6c965SJuan Quintela 110209d6c965SJuan Quintela if (params->has_x_checkpoint_delay) { 110309d6c965SJuan Quintela s->parameters.x_checkpoint_delay = params->x_checkpoint_delay; 110409d6c965SJuan Quintela if (migration_in_colo_state()) { 110509d6c965SJuan Quintela colo_checkpoint_notify(s); 110609d6c965SJuan Quintela } 110709d6c965SJuan Quintela } 110809d6c965SJuan Quintela 110909d6c965SJuan Quintela if (params->has_block_incremental) { 111009d6c965SJuan Quintela s->parameters.block_incremental = params->block_incremental; 111109d6c965SJuan Quintela } 111209d6c965SJuan Quintela if (params->has_multifd_channels) { 111309d6c965SJuan Quintela s->parameters.multifd_channels = params->multifd_channels; 111409d6c965SJuan Quintela } 111509d6c965SJuan Quintela if (params->has_multifd_compression) { 111609d6c965SJuan Quintela s->parameters.multifd_compression = params->multifd_compression; 111709d6c965SJuan Quintela } 111809d6c965SJuan Quintela if (params->has_xbzrle_cache_size) { 111909d6c965SJuan Quintela s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; 112009d6c965SJuan Quintela xbzrle_cache_resize(params->xbzrle_cache_size, errp); 112109d6c965SJuan Quintela } 112209d6c965SJuan Quintela if (params->has_max_postcopy_bandwidth) { 112309d6c965SJuan Quintela s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; 112409d6c965SJuan Quintela if (s->to_dst_file && migration_in_postcopy()) { 112509d6c965SJuan Quintela qemu_file_set_rate_limit(s->to_dst_file, 112609d6c965SJuan Quintela s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO); 112709d6c965SJuan Quintela } 112809d6c965SJuan Quintela } 112909d6c965SJuan Quintela if (params->has_max_cpu_throttle) { 113009d6c965SJuan Quintela s->parameters.max_cpu_throttle = params->max_cpu_throttle; 113109d6c965SJuan Quintela } 113209d6c965SJuan Quintela if (params->has_announce_initial) { 113309d6c965SJuan Quintela s->parameters.announce_initial = params->announce_initial; 113409d6c965SJuan Quintela } 113509d6c965SJuan Quintela if (params->has_announce_max) { 113609d6c965SJuan Quintela s->parameters.announce_max = params->announce_max; 113709d6c965SJuan Quintela } 113809d6c965SJuan Quintela if (params->has_announce_rounds) { 113909d6c965SJuan Quintela s->parameters.announce_rounds = params->announce_rounds; 114009d6c965SJuan Quintela } 114109d6c965SJuan Quintela if (params->has_announce_step) { 114209d6c965SJuan Quintela s->parameters.announce_step = params->announce_step; 114309d6c965SJuan Quintela } 114409d6c965SJuan Quintela 114509d6c965SJuan Quintela if (params->has_block_bitmap_mapping) { 114609d6c965SJuan Quintela qapi_free_BitmapMigrationNodeAliasList( 114709d6c965SJuan Quintela s->parameters.block_bitmap_mapping); 114809d6c965SJuan Quintela 114909d6c965SJuan Quintela s->parameters.has_block_bitmap_mapping = true; 115009d6c965SJuan Quintela s->parameters.block_bitmap_mapping = 115109d6c965SJuan Quintela QAPI_CLONE(BitmapMigrationNodeAliasList, 115209d6c965SJuan Quintela params->block_bitmap_mapping); 115309d6c965SJuan Quintela } 115409d6c965SJuan Quintela } 115509d6c965SJuan Quintela 115609d6c965SJuan Quintela void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) 115709d6c965SJuan Quintela { 115809d6c965SJuan Quintela MigrationParameters tmp; 115909d6c965SJuan Quintela 116009d6c965SJuan Quintela /* TODO Rewrite "" to null instead */ 116109d6c965SJuan Quintela if (params->tls_creds 116209d6c965SJuan Quintela && params->tls_creds->type == QTYPE_QNULL) { 116309d6c965SJuan Quintela qobject_unref(params->tls_creds->u.n); 116409d6c965SJuan Quintela params->tls_creds->type = QTYPE_QSTRING; 116509d6c965SJuan Quintela params->tls_creds->u.s = strdup(""); 116609d6c965SJuan Quintela } 116709d6c965SJuan Quintela /* TODO Rewrite "" to null instead */ 116809d6c965SJuan Quintela if (params->tls_hostname 116909d6c965SJuan Quintela && params->tls_hostname->type == QTYPE_QNULL) { 117009d6c965SJuan Quintela qobject_unref(params->tls_hostname->u.n); 117109d6c965SJuan Quintela params->tls_hostname->type = QTYPE_QSTRING; 117209d6c965SJuan Quintela params->tls_hostname->u.s = strdup(""); 117309d6c965SJuan Quintela } 117409d6c965SJuan Quintela 117509d6c965SJuan Quintela migrate_params_test_apply(params, &tmp); 117609d6c965SJuan Quintela 117709d6c965SJuan Quintela if (!migrate_params_check(&tmp, errp)) { 117809d6c965SJuan Quintela /* Invalid parameter */ 117909d6c965SJuan Quintela return; 118009d6c965SJuan Quintela } 118109d6c965SJuan Quintela 118209d6c965SJuan Quintela migrate_params_apply(params, errp); 118309d6c965SJuan Quintela } 1184