From 944bf4759d1279c342ddd29c47d47c9670b64625 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 10:13:16 +0100 Subject: [PATCH 50/56] migration: Move qmp_migrate_set_parameters() to options.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Peter Xu RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types RH-Bugzilla: 2057267 RH-Acked-by: Leonardo BrĂ¡s RH-Acked-by: Miroslav Rezanina RH-Acked-by: quintela1 RH-Commit: [49/50] b55f7afe868e117d4212f1518b9a37514cc99b33 (peterx/qemu-kvm) Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy (cherry picked from commit 09d6c9658474e8573c5ada58dca8b20fe47dd99e) Signed-off-by: Peter Xu --- migration/migration.c | 420 ------------------------------------------ migration/options.c | 418 +++++++++++++++++++++++++++++++++++++++++ migration/options.h | 11 ++ 3 files changed, 429 insertions(+), 420 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 22ef83c619..08f87f2b0e 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -67,19 +67,10 @@ #define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */ -/* Amount of time to allocate to each "chunk" of bandwidth-throttled - * data. */ -#define BUFFER_DELAY 100 -#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY) - /* Time in milliseconds we are allowed to stop the source, * for sending the last part */ #define DEFAULT_MIGRATE_SET_DOWNTIME 300 -/* Maximum migrate downtime set to 2000 seconds */ -#define MAX_MIGRATE_DOWNTIME_SECONDS 2000 -#define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000) - /* Default compression thread count */ #define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8 /* Default decompression thread count, usually decompression is at @@ -1140,417 +1131,6 @@ MigrationInfo *qmp_query_migrate(Error **errp) return info; } -/* - * Check whether the parameters are valid. Error will be put into errp - * (if provided). Return true if valid, otherwise false. - */ -static bool migrate_params_check(MigrationParameters *params, Error **errp) -{ - if (params->has_compress_level && - (params->compress_level > 9)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", - "a value between 0 and 9"); - return false; - } - - if (params->has_compress_threads && (params->compress_threads < 1)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "compress_threads", - "a value between 1 and 255"); - return false; - } - - if (params->has_decompress_threads && (params->decompress_threads < 1)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "decompress_threads", - "a value between 1 and 255"); - return false; - } - - if (params->has_throttle_trigger_threshold && - (params->throttle_trigger_threshold < 1 || - params->throttle_trigger_threshold > 100)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "throttle_trigger_threshold", - "an integer in the range of 1 to 100"); - return false; - } - - if (params->has_cpu_throttle_initial && - (params->cpu_throttle_initial < 1 || - params->cpu_throttle_initial > 99)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "cpu_throttle_initial", - "an integer in the range of 1 to 99"); - return false; - } - - if (params->has_cpu_throttle_increment && - (params->cpu_throttle_increment < 1 || - params->cpu_throttle_increment > 99)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "cpu_throttle_increment", - "an integer in the range of 1 to 99"); - return false; - } - - if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "max_bandwidth", - "an integer in the range of 0 to "stringify(SIZE_MAX) - " bytes/second"); - return false; - } - - if (params->has_downtime_limit && - (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "downtime_limit", - "an integer in the range of 0 to " - stringify(MAX_MIGRATE_DOWNTIME)" ms"); - return false; - } - - /* x_checkpoint_delay is now always positive */ - - if (params->has_multifd_channels && (params->multifd_channels < 1)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "multifd_channels", - "a value between 1 and 255"); - return false; - } - - if (params->has_multifd_zlib_level && - (params->multifd_zlib_level > 9)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level", - "a value between 0 and 9"); - return false; - } - - if (params->has_multifd_zstd_level && - (params->multifd_zstd_level > 20)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level", - "a value between 0 and 20"); - return false; - } - - if (params->has_xbzrle_cache_size && - (params->xbzrle_cache_size < qemu_target_page_size() || - !is_power_of_2(params->xbzrle_cache_size))) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "xbzrle_cache_size", - "a power of two no less than the target page size"); - return false; - } - - if (params->has_max_cpu_throttle && - (params->max_cpu_throttle < params->cpu_throttle_initial || - params->max_cpu_throttle > 99)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "max_cpu_throttle", - "an integer in the range of cpu_throttle_initial to 99"); - return false; - } - - if (params->has_announce_initial && - params->announce_initial > 100000) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "announce_initial", - "a value between 0 and 100000"); - return false; - } - if (params->has_announce_max && - params->announce_max > 100000) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "announce_max", - "a value between 0 and 100000"); - return false; - } - if (params->has_announce_rounds && - params->announce_rounds > 1000) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "announce_rounds", - "a value between 0 and 1000"); - return false; - } - if (params->has_announce_step && - (params->announce_step < 1 || - params->announce_step > 10000)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "announce_step", - "a value between 0 and 10000"); - return false; - } - - if (params->has_block_bitmap_mapping && - !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) { - error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: "); - return false; - } - -#ifdef CONFIG_LINUX - if (migrate_zero_copy_send() && - ((params->has_multifd_compression && params->multifd_compression) || - (params->tls_creds && *params->tls_creds))) { - error_setg(errp, - "Zero copy only available for non-compressed non-TLS multifd migration"); - return false; - } -#endif - - return true; -} - -static void migrate_params_test_apply(MigrateSetParameters *params, - MigrationParameters *dest) -{ - *dest = migrate_get_current()->parameters; - - /* TODO use QAPI_CLONE() instead of duplicating it inline */ - - if (params->has_compress_level) { - dest->compress_level = params->compress_level; - } - - if (params->has_compress_threads) { - dest->compress_threads = params->compress_threads; - } - - if (params->has_compress_wait_thread) { - dest->compress_wait_thread = params->compress_wait_thread; - } - - if (params->has_decompress_threads) { - dest->decompress_threads = params->decompress_threads; - } - - if (params->has_throttle_trigger_threshold) { - dest->throttle_trigger_threshold = params->throttle_trigger_threshold; - } - - if (params->has_cpu_throttle_initial) { - dest->cpu_throttle_initial = params->cpu_throttle_initial; - } - - if (params->has_cpu_throttle_increment) { - dest->cpu_throttle_increment = params->cpu_throttle_increment; - } - - if (params->has_cpu_throttle_tailslow) { - dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow; - } - - if (params->tls_creds) { - assert(params->tls_creds->type == QTYPE_QSTRING); - dest->tls_creds = params->tls_creds->u.s; - } - - if (params->tls_hostname) { - assert(params->tls_hostname->type == QTYPE_QSTRING); - dest->tls_hostname = params->tls_hostname->u.s; - } - - if (params->has_max_bandwidth) { - dest->max_bandwidth = params->max_bandwidth; - } - - if (params->has_downtime_limit) { - dest->downtime_limit = params->downtime_limit; - } - - if (params->has_x_checkpoint_delay) { - dest->x_checkpoint_delay = params->x_checkpoint_delay; - } - - if (params->has_block_incremental) { - dest->block_incremental = params->block_incremental; - } - if (params->has_multifd_channels) { - dest->multifd_channels = params->multifd_channels; - } - if (params->has_multifd_compression) { - dest->multifd_compression = params->multifd_compression; - } - if (params->has_xbzrle_cache_size) { - dest->xbzrle_cache_size = params->xbzrle_cache_size; - } - if (params->has_max_postcopy_bandwidth) { - dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth; - } - if (params->has_max_cpu_throttle) { - dest->max_cpu_throttle = params->max_cpu_throttle; - } - if (params->has_announce_initial) { - dest->announce_initial = params->announce_initial; - } - if (params->has_announce_max) { - dest->announce_max = params->announce_max; - } - if (params->has_announce_rounds) { - dest->announce_rounds = params->announce_rounds; - } - if (params->has_announce_step) { - dest->announce_step = params->announce_step; - } - - if (params->has_block_bitmap_mapping) { - dest->has_block_bitmap_mapping = true; - dest->block_bitmap_mapping = params->block_bitmap_mapping; - } -} - -static void migrate_params_apply(MigrateSetParameters *params, Error **errp) -{ - MigrationState *s = migrate_get_current(); - - /* TODO use QAPI_CLONE() instead of duplicating it inline */ - - if (params->has_compress_level) { - s->parameters.compress_level = params->compress_level; - } - - if (params->has_compress_threads) { - s->parameters.compress_threads = params->compress_threads; - } - - if (params->has_compress_wait_thread) { - s->parameters.compress_wait_thread = params->compress_wait_thread; - } - - if (params->has_decompress_threads) { - s->parameters.decompress_threads = params->decompress_threads; - } - - if (params->has_throttle_trigger_threshold) { - s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; - } - - if (params->has_cpu_throttle_initial) { - s->parameters.cpu_throttle_initial = params->cpu_throttle_initial; - } - - if (params->has_cpu_throttle_increment) { - s->parameters.cpu_throttle_increment = params->cpu_throttle_increment; - } - - if (params->has_cpu_throttle_tailslow) { - s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow; - } - - if (params->tls_creds) { - g_free(s->parameters.tls_creds); - assert(params->tls_creds->type == QTYPE_QSTRING); - s->parameters.tls_creds = g_strdup(params->tls_creds->u.s); - } - - if (params->tls_hostname) { - g_free(s->parameters.tls_hostname); - assert(params->tls_hostname->type == QTYPE_QSTRING); - s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); - } - - if (params->tls_authz) { - g_free(s->parameters.tls_authz); - assert(params->tls_authz->type == QTYPE_QSTRING); - s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); - } - - if (params->has_max_bandwidth) { - s->parameters.max_bandwidth = params->max_bandwidth; - if (s->to_dst_file && !migration_in_postcopy()) { - qemu_file_set_rate_limit(s->to_dst_file, - s->parameters.max_bandwidth / XFER_LIMIT_RATIO); - } - } - - if (params->has_downtime_limit) { - s->parameters.downtime_limit = params->downtime_limit; - } - - if (params->has_x_checkpoint_delay) { - s->parameters.x_checkpoint_delay = params->x_checkpoint_delay; - if (migration_in_colo_state()) { - colo_checkpoint_notify(s); - } - } - - if (params->has_block_incremental) { - s->parameters.block_incremental = params->block_incremental; - } - if (params->has_multifd_channels) { - s->parameters.multifd_channels = params->multifd_channels; - } - if (params->has_multifd_compression) { - s->parameters.multifd_compression = params->multifd_compression; - } - if (params->has_xbzrle_cache_size) { - s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; - xbzrle_cache_resize(params->xbzrle_cache_size, errp); - } - if (params->has_max_postcopy_bandwidth) { - s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; - if (s->to_dst_file && migration_in_postcopy()) { - qemu_file_set_rate_limit(s->to_dst_file, - s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO); - } - } - if (params->has_max_cpu_throttle) { - s->parameters.max_cpu_throttle = params->max_cpu_throttle; - } - if (params->has_announce_initial) { - s->parameters.announce_initial = params->announce_initial; - } - if (params->has_announce_max) { - s->parameters.announce_max = params->announce_max; - } - if (params->has_announce_rounds) { - s->parameters.announce_rounds = params->announce_rounds; - } - if (params->has_announce_step) { - s->parameters.announce_step = params->announce_step; - } - - if (params->has_block_bitmap_mapping) { - qapi_free_BitmapMigrationNodeAliasList( - s->parameters.block_bitmap_mapping); - - s->parameters.has_block_bitmap_mapping = true; - s->parameters.block_bitmap_mapping = - QAPI_CLONE(BitmapMigrationNodeAliasList, - params->block_bitmap_mapping); - } -} - -void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) -{ - MigrationParameters tmp; - - /* TODO Rewrite "" to null instead */ - if (params->tls_creds - && params->tls_creds->type == QTYPE_QNULL) { - qobject_unref(params->tls_creds->u.n); - params->tls_creds->type = QTYPE_QSTRING; - params->tls_creds->u.s = strdup(""); - } - /* TODO Rewrite "" to null instead */ - if (params->tls_hostname - && params->tls_hostname->type == QTYPE_QNULL) { - qobject_unref(params->tls_hostname->u.n); - params->tls_hostname->type = QTYPE_QSTRING; - params->tls_hostname->u.s = strdup(""); - } - - migrate_params_test_apply(params, &tmp); - - if (!migrate_params_check(&tmp, errp)) { - /* Invalid parameter */ - return; - } - - migrate_params_apply(params, errp); -} - - void qmp_migrate_start_postcopy(Error **errp) { MigrationState *s = migrate_get_current(); diff --git a/migration/options.c b/migration/options.c index d4c0714683..4701c75a4d 100644 --- a/migration/options.c +++ b/migration/options.c @@ -12,17 +12,25 @@ */ #include "qemu/osdep.h" +#include "exec/target_page.h" #include "qapi/clone-visitor.h" #include "qapi/error.h" #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-visit-migration.h" #include "qapi/qmp/qerror.h" +#include "qapi/qmp/qnull.h" #include "sysemu/runstate.h" +#include "migration/colo.h" #include "migration/misc.h" #include "migration.h" +#include "qemu-file.h" #include "ram.h" #include "options.h" +/* Maximum migrate downtime set to 2000 seconds */ +#define MAX_MIGRATE_DOWNTIME_SECONDS 2000 +#define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000) + bool migrate_auto_converge(void) { MigrationState *s; @@ -729,3 +737,413 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) return params; } + +/* + * Check whether the parameters are valid. Error will be put into errp + * (if provided). Return true if valid, otherwise false. + */ +bool migrate_params_check(MigrationParameters *params, Error **errp) +{ + if (params->has_compress_level && + (params->compress_level > 9)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", + "a value between 0 and 9"); + return false; + } + + if (params->has_compress_threads && (params->compress_threads < 1)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "compress_threads", + "a value between 1 and 255"); + return false; + } + + if (params->has_decompress_threads && (params->decompress_threads < 1)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "decompress_threads", + "a value between 1 and 255"); + return false; + } + + if (params->has_throttle_trigger_threshold && + (params->throttle_trigger_threshold < 1 || + params->throttle_trigger_threshold > 100)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "throttle_trigger_threshold", + "an integer in the range of 1 to 100"); + return false; + } + + if (params->has_cpu_throttle_initial && + (params->cpu_throttle_initial < 1 || + params->cpu_throttle_initial > 99)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "cpu_throttle_initial", + "an integer in the range of 1 to 99"); + return false; + } + + if (params->has_cpu_throttle_increment && + (params->cpu_throttle_increment < 1 || + params->cpu_throttle_increment > 99)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "cpu_throttle_increment", + "an integer in the range of 1 to 99"); + return false; + } + + if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "max_bandwidth", + "an integer in the range of 0 to "stringify(SIZE_MAX) + " bytes/second"); + return false; + } + + if (params->has_downtime_limit && + (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "downtime_limit", + "an integer in the range of 0 to " + stringify(MAX_MIGRATE_DOWNTIME)" ms"); + return false; + } + + /* x_checkpoint_delay is now always positive */ + + if (params->has_multifd_channels && (params->multifd_channels < 1)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "multifd_channels", + "a value between 1 and 255"); + return false; + } + + if (params->has_multifd_zlib_level && + (params->multifd_zlib_level > 9)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level", + "a value between 0 and 9"); + return false; + } + + if (params->has_multifd_zstd_level && + (params->multifd_zstd_level > 20)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level", + "a value between 0 and 20"); + return false; + } + + if (params->has_xbzrle_cache_size && + (params->xbzrle_cache_size < qemu_target_page_size() || + !is_power_of_2(params->xbzrle_cache_size))) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "xbzrle_cache_size", + "a power of two no less than the target page size"); + return false; + } + + if (params->has_max_cpu_throttle && + (params->max_cpu_throttle < params->cpu_throttle_initial || + params->max_cpu_throttle > 99)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "max_cpu_throttle", + "an integer in the range of cpu_throttle_initial to 99"); + return false; + } + + if (params->has_announce_initial && + params->announce_initial > 100000) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "announce_initial", + "a value between 0 and 100000"); + return false; + } + if (params->has_announce_max && + params->announce_max > 100000) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "announce_max", + "a value between 0 and 100000"); + return false; + } + if (params->has_announce_rounds && + params->announce_rounds > 1000) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "announce_rounds", + "a value between 0 and 1000"); + return false; + } + if (params->has_announce_step && + (params->announce_step < 1 || + params->announce_step > 10000)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "announce_step", + "a value between 0 and 10000"); + return false; + } + + if (params->has_block_bitmap_mapping && + !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) { + error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: "); + return false; + } + +#ifdef CONFIG_LINUX + if (migrate_zero_copy_send() && + ((params->has_multifd_compression && params->multifd_compression) || + (params->tls_creds && *params->tls_creds))) { + error_setg(errp, + "Zero copy only available for non-compressed non-TLS multifd migration"); + return false; + } +#endif + + return true; +} + +static void migrate_params_test_apply(MigrateSetParameters *params, + MigrationParameters *dest) +{ + *dest = migrate_get_current()->parameters; + + /* TODO use QAPI_CLONE() instead of duplicating it inline */ + + if (params->has_compress_level) { + dest->compress_level = params->compress_level; + } + + if (params->has_compress_threads) { + dest->compress_threads = params->compress_threads; + } + + if (params->has_compress_wait_thread) { + dest->compress_wait_thread = params->compress_wait_thread; + } + + if (params->has_decompress_threads) { + dest->decompress_threads = params->decompress_threads; + } + + if (params->has_throttle_trigger_threshold) { + dest->throttle_trigger_threshold = params->throttle_trigger_threshold; + } + + if (params->has_cpu_throttle_initial) { + dest->cpu_throttle_initial = params->cpu_throttle_initial; + } + + if (params->has_cpu_throttle_increment) { + dest->cpu_throttle_increment = params->cpu_throttle_increment; + } + + if (params->has_cpu_throttle_tailslow) { + dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow; + } + + if (params->tls_creds) { + assert(params->tls_creds->type == QTYPE_QSTRING); + dest->tls_creds = params->tls_creds->u.s; + } + + if (params->tls_hostname) { + assert(params->tls_hostname->type == QTYPE_QSTRING); + dest->tls_hostname = params->tls_hostname->u.s; + } + + if (params->has_max_bandwidth) { + dest->max_bandwidth = params->max_bandwidth; + } + + if (params->has_downtime_limit) { + dest->downtime_limit = params->downtime_limit; + } + + if (params->has_x_checkpoint_delay) { + dest->x_checkpoint_delay = params->x_checkpoint_delay; + } + + if (params->has_block_incremental) { + dest->block_incremental = params->block_incremental; + } + if (params->has_multifd_channels) { + dest->multifd_channels = params->multifd_channels; + } + if (params->has_multifd_compression) { + dest->multifd_compression = params->multifd_compression; + } + if (params->has_xbzrle_cache_size) { + dest->xbzrle_cache_size = params->xbzrle_cache_size; + } + if (params->has_max_postcopy_bandwidth) { + dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth; + } + if (params->has_max_cpu_throttle) { + dest->max_cpu_throttle = params->max_cpu_throttle; + } + if (params->has_announce_initial) { + dest->announce_initial = params->announce_initial; + } + if (params->has_announce_max) { + dest->announce_max = params->announce_max; + } + if (params->has_announce_rounds) { + dest->announce_rounds = params->announce_rounds; + } + if (params->has_announce_step) { + dest->announce_step = params->announce_step; + } + + if (params->has_block_bitmap_mapping) { + dest->has_block_bitmap_mapping = true; + dest->block_bitmap_mapping = params->block_bitmap_mapping; + } +} + +static void migrate_params_apply(MigrateSetParameters *params, Error **errp) +{ + MigrationState *s = migrate_get_current(); + + /* TODO use QAPI_CLONE() instead of duplicating it inline */ + + if (params->has_compress_level) { + s->parameters.compress_level = params->compress_level; + } + + if (params->has_compress_threads) { + s->parameters.compress_threads = params->compress_threads; + } + + if (params->has_compress_wait_thread) { + s->parameters.compress_wait_thread = params->compress_wait_thread; + } + + if (params->has_decompress_threads) { + s->parameters.decompress_threads = params->decompress_threads; + } + + if (params->has_throttle_trigger_threshold) { + s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; + } + + if (params->has_cpu_throttle_initial) { + s->parameters.cpu_throttle_initial = params->cpu_throttle_initial; + } + + if (params->has_cpu_throttle_increment) { + s->parameters.cpu_throttle_increment = params->cpu_throttle_increment; + } + + if (params->has_cpu_throttle_tailslow) { + s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow; + } + + if (params->tls_creds) { + g_free(s->parameters.tls_creds); + assert(params->tls_creds->type == QTYPE_QSTRING); + s->parameters.tls_creds = g_strdup(params->tls_creds->u.s); + } + + if (params->tls_hostname) { + g_free(s->parameters.tls_hostname); + assert(params->tls_hostname->type == QTYPE_QSTRING); + s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); + } + + if (params->tls_authz) { + g_free(s->parameters.tls_authz); + assert(params->tls_authz->type == QTYPE_QSTRING); + s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); + } + + if (params->has_max_bandwidth) { + s->parameters.max_bandwidth = params->max_bandwidth; + if (s->to_dst_file && !migration_in_postcopy()) { + qemu_file_set_rate_limit(s->to_dst_file, + s->parameters.max_bandwidth / XFER_LIMIT_RATIO); + } + } + + if (params->has_downtime_limit) { + s->parameters.downtime_limit = params->downtime_limit; + } + + if (params->has_x_checkpoint_delay) { + s->parameters.x_checkpoint_delay = params->x_checkpoint_delay; + if (migration_in_colo_state()) { + colo_checkpoint_notify(s); + } + } + + if (params->has_block_incremental) { + s->parameters.block_incremental = params->block_incremental; + } + if (params->has_multifd_channels) { + s->parameters.multifd_channels = params->multifd_channels; + } + if (params->has_multifd_compression) { + s->parameters.multifd_compression = params->multifd_compression; + } + if (params->has_xbzrle_cache_size) { + s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; + xbzrle_cache_resize(params->xbzrle_cache_size, errp); + } + if (params->has_max_postcopy_bandwidth) { + s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; + if (s->to_dst_file && migration_in_postcopy()) { + qemu_file_set_rate_limit(s->to_dst_file, + s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO); + } + } + if (params->has_max_cpu_throttle) { + s->parameters.max_cpu_throttle = params->max_cpu_throttle; + } + if (params->has_announce_initial) { + s->parameters.announce_initial = params->announce_initial; + } + if (params->has_announce_max) { + s->parameters.announce_max = params->announce_max; + } + if (params->has_announce_rounds) { + s->parameters.announce_rounds = params->announce_rounds; + } + if (params->has_announce_step) { + s->parameters.announce_step = params->announce_step; + } + + if (params->has_block_bitmap_mapping) { + qapi_free_BitmapMigrationNodeAliasList( + s->parameters.block_bitmap_mapping); + + s->parameters.has_block_bitmap_mapping = true; + s->parameters.block_bitmap_mapping = + QAPI_CLONE(BitmapMigrationNodeAliasList, + params->block_bitmap_mapping); + } +} + +void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) +{ + MigrationParameters tmp; + + /* TODO Rewrite "" to null instead */ + if (params->tls_creds + && params->tls_creds->type == QTYPE_QNULL) { + qobject_unref(params->tls_creds->u.n); + params->tls_creds->type = QTYPE_QSTRING; + params->tls_creds->u.s = strdup(""); + } + /* TODO Rewrite "" to null instead */ + if (params->tls_hostname + && params->tls_hostname->type == QTYPE_QNULL) { + qobject_unref(params->tls_hostname->u.n); + params->tls_hostname->type = QTYPE_QSTRING; + params->tls_hostname->u.s = strdup(""); + } + + migrate_params_test_apply(params, &tmp); + + if (!migrate_params_check(&tmp, errp)) { + /* Invalid parameter */ + return; + } + + migrate_params_apply(params, errp); +} diff --git a/migration/options.h b/migration/options.h index 13318a16c7..89067e59a0 100644 --- a/migration/options.h +++ b/migration/options.h @@ -14,6 +14,13 @@ #ifndef QEMU_MIGRATION_OPTIONS_H #define QEMU_MIGRATION_OPTIONS_H +/* constants */ + +/* Amount of time to allocate to each "chunk" of bandwidth-throttled + * data. */ +#define BUFFER_DELAY 100 +#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY) + /* capabilities */ bool migrate_auto_converge(void); @@ -74,4 +81,8 @@ int migrate_multifd_zstd_level(void); uint8_t migrate_throttle_trigger_threshold(void); uint64_t migrate_xbzrle_cache_size(void); +/* parameters helpers */ + +bool migrate_params_check(MigrationParameters *params, Error **errp); + #endif -- 2.39.1