Migration Pull request (20230427 edition)
Hi Everything that has been reviewed: - stat64_set() by paolo - atomic_counters series fully reviewed (juan) - move capabilities to options.c fully reviewed (juan) - fix the channels_ready semaphore (juan) - multifd flush optimization reviewed (juan) Please, apply. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmRKi3YACgkQ9IfvGFhy 1yPtERAAgkBt4g3tpn90q+QeFLBPyo0KGxX4UiAmh8aiGRAJzmSJfjaQG3RgK0vM Iyat60Tx6lpHta7xRE+pDF7tXmoi0631B5FJjfuyTIFGWdrOpjGHihuxWdnIjK0H ZhR3LfQvHqybMfiyZN/7T5/qICB0zZ+erIeoaurRU3RVrO8yRPM+VBwsYr1RW1S4 DxUeXEJF09tat7TgiQYp2w5cMPcQ2AvzgViR2r7yc0WjY2yUscyMjuPbHPqAsYWB UkbNuH7M/quvHqGvgxGYEQ+a6wyBzKlissjxWe8KTuSLNML2RVR6IrpuEPe6XyGe FWi+XRB5114EMy7YjjgTWzcLMC9EmhpzKTgJi0NEtL+cGRb9ZaSaSLE5yO7GLF9b efhCXT9jIef9/3Hi+Kr0juJ3nX6c7pINTAsx7wxKU0phz5kYx37IqIioMlVDh1ew ECpH+8Syrp/zYytc/HIpyOwIR9VdZrRi6jr2yqcc9lLLcuNUzl+E+9mAxWzO/gef +cYPnQZC0rjIzJSBZjq7TXYFNblD6HreONGL8UdFN0B7Js5mPu2PU3449jYNSOxi 1aj/eHNXEcqKcVZ3GDGgtus3ARvFsbEba0UZYIVboKp5i96f8O9YqKvRdBjAjpq1 IDT/fvI2Fj1mjKi8KuAq8fK5utm+g4NR9WkQX0d661dQNZ3XqVc= =NE9v -----END PGP SIGNATURE----- Merge tag 'migration-20230427-pull-request' of https://gitlab.com/juan.quintela/qemu into staging Migration Pull request (20230427 edition) Hi Everything that has been reviewed: - stat64_set() by paolo - atomic_counters series fully reviewed (juan) - move capabilities to options.c fully reviewed (juan) - fix the channels_ready semaphore (juan) - multifd flush optimization reviewed (juan) Please, apply. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmRKi3YACgkQ9IfvGFhy # 1yPtERAAgkBt4g3tpn90q+QeFLBPyo0KGxX4UiAmh8aiGRAJzmSJfjaQG3RgK0vM # Iyat60Tx6lpHta7xRE+pDF7tXmoi0631B5FJjfuyTIFGWdrOpjGHihuxWdnIjK0H # ZhR3LfQvHqybMfiyZN/7T5/qICB0zZ+erIeoaurRU3RVrO8yRPM+VBwsYr1RW1S4 # DxUeXEJF09tat7TgiQYp2w5cMPcQ2AvzgViR2r7yc0WjY2yUscyMjuPbHPqAsYWB # UkbNuH7M/quvHqGvgxGYEQ+a6wyBzKlissjxWe8KTuSLNML2RVR6IrpuEPe6XyGe # FWi+XRB5114EMy7YjjgTWzcLMC9EmhpzKTgJi0NEtL+cGRb9ZaSaSLE5yO7GLF9b # efhCXT9jIef9/3Hi+Kr0juJ3nX6c7pINTAsx7wxKU0phz5kYx37IqIioMlVDh1ew # ECpH+8Syrp/zYytc/HIpyOwIR9VdZrRi6jr2yqcc9lLLcuNUzl+E+9mAxWzO/gef # +cYPnQZC0rjIzJSBZjq7TXYFNblD6HreONGL8UdFN0B7Js5mPu2PU3449jYNSOxi # 1aj/eHNXEcqKcVZ3GDGgtus3ARvFsbEba0UZYIVboKp5i96f8O9YqKvRdBjAjpq1 # IDT/fvI2Fj1mjKi8KuAq8fK5utm+g4NR9WkQX0d661dQNZ3XqVc= # =NE9v # -----END PGP SIGNATURE----- # gpg: Signature made Thu 27 Apr 2023 03:49:26 PM BST # gpg: using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [undefined] # gpg: aka "Juan Quintela <quintela@trasno.org>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * tag 'migration-20230427-pull-request' of https://gitlab.com/juan.quintela/qemu: migration: Make dirty_bytes_last_sync atomic migration: Make dirty_pages_rate atomic stat64: Add stat64_set() operation multifd: Only flush once each full round of memory multifd: Protect multifd_send_sync_main() calls multifd: Create property multifd-flush-after-each-section migration: Move migration_properties to options.c migration: Create migrate_block_bitmap_mapping() function migration: Create migrate_tls_hostname() function migration: Create migrate_tls_authz() function migration: Create migrate_tls_creds() function migration: Remove MigrationState from block_cleanup_parameters() migration: Move block_cleanup_parameters() to options.c migration: Move migrate_set_block_incremental() to options.c migration: Create migrate_downtime_limit() function migration: Make all functions check have the same format migration: Create migrate_params_init() function multifd: Fix the number of channels ready Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
05d50ba2d4
@ -39,7 +39,9 @@
|
|||||||
#include "hw/virtio/virtio.h"
|
#include "hw/virtio/virtio.h"
|
||||||
#include "hw/virtio/virtio-pci.h"
|
#include "hw/virtio/virtio-pci.h"
|
||||||
|
|
||||||
GlobalProperty hw_compat_8_0[] = {};
|
GlobalProperty hw_compat_8_0[] = {
|
||||||
|
{ "migration", "multifd-flush-after-each-section", "on"},
|
||||||
|
};
|
||||||
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
|
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
|
||||||
|
|
||||||
GlobalProperty hw_compat_7_2[] = {
|
GlobalProperty hw_compat_7_2[] = {
|
||||||
|
@ -40,6 +40,11 @@ static inline uint64_t stat64_get(const Stat64 *s)
|
|||||||
return qatomic_read__nocheck(&s->value);
|
return qatomic_read__nocheck(&s->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void stat64_set(Stat64 *s, uint64_t value)
|
||||||
|
{
|
||||||
|
qatomic_set__nocheck(&s->value, value);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void stat64_add(Stat64 *s, uint64_t value)
|
static inline void stat64_add(Stat64 *s, uint64_t value)
|
||||||
{
|
{
|
||||||
qatomic_add(&s->value, value);
|
qatomic_add(&s->value, value);
|
||||||
@ -62,6 +67,7 @@ static inline void stat64_max(Stat64 *s, uint64_t value)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
uint64_t stat64_get(const Stat64 *s);
|
uint64_t stat64_get(const Stat64 *s);
|
||||||
|
void stat64_set(Stat64 *s, uint64_t value);
|
||||||
bool stat64_min_slow(Stat64 *s, uint64_t value);
|
bool stat64_min_slow(Stat64 *s, uint64_t value);
|
||||||
bool stat64_max_slow(Stat64 *s, uint64_t value);
|
bool stat64_max_slow(Stat64 *s, uint64_t value);
|
||||||
bool stat64_add32_carry(Stat64 *s, uint32_t low, uint32_t high);
|
bool stat64_add32_carry(Stat64 *s, uint32_t low, uint32_t high);
|
||||||
|
@ -605,11 +605,12 @@ static int init_dirty_bitmap_migration(DBMSaveState *s)
|
|||||||
SaveBitmapState *dbms;
|
SaveBitmapState *dbms;
|
||||||
GHashTable *handled_by_blk = g_hash_table_new(NULL, NULL);
|
GHashTable *handled_by_blk = g_hash_table_new(NULL, NULL);
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
const MigrationParameters *mig_params = &migrate_get_current()->parameters;
|
|
||||||
GHashTable *alias_map = NULL;
|
GHashTable *alias_map = NULL;
|
||||||
|
const BitmapMigrationNodeAliasList *block_bitmap_mapping =
|
||||||
|
migrate_block_bitmap_mapping();
|
||||||
|
|
||||||
if (mig_params->has_block_bitmap_mapping) {
|
if (block_bitmap_mapping) {
|
||||||
alias_map = construct_alias_map(mig_params->block_bitmap_mapping, true,
|
alias_map = construct_alias_map(block_bitmap_mapping, true,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,7 +1159,8 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s,
|
|||||||
static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
|
static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
GHashTable *alias_map = NULL;
|
GHashTable *alias_map = NULL;
|
||||||
const MigrationParameters *mig_params = &migrate_get_current()->parameters;
|
const BitmapMigrationNodeAliasList *block_bitmap_mapping =
|
||||||
|
migrate_block_bitmap_mapping();
|
||||||
DBMLoadState *s = &((DBMState *)opaque)->load;
|
DBMLoadState *s = &((DBMState *)opaque)->load;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -1170,8 +1172,8 @@ static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mig_params->has_block_bitmap_mapping) {
|
if (block_bitmap_mapping) {
|
||||||
alias_map = construct_alias_map(mig_params->block_bitmap_mapping,
|
alias_map = construct_alias_map(block_bitmap_mapping,
|
||||||
false, &error_abort);
|
false, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +52,6 @@
|
|||||||
#include "io/channel-tls.h"
|
#include "io/channel-tls.h"
|
||||||
#include "migration/colo.h"
|
#include "migration/colo.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "hw/qdev-properties.h"
|
|
||||||
#include "hw/qdev-properties-system.h"
|
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
#include "net/announce.h"
|
#include "net/announce.h"
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
@ -65,51 +63,6 @@
|
|||||||
#include "sysemu/qtest.h"
|
#include "sysemu/qtest.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
#define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */
|
|
||||||
|
|
||||||
/* Time in milliseconds we are allowed to stop the source,
|
|
||||||
* for sending the last part */
|
|
||||||
#define DEFAULT_MIGRATE_SET_DOWNTIME 300
|
|
||||||
|
|
||||||
/* Default compression thread count */
|
|
||||||
#define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
|
|
||||||
/* Default decompression thread count, usually decompression is at
|
|
||||||
* least 4 times as fast as compression.*/
|
|
||||||
#define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2
|
|
||||||
/*0: means nocompress, 1: best speed, ... 9: best compress ratio */
|
|
||||||
#define DEFAULT_MIGRATE_COMPRESS_LEVEL 1
|
|
||||||
/* Define default autoconverge cpu throttle migration parameters */
|
|
||||||
#define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50
|
|
||||||
#define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
|
|
||||||
#define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
|
|
||||||
#define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99
|
|
||||||
|
|
||||||
/* Migration XBZRLE default cache size */
|
|
||||||
#define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024)
|
|
||||||
|
|
||||||
/* The delay time (in ms) between two COLO checkpoints */
|
|
||||||
#define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100)
|
|
||||||
#define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
|
|
||||||
#define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE
|
|
||||||
/* 0: means nocompress, 1: best speed, ... 9: best compress ratio */
|
|
||||||
#define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1
|
|
||||||
/* 0: means nocompress, 1: best speed, ... 20: best compress ratio */
|
|
||||||
#define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1
|
|
||||||
|
|
||||||
/* Background transfer rate for postcopy, 0 means unlimited, note
|
|
||||||
* that page requests can still exceed this limit.
|
|
||||||
*/
|
|
||||||
#define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parameters for self_announce_delay giving a stream of RARP/ARP
|
|
||||||
* packets after migration.
|
|
||||||
*/
|
|
||||||
#define DEFAULT_MIGRATE_ANNOUNCE_INITIAL 50
|
|
||||||
#define DEFAULT_MIGRATE_ANNOUNCE_MAX 550
|
|
||||||
#define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS 5
|
|
||||||
#define DEFAULT_MIGRATE_ANNOUNCE_STEP 100
|
|
||||||
|
|
||||||
static NotifierList migration_state_notifiers =
|
static NotifierList migration_state_notifiers =
|
||||||
NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
|
NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
|
||||||
|
|
||||||
@ -1005,7 +958,8 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
|
|||||||
|
|
||||||
if (s->state != MIGRATION_STATUS_COMPLETED) {
|
if (s->state != MIGRATION_STATUS_COMPLETED) {
|
||||||
info->ram->remaining = ram_bytes_remaining();
|
info->ram->remaining = ram_bytes_remaining();
|
||||||
info->ram->dirty_pages_rate = ram_counters.dirty_pages_rate;
|
info->ram->dirty_pages_rate =
|
||||||
|
stat64_get(&ram_counters.dirty_pages_rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1164,21 +1118,6 @@ void migrate_set_state(int *state, int old_state, int new_state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void migrate_set_block_incremental(MigrationState *s, bool value)
|
|
||||||
{
|
|
||||||
s->parameters.block_incremental = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void block_cleanup_parameters(MigrationState *s)
|
|
||||||
{
|
|
||||||
if (s->must_remove_block_options) {
|
|
||||||
/* setting to false can never fail */
|
|
||||||
migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort);
|
|
||||||
migrate_set_block_incremental(s, false);
|
|
||||||
s->must_remove_block_options = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void migrate_fd_cleanup(MigrationState *s)
|
static void migrate_fd_cleanup(MigrationState *s)
|
||||||
{
|
{
|
||||||
qemu_bh_delete(s->cleanup_bh);
|
qemu_bh_delete(s->cleanup_bh);
|
||||||
@ -1233,7 +1172,7 @@ static void migrate_fd_cleanup(MigrationState *s)
|
|||||||
error_report_err(error_copy(s->error));
|
error_report_err(error_copy(s->error));
|
||||||
}
|
}
|
||||||
notifier_list_notify(&migration_state_notifiers, s);
|
notifier_list_notify(&migration_state_notifiers, s);
|
||||||
block_cleanup_parameters(s);
|
block_cleanup_parameters();
|
||||||
yank_unregister_instance(MIGRATION_YANK_INSTANCE);
|
yank_unregister_instance(MIGRATION_YANK_INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1668,7 +1607,7 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (blk_inc) {
|
if (blk_inc) {
|
||||||
migrate_set_block_incremental(s, true);
|
migrate_set_block_incremental(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
migrate_init(s);
|
migrate_init(s);
|
||||||
@ -1727,7 +1666,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
|
|||||||
"a valid migration protocol");
|
"a valid migration protocol");
|
||||||
migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
|
migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
|
||||||
MIGRATION_STATUS_FAILED);
|
MIGRATION_STATUS_FAILED);
|
||||||
block_cleanup_parameters(s);
|
block_cleanup_parameters();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2737,7 +2676,7 @@ static void migration_update_counters(MigrationState *s,
|
|||||||
transferred = current_bytes - s->iteration_initial_bytes;
|
transferred = current_bytes - s->iteration_initial_bytes;
|
||||||
time_spent = current_time - s->iteration_start_time;
|
time_spent = current_time - s->iteration_start_time;
|
||||||
bandwidth = (double)transferred / time_spent;
|
bandwidth = (double)transferred / time_spent;
|
||||||
s->threshold_size = bandwidth * s->parameters.downtime_limit;
|
s->threshold_size = bandwidth * migrate_downtime_limit();
|
||||||
|
|
||||||
s->mbps = (((double) transferred * 8.0) /
|
s->mbps = (((double) transferred * 8.0) /
|
||||||
((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
|
((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
|
||||||
@ -2751,8 +2690,10 @@ static void migration_update_counters(MigrationState *s,
|
|||||||
* if we haven't sent anything, we don't want to
|
* if we haven't sent anything, we don't want to
|
||||||
* recalculate. 10000 is a small enough number for our purposes
|
* recalculate. 10000 is a small enough number for our purposes
|
||||||
*/
|
*/
|
||||||
if (ram_counters.dirty_pages_rate && transferred > 10000) {
|
if (stat64_get(&ram_counters.dirty_pages_rate) &&
|
||||||
s->expected_downtime = ram_counters.remaining / bandwidth;
|
transferred > 10000) {
|
||||||
|
s->expected_downtime =
|
||||||
|
stat64_get(&ram_counters.dirty_bytes_last_sync) / bandwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_file_reset_rate_limit(s->to_dst_file);
|
qemu_file_reset_rate_limit(s->to_dst_file);
|
||||||
@ -3244,7 +3185,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in)
|
|||||||
*/
|
*/
|
||||||
migrate_error_free(s);
|
migrate_error_free(s);
|
||||||
|
|
||||||
s->expected_downtime = s->parameters.downtime_limit;
|
s->expected_downtime = migrate_downtime_limit();
|
||||||
if (resume) {
|
if (resume) {
|
||||||
assert(s->cleanup_bh);
|
assert(s->cleanup_bh);
|
||||||
} else {
|
} else {
|
||||||
@ -3332,116 +3273,6 @@ void migrate_fd_connect(MigrationState *s, Error *error_in)
|
|||||||
s->migration_thread_running = true;
|
s->migration_thread_running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_PROP_MIG_CAP(name, x) \
|
|
||||||
DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false)
|
|
||||||
|
|
||||||
static Property migration_properties[] = {
|
|
||||||
DEFINE_PROP_BOOL("store-global-state", MigrationState,
|
|
||||||
store_global_state, true),
|
|
||||||
DEFINE_PROP_BOOL("send-configuration", MigrationState,
|
|
||||||
send_configuration, true),
|
|
||||||
DEFINE_PROP_BOOL("send-section-footer", MigrationState,
|
|
||||||
send_section_footer, true),
|
|
||||||
DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
|
|
||||||
decompress_error_check, true),
|
|
||||||
DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
|
|
||||||
clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
|
|
||||||
DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
|
|
||||||
preempt_pre_7_2, false),
|
|
||||||
|
|
||||||
/* Migration parameters */
|
|
||||||
DEFINE_PROP_UINT8("x-compress-level", MigrationState,
|
|
||||||
parameters.compress_level,
|
|
||||||
DEFAULT_MIGRATE_COMPRESS_LEVEL),
|
|
||||||
DEFINE_PROP_UINT8("x-compress-threads", MigrationState,
|
|
||||||
parameters.compress_threads,
|
|
||||||
DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT),
|
|
||||||
DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState,
|
|
||||||
parameters.compress_wait_thread, true),
|
|
||||||
DEFINE_PROP_UINT8("x-decompress-threads", MigrationState,
|
|
||||||
parameters.decompress_threads,
|
|
||||||
DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT),
|
|
||||||
DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState,
|
|
||||||
parameters.throttle_trigger_threshold,
|
|
||||||
DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
|
|
||||||
DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState,
|
|
||||||
parameters.cpu_throttle_initial,
|
|
||||||
DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL),
|
|
||||||
DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState,
|
|
||||||
parameters.cpu_throttle_increment,
|
|
||||||
DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
|
|
||||||
DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState,
|
|
||||||
parameters.cpu_throttle_tailslow, false),
|
|
||||||
DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState,
|
|
||||||
parameters.max_bandwidth, MAX_THROTTLE),
|
|
||||||
DEFINE_PROP_UINT64("x-downtime-limit", MigrationState,
|
|
||||||
parameters.downtime_limit,
|
|
||||||
DEFAULT_MIGRATE_SET_DOWNTIME),
|
|
||||||
DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
|
|
||||||
parameters.x_checkpoint_delay,
|
|
||||||
DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
|
|
||||||
DEFINE_PROP_UINT8("multifd-channels", MigrationState,
|
|
||||||
parameters.multifd_channels,
|
|
||||||
DEFAULT_MIGRATE_MULTIFD_CHANNELS),
|
|
||||||
DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState,
|
|
||||||
parameters.multifd_compression,
|
|
||||||
DEFAULT_MIGRATE_MULTIFD_COMPRESSION),
|
|
||||||
DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState,
|
|
||||||
parameters.multifd_zlib_level,
|
|
||||||
DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL),
|
|
||||||
DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState,
|
|
||||||
parameters.multifd_zstd_level,
|
|
||||||
DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL),
|
|
||||||
DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
|
|
||||||
parameters.xbzrle_cache_size,
|
|
||||||
DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
|
|
||||||
DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState,
|
|
||||||
parameters.max_postcopy_bandwidth,
|
|
||||||
DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH),
|
|
||||||
DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState,
|
|
||||||
parameters.max_cpu_throttle,
|
|
||||||
DEFAULT_MIGRATE_MAX_CPU_THROTTLE),
|
|
||||||
DEFINE_PROP_SIZE("announce-initial", MigrationState,
|
|
||||||
parameters.announce_initial,
|
|
||||||
DEFAULT_MIGRATE_ANNOUNCE_INITIAL),
|
|
||||||
DEFINE_PROP_SIZE("announce-max", MigrationState,
|
|
||||||
parameters.announce_max,
|
|
||||||
DEFAULT_MIGRATE_ANNOUNCE_MAX),
|
|
||||||
DEFINE_PROP_SIZE("announce-rounds", MigrationState,
|
|
||||||
parameters.announce_rounds,
|
|
||||||
DEFAULT_MIGRATE_ANNOUNCE_ROUNDS),
|
|
||||||
DEFINE_PROP_SIZE("announce-step", MigrationState,
|
|
||||||
parameters.announce_step,
|
|
||||||
DEFAULT_MIGRATE_ANNOUNCE_STEP),
|
|
||||||
DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds),
|
|
||||||
DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname),
|
|
||||||
DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz),
|
|
||||||
|
|
||||||
/* Migration capabilities */
|
|
||||||
DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-postcopy-preempt",
|
|
||||||
MIGRATION_CAPABILITY_POSTCOPY_PREEMPT),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
|
|
||||||
DEFINE_PROP_MIG_CAP("x-background-snapshot",
|
|
||||||
MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
|
|
||||||
#ifdef CONFIG_LINUX
|
|
||||||
DEFINE_PROP_MIG_CAP("x-zero-copy-send",
|
|
||||||
MIGRATION_CAPABILITY_ZERO_COPY_SEND),
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void migration_class_init(ObjectClass *klass, void *data)
|
static void migration_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
@ -3470,7 +3301,6 @@ static void migration_instance_finalize(Object *obj)
|
|||||||
static void migration_instance_init(Object *obj)
|
static void migration_instance_init(Object *obj)
|
||||||
{
|
{
|
||||||
MigrationState *ms = MIGRATION_OBJ(obj);
|
MigrationState *ms = MIGRATION_OBJ(obj);
|
||||||
MigrationParameters *params = &ms->parameters;
|
|
||||||
|
|
||||||
ms->state = MIGRATION_STATUS_NONE;
|
ms->state = MIGRATION_STATUS_NONE;
|
||||||
ms->mbps = -1;
|
ms->mbps = -1;
|
||||||
@ -3478,33 +3308,7 @@ static void migration_instance_init(Object *obj)
|
|||||||
qemu_sem_init(&ms->pause_sem, 0);
|
qemu_sem_init(&ms->pause_sem, 0);
|
||||||
qemu_mutex_init(&ms->error_mutex);
|
qemu_mutex_init(&ms->error_mutex);
|
||||||
|
|
||||||
params->tls_hostname = g_strdup("");
|
migrate_params_init(&ms->parameters);
|
||||||
params->tls_creds = g_strdup("");
|
|
||||||
|
|
||||||
/* Set has_* up only for parameter checks */
|
|
||||||
params->has_compress_level = true;
|
|
||||||
params->has_compress_threads = true;
|
|
||||||
params->has_compress_wait_thread = true;
|
|
||||||
params->has_decompress_threads = true;
|
|
||||||
params->has_throttle_trigger_threshold = true;
|
|
||||||
params->has_cpu_throttle_initial = true;
|
|
||||||
params->has_cpu_throttle_increment = true;
|
|
||||||
params->has_cpu_throttle_tailslow = true;
|
|
||||||
params->has_max_bandwidth = true;
|
|
||||||
params->has_downtime_limit = true;
|
|
||||||
params->has_x_checkpoint_delay = true;
|
|
||||||
params->has_block_incremental = true;
|
|
||||||
params->has_multifd_channels = true;
|
|
||||||
params->has_multifd_compression = true;
|
|
||||||
params->has_multifd_zlib_level = true;
|
|
||||||
params->has_multifd_zstd_level = true;
|
|
||||||
params->has_xbzrle_cache_size = true;
|
|
||||||
params->has_max_postcopy_bandwidth = true;
|
|
||||||
params->has_max_cpu_throttle = true;
|
|
||||||
params->has_announce_initial = true;
|
|
||||||
params->has_announce_max = true;
|
|
||||||
params->has_announce_rounds = true;
|
|
||||||
params->has_announce_step = true;
|
|
||||||
|
|
||||||
qemu_sem_init(&ms->postcopy_pause_sem, 0);
|
qemu_sem_init(&ms->postcopy_pause_sem, 0);
|
||||||
qemu_sem_init(&ms->postcopy_pause_rp_sem, 0);
|
qemu_sem_init(&ms->postcopy_pause_rp_sem, 0);
|
||||||
|
@ -404,6 +404,17 @@ struct MigrationState {
|
|||||||
*/
|
*/
|
||||||
bool preempt_pre_7_2;
|
bool preempt_pre_7_2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flush every channel after each section sent.
|
||||||
|
*
|
||||||
|
* This assures that we can't mix pages from one iteration through
|
||||||
|
* ram pages with pages for the following iteration. We really
|
||||||
|
* only need to do this flush after we have go through all the
|
||||||
|
* dirty pages. For historical reasons, we do that after each
|
||||||
|
* section. This is suboptimal (we flush too many times).
|
||||||
|
* Default value is false. (since 8.1)
|
||||||
|
*/
|
||||||
|
bool multifd_flush_after_each_section;
|
||||||
/*
|
/*
|
||||||
* This decides the size of guest memory chunk that will be used
|
* This decides the size of guest memory chunk that will be used
|
||||||
* to track dirty bitmap clearing. The size of memory chunk will
|
* to track dirty bitmap clearing. The size of memory chunk will
|
||||||
|
@ -635,6 +635,7 @@ int multifd_send_sync_main(QEMUFile *f)
|
|||||||
for (i = 0; i < migrate_multifd_channels(); i++) {
|
for (i = 0; i < migrate_multifd_channels(); i++) {
|
||||||
MultiFDSendParams *p = &multifd_send_state->params[i];
|
MultiFDSendParams *p = &multifd_send_state->params[i];
|
||||||
|
|
||||||
|
qemu_sem_wait(&multifd_send_state->channels_ready);
|
||||||
trace_multifd_send_sync_main_wait(p->id);
|
trace_multifd_send_sync_main_wait(p->id);
|
||||||
qemu_sem_wait(&p->sem_sync);
|
qemu_sem_wait(&p->sem_sync);
|
||||||
|
|
||||||
@ -668,6 +669,7 @@ static void *multifd_send_thread(void *opaque)
|
|||||||
p->num_packets = 1;
|
p->num_packets = 1;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
qemu_sem_post(&multifd_send_state->channels_ready);
|
||||||
qemu_sem_wait(&p->sem);
|
qemu_sem_wait(&p->sem);
|
||||||
|
|
||||||
if (qatomic_read(&multifd_send_state->exiting)) {
|
if (qatomic_read(&multifd_send_state->exiting)) {
|
||||||
@ -736,7 +738,6 @@ static void *multifd_send_thread(void *opaque)
|
|||||||
if (flags & MULTIFD_FLAG_SYNC) {
|
if (flags & MULTIFD_FLAG_SYNC) {
|
||||||
qemu_sem_post(&p->sem_sync);
|
qemu_sem_post(&p->sem_sync);
|
||||||
}
|
}
|
||||||
qemu_sem_post(&multifd_send_state->channels_ready);
|
|
||||||
} else if (p->quit) {
|
} else if (p->quit) {
|
||||||
qemu_mutex_unlock(&p->mutex);
|
qemu_mutex_unlock(&p->mutex);
|
||||||
break;
|
break;
|
||||||
|
@ -31,29 +31,180 @@
|
|||||||
#define MAX_MIGRATE_DOWNTIME_SECONDS 2000
|
#define MAX_MIGRATE_DOWNTIME_SECONDS 2000
|
||||||
#define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000)
|
#define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000)
|
||||||
|
|
||||||
|
#define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */
|
||||||
|
|
||||||
|
/* Time in milliseconds we are allowed to stop the source,
|
||||||
|
* for sending the last part */
|
||||||
|
#define DEFAULT_MIGRATE_SET_DOWNTIME 300
|
||||||
|
|
||||||
|
/* Default compression thread count */
|
||||||
|
#define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
|
||||||
|
/* Default decompression thread count, usually decompression is at
|
||||||
|
* least 4 times as fast as compression.*/
|
||||||
|
#define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2
|
||||||
|
/*0: means nocompress, 1: best speed, ... 9: best compress ratio */
|
||||||
|
#define DEFAULT_MIGRATE_COMPRESS_LEVEL 1
|
||||||
|
/* Define default autoconverge cpu throttle migration parameters */
|
||||||
|
#define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50
|
||||||
|
#define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
|
||||||
|
#define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
|
||||||
|
#define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99
|
||||||
|
|
||||||
|
/* Migration XBZRLE default cache size */
|
||||||
|
#define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024)
|
||||||
|
|
||||||
|
/* The delay time (in ms) between two COLO checkpoints */
|
||||||
|
#define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100)
|
||||||
|
#define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
|
||||||
|
#define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE
|
||||||
|
/* 0: means nocompress, 1: best speed, ... 9: best compress ratio */
|
||||||
|
#define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1
|
||||||
|
/* 0: means nocompress, 1: best speed, ... 20: best compress ratio */
|
||||||
|
#define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1
|
||||||
|
|
||||||
|
/* Background transfer rate for postcopy, 0 means unlimited, note
|
||||||
|
* that page requests can still exceed this limit.
|
||||||
|
*/
|
||||||
|
#define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parameters for self_announce_delay giving a stream of RARP/ARP
|
||||||
|
* packets after migration.
|
||||||
|
*/
|
||||||
|
#define DEFAULT_MIGRATE_ANNOUNCE_INITIAL 50
|
||||||
|
#define DEFAULT_MIGRATE_ANNOUNCE_MAX 550
|
||||||
|
#define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS 5
|
||||||
|
#define DEFAULT_MIGRATE_ANNOUNCE_STEP 100
|
||||||
|
|
||||||
|
#define DEFINE_PROP_MIG_CAP(name, x) \
|
||||||
|
DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false)
|
||||||
|
|
||||||
|
Property migration_properties[] = {
|
||||||
|
DEFINE_PROP_BOOL("store-global-state", MigrationState,
|
||||||
|
store_global_state, true),
|
||||||
|
DEFINE_PROP_BOOL("send-configuration", MigrationState,
|
||||||
|
send_configuration, true),
|
||||||
|
DEFINE_PROP_BOOL("send-section-footer", MigrationState,
|
||||||
|
send_section_footer, true),
|
||||||
|
DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
|
||||||
|
decompress_error_check, true),
|
||||||
|
DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
|
||||||
|
multifd_flush_after_each_section, false),
|
||||||
|
DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
|
||||||
|
clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
|
||||||
|
DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
|
||||||
|
preempt_pre_7_2, false),
|
||||||
|
|
||||||
|
/* Migration parameters */
|
||||||
|
DEFINE_PROP_UINT8("x-compress-level", MigrationState,
|
||||||
|
parameters.compress_level,
|
||||||
|
DEFAULT_MIGRATE_COMPRESS_LEVEL),
|
||||||
|
DEFINE_PROP_UINT8("x-compress-threads", MigrationState,
|
||||||
|
parameters.compress_threads,
|
||||||
|
DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT),
|
||||||
|
DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState,
|
||||||
|
parameters.compress_wait_thread, true),
|
||||||
|
DEFINE_PROP_UINT8("x-decompress-threads", MigrationState,
|
||||||
|
parameters.decompress_threads,
|
||||||
|
DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT),
|
||||||
|
DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState,
|
||||||
|
parameters.throttle_trigger_threshold,
|
||||||
|
DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
|
||||||
|
DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState,
|
||||||
|
parameters.cpu_throttle_initial,
|
||||||
|
DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL),
|
||||||
|
DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState,
|
||||||
|
parameters.cpu_throttle_increment,
|
||||||
|
DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
|
||||||
|
DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState,
|
||||||
|
parameters.cpu_throttle_tailslow, false),
|
||||||
|
DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState,
|
||||||
|
parameters.max_bandwidth, MAX_THROTTLE),
|
||||||
|
DEFINE_PROP_UINT64("x-downtime-limit", MigrationState,
|
||||||
|
parameters.downtime_limit,
|
||||||
|
DEFAULT_MIGRATE_SET_DOWNTIME),
|
||||||
|
DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
|
||||||
|
parameters.x_checkpoint_delay,
|
||||||
|
DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
|
||||||
|
DEFINE_PROP_UINT8("multifd-channels", MigrationState,
|
||||||
|
parameters.multifd_channels,
|
||||||
|
DEFAULT_MIGRATE_MULTIFD_CHANNELS),
|
||||||
|
DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState,
|
||||||
|
parameters.multifd_compression,
|
||||||
|
DEFAULT_MIGRATE_MULTIFD_COMPRESSION),
|
||||||
|
DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState,
|
||||||
|
parameters.multifd_zlib_level,
|
||||||
|
DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL),
|
||||||
|
DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState,
|
||||||
|
parameters.multifd_zstd_level,
|
||||||
|
DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL),
|
||||||
|
DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
|
||||||
|
parameters.xbzrle_cache_size,
|
||||||
|
DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
|
||||||
|
DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState,
|
||||||
|
parameters.max_postcopy_bandwidth,
|
||||||
|
DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH),
|
||||||
|
DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState,
|
||||||
|
parameters.max_cpu_throttle,
|
||||||
|
DEFAULT_MIGRATE_MAX_CPU_THROTTLE),
|
||||||
|
DEFINE_PROP_SIZE("announce-initial", MigrationState,
|
||||||
|
parameters.announce_initial,
|
||||||
|
DEFAULT_MIGRATE_ANNOUNCE_INITIAL),
|
||||||
|
DEFINE_PROP_SIZE("announce-max", MigrationState,
|
||||||
|
parameters.announce_max,
|
||||||
|
DEFAULT_MIGRATE_ANNOUNCE_MAX),
|
||||||
|
DEFINE_PROP_SIZE("announce-rounds", MigrationState,
|
||||||
|
parameters.announce_rounds,
|
||||||
|
DEFAULT_MIGRATE_ANNOUNCE_ROUNDS),
|
||||||
|
DEFINE_PROP_SIZE("announce-step", MigrationState,
|
||||||
|
parameters.announce_step,
|
||||||
|
DEFAULT_MIGRATE_ANNOUNCE_STEP),
|
||||||
|
DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds),
|
||||||
|
DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname),
|
||||||
|
DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz),
|
||||||
|
|
||||||
|
/* Migration capabilities */
|
||||||
|
DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-postcopy-preempt",
|
||||||
|
MIGRATION_CAPABILITY_POSTCOPY_PREEMPT),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
|
||||||
|
DEFINE_PROP_MIG_CAP("x-background-snapshot",
|
||||||
|
MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
|
||||||
|
#ifdef CONFIG_LINUX
|
||||||
|
DEFINE_PROP_MIG_CAP("x-zero-copy-send",
|
||||||
|
MIGRATION_CAPABILITY_ZERO_COPY_SEND),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
bool migrate_auto_converge(void)
|
bool migrate_auto_converge(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
|
return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_background_snapshot(void)
|
bool migrate_background_snapshot(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
|
return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_block(void)
|
bool migrate_block(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_BLOCK];
|
return s->capabilities[MIGRATION_CAPABILITY_BLOCK];
|
||||||
}
|
}
|
||||||
@ -61,95 +212,76 @@ bool migrate_block(void)
|
|||||||
bool migrate_colo(void)
|
bool migrate_colo(void)
|
||||||
{
|
{
|
||||||
MigrationState *s = migrate_get_current();
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
|
return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_compress(void)
|
bool migrate_compress(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
|
return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_dirty_bitmaps(void)
|
bool migrate_dirty_bitmaps(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
|
return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_events(void)
|
bool migrate_events(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
|
return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_ignore_shared(void)
|
bool migrate_ignore_shared(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
|
return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_late_block_activate(void)
|
bool migrate_late_block_activate(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
|
return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_multifd(void)
|
bool migrate_multifd(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
|
return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_pause_before_switchover(void)
|
bool migrate_pause_before_switchover(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
|
return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_postcopy_blocktime(void)
|
bool migrate_postcopy_blocktime(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
|
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_postcopy_preempt(void)
|
bool migrate_postcopy_preempt(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
|
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_postcopy_ram(void)
|
bool migrate_postcopy_ram(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
|
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
|
||||||
}
|
}
|
||||||
@ -163,60 +295,55 @@ bool migrate_rdma_pin_all(void)
|
|||||||
|
|
||||||
bool migrate_release_ram(void)
|
bool migrate_release_ram(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
|
return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_return_path(void)
|
bool migrate_return_path(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
|
return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_validate_uuid(void)
|
bool migrate_validate_uuid(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
|
return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_xbzrle(void)
|
bool migrate_xbzrle(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
|
return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_zero_blocks(void)
|
bool migrate_zero_blocks(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
|
return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_zero_copy_send(void)
|
bool migrate_zero_copy_send(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
|
return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pseudo capabilities */
|
/* pseudo capabilities */
|
||||||
|
|
||||||
|
bool migrate_multifd_flush_after_each_section(void)
|
||||||
|
{
|
||||||
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
|
return s->multifd_flush_after_each_section;
|
||||||
|
}
|
||||||
|
|
||||||
bool migrate_postcopy(void)
|
bool migrate_postcopy(void)
|
||||||
{
|
{
|
||||||
return migrate_postcopy_ram() || migrate_dirty_bitmaps();
|
return migrate_postcopy_ram() || migrate_dirty_bitmaps();
|
||||||
@ -224,9 +351,7 @@ bool migrate_postcopy(void)
|
|||||||
|
|
||||||
bool migrate_tls(void)
|
bool migrate_tls(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.tls_creds && *s->parameters.tls_creds;
|
return s->parameters.tls_creds && *s->parameters.tls_creds;
|
||||||
}
|
}
|
||||||
@ -494,128 +619,114 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
|
|||||||
|
|
||||||
/* parameters */
|
/* parameters */
|
||||||
|
|
||||||
|
const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
|
||||||
|
{
|
||||||
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
|
return s->parameters.block_bitmap_mapping;
|
||||||
|
}
|
||||||
|
|
||||||
bool migrate_block_incremental(void)
|
bool migrate_block_incremental(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.block_incremental;
|
return s->parameters.block_incremental;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t migrate_checkpoint_delay(void)
|
uint32_t migrate_checkpoint_delay(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.x_checkpoint_delay;
|
return s->parameters.x_checkpoint_delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
int migrate_compress_level(void)
|
int migrate_compress_level(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.compress_level;
|
return s->parameters.compress_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
int migrate_compress_threads(void)
|
int migrate_compress_threads(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.compress_threads;
|
return s->parameters.compress_threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
int migrate_compress_wait_thread(void)
|
int migrate_compress_wait_thread(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.compress_wait_thread;
|
return s->parameters.compress_wait_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t migrate_cpu_throttle_increment(void)
|
uint8_t migrate_cpu_throttle_increment(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.cpu_throttle_increment;
|
return s->parameters.cpu_throttle_increment;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t migrate_cpu_throttle_initial(void)
|
uint8_t migrate_cpu_throttle_initial(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.cpu_throttle_initial;
|
return s->parameters.cpu_throttle_initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool migrate_cpu_throttle_tailslow(void)
|
bool migrate_cpu_throttle_tailslow(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.cpu_throttle_tailslow;
|
return s->parameters.cpu_throttle_tailslow;
|
||||||
}
|
}
|
||||||
|
|
||||||
int migrate_decompress_threads(void)
|
int migrate_decompress_threads(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.decompress_threads;
|
return s->parameters.decompress_threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t migrate_downtime_limit(void)
|
||||||
|
{
|
||||||
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
|
return s->parameters.downtime_limit;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t migrate_max_cpu_throttle(void)
|
uint8_t migrate_max_cpu_throttle(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.max_cpu_throttle;
|
return s->parameters.max_cpu_throttle;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t migrate_max_bandwidth(void)
|
uint64_t migrate_max_bandwidth(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.max_bandwidth;
|
return s->parameters.max_bandwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t migrate_max_postcopy_bandwidth(void)
|
int64_t migrate_max_postcopy_bandwidth(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.max_postcopy_bandwidth;
|
return s->parameters.max_postcopy_bandwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
int migrate_multifd_channels(void)
|
int migrate_multifd_channels(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.multifd_channels;
|
return s->parameters.multifd_channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiFDCompression migrate_multifd_compression(void)
|
MultiFDCompression migrate_multifd_compression(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
|
assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
|
||||||
return s->parameters.multifd_compression;
|
return s->parameters.multifd_compression;
|
||||||
@ -623,42 +734,76 @@ MultiFDCompression migrate_multifd_compression(void)
|
|||||||
|
|
||||||
int migrate_multifd_zlib_level(void)
|
int migrate_multifd_zlib_level(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.multifd_zlib_level;
|
return s->parameters.multifd_zlib_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
int migrate_multifd_zstd_level(void)
|
int migrate_multifd_zstd_level(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.multifd_zstd_level;
|
return s->parameters.multifd_zstd_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t migrate_throttle_trigger_threshold(void)
|
uint8_t migrate_throttle_trigger_threshold(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.throttle_trigger_threshold;
|
return s->parameters.throttle_trigger_threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *migrate_tls_authz(void)
|
||||||
|
{
|
||||||
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
|
return s->parameters.tls_authz;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *migrate_tls_creds(void)
|
||||||
|
{
|
||||||
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
|
return s->parameters.tls_creds;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *migrate_tls_hostname(void)
|
||||||
|
{
|
||||||
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
|
return s->parameters.tls_hostname;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t migrate_xbzrle_cache_size(void)
|
uint64_t migrate_xbzrle_cache_size(void)
|
||||||
{
|
{
|
||||||
MigrationState *s;
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
s = migrate_get_current();
|
|
||||||
|
|
||||||
return s->parameters.xbzrle_cache_size;
|
return s->parameters.xbzrle_cache_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* parameter setters */
|
||||||
|
|
||||||
|
void migrate_set_block_incremental(bool value)
|
||||||
|
{
|
||||||
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
|
s->parameters.block_incremental = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* parameters helpers */
|
/* parameters helpers */
|
||||||
|
|
||||||
|
void block_cleanup_parameters(void)
|
||||||
|
{
|
||||||
|
MigrationState *s = migrate_get_current();
|
||||||
|
|
||||||
|
if (s->must_remove_block_options) {
|
||||||
|
/* setting to false can never fail */
|
||||||
|
migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort);
|
||||||
|
migrate_set_block_incremental(false);
|
||||||
|
s->must_remove_block_options = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AnnounceParameters *migrate_announce_params(void)
|
AnnounceParameters *migrate_announce_params(void)
|
||||||
{
|
{
|
||||||
static AnnounceParameters ap;
|
static AnnounceParameters ap;
|
||||||
@ -741,6 +886,37 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void migrate_params_init(MigrationParameters *params)
|
||||||
|
{
|
||||||
|
params->tls_hostname = g_strdup("");
|
||||||
|
params->tls_creds = g_strdup("");
|
||||||
|
|
||||||
|
/* Set has_* up only for parameter checks */
|
||||||
|
params->has_compress_level = true;
|
||||||
|
params->has_compress_threads = true;
|
||||||
|
params->has_compress_wait_thread = true;
|
||||||
|
params->has_decompress_threads = true;
|
||||||
|
params->has_throttle_trigger_threshold = true;
|
||||||
|
params->has_cpu_throttle_initial = true;
|
||||||
|
params->has_cpu_throttle_increment = true;
|
||||||
|
params->has_cpu_throttle_tailslow = true;
|
||||||
|
params->has_max_bandwidth = true;
|
||||||
|
params->has_downtime_limit = true;
|
||||||
|
params->has_x_checkpoint_delay = true;
|
||||||
|
params->has_block_incremental = true;
|
||||||
|
params->has_multifd_channels = true;
|
||||||
|
params->has_multifd_compression = true;
|
||||||
|
params->has_multifd_zlib_level = true;
|
||||||
|
params->has_multifd_zstd_level = true;
|
||||||
|
params->has_xbzrle_cache_size = true;
|
||||||
|
params->has_max_postcopy_bandwidth = true;
|
||||||
|
params->has_max_cpu_throttle = true;
|
||||||
|
params->has_announce_initial = true;
|
||||||
|
params->has_announce_max = true;
|
||||||
|
params->has_announce_rounds = true;
|
||||||
|
params->has_announce_step = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether the parameters are valid. Error will be put into errp
|
* Check whether the parameters are valid. Error will be put into errp
|
||||||
* (if provided). Return true if valid, otherwise false.
|
* (if provided). Return true if valid, otherwise false.
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
#ifndef QEMU_MIGRATION_OPTIONS_H
|
#ifndef QEMU_MIGRATION_OPTIONS_H
|
||||||
#define QEMU_MIGRATION_OPTIONS_H
|
#define QEMU_MIGRATION_OPTIONS_H
|
||||||
|
|
||||||
|
#include "hw/qdev-properties.h"
|
||||||
|
#include "hw/qdev-properties-system.h"
|
||||||
|
|
||||||
/* constants */
|
/* constants */
|
||||||
|
|
||||||
/* Amount of time to allocate to each "chunk" of bandwidth-throttled
|
/* Amount of time to allocate to each "chunk" of bandwidth-throttled
|
||||||
@ -21,6 +24,10 @@
|
|||||||
#define BUFFER_DELAY 100
|
#define BUFFER_DELAY 100
|
||||||
#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY)
|
#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY)
|
||||||
|
|
||||||
|
/* migration properties */
|
||||||
|
|
||||||
|
extern Property migration_properties[];
|
||||||
|
|
||||||
/* capabilities */
|
/* capabilities */
|
||||||
|
|
||||||
bool migrate_auto_converge(void);
|
bool migrate_auto_converge(void);
|
||||||
@ -52,6 +59,7 @@ bool migrate_zero_copy_send(void);
|
|||||||
* check, but they are not a capability.
|
* check, but they are not a capability.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool migrate_multifd_flush_after_each_section(void);
|
||||||
bool migrate_postcopy(void);
|
bool migrate_postcopy(void);
|
||||||
bool migrate_tls(void);
|
bool migrate_tls(void);
|
||||||
|
|
||||||
@ -62,6 +70,7 @@ bool migrate_cap_set(int cap, bool value, Error **errp);
|
|||||||
|
|
||||||
/* parameters */
|
/* parameters */
|
||||||
|
|
||||||
|
const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void);
|
||||||
bool migrate_block_incremental(void);
|
bool migrate_block_incremental(void);
|
||||||
uint32_t migrate_checkpoint_delay(void);
|
uint32_t migrate_checkpoint_delay(void);
|
||||||
int migrate_compress_level(void);
|
int migrate_compress_level(void);
|
||||||
@ -71,6 +80,7 @@ uint8_t migrate_cpu_throttle_increment(void);
|
|||||||
uint8_t migrate_cpu_throttle_initial(void);
|
uint8_t migrate_cpu_throttle_initial(void);
|
||||||
bool migrate_cpu_throttle_tailslow(void);
|
bool migrate_cpu_throttle_tailslow(void);
|
||||||
int migrate_decompress_threads(void);
|
int migrate_decompress_threads(void);
|
||||||
|
uint64_t migrate_downtime_limit(void);
|
||||||
uint8_t migrate_max_cpu_throttle(void);
|
uint8_t migrate_max_cpu_throttle(void);
|
||||||
uint64_t migrate_max_bandwidth(void);
|
uint64_t migrate_max_bandwidth(void);
|
||||||
int64_t migrate_max_postcopy_bandwidth(void);
|
int64_t migrate_max_postcopy_bandwidth(void);
|
||||||
@ -79,10 +89,19 @@ MultiFDCompression migrate_multifd_compression(void);
|
|||||||
int migrate_multifd_zlib_level(void);
|
int migrate_multifd_zlib_level(void);
|
||||||
int migrate_multifd_zstd_level(void);
|
int migrate_multifd_zstd_level(void);
|
||||||
uint8_t migrate_throttle_trigger_threshold(void);
|
uint8_t migrate_throttle_trigger_threshold(void);
|
||||||
|
const char *migrate_tls_authz(void);
|
||||||
|
const char *migrate_tls_creds(void);
|
||||||
|
const char *migrate_tls_hostname(void);
|
||||||
uint64_t migrate_xbzrle_cache_size(void);
|
uint64_t migrate_xbzrle_cache_size(void);
|
||||||
|
|
||||||
|
/* parameters setters */
|
||||||
|
|
||||||
|
void migrate_set_block_incremental(bool value);
|
||||||
|
|
||||||
/* parameters helpers */
|
/* parameters helpers */
|
||||||
|
|
||||||
bool migrate_params_check(MigrationParameters *params, Error **errp);
|
bool migrate_params_check(MigrationParameters *params, Error **errp);
|
||||||
|
void migrate_params_init(MigrationParameters *params);
|
||||||
|
void block_cleanup_parameters(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -86,6 +86,7 @@
|
|||||||
#define RAM_SAVE_FLAG_XBZRLE 0x40
|
#define RAM_SAVE_FLAG_XBZRLE 0x40
|
||||||
/* 0x80 is reserved in qemu-file.h for RAM_SAVE_FLAG_HOOK */
|
/* 0x80 is reserved in qemu-file.h for RAM_SAVE_FLAG_HOOK */
|
||||||
#define RAM_SAVE_FLAG_COMPRESS_PAGE 0x100
|
#define RAM_SAVE_FLAG_COMPRESS_PAGE 0x100
|
||||||
|
#define RAM_SAVE_FLAG_MULTIFD_FLUSH 0x200
|
||||||
/* We can't use any flag that is bigger than 0x200 */
|
/* We can't use any flag that is bigger than 0x200 */
|
||||||
|
|
||||||
int (*xbzrle_encode_buffer_func)(uint8_t *, uint8_t *, int,
|
int (*xbzrle_encode_buffer_func)(uint8_t *, uint8_t *, int,
|
||||||
@ -1129,8 +1130,9 @@ static void migration_update_rates(RAMState *rs, int64_t end_time)
|
|||||||
double compressed_size;
|
double compressed_size;
|
||||||
|
|
||||||
/* calculate period counters */
|
/* calculate period counters */
|
||||||
ram_counters.dirty_pages_rate = rs->num_dirty_pages_period * 1000
|
stat64_set(&ram_counters.dirty_pages_rate,
|
||||||
/ (end_time - rs->time_last_bitmap_sync);
|
rs->num_dirty_pages_period * 1000 /
|
||||||
|
(end_time - rs->time_last_bitmap_sync));
|
||||||
|
|
||||||
if (!page_count) {
|
if (!page_count) {
|
||||||
return;
|
return;
|
||||||
@ -1222,7 +1224,7 @@ static void migration_bitmap_sync(RAMState *rs)
|
|||||||
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
||||||
ramblock_sync_dirty_bitmap(rs, block);
|
ramblock_sync_dirty_bitmap(rs, block);
|
||||||
}
|
}
|
||||||
ram_counters.remaining = ram_bytes_remaining();
|
stat64_set(&ram_counters.dirty_bytes_last_sync, ram_bytes_remaining());
|
||||||
}
|
}
|
||||||
qemu_mutex_unlock(&rs->bitmap_mutex);
|
qemu_mutex_unlock(&rs->bitmap_mutex);
|
||||||
|
|
||||||
@ -1581,6 +1583,7 @@ retry:
|
|||||||
* associated with the search process.
|
* associated with the search process.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
|
* <0: An error happened
|
||||||
* PAGE_ALL_CLEAN: no dirty page found, give up
|
* PAGE_ALL_CLEAN: no dirty page found, give up
|
||||||
* PAGE_TRY_AGAIN: no dirty page found, retry for next block
|
* PAGE_TRY_AGAIN: no dirty page found, retry for next block
|
||||||
* PAGE_DIRTY_FOUND: dirty page found
|
* PAGE_DIRTY_FOUND: dirty page found
|
||||||
@ -1608,6 +1611,15 @@ static int find_dirty_block(RAMState *rs, PageSearchStatus *pss)
|
|||||||
pss->page = 0;
|
pss->page = 0;
|
||||||
pss->block = QLIST_NEXT_RCU(pss->block, next);
|
pss->block = QLIST_NEXT_RCU(pss->block, next);
|
||||||
if (!pss->block) {
|
if (!pss->block) {
|
||||||
|
if (!migrate_multifd_flush_after_each_section()) {
|
||||||
|
QEMUFile *f = rs->pss[RAM_CHANNEL_PRECOPY].pss_channel;
|
||||||
|
int ret = multifd_send_sync_main(f);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
|
||||||
|
qemu_fflush(f);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* If memory migration starts over, we will meet a dirtied page
|
* If memory migration starts over, we will meet a dirtied page
|
||||||
* which may still exists in compression threads's ring, so we
|
* which may still exists in compression threads's ring, so we
|
||||||
@ -2600,6 +2612,9 @@ static int ram_find_and_save_block(RAMState *rs)
|
|||||||
break;
|
break;
|
||||||
} else if (res == PAGE_TRY_AGAIN) {
|
} else if (res == PAGE_TRY_AGAIN) {
|
||||||
continue;
|
continue;
|
||||||
|
} else if (res < 0) {
|
||||||
|
pages = res;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3286,6 +3301,10 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!migrate_multifd_flush_after_each_section()) {
|
||||||
|
qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||||
qemu_fflush(f);
|
qemu_fflush(f);
|
||||||
|
|
||||||
@ -3394,9 +3413,11 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
|
|||||||
out:
|
out:
|
||||||
if (ret >= 0
|
if (ret >= 0
|
||||||
&& migration_is_setup_or_active(migrate_get_current()->state)) {
|
&& migration_is_setup_or_active(migrate_get_current()->state)) {
|
||||||
ret = multifd_send_sync_main(rs->pss[RAM_CHANNEL_PRECOPY].pss_channel);
|
if (migrate_multifd_flush_after_each_section()) {
|
||||||
if (ret < 0) {
|
ret = multifd_send_sync_main(rs->pss[RAM_CHANNEL_PRECOPY].pss_channel);
|
||||||
return ret;
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||||
@ -3469,6 +3490,9 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!migrate_multifd_flush_after_each_section()) {
|
||||||
|
qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
|
||||||
|
}
|
||||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||||
qemu_fflush(f);
|
qemu_fflush(f);
|
||||||
|
|
||||||
@ -4150,10 +4174,14 @@ int ram_load_postcopy(QEMUFile *f, int channel)
|
|||||||
}
|
}
|
||||||
decompress_data_with_multi_threads(f, page_buffer, len);
|
decompress_data_with_multi_threads(f, page_buffer, len);
|
||||||
break;
|
break;
|
||||||
|
case RAM_SAVE_FLAG_MULTIFD_FLUSH:
|
||||||
|
multifd_recv_sync_main();
|
||||||
|
break;
|
||||||
case RAM_SAVE_FLAG_EOS:
|
case RAM_SAVE_FLAG_EOS:
|
||||||
/* normal exit */
|
/* normal exit */
|
||||||
multifd_recv_sync_main();
|
if (migrate_multifd_flush_after_each_section()) {
|
||||||
|
multifd_recv_sync_main();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error_report("Unknown combination of migration flags: 0x%x"
|
error_report("Unknown combination of migration flags: 0x%x"
|
||||||
@ -4422,9 +4450,14 @@ static int ram_load_precopy(QEMUFile *f)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RAM_SAVE_FLAG_MULTIFD_FLUSH:
|
||||||
|
multifd_recv_sync_main();
|
||||||
|
break;
|
||||||
case RAM_SAVE_FLAG_EOS:
|
case RAM_SAVE_FLAG_EOS:
|
||||||
/* normal exit */
|
/* normal exit */
|
||||||
multifd_recv_sync_main();
|
if (migrate_multifd_flush_after_each_section()) {
|
||||||
|
multifd_recv_sync_main();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (flags & RAM_SAVE_FLAG_HOOK) {
|
if (flags & RAM_SAVE_FLAG_HOOK) {
|
||||||
|
@ -41,7 +41,8 @@
|
|||||||
* one thread).
|
* one thread).
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t dirty_pages_rate;
|
Stat64 dirty_bytes_last_sync;
|
||||||
|
Stat64 dirty_pages_rate;
|
||||||
Stat64 dirty_sync_count;
|
Stat64 dirty_sync_count;
|
||||||
Stat64 dirty_sync_missed_zero_copy;
|
Stat64 dirty_sync_missed_zero_copy;
|
||||||
Stat64 downtime_bytes;
|
Stat64 downtime_bytes;
|
||||||
@ -51,7 +52,6 @@ typedef struct {
|
|||||||
Stat64 postcopy_bytes;
|
Stat64 postcopy_bytes;
|
||||||
Stat64 postcopy_requests;
|
Stat64 postcopy_requests;
|
||||||
Stat64 precopy_bytes;
|
Stat64 precopy_bytes;
|
||||||
int64_t remaining;
|
|
||||||
Stat64 transferred;
|
Stat64 transferred;
|
||||||
} RAMStats;
|
} RAMStats;
|
||||||
|
|
||||||
|
@ -34,20 +34,19 @@ migration_tls_get_creds(MigrationState *s,
|
|||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
Object *creds;
|
Object *creds;
|
||||||
|
const char *tls_creds = migrate_tls_creds();
|
||||||
QCryptoTLSCreds *ret;
|
QCryptoTLSCreds *ret;
|
||||||
|
|
||||||
creds = object_resolve_path_component(
|
creds = object_resolve_path_component(object_get_objects_root(), tls_creds);
|
||||||
object_get_objects_root(), s->parameters.tls_creds);
|
|
||||||
if (!creds) {
|
if (!creds) {
|
||||||
error_setg(errp, "No TLS credentials with id '%s'",
|
error_setg(errp, "No TLS credentials with id '%s'", tls_creds);
|
||||||
s->parameters.tls_creds);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ret = (QCryptoTLSCreds *)object_dynamic_cast(
|
ret = (QCryptoTLSCreds *)object_dynamic_cast(
|
||||||
creds, TYPE_QCRYPTO_TLS_CREDS);
|
creds, TYPE_QCRYPTO_TLS_CREDS);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
error_setg(errp, "Object with id '%s' is not TLS credentials",
|
error_setg(errp, "Object with id '%s' is not TLS credentials",
|
||||||
s->parameters.tls_creds);
|
tls_creds);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!qcrypto_tls_creds_check_endpoint(ret, endpoint, errp)) {
|
if (!qcrypto_tls_creds_check_endpoint(ret, endpoint, errp)) {
|
||||||
@ -87,10 +86,7 @@ void migration_tls_channel_process_incoming(MigrationState *s,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tioc = qio_channel_tls_new_server(
|
tioc = qio_channel_tls_new_server(ioc, creds, migrate_tls_authz(), errp);
|
||||||
ioc, creds,
|
|
||||||
s->parameters.tls_authz,
|
|
||||||
errp);
|
|
||||||
if (!tioc) {
|
if (!tioc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -134,8 +130,9 @@ QIOChannelTLS *migration_tls_client_create(MigrationState *s,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->parameters.tls_hostname && *s->parameters.tls_hostname) {
|
const char *tls_hostname = migrate_tls_hostname();
|
||||||
hostname = s->parameters.tls_hostname;
|
if (tls_hostname && *tls_hostname) {
|
||||||
|
hostname = tls_hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
return qio_channel_tls_new_client(ioc, creds, hostname, errp);
|
return qio_channel_tls_new_client(ioc, creds, hostname, errp);
|
||||||
|
@ -57,6 +57,17 @@ uint64_t stat64_get(const Stat64 *s)
|
|||||||
return ((uint64_t)high << 32) | low;
|
return ((uint64_t)high << 32) | low;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stat64_set(Stat64 *s, uint64_t val)
|
||||||
|
{
|
||||||
|
while (!stat64_wrtrylock(s)) {
|
||||||
|
cpu_relax();
|
||||||
|
}
|
||||||
|
|
||||||
|
qatomic_set(&s->high, val >> 32);
|
||||||
|
qatomic_set(&s->low, val);
|
||||||
|
stat64_wrunlock(s);
|
||||||
|
}
|
||||||
|
|
||||||
bool stat64_add32_carry(Stat64 *s, uint32_t low, uint32_t high)
|
bool stat64_add32_carry(Stat64 *s, uint32_t low, uint32_t high)
|
||||||
{
|
{
|
||||||
uint32_t old;
|
uint32_t old;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user