From 2bd3bce8efebe86b031beab5c0e3b9bbaec0b502 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 5 Jun 2014 14:53:59 +0200 Subject: block: asynchronously stop the VM on I/O errors With virtio-blk dataplane, I/O errors might occur while QEMU is not in the main I/O thread. However, it's invalid to call vm_stop when we're neither in a VCPU thread nor in the main I/O thread, even if we were to take the iothread mutex around it. To avoid this problem, we can raise a request to the main I/O thread, similar to what QEMU does when vm_stop is called from a CPU thread. We know that bdrv_error_action is called from an AIO callback, and the moment at which the callback will fire is not well-defined; it depends on the moment at which the disk or OS finishes the operation, which can happen at any time. Note that QEMU is certainly not in a CPU thread and we do not need to call cpu_stop_current() like vm_stop() does. However, we need to ensure that any action taken by management will result in correct detection of the error _and_ a running VM. In particular: - the event must be raised after the iostatus has been set, so that "info block" will return an iostatus that matches the event. - the VM must be stopped after the iostatus has been set, so that "info block" will return an iostatus that matches the runstate. The ordering between the STOP and BLOCK_IO_ERROR events is preserved; BLOCK_IO_ERROR is documented to come first. This makes bdrv_error_action() thread safe (assuming QMP events are, which is attacked by a separate series). Signed-off-by: Paolo Bonzini Reviewed-by: Eric Blake Signed-off-by: Stefan Hajnoczi --- stubs/vm-stop.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'stubs') diff --git a/stubs/vm-stop.c b/stubs/vm-stop.c index f82c897dfe..69fd86b2e8 100644 --- a/stubs/vm-stop.c +++ b/stubs/vm-stop.c @@ -1,7 +1,12 @@ #include "qemu-common.h" #include "sysemu/sysemu.h" -int vm_stop(RunState state) +void qemu_system_vmstop_request_prepare(void) +{ + abort(); +} + +void qemu_system_vmstop_request(RunState state) { abort(); } -- cgit v1.2.1