migration: Switch to COLO process after finishing loadvm
Switch from normal migration loadvm process into COLO checkpoint process if COLO mode is enabled. We add three new members to struct MigrationIncomingState, 'have_colo_incoming_thread' and 'colo_incoming_thread' record the COLO related thread for secondary VM, 'migration_incoming_co' records the original migration incoming coroutine. Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.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:
parent
0b827d5e72
commit
25d0c16f62
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "migration/migration.h"
|
#include "migration/migration.h"
|
||||||
|
#include "qemu/coroutine_int.h"
|
||||||
|
#include "qemu/thread.h"
|
||||||
|
|
||||||
bool colo_supported(void);
|
bool colo_supported(void);
|
||||||
void colo_info_init(void);
|
void colo_info_init(void);
|
||||||
@ -22,4 +24,9 @@ void colo_info_init(void);
|
|||||||
void migrate_start_colo_process(MigrationState *s);
|
void migrate_start_colo_process(MigrationState *s);
|
||||||
bool migration_in_colo_state(void);
|
bool migration_in_colo_state(void);
|
||||||
|
|
||||||
|
/* loadvm */
|
||||||
|
bool migration_incoming_enable_colo(void);
|
||||||
|
void migration_incoming_exit_colo(void);
|
||||||
|
void *colo_process_incoming_thread(void *opaque);
|
||||||
|
bool migration_incoming_in_colo_state(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "qapi-types.h"
|
#include "qapi-types.h"
|
||||||
#include "exec/cpu-common.h"
|
#include "exec/cpu-common.h"
|
||||||
|
#include "qemu/coroutine_int.h"
|
||||||
|
|
||||||
#define QEMU_VM_FILE_MAGIC 0x5145564d
|
#define QEMU_VM_FILE_MAGIC 0x5145564d
|
||||||
#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
|
#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
|
||||||
@ -107,6 +108,12 @@ struct MigrationIncomingState {
|
|||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
|
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
|
bool have_colo_incoming_thread;
|
||||||
|
QemuThread colo_incoming_thread;
|
||||||
|
/* The coroutine we should enter (back) after failover */
|
||||||
|
Coroutine *migration_incoming_co;
|
||||||
|
|
||||||
/* See savevm.c */
|
/* See savevm.c */
|
||||||
LoadStateEntry_Head loadvm_handlers;
|
LoadStateEntry_Head loadvm_handlers;
|
||||||
};
|
};
|
||||||
|
@ -49,3 +49,13 @@ void colo_info_init(void)
|
|||||||
{
|
{
|
||||||
vmstate_register(NULL, 0, &colo_state, &colo_info);
|
vmstate_register(NULL, 0, &colo_state, &colo_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool migration_incoming_enable_colo(void)
|
||||||
|
{
|
||||||
|
return colo_info.colo_requested;
|
||||||
|
}
|
||||||
|
|
||||||
|
void migration_incoming_exit_colo(void)
|
||||||
|
{
|
||||||
|
colo_info.colo_requested = false;
|
||||||
|
}
|
||||||
|
@ -27,6 +27,13 @@ bool migration_in_colo_state(void)
|
|||||||
return (s->state == MIGRATION_STATUS_COLO);
|
return (s->state == MIGRATION_STATUS_COLO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool migration_incoming_in_colo_state(void)
|
||||||
|
{
|
||||||
|
MigrationIncomingState *mis = migration_incoming_get_current();
|
||||||
|
|
||||||
|
return mis && (mis->state == MIGRATION_STATUS_COLO);
|
||||||
|
}
|
||||||
|
|
||||||
static void colo_process_checkpoint(MigrationState *s)
|
static void colo_process_checkpoint(MigrationState *s)
|
||||||
{
|
{
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
@ -46,3 +53,17 @@ void migrate_start_colo_process(MigrationState *s)
|
|||||||
colo_process_checkpoint(s);
|
colo_process_checkpoint(s);
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *colo_process_incoming_thread(void *opaque)
|
||||||
|
{
|
||||||
|
MigrationIncomingState *mis = opaque;
|
||||||
|
|
||||||
|
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
|
||||||
|
MIGRATION_STATUS_COLO);
|
||||||
|
|
||||||
|
/* TODO: COLO checkpoint restore loop */
|
||||||
|
|
||||||
|
migration_incoming_exit_colo();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -407,6 +407,18 @@ static void process_incoming_migration_co(void *opaque)
|
|||||||
/* Else if something went wrong then just fall out of the normal exit */
|
/* Else if something went wrong then just fall out of the normal exit */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we get COLO info, and know if we are in COLO mode */
|
||||||
|
if (!ret && migration_incoming_enable_colo()) {
|
||||||
|
mis->migration_incoming_co = qemu_coroutine_self();
|
||||||
|
qemu_thread_create(&mis->colo_incoming_thread, "COLO incoming",
|
||||||
|
colo_process_incoming_thread, mis, QEMU_THREAD_JOINABLE);
|
||||||
|
mis->have_colo_incoming_thread = true;
|
||||||
|
qemu_coroutine_yield();
|
||||||
|
|
||||||
|
/* Wait checkpoint incoming thread exit before free resource */
|
||||||
|
qemu_thread_join(&mis->colo_incoming_thread);
|
||||||
|
}
|
||||||
|
|
||||||
qemu_fclose(f);
|
qemu_fclose(f);
|
||||||
free_xbzrle_decoded_buf();
|
free_xbzrle_decoded_buf();
|
||||||
|
|
||||||
|
@ -23,6 +23,16 @@ bool migration_in_colo_state(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool migration_incoming_in_colo_state(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void migrate_start_colo_process(MigrationState *s)
|
void migrate_start_colo_process(MigrationState *s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *colo_process_incoming_thread(void *opaque)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user