xref: /openbmc/qemu/migration/options.c (revision 2eb0308bbd5e20bb20229c790dc2c7f1ae8e3ba9)
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 
4586f8be708SJuan Quintela bool migrate_block_incremental(void)
4596f8be708SJuan Quintela {
4608f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4616f8be708SJuan Quintela 
4626f8be708SJuan Quintela     return s->parameters.block_incremental;
4636f8be708SJuan Quintela }
4646f8be708SJuan Quintela 
465f94a858fSJuan Quintela uint32_t migrate_checkpoint_delay(void)
466f94a858fSJuan Quintela {
4678f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
468f94a858fSJuan Quintela 
469f94a858fSJuan Quintela     return s->parameters.x_checkpoint_delay;
470f94a858fSJuan Quintela }
471f94a858fSJuan Quintela 
4721dfc4b9eSJuan Quintela int migrate_compress_level(void)
4731dfc4b9eSJuan Quintela {
4748f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4751dfc4b9eSJuan Quintela 
4761dfc4b9eSJuan Quintela     return s->parameters.compress_level;
4771dfc4b9eSJuan Quintela }
4781dfc4b9eSJuan Quintela 
4791dfc4b9eSJuan Quintela int migrate_compress_threads(void)
4801dfc4b9eSJuan Quintela {
4818f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4821dfc4b9eSJuan Quintela 
4831dfc4b9eSJuan Quintela     return s->parameters.compress_threads;
4841dfc4b9eSJuan Quintela }
4851dfc4b9eSJuan Quintela 
4861dfc4b9eSJuan Quintela int migrate_compress_wait_thread(void)
4871dfc4b9eSJuan Quintela {
4888f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4891dfc4b9eSJuan Quintela 
4901dfc4b9eSJuan Quintela     return s->parameters.compress_wait_thread;
4911dfc4b9eSJuan Quintela }
4921dfc4b9eSJuan Quintela 
4939605c2acSJuan Quintela uint8_t migrate_cpu_throttle_increment(void)
4949605c2acSJuan Quintela {
4958f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
4969605c2acSJuan Quintela 
4979605c2acSJuan Quintela     return s->parameters.cpu_throttle_increment;
4989605c2acSJuan Quintela }
4999605c2acSJuan Quintela 
5002a8ec380SJuan Quintela uint8_t migrate_cpu_throttle_initial(void)
5012a8ec380SJuan Quintela {
5028f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5032a8ec380SJuan Quintela 
5042a8ec380SJuan Quintela     return s->parameters.cpu_throttle_initial;
5052a8ec380SJuan Quintela }
5062a8ec380SJuan Quintela 
507873f674cSJuan Quintela bool migrate_cpu_throttle_tailslow(void)
508873f674cSJuan Quintela {
5098f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
510873f674cSJuan Quintela 
511873f674cSJuan Quintela     return s->parameters.cpu_throttle_tailslow;
512873f674cSJuan Quintela }
513873f674cSJuan Quintela 
5141dfc4b9eSJuan Quintela int migrate_decompress_threads(void)
5151dfc4b9eSJuan Quintela {
5168f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5171dfc4b9eSJuan Quintela 
5181dfc4b9eSJuan Quintela     return s->parameters.decompress_threads;
5191dfc4b9eSJuan Quintela }
5201dfc4b9eSJuan Quintela 
521f5da8ba4SJuan Quintela uint64_t migrate_downtime_limit(void)
522f5da8ba4SJuan Quintela {
523f5da8ba4SJuan Quintela     MigrationState *s = migrate_get_current();
524f5da8ba4SJuan Quintela 
525f5da8ba4SJuan Quintela     return s->parameters.downtime_limit;
526f5da8ba4SJuan Quintela }
527f5da8ba4SJuan Quintela 
52824155bd0SJuan Quintela uint8_t migrate_max_cpu_throttle(void)
52924155bd0SJuan Quintela {
5308f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
53124155bd0SJuan Quintela 
53224155bd0SJuan Quintela     return s->parameters.max_cpu_throttle;
53324155bd0SJuan Quintela }
53424155bd0SJuan Quintela 
5359c894df3SJuan Quintela uint64_t migrate_max_bandwidth(void)
5369c894df3SJuan Quintela {
5378f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5389c894df3SJuan Quintela 
5399c894df3SJuan Quintela     return s->parameters.max_bandwidth;
5409c894df3SJuan Quintela }
5419c894df3SJuan Quintela 
5421dfc4b9eSJuan Quintela int64_t migrate_max_postcopy_bandwidth(void)
5431dfc4b9eSJuan Quintela {
5448f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5451dfc4b9eSJuan Quintela 
5461dfc4b9eSJuan Quintela     return s->parameters.max_postcopy_bandwidth;
5471dfc4b9eSJuan Quintela }
5481dfc4b9eSJuan Quintela 
5491dfc4b9eSJuan Quintela int migrate_multifd_channels(void)
5501dfc4b9eSJuan Quintela {
5518f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5521dfc4b9eSJuan Quintela 
5531dfc4b9eSJuan Quintela     return s->parameters.multifd_channels;
5541dfc4b9eSJuan Quintela }
5551dfc4b9eSJuan Quintela 
5561dfc4b9eSJuan Quintela MultiFDCompression migrate_multifd_compression(void)
5571dfc4b9eSJuan Quintela {
5588f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5591dfc4b9eSJuan Quintela 
5601dfc4b9eSJuan Quintela     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
5611dfc4b9eSJuan Quintela     return s->parameters.multifd_compression;
5621dfc4b9eSJuan Quintela }
5631dfc4b9eSJuan Quintela 
5641dfc4b9eSJuan Quintela int migrate_multifd_zlib_level(void)
5651dfc4b9eSJuan Quintela {
5668f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5671dfc4b9eSJuan Quintela 
5681dfc4b9eSJuan Quintela     return s->parameters.multifd_zlib_level;
5691dfc4b9eSJuan Quintela }
5701dfc4b9eSJuan Quintela 
5711dfc4b9eSJuan Quintela int migrate_multifd_zstd_level(void)
5721dfc4b9eSJuan Quintela {
5738f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5741dfc4b9eSJuan Quintela 
5751dfc4b9eSJuan Quintela     return s->parameters.multifd_zstd_level;
5761dfc4b9eSJuan Quintela }
5771dfc4b9eSJuan Quintela 
5786499efdbSJuan Quintela uint8_t migrate_throttle_trigger_threshold(void)
5796499efdbSJuan Quintela {
5808f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
5816499efdbSJuan Quintela 
5826499efdbSJuan Quintela     return s->parameters.throttle_trigger_threshold;
5836499efdbSJuan Quintela }
5846499efdbSJuan Quintela 
585*2eb0308bSJuan Quintela const char *migrate_tls_authz(void)
586*2eb0308bSJuan Quintela {
587*2eb0308bSJuan Quintela     MigrationState *s = migrate_get_current();
588*2eb0308bSJuan Quintela 
589*2eb0308bSJuan Quintela     return s->parameters.tls_authz;
590*2eb0308bSJuan Quintela }
591*2eb0308bSJuan Quintela 
592d5c3e195SJuan Quintela const char *migrate_tls_creds(void)
593d5c3e195SJuan Quintela {
594d5c3e195SJuan Quintela     MigrationState *s = migrate_get_current();
595d5c3e195SJuan Quintela 
596d5c3e195SJuan Quintela     return s->parameters.tls_creds;
597d5c3e195SJuan Quintela }
598d5c3e195SJuan Quintela 
5991dfc4b9eSJuan Quintela uint64_t migrate_xbzrle_cache_size(void)
6001dfc4b9eSJuan Quintela {
6018f9c5327SJuan Quintela     MigrationState *s = migrate_get_current();
6021dfc4b9eSJuan Quintela 
6031dfc4b9eSJuan Quintela     return s->parameters.xbzrle_cache_size;
6041dfc4b9eSJuan Quintela }
6052682c4eeSJuan Quintela 
60687c22901SJuan Quintela /* parameter setters */
60787c22901SJuan Quintela 
60887c22901SJuan Quintela void migrate_set_block_incremental(bool value)
60987c22901SJuan Quintela {
61087c22901SJuan Quintela     MigrationState *s = migrate_get_current();
61187c22901SJuan Quintela 
61287c22901SJuan Quintela     s->parameters.block_incremental = value;
61387c22901SJuan Quintela }
61487c22901SJuan Quintela 
6152682c4eeSJuan Quintela /* parameters helpers */
6162682c4eeSJuan Quintela 
617b1a87956SJuan Quintela void block_cleanup_parameters(void)
618b7b73122SJuan Quintela {
619b1a87956SJuan Quintela     MigrationState *s = migrate_get_current();
620b1a87956SJuan Quintela 
621b7b73122SJuan Quintela     if (s->must_remove_block_options) {
622b7b73122SJuan Quintela         /* setting to false can never fail */
623b7b73122SJuan Quintela         migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort);
624b7b73122SJuan Quintela         migrate_set_block_incremental(false);
625b7b73122SJuan Quintela         s->must_remove_block_options = false;
626b7b73122SJuan Quintela     }
627b7b73122SJuan Quintela }
628b7b73122SJuan Quintela 
6292682c4eeSJuan Quintela AnnounceParameters *migrate_announce_params(void)
6302682c4eeSJuan Quintela {
6312682c4eeSJuan Quintela     static AnnounceParameters ap;
6322682c4eeSJuan Quintela 
6332682c4eeSJuan Quintela     MigrationState *s = migrate_get_current();
6342682c4eeSJuan Quintela 
6352682c4eeSJuan Quintela     ap.initial = s->parameters.announce_initial;
6362682c4eeSJuan Quintela     ap.max = s->parameters.announce_max;
6372682c4eeSJuan Quintela     ap.rounds = s->parameters.announce_rounds;
6382682c4eeSJuan Quintela     ap.step = s->parameters.announce_step;
6392682c4eeSJuan Quintela 
6402682c4eeSJuan Quintela     return &ap;
6412682c4eeSJuan Quintela }
6429c894df3SJuan Quintela 
6439c894df3SJuan Quintela MigrationParameters *qmp_query_migrate_parameters(Error **errp)
6449c894df3SJuan Quintela {
6459c894df3SJuan Quintela     MigrationParameters *params;
6469c894df3SJuan Quintela     MigrationState *s = migrate_get_current();
6479c894df3SJuan Quintela 
6489c894df3SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
6499c894df3SJuan Quintela     params = g_malloc0(sizeof(*params));
6509c894df3SJuan Quintela     params->has_compress_level = true;
6519c894df3SJuan Quintela     params->compress_level = s->parameters.compress_level;
6529c894df3SJuan Quintela     params->has_compress_threads = true;
6539c894df3SJuan Quintela     params->compress_threads = s->parameters.compress_threads;
6549c894df3SJuan Quintela     params->has_compress_wait_thread = true;
6559c894df3SJuan Quintela     params->compress_wait_thread = s->parameters.compress_wait_thread;
6569c894df3SJuan Quintela     params->has_decompress_threads = true;
6579c894df3SJuan Quintela     params->decompress_threads = s->parameters.decompress_threads;
6589c894df3SJuan Quintela     params->has_throttle_trigger_threshold = true;
6599c894df3SJuan Quintela     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
6609c894df3SJuan Quintela     params->has_cpu_throttle_initial = true;
6619c894df3SJuan Quintela     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
6629c894df3SJuan Quintela     params->has_cpu_throttle_increment = true;
6639c894df3SJuan Quintela     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
6649c894df3SJuan Quintela     params->has_cpu_throttle_tailslow = true;
6659c894df3SJuan Quintela     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
6669c894df3SJuan Quintela     params->tls_creds = g_strdup(s->parameters.tls_creds);
6679c894df3SJuan Quintela     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
6689c894df3SJuan Quintela     params->tls_authz = g_strdup(s->parameters.tls_authz ?
6699c894df3SJuan Quintela                                  s->parameters.tls_authz : "");
6709c894df3SJuan Quintela     params->has_max_bandwidth = true;
6719c894df3SJuan Quintela     params->max_bandwidth = s->parameters.max_bandwidth;
6729c894df3SJuan Quintela     params->has_downtime_limit = true;
6739c894df3SJuan Quintela     params->downtime_limit = s->parameters.downtime_limit;
6749c894df3SJuan Quintela     params->has_x_checkpoint_delay = true;
6759c894df3SJuan Quintela     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
6769c894df3SJuan Quintela     params->has_block_incremental = true;
6779c894df3SJuan Quintela     params->block_incremental = s->parameters.block_incremental;
6789c894df3SJuan Quintela     params->has_multifd_channels = true;
6799c894df3SJuan Quintela     params->multifd_channels = s->parameters.multifd_channels;
6809c894df3SJuan Quintela     params->has_multifd_compression = true;
6819c894df3SJuan Quintela     params->multifd_compression = s->parameters.multifd_compression;
6829c894df3SJuan Quintela     params->has_multifd_zlib_level = true;
6839c894df3SJuan Quintela     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
6849c894df3SJuan Quintela     params->has_multifd_zstd_level = true;
6859c894df3SJuan Quintela     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
6869c894df3SJuan Quintela     params->has_xbzrle_cache_size = true;
6879c894df3SJuan Quintela     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
6889c894df3SJuan Quintela     params->has_max_postcopy_bandwidth = true;
6899c894df3SJuan Quintela     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
6909c894df3SJuan Quintela     params->has_max_cpu_throttle = true;
6919c894df3SJuan Quintela     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
6929c894df3SJuan Quintela     params->has_announce_initial = true;
6939c894df3SJuan Quintela     params->announce_initial = s->parameters.announce_initial;
6949c894df3SJuan Quintela     params->has_announce_max = true;
6959c894df3SJuan Quintela     params->announce_max = s->parameters.announce_max;
6969c894df3SJuan Quintela     params->has_announce_rounds = true;
6979c894df3SJuan Quintela     params->announce_rounds = s->parameters.announce_rounds;
6989c894df3SJuan Quintela     params->has_announce_step = true;
6999c894df3SJuan Quintela     params->announce_step = s->parameters.announce_step;
7009c894df3SJuan Quintela 
7019c894df3SJuan Quintela     if (s->parameters.has_block_bitmap_mapping) {
7029c894df3SJuan Quintela         params->has_block_bitmap_mapping = true;
7039c894df3SJuan Quintela         params->block_bitmap_mapping =
7049c894df3SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
7059c894df3SJuan Quintela                        s->parameters.block_bitmap_mapping);
7069c894df3SJuan Quintela     }
7079c894df3SJuan Quintela 
7089c894df3SJuan Quintela     return params;
7099c894df3SJuan Quintela }
71009d6c965SJuan Quintela 
71161a174e2SJuan Quintela void migrate_params_init(MigrationParameters *params)
71261a174e2SJuan Quintela {
71361a174e2SJuan Quintela     params->tls_hostname = g_strdup("");
71461a174e2SJuan Quintela     params->tls_creds = g_strdup("");
71561a174e2SJuan Quintela 
71661a174e2SJuan Quintela     /* Set has_* up only for parameter checks */
71761a174e2SJuan Quintela     params->has_compress_level = true;
71861a174e2SJuan Quintela     params->has_compress_threads = true;
71961a174e2SJuan Quintela     params->has_compress_wait_thread = true;
72061a174e2SJuan Quintela     params->has_decompress_threads = true;
72161a174e2SJuan Quintela     params->has_throttle_trigger_threshold = true;
72261a174e2SJuan Quintela     params->has_cpu_throttle_initial = true;
72361a174e2SJuan Quintela     params->has_cpu_throttle_increment = true;
72461a174e2SJuan Quintela     params->has_cpu_throttle_tailslow = true;
72561a174e2SJuan Quintela     params->has_max_bandwidth = true;
72661a174e2SJuan Quintela     params->has_downtime_limit = true;
72761a174e2SJuan Quintela     params->has_x_checkpoint_delay = true;
72861a174e2SJuan Quintela     params->has_block_incremental = true;
72961a174e2SJuan Quintela     params->has_multifd_channels = true;
73061a174e2SJuan Quintela     params->has_multifd_compression = true;
73161a174e2SJuan Quintela     params->has_multifd_zlib_level = true;
73261a174e2SJuan Quintela     params->has_multifd_zstd_level = true;
73361a174e2SJuan Quintela     params->has_xbzrle_cache_size = true;
73461a174e2SJuan Quintela     params->has_max_postcopy_bandwidth = true;
73561a174e2SJuan Quintela     params->has_max_cpu_throttle = true;
73661a174e2SJuan Quintela     params->has_announce_initial = true;
73761a174e2SJuan Quintela     params->has_announce_max = true;
73861a174e2SJuan Quintela     params->has_announce_rounds = true;
73961a174e2SJuan Quintela     params->has_announce_step = true;
74061a174e2SJuan Quintela }
74161a174e2SJuan Quintela 
74209d6c965SJuan Quintela /*
74309d6c965SJuan Quintela  * Check whether the parameters are valid. Error will be put into errp
74409d6c965SJuan Quintela  * (if provided). Return true if valid, otherwise false.
74509d6c965SJuan Quintela  */
74609d6c965SJuan Quintela bool migrate_params_check(MigrationParameters *params, Error **errp)
74709d6c965SJuan Quintela {
74809d6c965SJuan Quintela     if (params->has_compress_level &&
74909d6c965SJuan Quintela         (params->compress_level > 9)) {
75009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",
75109d6c965SJuan Quintela                    "a value between 0 and 9");
75209d6c965SJuan Quintela         return false;
75309d6c965SJuan Quintela     }
75409d6c965SJuan Quintela 
75509d6c965SJuan Quintela     if (params->has_compress_threads && (params->compress_threads < 1)) {
75609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
75709d6c965SJuan Quintela                    "compress_threads",
75809d6c965SJuan Quintela                    "a value between 1 and 255");
75909d6c965SJuan Quintela         return false;
76009d6c965SJuan Quintela     }
76109d6c965SJuan Quintela 
76209d6c965SJuan Quintela     if (params->has_decompress_threads && (params->decompress_threads < 1)) {
76309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
76409d6c965SJuan Quintela                    "decompress_threads",
76509d6c965SJuan Quintela                    "a value between 1 and 255");
76609d6c965SJuan Quintela         return false;
76709d6c965SJuan Quintela     }
76809d6c965SJuan Quintela 
76909d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold &&
77009d6c965SJuan Quintela         (params->throttle_trigger_threshold < 1 ||
77109d6c965SJuan Quintela          params->throttle_trigger_threshold > 100)) {
77209d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
77309d6c965SJuan Quintela                    "throttle_trigger_threshold",
77409d6c965SJuan Quintela                    "an integer in the range of 1 to 100");
77509d6c965SJuan Quintela         return false;
77609d6c965SJuan Quintela     }
77709d6c965SJuan Quintela 
77809d6c965SJuan Quintela     if (params->has_cpu_throttle_initial &&
77909d6c965SJuan Quintela         (params->cpu_throttle_initial < 1 ||
78009d6c965SJuan Quintela          params->cpu_throttle_initial > 99)) {
78109d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
78209d6c965SJuan Quintela                    "cpu_throttle_initial",
78309d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
78409d6c965SJuan Quintela         return false;
78509d6c965SJuan Quintela     }
78609d6c965SJuan Quintela 
78709d6c965SJuan Quintela     if (params->has_cpu_throttle_increment &&
78809d6c965SJuan Quintela         (params->cpu_throttle_increment < 1 ||
78909d6c965SJuan Quintela          params->cpu_throttle_increment > 99)) {
79009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
79109d6c965SJuan Quintela                    "cpu_throttle_increment",
79209d6c965SJuan Quintela                    "an integer in the range of 1 to 99");
79309d6c965SJuan Quintela         return false;
79409d6c965SJuan Quintela     }
79509d6c965SJuan Quintela 
79609d6c965SJuan Quintela     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
79709d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
79809d6c965SJuan Quintela                    "max_bandwidth",
79909d6c965SJuan Quintela                    "an integer in the range of 0 to "stringify(SIZE_MAX)
80009d6c965SJuan Quintela                    " bytes/second");
80109d6c965SJuan Quintela         return false;
80209d6c965SJuan Quintela     }
80309d6c965SJuan Quintela 
80409d6c965SJuan Quintela     if (params->has_downtime_limit &&
80509d6c965SJuan Quintela         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
80609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
80709d6c965SJuan Quintela                    "downtime_limit",
80809d6c965SJuan Quintela                    "an integer in the range of 0 to "
80909d6c965SJuan Quintela                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
81009d6c965SJuan Quintela         return false;
81109d6c965SJuan Quintela     }
81209d6c965SJuan Quintela 
81309d6c965SJuan Quintela     /* x_checkpoint_delay is now always positive */
81409d6c965SJuan Quintela 
81509d6c965SJuan Quintela     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
81609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
81709d6c965SJuan Quintela                    "multifd_channels",
81809d6c965SJuan Quintela                    "a value between 1 and 255");
81909d6c965SJuan Quintela         return false;
82009d6c965SJuan Quintela     }
82109d6c965SJuan Quintela 
82209d6c965SJuan Quintela     if (params->has_multifd_zlib_level &&
82309d6c965SJuan Quintela         (params->multifd_zlib_level > 9)) {
82409d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
82509d6c965SJuan Quintela                    "a value between 0 and 9");
82609d6c965SJuan Quintela         return false;
82709d6c965SJuan Quintela     }
82809d6c965SJuan Quintela 
82909d6c965SJuan Quintela     if (params->has_multifd_zstd_level &&
83009d6c965SJuan Quintela         (params->multifd_zstd_level > 20)) {
83109d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
83209d6c965SJuan Quintela                    "a value between 0 and 20");
83309d6c965SJuan Quintela         return false;
83409d6c965SJuan Quintela     }
83509d6c965SJuan Quintela 
83609d6c965SJuan Quintela     if (params->has_xbzrle_cache_size &&
83709d6c965SJuan Quintela         (params->xbzrle_cache_size < qemu_target_page_size() ||
83809d6c965SJuan Quintela          !is_power_of_2(params->xbzrle_cache_size))) {
83909d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
84009d6c965SJuan Quintela                    "xbzrle_cache_size",
84109d6c965SJuan Quintela                    "a power of two no less than the target page size");
84209d6c965SJuan Quintela         return false;
84309d6c965SJuan Quintela     }
84409d6c965SJuan Quintela 
84509d6c965SJuan Quintela     if (params->has_max_cpu_throttle &&
84609d6c965SJuan Quintela         (params->max_cpu_throttle < params->cpu_throttle_initial ||
84709d6c965SJuan Quintela          params->max_cpu_throttle > 99)) {
84809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
84909d6c965SJuan Quintela                    "max_cpu_throttle",
85009d6c965SJuan Quintela                    "an integer in the range of cpu_throttle_initial to 99");
85109d6c965SJuan Quintela         return false;
85209d6c965SJuan Quintela     }
85309d6c965SJuan Quintela 
85409d6c965SJuan Quintela     if (params->has_announce_initial &&
85509d6c965SJuan Quintela         params->announce_initial > 100000) {
85609d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
85709d6c965SJuan Quintela                    "announce_initial",
85809d6c965SJuan Quintela                    "a value between 0 and 100000");
85909d6c965SJuan Quintela         return false;
86009d6c965SJuan Quintela     }
86109d6c965SJuan Quintela     if (params->has_announce_max &&
86209d6c965SJuan Quintela         params->announce_max > 100000) {
86309d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
86409d6c965SJuan Quintela                    "announce_max",
86509d6c965SJuan Quintela                    "a value between 0 and 100000");
86609d6c965SJuan Quintela        return false;
86709d6c965SJuan Quintela     }
86809d6c965SJuan Quintela     if (params->has_announce_rounds &&
86909d6c965SJuan Quintela         params->announce_rounds > 1000) {
87009d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
87109d6c965SJuan Quintela                    "announce_rounds",
87209d6c965SJuan Quintela                    "a value between 0 and 1000");
87309d6c965SJuan Quintela        return false;
87409d6c965SJuan Quintela     }
87509d6c965SJuan Quintela     if (params->has_announce_step &&
87609d6c965SJuan Quintela         (params->announce_step < 1 ||
87709d6c965SJuan Quintela         params->announce_step > 10000)) {
87809d6c965SJuan Quintela         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
87909d6c965SJuan Quintela                    "announce_step",
88009d6c965SJuan Quintela                    "a value between 0 and 10000");
88109d6c965SJuan Quintela        return false;
88209d6c965SJuan Quintela     }
88309d6c965SJuan Quintela 
88409d6c965SJuan Quintela     if (params->has_block_bitmap_mapping &&
88509d6c965SJuan Quintela         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
88609d6c965SJuan Quintela         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
88709d6c965SJuan Quintela         return false;
88809d6c965SJuan Quintela     }
88909d6c965SJuan Quintela 
89009d6c965SJuan Quintela #ifdef CONFIG_LINUX
89109d6c965SJuan Quintela     if (migrate_zero_copy_send() &&
89209d6c965SJuan Quintela         ((params->has_multifd_compression && params->multifd_compression) ||
89309d6c965SJuan Quintela          (params->tls_creds && *params->tls_creds))) {
89409d6c965SJuan Quintela         error_setg(errp,
89509d6c965SJuan Quintela                    "Zero copy only available for non-compressed non-TLS multifd migration");
89609d6c965SJuan Quintela         return false;
89709d6c965SJuan Quintela     }
89809d6c965SJuan Quintela #endif
89909d6c965SJuan Quintela 
90009d6c965SJuan Quintela     return true;
90109d6c965SJuan Quintela }
90209d6c965SJuan Quintela 
90309d6c965SJuan Quintela static void migrate_params_test_apply(MigrateSetParameters *params,
90409d6c965SJuan Quintela                                       MigrationParameters *dest)
90509d6c965SJuan Quintela {
90609d6c965SJuan Quintela     *dest = migrate_get_current()->parameters;
90709d6c965SJuan Quintela 
90809d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
90909d6c965SJuan Quintela 
91009d6c965SJuan Quintela     if (params->has_compress_level) {
91109d6c965SJuan Quintela         dest->compress_level = params->compress_level;
91209d6c965SJuan Quintela     }
91309d6c965SJuan Quintela 
91409d6c965SJuan Quintela     if (params->has_compress_threads) {
91509d6c965SJuan Quintela         dest->compress_threads = params->compress_threads;
91609d6c965SJuan Quintela     }
91709d6c965SJuan Quintela 
91809d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
91909d6c965SJuan Quintela         dest->compress_wait_thread = params->compress_wait_thread;
92009d6c965SJuan Quintela     }
92109d6c965SJuan Quintela 
92209d6c965SJuan Quintela     if (params->has_decompress_threads) {
92309d6c965SJuan Quintela         dest->decompress_threads = params->decompress_threads;
92409d6c965SJuan Quintela     }
92509d6c965SJuan Quintela 
92609d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
92709d6c965SJuan Quintela         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
92809d6c965SJuan Quintela     }
92909d6c965SJuan Quintela 
93009d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
93109d6c965SJuan Quintela         dest->cpu_throttle_initial = params->cpu_throttle_initial;
93209d6c965SJuan Quintela     }
93309d6c965SJuan Quintela 
93409d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
93509d6c965SJuan Quintela         dest->cpu_throttle_increment = params->cpu_throttle_increment;
93609d6c965SJuan Quintela     }
93709d6c965SJuan Quintela 
93809d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
93909d6c965SJuan Quintela         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
94009d6c965SJuan Quintela     }
94109d6c965SJuan Quintela 
94209d6c965SJuan Quintela     if (params->tls_creds) {
94309d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
94409d6c965SJuan Quintela         dest->tls_creds = params->tls_creds->u.s;
94509d6c965SJuan Quintela     }
94609d6c965SJuan Quintela 
94709d6c965SJuan Quintela     if (params->tls_hostname) {
94809d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
94909d6c965SJuan Quintela         dest->tls_hostname = params->tls_hostname->u.s;
95009d6c965SJuan Quintela     }
95109d6c965SJuan Quintela 
95209d6c965SJuan Quintela     if (params->has_max_bandwidth) {
95309d6c965SJuan Quintela         dest->max_bandwidth = params->max_bandwidth;
95409d6c965SJuan Quintela     }
95509d6c965SJuan Quintela 
95609d6c965SJuan Quintela     if (params->has_downtime_limit) {
95709d6c965SJuan Quintela         dest->downtime_limit = params->downtime_limit;
95809d6c965SJuan Quintela     }
95909d6c965SJuan Quintela 
96009d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
96109d6c965SJuan Quintela         dest->x_checkpoint_delay = params->x_checkpoint_delay;
96209d6c965SJuan Quintela     }
96309d6c965SJuan Quintela 
96409d6c965SJuan Quintela     if (params->has_block_incremental) {
96509d6c965SJuan Quintela         dest->block_incremental = params->block_incremental;
96609d6c965SJuan Quintela     }
96709d6c965SJuan Quintela     if (params->has_multifd_channels) {
96809d6c965SJuan Quintela         dest->multifd_channels = params->multifd_channels;
96909d6c965SJuan Quintela     }
97009d6c965SJuan Quintela     if (params->has_multifd_compression) {
97109d6c965SJuan Quintela         dest->multifd_compression = params->multifd_compression;
97209d6c965SJuan Quintela     }
97309d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
97409d6c965SJuan Quintela         dest->xbzrle_cache_size = params->xbzrle_cache_size;
97509d6c965SJuan Quintela     }
97609d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
97709d6c965SJuan Quintela         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
97809d6c965SJuan Quintela     }
97909d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
98009d6c965SJuan Quintela         dest->max_cpu_throttle = params->max_cpu_throttle;
98109d6c965SJuan Quintela     }
98209d6c965SJuan Quintela     if (params->has_announce_initial) {
98309d6c965SJuan Quintela         dest->announce_initial = params->announce_initial;
98409d6c965SJuan Quintela     }
98509d6c965SJuan Quintela     if (params->has_announce_max) {
98609d6c965SJuan Quintela         dest->announce_max = params->announce_max;
98709d6c965SJuan Quintela     }
98809d6c965SJuan Quintela     if (params->has_announce_rounds) {
98909d6c965SJuan Quintela         dest->announce_rounds = params->announce_rounds;
99009d6c965SJuan Quintela     }
99109d6c965SJuan Quintela     if (params->has_announce_step) {
99209d6c965SJuan Quintela         dest->announce_step = params->announce_step;
99309d6c965SJuan Quintela     }
99409d6c965SJuan Quintela 
99509d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
99609d6c965SJuan Quintela         dest->has_block_bitmap_mapping = true;
99709d6c965SJuan Quintela         dest->block_bitmap_mapping = params->block_bitmap_mapping;
99809d6c965SJuan Quintela     }
99909d6c965SJuan Quintela }
100009d6c965SJuan Quintela 
100109d6c965SJuan Quintela static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
100209d6c965SJuan Quintela {
100309d6c965SJuan Quintela     MigrationState *s = migrate_get_current();
100409d6c965SJuan Quintela 
100509d6c965SJuan Quintela     /* TODO use QAPI_CLONE() instead of duplicating it inline */
100609d6c965SJuan Quintela 
100709d6c965SJuan Quintela     if (params->has_compress_level) {
100809d6c965SJuan Quintela         s->parameters.compress_level = params->compress_level;
100909d6c965SJuan Quintela     }
101009d6c965SJuan Quintela 
101109d6c965SJuan Quintela     if (params->has_compress_threads) {
101209d6c965SJuan Quintela         s->parameters.compress_threads = params->compress_threads;
101309d6c965SJuan Quintela     }
101409d6c965SJuan Quintela 
101509d6c965SJuan Quintela     if (params->has_compress_wait_thread) {
101609d6c965SJuan Quintela         s->parameters.compress_wait_thread = params->compress_wait_thread;
101709d6c965SJuan Quintela     }
101809d6c965SJuan Quintela 
101909d6c965SJuan Quintela     if (params->has_decompress_threads) {
102009d6c965SJuan Quintela         s->parameters.decompress_threads = params->decompress_threads;
102109d6c965SJuan Quintela     }
102209d6c965SJuan Quintela 
102309d6c965SJuan Quintela     if (params->has_throttle_trigger_threshold) {
102409d6c965SJuan Quintela         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
102509d6c965SJuan Quintela     }
102609d6c965SJuan Quintela 
102709d6c965SJuan Quintela     if (params->has_cpu_throttle_initial) {
102809d6c965SJuan Quintela         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
102909d6c965SJuan Quintela     }
103009d6c965SJuan Quintela 
103109d6c965SJuan Quintela     if (params->has_cpu_throttle_increment) {
103209d6c965SJuan Quintela         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
103309d6c965SJuan Quintela     }
103409d6c965SJuan Quintela 
103509d6c965SJuan Quintela     if (params->has_cpu_throttle_tailslow) {
103609d6c965SJuan Quintela         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
103709d6c965SJuan Quintela     }
103809d6c965SJuan Quintela 
103909d6c965SJuan Quintela     if (params->tls_creds) {
104009d6c965SJuan Quintela         g_free(s->parameters.tls_creds);
104109d6c965SJuan Quintela         assert(params->tls_creds->type == QTYPE_QSTRING);
104209d6c965SJuan Quintela         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
104309d6c965SJuan Quintela     }
104409d6c965SJuan Quintela 
104509d6c965SJuan Quintela     if (params->tls_hostname) {
104609d6c965SJuan Quintela         g_free(s->parameters.tls_hostname);
104709d6c965SJuan Quintela         assert(params->tls_hostname->type == QTYPE_QSTRING);
104809d6c965SJuan Quintela         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
104909d6c965SJuan Quintela     }
105009d6c965SJuan Quintela 
105109d6c965SJuan Quintela     if (params->tls_authz) {
105209d6c965SJuan Quintela         g_free(s->parameters.tls_authz);
105309d6c965SJuan Quintela         assert(params->tls_authz->type == QTYPE_QSTRING);
105409d6c965SJuan Quintela         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
105509d6c965SJuan Quintela     }
105609d6c965SJuan Quintela 
105709d6c965SJuan Quintela     if (params->has_max_bandwidth) {
105809d6c965SJuan Quintela         s->parameters.max_bandwidth = params->max_bandwidth;
105909d6c965SJuan Quintela         if (s->to_dst_file && !migration_in_postcopy()) {
106009d6c965SJuan Quintela             qemu_file_set_rate_limit(s->to_dst_file,
106109d6c965SJuan Quintela                                 s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
106209d6c965SJuan Quintela         }
106309d6c965SJuan Quintela     }
106409d6c965SJuan Quintela 
106509d6c965SJuan Quintela     if (params->has_downtime_limit) {
106609d6c965SJuan Quintela         s->parameters.downtime_limit = params->downtime_limit;
106709d6c965SJuan Quintela     }
106809d6c965SJuan Quintela 
106909d6c965SJuan Quintela     if (params->has_x_checkpoint_delay) {
107009d6c965SJuan Quintela         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
107109d6c965SJuan Quintela         if (migration_in_colo_state()) {
107209d6c965SJuan Quintela             colo_checkpoint_notify(s);
107309d6c965SJuan Quintela         }
107409d6c965SJuan Quintela     }
107509d6c965SJuan Quintela 
107609d6c965SJuan Quintela     if (params->has_block_incremental) {
107709d6c965SJuan Quintela         s->parameters.block_incremental = params->block_incremental;
107809d6c965SJuan Quintela     }
107909d6c965SJuan Quintela     if (params->has_multifd_channels) {
108009d6c965SJuan Quintela         s->parameters.multifd_channels = params->multifd_channels;
108109d6c965SJuan Quintela     }
108209d6c965SJuan Quintela     if (params->has_multifd_compression) {
108309d6c965SJuan Quintela         s->parameters.multifd_compression = params->multifd_compression;
108409d6c965SJuan Quintela     }
108509d6c965SJuan Quintela     if (params->has_xbzrle_cache_size) {
108609d6c965SJuan Quintela         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
108709d6c965SJuan Quintela         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
108809d6c965SJuan Quintela     }
108909d6c965SJuan Quintela     if (params->has_max_postcopy_bandwidth) {
109009d6c965SJuan Quintela         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
109109d6c965SJuan Quintela         if (s->to_dst_file && migration_in_postcopy()) {
109209d6c965SJuan Quintela             qemu_file_set_rate_limit(s->to_dst_file,
109309d6c965SJuan Quintela                     s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO);
109409d6c965SJuan Quintela         }
109509d6c965SJuan Quintela     }
109609d6c965SJuan Quintela     if (params->has_max_cpu_throttle) {
109709d6c965SJuan Quintela         s->parameters.max_cpu_throttle = params->max_cpu_throttle;
109809d6c965SJuan Quintela     }
109909d6c965SJuan Quintela     if (params->has_announce_initial) {
110009d6c965SJuan Quintela         s->parameters.announce_initial = params->announce_initial;
110109d6c965SJuan Quintela     }
110209d6c965SJuan Quintela     if (params->has_announce_max) {
110309d6c965SJuan Quintela         s->parameters.announce_max = params->announce_max;
110409d6c965SJuan Quintela     }
110509d6c965SJuan Quintela     if (params->has_announce_rounds) {
110609d6c965SJuan Quintela         s->parameters.announce_rounds = params->announce_rounds;
110709d6c965SJuan Quintela     }
110809d6c965SJuan Quintela     if (params->has_announce_step) {
110909d6c965SJuan Quintela         s->parameters.announce_step = params->announce_step;
111009d6c965SJuan Quintela     }
111109d6c965SJuan Quintela 
111209d6c965SJuan Quintela     if (params->has_block_bitmap_mapping) {
111309d6c965SJuan Quintela         qapi_free_BitmapMigrationNodeAliasList(
111409d6c965SJuan Quintela             s->parameters.block_bitmap_mapping);
111509d6c965SJuan Quintela 
111609d6c965SJuan Quintela         s->parameters.has_block_bitmap_mapping = true;
111709d6c965SJuan Quintela         s->parameters.block_bitmap_mapping =
111809d6c965SJuan Quintela             QAPI_CLONE(BitmapMigrationNodeAliasList,
111909d6c965SJuan Quintela                        params->block_bitmap_mapping);
112009d6c965SJuan Quintela     }
112109d6c965SJuan Quintela }
112209d6c965SJuan Quintela 
112309d6c965SJuan Quintela void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
112409d6c965SJuan Quintela {
112509d6c965SJuan Quintela     MigrationParameters tmp;
112609d6c965SJuan Quintela 
112709d6c965SJuan Quintela     /* TODO Rewrite "" to null instead */
112809d6c965SJuan Quintela     if (params->tls_creds
112909d6c965SJuan Quintela         && params->tls_creds->type == QTYPE_QNULL) {
113009d6c965SJuan Quintela         qobject_unref(params->tls_creds->u.n);
113109d6c965SJuan Quintela         params->tls_creds->type = QTYPE_QSTRING;
113209d6c965SJuan Quintela         params->tls_creds->u.s = strdup("");
113309d6c965SJuan Quintela     }
113409d6c965SJuan Quintela     /* TODO Rewrite "" to null instead */
113509d6c965SJuan Quintela     if (params->tls_hostname
113609d6c965SJuan Quintela         && params->tls_hostname->type == QTYPE_QNULL) {
113709d6c965SJuan Quintela         qobject_unref(params->tls_hostname->u.n);
113809d6c965SJuan Quintela         params->tls_hostname->type = QTYPE_QSTRING;
113909d6c965SJuan Quintela         params->tls_hostname->u.s = strdup("");
114009d6c965SJuan Quintela     }
114109d6c965SJuan Quintela 
114209d6c965SJuan Quintela     migrate_params_test_apply(params, &tmp);
114309d6c965SJuan Quintela 
114409d6c965SJuan Quintela     if (!migrate_params_check(&tmp, errp)) {
114509d6c965SJuan Quintela         /* Invalid parameter */
114609d6c965SJuan Quintela         return;
114709d6c965SJuan Quintela     }
114809d6c965SJuan Quintela 
114909d6c965SJuan Quintela     migrate_params_apply(params, errp);
115009d6c965SJuan Quintela }
1151