From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:47574) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R6zqA-0004bn-D8 for qemu-devel@nongnu.org; Fri, 23 Sep 2011 03:06:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R6zq9-0005aN-6e for qemu-devel@nongnu.org; Fri, 23 Sep 2011 03:06:30 -0400 Received: from mail-wy0-f173.google.com ([74.125.82.173]:51999) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R6zq8-0005aJ-TZ for qemu-devel@nongnu.org; Fri, 23 Sep 2011 03:06:29 -0400 Received: by wyh22 with SMTP id 22so3900352wyh.4 for ; Fri, 23 Sep 2011 00:06:27 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <1316715584-25557-2-git-send-email-lcapitulino@redhat.com> References: <1316715584-25557-1-git-send-email-lcapitulino@redhat.com> <1316715584-25557-2-git-send-email-lcapitulino@redhat.com> Date: Fri, 23 Sep 2011 15:06:27 +0800 Message-ID: From: Zhi Yong Wu Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH 1/6] block: Keep track of devices' I/O status List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Luiz Capitulino Cc: kwolf@redhat.com, armbru@redhat.com, qemu-devel@nongnu.org On Fri, Sep 23, 2011 at 2:19 AM, Luiz Capitulino w= rote: > 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=3Dstop|enospc or > rerror=3Dstop). > > 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 > --- > =A0block.c =A0 =A0 | =A0 32 ++++++++++++++++++++++++++++++++ > =A0block.h =A0 =A0 | =A0 =A09 +++++++++ > =A0block_int.h | =A0 =A01 + > =A0monitor.c =A0 | =A0 =A06 ++++++ > =A04 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) > =A0 =A0 if (device_name[0] !=3D '\0') { > =A0 =A0 =A0 =A0 QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); > =A0 =A0 } > + =A0 =A0bs->iostatus =3D BDRV_IOS_INVAL; > =A0 =A0 return bs; > =A0} 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) > =A0 =A0 return bs->in_use; > =A0} > > +void bdrv_iostatus_enable(BlockDriverState *bs) > +{ > + =A0 =A0assert(bs->iostatus =3D=3D BDRV_IOS_INVAL); > + =A0 =A0bs->iostatus =3D 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) > +{ > + =A0 =A0return (bs->iostatus !=3D BDRV_IOS_INVAL && > + =A0 =A0 =A0 =A0 =A0 (bs->on_write_error =3D=3D BLOCK_ERR_STOP_ENOSPC || > + =A0 =A0 =A0 =A0 =A0 =A0bs->on_write_error =3D=3D BLOCK_ERR_STOP_ANY =A0= =A0|| > + =A0 =A0 =A0 =A0 =A0 =A0bs->on_read_error =3D=3D BLOCK_ERR_STOP_ANY)); > +} > + > +void bdrv_iostatus_reset(BlockDriverState *bs) > +{ > + =A0 =A0if (bdrv_iostatus_is_enabled(bs)) { > + =A0 =A0 =A0 =A0bs->iostatus =3D BDRV_IOS_OK; > + =A0 =A0} > +} > + > +void bdrv_iostatus_set_err(BlockDriverState *bs, int error) > +{ > + =A0 =A0if (bdrv_iostatus_is_enabled(bs) && bs->iostatus =3D=3D BDRV_IOS= _OK) { > + =A0 =A0 =A0 =A0bs->iostatus =3D (abs(error) =3D=3D ENOSPC) ? BDRV_IOS_E= NOSPC : > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0BDRV_IOS_FAILED; > + =A0 =A0} > +} > + > =A0void > =A0bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t= bytes, > =A0 =A0 =A0 =A0 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 { > =A0 =A0 BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP > =A0} BlockMonEventAction; > > +typedef enum { > + =A0 =A0BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, > + =A0 =A0BDRV_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); > =A0void bdrv_mon_event(const BlockDriverState *bdrv, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 BlockMonEventAction action, int i= s_read); > =A0void 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 { > =A0 =A0 =A0 =A0drivers. They are not used by the block driver */ > =A0 =A0 int cyls, heads, secs, translation; > =A0 =A0 BlockErrorAction on_read_error, on_write_error; > + =A0 =A0BlockIOStatus iostatus; > =A0 =A0 char device_name[32]; > =A0 =A0 unsigned long *dirty_bitmap; > =A0 =A0 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 { > =A0 =A0 int err; > =A0}; > > +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) > +{ > + =A0 =A0bdrv_iostatus_reset(bs); > +} > + > =A0/** > =A0* do_cont(): Resume emulation. > =A0*/ > @@ -1320,6 +1325,7 @@ static int do_cont(Monitor *mon, const QDict *qdict= , QObject **ret_data) > =A0 =A0 =A0 =A0 return -1; > =A0 =A0 } > > + =A0 =A0bdrv_iterate(iostatus_bdrv_it, NULL); > =A0 =A0 bdrv_iterate(encrypted_bdrv_it, &context); > =A0 =A0 /* only resume the vm if all keys are set and valid */ > =A0 =A0 if (!context.err) { > -- > 1.7.7.rc0.72.g4b5ea > > > --=20 Regards, Zhi Yong Wu