[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 11/47] block: reorganize io error code
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 11/47] block: reorganize io error code |
Date: |
Tue, 24 Jul 2012 13:03:49 +0200 |
Move the common part of IDE/SCSI/virtio error handling to the block
layer. The new function bdrv_error_action subsumes all three of
bdrv_emit_qmp_error_event, vm_stop, bdrv_iostatus_set_err.
The same scheme will be used for errors in block jobs.
Signed-off-by: Paolo Bonzini <address@hidden>
---
block.c | 46 ++++++++++++++++++++++++++++++++++++++--------
block.h | 5 +++--
hw/ide/core.c | 20 +++++---------------
hw/scsi-disk.c | 23 +++++++----------------
hw/virtio-blk.c | 19 +++++--------------
qemu-tool.c | 6 ++++++
6 files changed, 64 insertions(+), 55 deletions(-)
diff --git a/block.c b/block.c
index 5cd3a4b..333a8fd 100644
--- a/block.c
+++ b/block.c
@@ -29,6 +29,7 @@
#include "blockjob.h"
#include "module.h"
#include "qjson.h"
+#include "sysemu.h"
#include "qemu-coroutine.h"
#include "qmp-commands.h"
#include "qemu-timer.h"
@@ -1152,8 +1153,8 @@ void bdrv_set_dev_ops(BlockDriverState *bs, const
BlockDevOps *ops,
}
}
-void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
- BlockErrorAction action, int is_read)
+static void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
+ BlockErrorAction action, int is_read)
{
QObject *data;
const char *action_str;
@@ -2147,6 +2148,39 @@ BlockdevOnError bdrv_get_on_error(BlockDriverState *bs,
int is_read)
return is_read ? bs->on_read_error : bs->on_write_error;
}
+BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, int is_read, int
error)
+{
+ BlockdevOnError on_err = is_read ? bs->on_read_error : bs->on_write_error;
+
+ switch (on_err) {
+ case BLOCKDEV_ON_ERROR_ENOSPC:
+ return (error == ENOSPC) ? BDRV_ACTION_STOP : BDRV_ACTION_REPORT;
+ case BLOCKDEV_ON_ERROR_STOP:
+ return BDRV_ACTION_STOP;
+ case BLOCKDEV_ON_ERROR_REPORT:
+ return BDRV_ACTION_REPORT;
+ case BLOCKDEV_ON_ERROR_IGNORE:
+ return BDRV_ACTION_IGNORE;
+ default:
+ abort();
+ }
+}
+
+/* This is done by device models because, while the block layer knows
+ * about the error, it does not know whether an operation comes from
+ * the device or the block layer (from a job, for example).
+ */
+void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
+ int is_read, int error)
+{
+ assert(error >= 0);
+ bdrv_emit_qmp_error_event(bs, action, is_read);
+ if (action == BDRV_ACTION_STOP) {
+ vm_stop(RUN_STATE_IO_ERROR);
+ bdrv_iostatus_set_err(bs, error);
+ }
+}
+
int bdrv_is_read_only(BlockDriverState *bs)
{
return bs->read_only;
@@ -3846,14 +3880,10 @@ void bdrv_iostatus_reset(BlockDriverState *bs)
}
}
-/* XXX: Today this is set by device models because it makes the implementation
- quite simple. However, the block layer knows about the error, so it's
- possible to implement this without device models being involved */
void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
{
- if (bdrv_iostatus_is_enabled(bs) &&
- bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
- assert(error >= 0);
+ assert(bdrv_iostatus_is_enabled(bs));
+ if (bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
bs->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
BLOCK_DEVICE_IO_STATUS_FAILED;
}
diff --git a/block.h b/block.h
index f0466b8..935e04e 100644
--- a/block.h
+++ b/block.h
@@ -97,8 +97,6 @@ void bdrv_iostatus_reset(BlockDriverState *bs);
void bdrv_iostatus_disable(BlockDriverState *bs);
bool bdrv_iostatus_is_enabled(const BlockDriverState *bs);
void bdrv_iostatus_set_err(BlockDriverState *bs, int error);
-void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
- BlockErrorAction action, int is_read);
void bdrv_info_print(Monitor *mon, const QObject *data);
void bdrv_info(Monitor *mon, QObject **ret_data);
void bdrv_stats_print(Monitor *mon, const QObject *data);
@@ -257,6 +255,9 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t
sector_num, int nb_sectors,
void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error,
BlockdevOnError on_write_error);
BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, int is_read);
+BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, int is_read, int
error);
+void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
+ int is_read, int error);
int bdrv_is_read_only(BlockDriverState *bs);
int bdrv_is_sg(BlockDriverState *bs);
int bdrv_enable_write_cache(BlockDriverState *bs);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 73f830d..cb5ca4b 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -559,31 +559,21 @@ void ide_dma_error(IDEState *s)
static int ide_handle_rw_error(IDEState *s, int error, int op)
{
int is_read = (op & BM_STATUS_RETRY_READ);
- BlockdevOnError action = bdrv_get_on_error(s->bs, is_read);
+ BlockErrorAction action = bdrv_get_error_action(s->bs, is_read, error);
- if (action == BLOCKDEV_ON_ERROR_IGNORE) {
- bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read);
- return 0;
- }
-
- if ((error == ENOSPC && action == BLOCKDEV_ON_ERROR_ENOSPC)
- || action == BLOCKDEV_ON_ERROR_STOP) {
+ if (action == BDRV_ACTION_STOP) {
s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
s->bus->error_status = op;
- bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_STOP, is_read);
- vm_stop(RUN_STATE_IO_ERROR);
- bdrv_iostatus_set_err(s->bs, error);
- } else {
+ } else if (action == BDRV_ACTION_REPORT) {
if (op & BM_STATUS_DMA_RETRY) {
dma_buf_commit(s);
ide_dma_error(s);
} else {
ide_rw_error(s);
}
- bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_REPORT, is_read);
}
-
- return 1;
+ bdrv_error_action(s->bs, action, is_read, error);
+ return action != BDRV_ACTION_IGNORE;
}
void ide_dma_cb(void *opaque, int ret)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 39d0053..39a2830 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -392,21 +392,9 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
{
int is_read = (r->req.cmd.xfer == SCSI_XFER_FROM_DEV);
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
- BlockdevOnError action = bdrv_get_on_error(s->qdev.conf.bs, is_read);
+ BlockErrorAction action = bdrv_get_error_action(s->qdev.conf.bs, is_read,
error);
- if (action == BLOCKDEV_ON_ERROR_IGNORE) {
- bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE,
is_read);
- return 0;
- }
-
- if ((error == ENOSPC && action == BLOCKDEV_ON_ERROR_ENOSPC)
- || action == BLOCKDEV_ON_ERROR_STOP) {
-
- bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_STOP, is_read);
- vm_stop(RUN_STATE_IO_ERROR);
- bdrv_iostatus_set_err(s->qdev.conf.bs, error);
- scsi_req_retry(&r->req);
- } else {
+ if (action == BDRV_ACTION_REPORT) {
switch (error) {
case ENOMEDIUM:
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
@@ -421,9 +409,12 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
scsi_check_condition(r, SENSE_CODE(IO_ERROR));
break;
}
- bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_REPORT,
is_read);
}
- return 1;
+ bdrv_error_action(s->qdev.conf.bs, action, is_read, error);
+ if (action == BDRV_ACTION_STOP) {
+ scsi_req_retry(&r->req);
+ }
+ return action != BDRV_ACTION_IGNORE;
}
static void scsi_write_complete(void * opaque, int ret)
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 095e84c..d8031ec 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -66,29 +66,20 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req,
int status)
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
int is_read)
{
- BlockdevOnError action = bdrv_get_on_error(req->dev->bs, is_read);
+ BlockErrorAction action = bdrv_get_error_action(req->dev->bs, is_read,
error);
VirtIOBlock *s = req->dev;
- if (action == BLOCKDEV_ON_ERROR_IGNORE) {
- bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read);
- return 0;
- }
-
- if ((error == ENOSPC && action == BLOCKDEV_ON_ERROR_ENOSPC)
- || action == BLOCKDEV_ON_ERROR_STOP) {
+ if (action == BDRV_ACTION_STOP) {
req->next = s->rq;
s->rq = req;
- bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_STOP, is_read);
- vm_stop(RUN_STATE_IO_ERROR);
- bdrv_iostatus_set_err(s->bs, error);
- } else {
+ } else if (action == BDRV_ACTION_REPORT) {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
bdrv_acct_done(s->bs, &req->acct);
g_free(req);
- bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_REPORT, is_read);
}
- return 1;
+ bdrv_error_action(s->bs, action, is_read, error);
+ return action != BDRV_ACTION_IGNORE;
}
static void virtio_blk_rw_complete(void *opaque, int ret)
diff --git a/qemu-tool.c b/qemu-tool.c
index 318c5fc..a59c24c 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -19,6 +19,7 @@
#include "qemu-log.h"
#include "migration.h"
#include "main-loop.h"
+#include "sysemu.h"
#include "qemu_socket.h"
#include "slirp/libslirp.h"
@@ -32,6 +33,11 @@ struct QEMUBH
Monitor *cur_mon;
+void vm_stop(RunState state)
+{
+ abort();
+}
+
int monitor_cur_is_qmp(void)
{
return 0;
--
1.7.10.4
- [Qemu-devel] [PATCH 06/47] qmp: add block-job-pause and block-job-resume, (continued)
- [Qemu-devel] [PATCH 06/47] qmp: add block-job-pause and block-job-resume, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 03/47] block: move job APIs to separate files, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 07/47] qemu-iotests: add test for pausing a streaming operation, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 08/47] block: rename block_job_complete to block_job_completed, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 10/47] block: move BlockdevOnError declaration to QAPI, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 09/47] block: rename BlockErrorAction, BlockQMPEventAction, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 12/47] block: sort BlockDeviceIoStatus errors by severity, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 13/47] block: introduce block job error, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 11/47] block: reorganize io error code,
Paolo Bonzini <=
- [Qemu-devel] [PATCH 16/47] qemu-iotests: map underscore to dash in QMP argument names, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 15/47] blkdebug: process all set_state rules in the old state, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 14/47] stream: add on-error argument, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 19/47] block: add bdrv_query_info, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 20/47] block: add bdrv_query_stats, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 26/47] block: introduce BLOCK_JOB_READY event, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 27/47] block: introduce mirror job, Paolo Bonzini, 2012/07/24