For SVM, we forbid it shutdown directly when in COLO mode, FOR PVM's shutdown, we should do some work to ensure the consistent action between PVM and SVM.
Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> Signed-off-by: Lai Jiangshan <la...@cn.fujitsu.com> Signed-off-by: Li Zhijian <lizhij...@cn.fujitsu.com> --- include/migration/migration-colo.h | 1 + include/sysemu/sysemu.h | 3 +++ migration/colo-comm.c | 5 +++++ migration/colo.c | 19 +++++++++++++++++++ vl.c | 23 +++++++++++++++++++++-- 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/include/migration/migration-colo.h b/include/migration/migration-colo.h index 3bdd1ae..5747c0d 100644 --- a/include/migration/migration-colo.h +++ b/include/migration/migration-colo.h @@ -43,6 +43,7 @@ void loadvm_exit_colo(void); void *colo_process_incoming_checkpoints(void *opaque); bool loadvm_in_colo_state(void); +bool vm_in_colo_state(void); int get_colo_mode(void); /* ram cache */ diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 748d059..045d11d 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -51,6 +51,8 @@ typedef enum WakeupReason { QEMU_WAKEUP_REASON_OTHER, } WakeupReason; +extern int colo_shutdown_requested; + void qemu_system_reset_request(void); void qemu_system_suspend_request(void); void qemu_register_suspend_notifier(Notifier *notifier); @@ -58,6 +60,7 @@ void qemu_system_wakeup_request(WakeupReason reason); void qemu_system_wakeup_enable(WakeupReason reason, bool enabled); void qemu_register_wakeup_notifier(Notifier *notifier); void qemu_system_shutdown_request(void); +void qemu_system_shutdown_request_core(void); void qemu_system_powerdown_request(void); void qemu_register_powerdown_notifier(Notifier *notifier); void qemu_system_debug_request(void); diff --git a/migration/colo-comm.c b/migration/colo-comm.c index 57bc6cd..90c109b 100644 --- a/migration/colo-comm.c +++ b/migration/colo-comm.c @@ -32,6 +32,11 @@ static void colo_info_save(QEMUFile *f, void *opaque) } /* restore */ +bool vm_in_colo_state(void) +{ + return migrate_in_colo_state() || loadvm_in_colo_state(); +} + int get_colo_mode(void) { if (migrate_in_colo_state()) { diff --git a/migration/colo.c b/migration/colo.c index aadecc5..d5baf87 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -66,6 +66,8 @@ enum { COLO_CHECKPOINT_SEND, COLO_CHECKPOINT_RECEIVED, COLO_CHECKPOINT_LOADED, + + COLO_GUEST_SHUTDOWN }; static QEMUBH *colo_bh; @@ -284,6 +286,13 @@ static int do_colo_transaction(MigrationState *s, QEMUFile *control) } DPRINTF("got COLO_CHECKPOINT_LOADED\n"); + if (colo_shutdown_requested) { + colo_ctl_put(s->file, COLO_GUEST_SHUTDOWN); + qemu_fflush(s->file); + colo_shutdown_requested = 0; + qemu_system_shutdown_request_core(); + } + ret = 0; /* resume master */ qemu_mutex_lock_iothread(); @@ -454,6 +463,16 @@ static int slave_wait_new_checkpoint(QEMUFile *f) switch (cmd) { case COLO_CHECKPOINT_NEW: return 0; + case COLO_GUEST_SHUTDOWN: + qemu_mutex_lock_iothread(); + qemu_system_shutdown_request_core(); + qemu_mutex_unlock_iothread(); + /* the main thread will exit and termiante the whole + * process, do we need some cleanup? + */ + for (;;) { + ; + } default: return -1; } diff --git a/vl.c b/vl.c index aed26c1..74ffb57 100644 --- a/vl.c +++ b/vl.c @@ -1528,6 +1528,8 @@ static NotifierList wakeup_notifiers = NOTIFIER_LIST_INITIALIZER(wakeup_notifiers); static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE); +int colo_shutdown_requested; + int qemu_shutdown_requested_get(void) { return shutdown_requested; @@ -1644,6 +1646,10 @@ void qemu_system_reset(bool report) void qemu_system_reset_request(void) { if (no_reboot) { + if (vm_in_colo_state()) { + colo_shutdown_requested = 1; + return; + } shutdown_requested = 1; } else { reset_requested = 1; @@ -1712,13 +1718,26 @@ void qemu_system_killed(int signal, pid_t pid) qemu_system_shutdown_request(); } -void qemu_system_shutdown_request(void) +void qemu_system_shutdown_request_core(void) { - trace_qemu_system_shutdown_request(); shutdown_requested = 1; qemu_notify_event(); } +void qemu_system_shutdown_request(void) +{ + trace_qemu_system_shutdown_request(); + /* + * if in colo mode, we need do some significant work before respond to the + * shutdown request. + */ + if (vm_in_colo_state()) { + colo_shutdown_requested = 1; + return; + } + qemu_system_shutdown_request_core(); +} + static void qemu_system_powerdown(void) { qapi_event_send_powerdown(&error_abort); -- 1.7.12.4