runstate: introduce suspended state
QEMU enters in this state when the guest suspends to ram (S3). This is important so that HMP users and QMP clients can know that the guest is suspended. QMP also has an event for this, but events are not reliable and are limited (ie. a client can connect to QEMU after the event has been emitted). Having a different state for S3 brings a new issue, though. Every device that doesn't run when the VM is stopped but wants to run when the VM is suspended has to check for RUN_STATE_SUSPENDED explicitly. This is the case for the keyboard and mouse devices, for example. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
0a24c7b18e
commit
ad02b96ad8
4
input.c
4
input.c
@ -130,7 +130,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
|
|||||||
|
|
||||||
void kbd_put_keycode(int keycode)
|
void kbd_put_keycode(int keycode)
|
||||||
{
|
{
|
||||||
if (!runstate_is_running()) {
|
if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (qemu_put_kbd_event) {
|
if (qemu_put_kbd_event) {
|
||||||
@ -154,7 +154,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
|
|||||||
void *mouse_event_opaque;
|
void *mouse_event_opaque;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
if (!runstate_is_running()) {
|
if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (QTAILQ_EMPTY(&mouse_handlers)) {
|
if (QTAILQ_EMPTY(&mouse_handlers)) {
|
||||||
|
@ -116,12 +116,14 @@
|
|||||||
#
|
#
|
||||||
# @shutdown: guest is shut down (and -no-shutdown is in use)
|
# @shutdown: guest is shut down (and -no-shutdown is in use)
|
||||||
#
|
#
|
||||||
|
# @suspended: guest is suspended (ACPI S3)
|
||||||
|
#
|
||||||
# @watchdog: the watchdog action is configured to pause and has been triggered
|
# @watchdog: the watchdog action is configured to pause and has been triggered
|
||||||
##
|
##
|
||||||
{ 'enum': 'RunState',
|
{ 'enum': 'RunState',
|
||||||
'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
|
'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
|
||||||
'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
|
'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
|
||||||
'running', 'save-vm', 'shutdown', 'watchdog' ] }
|
'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @StatusInfo:
|
# @StatusInfo:
|
||||||
|
2
qmp.c
2
qmp.c
@ -151,6 +151,8 @@ void qmp_cont(Error **errp)
|
|||||||
runstate_check(RUN_STATE_SHUTDOWN)) {
|
runstate_check(RUN_STATE_SHUTDOWN)) {
|
||||||
error_set(errp, QERR_RESET_REQUIRED);
|
error_set(errp, QERR_RESET_REQUIRED);
|
||||||
return;
|
return;
|
||||||
|
} else if (runstate_check(RUN_STATE_SUSPENDED)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bdrv_iterate(iostatus_bdrv_it, NULL);
|
bdrv_iterate(iostatus_bdrv_it, NULL);
|
||||||
|
7
vl.c
7
vl.c
@ -366,6 +366,11 @@ static const RunStateTransition runstate_transitions_def[] = {
|
|||||||
{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
|
{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
|
||||||
{ RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
|
{ RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
|
||||||
|
|
||||||
|
{ RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
|
||||||
|
{ RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
|
||||||
|
{ RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
|
||||||
|
{ RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
|
||||||
|
|
||||||
{ RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
|
{ RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
|
||||||
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
|
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
|
||||||
|
|
||||||
@ -1420,6 +1425,7 @@ static void qemu_system_suspend(void)
|
|||||||
{
|
{
|
||||||
pause_all_vcpus();
|
pause_all_vcpus();
|
||||||
notifier_list_notify(&suspend_notifiers, NULL);
|
notifier_list_notify(&suspend_notifiers, NULL);
|
||||||
|
runstate_set(RUN_STATE_SUSPENDED);
|
||||||
monitor_protocol_event(QEVENT_SUSPEND, NULL);
|
monitor_protocol_event(QEVENT_SUSPEND, NULL);
|
||||||
is_suspended = true;
|
is_suspended = true;
|
||||||
}
|
}
|
||||||
@ -1447,6 +1453,7 @@ void qemu_system_wakeup_request(WakeupReason reason)
|
|||||||
if (!(wakeup_reason_mask & (1 << reason))) {
|
if (!(wakeup_reason_mask & (1 << reason))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
runstate_set(RUN_STATE_RUNNING);
|
||||||
monitor_protocol_event(QEVENT_WAKEUP, NULL);
|
monitor_protocol_event(QEVENT_WAKEUP, NULL);
|
||||||
notifier_list_notify(&wakeup_notifiers, &reason);
|
notifier_list_notify(&wakeup_notifiers, &reason);
|
||||||
reset_requested = 1;
|
reset_requested = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user