From efd1a1d6407f73565cf3b4089a2baa4bad0650f8 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 20 Feb 2019 12:06:03 +0100 Subject: multifd: Drop x-multifd-page-count parameter Libvirt don't want to expose (and explain it). From now on we measure the number of packages in bytes instead of pages, so it is the same independently of architecture. We choose the page size of x86. Notice that in the following patch we make this variable. Signed-off-by: Juan Quintela Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Markus Armbruster Signed-off-by: Juan Quintela --- qapi/migration.json | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'qapi') diff --git a/qapi/migration.json b/qapi/migration.json index 5684733754..7cd03596ae 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -562,9 +562,6 @@ # 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) -# # @xbzrle-cache-size: cache size to be used by XBZRLE migration. It # needs to be a multiple of the target page size # and a power of 2 @@ -587,7 +584,7 @@ 'cpu-throttle-initial', 'cpu-throttle-increment', 'tls-creds', 'tls-hostname', 'max-bandwidth', 'downtime-limit', 'x-checkpoint-delay', 'block-incremental', - 'x-multifd-channels', 'x-multifd-page-count', + 'x-multifd-channels', 'xbzrle-cache-size', 'max-postcopy-bandwidth', 'max-cpu-throttle' ] } @@ -667,9 +664,6 @@ # 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) -# # @xbzrle-cache-size: cache size to be used by XBZRLE migration. It # needs to be a multiple of the target page size # and a power of 2 @@ -704,7 +698,6 @@ '*x-checkpoint-delay': 'int', '*block-incremental': 'bool', '*x-multifd-channels': 'int', - '*x-multifd-page-count': 'int', '*xbzrle-cache-size': 'size', '*max-postcopy-bandwidth': 'size', '*max-cpu-throttle': 'int' } } @@ -800,9 +793,6 @@ # 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) -# # @xbzrle-cache-size: cache size to be used by XBZRLE migration. It # needs to be a multiple of the target page size # and a power of 2 @@ -836,7 +826,6 @@ '*x-checkpoint-delay': 'uint32', '*block-incremental': 'bool' , '*x-multifd-channels': 'uint8', - '*x-multifd-page-count': 'uint32', '*xbzrle-cache-size': 'size', '*max-postcopy-bandwidth': 'size', '*max-cpu-throttle':'uint8'} } -- cgit v1.2.3-55-g7522 From cbfd6c957a4437d4759ca660e621daa381bf2898 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 6 Feb 2019 13:54:06 +0100 Subject: multifd: Drop x- We make it supported from now on. Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Markus Armbruster Signed-off-by: Juan Quintela --- hmp.c | 10 +++++----- migration/migration.c | 26 +++++++++++++------------- qapi/migration.json | 34 +++++++++++++++++----------------- 3 files changed, 35 insertions(+), 35 deletions(-) (limited to 'qapi') diff --git a/hmp.c b/hmp.c index 5a68544042..6bbbe1ad85 100644 --- a/hmp.c +++ b/hmp.c @@ -433,8 +433,8 @@ 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); + 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); @@ -1809,9 +1809,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); + 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; diff --git a/migration/migration.c b/migration/migration.c index 52c8121628..b36cf9c9a0 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -765,8 +765,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_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; @@ -1149,7 +1149,7 @@ 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"); @@ -1263,8 +1263,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_multifd_channels) { + dest->multifd_channels = params->multifd_channels; } if (params->has_xbzrle_cache_size) { dest->xbzrle_cache_size = params->xbzrle_cache_size; @@ -1353,8 +1353,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_multifd_channels) { + s->parameters.multifd_channels = params->multifd_channels; } if (params->has_xbzrle_cache_size) { s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; @@ -2113,7 +2113,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) @@ -2132,7 +2132,7 @@ int migrate_multifd_channels(void) s = migrate_get_current(); - return s->parameters.x_multifd_channels; + return s->parameters.multifd_channels; } int migrate_use_xbzrle(void) @@ -3374,8 +3374,8 @@ 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_SIZE("xbzrle-cache-size", MigrationState, parameters.xbzrle_cache_size, @@ -3411,7 +3411,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(), }; @@ -3465,7 +3465,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_multifd_channels = true; params->has_xbzrle_cache_size = true; params->has_max_postcopy_bandwidth = true; params->has_max_cpu_throttle = true; diff --git a/qapi/migration.json b/qapi/migration.json index 7cd03596ae..ff3616f4c2 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -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' ] } @@ -557,10 +557,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) +# @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 @@ -584,7 +584,7 @@ 'cpu-throttle-initial', 'cpu-throttle-increment', 'tls-creds', 'tls-hostname', 'max-bandwidth', 'downtime-limit', 'x-checkpoint-delay', 'block-incremental', - 'x-multifd-channels', + 'multifd-channels', 'xbzrle-cache-size', 'max-postcopy-bandwidth', 'max-cpu-throttle' ] } @@ -659,10 +659,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) +# @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 @@ -697,7 +697,7 @@ '*downtime-limit': 'int', '*x-checkpoint-delay': 'int', '*block-incremental': 'bool', - '*x-multifd-channels': 'int', + '*multifd-channels': 'int', '*xbzrle-cache-size': 'size', '*max-postcopy-bandwidth': 'size', '*max-cpu-throttle': 'int' } } @@ -788,10 +788,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) +# @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 @@ -825,7 +825,7 @@ '*downtime-limit': 'uint64', '*x-checkpoint-delay': 'uint32', '*block-incremental': 'bool' , - '*x-multifd-channels': 'uint8', + '*multifd-channels': 'uint8', '*xbzrle-cache-size': 'size', '*max-postcopy-bandwidth': 'size', '*max-cpu-throttle':'uint8'} } -- cgit v1.2.3-55-g7522 From d2f1d29b95aa45d13262b39153ff501ed6b1ac95 Mon Sep 17 00:00:00 2001 From: Daniel P. Berrange Date: Wed, 27 Feb 2019 14:53:24 +0000 Subject: migration: add support for a "tls-authz" migration parameter The QEMU instance that runs as the server for the migration data transport (ie the target QEMU) needs to be able to configure access control so it can prevent unauthorized clients initiating an incoming migration. This adds a new 'tls-authz' migration parameter that is used to provide the QOM ID of a QAuthZ subclass instance that provides the access control check. This is checked against the x509 certificate obtained during the TLS handshake. For example, when starting a QEMU for incoming migration, it is possible to give an example identity of the source QEMU that is intended to be connecting later: $QEMU \ -monitor stdio \ -incoming defer \ ...other args... (qemu) object_add tls-creds-x509,id=tls0,dir=/home/berrange/qemutls,\ endpoint=server,verify-peer=yes \ (qemu) object_add authz-simple,id=auth0,identity=CN=laptop.example.com,,\ O=Example Org,,L=London,,ST=London,,C=GB \ (qemu) migrate_incoming tcp:localhost:9000 Reviewed-by: Juan Quintela Signed-off-by: Daniel P. Berrange Signed-off-by: Juan Quintela --- hmp.c | 9 +++++++++ migration/migration.c | 8 ++++++++ migration/tls.c | 2 +- qapi/migration.json | 14 +++++++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) (limited to 'qapi') diff --git a/hmp.c b/hmp.c index 6bbbe1ad85..92941142af 100644 --- a/hmp.c +++ b/hmp.c @@ -441,6 +441,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) 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); @@ -1783,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; /* diff --git a/migration/migration.c b/migration/migration.c index b36cf9c9a0..d5c218a22b 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -757,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; @@ -1331,6 +1333,12 @@ 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) { diff --git a/migration/tls.c b/migration/tls.c index 3b9e8c9263..5171afc6c4 100644 --- a/migration/tls.c +++ b/migration/tls.c @@ -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; diff --git a/qapi/migration.json b/qapi/migration.json index ff3616f4c2..0a85aadd15 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -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) # @@ -582,7 +588,7 @@ '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', 'multifd-channels', 'xbzrle-cache-size', 'max-postcopy-bandwidth', @@ -693,6 +699,7 @@ '*cpu-throttle-increment': 'int', '*tls-creds': 'StrOrNull', '*tls-hostname': 'StrOrNull', + '*tls-authz': 'StrOrNull', '*max-bandwidth': 'int', '*downtime-limit': 'int', '*x-checkpoint-delay': 'int', @@ -773,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) # @@ -821,6 +832,7 @@ '*cpu-throttle-increment': 'uint8', '*tls-creds': 'str', '*tls-hostname': 'str', + '*tls-authz': 'str', '*max-bandwidth': 'size', '*downtime-limit': 'uint64', '*x-checkpoint-delay': 'uint32', -- cgit v1.2.3-55-g7522 From 3a43ac4757b70dfc2964c12ca1ac82f61128cc04 Mon Sep 17 00:00:00 2001 From: Zhang Chen Date: Fri, 22 Mar 2019 18:13:31 +0800 Subject: Migration/colo.c: Add new COLOExitReason to handle all failover state In this patch we add the processing state for COLOExitReason, because we have to identify COLO in the failover processing state or failover error state. In the way, we can handle all the failover state. We have improved the description of the COLOExitReason by the way. Signed-off-by: Zhang Chen Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- migration/colo.c | 24 +++++++++++++----------- qapi/migration.json | 15 +++++++++------ 2 files changed, 22 insertions(+), 17 deletions(-) (limited to 'qapi') diff --git a/migration/colo.c b/migration/colo.c index 89325952c7..dbe2b88807 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -267,7 +267,11 @@ COLOStatus *qmp_query_colo_status(Error **errp) 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; @@ -579,16 +583,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_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 */ @@ -850,17 +851,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_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) { diff --git a/qapi/migration.json b/qapi/migration.json index 0a85aadd15..e383951765 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1038,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: -- cgit v1.2.3-55-g7522 From 5ed0deca41b201a66d858d7296fe6b780d757404 Mon Sep 17 00:00:00 2001 From: Zhang Chen Date: Fri, 22 Mar 2019 18:13:33 +0800 Subject: Migration/colo.c: Make user obtain the last COLO mode info after failover Add the last_colo_mode to save the status after failover. This patch can solve the issue that user want to get last colo mode use query_colo_status after failover. Signed-off-by: Zhang Chen Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- migration/colo.c | 16 ++++++++++++++++ qapi/migration.json | 7 ++++++- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'qapi') diff --git a/migration/colo.c b/migration/colo.c index d1ae2e6d11..238a6d62c7 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -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) @@ -264,6 +267,7 @@ 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: @@ -515,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); @@ -688,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); diff --git a/qapi/migration.json b/qapi/migration.json index e383951765..cfde29acf8 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1380,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: -- cgit v1.2.3-55-g7522