[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status |
Date: |
Fri, 23 Sep 2011 17:36:53 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) |
Luiz Capitulino <address@hidden> writes:
> On Fri, 23 Sep 2011 09:51:24 +0200
> Markus Armbruster <address@hidden> wrote:
>
>> Luiz Capitulino <address@hidden> 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 <address@hidden>
>> > ---
>> > 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.
[...]
- [Qemu-devel] [PATCH v2 0/6]: block: Add I/O status support, Luiz Capitulino, 2011/09/22
- [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Luiz Capitulino, 2011/09/22
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Zhi Yong Wu, 2011/09/23
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Markus Armbruster, 2011/09/23
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Markus Armbruster, 2011/09/23
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Luiz Capitulino, 2011/09/23
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status,
Markus Armbruster <=
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Luiz Capitulino, 2011/09/23
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Markus Armbruster, 2011/09/26
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Luiz Capitulino, 2011/09/26
- Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status, Markus Armbruster, 2011/09/26
[Qemu-devel] [PATCH 2/6] virtio: Support I/O status, Luiz Capitulino, 2011/09/22
[Qemu-devel] [PATCH 3/6] ide: Support I/O status, Luiz Capitulino, 2011/09/22
[Qemu-devel] [PATCH 4/6] scsi: Support I/O status, Luiz Capitulino, 2011/09/22
[Qemu-devel] [PATCH 5/6] QMP: query-status: Add 'io-status' key, Luiz Capitulino, 2011/09/22
[Qemu-devel] [PATCH 6/6] HMP: Print 'io-status' information, Luiz Capitulino, 2011/09/22