xref: /openbmc/qemu/migration/options.c (revision b804b35b1c8a0edfd127ac20819c234be55ac7fc)
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 {
368f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
371f0776f1SJuan Quintela 
381f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
391f0776f1SJuan Quintela }
401f0776f1SJuan Quintela 
411f0776f1SJuan Quintela bool migrate_background_snapshot(void)
421f0776f1SJuan Quintela {
438f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
441f0776f1SJuan Quintela 
451f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
461f0776f1SJuan Quintela }
471f0776f1SJuan Quintela 
489d4b1e5fSJuan Quintela bool migrate_block(void)
499d4b1e5fSJuan Quintela {
508f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
519d4b1e5fSJuan Quintela 
529d4b1e5fSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_BLOCK];
539d4b1e5fSJuan Quintela }
549d4b1e5fSJuan Quintela 
555e804644SJuan Quintela bool migrate_colo(void)
565e804644SJuan Quintela {
575e804644SJuan Quintela     MigrationState *s = migrate_get_current();
588f9c5327SJuan Quintela 
595e804644SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
605e804644SJuan Quintela }
615e804644SJuan Quintela 
62a7a94d14SJuan Quintela bool migrate_compress(void)
63a7a94d14SJuan Quintela {
648f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
65a7a94d14SJuan Quintela 
66a7a94d14SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
67a7a94d14SJuan Quintela }
68a7a94d14SJuan Quintela 
691f0776f1SJuan Quintela bool migrate_dirty_bitmaps(void)
701f0776f1SJuan Quintela {
718f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
721f0776f1SJuan Quintela 
731f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
741f0776f1SJuan Quintela }
751f0776f1SJuan Quintela 
76b890902cSJuan Quintela bool migrate_events(void)
77b890902cSJuan Quintela {
788f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
79b890902cSJuan Quintela 
80b890902cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
81b890902cSJuan Quintela }
82b890902cSJuan Quintela 
831f0776f1SJuan Quintela bool migrate_ignore_shared(void)
841f0776f1SJuan Quintela {
858f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
861f0776f1SJuan Quintela 
871f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
881f0776f1SJuan Quintela }
891f0776f1SJuan Quintela 
901f0776f1SJuan Quintela bool migrate_late_block_activate(void)
911f0776f1SJuan Quintela {
928f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
931f0776f1SJuan Quintela 
941f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
951f0776f1SJuan Quintela }
961f0776f1SJuan Quintela 
9751b07548SJuan Quintela bool migrate_multifd(void)
9851b07548SJuan Quintela {
998f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
10051b07548SJuan Quintela 
10151b07548SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
10251b07548SJuan Quintela }
10351b07548SJuan Quintela 
1041f0776f1SJuan Quintela bool migrate_pause_before_switchover(void)
1051f0776f1SJuan Quintela {
1068f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1071f0776f1SJuan Quintela 
1081f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
1091f0776f1SJuan Quintela }
1101f0776f1SJuan Quintela 
1111f0776f1SJuan Quintela bool migrate_postcopy_blocktime(void)
1121f0776f1SJuan Quintela {
1138f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1141f0776f1SJuan Quintela 
1151f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
1161f0776f1SJuan Quintela }
1171f0776f1SJuan Quintela 
1181f0776f1SJuan Quintela bool migrate_postcopy_preempt(void)
1191f0776f1SJuan Quintela {
1208f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1211f0776f1SJuan Quintela 
1221f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
1231f0776f1SJuan Quintela }
1241f0776f1SJuan Quintela 
1251f0776f1SJuan Quintela bool migrate_postcopy_ram(void)
1261f0776f1SJuan Quintela {
1278f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1281f0776f1SJuan Quintela 
1291f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
1301f0776f1SJuan Quintela }
1311f0776f1SJuan Quintela 
13217cba690SJuan Quintela bool migrate_rdma_pin_all(void)
13317cba690SJuan Quintela {
13417cba690SJuan Quintela     MigrationState *s = migrate_get_current();
13517cba690SJuan Quintela 
13617cba690SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
13717cba690SJuan Quintela }
13817cba690SJuan Quintela 
1391f0776f1SJuan Quintela bool migrate_release_ram(void)
1401f0776f1SJuan Quintela {
1418f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1421f0776f1SJuan Quintela 
1431f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
1441f0776f1SJuan Quintela }
1451f0776f1SJuan Quintela 
14638ad1110SJuan Quintela bool migrate_return_path(void)
14738ad1110SJuan Quintela {
1488f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
14938ad1110SJuan Quintela 
15038ad1110SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
15138ad1110SJuan Quintela }
15238ad1110SJuan Quintela 
1531f0776f1SJuan Quintela bool migrate_validate_uuid(void)
1541f0776f1SJuan Quintela {
1558f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1561f0776f1SJuan Quintela 
1571f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
1581f0776f1SJuan Quintela }
1591f0776f1SJuan Quintela 
16087dca0c9SJuan Quintela bool migrate_xbzrle(void)
16187dca0c9SJuan Quintela {
1628f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
16387dca0c9SJuan Quintela 
16487dca0c9SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
16587dca0c9SJuan Quintela }
16687dca0c9SJuan Quintela 
1671f0776f1SJuan Quintela bool migrate_zero_blocks(void)
1681f0776f1SJuan Quintela {
1698f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
1701f0776f1SJuan Quintela 
1711f0776f1SJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
1721f0776f1SJuan Quintela }
173b4bc342cSJuan Quintela 
174b4bc342cSJuan Quintela bool migrate_zero_copy_send(void)
175b4bc342cSJuan Quintela {
1768f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
177b4bc342cSJuan Quintela 
178b4bc342cSJuan Quintela     return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
179b4bc342cSJuan Quintela }
180f774fde5SJuan Quintela 
181f774fde5SJuan Quintela /* pseudo capabilities */
182f774fde5SJuan Quintela 
183f774fde5SJuan Quintela bool migrate_postcopy(void)
184f774fde5SJuan Quintela {
185f774fde5SJuan Quintela     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
186f774fde5SJuan Quintela }
187f774fde5SJuan Quintela 
18810d4703bSJuan Quintela bool migrate_tls(void)
18910d4703bSJuan Quintela {
1908f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
19110d4703bSJuan Quintela 
19210d4703bSJuan Quintela     return s->parameters.tls_creds && *s->parameters.tls_creds;
19310d4703bSJuan Quintela }
19410d4703bSJuan Quintela 
19577608706SJuan Quintela typedef enum WriteTrackingSupport {
19677608706SJuan Quintela     WT_SUPPORT_UNKNOWN = 0,
19777608706SJuan Quintela     WT_SUPPORT_ABSENT,
19877608706SJuan Quintela     WT_SUPPORT_AVAILABLE,
19977608706SJuan Quintela     WT_SUPPORT_COMPATIBLE
20077608706SJuan Quintela } WriteTrackingSupport;
20177608706SJuan Quintela 
20277608706SJuan Quintela static
20377608706SJuan Quintela WriteTrackingSupport migrate_query_write_tracking(void)
20477608706SJuan Quintela {
20577608706SJuan Quintela     /* Check if kernel supports required UFFD features */
20677608706SJuan Quintela     if (!ram_write_tracking_available()) {
20777608706SJuan Quintela         return WT_SUPPORT_ABSENT;
20877608706SJuan Quintela     }
20977608706SJuan Quintela     /*
21077608706SJuan Quintela      * Check if current memory configuration is
21177608706SJuan Quintela      * compatible with required UFFD features.
21277608706SJuan Quintela      */
21377608706SJuan Quintela     if (!ram_write_tracking_compatible()) {
21477608706SJuan Quintela         return WT_SUPPORT_AVAILABLE;
21577608706SJuan Quintela     }
21677608706SJuan Quintela 
21777608706SJuan Quintela     return WT_SUPPORT_COMPATIBLE;
21877608706SJuan Quintela }
21977608706SJuan Quintela 
22077608706SJuan Quintela /* Migration capabilities set */
22177608706SJuan Quintela struct MigrateCapsSet {
22277608706SJuan Quintela     int size;                       /* Capability set size */
22377608706SJuan Quintela     MigrationCapability caps[];     /* Variadic array of capabilities */
22477608706SJuan Quintela };
22577608706SJuan Quintela typedef struct MigrateCapsSet MigrateCapsSet;
22677608706SJuan Quintela 
22777608706SJuan Quintela /* Define and initialize MigrateCapsSet */
22877608706SJuan Quintela #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
22977608706SJuan Quintela     MigrateCapsSet _name = {    \
23077608706SJuan Quintela         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
23177608706SJuan Quintela         .caps = { __VA_ARGS__ } \
23277608706SJuan Quintela     }
23377608706SJuan Quintela 
23477608706SJuan Quintela /* Background-snapshot compatibility check list */
23577608706SJuan Quintela static const
23677608706SJuan Quintela INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
23777608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_RAM,
23877608706SJuan Quintela     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
23977608706SJuan Quintela     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
24077608706SJuan Quintela     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
24177608706SJuan Quintela     MIGRATION_CAPABILITY_RETURN_PATH,
24277608706SJuan Quintela     MIGRATION_CAPABILITY_MULTIFD,
24377608706SJuan Quintela     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
24477608706SJuan Quintela     MIGRATION_CAPABILITY_AUTO_CONVERGE,
24577608706SJuan Quintela     MIGRATION_CAPABILITY_RELEASE_RAM,
24677608706SJuan Quintela     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
24777608706SJuan Quintela     MIGRATION_CAPABILITY_COMPRESS,
24877608706SJuan Quintela     MIGRATION_CAPABILITY_XBZRLE,
24977608706SJuan Quintela     MIGRATION_CAPABILITY_X_COLO,
25077608706SJuan Quintela     MIGRATION_CAPABILITY_VALIDATE_UUID,
25177608706SJuan Quintela     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
25277608706SJuan Quintela 
25377608706SJuan Quintela /**
25477608706SJuan Quintela  * @migration_caps_check - check capability compatibility
25577608706SJuan Quintela  *
25677608706SJuan Quintela  * @old_caps: old capability list
25777608706SJuan Quintela  * @new_caps: new capability list
25877608706SJuan Quintela  * @errp: set *errp if the check failed, with reason
25977608706SJuan Quintela  *
26077608706SJuan Quintela  * Returns true if check passed, otherwise false.
26177608706SJuan Quintela  */
26277608706SJuan Quintela bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
26377608706SJuan Quintela {
26477608706SJuan Quintela     MigrationIncomingState *mis = migration_incoming_get_current();
26577608706SJuan Quintela 
26674c38cf7SPeter Xu     ERRP_GUARD();
26777608706SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
26877608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BLOCK]) {
26977608706SJuan Quintela         error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) "
27077608706SJuan Quintela                    "block migration");
27177608706SJuan Quintela         error_append_hint(errp, "Use drive_mirror+NBD instead.\n");
27277608706SJuan Quintela         return false;
27377608706SJuan Quintela     }
27477608706SJuan Quintela #endif
27577608706SJuan Quintela 
27677608706SJuan Quintela #ifndef CONFIG_REPLICATION
27777608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
27877608706SJuan Quintela         error_setg(errp, "QEMU compiled without replication module"
27977608706SJuan Quintela                    " can't enable COLO");
28077608706SJuan Quintela         error_append_hint(errp, "Please enable replication before COLO.\n");
28177608706SJuan Quintela         return false;
28277608706SJuan Quintela     }
28377608706SJuan Quintela #endif
28477608706SJuan Quintela 
28577608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
28677608706SJuan Quintela         /* This check is reasonably expensive, so only when it's being
28777608706SJuan Quintela          * set the first time, also it's only the destination that needs
28877608706SJuan Quintela          * special support.
28977608706SJuan Quintela          */
29077608706SJuan Quintela         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
29177608706SJuan Quintela             runstate_check(RUN_STATE_INMIGRATE) &&
29274c38cf7SPeter Xu             !postcopy_ram_supported_by_host(mis, errp)) {
29374c38cf7SPeter Xu             error_prepend(errp, "Postcopy is not supported: ");
29477608706SJuan Quintela             return false;
29577608706SJuan Quintela         }
29677608706SJuan Quintela 
29777608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
29877608706SJuan Quintela             error_setg(errp, "Postcopy is not compatible with ignore-shared");
29977608706SJuan Quintela             return false;
30077608706SJuan Quintela         }
301b405dfffSLeonardo Bras 
302b405dfffSLeonardo Bras         if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
303b405dfffSLeonardo Bras             error_setg(errp, "Postcopy is not yet compatible with multifd");
304b405dfffSLeonardo Bras             return false;
305b405dfffSLeonardo Bras         }
30677608706SJuan Quintela     }
30777608706SJuan Quintela 
30877608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
30977608706SJuan Quintela         WriteTrackingSupport wt_support;
31077608706SJuan Quintela         int idx;
31177608706SJuan Quintela         /*
31277608706SJuan Quintela          * Check if 'background-snapshot' capability is supported by
31377608706SJuan Quintela          * host kernel and compatible with guest memory configuration.
31477608706SJuan Quintela          */
31577608706SJuan Quintela         wt_support = migrate_query_write_tracking();
31677608706SJuan Quintela         if (wt_support < WT_SUPPORT_AVAILABLE) {
31777608706SJuan Quintela             error_setg(errp, "Background-snapshot is not supported by host kernel");
31877608706SJuan Quintela             return false;
31977608706SJuan Quintela         }
32077608706SJuan Quintela         if (wt_support < WT_SUPPORT_COMPATIBLE) {
32177608706SJuan Quintela             error_setg(errp, "Background-snapshot is not compatible "
32277608706SJuan Quintela                     "with guest memory configuration");
32377608706SJuan Quintela             return false;
32477608706SJuan Quintela         }
32577608706SJuan Quintela 
32677608706SJuan Quintela         /*
32777608706SJuan Quintela          * Check if there are any migration capabilities
32877608706SJuan Quintela          * incompatible with 'background-snapshot'.
32977608706SJuan Quintela          */
33077608706SJuan Quintela         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
33177608706SJuan Quintela             int incomp_cap = check_caps_background_snapshot.caps[idx];
33277608706SJuan Quintela             if (new_caps[incomp_cap]) {
33377608706SJuan Quintela                 error_setg(errp,
33477608706SJuan Quintela                         "Background-snapshot is not compatible with %s",
33577608706SJuan Quintela                         MigrationCapability_str(incomp_cap));
33677608706SJuan Quintela                 return false;
33777608706SJuan Quintela             }
33877608706SJuan Quintela         }
33977608706SJuan Quintela     }
34077608706SJuan Quintela 
34177608706SJuan Quintela #ifdef CONFIG_LINUX
34277608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
34377608706SJuan Quintela         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
34477608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_COMPRESS] ||
34577608706SJuan Quintela          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
34677608706SJuan Quintela          migrate_multifd_compression() ||
34710d4703bSJuan Quintela          migrate_tls())) {
34877608706SJuan Quintela         error_setg(errp,
34977608706SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
35077608706SJuan Quintela         return false;
35177608706SJuan Quintela     }
35277608706SJuan Quintela #else
35377608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
35477608706SJuan Quintela         error_setg(errp,
35577608706SJuan Quintela                    "Zero copy currently only available on Linux");
35677608706SJuan Quintela         return false;
35777608706SJuan Quintela     }
35877608706SJuan Quintela #endif
35977608706SJuan Quintela 
36077608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
36177608706SJuan Quintela         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
36277608706SJuan Quintela             error_setg(errp, "Postcopy preempt requires postcopy-ram");
36377608706SJuan Quintela             return false;
36477608706SJuan Quintela         }
36577608706SJuan Quintela 
36677608706SJuan Quintela         /*
36777608706SJuan Quintela          * Preempt mode requires urgent pages to be sent in separate
36877608706SJuan Quintela          * channel, OTOH compression logic will disorder all pages into
36977608706SJuan Quintela          * different compression channels, which is not compatible with the
37077608706SJuan Quintela          * preempt assumptions on channel assignments.
37177608706SJuan Quintela          */
37277608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
37377608706SJuan Quintela             error_setg(errp, "Postcopy preempt not compatible with compress");
37477608706SJuan Quintela             return false;
37577608706SJuan Quintela         }
37677608706SJuan Quintela     }
37777608706SJuan Quintela 
37877608706SJuan Quintela     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
37977608706SJuan Quintela         if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
38077608706SJuan Quintela             error_setg(errp, "Multifd is not compatible with compress");
38177608706SJuan Quintela             return false;
38277608706SJuan Quintela         }
38377608706SJuan Quintela     }
38477608706SJuan Quintela 
38577608706SJuan Quintela     return true;
38677608706SJuan Quintela }
3874d0c6b69SJuan Quintela 
388f80196b7SJuan Quintela bool migrate_cap_set(int cap, bool value, Error **errp)
389f80196b7SJuan Quintela {
390f80196b7SJuan Quintela     MigrationState *s = migrate_get_current();
391f80196b7SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
392f80196b7SJuan Quintela 
393f80196b7SJuan Quintela     if (migration_is_running(s->state)) {
394f80196b7SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
395f80196b7SJuan Quintela         return false;
396f80196b7SJuan Quintela     }
397f80196b7SJuan Quintela 
398f80196b7SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
399f80196b7SJuan Quintela     new_caps[cap] = value;
400f80196b7SJuan Quintela 
401f80196b7SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
402f80196b7SJuan Quintela         return false;
403f80196b7SJuan Quintela     }
404f80196b7SJuan Quintela     s->capabilities[cap] = value;
405f80196b7SJuan Quintela     return true;
406f80196b7SJuan Quintela }
407f80196b7SJuan Quintela 
4084d0c6b69SJuan Quintela MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
4094d0c6b69SJuan Quintela {
4104d0c6b69SJuan Quintela     MigrationCapabilityStatusList *head = NULL, **tail = &head;
4114d0c6b69SJuan Quintela     MigrationCapabilityStatus *caps;
4124d0c6b69SJuan Quintela     MigrationState *s = migrate_get_current();
4134d0c6b69SJuan Quintela     int i;
4144d0c6b69SJuan Quintela 
4154d0c6b69SJuan Quintela     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
4164d0c6b69SJuan Quintela #ifndef CONFIG_LIVE_BLOCK_MIGRATION
4174d0c6b69SJuan Quintela         if (i == MIGRATION_CAPABILITY_BLOCK) {
4184d0c6b69SJuan Quintela             continue;
4194d0c6b69SJuan Quintela         }
4204d0c6b69SJuan Quintela #endif
4214d0c6b69SJuan Quintela         caps = g_malloc0(sizeof(*caps));
4224d0c6b69SJuan Quintela         caps->capability = i;
4234d0c6b69SJuan Quintela         caps->state = s->capabilities[i];
4244d0c6b69SJuan Quintela         QAPI_LIST_APPEND(tail, caps);
4254d0c6b69SJuan Quintela     }
4264d0c6b69SJuan Quintela 
4274d0c6b69SJuan Quintela     return head;
4284d0c6b69SJuan Quintela }
42945c1de13SJuan Quintela 
43045c1de13SJuan Quintela void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
43145c1de13SJuan Quintela                                   Error **errp)
43245c1de13SJuan Quintela {
43345c1de13SJuan Quintela     MigrationState *s = migrate_get_current();
43445c1de13SJuan Quintela     MigrationCapabilityStatusList *cap;
43545c1de13SJuan Quintela     bool new_caps[MIGRATION_CAPABILITY__MAX];
43645c1de13SJuan Quintela 
43745c1de13SJuan Quintela     if (migration_is_running(s->state)) {
43845c1de13SJuan Quintela         error_setg(errp, QERR_MIGRATION_ACTIVE);
43945c1de13SJuan Quintela         return;
44045c1de13SJuan Quintela     }
44145c1de13SJuan Quintela 
44245c1de13SJuan Quintela     memcpy(new_caps, s->capabilities, sizeof(new_caps));
44345c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
44445c1de13SJuan Quintela         new_caps[cap->value->capability] = cap->value->state;
44545c1de13SJuan Quintela     }
44645c1de13SJuan Quintela 
44745c1de13SJuan Quintela     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
44845c1de13SJuan Quintela         return;
44945c1de13SJuan Quintela     }
45045c1de13SJuan Quintela 
45145c1de13SJuan Quintela     for (cap = params; cap; cap = cap->next) {
45245c1de13SJuan Quintela         s->capabilities[cap->value->capability] = cap->value->state;
45345c1de13SJuan Quintela     }
45445c1de13SJuan Quintela }
4551dfc4b9eSJuan Quintela 
4561dfc4b9eSJuan Quintela /* parameters */
4571dfc4b9eSJuan Quintela 
458*b804b35bSJuan Quintela const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
459*b804b35bSJuan Quintela {
460*b804b35bSJuan Quintela     MigrationState *s = migrate_get_current();
461*b804b35bSJuan Quintela 
462*b804b35bSJuan Quintela     return s->parameters.block_bitmap_mapping;
463*b804b35bSJuan Quintela }
464*b804b35bSJuan Quintela 
4656f8be708SJuan Quintela bool migrate_block_incremental(void)
4666f8be708SJuan Quintela {
4678f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4686f8be708SJuan Quintela 
4696f8be708SJuan Quintela     return s->parameters.block_incremental;
4706f8be708SJuan Quintela }
4716f8be708SJuan Quintela 
472f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void)
473f94a858fSJuan Quintela {
4748f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
475f94a858fSJuan Quintela 
476f94a858fSJuan Quintela     return s->parameters.x_checkpoint_delay;
477f94a858fSJuan Quintela }
478f94a858fSJuan Quintela 
4791dfc4b9eSJuan Quintela int migrate_compress_level(void)
4801dfc4b9eSJuan Quintela {
4818f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4821dfc4b9eSJuan Quintela 
4831dfc4b9eSJuan Quintela     return s->parameters.compress_level;
4841dfc4b9eSJuan Quintela }
4851dfc4b9eSJuan Quintela 
4861dfc4b9eSJuan Quintela int migrate_compress_threads(void)
4871dfc4b9eSJuan Quintela {
4888f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4891dfc4b9eSJuan Quintela 
4901dfc4b9eSJuan Quintela     return s->parameters.compress_threads;
4911dfc4b9eSJuan Quintela }
4921dfc4b9eSJuan Quintela 
4931dfc4b9eSJuan Quintela int migrate_compress_wait_thread(void)
4941dfc4b9eSJuan Quintela {
4958f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4961dfc4b9eSJuan Quintela 
4971dfc4b9eSJuan Quintela     return s->parameters.compress_wait_thread;
4981dfc4b9eSJuan Quintela }
4991dfc4b9eSJuan Quintela 
5009605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void)
5019605c2acSJuan Quintela {
5028f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5039605c2acSJuan Quintela 
5049605c2acSJuan Quintela     return s->parameters.cpu_throttle_increment;
5059605c2acSJuan Quintela }
5069605c2acSJuan Quintela 
5072a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void)
5082a8ec380SJuan Quintela {
5098f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5102a8ec380SJuan Quintela 
5112a8ec380SJuan Quintela     return s->parameters.cpu_throttle_initial;
5122a8ec380SJuan Quintela }
5132a8ec380SJuan Quintela 
514873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void)
515873f674cSJuan Quintela {
5168f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
517873f674cSJuan Quintela 
518873f674cSJuan Quintela     return s->parameters.cpu_throttle_tailslow;
519873f674cSJuan Quintela }
520873f674cSJuan Quintela 
5211dfc4b9eSJuan Quintela int migrate_decompress_threads(void)
5221dfc4b9eSJuan Quintela {
5238f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5241dfc4b9eSJuan Quintela 
5251dfc4b9eSJuan Quintela     return s->parameters.decompress_threads;
5261dfc4b9eSJuan Quintela }
5271dfc4b9eSJuan Quintela 
528f5da8ba4SJuan Quintela uint64_t migrate_downtime_limit(void)
529f5da8ba4SJuan Quintela {
530f5da8ba4SJuan Quintela     MigrationState *s = migrate_get_current();
531f5da8ba4SJuan Quintela 
532f5da8ba4SJuan Quintela     return s->parameters.downtime_limit;
533f5da8ba4SJuan Quintela }
534f5da8ba4SJuan Quintela 
53524155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void)
53624155bd0SJuan Quintela {
5378f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
53824155bd0SJuan Quintela 
53924155bd0SJuan Quintela     return s->parameters.max_cpu_throttle;
54024155bd0SJuan Quintela }
54124155bd0SJuan Quintela 
5429c894df3SJuan Quintela uint64_t migrate_max_bandwidth(void)
5439c894df3SJuan Quintela {
5448f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5459c894df3SJuan Quintela 
5469c894df3SJuan Quintela     return s->parameters.max_bandwidth;
5479c894df3SJuan Quintela }
5489c894df3SJuan Quintela 
5491dfc4b9eSJuan Quintela int64_t migrate_max_postcopy_bandwidth(void)
5501dfc4b9eSJuan Quintela {
5518f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5521dfc4b9eSJuan Quintela 
5531dfc4b9eSJuan Quintela     return s->parameters.max_postcopy_bandwidth;
5541dfc4b9eSJuan Quintela }
5551dfc4b9eSJuan Quintela 
5561dfc4b9eSJuan Quintela int migrate_multifd_channels(void)
5571dfc4b9eSJuan Quintela {
5588f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5591dfc4b9eSJuan Quintela 
5601dfc4b9eSJuan Quintela     return s->parameters.multifd_channels;
5611dfc4b9eSJuan Quintela }
5621dfc4b9eSJuan Quintela 
5631dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void)
5641dfc4b9eSJuan Quintela {
5658f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5661dfc4b9eSJuan Quintela 
5671dfc4b9eSJuan Quintela     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
5681dfc4b9eSJuan Quintela     return s->parameters.multifd_compression;
5691dfc4b9eSJuan Quintela }
5701dfc4b9eSJuan Quintela 
5711dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void)
5721dfc4b9eSJuan Quintela {
5738f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5741dfc4b9eSJuan Quintela 
5751dfc4b9eSJuan Quintela     return s->parameters.multifd_zlib_level;
5761dfc4b9eSJuan Quintela }
5771dfc4b9eSJuan Quintela 
5781dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void)
5791dfc4b9eSJuan Quintela {
5808f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5811dfc4b9eSJuan Quintela 
5821dfc4b9eSJuan Quintela     return s->parameters.multifd_zstd_level;
5831dfc4b9eSJuan Quintela }
5841dfc4b9eSJuan Quintela 
5856499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void)
5866499efdbSJuan Quintela {
5878f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5886499efdbSJuan Quintela 
5896499efdbSJuan Quintela     return s->parameters.throttle_trigger_threshold;
5906499efdbSJuan Quintela }
5916499efdbSJuan Quintela 
5922eb0308bSJuan Quintela const char *migrate_tls_authz(void)
5932eb0308bSJuan Quintela {
5942eb0308bSJuan Quintela     MigrationState *s = migrate_get_current();
5952eb0308bSJuan Quintela 
5962eb0308bSJuan Quintela     return s->parameters.tls_authz;
5972eb0308bSJuan Quintela }
5982eb0308bSJuan Quintela 
599d5c3e195SJuan Quintela const char *migrate_tls_creds(void)
600d5c3e195SJuan Quintela {
601d5c3e195SJuan Quintela     MigrationState *s = migrate_get_current();
602d5c3e195SJuan Quintela 
603d5c3e195SJuan Quintela     return s->parameters.tls_creds;
604d5c3e195SJuan Quintela }
605d5c3e195SJuan Quintela 
6061f2f366cSJuan Quintela const char *migrate_tls_hostname(void)
6071f2f366cSJuan Quintela {
6081f2f366cSJuan Quintela     MigrationState *s = migrate_get_current();
6091f2f366cSJuan Quintela 
6101f2f366cSJuan Quintela     return s->parameters.tls_hostname;
6111f2f366cSJuan Quintela }
6121f2f366cSJuan Quintela 
6131dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void)
6141dfc4b9eSJuan Quintela {
6158f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6161dfc4b9eSJuan Quintela 
6171dfc4b9eSJuan Quintela     return s->parameters.xbzrle_cache_size;
6181dfc4b9eSJuan Quintela }
6192682c4eeSJuan Quintela 
62087c22901SJuan Quintela /* parameter setters */
62187c22901SJuan Quintela 
62287c22901SJuan Quintela void migrate_set_block_incremental(bool value)
62387c22901SJuan Quintela {
62487c22901SJuan Quintela     MigrationState *s = migrate_get_current();
62587c22901SJuan Quintela 
62687c22901SJuan Quintela     s->parameters.block_incremental = value;
62787c22901SJuan Quintela }
62887c22901SJuan Quintela 
6292682c4eeSJuan Quintela /* parameters helpers */
6302682c4eeSJuan Quintela 
631b1a87956SJuan Quintela void block_cleanup_parameters(void)
632b7b73122SJuan Quintela {
633b1a87956SJuan Quintela     MigrationState *s = migrate_get_current();
634b1a87956SJuan Quintela 
635b7b73122SJuan Quintela     if (s->must_remove_block_options) {
636b7b73122SJuan Quintela         /* setting to false can never fail */
637b7b73122SJuan Quintela         migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort);
638b7b73122SJuan Quintela         migrate_set_block_incremental(false);
639b7b73122SJuan Quintela         s->must_remove_block_options = false;
640b7b73122SJuan Quintela     }
641b7b73122SJuan Quintela }
642b7b73122SJuan Quintela 
6432682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void)
6442682c4eeSJuan Quintela {
6452682c4eeSJuan Quintela     static AnnounceParameters ap;
6462682c4eeSJuan Quintela 
6472682c4eeSJuan Quintela     MigrationState *s = migrate_get_current();
6482682c4eeSJuan Quintela 
6492682c4eeSJuan Quintela     ap.initial = s->parameters.announce_initial;
6502682c4eeSJuan Quintela     ap.max = s->parameters.announce_max;
6512682c4eeSJuan Quintela     ap.rounds = s->parameters.announce_rounds;
6522682c4eeSJuan Quintela     ap.step = s->parameters.announce_step;
6532682c4eeSJuan Quintela 
6542682c4eeSJuan Quintela     return &ap;
6552682c4eeSJuan Quintela }
6569c894df3SJuan Quintela 
6579c894df3SJuan Quintela MigrationParameters *qmp_query_migrate_parameters(Error **errp)
6589c894df3SJuan Quintela {
6599c894df3SJuan Quintela     MigrationParameters *params;
6609c894df3SJuan Quintela     MigrationState *s = migrate_get_current();
6619c894df3SJuan Quintela 
6629c894df3SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
6639c894df3SJuan Quintela     params = g_malloc0(sizeof(*params));
6649c894df3SJuan Quintela     params->has_compress_level = true;
6659c894df3SJuan Quintela     params->compress_level = s->parameters.compress_level;
6669c894df3SJuan Quintela     params->has_compress_threads = true;
6679c894df3SJuan Quintela     params->compress_threads = s->parameters.compress_threads;
6689c894df3SJuan Quintela     params->has_compress_wait_thread = true;
6699c894df3SJuan Quintela     params->compress_wait_thread = s->parameters.compress_wait_thread;
6709c894df3SJuan Quintela     params->has_decompress_threads = true;
6719c894df3SJuan Quintela     params->decompress_threads = s->parameters.decompress_threads;
6729c894df3SJuan Quintela     params->has_throttle_trigger_threshold = true;
6739c894df3SJuan Quintela     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
6749c894df3SJuan Quintela     params->has_cpu_throttle_initial = true;
6759c894df3SJuan Quintela     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
6769c894df3SJuan Quintela     params->has_cpu_throttle_increment = true;
6779c894df3SJuan Quintela     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
6789c894df3SJuan Quintela     params->has_cpu_throttle_tailslow = true;
6799c894df3SJuan Quintela     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
6809c894df3SJuan Quintela     params->tls_creds = g_strdup(s->parameters.tls_creds);
6819c894df3SJuan Quintela     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
6829c894df3SJuan Quintela     params->tls_authz = g_strdup(s->parameters.tls_authz ?
6839c894df3SJuan Quintela                                  s->parameters.tls_authz : "");
6849c894df3SJuan Quintela     params->has_max_bandwidth = true;
6859c894df3SJuan Quintela     params->max_bandwidth = s->parameters.max_bandwidth;
6869c894df3SJuan Quintela     params->has_downtime_limit = true;
6879c894df3SJuan Quintela     params->downtime_limit = s->parameters.downtime_limit;
6889c894df3SJuan Quintela     params->has_x_checkpoint_delay = true;
6899c894df3SJuan Quintela     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
6909c894df3SJuan Quintela     params->has_block_incremental = true;
6919c894df3SJuan Quintela     params->block_incremental = s->parameters.block_incremental;
6929c894df3SJuan Quintela     params->has_multifd_channels = true;
6939c894df3SJuan Quintela     params->multifd_channels = s->parameters.multifd_channels;
6949c894df3SJuan Quintela     params->has_multifd_compression = true;
6959c894df3SJuan Quintela     params->multifd_compression = s->parameters.multifd_compression;
6969c894df3SJuan Quintela     params->has_multifd_zlib_level = true;
6979c894df3SJuan Quintela     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
6989c894df3SJuan Quintela     params->has_multifd_zstd_level = true;
6999c894df3SJuan Quintela     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
7009c894df3SJuan Quintela     params->has_xbzrle_cache_size = true;
7019c894df3SJuan Quintela     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
7029c894df3SJuan Quintela     params->has_max_postcopy_bandwidth = true;
7039c894df3SJuan Quintela     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
7049c894df3SJuan Quintela     params->has_max_cpu_throttle = true;
7059c894df3SJuan Quintela     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
7069c894df3SJuan Quintela     params->has_announce_initial = true;
7079c894df3SJuan Quintela     params->announce_initial = s->parameters.announce_initial;
7089c894df3SJuan Quintela     params->has_announce_max = true;
7099c894df3SJuan Quintela     params->announce_max = s->parameters.announce_max;
7109c894df3SJuan Quintela     params->has_announce_rounds = true;
7119c894df3SJuan Quintela     params->announce_rounds = s->parameters.announce_rounds;
7129c894df3SJuan Quintela     params->has_announce_step = true;
7139c894df3SJuan Quintela     params->announce_step = s->parameters.announce_step;
7149c894df3SJuan Quintela 
7159c894df3SJuan Quintela     if (s->parameters.has_block_bitmap_mapping) {
7169c894df3SJuan Quintela         params->has_block_bitmap_mapping = true;
7179c894df3SJuan Quintela         params->block_bitmap_mapping =
7189c894df3SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
7199c894df3SJuan Quintela                        s->parameters.block_bitmap_mapping);
7209c894df3SJuan Quintela     }
7219c894df3SJuan Quintela 
7229c894df3SJuan Quintela     return params;
7239c894df3SJuan Quintela }
72409d6c965SJuan Quintela 
72561a174e2SJuan Quintela void migrate_params_init(MigrationParameters *params)
72661a174e2SJuan Quintela {
72761a174e2SJuan Quintela     params->tls_hostname = g_strdup("");
72861a174e2SJuan Quintela     params->tls_creds = g_strdup("");
72961a174e2SJuan Quintela 
73061a174e2SJuan Quintela     /* Set has_* up only for parameter checks */
73161a174e2SJuan Quintela     params->has_compress_level = true;
73261a174e2SJuan Quintela     params->has_compress_threads = true;
73361a174e2SJuan Quintela     params->has_compress_wait_thread = true;
73461a174e2SJuan Quintela     params->has_decompress_threads = true;
73561a174e2SJuan Quintela     params->has_throttle_trigger_threshold = true;
73661a174e2SJuan Quintela     params->has_cpu_throttle_initial = true;
73761a174e2SJuan Quintela     params->has_cpu_throttle_increment = true;
73861a174e2SJuan Quintela     params->has_cpu_throttle_tailslow = true;
73961a174e2SJuan Quintela     params->has_max_bandwidth = true;
74061a174e2SJuan Quintela     params->has_downtime_limit = true;
74161a174e2SJuan Quintela     params->has_x_checkpoint_delay = true;
74261a174e2SJuan Quintela     params->has_block_incremental = true;
74361a174e2SJuan Quintela     params->has_multifd_channels = true;
74461a174e2SJuan Quintela     params->has_multifd_compression = true;
74561a174e2SJuan Quintela     params->has_multifd_zlib_level = true;
74661a174e2SJuan Quintela     params->has_multifd_zstd_level = true;
74761a174e2SJuan Quintela     params->has_xbzrle_cache_size = true;
74861a174e2SJuan Quintela     params->has_max_postcopy_bandwidth = true;
74961a174e2SJuan Quintela     params->has_max_cpu_throttle = true;
75061a174e2SJuan Quintela     params->has_announce_initial = true;
75161a174e2SJuan Quintela     params->has_announce_max = true;
75261a174e2SJuan Quintela     params->has_announce_rounds = true;
75361a174e2SJuan Quintela     params->has_announce_step = true;
75461a174e2SJuan Quintela }
75561a174e2SJuan Quintela 
75609d6c965SJuan Quintela /*
75709d6c965SJuan Quintela  * Check whether the parameters are valid. Error will be put into errp
75809d6c965SJuan Quintela  * (if provided). Return true if valid, otherwise false.
75909d6c965SJuan Quintela  */
76009d6c965SJuan Quintela bool migrate_params_check(MigrationParameters *params, Error **errp)
76109d6c965SJuan Quintela {
76209d6c965SJuan Quintela     if (params->has_compress_level &&
76309d6c965SJuan Quintela         (params->compress_level > 9)) {
76409d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",
76509d6c965SJuan Quintela                    "a value between 0 and 9");
76609d6c965SJuan Quintela         return false;
76709d6c965SJuan Quintela     }
76809d6c965SJuan Quintela 
76909d6c965SJuan Quintela     if (params->has_compress_threads && (params->compress_threads < 1)) {
77009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
77109d6c965SJuan Quintela                    "compress_threads",
77209d6c965SJuan Quintela                    "a value between 1 and 255");
77309d6c965SJuan Quintela         return false;
77409d6c965SJuan Quintela     }
77509d6c965SJuan Quintela 
77609d6c965SJuan Quintela     if (params->has_decompress_threads && (params->decompress_threads < 1)) {
77709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
77809d6c965SJuan Quintela                    "decompress_threads",
77909d6c965SJuan Quintela                    "a value between 1 and 255");
78009d6c965SJuan Quintela         return false;
78109d6c965SJuan Quintela     }
78209d6c965SJuan Quintela 
78309d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold &&
78409d6c965SJuan Quintela         (params->throttle_trigger_threshold < 1 ||
78509d6c965SJuan Quintela          params->throttle_trigger_threshold > 100)) {
78609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
78709d6c965SJuan Quintela                    "throttle_trigger_threshold",
78809d6c965SJuan Quintela                    "an integer in the range of 1 to 100");
78909d6c965SJuan Quintela         return false;
79009d6c965SJuan Quintela     }
79109d6c965SJuan Quintela 
79209d6c965SJuan Quintela     if (params->has_cpu_throttle_initial &&
79309d6c965SJuan Quintela         (params->cpu_throttle_initial < 1 ||
79409d6c965SJuan Quintela          params->cpu_throttle_initial > 99)) {
79509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
79609d6c965SJuan Quintela                    "cpu_throttle_initial",
79709d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
79809d6c965SJuan Quintela         return false;
79909d6c965SJuan Quintela     }
80009d6c965SJuan Quintela 
80109d6c965SJuan Quintela     if (params->has_cpu_throttle_increment &&
80209d6c965SJuan Quintela         (params->cpu_throttle_increment < 1 ||
80309d6c965SJuan Quintela          params->cpu_throttle_increment > 99)) {
80409d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
80509d6c965SJuan Quintela                    "cpu_throttle_increment",
80609d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
80709d6c965SJuan Quintela         return false;
80809d6c965SJuan Quintela     }
80909d6c965SJuan Quintela 
81009d6c965SJuan Quintela     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
81109d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
81209d6c965SJuan Quintela                    "max_bandwidth",
81309d6c965SJuan Quintela                    "an integer in the range of 0 to "stringify(SIZE_MAX)
81409d6c965SJuan Quintela                    " bytes/second");
81509d6c965SJuan Quintela         return false;
81609d6c965SJuan Quintela     }
81709d6c965SJuan Quintela 
81809d6c965SJuan Quintela     if (params->has_downtime_limit &&
81909d6c965SJuan Quintela         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
82009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
82109d6c965SJuan Quintela                    "downtime_limit",
82209d6c965SJuan Quintela                    "an integer in the range of 0 to "
82309d6c965SJuan Quintela                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
82409d6c965SJuan Quintela         return false;
82509d6c965SJuan Quintela     }
82609d6c965SJuan Quintela 
82709d6c965SJuan Quintela     /* x_checkpoint_delay is now always positive */
82809d6c965SJuan Quintela 
82909d6c965SJuan Quintela     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
83009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
83109d6c965SJuan Quintela                    "multifd_channels",
83209d6c965SJuan Quintela                    "a value between 1 and 255");
83309d6c965SJuan Quintela         return false;
83409d6c965SJuan Quintela     }
83509d6c965SJuan Quintela 
83609d6c965SJuan Quintela     if (params->has_multifd_zlib_level &&
83709d6c965SJuan Quintela         (params->multifd_zlib_level > 9)) {
83809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
83909d6c965SJuan Quintela                    "a value between 0 and 9");
84009d6c965SJuan Quintela         return false;
84109d6c965SJuan Quintela     }
84209d6c965SJuan Quintela 
84309d6c965SJuan Quintela     if (params->has_multifd_zstd_level &&
84409d6c965SJuan Quintela         (params->multifd_zstd_level > 20)) {
84509d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
84609d6c965SJuan Quintela                    "a value between 0 and 20");
84709d6c965SJuan Quintela         return false;
84809d6c965SJuan Quintela     }
84909d6c965SJuan Quintela 
85009d6c965SJuan Quintela     if (params->has_xbzrle_cache_size &&
85109d6c965SJuan Quintela         (params->xbzrle_cache_size < qemu_target_page_size() ||
85209d6c965SJuan Quintela          !is_power_of_2(params->xbzrle_cache_size))) {
85309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
85409d6c965SJuan Quintela                    "xbzrle_cache_size",
85509d6c965SJuan Quintela                    "a power of two no less than the target page size");
85609d6c965SJuan Quintela         return false;
85709d6c965SJuan Quintela     }
85809d6c965SJuan Quintela 
85909d6c965SJuan Quintela     if (params->has_max_cpu_throttle &&
86009d6c965SJuan Quintela         (params->max_cpu_throttle < params->cpu_throttle_initial ||
86109d6c965SJuan Quintela          params->max_cpu_throttle > 99)) {
86209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
86309d6c965SJuan Quintela                    "max_cpu_throttle",
86409d6c965SJuan Quintela                    "an integer in the range of cpu_throttle_initial to 99");
86509d6c965SJuan Quintela         return false;
86609d6c965SJuan Quintela     }
86709d6c965SJuan Quintela 
86809d6c965SJuan Quintela     if (params->has_announce_initial &&
86909d6c965SJuan Quintela         params->announce_initial > 100000) {
87009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
87109d6c965SJuan Quintela                    "announce_initial",
87209d6c965SJuan Quintela                    "a value between 0 and 100000");
87309d6c965SJuan Quintela         return false;
87409d6c965SJuan Quintela     }
87509d6c965SJuan Quintela     if (params->has_announce_max &&
87609d6c965SJuan Quintela         params->announce_max > 100000) {
87709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
87809d6c965SJuan Quintela                    "announce_max",
87909d6c965SJuan Quintela                    "a value between 0 and 100000");
88009d6c965SJuan Quintela        return false;
88109d6c965SJuan Quintela     }
88209d6c965SJuan Quintela     if (params->has_announce_rounds &&
88309d6c965SJuan Quintela         params->announce_rounds > 1000) {
88409d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
88509d6c965SJuan Quintela                    "announce_rounds",
88609d6c965SJuan Quintela                    "a value between 0 and 1000");
88709d6c965SJuan Quintela        return false;
88809d6c965SJuan Quintela     }
88909d6c965SJuan Quintela     if (params->has_announce_step &&
89009d6c965SJuan Quintela         (params->announce_step < 1 ||
89109d6c965SJuan Quintela         params->announce_step > 10000)) {
89209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
89309d6c965SJuan Quintela                    "announce_step",
89409d6c965SJuan Quintela                    "a value between 0 and 10000");
89509d6c965SJuan Quintela        return false;
89609d6c965SJuan Quintela     }
89709d6c965SJuan Quintela 
89809d6c965SJuan Quintela     if (params->has_block_bitmap_mapping &&
89909d6c965SJuan Quintela         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
90009d6c965SJuan Quintela         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
90109d6c965SJuan Quintela         return false;
90209d6c965SJuan Quintela     }
90309d6c965SJuan Quintela 
90409d6c965SJuan Quintela #ifdef CONFIG_LINUX
90509d6c965SJuan Quintela     if (migrate_zero_copy_send() &&
90609d6c965SJuan Quintela         ((params->has_multifd_compression && params->multifd_compression) ||
90709d6c965SJuan Quintela          (params->tls_creds && *params->tls_creds))) {
90809d6c965SJuan Quintela         error_setg(errp,
90909d6c965SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
91009d6c965SJuan Quintela         return false;
91109d6c965SJuan Quintela     }
91209d6c965SJuan Quintela #endif
91309d6c965SJuan Quintela 
91409d6c965SJuan Quintela     return true;
91509d6c965SJuan Quintela }
91609d6c965SJuan Quintela 
91709d6c965SJuan Quintela static void migrate_params_test_apply(MigrateSetParameters *params,
91809d6c965SJuan Quintela                                       MigrationParameters *dest)
91909d6c965SJuan Quintela {
92009d6c965SJuan Quintela     *dest = migrate_get_current()->parameters;
92109d6c965SJuan Quintela 
92209d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
92309d6c965SJuan Quintela 
92409d6c965SJuan Quintela     if (params->has_compress_level) {
92509d6c965SJuan Quintela         dest->compress_level = params->compress_level;
92609d6c965SJuan Quintela     }
92709d6c965SJuan Quintela 
92809d6c965SJuan Quintela     if (params->has_compress_threads) {
92909d6c965SJuan Quintela         dest->compress_threads = params->compress_threads;
93009d6c965SJuan Quintela     }
93109d6c965SJuan Quintela 
93209d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
93309d6c965SJuan Quintela         dest->compress_wait_thread = params->compress_wait_thread;
93409d6c965SJuan Quintela     }
93509d6c965SJuan Quintela 
93609d6c965SJuan Quintela     if (params->has_decompress_threads) {
93709d6c965SJuan Quintela         dest->decompress_threads = params->decompress_threads;
93809d6c965SJuan Quintela     }
93909d6c965SJuan Quintela 
94009d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
94109d6c965SJuan Quintela         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
94209d6c965SJuan Quintela     }
94309d6c965SJuan Quintela 
94409d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
94509d6c965SJuan Quintela         dest->cpu_throttle_initial = params->cpu_throttle_initial;
94609d6c965SJuan Quintela     }
94709d6c965SJuan Quintela 
94809d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
94909d6c965SJuan Quintela         dest->cpu_throttle_increment = params->cpu_throttle_increment;
95009d6c965SJuan Quintela     }
95109d6c965SJuan Quintela 
95209d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
95309d6c965SJuan Quintela         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
95409d6c965SJuan Quintela     }
95509d6c965SJuan Quintela 
95609d6c965SJuan Quintela     if (params->tls_creds) {
95709d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
95809d6c965SJuan Quintela         dest->tls_creds = params->tls_creds->u.s;
95909d6c965SJuan Quintela     }
96009d6c965SJuan Quintela 
96109d6c965SJuan Quintela     if (params->tls_hostname) {
96209d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
96309d6c965SJuan Quintela         dest->tls_hostname = params->tls_hostname->u.s;
96409d6c965SJuan Quintela     }
96509d6c965SJuan Quintela 
96609d6c965SJuan Quintela     if (params->has_max_bandwidth) {
96709d6c965SJuan Quintela         dest->max_bandwidth = params->max_bandwidth;
96809d6c965SJuan Quintela     }
96909d6c965SJuan Quintela 
97009d6c965SJuan Quintela     if (params->has_downtime_limit) {
97109d6c965SJuan Quintela         dest->downtime_limit = params->downtime_limit;
97209d6c965SJuan Quintela     }
97309d6c965SJuan Quintela 
97409d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
97509d6c965SJuan Quintela         dest->x_checkpoint_delay = params->x_checkpoint_delay;
97609d6c965SJuan Quintela     }
97709d6c965SJuan Quintela 
97809d6c965SJuan Quintela     if (params->has_block_incremental) {
97909d6c965SJuan Quintela         dest->block_incremental = params->block_incremental;
98009d6c965SJuan Quintela     }
98109d6c965SJuan Quintela     if (params->has_multifd_channels) {
98209d6c965SJuan Quintela         dest->multifd_channels = params->multifd_channels;
98309d6c965SJuan Quintela     }
98409d6c965SJuan Quintela     if (params->has_multifd_compression) {
98509d6c965SJuan Quintela         dest->multifd_compression = params->multifd_compression;
98609d6c965SJuan Quintela     }
98709d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
98809d6c965SJuan Quintela         dest->xbzrle_cache_size = params->xbzrle_cache_size;
98909d6c965SJuan Quintela     }
99009d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
99109d6c965SJuan Quintela         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
99209d6c965SJuan Quintela     }
99309d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
99409d6c965SJuan Quintela         dest->max_cpu_throttle = params->max_cpu_throttle;
99509d6c965SJuan Quintela     }
99609d6c965SJuan Quintela     if (params->has_announce_initial) {
99709d6c965SJuan Quintela         dest->announce_initial = params->announce_initial;
99809d6c965SJuan Quintela     }
99909d6c965SJuan Quintela     if (params->has_announce_max) {
100009d6c965SJuan Quintela         dest->announce_max = params->announce_max;
100109d6c965SJuan Quintela     }
100209d6c965SJuan Quintela     if (params->has_announce_rounds) {
100309d6c965SJuan Quintela         dest->announce_rounds = params->announce_rounds;
100409d6c965SJuan Quintela     }
100509d6c965SJuan Quintela     if (params->has_announce_step) {
100609d6c965SJuan Quintela         dest->announce_step = params->announce_step;
100709d6c965SJuan Quintela     }
100809d6c965SJuan Quintela 
100909d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
101009d6c965SJuan Quintela         dest->has_block_bitmap_mapping = true;
101109d6c965SJuan Quintela         dest->block_bitmap_mapping = params->block_bitmap_mapping;
101209d6c965SJuan Quintela     }
101309d6c965SJuan Quintela }
101409d6c965SJuan Quintela 
101509d6c965SJuan Quintela static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
101609d6c965SJuan Quintela {
101709d6c965SJuan Quintela     MigrationState *s = migrate_get_current();
101809d6c965SJuan Quintela 
101909d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
102009d6c965SJuan Quintela 
102109d6c965SJuan Quintela     if (params->has_compress_level) {
102209d6c965SJuan Quintela         s->parameters.compress_level = params->compress_level;
102309d6c965SJuan Quintela     }
102409d6c965SJuan Quintela 
102509d6c965SJuan Quintela     if (params->has_compress_threads) {
102609d6c965SJuan Quintela         s->parameters.compress_threads = params->compress_threads;
102709d6c965SJuan Quintela     }
102809d6c965SJuan Quintela 
102909d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
103009d6c965SJuan Quintela         s->parameters.compress_wait_thread = params->compress_wait_thread;
103109d6c965SJuan Quintela     }
103209d6c965SJuan Quintela 
103309d6c965SJuan Quintela     if (params->has_decompress_threads) {
103409d6c965SJuan Quintela         s->parameters.decompress_threads = params->decompress_threads;
103509d6c965SJuan Quintela     }
103609d6c965SJuan Quintela 
103709d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
103809d6c965SJuan Quintela         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
103909d6c965SJuan Quintela     }
104009d6c965SJuan Quintela 
104109d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
104209d6c965SJuan Quintela         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
104309d6c965SJuan Quintela     }
104409d6c965SJuan Quintela 
104509d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
104609d6c965SJuan Quintela         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
104709d6c965SJuan Quintela     }
104809d6c965SJuan Quintela 
104909d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
105009d6c965SJuan Quintela         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
105109d6c965SJuan Quintela     }
105209d6c965SJuan Quintela 
105309d6c965SJuan Quintela     if (params->tls_creds) {
105409d6c965SJuan Quintela         g_free(s->parameters.tls_creds);
105509d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
105609d6c965SJuan Quintela         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
105709d6c965SJuan Quintela     }
105809d6c965SJuan Quintela 
105909d6c965SJuan Quintela     if (params->tls_hostname) {
106009d6c965SJuan Quintela         g_free(s->parameters.tls_hostname);
106109d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
106209d6c965SJuan Quintela         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
106309d6c965SJuan Quintela     }
106409d6c965SJuan Quintela 
106509d6c965SJuan Quintela     if (params->tls_authz) {
106609d6c965SJuan Quintela         g_free(s->parameters.tls_authz);
106709d6c965SJuan Quintela         assert(params->tls_authz->type == QTYPE_QSTRING);
106809d6c965SJuan Quintela         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
106909d6c965SJuan Quintela     }
107009d6c965SJuan Quintela 
107109d6c965SJuan Quintela     if (params->has_max_bandwidth) {
107209d6c965SJuan Quintela         s->parameters.max_bandwidth = params->max_bandwidth;
107309d6c965SJuan Quintela         if (s->to_dst_file && !migration_in_postcopy()) {
107409d6c965SJuan Quintela             qemu_file_set_rate_limit(s->to_dst_file,
107509d6c965SJuan Quintela                                 s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
107609d6c965SJuan Quintela         }
107709d6c965SJuan Quintela     }
107809d6c965SJuan Quintela 
107909d6c965SJuan Quintela     if (params->has_downtime_limit) {
108009d6c965SJuan Quintela         s->parameters.downtime_limit = params->downtime_limit;
108109d6c965SJuan Quintela     }
108209d6c965SJuan Quintela 
108309d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
108409d6c965SJuan Quintela         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
108509d6c965SJuan Quintela         if (migration_in_colo_state()) {
108609d6c965SJuan Quintela             colo_checkpoint_notify(s);
108709d6c965SJuan Quintela         }
108809d6c965SJuan Quintela     }
108909d6c965SJuan Quintela 
109009d6c965SJuan Quintela     if (params->has_block_incremental) {
109109d6c965SJuan Quintela         s->parameters.block_incremental = params->block_incremental;
109209d6c965SJuan Quintela     }
109309d6c965SJuan Quintela     if (params->has_multifd_channels) {
109409d6c965SJuan Quintela         s->parameters.multifd_channels = params->multifd_channels;
109509d6c965SJuan Quintela     }
109609d6c965SJuan Quintela     if (params->has_multifd_compression) {
109709d6c965SJuan Quintela         s->parameters.multifd_compression = params->multifd_compression;
109809d6c965SJuan Quintela     }
109909d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
110009d6c965SJuan Quintela         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
110109d6c965SJuan Quintela         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
110209d6c965SJuan Quintela     }
110309d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
110409d6c965SJuan Quintela         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
110509d6c965SJuan Quintela         if (s->to_dst_file && migration_in_postcopy()) {
110609d6c965SJuan Quintela             qemu_file_set_rate_limit(s->to_dst_file,
110709d6c965SJuan Quintela                     s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO);
110809d6c965SJuan Quintela         }
110909d6c965SJuan Quintela     }
111009d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
111109d6c965SJuan Quintela         s->parameters.max_cpu_throttle = params->max_cpu_throttle;
111209d6c965SJuan Quintela     }
111309d6c965SJuan Quintela     if (params->has_announce_initial) {
111409d6c965SJuan Quintela         s->parameters.announce_initial = params->announce_initial;
111509d6c965SJuan Quintela     }
111609d6c965SJuan Quintela     if (params->has_announce_max) {
111709d6c965SJuan Quintela         s->parameters.announce_max = params->announce_max;
111809d6c965SJuan Quintela     }
111909d6c965SJuan Quintela     if (params->has_announce_rounds) {
112009d6c965SJuan Quintela         s->parameters.announce_rounds = params->announce_rounds;
112109d6c965SJuan Quintela     }
112209d6c965SJuan Quintela     if (params->has_announce_step) {
112309d6c965SJuan Quintela         s->parameters.announce_step = params->announce_step;
112409d6c965SJuan Quintela     }
112509d6c965SJuan Quintela 
112609d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
112709d6c965SJuan Quintela         qapi_free_BitmapMigrationNodeAliasList(
112809d6c965SJuan Quintela             s->parameters.block_bitmap_mapping);
112909d6c965SJuan Quintela 
113009d6c965SJuan Quintela         s->parameters.has_block_bitmap_mapping = true;
113109d6c965SJuan Quintela         s->parameters.block_bitmap_mapping =
113209d6c965SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
113309d6c965SJuan Quintela                        params->block_bitmap_mapping);
113409d6c965SJuan Quintela     }
113509d6c965SJuan Quintela }
113609d6c965SJuan Quintela 
113709d6c965SJuan Quintela void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
113809d6c965SJuan Quintela {
113909d6c965SJuan Quintela     MigrationParameters tmp;
114009d6c965SJuan Quintela 
114109d6c965SJuan Quintela     /* TODO Rewrite "" to null instead */
114209d6c965SJuan Quintela     if (params->tls_creds
114309d6c965SJuan Quintela         && params->tls_creds->type == QTYPE_QNULL) {
114409d6c965SJuan Quintela         qobject_unref(params->tls_creds->u.n);
114509d6c965SJuan Quintela         params->tls_creds->type = QTYPE_QSTRING;
114609d6c965SJuan Quintela         params->tls_creds->u.s = strdup("");
114709d6c965SJuan Quintela     }
114809d6c965SJuan Quintela     /* TODO Rewrite "" to null instead */
114909d6c965SJuan Quintela     if (params->tls_hostname
115009d6c965SJuan Quintela         && params->tls_hostname->type == QTYPE_QNULL) {
115109d6c965SJuan Quintela         qobject_unref(params->tls_hostname->u.n);
115209d6c965SJuan Quintela         params->tls_hostname->type = QTYPE_QSTRING;
115309d6c965SJuan Quintela         params->tls_hostname->u.s = strdup("");
115409d6c965SJuan Quintela     }
115509d6c965SJuan Quintela 
115609d6c965SJuan Quintela     migrate_params_test_apply(params, &tmp);
115709d6c965SJuan Quintela 
115809d6c965SJuan Quintela     if (!migrate_params_check(&tmp, errp)) {
115909d6c965SJuan Quintela         /* Invalid parameter */
116009d6c965SJuan Quintela         return;
116109d6c965SJuan Quintela     }
116209d6c965SJuan Quintela 
116309d6c965SJuan Quintela     migrate_params_apply(params, errp);
116409d6c965SJuan Quintela }
1165