From patchwork Mon Mar 22 10:00:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 48288 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9627FB7CF3 for ; Mon, 22 Mar 2010 22:02:40 +1100 (EST) Received: from localhost ([127.0.0.1]:59570 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ntf7l-0003nP-04 for incoming@patchwork.ozlabs.org; Mon, 22 Mar 2010 06:44:45 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NteRb-0004EI-5V for qemu-devel@nongnu.org; Mon, 22 Mar 2010 06:01:11 -0400 Received: from [199.232.76.173] (port=52953 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NteRa-0004Dc-Aw for qemu-devel@nongnu.org; Mon, 22 Mar 2010 06:01:10 -0400 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1NteRX-000889-TH for qemu-devel@nongnu.org; Mon, 22 Mar 2010 06:01:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:2062) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NteRW-000881-QA for qemu-devel@nongnu.org; Mon, 22 Mar 2010 06:01:07 -0400 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o2MA15mg005995 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 22 Mar 2010 06:01:06 -0400 Received: from localhost.localdomain (dhcp-5-175.str.redhat.com [10.32.5.175]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2MA0xHq006105; Mon, 22 Mar 2010 06:01:05 -0400 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Mon, 22 Mar 2010 11:00:21 +0100 Message-Id: <1269252024-5271-5-git-send-email-kwolf@redhat.com> In-Reply-To: <1269252024-5271-1-git-send-email-kwolf@redhat.com> References: <1269252024-5271-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: kwolf@redhat.com Subject: [Qemu-devel] [PATCH 4/7] blkdebug: Inject errors X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add a mechanism to inject errors instead of passing requests on. With no further patches applied, you can use it by setting inject_errno in gdb. Signed-off-by: Kevin Wolf --- block/blkdebug.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 81 insertions(+), 0 deletions(-) diff --git a/block/blkdebug.c b/block/blkdebug.c index 2c7e0dd..dad3ac6 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -26,10 +26,41 @@ #include "block_int.h" #include "module.h" +#include + +typedef struct BlkdebugVars { + int state; + + /* If inject_errno != 0, an error is injected for requests */ + int inject_errno; + + /* Decides if all future requests fail (false) or only the next one and + * after the next request inject_errno is reset to 0 (true) */ + bool inject_once; + + /* Decides if aio_readv/writev fails right away (true) or returns an error + * return value only in the callback (false) */ + bool inject_immediately; +} BlkdebugVars; + typedef struct BDRVBlkdebugState { BlockDriverState *hd; + BlkdebugVars vars; } BDRVBlkdebugState; +typedef struct BlkdebugAIOCB { + BlockDriverAIOCB common; + QEMUBH *bh; + int ret; +} BlkdebugAIOCB; + +static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb); + +static AIOPool blkdebug_aio_pool = { + .aiocb_size = sizeof(BlkdebugAIOCB), + .cancel = blkdebug_aio_cancel, +}; + static int blkdebug_open(BlockDriverState *bs, const char *filename, int flags) { BDRVBlkdebugState *s = bs->opaque; @@ -42,11 +73,56 @@ static int blkdebug_open(BlockDriverState *bs, const char *filename, int flags) return bdrv_file_open(&s->hd, filename, flags); } +static void error_callback_bh(void *opaque) +{ + struct BlkdebugAIOCB *acb = opaque; + qemu_bh_delete(acb->bh); + acb->common.cb(acb->common.opaque, acb->ret); + qemu_aio_release(acb); +} + +static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb) +{ + BlkdebugAIOCB *acb = (BlkdebugAIOCB*) blockacb; + qemu_aio_release(acb); +} + +static BlockDriverAIOCB *inject_error(BlockDriverState *bs, + BlockDriverCompletionFunc *cb, void *opaque) +{ + BDRVBlkdebugState *s = bs->opaque; + int error = s->vars.inject_errno; + struct BlkdebugAIOCB *acb; + QEMUBH *bh; + + if (s->vars.inject_once) { + s->vars.inject_errno = 0; + } + + if (s->vars.inject_immediately) { + return NULL; + } + + acb = qemu_aio_get(&blkdebug_aio_pool, bs, cb, opaque); + acb->ret = -error; + + bh = qemu_bh_new(error_callback_bh, acb); + acb->bh = bh; + qemu_bh_schedule(bh); + + return (BlockDriverAIOCB*) acb; +} + static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { BDRVBlkdebugState *s = bs->opaque; + + if (s->vars.inject_errno) { + return inject_error(bs, cb, opaque); + } + BlockDriverAIOCB *acb = bdrv_aio_readv(s->hd, sector_num, qiov, nb_sectors, cb, opaque); return acb; @@ -57,6 +133,11 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque) { BDRVBlkdebugState *s = bs->opaque; + + if (s->vars.inject_errno) { + return inject_error(bs, cb, opaque); + } + BlockDriverAIOCB *acb = bdrv_aio_writev(s->hd, sector_num, qiov, nb_sectors, cb, opaque); return acb;