migration: Enter into COLO mode after migration if COLO is enabled

Add a new migration state: MIGRATION_STATUS_COLO. Migration source side
enters this state after the first live migration successfully finished
if COLO is enabled by command 'migrate_set_capability x-colo on'.

We reuse migration thread, so the process of checkpointing will be handled
in migration thread.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Amit Shah <amit@amitshah.net>
This commit is contained in:
zhanghailiang
2016-10-27 14:42:54 +08:00
committed by Amit Shah
parent 5821ebf93b
commit 0b827d5e72
6 changed files with 80 additions and 6 deletions

View File

@@ -695,6 +695,10 @@ MigrationInfo *qmp_query_migrate(Error **errp)
get_xbzrle_cache_stats(info);
break;
case MIGRATION_STATUS_COLO:
info->has_status = true;
/* TODO: display COLO specific information (checkpoint info etc.) */
break;
case MIGRATION_STATUS_COMPLETED:
get_xbzrle_cache_stats(info);
@@ -1113,7 +1117,8 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
params.shared = has_inc && inc;
if (migration_is_setup_or_active(s->state) ||
s->state == MIGRATION_STATUS_CANCELLING) {
s->state == MIGRATION_STATUS_CANCELLING ||
s->state == MIGRATION_STATUS_COLO) {
error_setg(errp, QERR_MIGRATION_ACTIVE);
return;
}
@@ -1661,7 +1666,11 @@ static void migration_completion(MigrationState *s, int current_active_state,
if (!ret) {
ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
if (ret >= 0) {
/*
* Don't mark the image with BDRV_O_INACTIVE flag if
* we will go into COLO stage later.
*/
if (ret >= 0 && !migrate_colo_enabled()) {
ret = bdrv_inactivate_all();
}
if (ret >= 0) {
@@ -1703,8 +1712,11 @@ static void migration_completion(MigrationState *s, int current_active_state,
goto fail_invalidate;
}
migrate_set_state(&s->state, current_active_state,
MIGRATION_STATUS_COMPLETED);
if (!migrate_colo_enabled()) {
migrate_set_state(&s->state, current_active_state,
MIGRATION_STATUS_COMPLETED);
}
return;
fail_invalidate:
@@ -1749,6 +1761,7 @@ static void *migration_thread(void *opaque)
bool entered_postcopy = false;
/* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */
enum MigrationStatus current_active_state = MIGRATION_STATUS_ACTIVE;
bool enable_colo = migrate_colo_enabled();
rcu_register_thread();
@@ -1857,7 +1870,13 @@ static void *migration_thread(void *opaque)
end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
qemu_mutex_lock_iothread();
qemu_savevm_state_cleanup();
/*
* The resource has been allocated by migration will be reused in COLO
* process, so don't release them.
*/
if (!enable_colo) {
qemu_savevm_state_cleanup();
}
if (s->state == MIGRATION_STATUS_COMPLETED) {
uint64_t transferred_bytes = qemu_ftell(s->to_dst_file);
s->total_time = end_time - s->total_time;
@@ -1870,6 +1889,15 @@ static void *migration_thread(void *opaque)
}
runstate_set(RUN_STATE_POSTMIGRATE);
} else {
if (s->state == MIGRATION_STATUS_ACTIVE && enable_colo) {
migrate_start_colo_process(s);
qemu_savevm_state_cleanup();
/*
* Fixme: we will run VM in COLO no matter its old running state.
* After exited COLO, we will keep running.
*/
old_vm_running = true;
}
if (old_vm_running && !entered_postcopy) {
vm_start();
} else {