This state is similar to io-error, but is not entered on I/O errors but instead when a request takes longer than a user-defined time (set via the delay-stop-ns property on a block device, which is not yet available but will be added by a future patch in this series).
In contrast to other stop states, this state does not drain block devices. That is because it is entered only when a request hangs, which means that draining would be counter-productive. Signed-off-by: Hanna Czenczek <[email protected]> --- qapi/run-state.json | 7 ++++++- system/runstate.c | 25 ++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/qapi/run-state.json b/qapi/run-state.json index 8bbd9884087..cf3f43579de 100644 --- a/qapi/run-state.json +++ b/qapi/run-state.json @@ -53,12 +53,17 @@ # @colo: guest is paused to save/restore VM state under colo # checkpoint, VM can not get into this state unless colo # capability is enabled for migration. (since 2.8) +# +# @io-hang: An I/O operation has been delayed for too long and the +# device is configured to stop the VM when that happens. In +# contrast to other paused states, the VM's block devices will not +# be drained when entering this run state. (since 11.2) ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', - 'guest-panicked', 'colo' ] } + 'guest-panicked', 'colo', 'io-hang' ] } ## # @ShutdownCause: diff --git a/system/runstate.c b/system/runstate.c index 7b3233f77f6..c5b56308735 100644 --- a/system/runstate.c +++ b/system/runstate.c @@ -98,6 +98,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH }, { RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_INMIGRATE, RUN_STATE_COLO }, + { RUN_STATE_INMIGRATE, RUN_STATE_IO_HANG }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, @@ -135,6 +136,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_SUSPENDED }, { RUN_STATE_FINISH_MIGRATE, RUN_STATE_WATCHDOG }, { RUN_STATE_FINISH_MIGRATE, RUN_STATE_GUEST_PANICKED }, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_IO_HANG }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH }, @@ -155,6 +157,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RUNNING, RUN_STATE_COLO}, + { RUN_STATE_RUNNING, RUN_STATE_IO_HANG }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, { RUN_STATE_SAVE_VM, RUN_STATE_SUSPENDED }, @@ -175,6 +178,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SUSPENDED, RUN_STATE_RESTORE_VM }, { RUN_STATE_SUSPENDED, RUN_STATE_SHUTDOWN }, { RUN_STATE_SUSPENDED, RUN_STATE_IO_ERROR }, + { RUN_STATE_SUSPENDED, RUN_STATE_IO_HANG }, { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, @@ -185,6 +189,11 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_GUEST_PANICKED, RUN_STATE_PRELAUNCH }, + { RUN_STATE_IO_HANG, RUN_STATE_RUNNING }, + { RUN_STATE_IO_HANG, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_IO_HANG, RUN_STATE_PRELAUNCH }, + { RUN_STATE_IO_HANG, RUN_STATE_SUSPENDED }, + { RUN_STATE__MAX, RUN_STATE__MAX }, }; @@ -445,13 +454,15 @@ static int do_vm_stop(RunState state, bool send_stop) } } - bdrv_drain_all(); - /* - * Even if vm_state_notify() return failure, - * it would be better to flush as before. - */ - ret |= bdrv_flush_all(); - trace_vm_stop_flush_all(ret); + if (state != RUN_STATE_IO_HANG) { + bdrv_drain_all(); + /* + * Even if vm_state_notify() return failure, + * it would be better to flush as before. + */ + ret |= bdrv_flush_all(); + trace_vm_stop_flush_all(ret); + } return ret; } -- 2.55.0
