mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
Pull request
- Rebase last pull request - Drop multifd - several other minor fixesLaLaLa -----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJcmRP1AAoJEPSH7xhYctcjVDcP/iZoCgMDn0BVzYFamRAIvtlh 1h1ElV+Jx49bHRvDRs0RaTSIlowqnbMY5yiTfn0L7aSbOr8KLEbs+i+jo5moF3+Q 50TNxGTDF/WWvl+z8X3WljwDPYBnG7mYeDBNBk+8V2RI/DvV2uAdm29VPmPN/Kc8 hW8S6kXRAQekkkt0BOkXHXWQlmvzHS9RqQoZ0dETP9GqcT7cJ6HDZJu8akiz6Oz3 r0Hek41EVQirjfKL+Sm5BluiiuvNcdFGsYK/TqLiCpnHolNUboMnIhXiTX2BJRf7 TEK8UGrbgXa3SarszCBxjsjMFYRJlq6Vi7ZQ54Ly7+wFr09jhIDgt9AlEr0YjOj4 8AgGF6nKYmFahQuKvJ1xMrgY3EccBDWXJKBwcnnd5zMJyVGlNtUUs7f7pSA3V/oG wEDMzmxcpKxK3A9jpPBgEN4ev0oKaR+rxAdy5NPTU7kMZV651JXt2pOirGm5AL2V soKiiSklUZ7VpJ998PnGj7pO4LL8xWW3Pi4mzlH6dv+Aw9T2L9vY8rPFEktOJ4V5 8qB9PERlAG/KbpVH2lrkUFFk4sfxBmVTG+SppwCk4I6/eSaDuO3pjXcuwiFaIyqT kHLsBVT0kLEYeE6zty2YHvjIEmAyaJxr2HezWquQ9xQOezDl1s3wjVGRFJ6xZDKn uMHI4j2i5UWA8B73inh0 =kjyq -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/juanquintela/tags/migration-pull-request' into staging Pull request - Rebase last pull request - Drop multifd - several other minor fixesLaLaLa # gpg: Signature made Mon 25 Mar 2019 17:46:29 GMT # gpg: using RSA key F487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [full] # gpg: aka "Juan Quintela <quintela@trasno.org>" [full] # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * remotes/juanquintela/tags/migration-pull-request: migration/postcopy: Update the bandwidth during postcopy Migration/colo.c: Make user obtain the last COLO mode info after failover Migration/colo.c: Add the necessary checks for colo_do_failover Migration/colo.c: Add new COLOExitReason to handle all failover state Migration/colo.c: Fix COLO failover status error migration/rdma: Check qemu_rdma_init_one_block migration: add support for a "tls-authz" migration parameter multifd: Drop x- multifd: Add some padding multifd: Change default packet size multifd: Be flexible about packet size multifd: Drop x-multifd-page-count parameter multifd: Create new next_packet_size field multifd: Rename "size" member to pages_alloc multifd: Only send pages when packet are not empty Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
7e9a2137ce
26
hmp.c
26
hmp.c
@ -433,17 +433,17 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
|
||||
MigrationParameter_str(MIGRATION_PARAMETER_BLOCK_INCREMENTAL),
|
||||
params->block_incremental ? "on" : "off");
|
||||
monitor_printf(mon, "%s: %u\n",
|
||||
MigrationParameter_str(MIGRATION_PARAMETER_X_MULTIFD_CHANNELS),
|
||||
params->x_multifd_channels);
|
||||
monitor_printf(mon, "%s: %u\n",
|
||||
MigrationParameter_str(MIGRATION_PARAMETER_X_MULTIFD_PAGE_COUNT),
|
||||
params->x_multifd_page_count);
|
||||
MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
|
||||
params->multifd_channels);
|
||||
monitor_printf(mon, "%s: %" PRIu64 "\n",
|
||||
MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
|
||||
params->xbzrle_cache_size);
|
||||
monitor_printf(mon, "%s: %" PRIu64 "\n",
|
||||
MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
|
||||
params->max_postcopy_bandwidth);
|
||||
monitor_printf(mon, " %s: '%s'\n",
|
||||
MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
|
||||
params->has_tls_authz ? params->tls_authz : "");
|
||||
}
|
||||
|
||||
qapi_free_MigrationParameters(params);
|
||||
@ -1786,6 +1786,12 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
|
||||
p->tls_hostname->type = QTYPE_QSTRING;
|
||||
visit_type_str(v, param, &p->tls_hostname->u.s, &err);
|
||||
break;
|
||||
case MIGRATION_PARAMETER_TLS_AUTHZ:
|
||||
p->has_tls_authz = true;
|
||||
p->tls_authz = g_new0(StrOrNull, 1);
|
||||
p->tls_authz->type = QTYPE_QSTRING;
|
||||
visit_type_str(v, param, &p->tls_authz->u.s, &err);
|
||||
break;
|
||||
case MIGRATION_PARAMETER_MAX_BANDWIDTH:
|
||||
p->has_max_bandwidth = true;
|
||||
/*
|
||||
@ -1812,13 +1818,9 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
|
||||
p->has_block_incremental = true;
|
||||
visit_type_bool(v, param, &p->block_incremental, &err);
|
||||
break;
|
||||
case MIGRATION_PARAMETER_X_MULTIFD_CHANNELS:
|
||||
p->has_x_multifd_channels = true;
|
||||
visit_type_int(v, param, &p->x_multifd_channels, &err);
|
||||
break;
|
||||
case MIGRATION_PARAMETER_X_MULTIFD_PAGE_COUNT:
|
||||
p->has_x_multifd_page_count = true;
|
||||
visit_type_int(v, param, &p->x_multifd_page_count, &err);
|
||||
case MIGRATION_PARAMETER_MULTIFD_CHANNELS:
|
||||
p->has_multifd_channels = true;
|
||||
visit_type_int(v, param, &p->multifd_channels, &err);
|
||||
break;
|
||||
case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
|
||||
p->has_xbzrle_cache_size = true;
|
||||
|
@ -38,6 +38,9 @@
|
||||
static bool vmstate_loading;
|
||||
static Notifier packets_compare_notifier;
|
||||
|
||||
/* User need to know colo mode after COLO failover */
|
||||
static COLOMode last_colo_mode;
|
||||
|
||||
#define COLO_BUFFER_BASE_SIZE (4 * 1024 * 1024)
|
||||
|
||||
bool migration_in_colo_state(void)
|
||||
@ -121,6 +124,7 @@ static void secondary_vm_do_failover(void)
|
||||
}
|
||||
/* Notify COLO incoming thread that failover work is finished */
|
||||
qemu_sem_post(&mis->colo_incoming_sem);
|
||||
|
||||
/* For Secondary VM, jump to incoming co */
|
||||
if (mis->migration_incoming_co) {
|
||||
qemu_coroutine_enter(mis->migration_incoming_co);
|
||||
@ -196,10 +200,16 @@ void colo_do_failover(MigrationState *s)
|
||||
vm_stop_force_state(RUN_STATE_COLO);
|
||||
}
|
||||
|
||||
if (get_colo_mode() == COLO_MODE_PRIMARY) {
|
||||
switch (get_colo_mode()) {
|
||||
case COLO_MODE_PRIMARY:
|
||||
primary_vm_do_failover();
|
||||
} else {
|
||||
break;
|
||||
case COLO_MODE_SECONDARY:
|
||||
secondary_vm_do_failover();
|
||||
break;
|
||||
default:
|
||||
error_report("colo_do_failover failed because the colo mode"
|
||||
" could not be obtained");
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,16 +267,21 @@ COLOStatus *qmp_query_colo_status(Error **errp)
|
||||
COLOStatus *s = g_new0(COLOStatus, 1);
|
||||
|
||||
s->mode = get_colo_mode();
|
||||
s->last_mode = last_colo_mode;
|
||||
|
||||
switch (failover_get_state()) {
|
||||
case FAILOVER_STATUS_NONE:
|
||||
s->reason = COLO_EXIT_REASON_NONE;
|
||||
break;
|
||||
case FAILOVER_STATUS_REQUIRE:
|
||||
case FAILOVER_STATUS_COMPLETED:
|
||||
s->reason = COLO_EXIT_REASON_REQUEST;
|
||||
break;
|
||||
default:
|
||||
s->reason = COLO_EXIT_REASON_ERROR;
|
||||
if (migration_in_colo_state()) {
|
||||
s->reason = COLO_EXIT_REASON_PROCESSING;
|
||||
} else {
|
||||
s->reason = COLO_EXIT_REASON_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
@ -504,6 +519,12 @@ static void colo_process_checkpoint(MigrationState *s)
|
||||
Error *local_err = NULL;
|
||||
int ret;
|
||||
|
||||
last_colo_mode = get_colo_mode();
|
||||
if (last_colo_mode != COLO_MODE_PRIMARY) {
|
||||
error_report("COLO mode must be COLO_MODE_PRIMARY");
|
||||
return;
|
||||
}
|
||||
|
||||
failover_init_state();
|
||||
|
||||
s->rp_state.from_dst_file = qemu_file_get_return_path(s->to_dst_file);
|
||||
@ -578,16 +599,13 @@ out:
|
||||
* or the user triggered failover.
|
||||
*/
|
||||
switch (failover_get_state()) {
|
||||
case FAILOVER_STATUS_NONE:
|
||||
qapi_event_send_colo_exit(COLO_MODE_PRIMARY,
|
||||
COLO_EXIT_REASON_ERROR);
|
||||
break;
|
||||
case FAILOVER_STATUS_REQUIRE:
|
||||
case FAILOVER_STATUS_COMPLETED:
|
||||
qapi_event_send_colo_exit(COLO_MODE_PRIMARY,
|
||||
COLO_EXIT_REASON_REQUEST);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
qapi_event_send_colo_exit(COLO_MODE_PRIMARY,
|
||||
COLO_EXIT_REASON_ERROR);
|
||||
}
|
||||
|
||||
/* Hope this not to be too long to wait here */
|
||||
@ -680,6 +698,12 @@ void *colo_process_incoming_thread(void *opaque)
|
||||
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
|
||||
MIGRATION_STATUS_COLO);
|
||||
|
||||
last_colo_mode = get_colo_mode();
|
||||
if (last_colo_mode != COLO_MODE_SECONDARY) {
|
||||
error_report("COLO mode must be COLO_MODE_SECONDARY");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
failover_init_state();
|
||||
|
||||
mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
|
||||
@ -849,17 +873,18 @@ out:
|
||||
error_report_err(local_err);
|
||||
}
|
||||
|
||||
/*
|
||||
* There are only two reasons we can get here, some error happened
|
||||
* or the user triggered failover.
|
||||
*/
|
||||
switch (failover_get_state()) {
|
||||
case FAILOVER_STATUS_NONE:
|
||||
qapi_event_send_colo_exit(COLO_MODE_SECONDARY,
|
||||
COLO_EXIT_REASON_ERROR);
|
||||
break;
|
||||
case FAILOVER_STATUS_REQUIRE:
|
||||
case FAILOVER_STATUS_COMPLETED:
|
||||
qapi_event_send_colo_exit(COLO_MODE_SECONDARY,
|
||||
COLO_EXIT_REASON_REQUEST);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
qapi_event_send_colo_exit(COLO_MODE_SECONDARY,
|
||||
COLO_EXIT_REASON_ERROR);
|
||||
}
|
||||
|
||||
if (fb) {
|
||||
|
@ -82,7 +82,6 @@
|
||||
/* 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_PAGE_COUNT 16
|
||||
|
||||
/* Background transfer rate for postcopy, 0 means unlimited, note
|
||||
* that page requests can still exceed this limit.
|
||||
@ -758,6 +757,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
|
||||
params->tls_creds = g_strdup(s->parameters.tls_creds);
|
||||
params->has_tls_hostname = true;
|
||||
params->tls_hostname = g_strdup(s->parameters.tls_hostname);
|
||||
params->has_tls_authz = true;
|
||||
params->tls_authz = g_strdup(s->parameters.tls_authz);
|
||||
params->has_max_bandwidth = true;
|
||||
params->max_bandwidth = s->parameters.max_bandwidth;
|
||||
params->has_downtime_limit = true;
|
||||
@ -766,10 +767,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
|
||||
params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
|
||||
params->has_block_incremental = true;
|
||||
params->block_incremental = s->parameters.block_incremental;
|
||||
params->has_x_multifd_channels = true;
|
||||
params->x_multifd_channels = s->parameters.x_multifd_channels;
|
||||
params->has_x_multifd_page_count = true;
|
||||
params->x_multifd_page_count = s->parameters.x_multifd_page_count;
|
||||
params->has_multifd_channels = true;
|
||||
params->multifd_channels = s->parameters.multifd_channels;
|
||||
params->has_xbzrle_cache_size = true;
|
||||
params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
|
||||
params->has_max_postcopy_bandwidth = true;
|
||||
@ -1152,20 +1151,12 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp)
|
||||
|
||||
/* x_checkpoint_delay is now always positive */
|
||||
|
||||
if (params->has_x_multifd_channels && (params->x_multifd_channels < 1)) {
|
||||
if (params->has_multifd_channels && (params->multifd_channels < 1)) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
||||
"multifd_channels",
|
||||
"is invalid, it should be in the range of 1 to 255");
|
||||
return false;
|
||||
}
|
||||
if (params->has_x_multifd_page_count &&
|
||||
(params->x_multifd_page_count < 1 ||
|
||||
params->x_multifd_page_count > 10000)) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
||||
"multifd_page_count",
|
||||
"is invalid, it should be in the range of 1 to 10000");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (params->has_xbzrle_cache_size &&
|
||||
(params->xbzrle_cache_size < qemu_target_page_size() ||
|
||||
@ -1274,11 +1265,8 @@ static void migrate_params_test_apply(MigrateSetParameters *params,
|
||||
if (params->has_block_incremental) {
|
||||
dest->block_incremental = params->block_incremental;
|
||||
}
|
||||
if (params->has_x_multifd_channels) {
|
||||
dest->x_multifd_channels = params->x_multifd_channels;
|
||||
}
|
||||
if (params->has_x_multifd_page_count) {
|
||||
dest->x_multifd_page_count = params->x_multifd_page_count;
|
||||
if (params->has_multifd_channels) {
|
||||
dest->multifd_channels = params->multifd_channels;
|
||||
}
|
||||
if (params->has_xbzrle_cache_size) {
|
||||
dest->xbzrle_cache_size = params->xbzrle_cache_size;
|
||||
@ -1345,9 +1333,15 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
|
||||
s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
|
||||
}
|
||||
|
||||
if (params->has_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) {
|
||||
if (s->to_dst_file && !migration_in_postcopy()) {
|
||||
qemu_file_set_rate_limit(s->to_dst_file,
|
||||
s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
|
||||
}
|
||||
@ -1367,11 +1361,8 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
|
||||
if (params->has_block_incremental) {
|
||||
s->parameters.block_incremental = params->block_incremental;
|
||||
}
|
||||
if (params->has_x_multifd_channels) {
|
||||
s->parameters.x_multifd_channels = params->x_multifd_channels;
|
||||
}
|
||||
if (params->has_x_multifd_page_count) {
|
||||
s->parameters.x_multifd_page_count = params->x_multifd_page_count;
|
||||
if (params->has_multifd_channels) {
|
||||
s->parameters.multifd_channels = params->multifd_channels;
|
||||
}
|
||||
if (params->has_xbzrle_cache_size) {
|
||||
s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
|
||||
@ -1379,6 +1370,10 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **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;
|
||||
@ -2130,7 +2125,7 @@ bool migrate_use_multifd(void)
|
||||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_X_MULTIFD];
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_MULTIFD];
|
||||
}
|
||||
|
||||
bool migrate_pause_before_switchover(void)
|
||||
@ -2149,16 +2144,7 @@ int migrate_multifd_channels(void)
|
||||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->parameters.x_multifd_channels;
|
||||
}
|
||||
|
||||
int migrate_multifd_page_count(void)
|
||||
{
|
||||
MigrationState *s;
|
||||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->parameters.x_multifd_page_count;
|
||||
return s->parameters.multifd_channels;
|
||||
}
|
||||
|
||||
int migrate_use_xbzrle(void)
|
||||
@ -3400,12 +3386,9 @@ static Property migration_properties[] = {
|
||||
DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
|
||||
parameters.x_checkpoint_delay,
|
||||
DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
|
||||
DEFINE_PROP_UINT8("x-multifd-channels", MigrationState,
|
||||
parameters.x_multifd_channels,
|
||||
DEFINE_PROP_UINT8("multifd-channels", MigrationState,
|
||||
parameters.multifd_channels,
|
||||
DEFAULT_MIGRATE_MULTIFD_CHANNELS),
|
||||
DEFINE_PROP_UINT32("x-multifd-page-count", MigrationState,
|
||||
parameters.x_multifd_page_count,
|
||||
DEFAULT_MIGRATE_MULTIFD_PAGE_COUNT),
|
||||
DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
|
||||
parameters.xbzrle_cache_size,
|
||||
DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
|
||||
@ -3440,7 +3423,7 @@ static Property migration_properties[] = {
|
||||
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_X_MULTIFD),
|
||||
DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
|
||||
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
@ -3494,8 +3477,7 @@ static void migration_instance_init(Object *obj)
|
||||
params->has_downtime_limit = true;
|
||||
params->has_x_checkpoint_delay = true;
|
||||
params->has_block_incremental = true;
|
||||
params->has_x_multifd_channels = true;
|
||||
params->has_x_multifd_page_count = true;
|
||||
params->has_multifd_channels = true;
|
||||
params->has_xbzrle_cache_size = true;
|
||||
params->has_max_postcopy_bandwidth = true;
|
||||
params->has_max_cpu_throttle = true;
|
||||
|
@ -274,7 +274,6 @@ bool migrate_auto_converge(void);
|
||||
bool migrate_use_multifd(void);
|
||||
bool migrate_pause_before_switchover(void);
|
||||
int migrate_multifd_channels(void);
|
||||
int migrate_multifd_page_count(void);
|
||||
|
||||
int migrate_use_xbzrle(void);
|
||||
int64_t migrate_xbzrle_cache_size(void);
|
||||
|
@ -583,20 +583,29 @@ exit:
|
||||
|
||||
#define MULTIFD_FLAG_SYNC (1 << 0)
|
||||
|
||||
/* This value needs to be a multiple of qemu_target_page_size() */
|
||||
#define MULTIFD_PACKET_SIZE (512 * 1024)
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
unsigned char uuid[16]; /* QemuUUID */
|
||||
uint8_t id;
|
||||
uint8_t unused1[7]; /* Reserved for future use */
|
||||
uint64_t unused2[4]; /* Reserved for future use */
|
||||
} __attribute__((packed)) MultiFDInit_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint32_t flags;
|
||||
uint32_t size;
|
||||
uint32_t used;
|
||||
/* maximum number of allocated pages */
|
||||
uint32_t pages_alloc;
|
||||
uint32_t pages_used;
|
||||
/* size of the next packet that contains pages */
|
||||
uint32_t next_packet_size;
|
||||
uint64_t packet_num;
|
||||
uint64_t unused[4]; /* Reserved for future use */
|
||||
char ramblock[256];
|
||||
uint64_t offset[];
|
||||
} __attribute__((packed)) MultiFDPacket_t;
|
||||
@ -643,6 +652,8 @@ typedef struct {
|
||||
MultiFDPacket_t *packet;
|
||||
/* multifd flags for each packet */
|
||||
uint32_t flags;
|
||||
/* size of the next packet that contains pages */
|
||||
uint32_t next_packet_size;
|
||||
/* global number of generated multifd packets */
|
||||
uint64_t packet_num;
|
||||
/* thread local variables */
|
||||
@ -679,6 +690,8 @@ typedef struct {
|
||||
/* global number of generated multifd packets */
|
||||
uint64_t packet_num;
|
||||
/* thread local variables */
|
||||
/* size of the next packet that contains pages */
|
||||
uint32_t next_packet_size;
|
||||
/* packets sent through this channel */
|
||||
uint64_t num_packets;
|
||||
/* pages sent through this channel */
|
||||
@ -776,13 +789,15 @@ static void multifd_pages_clear(MultiFDPages_t *pages)
|
||||
static void multifd_send_fill_packet(MultiFDSendParams *p)
|
||||
{
|
||||
MultiFDPacket_t *packet = p->packet;
|
||||
uint32_t page_max = MULTIFD_PACKET_SIZE / qemu_target_page_size();
|
||||
int i;
|
||||
|
||||
packet->magic = cpu_to_be32(MULTIFD_MAGIC);
|
||||
packet->version = cpu_to_be32(MULTIFD_VERSION);
|
||||
packet->flags = cpu_to_be32(p->flags);
|
||||
packet->size = cpu_to_be32(migrate_multifd_page_count());
|
||||
packet->used = cpu_to_be32(p->pages->used);
|
||||
packet->pages_alloc = cpu_to_be32(page_max);
|
||||
packet->pages_used = cpu_to_be32(p->pages->used);
|
||||
packet->next_packet_size = cpu_to_be32(p->next_packet_size);
|
||||
packet->packet_num = cpu_to_be64(p->packet_num);
|
||||
|
||||
if (p->pages->block) {
|
||||
@ -797,6 +812,7 @@ static void multifd_send_fill_packet(MultiFDSendParams *p)
|
||||
static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
|
||||
{
|
||||
MultiFDPacket_t *packet = p->packet;
|
||||
uint32_t pages_max = MULTIFD_PACKET_SIZE / qemu_target_page_size();
|
||||
RAMBlock *block;
|
||||
int i;
|
||||
|
||||
@ -818,22 +834,35 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
|
||||
|
||||
p->flags = be32_to_cpu(packet->flags);
|
||||
|
||||
packet->size = be32_to_cpu(packet->size);
|
||||
if (packet->size > migrate_multifd_page_count()) {
|
||||
packet->pages_alloc = be32_to_cpu(packet->pages_alloc);
|
||||
/*
|
||||
* If we recevied a packet that is 100 times bigger than expected
|
||||
* just stop migration. It is a magic number.
|
||||
*/
|
||||
if (packet->pages_alloc > pages_max * 100) {
|
||||
error_setg(errp, "multifd: received packet "
|
||||
"with size %d and expected maximum size %d",
|
||||
packet->size, migrate_multifd_page_count()) ;
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->pages->used = be32_to_cpu(packet->used);
|
||||
if (p->pages->used > packet->size) {
|
||||
error_setg(errp, "multifd: received packet "
|
||||
"with size %d and expected maximum size %d",
|
||||
p->pages->used, packet->size) ;
|
||||
"with size %d and expected a maximum size of %d",
|
||||
packet->pages_alloc, pages_max * 100) ;
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* We received a packet that is bigger than expected but inside
|
||||
* reasonable limits (see previous comment). Just reallocate.
|
||||
*/
|
||||
if (packet->pages_alloc > p->pages->allocated) {
|
||||
multifd_pages_clear(p->pages);
|
||||
multifd_pages_init(packet->pages_alloc);
|
||||
}
|
||||
|
||||
p->pages->used = be32_to_cpu(packet->pages_used);
|
||||
if (p->pages->used > packet->pages_alloc) {
|
||||
error_setg(errp, "multifd: received packet "
|
||||
"with %d pages and expected maximum pages are %d",
|
||||
p->pages->used, packet->pages_alloc) ;
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->next_packet_size = be32_to_cpu(packet->next_packet_size);
|
||||
p->packet_num = be64_to_cpu(packet->packet_num);
|
||||
|
||||
if (p->pages->used) {
|
||||
@ -1073,6 +1102,7 @@ static void *multifd_send_thread(void *opaque)
|
||||
uint64_t packet_num = p->packet_num;
|
||||
uint32_t flags = p->flags;
|
||||
|
||||
p->next_packet_size = used * qemu_target_page_size();
|
||||
multifd_send_fill_packet(p);
|
||||
p->flags = 0;
|
||||
p->num_packets++;
|
||||
@ -1080,7 +1110,8 @@ static void *multifd_send_thread(void *opaque)
|
||||
p->pages->used = 0;
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
|
||||
trace_multifd_send(p->id, packet_num, used, flags);
|
||||
trace_multifd_send(p->id, packet_num, used, flags,
|
||||
p->next_packet_size);
|
||||
|
||||
ret = qio_channel_write_all(p->c, (void *)p->packet,
|
||||
p->packet_len, &local_err);
|
||||
@ -1088,9 +1119,12 @@ static void *multifd_send_thread(void *opaque)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = qio_channel_writev_all(p->c, p->pages->iov, used, &local_err);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
if (used) {
|
||||
ret = qio_channel_writev_all(p->c, p->pages->iov,
|
||||
used, &local_err);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qemu_mutex_lock(&p->mutex);
|
||||
@ -1148,7 +1182,7 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
|
||||
int multifd_save_setup(void)
|
||||
{
|
||||
int thread_count;
|
||||
uint32_t page_count = migrate_multifd_page_count();
|
||||
uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size();
|
||||
uint8_t i;
|
||||
|
||||
if (!migrate_use_multifd()) {
|
||||
@ -1312,14 +1346,18 @@ static void *multifd_recv_thread(void *opaque)
|
||||
|
||||
used = p->pages->used;
|
||||
flags = p->flags;
|
||||
trace_multifd_recv(p->id, p->packet_num, used, flags);
|
||||
trace_multifd_recv(p->id, p->packet_num, used, flags,
|
||||
p->next_packet_size);
|
||||
p->num_packets++;
|
||||
p->num_pages += used;
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
|
||||
ret = qio_channel_readv_all(p->c, p->pages->iov, used, &local_err);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
if (used) {
|
||||
ret = qio_channel_readv_all(p->c, p->pages->iov,
|
||||
used, &local_err);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & MULTIFD_FLAG_SYNC) {
|
||||
@ -1344,7 +1382,7 @@ static void *multifd_recv_thread(void *opaque)
|
||||
int multifd_load_setup(void)
|
||||
{
|
||||
int thread_count;
|
||||
uint32_t page_count = migrate_multifd_page_count();
|
||||
uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size();
|
||||
uint8_t i;
|
||||
|
||||
if (!migrate_use_multifd()) {
|
||||
|
@ -641,10 +641,14 @@ static int qemu_rdma_init_one_block(RAMBlock *rb, void *opaque)
|
||||
static int qemu_rdma_init_ram_blocks(RDMAContext *rdma)
|
||||
{
|
||||
RDMALocalBlocks *local = &rdma->local_ram_blocks;
|
||||
int ret;
|
||||
|
||||
assert(rdma->blockmap == NULL);
|
||||
memset(local, 0, sizeof *local);
|
||||
foreach_not_ignored_block(qemu_rdma_init_one_block, rdma);
|
||||
ret = foreach_not_ignored_block(qemu_rdma_init_one_block, rdma);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
trace_qemu_rdma_init_ram_blocks(local->nb_blocks);
|
||||
rdma->dest_blocks = g_new0(RDMADestBlock,
|
||||
rdma->local_ram_blocks.nb_blocks);
|
||||
|
@ -94,7 +94,7 @@ void migration_tls_channel_process_incoming(MigrationState *s,
|
||||
|
||||
tioc = qio_channel_tls_new_server(
|
||||
ioc, creds,
|
||||
NULL, /* XXX pass ACL name */
|
||||
s->parameters.tls_authz,
|
||||
errp);
|
||||
if (!tioc) {
|
||||
return;
|
||||
|
@ -80,13 +80,13 @@ get_queued_page_not_dirty(const char *block_name, uint64_t tmp_offset, unsigned
|
||||
migration_bitmap_sync_start(void) ""
|
||||
migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64
|
||||
migration_throttle(void) ""
|
||||
multifd_recv(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags) "channel %d packet number %" PRIu64 " pages %d flags 0x%x"
|
||||
multifd_recv(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags, uint32_t next_packet_size) "channel %d packet number %" PRIu64 " pages %d flags 0x%x next packet size %d"
|
||||
multifd_recv_sync_main(long packet_num) "packet num %ld"
|
||||
multifd_recv_sync_main_signal(uint8_t id) "channel %d"
|
||||
multifd_recv_sync_main_wait(uint8_t id) "channel %d"
|
||||
multifd_recv_thread_end(uint8_t id, uint64_t packets, uint64_t pages) "channel %d packets %" PRIu64 " pages %" PRIu64
|
||||
multifd_recv_thread_start(uint8_t id) "%d"
|
||||
multifd_send(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags) "channel %d packet_num %" PRIu64 " pages %d flags 0x%x"
|
||||
multifd_send(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags, uint32_t next_packet_size) "channel %d packet_num %" PRIu64 " pages %d flags 0x%x next packet size %d"
|
||||
multifd_send_sync_main(long packet_num) "packet num %ld"
|
||||
multifd_send_sync_main_signal(uint8_t id) "channel %d"
|
||||
multifd_send_sync_main_wait(uint8_t id) "channel %d"
|
||||
|
@ -401,7 +401,7 @@
|
||||
# @pause-before-switchover: Pause outgoing migration before serialising device
|
||||
# state and before disabling block IO (since 2.11)
|
||||
#
|
||||
# @x-multifd: Use more than one fd for migration (since 2.11)
|
||||
# @multifd: Use more than one fd for migration (since 4.0)
|
||||
#
|
||||
# @dirty-bitmaps: If enabled, QEMU will migrate named dirty bitmaps.
|
||||
# (since 2.12)
|
||||
@ -420,7 +420,7 @@
|
||||
{ 'enum': 'MigrationCapability',
|
||||
'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
|
||||
'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
|
||||
'block', 'return-path', 'pause-before-switchover', 'x-multifd',
|
||||
'block', 'return-path', 'pause-before-switchover', 'multifd',
|
||||
'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
|
||||
'x-ignore-shared' ] }
|
||||
|
||||
@ -541,6 +541,12 @@
|
||||
# hostname must be provided so that the server's x509
|
||||
# certificate identity can be validated. (Since 2.7)
|
||||
#
|
||||
# @tls-authz: ID of the 'authz' object subclass that provides access control
|
||||
# checking of the TLS x509 certificate distinguished name.
|
||||
# This object is only resolved at time of use, so can be deleted
|
||||
# and recreated on the fly while the migration server is active.
|
||||
# If missing, it will default to denying access (Since 4.0)
|
||||
#
|
||||
# @max-bandwidth: to set maximum speed for migration. maximum speed in
|
||||
# bytes per second. (Since 2.8)
|
||||
#
|
||||
@ -557,13 +563,10 @@
|
||||
# migrated and the destination must already have access to the
|
||||
# same backing chain as was used on the source. (since 2.10)
|
||||
#
|
||||
# @x-multifd-channels: Number of channels used to migrate data in
|
||||
# parallel. This is the same number that the
|
||||
# number of sockets used for migration. The
|
||||
# default value is 2 (since 2.11)
|
||||
#
|
||||
# @x-multifd-page-count: Number of pages sent together to a thread.
|
||||
# The default value is 16 (since 2.11)
|
||||
# @multifd-channels: Number of channels used to migrate data in
|
||||
# parallel. This is the same number that the
|
||||
# number of sockets used for migration. The
|
||||
# default value is 2 (since 4.0)
|
||||
#
|
||||
# @xbzrle-cache-size: cache size to be used by XBZRLE migration. It
|
||||
# needs to be a multiple of the target page size
|
||||
@ -585,9 +588,9 @@
|
||||
'compress-level', 'compress-threads', 'decompress-threads',
|
||||
'compress-wait-thread',
|
||||
'cpu-throttle-initial', 'cpu-throttle-increment',
|
||||
'tls-creds', 'tls-hostname', 'max-bandwidth',
|
||||
'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth',
|
||||
'downtime-limit', 'x-checkpoint-delay', 'block-incremental',
|
||||
'x-multifd-channels', 'x-multifd-page-count',
|
||||
'multifd-channels',
|
||||
'xbzrle-cache-size', 'max-postcopy-bandwidth',
|
||||
'max-cpu-throttle' ] }
|
||||
|
||||
@ -662,13 +665,10 @@
|
||||
# migrated and the destination must already have access to the
|
||||
# same backing chain as was used on the source. (since 2.10)
|
||||
#
|
||||
# @x-multifd-channels: Number of channels used to migrate data in
|
||||
# parallel. This is the same number that the
|
||||
# number of sockets used for migration. The
|
||||
# default value is 2 (since 2.11)
|
||||
#
|
||||
# @x-multifd-page-count: Number of pages sent together to a thread.
|
||||
# The default value is 16 (since 2.11)
|
||||
# @multifd-channels: Number of channels used to migrate data in
|
||||
# parallel. This is the same number that the
|
||||
# number of sockets used for migration. The
|
||||
# default value is 2 (since 4.0)
|
||||
#
|
||||
# @xbzrle-cache-size: cache size to be used by XBZRLE migration. It
|
||||
# needs to be a multiple of the target page size
|
||||
@ -699,12 +699,12 @@
|
||||
'*cpu-throttle-increment': 'int',
|
||||
'*tls-creds': 'StrOrNull',
|
||||
'*tls-hostname': 'StrOrNull',
|
||||
'*tls-authz': 'StrOrNull',
|
||||
'*max-bandwidth': 'int',
|
||||
'*downtime-limit': 'int',
|
||||
'*x-checkpoint-delay': 'int',
|
||||
'*block-incremental': 'bool',
|
||||
'*x-multifd-channels': 'int',
|
||||
'*x-multifd-page-count': 'int',
|
||||
'*multifd-channels': 'int',
|
||||
'*xbzrle-cache-size': 'size',
|
||||
'*max-postcopy-bandwidth': 'size',
|
||||
'*max-cpu-throttle': 'int' } }
|
||||
@ -780,6 +780,10 @@
|
||||
# associated with the migration URI, if any. (Since 2.9)
|
||||
# Note: 2.8 reports this by omitting tls-hostname instead.
|
||||
#
|
||||
# @tls-authz: ID of the 'authz' object subclass that provides access control
|
||||
# checking of the TLS x509 certificate distinguished name. (Since
|
||||
# 4.0)
|
||||
#
|
||||
# @max-bandwidth: to set maximum speed for migration. maximum speed in
|
||||
# bytes per second. (Since 2.8)
|
||||
#
|
||||
@ -795,13 +799,10 @@
|
||||
# migrated and the destination must already have access to the
|
||||
# same backing chain as was used on the source. (since 2.10)
|
||||
#
|
||||
# @x-multifd-channels: Number of channels used to migrate data in
|
||||
# parallel. This is the same number that the
|
||||
# number of sockets used for migration.
|
||||
# The default value is 2 (since 2.11)
|
||||
#
|
||||
# @x-multifd-page-count: Number of pages sent together to a thread.
|
||||
# The default value is 16 (since 2.11)
|
||||
# @multifd-channels: Number of channels used to migrate data in
|
||||
# parallel. This is the same number that the
|
||||
# number of sockets used for migration.
|
||||
# The default value is 2 (since 4.0)
|
||||
#
|
||||
# @xbzrle-cache-size: cache size to be used by XBZRLE migration. It
|
||||
# needs to be a multiple of the target page size
|
||||
@ -831,12 +832,12 @@
|
||||
'*cpu-throttle-increment': 'uint8',
|
||||
'*tls-creds': 'str',
|
||||
'*tls-hostname': 'str',
|
||||
'*tls-authz': 'str',
|
||||
'*max-bandwidth': 'size',
|
||||
'*downtime-limit': 'uint64',
|
||||
'*x-checkpoint-delay': 'uint32',
|
||||
'*block-incremental': 'bool' ,
|
||||
'*x-multifd-channels': 'uint8',
|
||||
'*x-multifd-page-count': 'uint32',
|
||||
'*multifd-channels': 'uint8',
|
||||
'*xbzrle-cache-size': 'size',
|
||||
'*max-postcopy-bandwidth': 'size',
|
||||
'*max-cpu-throttle':'uint8'} }
|
||||
@ -1037,19 +1038,22 @@
|
||||
##
|
||||
# @COLOExitReason:
|
||||
#
|
||||
# The reason for a COLO exit
|
||||
# The reason for a COLO exit.
|
||||
#
|
||||
# @none: no failover has ever happened. This can't occur in the
|
||||
# COLO_EXIT event, only in the result of query-colo-status.
|
||||
# @none: failover has never happened. This state does not occur
|
||||
# in the COLO_EXIT event, and is only visible in the result of
|
||||
# query-colo-status.
|
||||
#
|
||||
# @request: COLO exit is due to an external request
|
||||
# @request: COLO exit is due to an external request.
|
||||
#
|
||||
# @error: COLO exit is due to an internal error
|
||||
# @error: COLO exit is due to an internal error.
|
||||
#
|
||||
# @processing: COLO is currently handling a failover (since 4.0).
|
||||
#
|
||||
# Since: 3.1
|
||||
##
|
||||
{ 'enum': 'COLOExitReason',
|
||||
'data': [ 'none', 'request', 'error' ] }
|
||||
'data': [ 'none', 'request', 'error' , 'processing' ] }
|
||||
|
||||
##
|
||||
# @x-colo-lost-heartbeat:
|
||||
@ -1376,12 +1380,17 @@
|
||||
# @mode: COLO running mode. If COLO is running, this field will return
|
||||
# 'primary' or 'secondary'.
|
||||
#
|
||||
# @last_mode: COLO last running mode. If COLO is running, this field
|
||||
# will return same like mode field, after failover we can
|
||||
# use this field to get last colo mode. (since 4.1)
|
||||
#
|
||||
# @reason: describes the reason for the COLO exit.
|
||||
#
|
||||
# Since: 3.1
|
||||
##
|
||||
{ 'struct': 'COLOStatus',
|
||||
'data': { 'mode': 'COLOMode', 'reason': 'COLOExitReason' } }
|
||||
'data': { 'mode': 'COLOMode', 'last_mode': 'COLOMode',
|
||||
'reason': 'COLOExitReason' } }
|
||||
|
||||
##
|
||||
# @query-colo-status:
|
||||
|
Loading…
Reference in New Issue
Block a user