* [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support @ 2011-09-26 20:43 Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino ` (9 more replies) 0 siblings, 10 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-26 20:43 UTC (permalink / raw) To: kwolf; +Cc: zwu.kernel, armbru, qemu-devel This series adds support to the block layer to keep track of devices' I/O status. That information is also made available in QMP and HMP. The goal here is to allow management applications that miss the BLOCK_IO_ERROR event to able to query the VM to determine if any device has caused the VM to stop and which device caused it. Here's an HMP example: (qemu) info status VM status: paused (io-error) (qemu) info block ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] floppy0: removable=1 locked=0 [not inserted] sd0: removable=1 locked=0 [not inserted] The session above shows that the VM is stopped due to an I/O error. By using the info block command it's possible to determine that the 'ide0-hd1' device caused the error, which turns out to be due to no space. changelog --------- v3 o Introduce bdrv_iostatus_disable() o Also reset the I/O status on bdrv_attach_dev() o Fix bad assert() in bdrv_iostatus_enable() o Improve documentation v2 o Rebase against latest master o Renamed bdrv_iostatus_update() to bdrv_iostatus_set_err() o Minor changelog clarifications block.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ block.h | 10 +++++++++ block_int.h | 1 + hw/ide/core.c | 2 + hw/scsi-disk.c | 2 + hw/virtio-blk.c | 2 + monitor.c | 6 +++++ qmp-commands.hx | 6 +++++ 8 files changed, 86 insertions(+), 0 deletions(-) ^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino @ 2011-09-26 20:43 ` Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 2/6] virtio: Support " Luiz Capitulino ` (8 subsequent siblings) 9 siblings, 0 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-26 20:43 UTC (permalink / raw) To: kwolf; +Cc: zwu.kernel, armbru, qemu-devel This commit adds support to the BlockDriverState type to keep track of devices' I/O status. There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC (no space error) and BDRV_IOS_FAILED (any other error). The distinction between no space and other errors is important because a management application may want to watch for no space in order to extend the space assigned to the VM and put it to run again. Qemu devices supporting the I/O status feature have to enable it explicitly by calling bdrv_iostatus_enable() _and_ have to be configured to stop the VM on errors (ie. werror=stop|enospc or rerror=stop). In case of multiple errors being triggered in sequence only the first one is stored. The I/O status is always reset to BDRV_IOS_OK when the 'cont' command is issued. Next commits will add support to some devices and extend the query-block/info block commands to return the I/O status information. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- block.c | 40 ++++++++++++++++++++++++++++++++++++++++ block.h | 10 ++++++++++ block_int.h | 1 + monitor.c | 6 ++++++ 4 files changed, 57 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index e3fe97f..96b047b 100644 --- a/block.c +++ b/block.c @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) if (device_name[0] != '\0') { QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); } + bdrv_iostatus_disable(bs); return bs; } @@ -770,6 +771,7 @@ int bdrv_attach_dev(BlockDriverState *bs, void *dev) return -EBUSY; } bs->dev = dev; + bdrv_iostatus_reset(bs); return 0; } @@ -3181,6 +3183,44 @@ int bdrv_in_use(BlockDriverState *bs) return bs->in_use; } +void bdrv_iostatus_enable(BlockDriverState *bs) +{ + bs->iostatus = BDRV_IOS_OK; +} + +/* The I/O status is only enabled if the drive explicitly + * enables it _and_ the VM is configured to stop on errors */ +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) +{ + return (bs->iostatus != BDRV_IOS_INVAL && + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || + bs->on_write_error == BLOCK_ERR_STOP_ANY || + bs->on_read_error == BLOCK_ERR_STOP_ANY)); +} + +void bdrv_iostatus_disable(BlockDriverState *bs) +{ + bs->iostatus = BDRV_IOS_INVAL; +} + +void bdrv_iostatus_reset(BlockDriverState *bs) +{ + if (bdrv_iostatus_is_enabled(bs)) { + bs->iostatus = BDRV_IOS_OK; + } +} + +/* 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 == BDRV_IOS_OK) { + assert(error >= 0); + bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED; + } +} + void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, enum BlockAcctType type) diff --git a/block.h b/block.h index 16bfa0a..e77988e 100644 --- a/block.h +++ b/block.h @@ -77,6 +77,16 @@ typedef enum { BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP } BlockMonEventAction; +typedef enum { + BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, + BDRV_IOS_MAX +} BlockIOStatus; + +void bdrv_iostatus_enable(BlockDriverState *bs); +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_mon_event(const BlockDriverState *bdrv, BlockMonEventAction action, int is_read); void bdrv_info_print(Monitor *mon, const QObject *data); diff --git a/block_int.h b/block_int.h index 8c3b863..f2f4f2d 100644 --- a/block_int.h +++ b/block_int.h @@ -199,6 +199,7 @@ struct BlockDriverState { drivers. They are not used by the block driver */ int cyls, heads, secs, translation; BlockErrorAction on_read_error, on_write_error; + BlockIOStatus iostatus; char device_name[32]; unsigned long *dirty_bitmap; int64_t dirty_count; diff --git a/monitor.c b/monitor.c index 8ec2c5e..88d8228 100644 --- a/monitor.c +++ b/monitor.c @@ -1304,6 +1304,11 @@ struct bdrv_iterate_context { int err; }; +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +{ + bdrv_iostatus_reset(bs); +} + /** * do_cont(): Resume emulation. */ @@ -1320,6 +1325,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) return -1; } + bdrv_iterate(iostatus_bdrv_it, NULL); bdrv_iterate(encrypted_bdrv_it, &context); /* only resume the vm if all keys are set and valid */ if (!context.err) { -- 1.7.7.rc0.72.g4b5ea ^ permalink raw reply related [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH 2/6] virtio: Support I/O status 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino @ 2011-09-26 20:43 ` Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 3/6] ide: " Luiz Capitulino ` (7 subsequent siblings) 9 siblings, 0 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-26 20:43 UTC (permalink / raw) To: kwolf; +Cc: zwu.kernel, armbru, qemu-devel Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- hw/virtio-blk.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index daa8e42..bd63a85 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -78,6 +78,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, s->rq = req; bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); vm_stop(RSTATE_IO_ERROR); + bdrv_iostatus_set_err(s->bs, error); } else { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); bdrv_acct_done(s->bs, &req->acct); @@ -603,6 +604,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf, bdrv_set_dev_ops(s->bs, &virtio_block_ops, s); bdrv_set_buffer_alignment(s->bs, conf->logical_block_size); + bdrv_iostatus_enable(s->bs); add_boot_device_path(conf->bootindex, dev, "/disk@0,0"); return &s->vdev; -- 1.7.7.rc0.72.g4b5ea ^ permalink raw reply related [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH 3/6] ide: Support I/O status 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 2/6] virtio: Support " Luiz Capitulino @ 2011-09-26 20:43 ` Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 4/6] scsi: " Luiz Capitulino ` (6 subsequent siblings) 9 siblings, 0 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-26 20:43 UTC (permalink / raw) To: kwolf; +Cc: zwu.kernel, armbru, qemu-devel Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- hw/ide/core.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 4e76fc7..9ec1310 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -528,6 +528,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) s->bus->error_status = op; bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); vm_stop(RSTATE_IO_ERROR); + bdrv_iostatus_set_err(s->bs, error); } else { if (op & BM_STATUS_DMA_RETRY) { dma_buf_commit(s, 0); @@ -1872,6 +1873,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, } ide_reset(s); + bdrv_iostatus_enable(bs); return 0; } -- 1.7.7.rc0.72.g4b5ea ^ permalink raw reply related [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH 4/6] scsi: Support I/O status 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino ` (2 preceding siblings ...) 2011-09-26 20:43 ` [Qemu-devel] [PATCH 3/6] ide: " Luiz Capitulino @ 2011-09-26 20:43 ` Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 5/6] QMP: query-status: Add 'io-status' key Luiz Capitulino ` (5 subsequent siblings) 9 siblings, 0 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-26 20:43 UTC (permalink / raw) To: kwolf; +Cc: zwu.kernel, armbru, qemu-devel Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- hw/scsi-disk.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index e843f71..a980a53 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -228,6 +228,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); vm_stop(RSTATE_IO_ERROR); + bdrv_iostatus_set_err(s->bs, error); } else { switch (error) { case ENOMEM: @@ -1260,6 +1261,7 @@ static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type) s->qdev.type = scsi_type; qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s); + bdrv_iostatus_enable(s->bs); add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0"); return 0; } -- 1.7.7.rc0.72.g4b5ea ^ permalink raw reply related [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH 5/6] QMP: query-status: Add 'io-status' key 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino ` (3 preceding siblings ...) 2011-09-26 20:43 ` [Qemu-devel] [PATCH 4/6] scsi: " Luiz Capitulino @ 2011-09-26 20:43 ` Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 6/6] HMP: Print 'io-status' information Luiz Capitulino ` (4 subsequent siblings) 9 siblings, 0 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-26 20:43 UTC (permalink / raw) To: kwolf; +Cc: zwu.kernel, armbru, qemu-devel Contains the I/O status for the given device. The key is only present if the device supports it and the VM is configured to stop on errors. Please, check the documentation being added in this commit for more information. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- block.c | 12 ++++++++++++ qmp-commands.hx | 6 ++++++ 2 files changed, 18 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index 96b047b..7053c80 100644 --- a/block.c +++ b/block.c @@ -1891,6 +1891,12 @@ void bdrv_info_print(Monitor *mon, const QObject *data) qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); } +static const char *const io_status_name[BDRV_IOS_MAX] = { + [BDRV_IOS_OK] = "ok", + [BDRV_IOS_FAILED] = "failed", + [BDRV_IOS_ENOSPC] = "nospace", +}; + void bdrv_info(Monitor *mon, QObject **ret_data) { QList *bs_list; @@ -1913,6 +1919,12 @@ void bdrv_info(Monitor *mon, QObject **ret_data) qdict_put(bs_dict, "tray-open", qbool_from_int(bdrv_dev_is_tray_open(bs))); } + + if (bdrv_iostatus_is_enabled(bs)) { + qdict_put(bs_dict, "io-status", + qstring_from_str(io_status_name[bs->iostatus])); + } + if (bs->drv) { QObject *obj; diff --git a/qmp-commands.hx b/qmp-commands.hx index d83bce5..34cc353 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1145,6 +1145,10 @@ Each json-object contain the following: "tftp", "vdi", "vmdk", "vpc", "vvfat" - "backing_file": backing file name (json-string, optional) - "encrypted": true if encrypted, false otherwise (json-bool) +- "io-status": I/O operation status, only present if the device supports it + and the VM is configured to stop on errors. It's always reset + to "ok" when the "cont" command is issued (json_string, optional) + - Possible values: "ok", "failed", "nospace" Example: @@ -1152,6 +1156,7 @@ Example: <- { "return":[ { + "io-status": "ok", "device":"ide0-hd0", "locked":false, "removable":false, @@ -1164,6 +1169,7 @@ Example: "type":"unknown" }, { + "io-status": "ok", "device":"ide1-cd0", "locked":false, "removable":true, -- 1.7.7.rc0.72.g4b5ea ^ permalink raw reply related [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH 6/6] HMP: Print 'io-status' information 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino ` (4 preceding siblings ...) 2011-09-26 20:43 ` [Qemu-devel] [PATCH 5/6] QMP: query-status: Add 'io-status' key Luiz Capitulino @ 2011-09-26 20:43 ` Luiz Capitulino 2011-09-27 18:40 ` [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Markus Armbruster ` (3 subsequent siblings) 9 siblings, 0 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-26 20:43 UTC (permalink / raw) To: kwolf; +Cc: zwu.kernel, armbru, qemu-devel Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- block.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index 7053c80..061b4cc 100644 --- a/block.c +++ b/block.c @@ -1866,6 +1866,11 @@ static void bdrv_print_dict(QObject *obj, void *opaque) monitor_printf(mon, " tray-open=%d", qdict_get_bool(bs_dict, "tray-open")); } + + if (qdict_haskey(bs_dict, "io-status")) { + monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status")); + } + if (qdict_haskey(bs_dict, "inserted")) { QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted")); -- 1.7.7.rc0.72.g4b5ea ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino ` (5 preceding siblings ...) 2011-09-26 20:43 ` [Qemu-devel] [PATCH 6/6] HMP: Print 'io-status' information Luiz Capitulino @ 2011-09-27 18:40 ` Markus Armbruster 2011-09-28 9:45 ` hkran ` (2 subsequent siblings) 9 siblings, 0 replies; 25+ messages in thread From: Markus Armbruster @ 2011-09-27 18:40 UTC (permalink / raw) To: Luiz Capitulino; +Cc: kwolf, zwu.kernel, qemu-devel Luiz Capitulino <lcapitulino@redhat.com> writes: > This series adds support to the block layer to keep track of devices' > I/O status. That information is also made available in QMP and HMP. > > The goal here is to allow management applications that miss the > BLOCK_IO_ERROR event to able to query the VM to determine if any device has > caused the VM to stop and which device caused it. > > Here's an HMP example: > > (qemu) info status > VM status: paused (io-error) > (qemu) info block > ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 > ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 > ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] > floppy0: removable=1 locked=0 [not inserted] > sd0: removable=1 locked=0 [not inserted] > > The session above shows that the VM is stopped due to an I/O error. By using > the info block command it's possible to determine that the 'ide0-hd1' device > caused the error, which turns out to be due to no space. Reviewed-by: Markus Armbruster <armbru@redhat.com> ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino ` (6 preceding siblings ...) 2011-09-27 18:40 ` [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Markus Armbruster @ 2011-09-28 9:45 ` hkran 2011-09-28 20:00 ` Luiz Capitulino 2011-09-29 7:20 ` Mark Wu 2011-10-10 17:30 ` Kevin Wolf 9 siblings, 1 reply; 25+ messages in thread From: hkran @ 2011-09-28 9:45 UTC (permalink / raw) To: Luiz Capitulino; +Cc: kwolf, zwu.kernel, armbru, qemu-devel On 09/27/2011 04:43 AM, Luiz Capitulino wrote: > This series adds support to the block layer to keep track of devices' > I/O status. That information is also made available in QMP and HMP. > > The goal here is to allow management applications that miss the > BLOCK_IO_ERROR event to able to query the VM to determine if any device has > caused the VM to stop and which device caused it. > > Here's an HMP example: > > (qemu) info status > VM status: paused (io-error) > (qemu) info block > ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 > ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 > ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] > floppy0: removable=1 locked=0 [not inserted] > sd0: removable=1 locked=0 [not inserted] > > The session above shows that the VM is stopped due to an I/O error. By using > the info block command it's possible to determine that the 'ide0-hd1' device > caused the error, which turns out to be due to no space. > > changelog > --------- > > v3 > > o Introduce bdrv_iostatus_disable() > o Also reset the I/O status on bdrv_attach_dev() > o Fix bad assert() in bdrv_iostatus_enable() > o Improve documentation > > v2 > > o Rebase against latest master > o Renamed bdrv_iostatus_update() to bdrv_iostatus_set_err() > o Minor changelog clarifications > > block.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > block.h | 10 +++++++++ > block_int.h | 1 + > hw/ide/core.c | 2 + > hw/scsi-disk.c | 2 + > hw/virtio-blk.c | 2 + > monitor.c | 6 +++++ > qmp-commands.hx | 6 +++++ > 8 files changed, 86 insertions(+), 0 deletions(-) > Hi, How to reproduce a scenario in which the VM is stopped due to the I/O error? I tried several times by copying data from one place to another place in guest OS and finally the system prompted me that there is no space is available, however it did not cause any I/O error and not stop the VM either. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support 2011-09-28 9:45 ` hkran @ 2011-09-28 20:00 ` Luiz Capitulino 0 siblings, 0 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-28 20:00 UTC (permalink / raw) To: hkran; +Cc: kwolf, zwu.kernel, armbru, qemu-devel On Wed, 28 Sep 2011 17:45:27 +0800 hkran <hkran@vnet.linux.ibm.com> wrote: > On 09/27/2011 04:43 AM, Luiz Capitulino wrote: > > This series adds support to the block layer to keep track of devices' > > I/O status. That information is also made available in QMP and HMP. > > > > The goal here is to allow management applications that miss the > > BLOCK_IO_ERROR event to able to query the VM to determine if any device has > > caused the VM to stop and which device caused it. > > > > Here's an HMP example: > > > > (qemu) info status > > VM status: paused (io-error) > > (qemu) info block > > ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 > > ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 > > ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] > > floppy0: removable=1 locked=0 [not inserted] > > sd0: removable=1 locked=0 [not inserted] > > > > The session above shows that the VM is stopped due to an I/O error. By using > > the info block command it's possible to determine that the 'ide0-hd1' device > > caused the error, which turns out to be due to no space. > > > > changelog > > --------- > > > > v3 > > > > o Introduce bdrv_iostatus_disable() > > o Also reset the I/O status on bdrv_attach_dev() > > o Fix bad assert() in bdrv_iostatus_enable() > > o Improve documentation > > > > v2 > > > > o Rebase against latest master > > o Renamed bdrv_iostatus_update() to bdrv_iostatus_set_err() > > o Minor changelog clarifications > > > > block.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > block.h | 10 +++++++++ > > block_int.h | 1 + > > hw/ide/core.c | 2 + > > hw/scsi-disk.c | 2 + > > hw/virtio-blk.c | 2 + > > monitor.c | 6 +++++ > > qmp-commands.hx | 6 +++++ > > 8 files changed, 86 insertions(+), 0 deletions(-) > > > Hi, > > How to reproduce a scenario in which the VM is stopped due to the I/O error? > I tried several times by copying data from one place to another place in > guest OS and finally the system prompted me that there is no space is > available, however it did not > cause any I/O error and not stop the VM either. I use the test-case described here: http://lists.gnu.org/archive/html/qemu-devel/2011-08/msg03800.html ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino ` (7 preceding siblings ...) 2011-09-28 9:45 ` hkran @ 2011-09-29 7:20 ` Mark Wu 2011-10-10 17:30 ` Kevin Wolf 9 siblings, 0 replies; 25+ messages in thread From: Mark Wu @ 2011-09-29 7:20 UTC (permalink / raw) To: qemu-devel On 09/27/2011 04:43 AM, Luiz Capitulino wrote: > This series adds support to the block layer to keep track of devices' > I/O status. That information is also made available in QMP and HMP. > > The goal here is to allow management applications that miss the > BLOCK_IO_ERROR event to able to query the VM to determine if any device has > caused the VM to stop and which device caused it. > > Here's an HMP example: > > (qemu) info status > VM status: paused (io-error) > (qemu) info block > ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 > ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 > ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] > floppy0: removable=1 locked=0 [not inserted] > sd0: removable=1 locked=0 [not inserted] > > The session above shows that the VM is stopped due to an I/O error. By using > the info block command it's possible to determine that the 'ide0-hd1' device > caused the error, which turns out to be due to no space. > > I test it with the options enospc and stop on virtio and scsi models. It works fine. Tested-by: Mark Wu <wudxw@vnet.linux.ibm.com> ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino ` (8 preceding siblings ...) 2011-09-29 7:20 ` Mark Wu @ 2011-10-10 17:30 ` Kevin Wolf 2011-10-10 20:25 ` Luiz Capitulino 9 siblings, 1 reply; 25+ messages in thread From: Kevin Wolf @ 2011-10-10 17:30 UTC (permalink / raw) To: Luiz Capitulino; +Cc: zwu.kernel, armbru, qemu-devel Am 26.09.2011 22:43, schrieb Luiz Capitulino: > This series adds support to the block layer to keep track of devices' > I/O status. That information is also made available in QMP and HMP. > > The goal here is to allow management applications that miss the > BLOCK_IO_ERROR event to able to query the VM to determine if any device has > caused the VM to stop and which device caused it. > > Here's an HMP example: > > (qemu) info status > VM status: paused (io-error) > (qemu) info block > ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 > ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 > ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] > floppy0: removable=1 locked=0 [not inserted] > sd0: removable=1 locked=0 [not inserted] > > The session above shows that the VM is stopped due to an I/O error. By using > the info block command it's possible to determine that the 'ide0-hd1' device > caused the error, which turns out to be due to no space. Thanks, applied all to the block branch. Kevin ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support 2011-10-10 17:30 ` Kevin Wolf @ 2011-10-10 20:25 ` Luiz Capitulino 2011-10-11 7:49 ` Kevin Wolf 0 siblings, 1 reply; 25+ messages in thread From: Luiz Capitulino @ 2011-10-10 20:25 UTC (permalink / raw) To: Kevin Wolf; +Cc: zwu.kernel, armbru, qemu-devel On Mon, 10 Oct 2011 19:30:32 +0200 Kevin Wolf <kwolf@redhat.com> wrote: > Am 26.09.2011 22:43, schrieb Luiz Capitulino: > > This series adds support to the block layer to keep track of devices' > > I/O status. That information is also made available in QMP and HMP. > > > > The goal here is to allow management applications that miss the > > BLOCK_IO_ERROR event to able to query the VM to determine if any device has > > caused the VM to stop and which device caused it. > > > > Here's an HMP example: > > > > (qemu) info status > > VM status: paused (io-error) > > (qemu) info block > > ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 > > ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 > > ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] > > floppy0: removable=1 locked=0 [not inserted] > > sd0: removable=1 locked=0 [not inserted] > > > > The session above shows that the VM is stopped due to an I/O error. By using > > the info block command it's possible to determine that the 'ide0-hd1' device > > caused the error, which turns out to be due to no space. > > Thanks, applied all to the block branch. This series will conflict with my "first round of qapi conversions" series. It seems to me that the conflicts are rather simple, just doing s/RSTATE_/RUN_STATE should fix them, but I can resend the series if you think that's better. > > Kevin > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support 2011-10-10 20:25 ` Luiz Capitulino @ 2011-10-11 7:49 ` Kevin Wolf 0 siblings, 0 replies; 25+ messages in thread From: Kevin Wolf @ 2011-10-11 7:49 UTC (permalink / raw) To: Luiz Capitulino; +Cc: zwu.kernel, armbru, qemu-devel Am 10.10.2011 22:25, schrieb Luiz Capitulino: > On Mon, 10 Oct 2011 19:30:32 +0200 > Kevin Wolf <kwolf@redhat.com> wrote: > >> Am 26.09.2011 22:43, schrieb Luiz Capitulino: >>> This series adds support to the block layer to keep track of devices' >>> I/O status. That information is also made available in QMP and HMP. >>> >>> The goal here is to allow management applications that miss the >>> BLOCK_IO_ERROR event to able to query the VM to determine if any device has >>> caused the VM to stop and which device caused it. >>> >>> Here's an HMP example: >>> >>> (qemu) info status >>> VM status: paused (io-error) >>> (qemu) info block >>> ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 >>> ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 >>> ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] >>> floppy0: removable=1 locked=0 [not inserted] >>> sd0: removable=1 locked=0 [not inserted] >>> >>> The session above shows that the VM is stopped due to an I/O error. By using >>> the info block command it's possible to determine that the 'ide0-hd1' device >>> caused the error, which turns out to be due to no space. >> >> Thanks, applied all to the block branch. > > This series will conflict with my "first round of qapi conversions" series. > > It seems to me that the conflicts are rather simple, just doing > s/RSTATE_/RUN_STATE should fix them, but I can resend the series if you think > that's better. Thanks for the heads-up. It seems to be a trivial conflict indeed and I resolved it myself. Kevin ^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH v2 0/6]: block: Add I/O status support @ 2011-09-22 18:19 Luiz Capitulino 2011-09-22 18:19 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino 0 siblings, 1 reply; 25+ messages in thread From: Luiz Capitulino @ 2011-09-22 18:19 UTC (permalink / raw) To: kwolf; +Cc: armbru, qemu-devel This series adds support to the block layer to keep track of devices' I/O status. That information is also made available in QMP and HMP. The goal here is to allow management applications that miss the BLOCK_IO_ERROR event to able to query the VM to determine if any device has caused the VM to stop and which device caused it. Here's an HMP example: (qemu) info status VM status: paused (io-error) (qemu) info block ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] floppy0: removable=1 locked=0 [not inserted] sd0: removable=1 locked=0 [not inserted] The session above shows that the VM is stopped due to an I/O error. By using the info block command it's possible to determine that the 'ide0-hd1' device caused the error, which turns out to be due to no space. changelog --------- v2 o Rebase against latest master o Renamed bdrv_iostatus_update() to bdrv_iostatus_set_err() o Minor changelog clarifications block.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ block.h | 9 +++++++++ block_int.h | 1 + hw/ide/core.c | 2 ++ hw/scsi-disk.c | 2 ++ hw/virtio-blk.c | 2 ++ monitor.c | 6 ++++++ qmp-commands.hx | 6 ++++++ 8 files changed, 77 insertions(+), 0 deletions(-) ^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-22 18:19 [Qemu-devel] [PATCH v2 " Luiz Capitulino @ 2011-09-22 18:19 ` Luiz Capitulino 2011-09-23 7:06 ` Zhi Yong Wu 2011-09-23 7:51 ` Markus Armbruster 0 siblings, 2 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-22 18:19 UTC (permalink / raw) To: kwolf; +Cc: armbru, qemu-devel This commit adds support to the BlockDriverState type to keep track of devices' I/O status. There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC (no space error) and BDRV_IOS_FAILED (any other error). The distinction between no space and other errors is important because a management application may want to watch for no space in order to extend the space assigned to the VM and put it to run again. Qemu devices supporting the I/O status feature have to enable it explicitly by calling bdrv_iostatus_enable() _and_ have to be configured to stop the VM on errors (ie. werror=stop|enospc or rerror=stop). In case of multiple errors being triggered in sequence only the first one is stored. The I/O status is always reset to BDRV_IOS_OK when the 'cont' command is issued. Next commits will add support to some devices and extend the query-block/info block commands to return the I/O status information. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- block.c | 32 ++++++++++++++++++++++++++++++++ block.h | 9 +++++++++ block_int.h | 1 + monitor.c | 6 ++++++ 4 files changed, 48 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index e3fe97f..fbd90b4 100644 --- a/block.c +++ b/block.c @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) if (device_name[0] != '\0') { QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); } + bs->iostatus = BDRV_IOS_INVAL; return bs; } @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) return bs->in_use; } +void bdrv_iostatus_enable(BlockDriverState *bs) +{ + assert(bs->iostatus == BDRV_IOS_INVAL); + bs->iostatus = BDRV_IOS_OK; +} + +/* The I/O status is only enabled if the drive explicitly + * enables it _and_ the VM is configured to stop on errors */ +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) +{ + return (bs->iostatus != BDRV_IOS_INVAL && + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || + bs->on_write_error == BLOCK_ERR_STOP_ANY || + bs->on_read_error == BLOCK_ERR_STOP_ANY)); +} + +void bdrv_iostatus_reset(BlockDriverState *bs) +{ + if (bdrv_iostatus_is_enabled(bs)) { + bs->iostatus = BDRV_IOS_OK; + } +} + +void bdrv_iostatus_set_err(BlockDriverState *bs, int error) +{ + if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { + bs->iostatus = (abs(error) == ENOSPC) ? BDRV_IOS_ENOSPC : + BDRV_IOS_FAILED; + } +} + void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, enum BlockAcctType type) diff --git a/block.h b/block.h index 16bfa0a..de74af0 100644 --- a/block.h +++ b/block.h @@ -77,6 +77,15 @@ typedef enum { BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP } BlockMonEventAction; +typedef enum { + BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, + BDRV_IOS_MAX +} BlockIOStatus; + +void bdrv_iostatus_enable(BlockDriverState *bs); +void bdrv_iostatus_reset(BlockDriverState *bs); +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs); +void bdrv_iostatus_set_err(BlockDriverState *bs, int error); void bdrv_mon_event(const BlockDriverState *bdrv, BlockMonEventAction action, int is_read); void bdrv_info_print(Monitor *mon, const QObject *data); diff --git a/block_int.h b/block_int.h index 8c3b863..f2f4f2d 100644 --- a/block_int.h +++ b/block_int.h @@ -199,6 +199,7 @@ struct BlockDriverState { drivers. They are not used by the block driver */ int cyls, heads, secs, translation; BlockErrorAction on_read_error, on_write_error; + BlockIOStatus iostatus; char device_name[32]; unsigned long *dirty_bitmap; int64_t dirty_count; diff --git a/monitor.c b/monitor.c index 8ec2c5e..88d8228 100644 --- a/monitor.c +++ b/monitor.c @@ -1304,6 +1304,11 @@ struct bdrv_iterate_context { int err; }; +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +{ + bdrv_iostatus_reset(bs); +} + /** * do_cont(): Resume emulation. */ @@ -1320,6 +1325,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) return -1; } + bdrv_iterate(iostatus_bdrv_it, NULL); bdrv_iterate(encrypted_bdrv_it, &context); /* only resume the vm if all keys are set and valid */ if (!context.err) { -- 1.7.7.rc0.72.g4b5ea ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-22 18:19 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino @ 2011-09-23 7:06 ` Zhi Yong Wu 2011-09-23 7:51 ` Markus Armbruster 1 sibling, 0 replies; 25+ messages in thread From: Zhi Yong Wu @ 2011-09-23 7:06 UTC (permalink / raw) To: Luiz Capitulino; +Cc: kwolf, armbru, qemu-devel On Fri, Sep 23, 2011 at 2:19 AM, Luiz Capitulino <lcapitulino@redhat.com> wrote: > This commit adds support to the BlockDriverState type to keep track > of devices' I/O status. > > There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC > (no space error) and BDRV_IOS_FAILED (any other error). The distinction > between no space and other errors is important because a management > application may want to watch for no space in order to extend the > space assigned to the VM and put it to run again. > > Qemu devices supporting the I/O status feature have to enable it > explicitly by calling bdrv_iostatus_enable() _and_ have to be > configured to stop the VM on errors (ie. werror=stop|enospc or > rerror=stop). > > In case of multiple errors being triggered in sequence only the first > one is stored. The I/O status is always reset to BDRV_IOS_OK when the > 'cont' command is issued. > > Next commits will add support to some devices and extend the > query-block/info block commands to return the I/O status information. > > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> > --- > block.c | 32 ++++++++++++++++++++++++++++++++ > block.h | 9 +++++++++ > block_int.h | 1 + > monitor.c | 6 ++++++ > 4 files changed, 48 insertions(+), 0 deletions(-) > > diff --git a/block.c b/block.c > index e3fe97f..fbd90b4 100644 > --- a/block.c > +++ b/block.c > @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) > if (device_name[0] != '\0') { > QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); > } > + bs->iostatus = BDRV_IOS_INVAL; > return bs; > } bs->iostatus is set to BDRV_IOS_INVAL only in bdrv_new(), if the drive is opened and closed repeatly, how about the field? Moreover, it seems that it has not been reset when the drive is closed via bdrv_close(). > > @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) > return bs->in_use; > } > > +void bdrv_iostatus_enable(BlockDriverState *bs) > +{ > + assert(bs->iostatus == BDRV_IOS_INVAL); > + bs->iostatus = BDRV_IOS_OK; > +} > + > +/* The I/O status is only enabled if the drive explicitly > + * enables it _and_ the VM is configured to stop on errors */ > +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) > +{ > + return (bs->iostatus != BDRV_IOS_INVAL && > + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || > + bs->on_write_error == BLOCK_ERR_STOP_ANY || > + bs->on_read_error == BLOCK_ERR_STOP_ANY)); > +} > + > +void bdrv_iostatus_reset(BlockDriverState *bs) > +{ > + if (bdrv_iostatus_is_enabled(bs)) { > + bs->iostatus = BDRV_IOS_OK; > + } > +} > + > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error) > +{ > + if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { > + bs->iostatus = (abs(error) == ENOSPC) ? BDRV_IOS_ENOSPC : > + BDRV_IOS_FAILED; > + } > +} > + > void > bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, > enum BlockAcctType type) > diff --git a/block.h b/block.h > index 16bfa0a..de74af0 100644 > --- a/block.h > +++ b/block.h > @@ -77,6 +77,15 @@ typedef enum { > BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP > } BlockMonEventAction; > > +typedef enum { > + BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, > + BDRV_IOS_MAX > +} BlockIOStatus; > + > +void bdrv_iostatus_enable(BlockDriverState *bs); > +void bdrv_iostatus_reset(BlockDriverState *bs); > +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs); > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error); > void bdrv_mon_event(const BlockDriverState *bdrv, > BlockMonEventAction action, int is_read); > void bdrv_info_print(Monitor *mon, const QObject *data); > diff --git a/block_int.h b/block_int.h > index 8c3b863..f2f4f2d 100644 > --- a/block_int.h > +++ b/block_int.h > @@ -199,6 +199,7 @@ struct BlockDriverState { > drivers. They are not used by the block driver */ > int cyls, heads, secs, translation; > BlockErrorAction on_read_error, on_write_error; > + BlockIOStatus iostatus; > char device_name[32]; > unsigned long *dirty_bitmap; > int64_t dirty_count; > diff --git a/monitor.c b/monitor.c > index 8ec2c5e..88d8228 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -1304,6 +1304,11 @@ struct bdrv_iterate_context { > int err; > }; > > +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) > +{ > + bdrv_iostatus_reset(bs); > +} > + > /** > * do_cont(): Resume emulation. > */ > @@ -1320,6 +1325,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) > return -1; > } > > + bdrv_iterate(iostatus_bdrv_it, NULL); > bdrv_iterate(encrypted_bdrv_it, &context); > /* only resume the vm if all keys are set and valid */ > if (!context.err) { > -- > 1.7.7.rc0.72.g4b5ea > > > -- Regards, Zhi Yong Wu ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-22 18:19 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino 2011-09-23 7:06 ` Zhi Yong Wu @ 2011-09-23 7:51 ` Markus Armbruster 2011-09-23 7:53 ` Markus Armbruster 2011-09-23 14:01 ` Luiz Capitulino 1 sibling, 2 replies; 25+ messages in thread From: Markus Armbruster @ 2011-09-23 7:51 UTC (permalink / raw) To: Luiz Capitulino; +Cc: kwolf, qemu-devel Luiz Capitulino <lcapitulino@redhat.com> writes: > This commit adds support to the BlockDriverState type to keep track > of devices' I/O status. > > There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC > (no space error) and BDRV_IOS_FAILED (any other error). The distinction > between no space and other errors is important because a management > application may want to watch for no space in order to extend the > space assigned to the VM and put it to run again. > > Qemu devices supporting the I/O status feature have to enable it > explicitly by calling bdrv_iostatus_enable() _and_ have to be > configured to stop the VM on errors (ie. werror=stop|enospc or > rerror=stop). > > In case of multiple errors being triggered in sequence only the first > one is stored. The I/O status is always reset to BDRV_IOS_OK when the > 'cont' command is issued. > > Next commits will add support to some devices and extend the > query-block/info block commands to return the I/O status information. > > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> > --- > block.c | 32 ++++++++++++++++++++++++++++++++ > block.h | 9 +++++++++ > block_int.h | 1 + > monitor.c | 6 ++++++ > 4 files changed, 48 insertions(+), 0 deletions(-) > > diff --git a/block.c b/block.c > index e3fe97f..fbd90b4 100644 > --- a/block.c > +++ b/block.c > @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) > if (device_name[0] != '\0') { > QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); > } > + bs->iostatus = BDRV_IOS_INVAL; > return bs; > } > > @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) > return bs->in_use; > } > > +void bdrv_iostatus_enable(BlockDriverState *bs) > +{ > + assert(bs->iostatus == BDRV_IOS_INVAL); > + bs->iostatus = BDRV_IOS_OK; > +} bdrv_new() creates the BDS with I/O status tracking disabled. Devices that do tracking declare that by calling this function during initialization. Enables tracking if the BDS has suitable on_write_error and on_read_error. If a device gets hot unplugged, tracking remains enabled. If the BDS then gets reused with a device that doesn't do tracking, I/O status becomes incorrect. Can't happen right now, because we automatically delete the BDS on hot unplug, but it's a trap. Suggest to disable tracking in bdrv_detach_dev() or bdrv_attach_dev(). > + > +/* The I/O status is only enabled if the drive explicitly > + * enables it _and_ the VM is configured to stop on errors */ > +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) > +{ > + return (bs->iostatus != BDRV_IOS_INVAL && > + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || > + bs->on_write_error == BLOCK_ERR_STOP_ANY || > + bs->on_read_error == BLOCK_ERR_STOP_ANY)); > +} > + > +void bdrv_iostatus_reset(BlockDriverState *bs) > +{ > + if (bdrv_iostatus_is_enabled(bs)) { > + bs->iostatus = BDRV_IOS_OK; > + } > +} > + > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error) > +{ > + if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { > + bs->iostatus = (abs(error) == ENOSPC) ? BDRV_IOS_ENOSPC : > + BDRV_IOS_FAILED; > + } > +} > + abs(error) feels... unusual. If you want to guard against callers passing wrongly signed values, why not simply assert(error >= 0)? > void > bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, > enum BlockAcctType type) > diff --git a/block.h b/block.h > index 16bfa0a..de74af0 100644 > --- a/block.h > +++ b/block.h > @@ -77,6 +77,15 @@ typedef enum { > BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP > } BlockMonEventAction; > > +typedef enum { > + BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, > + BDRV_IOS_MAX > +} BlockIOStatus; Why is this in block.h? > + > +void bdrv_iostatus_enable(BlockDriverState *bs); > +void bdrv_iostatus_reset(BlockDriverState *bs); > +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs); > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error); > void bdrv_mon_event(const BlockDriverState *bdrv, > BlockMonEventAction action, int is_read); > void bdrv_info_print(Monitor *mon, const QObject *data); > diff --git a/block_int.h b/block_int.h > index 8c3b863..f2f4f2d 100644 > --- a/block_int.h > +++ b/block_int.h > @@ -199,6 +199,7 @@ struct BlockDriverState { > drivers. They are not used by the block driver */ > int cyls, heads, secs, translation; > BlockErrorAction on_read_error, on_write_error; > + BlockIOStatus iostatus; > char device_name[32]; > unsigned long *dirty_bitmap; > int64_t dirty_count; > diff --git a/monitor.c b/monitor.c > index 8ec2c5e..88d8228 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -1304,6 +1304,11 @@ struct bdrv_iterate_context { > int err; > }; > > +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) > +{ > + bdrv_iostatus_reset(bs); > +} > + > /** > * do_cont(): Resume emulation. > */ > @@ -1320,6 +1325,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) > return -1; > } > > + bdrv_iterate(iostatus_bdrv_it, NULL); > bdrv_iterate(encrypted_bdrv_it, &context); > /* only resume the vm if all keys are set and valid */ > if (!context.err) { ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-23 7:51 ` Markus Armbruster @ 2011-09-23 7:53 ` Markus Armbruster 2011-09-23 14:01 ` Luiz Capitulino 1 sibling, 0 replies; 25+ messages in thread From: Markus Armbruster @ 2011-09-23 7:53 UTC (permalink / raw) To: Luiz Capitulino; +Cc: kwolf, qemu-devel Markus Armbruster <armbru@redhat.com> writes: > Luiz Capitulino <lcapitulino@redhat.com> writes: > >> This commit adds support to the BlockDriverState type to keep track >> of devices' I/O status. >> >> There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC >> (no space error) and BDRV_IOS_FAILED (any other error). The distinction >> between no space and other errors is important because a management >> application may want to watch for no space in order to extend the >> space assigned to the VM and put it to run again. >> >> Qemu devices supporting the I/O status feature have to enable it >> explicitly by calling bdrv_iostatus_enable() _and_ have to be >> configured to stop the VM on errors (ie. werror=stop|enospc or >> rerror=stop). >> >> In case of multiple errors being triggered in sequence only the first >> one is stored. The I/O status is always reset to BDRV_IOS_OK when the >> 'cont' command is issued. >> >> Next commits will add support to some devices and extend the >> query-block/info block commands to return the I/O status information. >> >> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> >> --- >> block.c | 32 ++++++++++++++++++++++++++++++++ >> block.h | 9 +++++++++ >> block_int.h | 1 + >> monitor.c | 6 ++++++ >> 4 files changed, 48 insertions(+), 0 deletions(-) >> >> diff --git a/block.c b/block.c >> index e3fe97f..fbd90b4 100644 >> --- a/block.c >> +++ b/block.c >> @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) >> if (device_name[0] != '\0') { >> QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); >> } >> + bs->iostatus = BDRV_IOS_INVAL; >> return bs; >> } >> >> @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) >> return bs->in_use; >> } >> >> +void bdrv_iostatus_enable(BlockDriverState *bs) >> +{ >> + assert(bs->iostatus == BDRV_IOS_INVAL); >> + bs->iostatus = BDRV_IOS_OK; >> +} > > bdrv_new() creates the BDS with I/O status tracking disabled. Devices > that do tracking declare that by calling this function during > initialization. Enables tracking if the BDS has suitable on_write_error > and on_read_error. > > If a device gets hot unplugged, tracking remains enabled. If the BDS > then gets reused with a device that doesn't do tracking, I/O status > becomes incorrect. Can't happen right now, because we automatically > delete the BDS on hot unplug, but it's a trap. And if the BDS gets reused with a device that does tracking, the assertion above fails. > Suggest to disable tracking in bdrv_detach_dev() or bdrv_attach_dev(). [...] ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-23 7:51 ` Markus Armbruster 2011-09-23 7:53 ` Markus Armbruster @ 2011-09-23 14:01 ` Luiz Capitulino 2011-09-23 15:36 ` Markus Armbruster 1 sibling, 1 reply; 25+ messages in thread From: Luiz Capitulino @ 2011-09-23 14:01 UTC (permalink / raw) To: Markus Armbruster; +Cc: kwolf, zwu.kernel, qemu-devel On Fri, 23 Sep 2011 09:51:24 +0200 Markus Armbruster <armbru@redhat.com> wrote: > Luiz Capitulino <lcapitulino@redhat.com> writes: > > > This commit adds support to the BlockDriverState type to keep track > > of devices' I/O status. > > > > There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC > > (no space error) and BDRV_IOS_FAILED (any other error). The distinction > > between no space and other errors is important because a management > > application may want to watch for no space in order to extend the > > space assigned to the VM and put it to run again. > > > > Qemu devices supporting the I/O status feature have to enable it > > explicitly by calling bdrv_iostatus_enable() _and_ have to be > > configured to stop the VM on errors (ie. werror=stop|enospc or > > rerror=stop). > > > > In case of multiple errors being triggered in sequence only the first > > one is stored. The I/O status is always reset to BDRV_IOS_OK when the > > 'cont' command is issued. > > > > Next commits will add support to some devices and extend the > > query-block/info block commands to return the I/O status information. > > > > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> > > --- > > block.c | 32 ++++++++++++++++++++++++++++++++ > > block.h | 9 +++++++++ > > block_int.h | 1 + > > monitor.c | 6 ++++++ > > 4 files changed, 48 insertions(+), 0 deletions(-) > > > > diff --git a/block.c b/block.c > > index e3fe97f..fbd90b4 100644 > > --- a/block.c > > +++ b/block.c > > @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) > > if (device_name[0] != '\0') { > > QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); > > } > > + bs->iostatus = BDRV_IOS_INVAL; > > return bs; > > } > > > > @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) > > return bs->in_use; > > } > > > > +void bdrv_iostatus_enable(BlockDriverState *bs) > > +{ > > + assert(bs->iostatus == BDRV_IOS_INVAL); > > + bs->iostatus = BDRV_IOS_OK; > > +} > > bdrv_new() creates the BDS with I/O status tracking disabled. Devices > that do tracking declare that by calling this function during > initialization. Enables tracking if the BDS has suitable on_write_error > and on_read_error. > > If a device gets hot unplugged, tracking remains enabled. If the BDS > then gets reused with a device that doesn't do tracking, I/O status > becomes incorrect. Can't happen right now, because we automatically > delete the BDS on hot unplug, but it's a trap. > > Suggest to disable tracking in bdrv_detach_dev() or bdrv_attach_dev(). Ok, and in bdrv_close() as Zhi Yong said. > > + > > +/* The I/O status is only enabled if the drive explicitly > > + * enables it _and_ the VM is configured to stop on errors */ > > +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) > > +{ > > + return (bs->iostatus != BDRV_IOS_INVAL && > > + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || > > + bs->on_write_error == BLOCK_ERR_STOP_ANY || > > + bs->on_read_error == BLOCK_ERR_STOP_ANY)); > > +} > > + > > +void bdrv_iostatus_reset(BlockDriverState *bs) > > +{ > > + if (bdrv_iostatus_is_enabled(bs)) { > > + bs->iostatus = BDRV_IOS_OK; > > + } > > +} > > + > > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error) > > +{ > > + if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { > > + bs->iostatus = (abs(error) == ENOSPC) ? BDRV_IOS_ENOSPC : > > + BDRV_IOS_FAILED; > > + } > > +} > > + > > abs(error) feels... unusual. > > If you want to guard against callers passing wrongly signed values, why > not simply assert(error >= 0)? Yes. Actually, I thought that there were existing devices that could pass a positive value (while others passed a negative one), but by taking a look at the code now it seems that all supported devices pass a negative value, so your suggestion makes sense. > > > void > > bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, > > enum BlockAcctType type) > > diff --git a/block.h b/block.h > > index 16bfa0a..de74af0 100644 > > --- a/block.h > > +++ b/block.h > > @@ -77,6 +77,15 @@ typedef enum { > > BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP > > } BlockMonEventAction; > > > > +typedef enum { > > + BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, > > + BDRV_IOS_MAX > > +} BlockIOStatus; > > Why is this in block.h? I followed BlockErrorAction, you suggest block_int.h? > > > + > > +void bdrv_iostatus_enable(BlockDriverState *bs); > > +void bdrv_iostatus_reset(BlockDriverState *bs); > > +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs); > > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error); > > void bdrv_mon_event(const BlockDriverState *bdrv, > > BlockMonEventAction action, int is_read); > > void bdrv_info_print(Monitor *mon, const QObject *data); > > diff --git a/block_int.h b/block_int.h > > index 8c3b863..f2f4f2d 100644 > > --- a/block_int.h > > +++ b/block_int.h > > @@ -199,6 +199,7 @@ struct BlockDriverState { > > drivers. They are not used by the block driver */ > > int cyls, heads, secs, translation; > > BlockErrorAction on_read_error, on_write_error; > > + BlockIOStatus iostatus; > > char device_name[32]; > > unsigned long *dirty_bitmap; > > int64_t dirty_count; > > diff --git a/monitor.c b/monitor.c > > index 8ec2c5e..88d8228 100644 > > --- a/monitor.c > > +++ b/monitor.c > > @@ -1304,6 +1304,11 @@ struct bdrv_iterate_context { > > int err; > > }; > > > > +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) > > +{ > > + bdrv_iostatus_reset(bs); > > +} > > + > > /** > > * do_cont(): Resume emulation. > > */ > > @@ -1320,6 +1325,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) > > return -1; > > } > > > > + bdrv_iterate(iostatus_bdrv_it, NULL); > > bdrv_iterate(encrypted_bdrv_it, &context); > > /* only resume the vm if all keys are set and valid */ > > if (!context.err) { > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-23 14:01 ` Luiz Capitulino @ 2011-09-23 15:36 ` Markus Armbruster 2011-09-23 19:41 ` Luiz Capitulino 0 siblings, 1 reply; 25+ messages in thread From: Markus Armbruster @ 2011-09-23 15:36 UTC (permalink / raw) To: Luiz Capitulino; +Cc: kwolf, zwu.kernel, qemu-devel Luiz Capitulino <lcapitulino@redhat.com> writes: > On Fri, 23 Sep 2011 09:51:24 +0200 > Markus Armbruster <armbru@redhat.com> wrote: > >> Luiz Capitulino <lcapitulino@redhat.com> writes: >> >> > This commit adds support to the BlockDriverState type to keep track >> > of devices' I/O status. >> > >> > There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC >> > (no space error) and BDRV_IOS_FAILED (any other error). The distinction >> > between no space and other errors is important because a management >> > application may want to watch for no space in order to extend the >> > space assigned to the VM and put it to run again. >> > >> > Qemu devices supporting the I/O status feature have to enable it >> > explicitly by calling bdrv_iostatus_enable() _and_ have to be >> > configured to stop the VM on errors (ie. werror=stop|enospc or >> > rerror=stop). >> > >> > In case of multiple errors being triggered in sequence only the first >> > one is stored. The I/O status is always reset to BDRV_IOS_OK when the >> > 'cont' command is issued. >> > >> > Next commits will add support to some devices and extend the >> > query-block/info block commands to return the I/O status information. >> > >> > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> >> > --- >> > block.c | 32 ++++++++++++++++++++++++++++++++ >> > block.h | 9 +++++++++ >> > block_int.h | 1 + >> > monitor.c | 6 ++++++ >> > 4 files changed, 48 insertions(+), 0 deletions(-) >> > >> > diff --git a/block.c b/block.c >> > index e3fe97f..fbd90b4 100644 >> > --- a/block.c >> > +++ b/block.c >> > @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) >> > if (device_name[0] != '\0') { >> > QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); >> > } >> > + bs->iostatus = BDRV_IOS_INVAL; >> > return bs; >> > } >> > >> > @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) >> > return bs->in_use; >> > } >> > >> > +void bdrv_iostatus_enable(BlockDriverState *bs) >> > +{ >> > + assert(bs->iostatus == BDRV_IOS_INVAL); >> > + bs->iostatus = BDRV_IOS_OK; >> > +} >> >> bdrv_new() creates the BDS with I/O status tracking disabled. Devices >> that do tracking declare that by calling this function during >> initialization. Enables tracking if the BDS has suitable on_write_error >> and on_read_error. >> >> If a device gets hot unplugged, tracking remains enabled. If the BDS >> then gets reused with a device that doesn't do tracking, I/O status >> becomes incorrect. Can't happen right now, because we automatically >> delete the BDS on hot unplug, but it's a trap. >> >> Suggest to disable tracking in bdrv_detach_dev() or bdrv_attach_dev(). > > Ok, and in bdrv_close() as Zhi Yong said. Disabling in bdrv_close() makes the status go away on eject. Makes some sense, in a way. Also complicates the simple rule "status persists from stop to cont". Hmm, consider the following race: 1. Management app sends eject command 2. qemu gets read error on the same drive, VM stops, I/O status set, QEVENT_BLOCK_IO_ERROR sent to management app. 3. qemu receives eject command, bdrv_close() resets I/O status 4. Management receives QEVENT_BLOCK_IO_ERROR, and would like to find out which drive caused it. If 2 happens before 3, I/O status is lost. >> > + >> > +/* The I/O status is only enabled if the drive explicitly >> > + * enables it _and_ the VM is configured to stop on errors */ >> > +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) >> > +{ >> > + return (bs->iostatus != BDRV_IOS_INVAL && >> > + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || >> > + bs->on_write_error == BLOCK_ERR_STOP_ANY || >> > + bs->on_read_error == BLOCK_ERR_STOP_ANY)); >> > +} >> > + >> > +void bdrv_iostatus_reset(BlockDriverState *bs) >> > +{ >> > + if (bdrv_iostatus_is_enabled(bs)) { >> > + bs->iostatus = BDRV_IOS_OK; >> > + } >> > +} >> > + >> > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error) >> > +{ >> > + if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { >> > + bs->iostatus = (abs(error) == ENOSPC) ? BDRV_IOS_ENOSPC : >> > + BDRV_IOS_FAILED; >> > + } >> > +} >> > + >> >> abs(error) feels... unusual. >> >> If you want to guard against callers passing wrongly signed values, why >> not simply assert(error >= 0)? > > Yes. Actually, I thought that there were existing devices that could pass > a positive value (while others passed a negative one), but by taking a look > at the code now it seems that all supported devices pass a negative value, > so your suggestion makes sense. > >> >> > void >> > bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, >> > enum BlockAcctType type) >> > diff --git a/block.h b/block.h >> > index 16bfa0a..de74af0 100644 >> > --- a/block.h >> > +++ b/block.h >> > @@ -77,6 +77,15 @@ typedef enum { >> > BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP >> > } BlockMonEventAction; >> > >> > +typedef enum { >> > + BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, >> > + BDRV_IOS_MAX >> > +} BlockIOStatus; >> >> Why is this in block.h? > > I followed BlockErrorAction, you suggest block_int.h? I guess I'd put it in block_int.h, just because I can. No biggie, though. [...] ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-23 15:36 ` Markus Armbruster @ 2011-09-23 19:41 ` Luiz Capitulino 2011-09-26 9:34 ` Markus Armbruster 0 siblings, 1 reply; 25+ messages in thread From: Luiz Capitulino @ 2011-09-23 19:41 UTC (permalink / raw) To: Markus Armbruster; +Cc: kwolf, zwu.kernel, qemu-devel On Fri, 23 Sep 2011 17:36:53 +0200 Markus Armbruster <armbru@redhat.com> wrote: > Luiz Capitulino <lcapitulino@redhat.com> writes: > > > On Fri, 23 Sep 2011 09:51:24 +0200 > > Markus Armbruster <armbru@redhat.com> wrote: > > > >> Luiz Capitulino <lcapitulino@redhat.com> writes: > >> > >> > This commit adds support to the BlockDriverState type to keep track > >> > of devices' I/O status. > >> > > >> > There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC > >> > (no space error) and BDRV_IOS_FAILED (any other error). The distinction > >> > between no space and other errors is important because a management > >> > application may want to watch for no space in order to extend the > >> > space assigned to the VM and put it to run again. > >> > > >> > Qemu devices supporting the I/O status feature have to enable it > >> > explicitly by calling bdrv_iostatus_enable() _and_ have to be > >> > configured to stop the VM on errors (ie. werror=stop|enospc or > >> > rerror=stop). > >> > > >> > In case of multiple errors being triggered in sequence only the first > >> > one is stored. The I/O status is always reset to BDRV_IOS_OK when the > >> > 'cont' command is issued. > >> > > >> > Next commits will add support to some devices and extend the > >> > query-block/info block commands to return the I/O status information. > >> > > >> > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> > >> > --- > >> > block.c | 32 ++++++++++++++++++++++++++++++++ > >> > block.h | 9 +++++++++ > >> > block_int.h | 1 + > >> > monitor.c | 6 ++++++ > >> > 4 files changed, 48 insertions(+), 0 deletions(-) > >> > > >> > diff --git a/block.c b/block.c > >> > index e3fe97f..fbd90b4 100644 > >> > --- a/block.c > >> > +++ b/block.c > >> > @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) > >> > if (device_name[0] != '\0') { > >> > QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); > >> > } > >> > + bs->iostatus = BDRV_IOS_INVAL; > >> > return bs; > >> > } > >> > > >> > @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) > >> > return bs->in_use; > >> > } > >> > > >> > +void bdrv_iostatus_enable(BlockDriverState *bs) > >> > +{ > >> > + assert(bs->iostatus == BDRV_IOS_INVAL); > >> > + bs->iostatus = BDRV_IOS_OK; > >> > +} > >> > >> bdrv_new() creates the BDS with I/O status tracking disabled. Devices > >> that do tracking declare that by calling this function during > >> initialization. Enables tracking if the BDS has suitable on_write_error > >> and on_read_error. > >> > >> If a device gets hot unplugged, tracking remains enabled. If the BDS > >> then gets reused with a device that doesn't do tracking, I/O status > >> becomes incorrect. Can't happen right now, because we automatically > >> delete the BDS on hot unplug, but it's a trap. > >> > >> Suggest to disable tracking in bdrv_detach_dev() or bdrv_attach_dev(). > > > > Ok, and in bdrv_close() as Zhi Yong said. > > Disabling in bdrv_close() makes the status go away on eject. Makes some > sense, in a way. Also complicates the simple rule "status persists from > stop to cont". Hmm, consider the following race: > > 1. Management app sends eject command > > 2. qemu gets read error on the same drive, VM stops, I/O status set, > QEVENT_BLOCK_IO_ERROR sent to management app. > > 3. qemu receives eject command, bdrv_close() resets I/O status > > 4. Management receives QEVENT_BLOCK_IO_ERROR, and would like to find out > which drive caused it. > > If 2 happens before 3, I/O status is lost. Honestly speaking, I didn't intend to make it persistent on eject. Do we really want to support this? I find it a bit confusing to have the I/O status on something that has no media. In that case we should only return the io-status info if the media is inserted. This way, if the VM stops due to an I/O error and the media is ejected, a mngt application would: 1. Issue the query-block and find no guilt 2. Issue cont 3. The VM would execute normally Of course that we have to be clear about it in the documentation and a mngt app has to be prepared to deal with it. > >> > + > >> > +/* The I/O status is only enabled if the drive explicitly > >> > + * enables it _and_ the VM is configured to stop on errors */ > >> > +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) > >> > +{ > >> > + return (bs->iostatus != BDRV_IOS_INVAL && > >> > + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || > >> > + bs->on_write_error == BLOCK_ERR_STOP_ANY || > >> > + bs->on_read_error == BLOCK_ERR_STOP_ANY)); > >> > +} > >> > + > >> > +void bdrv_iostatus_reset(BlockDriverState *bs) > >> > +{ > >> > + if (bdrv_iostatus_is_enabled(bs)) { > >> > + bs->iostatus = BDRV_IOS_OK; > >> > + } > >> > +} > >> > + > >> > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error) > >> > +{ > >> > + if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { > >> > + bs->iostatus = (abs(error) == ENOSPC) ? BDRV_IOS_ENOSPC : > >> > + BDRV_IOS_FAILED; > >> > + } > >> > +} > >> > + > >> > >> abs(error) feels... unusual. > >> > >> If you want to guard against callers passing wrongly signed values, why > >> not simply assert(error >= 0)? > > > > Yes. Actually, I thought that there were existing devices that could pass > > a positive value (while others passed a negative one), but by taking a look > > at the code now it seems that all supported devices pass a negative value, > > so your suggestion makes sense. > > > >> > >> > void > >> > bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, > >> > enum BlockAcctType type) > >> > diff --git a/block.h b/block.h > >> > index 16bfa0a..de74af0 100644 > >> > --- a/block.h > >> > +++ b/block.h > >> > @@ -77,6 +77,15 @@ typedef enum { > >> > BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP > >> > } BlockMonEventAction; > >> > > >> > +typedef enum { > >> > + BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, > >> > + BDRV_IOS_MAX > >> > +} BlockIOStatus; > >> > >> Why is this in block.h? > > > > I followed BlockErrorAction, you suggest block_int.h? > > I guess I'd put it in block_int.h, just because I can. No biggie, > though. > > [...] > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-23 19:41 ` Luiz Capitulino @ 2011-09-26 9:34 ` Markus Armbruster 2011-09-26 12:49 ` Luiz Capitulino 0 siblings, 1 reply; 25+ messages in thread From: Markus Armbruster @ 2011-09-26 9:34 UTC (permalink / raw) To: Luiz Capitulino; +Cc: kwolf, zwu.kernel, qemu-devel Luiz Capitulino <lcapitulino@redhat.com> writes: > On Fri, 23 Sep 2011 17:36:53 +0200 > Markus Armbruster <armbru@redhat.com> wrote: > >> Luiz Capitulino <lcapitulino@redhat.com> writes: >> >> > On Fri, 23 Sep 2011 09:51:24 +0200 >> > Markus Armbruster <armbru@redhat.com> wrote: >> > >> >> Luiz Capitulino <lcapitulino@redhat.com> writes: >> >> >> >> > This commit adds support to the BlockDriverState type to keep track >> >> > of devices' I/O status. >> >> > >> >> > There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC >> >> > (no space error) and BDRV_IOS_FAILED (any other error). The distinction >> >> > between no space and other errors is important because a management >> >> > application may want to watch for no space in order to extend the >> >> > space assigned to the VM and put it to run again. >> >> > >> >> > Qemu devices supporting the I/O status feature have to enable it >> >> > explicitly by calling bdrv_iostatus_enable() _and_ have to be >> >> > configured to stop the VM on errors (ie. werror=stop|enospc or >> >> > rerror=stop). >> >> > >> >> > In case of multiple errors being triggered in sequence only the first >> >> > one is stored. The I/O status is always reset to BDRV_IOS_OK when the >> >> > 'cont' command is issued. >> >> > >> >> > Next commits will add support to some devices and extend the >> >> > query-block/info block commands to return the I/O status information. >> >> > >> >> > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> >> >> > --- >> >> > block.c | 32 ++++++++++++++++++++++++++++++++ >> >> > block.h | 9 +++++++++ >> >> > block_int.h | 1 + >> >> > monitor.c | 6 ++++++ >> >> > 4 files changed, 48 insertions(+), 0 deletions(-) >> >> > >> >> > diff --git a/block.c b/block.c >> >> > index e3fe97f..fbd90b4 100644 >> >> > --- a/block.c >> >> > +++ b/block.c >> >> > @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) >> >> > if (device_name[0] != '\0') { >> >> > QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); >> >> > } >> >> > + bs->iostatus = BDRV_IOS_INVAL; >> >> > return bs; >> >> > } >> >> > >> >> > @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) >> >> > return bs->in_use; >> >> > } >> >> > >> >> > +void bdrv_iostatus_enable(BlockDriverState *bs) >> >> > +{ >> >> > + assert(bs->iostatus == BDRV_IOS_INVAL); >> >> > + bs->iostatus = BDRV_IOS_OK; >> >> > +} >> >> >> >> bdrv_new() creates the BDS with I/O status tracking disabled. Devices >> >> that do tracking declare that by calling this function during >> >> initialization. Enables tracking if the BDS has suitable on_write_error >> >> and on_read_error. >> >> >> >> If a device gets hot unplugged, tracking remains enabled. If the BDS >> >> then gets reused with a device that doesn't do tracking, I/O status >> >> becomes incorrect. Can't happen right now, because we automatically >> >> delete the BDS on hot unplug, but it's a trap. >> >> >> >> Suggest to disable tracking in bdrv_detach_dev() or bdrv_attach_dev(). >> > >> > Ok, and in bdrv_close() as Zhi Yong said. >> >> Disabling in bdrv_close() makes the status go away on eject. Makes some >> sense, in a way. Also complicates the simple rule "status persists from >> stop to cont". Hmm, consider the following race: >> >> 1. Management app sends eject command >> >> 2. qemu gets read error on the same drive, VM stops, I/O status set, >> QEVENT_BLOCK_IO_ERROR sent to management app. >> >> 3. qemu receives eject command, bdrv_close() resets I/O status >> >> 4. Management receives QEVENT_BLOCK_IO_ERROR, and would like to find out >> which drive caused it. >> >> If 2 happens before 3, I/O status is lost. > > Honestly speaking, I didn't intend to make it persistent on eject. Do we really > want to support this? I find it a bit confusing to have the I/O status on > something that has no media. In that case we should only return the io-status > info if the media is inserted. > > This way, if the VM stops due to an I/O error and the media is ejected, a mngt > application would: > > 1. Issue the query-block and find no guilt > 2. Issue cont > 3. The VM would execute normally > > Of course that we have to be clear about it in the documentation and a > mngt app has to be prepared to deal with it. The management app may well want to know that we hit errors on the media, even when the error happens close to an eject. In particular, they probably want to alert their users on write errors. Just because you eject a medium doesn't mean you're no longer interested in the data on it ;) [...] ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-26 9:34 ` Markus Armbruster @ 2011-09-26 12:49 ` Luiz Capitulino 2011-09-26 13:41 ` Markus Armbruster 0 siblings, 1 reply; 25+ messages in thread From: Luiz Capitulino @ 2011-09-26 12:49 UTC (permalink / raw) To: Markus Armbruster; +Cc: kwolf, zwu.kernel, qemu-devel On Mon, 26 Sep 2011 11:34:34 +0200 Markus Armbruster <armbru@redhat.com> wrote: > Luiz Capitulino <lcapitulino@redhat.com> writes: > > > On Fri, 23 Sep 2011 17:36:53 +0200 > > Markus Armbruster <armbru@redhat.com> wrote: > > > >> Luiz Capitulino <lcapitulino@redhat.com> writes: > >> > >> > On Fri, 23 Sep 2011 09:51:24 +0200 > >> > Markus Armbruster <armbru@redhat.com> wrote: > >> > > >> >> Luiz Capitulino <lcapitulino@redhat.com> writes: > >> >> > >> >> > This commit adds support to the BlockDriverState type to keep track > >> >> > of devices' I/O status. > >> >> > > >> >> > There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC > >> >> > (no space error) and BDRV_IOS_FAILED (any other error). The distinction > >> >> > between no space and other errors is important because a management > >> >> > application may want to watch for no space in order to extend the > >> >> > space assigned to the VM and put it to run again. > >> >> > > >> >> > Qemu devices supporting the I/O status feature have to enable it > >> >> > explicitly by calling bdrv_iostatus_enable() _and_ have to be > >> >> > configured to stop the VM on errors (ie. werror=stop|enospc or > >> >> > rerror=stop). > >> >> > > >> >> > In case of multiple errors being triggered in sequence only the first > >> >> > one is stored. The I/O status is always reset to BDRV_IOS_OK when the > >> >> > 'cont' command is issued. > >> >> > > >> >> > Next commits will add support to some devices and extend the > >> >> > query-block/info block commands to return the I/O status information. > >> >> > > >> >> > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> > >> >> > --- > >> >> > block.c | 32 ++++++++++++++++++++++++++++++++ > >> >> > block.h | 9 +++++++++ > >> >> > block_int.h | 1 + > >> >> > monitor.c | 6 ++++++ > >> >> > 4 files changed, 48 insertions(+), 0 deletions(-) > >> >> > > >> >> > diff --git a/block.c b/block.c > >> >> > index e3fe97f..fbd90b4 100644 > >> >> > --- a/block.c > >> >> > +++ b/block.c > >> >> > @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) > >> >> > if (device_name[0] != '\0') { > >> >> > QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); > >> >> > } > >> >> > + bs->iostatus = BDRV_IOS_INVAL; > >> >> > return bs; > >> >> > } > >> >> > > >> >> > @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) > >> >> > return bs->in_use; > >> >> > } > >> >> > > >> >> > +void bdrv_iostatus_enable(BlockDriverState *bs) > >> >> > +{ > >> >> > + assert(bs->iostatus == BDRV_IOS_INVAL); > >> >> > + bs->iostatus = BDRV_IOS_OK; > >> >> > +} > >> >> > >> >> bdrv_new() creates the BDS with I/O status tracking disabled. Devices > >> >> that do tracking declare that by calling this function during > >> >> initialization. Enables tracking if the BDS has suitable on_write_error > >> >> and on_read_error. > >> >> > >> >> If a device gets hot unplugged, tracking remains enabled. If the BDS > >> >> then gets reused with a device that doesn't do tracking, I/O status > >> >> becomes incorrect. Can't happen right now, because we automatically > >> >> delete the BDS on hot unplug, but it's a trap. > >> >> > >> >> Suggest to disable tracking in bdrv_detach_dev() or bdrv_attach_dev(). > >> > > >> > Ok, and in bdrv_close() as Zhi Yong said. > >> > >> Disabling in bdrv_close() makes the status go away on eject. Makes some > >> sense, in a way. Also complicates the simple rule "status persists from > >> stop to cont". Hmm, consider the following race: > >> > >> 1. Management app sends eject command > >> > >> 2. qemu gets read error on the same drive, VM stops, I/O status set, > >> QEVENT_BLOCK_IO_ERROR sent to management app. > >> > >> 3. qemu receives eject command, bdrv_close() resets I/O status > >> > >> 4. Management receives QEVENT_BLOCK_IO_ERROR, and would like to find out > >> which drive caused it. > >> > >> If 2 happens before 3, I/O status is lost. > > > > Honestly speaking, I didn't intend to make it persistent on eject. Do we really > > want to support this? I find it a bit confusing to have the I/O status on > > something that has no media. In that case we should only return the io-status > > info if the media is inserted. > > > > This way, if the VM stops due to an I/O error and the media is ejected, a mngt > > application would: > > > > 1. Issue the query-block and find no guilt > > 2. Issue cont > > 3. The VM would execute normally > > > > Of course that we have to be clear about it in the documentation and a > > mngt app has to be prepared to deal with it. > > The management app may well want to know that we hit errors on the > media, even when the error happens close to an eject. In particular, > they probably want to alert their users on write errors. Just because > you eject a medium doesn't mean you're no longer interested in the data > on it ;) Ok, so I'll have to reset the I/O status on bdrv_open() too, so that a new inserted media won't contain the previous media status. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-26 12:49 ` Luiz Capitulino @ 2011-09-26 13:41 ` Markus Armbruster 0 siblings, 0 replies; 25+ messages in thread From: Markus Armbruster @ 2011-09-26 13:41 UTC (permalink / raw) To: Luiz Capitulino; +Cc: kwolf, zwu.kernel, qemu-devel Luiz Capitulino <lcapitulino@redhat.com> writes: > On Mon, 26 Sep 2011 11:34:34 +0200 > Markus Armbruster <armbru@redhat.com> wrote: > >> Luiz Capitulino <lcapitulino@redhat.com> writes: >> >> > On Fri, 23 Sep 2011 17:36:53 +0200 >> > Markus Armbruster <armbru@redhat.com> wrote: >> > >> >> Luiz Capitulino <lcapitulino@redhat.com> writes: >> >> >> >> > On Fri, 23 Sep 2011 09:51:24 +0200 >> >> > Markus Armbruster <armbru@redhat.com> wrote: >> >> > >> >> >> Luiz Capitulino <lcapitulino@redhat.com> writes: >> >> >> >> >> >> > This commit adds support to the BlockDriverState type to keep track >> >> >> > of devices' I/O status. >> >> >> > >> >> >> > There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC >> >> >> > (no space error) and BDRV_IOS_FAILED (any other error). The distinction >> >> >> > between no space and other errors is important because a management >> >> >> > application may want to watch for no space in order to extend the >> >> >> > space assigned to the VM and put it to run again. >> >> >> > >> >> >> > Qemu devices supporting the I/O status feature have to enable it >> >> >> > explicitly by calling bdrv_iostatus_enable() _and_ have to be >> >> >> > configured to stop the VM on errors (ie. werror=stop|enospc or >> >> >> > rerror=stop). >> >> >> > >> >> >> > In case of multiple errors being triggered in sequence only the first >> >> >> > one is stored. The I/O status is always reset to BDRV_IOS_OK when the >> >> >> > 'cont' command is issued. >> >> >> > >> >> >> > Next commits will add support to some devices and extend the >> >> >> > query-block/info block commands to return the I/O status information. >> >> >> > >> >> >> > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> >> >> >> > --- >> >> >> > block.c | 32 ++++++++++++++++++++++++++++++++ >> >> >> > block.h | 9 +++++++++ >> >> >> > block_int.h | 1 + >> >> >> > monitor.c | 6 ++++++ >> >> >> > 4 files changed, 48 insertions(+), 0 deletions(-) >> >> >> > >> >> >> > diff --git a/block.c b/block.c >> >> >> > index e3fe97f..fbd90b4 100644 >> >> >> > --- a/block.c >> >> >> > +++ b/block.c >> >> >> > @@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name) >> >> >> > if (device_name[0] != '\0') { >> >> >> > QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); >> >> >> > } >> >> >> > + bs->iostatus = BDRV_IOS_INVAL; >> >> >> > return bs; >> >> >> > } >> >> >> > >> >> >> > @@ -3181,6 +3182,37 @@ int bdrv_in_use(BlockDriverState *bs) >> >> >> > return bs->in_use; >> >> >> > } >> >> >> > >> >> >> > +void bdrv_iostatus_enable(BlockDriverState *bs) >> >> >> > +{ >> >> >> > + assert(bs->iostatus == BDRV_IOS_INVAL); >> >> >> > + bs->iostatus = BDRV_IOS_OK; >> >> >> > +} >> >> >> >> >> >> bdrv_new() creates the BDS with I/O status tracking disabled. Devices >> >> >> that do tracking declare that by calling this function during >> >> >> initialization. Enables tracking if the BDS has suitable on_write_error >> >> >> and on_read_error. >> >> >> >> >> >> If a device gets hot unplugged, tracking remains enabled. If the BDS >> >> >> then gets reused with a device that doesn't do tracking, I/O status >> >> >> becomes incorrect. Can't happen right now, because we automatically >> >> >> delete the BDS on hot unplug, but it's a trap. >> >> >> >> >> >> Suggest to disable tracking in bdrv_detach_dev() or bdrv_attach_dev(). >> >> > >> >> > Ok, and in bdrv_close() as Zhi Yong said. >> >> >> >> Disabling in bdrv_close() makes the status go away on eject. Makes some >> >> sense, in a way. Also complicates the simple rule "status persists from >> >> stop to cont". Hmm, consider the following race: >> >> >> >> 1. Management app sends eject command >> >> >> >> 2. qemu gets read error on the same drive, VM stops, I/O status set, >> >> QEVENT_BLOCK_IO_ERROR sent to management app. >> >> >> >> 3. qemu receives eject command, bdrv_close() resets I/O status >> >> >> >> 4. Management receives QEVENT_BLOCK_IO_ERROR, and would like to find out >> >> which drive caused it. >> >> >> >> If 2 happens before 3, I/O status is lost. >> > >> > Honestly speaking, I didn't intend to make it persistent on eject. Do we really >> > want to support this? I find it a bit confusing to have the I/O status on >> > something that has no media. In that case we should only return the io-status >> > info if the media is inserted. >> > >> > This way, if the VM stops due to an I/O error and the media is ejected, a mngt >> > application would: >> > >> > 1. Issue the query-block and find no guilt >> > 2. Issue cont >> > 3. The VM would execute normally >> > >> > Of course that we have to be clear about it in the documentation and a >> > mngt app has to be prepared to deal with it. >> >> The management app may well want to know that we hit errors on the >> media, even when the error happens close to an eject. In particular, >> they probably want to alert their users on write errors. Just because >> you eject a medium doesn't mean you're no longer interested in the data >> on it ;) > > Ok, so I'll have to reset the I/O status on bdrv_open() too, so that > a new inserted media won't contain the previous media status. Same race with "change" (which calls bdrv_close() and bdrv_open()) instead of "eject" (which only calls bdrv_close()). I figure we better define the problem away, like this: I/O status is what made the VM stop. It's valid from VM stop to VM continue or drive delete, whatever comes first. In particular, media change doesn't affect it. The only alternative I can see right now is making media change fail while I/O status isn't okay, but that "cure" looks far worse than the disease, and I'm not at all sure it's sufficient. Two more instances of the race, both caused by destroying the drive (and thus I/O status) while it's being used by a device (and thus prone to getting I/O status set): 1. Device hot unplug while drive is not empty Possible fix: stop auto-destroying drives on device unplug. Then a management app can unplug the device, wait until it's gone, then delete the drive. Safe, because I/O status can't change anymore once the device detached from the drive. 2. drive_del of non-empty drive while a device is attached. Possible fix: split into detach and delete. ^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH v1 0/6]: block: Add I/O status support @ 2011-09-01 18:37 Luiz Capitulino 2011-09-01 18:37 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino 0 siblings, 1 reply; 25+ messages in thread From: Luiz Capitulino @ 2011-09-01 18:37 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, aliguori, armbru This series adds support to the block layer to keep track of devices' I/O status. That information is also made available in QMP and HMP. The goal here is to allow management applications that miss the BLOCK_IO_ERROR event to able to query the VM to determine if any device has caused the VM to stop and which device caused it. Please, note that this series depends on the following series: o [PATCH v3 0/8]: Introduce the RunState type o http://lists.gnu.org/archive/html/qemu-devel/2011-09/msg00118.html And to be able to properly test it you'll also need: o [PATCH 0/3] qcow2/coroutine fixes o http://lists.gnu.org/archive/html/qemu-devel/2011-09/msg00074.html Here's an HMP example: (qemu) info status VM status: paused (io-error) (qemu) info block ide0-hd0: removable=0 io-status=ok file=disks/test2.img ro=0 drv=qcow2 encrypted=0 ide0-hd1: removable=0 io-status=nospace file=/dev/vg_doriath/kvmtest ro=0 drv=qcow2 encrypted=0 ide1-cd0: removable=1 locked=0 io-status=ok [not inserted] floppy0: removable=1 locked=0 [not inserted] sd0: removable=1 locked=0 [not inserted] The "info status" command shows that the VM is stopped due to an I/O error. By issuing "info block" it's possible to determine that the 'ide0-hd1' device caused the error, which turns out to be due to no space. block.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- block.h | 9 +++++++++ block_int.h | 1 + hw/ide/core.c | 2 ++ hw/scsi-disk.c | 2 ++ hw/virtio-blk.c | 2 ++ monitor.c | 6 ++++++ qmp-commands.hx | 5 +++++ 8 files changed, 77 insertions(+), 1 deletions(-) ^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status 2011-09-01 18:37 [Qemu-devel] [PATCH v1 0/6]: block: Add I/O status support Luiz Capitulino @ 2011-09-01 18:37 ` Luiz Capitulino 0 siblings, 0 replies; 25+ messages in thread From: Luiz Capitulino @ 2011-09-01 18:37 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, aliguori, armbru This commit adds support to the BlockDriverState type to keep track of the devices' I/O status. There are three possible status: BDRV_IOS_OK (no error so far), BDRV_IOS_ENOSPC (no space error) and BDRV_IOS_FAILED (any other error). The distinction between no space and other errors is important because a management application may want to watch for no space in order to extend the host's underline device and put the VM to run again. Qemu devices supporting the I/O status feature have to enable it explicitly by calling bdrv_iostatus_enable() _and_ have to be configured to stop the VM on errors (ie. werror=stop|enospc or rerror=stop). In case of multiple errors being triggered in sequence only the first one is stored. The I/O status is set back to BDRV_IOS_OK when the 'cont' command is issued. Next commits will add support to some devices and extend the query-block/info block commands with the I/O status information. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- block.c | 32 ++++++++++++++++++++++++++++++++ block.h | 9 +++++++++ block_int.h | 1 + monitor.c | 6 ++++++ 4 files changed, 48 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index 03a21d8..c54caf2 100644 --- a/block.c +++ b/block.c @@ -220,6 +220,7 @@ BlockDriverState *bdrv_new(const char *device_name) if (device_name[0] != '\0') { QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); } + bs->iostatus = BDRV_IOS_INVAL; return bs; } @@ -3165,6 +3166,37 @@ int bdrv_in_use(BlockDriverState *bs) return bs->in_use; } +void bdrv_iostatus_enable(BlockDriverState *bs) +{ + assert(bs->iostatus == BDRV_IOS_INVAL); + bs->iostatus = BDRV_IOS_OK; +} + +/* The I/O status is only enabled if the drive explicitly + * enables it _and_ the VM is configured to stop on errors */ +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) +{ + return (bs->iostatus != BDRV_IOS_INVAL && + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || + bs->on_write_error == BLOCK_ERR_STOP_ANY || + bs->on_read_error == BLOCK_ERR_STOP_ANY)); +} + +void bdrv_iostatus_reset(BlockDriverState *bs) +{ + if (bdrv_iostatus_is_enabled(bs)) { + bs->iostatus = BDRV_IOS_OK; + } +} + +void bdrv_iostatus_update(BlockDriverState *bs, int error) +{ + if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { + bs->iostatus = (abs(error) == ENOSPC) ? BDRV_IOS_ENOSPC : + BDRV_IOS_FAILED; + } +} + void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, enum BlockAcctType type) diff --git a/block.h b/block.h index 3ac0b94..24914e0 100644 --- a/block.h +++ b/block.h @@ -51,6 +51,15 @@ typedef enum { BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP } BlockMonEventAction; +typedef enum { + BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, + BDRV_IOS_MAX +} BlockIOStatus; + +void bdrv_iostatus_enable(BlockDriverState *bs); +void bdrv_iostatus_reset(BlockDriverState *bs); +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs); +void bdrv_iostatus_update(BlockDriverState *bs, int error); void bdrv_mon_event(const BlockDriverState *bdrv, BlockMonEventAction action, int is_read); void bdrv_info_print(Monitor *mon, const QObject *data); diff --git a/block_int.h b/block_int.h index 8a72b80..600801d 100644 --- a/block_int.h +++ b/block_int.h @@ -203,6 +203,7 @@ struct BlockDriverState { drivers. They are not used by the block driver */ int cyls, heads, secs, translation; BlockErrorAction on_read_error, on_write_error; + BlockIOStatus iostatus; char device_name[32]; unsigned long *dirty_bitmap; int64_t dirty_count; diff --git a/monitor.c b/monitor.c index 9807005..69f1b3c 100644 --- a/monitor.c +++ b/monitor.c @@ -1302,6 +1302,11 @@ struct bdrv_iterate_context { int err; }; +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +{ + bdrv_iostatus_reset(bs); +} + /** * do_cont(): Resume emulation. */ @@ -1318,6 +1323,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) return -1; } + bdrv_iterate(iostatus_bdrv_it, NULL); bdrv_iterate(encrypted_bdrv_it, &context); /* only resume the vm if all keys are set and valid */ if (!context.err) { -- 1.7.7.rc0.72.g4b5ea ^ permalink raw reply related [flat|nested] 25+ messages in thread
end of thread, other threads:[~2011-10-11 7:46 UTC | newest] Thread overview: 25+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-09-26 20:43 [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 2/6] virtio: Support " Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 3/6] ide: " Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 4/6] scsi: " Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 5/6] QMP: query-status: Add 'io-status' key Luiz Capitulino 2011-09-26 20:43 ` [Qemu-devel] [PATCH 6/6] HMP: Print 'io-status' information Luiz Capitulino 2011-09-27 18:40 ` [Qemu-devel] [PATCH v3 0/6]: block: Add I/O status support Markus Armbruster 2011-09-28 9:45 ` hkran 2011-09-28 20:00 ` Luiz Capitulino 2011-09-29 7:20 ` Mark Wu 2011-10-10 17:30 ` Kevin Wolf 2011-10-10 20:25 ` Luiz Capitulino 2011-10-11 7:49 ` Kevin Wolf -- strict thread matches above, loose matches on Subject: below -- 2011-09-22 18:19 [Qemu-devel] [PATCH v2 " Luiz Capitulino 2011-09-22 18:19 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino 2011-09-23 7:06 ` Zhi Yong Wu 2011-09-23 7:51 ` Markus Armbruster 2011-09-23 7:53 ` Markus Armbruster 2011-09-23 14:01 ` Luiz Capitulino 2011-09-23 15:36 ` Markus Armbruster 2011-09-23 19:41 ` Luiz Capitulino 2011-09-26 9:34 ` Markus Armbruster 2011-09-26 12:49 ` Luiz Capitulino 2011-09-26 13:41 ` Markus Armbruster 2011-09-01 18:37 [Qemu-devel] [PATCH v1 0/6]: block: Add I/O status support Luiz Capitulino 2011-09-01 18:37 ` [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status Luiz Capitulino
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).