diff options
author | Anthony Liguori | 2012-10-05 02:53:50 +0200 |
---|---|---|
committer | Anthony Liguori | 2012-10-05 02:53:50 +0200 |
commit | 05d4f2f2ca6053bfea2e97cf324901ca18e49c76 (patch) | |
tree | eeac556997cb7a8d45472919fe9b59a41ba9ed71 /hw | |
parent | Merge remote-tracking branch 'qmp/queue/qmp' into staging (diff) | |
parent | qemu-iotests: add tests for streaming error handling (diff) | |
download | qemu-05d4f2f2ca6053bfea2e97cf324901ca18e49c76.tar.gz qemu-05d4f2f2ca6053bfea2e97cf324901ca18e49c76.tar.xz qemu-05d4f2f2ca6053bfea2e97cf324901ca18e49c76.zip |
Merge remote-tracking branch 'kwolf/for-anthony' into staging
* kwolf/for-anthony: (30 commits)
qemu-iotests: add tests for streaming error handling
qemu-iotests: map underscore to dash in QMP argument names
blkdebug: process all set_state rules in the old state
stream: add on-error argument
block: introduce block job error
iostatus: reorganize io error code
iostatus: change is_read to a bool
iostatus: move BlockdevOnError declaration to QAPI
iostatus: rename BlockErrorAction, BlockQMPEventAction
qemu-iotests: add test for pausing a streaming operation
qmp: add block-job-pause and block-job-resume
block: add support for job pause/resume
qmp: add 'busy' member to BlockJobInfo
block: add block_job_query
block: move job APIs to separate files
block: fix documentation of block_job_cancel_sync
qerror/block: introduce QERR_BLOCK_JOB_NOT_ACTIVE
qemu-iotests: add initial tests for live block commit
QAPI: add command for live block commit, 'block-commit'
block: helper function, to find the base image of a chain
...
Diffstat (limited to 'hw')
-rw-r--r-- | hw/fdc.c | 4 | ||||
-rw-r--r-- | hw/ide/core.c | 22 | ||||
-rw-r--r-- | hw/ide/pci.c | 4 | ||||
-rw-r--r-- | hw/scsi-disk.c | 25 | ||||
-rw-r--r-- | hw/scsi-generic.c | 4 | ||||
-rw-r--r-- | hw/virtio-blk.c | 23 |
6 files changed, 27 insertions, 55 deletions
@@ -1994,11 +1994,11 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl) drive->fdctrl = fdctrl; if (drive->bs) { - if (bdrv_get_on_error(drive->bs, 0) != BLOCK_ERR_STOP_ENOSPC) { + if (bdrv_get_on_error(drive->bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) { error_report("fdc doesn't support drive option werror"); return -1; } - if (bdrv_get_on_error(drive->bs, 1) != BLOCK_ERR_REPORT) { + if (bdrv_get_on_error(drive->bs, 1) != BLOCKDEV_ON_ERROR_REPORT) { error_report("fdc doesn't support drive option rerror"); return -1; } diff --git a/hw/ide/core.c b/hw/ide/core.c index d6fb69c634..d683a8cc84 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -556,32 +556,22 @@ 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); - BlockErrorAction action = bdrv_get_on_error(s->bs, is_read); + bool is_read = (op & BM_STATUS_RETRY_READ) != 0; + BlockErrorAction action = bdrv_get_error_action(s->bs, is_read, error); - if (action == BLOCK_ERR_IGNORE) { - bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read); - return 0; - } - - if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC) - || action == BLOCK_ERR_STOP_ANY) { + 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/ide/pci.c b/hw/ide/pci.c index 88c0942e34..644533f777 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -188,7 +188,7 @@ static void bmdma_restart_bh(void *opaque) { BMDMAState *bm = opaque; IDEBus *bus = bm->bus; - int is_read; + bool is_read; int error_status; qemu_bh_delete(bm->bh); @@ -198,7 +198,7 @@ static void bmdma_restart_bh(void *opaque) return; } - is_read = !!(bus->error_status & BM_STATUS_RETRY_READ); + is_read = (bus->error_status & BM_STATUS_RETRY_READ) != 0; /* The error status must be cleared before resubmitting the request: The * request may fail again, and this case can only be distinguished if the diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 95e91585e6..99bb02ebf8 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -386,23 +386,11 @@ static void scsi_read_data(SCSIRequest *req) */ static int scsi_handle_rw_error(SCSIDiskReq *r, int error) { - int is_read = (r->req.cmd.xfer == SCSI_XFER_FROM_DEV); + bool is_read = (r->req.cmd.xfer == SCSI_XFER_FROM_DEV); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - BlockErrorAction 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 == BLOCK_ERR_IGNORE) { - bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE, is_read); - return 0; - } - - if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC) - || action == BLOCK_ERR_STOP_ANY) { - - 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)); @@ -417,9 +405,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/scsi-generic.c b/hw/scsi-generic.c index a5eb663ecf..d9045341ba 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -400,11 +400,11 @@ static int scsi_generic_initfn(SCSIDevice *s) return -1; } - if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) { + if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) { error_report("Device doesn't support drive option werror"); return -1; } - if (bdrv_get_on_error(s->conf.bs, 1) != BLOCK_ERR_REPORT) { + if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) { error_report("Device doesn't support drive option rerror"); return -1; } diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 6f6d172fd0..e25cc96477 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -64,31 +64,22 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) } static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, - int is_read) + bool is_read) { - BlockErrorAction 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 == BLOCK_ERR_IGNORE) { - bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read); - return 0; - } - - if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC) - || action == BLOCK_ERR_STOP_ANY) { + 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) @@ -98,7 +89,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret) trace_virtio_blk_rw_complete(req, ret); if (ret) { - int is_read = !(ldl_p(&req->out->type) & VIRTIO_BLK_T_OUT); + bool is_read = !(ldl_p(&req->out->type) & VIRTIO_BLK_T_OUT); if (virtio_blk_handle_rw_error(req, -ret, is_read)) return; } |