migration: Create block capability
Create one capability for block migration and one parameter for incremental block migration. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> --- - address all Markus comments - use Markus and Eric text descriptions - change logic another time - improve text messages
This commit is contained in:
parent
f4a06d1391
commit
2833c59b94
13
hmp.c
13
hmp.c
@ -327,6 +327,10 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
|
|||||||
monitor_printf(mon, "%s: %" PRId64 "\n",
|
monitor_printf(mon, "%s: %" PRId64 "\n",
|
||||||
MigrationParameter_lookup[MIGRATION_PARAMETER_X_CHECKPOINT_DELAY],
|
MigrationParameter_lookup[MIGRATION_PARAMETER_X_CHECKPOINT_DELAY],
|
||||||
params->x_checkpoint_delay);
|
params->x_checkpoint_delay);
|
||||||
|
assert(params->has_block_incremental);
|
||||||
|
monitor_printf(mon, "%s: %s\n",
|
||||||
|
MigrationParameter_lookup[MIGRATION_PARAMETER_BLOCK_INCREMENTAL],
|
||||||
|
params->block_incremental ? "on" : "off");
|
||||||
}
|
}
|
||||||
|
|
||||||
qapi_free_MigrationParameters(params);
|
qapi_free_MigrationParameters(params);
|
||||||
@ -1528,6 +1532,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
|
|||||||
Visitor *v = string_input_visitor_new(valuestr);
|
Visitor *v = string_input_visitor_new(valuestr);
|
||||||
uint64_t valuebw = 0;
|
uint64_t valuebw = 0;
|
||||||
int64_t valueint = 0;
|
int64_t valueint = 0;
|
||||||
|
bool valuebool = false;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
bool use_int_value = false;
|
bool use_int_value = false;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
@ -1582,6 +1587,14 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
|
|||||||
p.has_x_checkpoint_delay = true;
|
p.has_x_checkpoint_delay = true;
|
||||||
use_int_value = true;
|
use_int_value = true;
|
||||||
break;
|
break;
|
||||||
|
case MIGRATION_PARAMETER_BLOCK_INCREMENTAL:
|
||||||
|
p.has_block_incremental = true;
|
||||||
|
visit_type_bool(v, param, &valuebool, &err);
|
||||||
|
if (err) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
p.block_incremental = valuebool;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_int_value) {
|
if (use_int_value) {
|
||||||
|
@ -20,4 +20,6 @@ uint64_t blk_mig_bytes_transferred(void);
|
|||||||
uint64_t blk_mig_bytes_remaining(void);
|
uint64_t blk_mig_bytes_remaining(void);
|
||||||
uint64_t blk_mig_bytes_total(void);
|
uint64_t blk_mig_bytes_total(void);
|
||||||
|
|
||||||
|
void migrate_set_block_enabled(bool value, Error **errp);
|
||||||
|
|
||||||
#endif /* MIGRATION_BLOCK_H */
|
#endif /* MIGRATION_BLOCK_H */
|
||||||
|
@ -153,6 +153,9 @@ struct MigrationState
|
|||||||
|
|
||||||
/* The last error that occurred */
|
/* The last error that occurred */
|
||||||
Error *error;
|
Error *error;
|
||||||
|
/* Do we have to clean up -b/-i from old migrate parameters */
|
||||||
|
/* This feature is deprecated and will be removed */
|
||||||
|
bool must_remove_block_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
void migrate_set_state(int *state, int old_state, int new_state);
|
void migrate_set_state(int *state, int old_state, int new_state);
|
||||||
@ -265,6 +268,9 @@ bool migrate_colo_enabled(void);
|
|||||||
|
|
||||||
int64_t xbzrle_cache_resize(int64_t new_size);
|
int64_t xbzrle_cache_resize(int64_t new_size);
|
||||||
|
|
||||||
|
bool migrate_use_block(void);
|
||||||
|
bool migrate_use_block_incremental(void);
|
||||||
|
|
||||||
bool migrate_use_compression(void);
|
bool migrate_use_compression(void);
|
||||||
int migrate_compress_level(void);
|
int migrate_compress_level(void);
|
||||||
int migrate_compress_threads(void);
|
int migrate_compress_threads(void);
|
||||||
|
@ -592,6 +592,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
|
|||||||
params->downtime_limit = s->parameters.downtime_limit;
|
params->downtime_limit = s->parameters.downtime_limit;
|
||||||
params->has_x_checkpoint_delay = true;
|
params->has_x_checkpoint_delay = true;
|
||||||
params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
|
params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
|
||||||
|
params->has_block_incremental = true;
|
||||||
|
params->block_incremental = s->parameters.block_incremental;
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
@ -900,6 +902,9 @@ void qmp_migrate_set_parameters(MigrationParameters *params, Error **errp)
|
|||||||
colo_checkpoint_notify(s);
|
colo_checkpoint_notify(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (params->has_block_incremental) {
|
||||||
|
s->parameters.block_incremental = params->block_incremental;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -935,6 +940,33 @@ void migrate_set_state(int *state, int old_state, int new_state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void migrate_set_block_enabled(bool value, Error **errp)
|
||||||
|
{
|
||||||
|
MigrationCapabilityStatusList *cap;
|
||||||
|
|
||||||
|
cap = g_new0(MigrationCapabilityStatusList, 1);
|
||||||
|
cap->value = g_new0(MigrationCapabilityStatus, 1);
|
||||||
|
cap->value->capability = MIGRATION_CAPABILITY_BLOCK;
|
||||||
|
cap->value->state = value;
|
||||||
|
qmp_migrate_set_capabilities(cap, errp);
|
||||||
|
qapi_free_MigrationCapabilityStatusList(cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_set_block_enabled(false, &error_abort);
|
||||||
|
migrate_set_block_incremental(s, false);
|
||||||
|
s->must_remove_block_options = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void migrate_fd_cleanup(void *opaque)
|
static void migrate_fd_cleanup(void *opaque)
|
||||||
{
|
{
|
||||||
MigrationState *s = opaque;
|
MigrationState *s = opaque;
|
||||||
@ -967,6 +999,7 @@ static void migrate_fd_cleanup(void *opaque)
|
|||||||
}
|
}
|
||||||
|
|
||||||
notifier_list_notify(&migration_state_notifiers, s);
|
notifier_list_notify(&migration_state_notifiers, s);
|
||||||
|
block_cleanup_parameters(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void migrate_fd_error(MigrationState *s, const Error *error)
|
void migrate_fd_error(MigrationState *s, const Error *error)
|
||||||
@ -979,6 +1012,7 @@ void migrate_fd_error(MigrationState *s, const Error *error)
|
|||||||
s->error = error_copy(error);
|
s->error = error_copy(error);
|
||||||
}
|
}
|
||||||
notifier_list_notify(&migration_state_notifiers, s);
|
notifier_list_notify(&migration_state_notifiers, s);
|
||||||
|
block_cleanup_parameters(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void migrate_fd_cancel(MigrationState *s)
|
static void migrate_fd_cancel(MigrationState *s)
|
||||||
@ -1020,6 +1054,7 @@ static void migrate_fd_cancel(MigrationState *s)
|
|||||||
s->block_inactive = false;
|
s->block_inactive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
block_cleanup_parameters(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_migration_state_change_notifier(Notifier *notify)
|
void add_migration_state_change_notifier(Notifier *notify)
|
||||||
@ -1207,6 +1242,24 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((has_blk && blk) || (has_inc && inc)) {
|
||||||
|
if (migrate_use_block() || migrate_use_block_incremental()) {
|
||||||
|
error_setg(errp, "Command options are incompatible with "
|
||||||
|
"current migration capabilities");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
migrate_set_block_enabled(true, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s->must_remove_block_options = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_inc && inc) {
|
||||||
|
migrate_set_block_incremental(s, true);
|
||||||
|
}
|
||||||
|
|
||||||
s = migrate_init(¶ms);
|
s = migrate_init(¶ms);
|
||||||
|
|
||||||
if (strstart(uri, "tcp:", &p)) {
|
if (strstart(uri, "tcp:", &p)) {
|
||||||
@ -1404,6 +1457,24 @@ int64_t migrate_xbzrle_cache_size(void)
|
|||||||
return s->xbzrle_cache_size;
|
return s->xbzrle_cache_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool migrate_use_block(void)
|
||||||
|
{
|
||||||
|
MigrationState *s;
|
||||||
|
|
||||||
|
s = migrate_get_current();
|
||||||
|
|
||||||
|
return s->enabled_capabilities[MIGRATION_CAPABILITY_BLOCK];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool migrate_use_block_incremental(void)
|
||||||
|
{
|
||||||
|
MigrationState *s;
|
||||||
|
|
||||||
|
s = migrate_get_current();
|
||||||
|
|
||||||
|
return s->parameters.block_incremental;
|
||||||
|
}
|
||||||
|
|
||||||
/* migration thread support */
|
/* migration thread support */
|
||||||
/*
|
/*
|
||||||
* Something bad happened to the RP stream, mark an error
|
* Something bad happened to the RP stream, mark an error
|
||||||
|
@ -894,11 +894,18 @@
|
|||||||
# @release-ram: if enabled, qemu will free the migrated ram pages on the source
|
# @release-ram: if enabled, qemu will free the migrated ram pages on the source
|
||||||
# during postcopy-ram migration. (since 2.9)
|
# during postcopy-ram migration. (since 2.9)
|
||||||
#
|
#
|
||||||
|
# @block: If enabled, QEMU will also migrate the contents of all block
|
||||||
|
# devices. Default is disabled. A possible alternative uses
|
||||||
|
# mirror jobs to a builtin NBD server on the destination, which
|
||||||
|
# offers more flexibility.
|
||||||
|
# (Since 2.10)
|
||||||
|
#
|
||||||
# Since: 1.2
|
# Since: 1.2
|
||||||
##
|
##
|
||||||
{ 'enum': 'MigrationCapability',
|
{ 'enum': 'MigrationCapability',
|
||||||
'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
|
'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
|
||||||
'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram'] }
|
'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
|
||||||
|
'block' ] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @MigrationCapabilityStatus:
|
# @MigrationCapabilityStatus:
|
||||||
@ -1009,13 +1016,20 @@
|
|||||||
# @x-checkpoint-delay: The delay time (in ms) between two COLO checkpoints in
|
# @x-checkpoint-delay: The delay time (in ms) between two COLO checkpoints in
|
||||||
# periodic mode. (Since 2.8)
|
# periodic mode. (Since 2.8)
|
||||||
#
|
#
|
||||||
|
# @block-incremental: Affects how much storage is migrated when the
|
||||||
|
# block migration capability is enabled. When false, the entire
|
||||||
|
# storage backing chain is migrated into a flattened image at
|
||||||
|
# the destination; when true, only the active qcow2 layer is
|
||||||
|
# migrated and the destination must already have access to the
|
||||||
|
# same backing chain as was used on the source. (since 2.10)
|
||||||
|
#
|
||||||
# Since: 2.4
|
# Since: 2.4
|
||||||
##
|
##
|
||||||
{ 'enum': 'MigrationParameter',
|
{ 'enum': 'MigrationParameter',
|
||||||
'data': ['compress-level', 'compress-threads', 'decompress-threads',
|
'data': ['compress-level', 'compress-threads', 'decompress-threads',
|
||||||
'cpu-throttle-initial', 'cpu-throttle-increment',
|
'cpu-throttle-initial', 'cpu-throttle-increment',
|
||||||
'tls-creds', 'tls-hostname', 'max-bandwidth',
|
'tls-creds', 'tls-hostname', 'max-bandwidth',
|
||||||
'downtime-limit', 'x-checkpoint-delay' ] }
|
'downtime-limit', 'x-checkpoint-delay', 'block-incremental' ] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @migrate-set-parameters:
|
# @migrate-set-parameters:
|
||||||
@ -1082,6 +1096,13 @@
|
|||||||
#
|
#
|
||||||
# @x-checkpoint-delay: the delay time between two COLO checkpoints. (Since 2.8)
|
# @x-checkpoint-delay: the delay time between two COLO checkpoints. (Since 2.8)
|
||||||
#
|
#
|
||||||
|
# @block-incremental: Affects how much storage is migrated when the
|
||||||
|
# block migration capability is enabled. When false, the entire
|
||||||
|
# storage backing chain is migrated into a flattened image at
|
||||||
|
# the destination; when true, only the active qcow2 layer is
|
||||||
|
# migrated and the destination must already have access to the
|
||||||
|
# same backing chain as was used on the source. (since 2.10)
|
||||||
|
#
|
||||||
# Since: 2.4
|
# Since: 2.4
|
||||||
##
|
##
|
||||||
{ 'struct': 'MigrationParameters',
|
{ 'struct': 'MigrationParameters',
|
||||||
@ -1094,7 +1115,8 @@
|
|||||||
'*tls-hostname': 'str',
|
'*tls-hostname': 'str',
|
||||||
'*max-bandwidth': 'int',
|
'*max-bandwidth': 'int',
|
||||||
'*downtime-limit': 'int',
|
'*downtime-limit': 'int',
|
||||||
'*x-checkpoint-delay': 'int'} }
|
'*x-checkpoint-delay': 'int',
|
||||||
|
'*block-incremental': 'bool' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @query-migrate-parameters:
|
# @query-migrate-parameters:
|
||||||
|
Loading…
Reference in New Issue
Block a user