From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Stefan Hajnoczi <stefanha@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: [Qemu-devel] [PULL 6/6] block: asynchronously stop the VM on I/O errors
Date: Mon, 23 Jun 2014 17:31:19 +0800 [thread overview]
Message-ID: <1403515879-14359-7-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1403515879-14359-1-git-send-email-stefanha@redhat.com>
From: Paolo Bonzini <pbonzini@redhat.com>
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 <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block.c | 21 +++++++++++++++++++--
docs/qmp/qmp-events.txt | 2 +-
stubs/vm-stop.c | 7 ++++++-
3 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index 43abe96..ff44e76 100644
--- a/block.c
+++ b/block.c
@@ -3626,10 +3626,27 @@ void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
bool is_read, int error)
{
assert(error >= 0);
- bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, is_read);
+
if (action == BDRV_ACTION_STOP) {
- vm_stop(RUN_STATE_IO_ERROR);
+ /* First set the iostatus, so that "info block" returns an iostatus
+ * that matches the events raised so far (an additional error iostatus
+ * is fine, but not a lost one).
+ */
bdrv_iostatus_set_err(bs, error);
+
+ /* Then raise the request to stop the VM and the event.
+ * qemu_system_vmstop_request_prepare has two effects. First,
+ * it ensures that the STOP event always comes after the
+ * BLOCK_IO_ERROR event. Second, it ensures that even if management
+ * can observe the STOP event and do a "cont" before the STOP
+ * event is issued, the VM will not stop. In this case, vm_start()
+ * also ensures that the STOP/RESUME pair of events is emitted.
+ */
+ qemu_system_vmstop_request_prepare();
+ bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, is_read);
+ qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
+ } else {
+ bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, is_read);
}
}
diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt
index 019db53..22fea58 100644
--- a/docs/qmp/qmp-events.txt
+++ b/docs/qmp/qmp-events.txt
@@ -62,7 +62,7 @@ Data:
- "action": action that has been taken, it's one of the following (json-string):
"ignore": error has been ignored
"report": error has been reported to the device
- "stop": error caused VM to be stopped
+ "stop": the VM is going to stop because of the error
Example:
diff --git a/stubs/vm-stop.c b/stubs/vm-stop.c
index f82c897..69fd86b 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();
}
--
1.9.3
next prev parent reply other threads:[~2014-06-23 9:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-23 9:31 [Qemu-devel] [PULL 0/6] Block patches Stefan Hajnoczi
2014-06-23 9:31 ` [Qemu-devel] [PULL 1/6] block: m25p80: sync_page(): Deindent function body Stefan Hajnoczi
2014-06-23 9:31 ` [Qemu-devel] [PULL 2/6] block: m25p80: Support read only bdrvs Stefan Hajnoczi
2014-06-23 9:31 ` [Qemu-devel] [PULL 3/6] QemuOpts: check NULL opts in qemu_opt_get functions Stefan Hajnoczi
2014-06-23 9:31 ` [Qemu-devel] [PULL 4/6] sheepdog: fix NULL dereference in sd_create Stefan Hajnoczi
2014-06-23 9:31 ` [Qemu-devel] [PULL 5/6] vl: allow other threads to do qemu_system_vmstop_request Stefan Hajnoczi
2014-06-23 9:31 ` Stefan Hajnoczi [this message]
2014-06-23 12:18 ` [Qemu-devel] [PULL 0/6] Block patches Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1403515879-14359-7-git-send-email-stefanha@redhat.com \
--to=stefanha@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).