From patchwork Mon Mar 15 17:08:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 47773 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 C9FB6B7CFB for ; Tue, 16 Mar 2010 04:27:09 +1100 (EST) Received: from localhost ([127.0.0.1]:55008 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NrE0l-0000DV-G2 for incoming@patchwork.ozlabs.org; Mon, 15 Mar 2010 13:23:27 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NrDnJ-0004RX-FB for qemu-devel@nongnu.org; Mon, 15 Mar 2010 13:09:33 -0400 Received: from [199.232.76.173] (port=60321 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NrDnI-0004RC-Te for qemu-devel@nongnu.org; Mon, 15 Mar 2010 13:09:32 -0400 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1NrDnG-0005sH-Ml for qemu-devel@nongnu.org; Mon, 15 Mar 2010 13:09:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:1331) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NrDnF-0005sA-S0 for qemu-devel@nongnu.org; Mon, 15 Mar 2010 13:09:30 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o2FH9TQY006317 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 15 Mar 2010 13:09:29 -0400 Received: from localhost.localdomain (vpn1-6-64.ams2.redhat.com [10.36.6.64]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2FH9CWl018739; Mon, 15 Mar 2010 13:09:27 -0400 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Mon, 15 Mar 2010 18:08:35 +0100 Message-Id: <1268672915-12233-8-git-send-email-kwolf@redhat.com> In-Reply-To: <1268672915-12233-1-git-send-email-kwolf@redhat.com> References: <1268672915-12233-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: kwolf@redhat.com Subject: [Qemu-devel] [RFC][PATCH 7/7] qcow2: Trigger blkdebug events 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 This adds blkdebug events to qcow2 to allow injecting I/O errors in specific places. Signed-off-by: Kevin Wolf Reviewed-by: Christoph Hellwig --- block.h | 19 +++++++++++++++++++ block/blkdebug.c | 17 +++++++++++++++++ block/qcow2-cluster.c | 15 +++++++++++++++ 3 files changed, 51 insertions(+), 0 deletions(-) diff --git a/block.h b/block.h index 2fd8361..c0f17aa 100644 --- a/block.h +++ b/block.h @@ -210,6 +210,25 @@ int64_t bdrv_get_dirty_count(BlockDriverState *bs); typedef enum { + BLKDBG_L1_UPDATE, + + BLKDBG_L1_GROW_ALLOC_TABLE, + BLKDBG_L1_GROW_WRITE_TABLE, + BLKDBG_L1_GROW_ACTIVATE_TABLE, + + BLKDBG_L2_LOAD, + BLKDBG_L2_UPDATE, + BLKDBG_L2_UPDATE_COMPRESSED, + BLKDBG_L2_ALLOC_COW_READ, + BLKDBG_L2_ALLOC_WRITE, + + BLKDBG_READ, + BLKDBG_READ_BACKING, + BLKDBG_READ_COMPRESSED, + + BLKDBG_COW_READ, + BLKDBG_COW_WRITE, + BLKDBG_EVENT_MAX, } BlkDebugEvent; diff --git a/block/blkdebug.c b/block/blkdebug.c index 22b1768..2398975 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -126,6 +126,23 @@ static QemuOptsList *config_groups[] = { }; static const char *event_names[BLKDBG_EVENT_MAX] = { + [BLKDBG_L1_UPDATE] = "l1_update", + [BLKDBG_L1_GROW_ALLOC_TABLE] = "l1_grow.alloc_table", + [BLKDBG_L1_GROW_WRITE_TABLE] = "l1_grow.write_table", + [BLKDBG_L1_GROW_ACTIVATE_TABLE] = "l1_grow.activate_table", + + [BLKDBG_L2_LOAD] = "l2_load", + [BLKDBG_L2_UPDATE] = "l2_update", + [BLKDBG_L2_UPDATE_COMPRESSED] = "l2_update_compressed", + [BLKDBG_L2_ALLOC_COW_READ] = "l2_alloc.cow_read", + [BLKDBG_L2_ALLOC_WRITE] = "l2_alloc.write", + + [BLKDBG_READ] = "read", + [BLKDBG_READ_BACKING] = "read_backing", + [BLKDBG_READ_COMPRESSED] = "read_compressed", + + [BLKDBG_COW_READ] = "cow_read", + [BLKDBG_COW_WRITE] = "cow_write", }; static int get_event_by_name(const char *name, BlkDebugEvent *event) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index b13b693..9b3d686 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -54,12 +54,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size) memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t)); /* write new table (align to cluster) */ + BLKDBG_EVENT(s->hd, BLKDBG_L1_GROW_ALLOC_TABLE); new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2); if (new_l1_table_offset < 0) { qemu_free(new_l1_table); return new_l1_table_offset; } + BLKDBG_EVENT(s->hd, BLKDBG_L1_GROW_WRITE_TABLE); for(i = 0; i < s->l1_size; i++) new_l1_table[i] = cpu_to_be64(new_l1_table[i]); ret = bdrv_pwrite(s->hd, new_l1_table_offset, new_l1_table, new_l1_size2); @@ -69,6 +71,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size) new_l1_table[i] = be64_to_cpu(new_l1_table[i]); /* set new table */ + BLKDBG_EVENT(s->hd, BLKDBG_L1_GROW_ACTIVATE_TABLE); cpu_to_be32w((uint32_t*)data, new_l1_size); cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset); ret = bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,sizeof(data)); @@ -170,6 +173,8 @@ static uint64_t *l2_load(BlockDriverState *bs, uint64_t l2_offset) min_index = l2_cache_new_entry(bs); l2_table = s->l2_cache + (min_index << s->l2_bits); + + BLKDBG_EVENT(s->hd, BLKDBG_L2_LOAD); if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) != s->l2_size * sizeof(uint64_t)) return NULL; @@ -195,6 +200,7 @@ static int write_l1_entry(BDRVQcowState *s, int l1_index) buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]); } + BLKDBG_EVENT(s->hd, BLKDBG_L1_UPDATE); if (bdrv_pwrite(s->hd, s->l1_table_offset + 8 * l1_start_index, buf, sizeof(buf)) != sizeof(buf)) { @@ -248,12 +254,14 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index) memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); } else { /* if there was an old l2 table, read it from the disk */ + BLKDBG_EVENT(s->hd, BLKDBG_L2_ALLOC_COW_READ); if (bdrv_pread(s->hd, old_l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) != s->l2_size * sizeof(uint64_t)) return NULL; } /* write the l2 table to the file */ + BLKDBG_EVENT(s->hd, BLKDBG_L2_ALLOC_WRITE); if (bdrv_pwrite(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) != s->l2_size * sizeof(uint64_t)) @@ -335,6 +343,7 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num, /* read from the base image */ n1 = qcow2_backing_read1(bs->backing_hd, sector_num, buf, n); if (n1 > 0) { + BLKDBG_EVENT(s->hd, BLKDBG_READ_BACKING); ret = bdrv_read(bs->backing_hd, sector_num, buf, n1); if (ret < 0) return -1; @@ -347,6 +356,7 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num, return -1; memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n); } else { + BLKDBG_EVENT(s->hd, BLKDBG_READ); ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512); if (ret != n * 512) return -1; @@ -371,6 +381,7 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect, n = n_end - n_start; if (n <= 0) return 0; + BLKDBG_EVENT(s->hd, BLKDBG_COW_READ); ret = qcow_read(bs, start_sect + n_start, s->cluster_data, n); if (ret < 0) return ret; @@ -380,6 +391,7 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect, s->cluster_data, n, 1, &s->aes_encrypt_key); } + BLKDBG_EVENT(s->hd, BLKDBG_COW_WRITE); ret = bdrv_write(s->hd, (cluster_offset >> 9) + n_start, s->cluster_data, n); if (ret < 0) @@ -592,6 +604,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, /* compressed clusters never have the copied flag */ + BLKDBG_EVENT(s->hd, BLKDBG_L2_UPDATE_COMPRESSED); l2_table[l2_index] = cpu_to_be64(cluster_offset); if (bdrv_pwrite(s->hd, l2_offset + l2_index * sizeof(uint64_t), @@ -615,6 +628,7 @@ static int write_l2_entries(BDRVQcowState *s, uint64_t *l2_table, int end_offset = (8 * (l2_index + num) + 511) & ~511; size_t len = end_offset - start_offset; + BLKDBG_EVENT(s->hd, BLKDBG_L2_UPDATE); if (bdrv_pwrite(s->hd, l2_offset + start_offset, &l2_table[l2_start_index], len) != len) { @@ -865,6 +879,7 @@ int qcow2_decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset) nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1; sector_offset = coffset & 511; csize = nb_csectors * 512 - sector_offset; + BLKDBG_EVENT(s->hd, BLKDBG_READ_COMPRESSED); ret = bdrv_read(s->hd, coffset >> 9, s->cluster_data, nb_csectors); if (ret < 0) { return -1;