Switch from normal migration loadvm process into COLO checkpoint process if COLO mode is enabled.
Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> Signed-off-by: Li Zhijian <lizhij...@cn.fujitsu.com> Signed-off-by: Lai Jiangshan <la...@cn.fujitsu.com> Signed-off-by: Yang Hongyang <yan...@cn.fujitsu.com> --- include/migration/migration-colo.h | 14 +++++++++++++- migration/colo-comm.c | 10 ++++++++++ migration/colo.c | 15 ++++++++++++++- migration/migration.c | 21 ++++++++++++++++++++- stubs/migration-colo.c | 5 +++++ 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/include/migration/migration-colo.h b/include/migration/migration-colo.h index b72662c..9f1443b 100644 --- a/include/migration/migration-colo.h +++ b/include/migration/migration-colo.h @@ -15,9 +15,21 @@ #include "qemu-common.h" #include "migration/migration.h" +#include "block/coroutine.h" +#include "qemu/thread.h" void colo_info_mig_init(void); -void colo_init_checkpointer(MigrationState *s); +struct colo_incoming { + QEMUFile *file; + QemuThread thread; +}; +void colo_init_checkpointer(MigrationState *s); +/* loadvm */ +extern Coroutine *migration_incoming_co; +bool loadvm_enable_colo(void); +void loadvm_exit_colo(void); +void *colo_process_incoming_checkpoints(void *opaque); +bool loadvm_in_colo_state(void); #endif diff --git a/migration/colo-comm.c b/migration/colo-comm.c index 8caa948..038d12f 100644 --- a/migration/colo-comm.c +++ b/migration/colo-comm.c @@ -54,3 +54,13 @@ void colo_info_mig_init(void) register_savevm_live(NULL, "colo", -1, 1, &savevm_colo_info_handlers, NULL); } + +bool loadvm_enable_colo(void) +{ + return colo_requested; +} + +void loadvm_exit_colo(void) +{ + colo_requested = false; +} diff --git a/migration/colo.c b/migration/colo.c index f40b0d8..b54bb52 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -24,7 +24,7 @@ do { fprintf(stdout, "colo: " fmt , ## __VA_ARGS__); } while (0) #endif static QEMUBH *colo_bh; - +static Coroutine *colo; static void *colo_thread(void *opaque) { MigrationState *s = opaque; @@ -70,3 +70,16 @@ void colo_init_checkpointer(MigrationState *s) colo_bh = qemu_bh_new(colo_start_checkpointer, s); qemu_bh_schedule(colo_bh); } + +void *colo_process_incoming_checkpoints(void *opaque) +{ + colo = qemu_coroutine_self(); + assert(colo != NULL); + + /* TODO: COLO checkpoint restore loop */ + + colo = NULL; + loadvm_exit_colo(); + + return NULL; +} diff --git a/migration/migration.c b/migration/migration.c index 536ba01e..81f911f 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -79,6 +79,7 @@ void qemu_start_incoming_migration(const char *uri, Error **errp) } } +Coroutine *migration_incoming_co; static void process_incoming_migration_co(void *opaque) { QEMUFile *f = opaque; @@ -86,7 +87,25 @@ static void process_incoming_migration_co(void *opaque) int ret; ret = qemu_loadvm_state(f); - qemu_fclose(f); + + /* we get colo info, and know if we are in colo mode */ + if (loadvm_enable_colo()) { + struct colo_incoming *colo_in = g_malloc0(sizeof(*colo_in)); + + colo_in->file = f; + migration_incoming_co = qemu_coroutine_self(); + qemu_thread_create(&colo_in->thread, "colo incoming", + colo_process_incoming_checkpoints, colo_in, QEMU_THREAD_JOINABLE); + qemu_coroutine_yield(); + migration_incoming_co = NULL; +#if 0 + /* FIXME wait checkpoint incoming thread exit, and free resource */ + qemu_thread_join(&colo_in->thread); + g_free(colo_in); +#endif + } else { + qemu_fclose(f); + } free_xbzrle_decoded_buf(); if (ret < 0) { error_report("load of migration failed: %s", strerror(-ret)); diff --git a/stubs/migration-colo.c b/stubs/migration-colo.c index b2cff9c..7a3dbc5 100644 --- a/stubs/migration-colo.c +++ b/stubs/migration-colo.c @@ -15,3 +15,8 @@ void colo_init_checkpointer(MigrationState *s) { } + +void *colo_process_incoming_checkpoints(void *opaque) +{ + return NULL; +} -- 1.7.12.4