|
@@ -1598,8 +1598,9 @@ void vm_state_notify(int running, RunState state)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int reset_requested;
|
|
|
-static int shutdown_requested, shutdown_signal = -1;
|
|
|
+static ShutdownCause reset_requested;
|
|
|
+static ShutdownCause shutdown_requested;
|
|
|
+static int shutdown_signal;
|
|
|
static pid_t shutdown_pid;
|
|
|
static int powerdown_requested;
|
|
|
static int debug_requested;
|
|
@@ -1613,24 +1614,24 @@ static NotifierList wakeup_notifiers =
|
|
|
NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
|
|
|
static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
|
|
|
|
|
|
-int qemu_shutdown_requested_get(void)
|
|
|
+ShutdownCause qemu_shutdown_requested_get(void)
|
|
|
{
|
|
|
return shutdown_requested;
|
|
|
}
|
|
|
|
|
|
-int qemu_reset_requested_get(void)
|
|
|
+ShutdownCause qemu_reset_requested_get(void)
|
|
|
{
|
|
|
return reset_requested;
|
|
|
}
|
|
|
|
|
|
static int qemu_shutdown_requested(void)
|
|
|
{
|
|
|
- return atomic_xchg(&shutdown_requested, 0);
|
|
|
+ return atomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE);
|
|
|
}
|
|
|
|
|
|
static void qemu_kill_report(void)
|
|
|
{
|
|
|
- if (!qtest_driver() && shutdown_signal != -1) {
|
|
|
+ if (!qtest_driver() && shutdown_signal) {
|
|
|
if (shutdown_pid == 0) {
|
|
|
/* This happens for eg ^C at the terminal, so it's worth
|
|
|
* avoiding printing an odd message in that case.
|
|
@@ -1644,18 +1645,19 @@ static void qemu_kill_report(void)
|
|
|
shutdown_cmd ? shutdown_cmd : "<unknown process>");
|
|
|
g_free(shutdown_cmd);
|
|
|
}
|
|
|
- shutdown_signal = -1;
|
|
|
+ shutdown_signal = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int qemu_reset_requested(void)
|
|
|
+static ShutdownCause qemu_reset_requested(void)
|
|
|
{
|
|
|
- int r = reset_requested;
|
|
|
+ ShutdownCause r = reset_requested;
|
|
|
+
|
|
|
if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
|
|
|
- reset_requested = 0;
|
|
|
+ reset_requested = SHUTDOWN_CAUSE_NONE;
|
|
|
return r;
|
|
|
}
|
|
|
- return false;
|
|
|
+ return SHUTDOWN_CAUSE_NONE;
|
|
|
}
|
|
|
|
|
|
static int qemu_suspend_requested(void)
|
|
@@ -1687,7 +1689,10 @@ static int qemu_debug_requested(void)
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
-void qemu_system_reset(bool report)
|
|
|
+/*
|
|
|
+ * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
|
|
|
+ */
|
|
|
+void qemu_system_reset(ShutdownCause reason)
|
|
|
{
|
|
|
MachineClass *mc;
|
|
|
|
|
@@ -1700,8 +1705,9 @@ void qemu_system_reset(bool report)
|
|
|
} else {
|
|
|
qemu_devices_reset();
|
|
|
}
|
|
|
- if (report) {
|
|
|
- qapi_event_send_reset(&error_abort);
|
|
|
+ if (reason) {
|
|
|
+ qapi_event_send_reset(shutdown_caused_by_guest(reason),
|
|
|
+ &error_abort);
|
|
|
}
|
|
|
cpu_synchronize_all_post_reset();
|
|
|
}
|
|
@@ -1719,7 +1725,7 @@ void qemu_system_guest_panicked(GuestPanicInformation *info)
|
|
|
if (!no_shutdown) {
|
|
|
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
|
|
|
!!info, info, &error_abort);
|
|
|
- qemu_system_shutdown_request();
|
|
|
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
|
|
|
}
|
|
|
|
|
|
if (info) {
|
|
@@ -1736,12 +1742,12 @@ void qemu_system_guest_panicked(GuestPanicInformation *info)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void qemu_system_reset_request(void)
|
|
|
+void qemu_system_reset_request(ShutdownCause reason)
|
|
|
{
|
|
|
if (no_reboot) {
|
|
|
- shutdown_requested = 1;
|
|
|
+ shutdown_requested = reason;
|
|
|
} else {
|
|
|
- reset_requested = 1;
|
|
|
+ reset_requested = reason;
|
|
|
}
|
|
|
cpu_stop_current();
|
|
|
qemu_notify_event();
|
|
@@ -1808,15 +1814,15 @@ void qemu_system_killed(int signal, pid_t pid)
|
|
|
/* Cannot call qemu_system_shutdown_request directly because
|
|
|
* we are in a signal handler.
|
|
|
*/
|
|
|
- shutdown_requested = 1;
|
|
|
+ shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL;
|
|
|
qemu_notify_event();
|
|
|
}
|
|
|
|
|
|
-void qemu_system_shutdown_request(void)
|
|
|
+void qemu_system_shutdown_request(ShutdownCause reason)
|
|
|
{
|
|
|
- trace_qemu_system_shutdown_request();
|
|
|
- replay_shutdown_request();
|
|
|
- shutdown_requested = 1;
|
|
|
+ trace_qemu_system_shutdown_request(reason);
|
|
|
+ replay_shutdown_request(reason);
|
|
|
+ shutdown_requested = reason;
|
|
|
qemu_notify_event();
|
|
|
}
|
|
|
|
|
@@ -1847,24 +1853,29 @@ void qemu_system_debug_request(void)
|
|
|
static bool main_loop_should_exit(void)
|
|
|
{
|
|
|
RunState r;
|
|
|
+ ShutdownCause request;
|
|
|
+
|
|
|
if (qemu_debug_requested()) {
|
|
|
vm_stop(RUN_STATE_DEBUG);
|
|
|
}
|
|
|
if (qemu_suspend_requested()) {
|
|
|
qemu_system_suspend();
|
|
|
}
|
|
|
- if (qemu_shutdown_requested()) {
|
|
|
+ request = qemu_shutdown_requested();
|
|
|
+ if (request) {
|
|
|
qemu_kill_report();
|
|
|
- qapi_event_send_shutdown(&error_abort);
|
|
|
+ qapi_event_send_shutdown(shutdown_caused_by_guest(request),
|
|
|
+ &error_abort);
|
|
|
if (no_shutdown) {
|
|
|
vm_stop(RUN_STATE_SHUTDOWN);
|
|
|
} else {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
- if (qemu_reset_requested()) {
|
|
|
+ request = qemu_reset_requested();
|
|
|
+ if (request) {
|
|
|
pause_all_vcpus();
|
|
|
- qemu_system_reset(VMRESET_REPORT);
|
|
|
+ qemu_system_reset(request);
|
|
|
resume_all_vcpus();
|
|
|
if (!runstate_check(RUN_STATE_RUNNING) &&
|
|
|
!runstate_check(RUN_STATE_INMIGRATE)) {
|
|
@@ -1873,7 +1884,7 @@ static bool main_loop_should_exit(void)
|
|
|
}
|
|
|
if (qemu_wakeup_requested()) {
|
|
|
pause_all_vcpus();
|
|
|
- qemu_system_reset(VMRESET_SILENT);
|
|
|
+ qemu_system_reset(SHUTDOWN_CAUSE_NONE);
|
|
|
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
|
|
|
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
|
|
|
resume_all_vcpus();
|
|
@@ -4697,7 +4708,7 @@ int main(int argc, char **argv, char **envp)
|
|
|
reading from the other reads, because timer polling functions query
|
|
|
clock values from the log. */
|
|
|
replay_checkpoint(CHECKPOINT_RESET);
|
|
|
- qemu_system_reset(VMRESET_SILENT);
|
|
|
+ qemu_system_reset(SHUTDOWN_CAUSE_NONE);
|
|
|
register_global_state();
|
|
|
if (replay_mode != REPLAY_MODE_NONE) {
|
|
|
replay_vmstate_init();
|