xref: /openbmc/qemu/migration/options.c (revision f774fde5d4e97cbfc64dab6622c2c53c5fe5c9fe)
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"
1577608706SJuan Quintela #include "qapi/error.h"
164d0c6b69SJuan Quintela #include "qapi/qapi-commands-migration.h"
17f80196b7SJuan Quintela #include "qapi/qmp/qerror.h"
1877608706SJuan Quintela #include "sysemu/runstate.h"
192682c4eeSJuan Quintela #include "migration/misc.h"
201f0776f1SJuan Quintela #include "migration.h"
2177608706SJuan Quintela #include "ram.h"
221f0776f1SJuan Quintela #include "options.h"
231f0776f1SJuan Quintela 
241f0776f1SJuan Quintela bool migrate_auto_converge(void)
251f0776f1SJuan Quintela {
261f0776f1SJuan Quintela     MigrationState *s;
271f0776f1SJuan Quintela 
281f0776f1SJuan Quintela     s = migrate_get_current();
291f0776f1SJuan Quintela 
301f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
311f0776f1SJuan Quintela }
321f0776f1SJuan Quintela 
331f0776f1SJuan Quintela bool migrate_background_snapshot(void)
341f0776f1SJuan Quintela {
351f0776f1SJuan Quintela     MigrationState *s;
361f0776f1SJuan Quintela 
371f0776f1SJuan Quintela     s = migrate_get_current();
381f0776f1SJuan Quintela 
391f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
401f0776f1SJuan Quintela }
411f0776f1SJuan Quintela 
429d4b1e5fSJuan Quintela bool migrate_block(void)
439d4b1e5fSJuan Quintela {
449d4b1e5fSJuan Quintela     MigrationState *s;
459d4b1e5fSJuan Quintela 
469d4b1e5fSJuan Quintela     s = migrate_get_current();
479d4b1e5fSJuan Quintela 
489d4b1e5fSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BLOCK];
499d4b1e5fSJuan Quintela }
509d4b1e5fSJuan Quintela 
515e804644SJuan Quintela bool migrate_colo(void)
525e804644SJuan Quintela {
535e804644SJuan Quintela     MigrationState *s = migrate_get_current();
545e804644SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
555e804644SJuan Quintela }
565e804644SJuan Quintela 
57a7a94d14SJuan Quintela bool migrate_compress(void)
58a7a94d14SJuan Quintela {
59a7a94d14SJuan Quintela     MigrationState *s;
60a7a94d14SJuan Quintela 
61a7a94d14SJuan Quintela     s = migrate_get_current();
62a7a94d14SJuan Quintela 
63a7a94d14SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
64a7a94d14SJuan Quintela }
65a7a94d14SJuan Quintela 
661f0776f1SJuan Quintela bool migrate_dirty_bitmaps(void)
671f0776f1SJuan Quintela {
681f0776f1SJuan Quintela     MigrationState *s;
691f0776f1SJuan Quintela 
701f0776f1SJuan Quintela     s = migrate_get_current();
711f0776f1SJuan Quintela 
721f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
731f0776f1SJuan Quintela }
741f0776f1SJuan Quintela 
75b890902cSJuan Quintela bool migrate_events(void)
76b890902cSJuan Quintela {
77b890902cSJuan Quintela     MigrationState *s;
78b890902cSJuan Quintela 
79b890902cSJuan Quintela     s = migrate_get_current();
80b890902cSJuan Quintela 
81b890902cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
82b890902cSJuan Quintela }
83b890902cSJuan Quintela 
841f0776f1SJuan Quintela bool migrate_ignore_shared(void)
851f0776f1SJuan Quintela {
861f0776f1SJuan Quintela     MigrationState *s;
871f0776f1SJuan Quintela 
881f0776f1SJuan Quintela     s = migrate_get_current();
891f0776f1SJuan Quintela 
901f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
911f0776f1SJuan Quintela }
921f0776f1SJuan Quintela 
931f0776f1SJuan Quintela bool migrate_late_block_activate(void)
941f0776f1SJuan Quintela {
951f0776f1SJuan Quintela     MigrationState *s;
961f0776f1SJuan Quintela 
971f0776f1SJuan Quintela     s = migrate_get_current();
981f0776f1SJuan Quintela 
991f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
1001f0776f1SJuan Quintela }
1011f0776f1SJuan Quintela 
10251b07548SJuan Quintela bool migrate_multifd(void)
10351b07548SJuan Quintela {
10451b07548SJuan Quintela     MigrationState *s;
10551b07548SJuan Quintela 
10651b07548SJuan Quintela     s = migrate_get_current();
10751b07548SJuan Quintela 
10851b07548SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
10951b07548SJuan Quintela }
11051b07548SJuan Quintela 
1111f0776f1SJuan Quintela bool migrate_pause_before_switchover(void)
1121f0776f1SJuan Quintela {
1131f0776f1SJuan Quintela     MigrationState *s;
1141f0776f1SJuan Quintela 
1151f0776f1SJuan Quintela     s = migrate_get_current();
1161f0776f1SJuan Quintela 
1171f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
1181f0776f1SJuan Quintela }
1191f0776f1SJuan Quintela 
1201f0776f1SJuan Quintela bool migrate_postcopy_blocktime(void)
1211f0776f1SJuan Quintela {
1221f0776f1SJuan Quintela     MigrationState *s;
1231f0776f1SJuan Quintela 
1241f0776f1SJuan Quintela     s = migrate_get_current();
1251f0776f1SJuan Quintela 
1261f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
1271f0776f1SJuan Quintela }
1281f0776f1SJuan Quintela 
1291f0776f1SJuan Quintela bool migrate_postcopy_preempt(void)
1301f0776f1SJuan Quintela {
1311f0776f1SJuan Quintela     MigrationState *s;
1321f0776f1SJuan Quintela 
1331f0776f1SJuan Quintela     s = migrate_get_current();
1341f0776f1SJuan Quintela 
1351f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
1361f0776f1SJuan Quintela }
1371f0776f1SJuan Quintela 
1381f0776f1SJuan Quintela bool migrate_postcopy_ram(void)
1391f0776f1SJuan Quintela {
1401f0776f1SJuan Quintela     MigrationState *s;
1411f0776f1SJuan Quintela 
1421f0776f1SJuan Quintela     s = migrate_get_current();
1431f0776f1SJuan Quintela 
1441f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
1451f0776f1SJuan Quintela }
1461f0776f1SJuan Quintela 
14717cba690SJuan Quintela bool migrate_rdma_pin_all(void)
14817cba690SJuan Quintela {
14917cba690SJuan Quintela     MigrationState *s = migrate_get_current();
15017cba690SJuan Quintela 
15117cba690SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
15217cba690SJuan Quintela }
15317cba690SJuan Quintela 
1541f0776f1SJuan Quintela bool migrate_release_ram(void)
1551f0776f1SJuan Quintela {
1561f0776f1SJuan Quintela     MigrationState *s;
1571f0776f1SJuan Quintela 
1581f0776f1SJuan Quintela     s = migrate_get_current();
1591f0776f1SJuan Quintela 
1601f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
1611f0776f1SJuan Quintela }
1621f0776f1SJuan Quintela 
16338ad1110SJuan Quintela bool migrate_return_path(void)
16438ad1110SJuan Quintela {
16538ad1110SJuan Quintela     MigrationState *s;
16638ad1110SJuan Quintela 
16738ad1110SJuan Quintela     s = migrate_get_current();
16838ad1110SJuan Quintela 
16938ad1110SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
17038ad1110SJuan Quintela }
17138ad1110SJuan Quintela 
1721f0776f1SJuan Quintela bool migrate_validate_uuid(void)
1731f0776f1SJuan Quintela {
1741f0776f1SJuan Quintela     MigrationState *s;
1751f0776f1SJuan Quintela 
1761f0776f1SJuan Quintela     s = migrate_get_current();
1771f0776f1SJuan Quintela 
1781f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
1791f0776f1SJuan Quintela }
1801f0776f1SJuan Quintela 
18187dca0c9SJuan Quintela bool migrate_xbzrle(void)
18287dca0c9SJuan Quintela {
18387dca0c9SJuan Quintela     MigrationState *s;
18487dca0c9SJuan Quintela 
18587dca0c9SJuan Quintela     s = migrate_get_current();
18687dca0c9SJuan Quintela 
18787dca0c9SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
18887dca0c9SJuan Quintela }
18987dca0c9SJuan Quintela 
1901f0776f1SJuan Quintela bool migrate_zero_blocks(void)
1911f0776f1SJuan Quintela {
1921f0776f1SJuan Quintela     MigrationState *s;
1931f0776f1SJuan Quintela 
1941f0776f1SJuan Quintela     s = migrate_get_current();
1951f0776f1SJuan Quintela 
1961f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
1971f0776f1SJuan Quintela }
198b4bc342cSJuan Quintela 
199b4bc342cSJuan Quintela bool migrate_zero_copy_send(void)
200b4bc342cSJuan Quintela {
201b4bc342cSJuan Quintela     MigrationState *s;
202b4bc342cSJuan Quintela 
203b4bc342cSJuan Quintela     s = migrate_get_current();
204b4bc342cSJuan Quintela 
205b4bc342cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
206b4bc342cSJuan Quintela }
207*f774fde5SJuan Quintela 
208*f774fde5SJuan Quintela /* pseudo capabilities */
209*f774fde5SJuan Quintela 
210*f774fde5SJuan Quintela bool migrate_postcopy(void)
211*f774fde5SJuan Quintela {
212*f774fde5SJuan Quintela     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
213*f774fde5SJuan Quintela }
214*f774fde5SJuan Quintela 
21577608706SJuan Quintela typedef enum WriteTrackingSupport {
21677608706SJuan Quintela     WT_SUPPORT_UNKNOWN = 0,
21777608706SJuan Quintela     WT_SUPPORT_ABSENT,
21877608706SJuan Quintela     WT_SUPPORT_AVAILABLE,
21977608706SJuan Quintela     WT_SUPPORT_COMPATIBLE
22077608706SJuan Quintela } WriteTrackingSupport;
22177608706SJuan Quintela 
22277608706SJuan Quintela static
22377608706SJuan Quintela WriteTrackingSupport migrate_query_write_tracking(void)
22477608706SJuan Quintela {
22577608706SJuan Quintela     /* Check if kernel supports required UFFD features */
22677608706SJuan Quintela     if (!ram_write_tracking_available()) {
22777608706SJuan Quintela         return WT_SUPPORT_ABSENT;
22877608706SJuan Quintela     }
22977608706SJuan Quintela     /*
23077608706SJuan Quintela      * Check if current memory configuration is
23177608706SJuan Quintela      * compatible with required UFFD features.
23277608706SJuan Quintela      */
23377608706SJuan Quintela     if (!ram_write_tracking_compatible()) {
23477608706SJuan Quintela         return WT_SUPPORT_AVAILABLE;
23577608706SJuan Quintela     }
23677608706SJuan Quintela 
23777608706SJuan Quintela     return WT_SUPPORT_COMPATIBLE;
23877608706SJuan Quintela }
23977608706SJuan Quintela 
24077608706SJuan Quintela /* Migration capabilities set */
24177608706SJuan Quintela struct MigrateCapsSet {
24277608706SJuan Quintela     int size;                       /* Capability set size */
24377608706SJuan Quintela     MigrationCapability caps[];     /* Variadic array of capabilities */
24477608706SJuan Quintela };
24577608706SJuan Quintela typedef struct MigrateCapsSet MigrateCapsSet;
24677608706SJuan Quintela 
24777608706SJuan Quintela /* Define and initialize MigrateCapsSet */
24877608706SJuan Quintela #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
24977608706SJuan Quintela     MigrateCapsSet _name = {    \
25077608706SJuan Quintela         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
25177608706SJuan Quintela         .caps = { __VA_ARGS__ } \
25277608706SJuan Quintela     }
25377608706SJuan Quintela 
25477608706SJuan Quintela /* Background-snapshot compatibility check list */
25577608706SJuan Quintela static const
25677608706SJuan Quintela INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
25777608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_RAM,
25877608706SJuan Quintela     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
25977608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
26077608706SJuan Quintela     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
26177608706SJuan Quintela     MIGRATION_CAPABILITY_RETURN_PATH,
26277608706SJuan Quintela     MIGRATION_CAPABILITY_MULTIFD,
26377608706SJuan Quintela     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
26477608706SJuan Quintela     MIGRATION_CAPABILITY_AUTO_CONVERGE,
26577608706SJuan Quintela     MIGRATION_CAPABILITY_RELEASE_RAM,
26677608706SJuan Quintela     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
26777608706SJuan Quintela     MIGRATION_CAPABILITY_COMPRESS,
26877608706SJuan Quintela     MIGRATION_CAPABILITY_XBZRLE,
26977608706SJuan Quintela     MIGRATION_CAPABILITY_X_COLO,
27077608706SJuan Quintela     MIGRATION_CAPABILITY_VALIDATE_UUID,
27177608706SJuan Quintela     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
27277608706SJuan Quintela 
27377608706SJuan Quintela /**
27477608706SJuan Quintela  * @migration_caps_check - check capability compatibility
27577608706SJuan Quintela  *
27677608706SJuan Quintela  * @old_caps: old capability list
27777608706SJuan Quintela  * @new_caps: new capability list
27877608706SJuan Quintela  * @errp: set *errp if the check failed, with reason
27977608706SJuan Quintela  *
28077608706SJuan Quintela  * Returns true if check passed, otherwise false.
28177608706SJuan Quintela  */
28277608706SJuan Quintela bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
28377608706SJuan Quintela {
28477608706SJuan Quintela     MigrationIncomingState *mis = migration_incoming_get_current();
28577608706SJuan Quintela 
28677608706SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
28777608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BLOCK]) {
28877608706SJuan Quintela         error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) "
28977608706SJuan Quintela                    "block migration");
29077608706SJuan Quintela         error_append_hint(errp, "Use drive_mirror+NBD instead.\n");
29177608706SJuan Quintela         return false;
29277608706SJuan Quintela     }
29377608706SJuan Quintela #endif
29477608706SJuan Quintela 
29577608706SJuan Quintela #ifndef CONFIG_REPLICATION
29677608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
29777608706SJuan Quintela         error_setg(errp, "QEMU compiled without replication module"
29877608706SJuan Quintela                    " can't enable COLO");
29977608706SJuan Quintela         error_append_hint(errp, "Please enable replication before COLO.\n");
30077608706SJuan Quintela         return false;
30177608706SJuan Quintela     }
30277608706SJuan Quintela #endif
30377608706SJuan Quintela 
30477608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
30577608706SJuan Quintela         /* This check is reasonably expensive, so only when it's being
30677608706SJuan Quintela          * set the first time, also it's only the destination that needs
30777608706SJuan Quintela          * special support.
30877608706SJuan Quintela          */
30977608706SJuan Quintela         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
31077608706SJuan Quintela             runstate_check(RUN_STATE_INMIGRATE) &&
31177608706SJuan Quintela             !postcopy_ram_supported_by_host(mis)) {
31277608706SJuan Quintela             /* postcopy_ram_supported_by_host will have emitted a more
31377608706SJuan Quintela              * detailed message
31477608706SJuan Quintela              */
31577608706SJuan Quintela             error_setg(errp, "Postcopy is not supported");
31677608706SJuan Quintela             return false;
31777608706SJuan Quintela         }
31877608706SJuan Quintela 
31977608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
32077608706SJuan Quintela             error_setg(errp, "Postcopy is not compatible with ignore-shared");
32177608706SJuan Quintela             return false;
32277608706SJuan Quintela         }
32377608706SJuan Quintela     }
32477608706SJuan Quintela 
32577608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
32677608706SJuan Quintela         WriteTrackingSupport wt_support;
32777608706SJuan Quintela         int idx;
32877608706SJuan Quintela         /*
32977608706SJuan Quintela          * Check if 'background-snapshot' capability is supported by
33077608706SJuan Quintela          * host kernel and compatible with guest memory configuration.
33177608706SJuan Quintela          */
33277608706SJuan Quintela         wt_support = migrate_query_write_tracking();
33377608706SJuan Quintela         if (wt_support < WT_SUPPORT_AVAILABLE) {
33477608706SJuan Quintela             error_setg(errp, "Background-snapshot is not supported by host kernel");
33577608706SJuan Quintela             return false;
33677608706SJuan Quintela         }
33777608706SJuan Quintela         if (wt_support < WT_SUPPORT_COMPATIBLE) {
33877608706SJuan Quintela             error_setg(errp, "Background-snapshot is not compatible "
33977608706SJuan Quintela                     "with guest memory configuration");
34077608706SJuan Quintela             return false;
34177608706SJuan Quintela         }
34277608706SJuan Quintela 
34377608706SJuan Quintela         /*
34477608706SJuan Quintela          * Check if there are any migration capabilities
34577608706SJuan Quintela          * incompatible with 'background-snapshot'.
34677608706SJuan Quintela          */
34777608706SJuan Quintela         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
34877608706SJuan Quintela             int incomp_cap = check_caps_background_snapshot.caps[idx];
34977608706SJuan Quintela             if (new_caps[incomp_cap]) {
35077608706SJuan Quintela                 error_setg(errp,
35177608706SJuan Quintela                         "Background-snapshot is not compatible with %s",
35277608706SJuan Quintela                         MigrationCapability_str(incomp_cap));
35377608706SJuan Quintela                 return false;
35477608706SJuan Quintela             }
35577608706SJuan Quintela         }
35677608706SJuan Quintela     }
35777608706SJuan Quintela 
35877608706SJuan Quintela #ifdef CONFIG_LINUX
35977608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
36077608706SJuan Quintela         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
36177608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_COMPRESS] ||
36277608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
36377608706SJuan Quintela          migrate_multifd_compression() ||
36477608706SJuan Quintela          migrate_use_tls())) {
36577608706SJuan Quintela         error_setg(errp,
36677608706SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
36777608706SJuan Quintela         return false;
36877608706SJuan Quintela     }
36977608706SJuan Quintela #else
37077608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
37177608706SJuan Quintela         error_setg(errp,
37277608706SJuan Quintela                    "Zero copy currently only available on Linux");
37377608706SJuan Quintela         return false;
37477608706SJuan Quintela     }
37577608706SJuan Quintela #endif
37677608706SJuan Quintela 
37777608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
37877608706SJuan Quintela         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
37977608706SJuan Quintela             error_setg(errp, "Postcopy preempt requires postcopy-ram");
38077608706SJuan Quintela             return false;
38177608706SJuan Quintela         }
38277608706SJuan Quintela 
38377608706SJuan Quintela         /*
38477608706SJuan Quintela          * Preempt mode requires urgent pages to be sent in separate
38577608706SJuan Quintela          * channel, OTOH compression logic will disorder all pages into
38677608706SJuan Quintela          * different compression channels, which is not compatible with the
38777608706SJuan Quintela          * preempt assumptions on channel assignments.
38877608706SJuan Quintela          */
38977608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
39077608706SJuan Quintela             error_setg(errp, "Postcopy preempt not compatible with compress");
39177608706SJuan Quintela             return false;
39277608706SJuan Quintela         }
39377608706SJuan Quintela     }
39477608706SJuan Quintela 
39577608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
39677608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
39777608706SJuan Quintela             error_setg(errp, "Multifd is not compatible with compress");
39877608706SJuan Quintela             return false;
39977608706SJuan Quintela         }
40077608706SJuan Quintela     }
40177608706SJuan Quintela 
40277608706SJuan Quintela     return true;
40377608706SJuan Quintela }
4044d0c6b69SJuan Quintela 
405f80196b7SJuan Quintela bool migrate_cap_set(int cap, bool value, Error **errp)
406f80196b7SJuan Quintela {
407f80196b7SJuan Quintela     MigrationState *s = migrate_get_current();
408f80196b7SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
409f80196b7SJuan Quintela 
410f80196b7SJuan Quintela     if (migration_is_running(s->state)) {
411f80196b7SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
412f80196b7SJuan Quintela         return false;
413f80196b7SJuan Quintela     }
414f80196b7SJuan Quintela 
415f80196b7SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
416f80196b7SJuan Quintela     new_caps[cap] = value;
417f80196b7SJuan Quintela 
418f80196b7SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
419f80196b7SJuan Quintela         return false;
420f80196b7SJuan Quintela     }
421f80196b7SJuan Quintela     s->capabilities[cap] = value;
422f80196b7SJuan Quintela     return true;
423f80196b7SJuan Quintela }
424f80196b7SJuan Quintela 
4254d0c6b69SJuan Quintela MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
4264d0c6b69SJuan Quintela {
4274d0c6b69SJuan Quintela     MigrationCapabilityStatusList *head = NULL, **tail = &head;
4284d0c6b69SJuan Quintela     MigrationCapabilityStatus *caps;
4294d0c6b69SJuan Quintela     MigrationState *s = migrate_get_current();
4304d0c6b69SJuan Quintela     int i;
4314d0c6b69SJuan Quintela 
4324d0c6b69SJuan Quintela     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
4334d0c6b69SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
4344d0c6b69SJuan Quintela         if (i == MIGRATION_CAPABILITY_BLOCK) {
4354d0c6b69SJuan Quintela             continue;
4364d0c6b69SJuan Quintela         }
4374d0c6b69SJuan Quintela #endif
4384d0c6b69SJuan Quintela         caps = g_malloc0(sizeof(*caps));
4394d0c6b69SJuan Quintela         caps->capability = i;
4404d0c6b69SJuan Quintela         caps->state = s->capabilities[i];
4414d0c6b69SJuan Quintela         QAPI_LIST_APPEND(tail, caps);
4424d0c6b69SJuan Quintela     }
4434d0c6b69SJuan Quintela 
4444d0c6b69SJuan Quintela     return head;
4454d0c6b69SJuan Quintela }
44645c1de13SJuan Quintela 
44745c1de13SJuan Quintela void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
44845c1de13SJuan Quintela                                   Error **errp)
44945c1de13SJuan Quintela {
45045c1de13SJuan Quintela     MigrationState *s = migrate_get_current();
45145c1de13SJuan Quintela     MigrationCapabilityStatusList *cap;
45245c1de13SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
45345c1de13SJuan Quintela 
45445c1de13SJuan Quintela     if (migration_is_running(s->state)) {
45545c1de13SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
45645c1de13SJuan Quintela         return;
45745c1de13SJuan Quintela     }
45845c1de13SJuan Quintela 
45945c1de13SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
46045c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
46145c1de13SJuan Quintela         new_caps[cap->value->capability] = cap->value->state;
46245c1de13SJuan Quintela     }
46345c1de13SJuan Quintela 
46445c1de13SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
46545c1de13SJuan Quintela         return;
46645c1de13SJuan Quintela     }
46745c1de13SJuan Quintela 
46845c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
46945c1de13SJuan Quintela         s->capabilities[cap->value->capability] = cap->value->state;
47045c1de13SJuan Quintela     }
47145c1de13SJuan Quintela }
4721dfc4b9eSJuan Quintela 
4731dfc4b9eSJuan Quintela /* parameters */
4741dfc4b9eSJuan Quintela 
4756f8be708SJuan Quintela bool migrate_block_incremental(void)
4766f8be708SJuan Quintela {
4776f8be708SJuan Quintela     MigrationState *s;
4786f8be708SJuan Quintela 
4796f8be708SJuan Quintela     s = migrate_get_current();
4806f8be708SJuan Quintela 
4816f8be708SJuan Quintela     return s->parameters.block_incremental;
4826f8be708SJuan Quintela }
4836f8be708SJuan Quintela 
484f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void)
485f94a858fSJuan Quintela {
486f94a858fSJuan Quintela     MigrationState *s;
487f94a858fSJuan Quintela 
488f94a858fSJuan Quintela     s = migrate_get_current();
489f94a858fSJuan Quintela 
490f94a858fSJuan Quintela     return s->parameters.x_checkpoint_delay;
491f94a858fSJuan Quintela }
492f94a858fSJuan Quintela 
4931dfc4b9eSJuan Quintela int migrate_compress_level(void)
4941dfc4b9eSJuan Quintela {
4951dfc4b9eSJuan Quintela     MigrationState *s;
4961dfc4b9eSJuan Quintela 
4971dfc4b9eSJuan Quintela     s = migrate_get_current();
4981dfc4b9eSJuan Quintela 
4991dfc4b9eSJuan Quintela     return s->parameters.compress_level;
5001dfc4b9eSJuan Quintela }
5011dfc4b9eSJuan Quintela 
5021dfc4b9eSJuan Quintela int migrate_compress_threads(void)
5031dfc4b9eSJuan Quintela {
5041dfc4b9eSJuan Quintela     MigrationState *s;
5051dfc4b9eSJuan Quintela 
5061dfc4b9eSJuan Quintela     s = migrate_get_current();
5071dfc4b9eSJuan Quintela 
5081dfc4b9eSJuan Quintela     return s->parameters.compress_threads;
5091dfc4b9eSJuan Quintela }
5101dfc4b9eSJuan Quintela 
5111dfc4b9eSJuan Quintela int migrate_compress_wait_thread(void)
5121dfc4b9eSJuan Quintela {
5131dfc4b9eSJuan Quintela     MigrationState *s;
5141dfc4b9eSJuan Quintela 
5151dfc4b9eSJuan Quintela     s = migrate_get_current();
5161dfc4b9eSJuan Quintela 
5171dfc4b9eSJuan Quintela     return s->parameters.compress_wait_thread;
5181dfc4b9eSJuan Quintela }
5191dfc4b9eSJuan Quintela 
5209605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void)
5219605c2acSJuan Quintela {
5229605c2acSJuan Quintela     MigrationState *s;
5239605c2acSJuan Quintela 
5249605c2acSJuan Quintela     s = migrate_get_current();
5259605c2acSJuan Quintela 
5269605c2acSJuan Quintela     return s->parameters.cpu_throttle_increment;
5279605c2acSJuan Quintela }
5289605c2acSJuan Quintela 
5292a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void)
5302a8ec380SJuan Quintela {
5312a8ec380SJuan Quintela     MigrationState *s;
5322a8ec380SJuan Quintela 
5332a8ec380SJuan Quintela     s = migrate_get_current();
5342a8ec380SJuan Quintela 
5352a8ec380SJuan Quintela     return s->parameters.cpu_throttle_initial;
5362a8ec380SJuan Quintela }
5372a8ec380SJuan Quintela 
538873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void)
539873f674cSJuan Quintela {
540873f674cSJuan Quintela     MigrationState *s;
541873f674cSJuan Quintela 
542873f674cSJuan Quintela     s = migrate_get_current();
543873f674cSJuan Quintela 
544873f674cSJuan Quintela     return s->parameters.cpu_throttle_tailslow;
545873f674cSJuan Quintela }
546873f674cSJuan Quintela 
5471dfc4b9eSJuan Quintela int migrate_decompress_threads(void)
5481dfc4b9eSJuan Quintela {
5491dfc4b9eSJuan Quintela     MigrationState *s;
5501dfc4b9eSJuan Quintela 
5511dfc4b9eSJuan Quintela     s = migrate_get_current();
5521dfc4b9eSJuan Quintela 
5531dfc4b9eSJuan Quintela     return s->parameters.decompress_threads;
5541dfc4b9eSJuan Quintela }
5551dfc4b9eSJuan Quintela 
55624155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void)
55724155bd0SJuan Quintela {
55824155bd0SJuan Quintela     MigrationState *s;
55924155bd0SJuan Quintela 
56024155bd0SJuan Quintela     s = migrate_get_current();
56124155bd0SJuan Quintela 
56224155bd0SJuan Quintela     return s->parameters.max_cpu_throttle;
56324155bd0SJuan Quintela }
56424155bd0SJuan Quintela 
5651dfc4b9eSJuan Quintela int64_t migrate_max_postcopy_bandwidth(void)
5661dfc4b9eSJuan Quintela {
5671dfc4b9eSJuan Quintela     MigrationState *s;
5681dfc4b9eSJuan Quintela 
5691dfc4b9eSJuan Quintela     s = migrate_get_current();
5701dfc4b9eSJuan Quintela 
5711dfc4b9eSJuan Quintela     return s->parameters.max_postcopy_bandwidth;
5721dfc4b9eSJuan Quintela }
5731dfc4b9eSJuan Quintela 
5741dfc4b9eSJuan Quintela int migrate_multifd_channels(void)
5751dfc4b9eSJuan Quintela {
5761dfc4b9eSJuan Quintela     MigrationState *s;
5771dfc4b9eSJuan Quintela 
5781dfc4b9eSJuan Quintela     s = migrate_get_current();
5791dfc4b9eSJuan Quintela 
5801dfc4b9eSJuan Quintela     return s->parameters.multifd_channels;
5811dfc4b9eSJuan Quintela }
5821dfc4b9eSJuan Quintela 
5831dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void)
5841dfc4b9eSJuan Quintela {
5851dfc4b9eSJuan Quintela     MigrationState *s;
5861dfc4b9eSJuan Quintela 
5871dfc4b9eSJuan Quintela     s = migrate_get_current();
5881dfc4b9eSJuan Quintela 
5891dfc4b9eSJuan Quintela     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
5901dfc4b9eSJuan Quintela     return s->parameters.multifd_compression;
5911dfc4b9eSJuan Quintela }
5921dfc4b9eSJuan Quintela 
5931dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void)
5941dfc4b9eSJuan Quintela {
5951dfc4b9eSJuan Quintela     MigrationState *s;
5961dfc4b9eSJuan Quintela 
5971dfc4b9eSJuan Quintela     s = migrate_get_current();
5981dfc4b9eSJuan Quintela 
5991dfc4b9eSJuan Quintela     return s->parameters.multifd_zlib_level;
6001dfc4b9eSJuan Quintela }
6011dfc4b9eSJuan Quintela 
6021dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void)
6031dfc4b9eSJuan Quintela {
6041dfc4b9eSJuan Quintela     MigrationState *s;
6051dfc4b9eSJuan Quintela 
6061dfc4b9eSJuan Quintela     s = migrate_get_current();
6071dfc4b9eSJuan Quintela 
6081dfc4b9eSJuan Quintela     return s->parameters.multifd_zstd_level;
6091dfc4b9eSJuan Quintela }
6101dfc4b9eSJuan Quintela 
6116499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void)
6126499efdbSJuan Quintela {
6136499efdbSJuan Quintela     MigrationState *s;
6146499efdbSJuan Quintela 
6156499efdbSJuan Quintela     s = migrate_get_current();
6166499efdbSJuan Quintela 
6176499efdbSJuan Quintela     return s->parameters.throttle_trigger_threshold;
6186499efdbSJuan Quintela }
6196499efdbSJuan Quintela 
6201dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void)
6211dfc4b9eSJuan Quintela {
6221dfc4b9eSJuan Quintela     MigrationState *s;
6231dfc4b9eSJuan Quintela 
6241dfc4b9eSJuan Quintela     s = migrate_get_current();
6251dfc4b9eSJuan Quintela 
6261dfc4b9eSJuan Quintela     return s->parameters.xbzrle_cache_size;
6271dfc4b9eSJuan Quintela }
6282682c4eeSJuan Quintela 
6292682c4eeSJuan Quintela /* parameters helpers */
6302682c4eeSJuan Quintela 
6312682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void)
6322682c4eeSJuan Quintela {
6332682c4eeSJuan Quintela     static AnnounceParameters ap;
6342682c4eeSJuan Quintela 
6352682c4eeSJuan Quintela     MigrationState *s = migrate_get_current();
6362682c4eeSJuan Quintela 
6372682c4eeSJuan Quintela     ap.initial = s->parameters.announce_initial;
6382682c4eeSJuan Quintela     ap.max = s->parameters.announce_max;
6392682c4eeSJuan Quintela     ap.rounds = s->parameters.announce_rounds;
6402682c4eeSJuan Quintela     ap.step = s->parameters.announce_step;
6412682c4eeSJuan Quintela 
6422682c4eeSJuan Quintela     return &ap;
6432682c4eeSJuan Quintela }
644