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 7e8fe46..e8628f7 100644 --- a/include/migration/migration-colo.h +++ b/include/migration/migration-colo.h @@ -44,6 +44,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 8a52934..8b37bd2 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 c3dd617..ee92bb2 100644 --- a/migration/colo-comm.c +++ b/migration/colo-comm.c @@ -31,6 +31,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 7d57121..894bf5f 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -75,6 +75,8 @@ enum { COLO_CHECKPOINT_SEND, COLO_CHECKPOINT_RECEIVED, COLO_CHECKPOINT_LOADED, + + COLO_GUEST_SHUTDOWN }; static QEMUBH *colo_bh; @@ -308,6 +310,13 @@ static int colo_do_checkpoint_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(); @@ -483,6 +492,16 @@ static int colo_wait_handle_cmd(QEMUFile *f, int *checkpoint_request) case COLO_CHECKPOINT_NEW: *checkpoint_request = 1; 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 8c07244..b0f3237 100644 --- a/vl.c +++ b/vl.c @@ -1532,6 +1532,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; @@ -1648,6 +1650,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; @@ -1716,13 +1722,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