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>
void kbd_put_keycode(int keycode)
{
- if (!runstate_is_running()) {
+ if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
return;
}
if (qemu_put_kbd_event) {
void *mouse_event_opaque;
int width, height;
- if (!runstate_is_running()) {
+ if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
return;
}
if (QTAILQ_EMPTY(&mouse_handlers)) {
#
# @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
##
{ 'enum': 'RunState',
'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
- 'running', 'save-vm', 'shutdown', 'watchdog' ] }
+ 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] }
##
# @StatusInfo:
runstate_check(RUN_STATE_SHUTDOWN)) {
error_set(errp, QERR_RESET_REQUIRED);
return;
+ } else if (runstate_check(RUN_STATE_SUSPENDED)) {
+ return;
}
bdrv_iterate(iostatus_bdrv_it, NULL);
{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
{ 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_FINISH_MIGRATE },
{
pause_all_vcpus();
notifier_list_notify(&suspend_notifiers, NULL);
+ runstate_set(RUN_STATE_SUSPENDED);
monitor_protocol_event(QEVENT_SUSPEND, NULL);
is_suspended = true;
}
if (!(wakeup_reason_mask & (1 << reason))) {
return;
}
+ runstate_set(RUN_STATE_RUNNING);
monitor_protocol_event(QEVENT_WAKEUP, NULL);
notifier_list_notify(&wakeup_notifiers, &reason);
reset_requested = 1;