On 01/21/2011 04:19 PM, Chunqiang Tang wrote:
This patch is part of the Fast Virtual Disk (FVD) proposal. See the related
discussions at
http://lists.gnu.org/archive/html/qemu-devel/2011-01/msg00426.html.
This patch adds the 'blksim' block device driver, which is a tool to
facilitate testing and debugging. blksim operates on a RAW image, but it uses
neither AIO nor posix threads to perform I/Os. Instead, blksim functions like
an event-driven disk simulator, and allows a block device driver developer to
fully control the order of disk I/Os, the order of callbacks, and the return
code of every I/O operation. The purpose is to comprehensively test a block
device driver under failures and race conditions. Bugs found by blksim under
rare race conditions are guaranteed to be precisely reproducible, with no
dependency on thread timing etc., which makes debugging much easier.
Signed-off-by: Chunqiang Tangct...@us.ibm.com
---
Makefile.objs |1 +
block/blksim.c | 752
block/blksim.h | 35 +++
3 files changed, 788 insertions(+), 0 deletions(-)
create mode 100644 block/blksim.c
create mode 100644 block/blksim.h
diff --git a/Makefile.objs b/Makefile.objs
index c3e52c5..ce5cc8d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -23,6 +23,7 @@ block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o
qcow2-snapshot.o
block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
block-nested-y += qed-check.o
block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
+block-nested-y += blksim.o
block-nested-$(CONFIG_WIN32) += raw-win32.o
block-nested-$(CONFIG_POSIX) += raw-posix.o
block-nested-$(CONFIG_CURL) += curl.o
diff --git a/block/blksim.c b/block/blksim.c
new file mode 100644
index 000..a92ba11
--- /dev/null
+++ b/block/blksim.c
@@ -0,0 +1,752 @@
+/*
+ * Copyright (c) 2010-2011 IBM
+ *
+ * Authors:
+ * Chunqiang Tangct...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+/*=
+ * A short description: this module implements a simulated block device
+ * driver blksim. It works with qemu-io and qemu-test to perform testing,
+ * allowing changing the order of disk I/O and callback activities to test
+ * rare race conditions. See qemu-test.c, qemu-io.c, and qemu-io-sim.c.
+
**/
+
+#includesys/vfs.h
+#includesys/mman.h
+#includepthread.h
+#includeexecinfo.h
+#includestdlib.h
+#includesys/ioctl.h
+#includestdint.h
+#includestdio.h
+#includeinttypes.h
QEMU code shouldn't include headers like this. It almost guarantees
breaking portability.
+#include block_int.h
+#include osdep.h
+#include qemu-option.h
+#include qemu-timer.h
+#include block.h
+#include qemu-queue.h
+#include qemu-common.h
+#include block/blksim.h
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+#endif
C99 introduces stdbool.h. That's the appropriate defines to use for
booleans.
+
+#if 0
+# define QDEBUG printf
+#else
+# define QDEBUG(format,...) do {} while (0)
+#endif
+
+typedef enum {
+SIM_NULL,
+SIM_READ,
+SIM_WRITE,
+SIM_FLUSH,
+SIM_READ_CALLBACK,
+SIM_WRITE_CALLBACK,
+SIM_FLUSH_CALLBACK,
+SIM_TIMER
+} sim_op_t;
Breaks coding style (and the C standard).
+static void sim_aio_cancel (BlockDriverAIOCB * acb);
+static int64_t sim_uuid = 0;
+static int64_t current_time = 0;
+static int64_t rand_time = 0;
+static int interactive_print = TRUE;
+static int blksim_invoked = FALSE;
+static int instant_qemubh = TRUE;
+struct SimAIOCB;
+
+/*
+ * Note: disk_io_return_code, set_disk_io_return_code(), and insert_task() work
+ * together to ensure that multiple subrequests triggered by the same
+ * outtermost request either succeed together or fail together. This behavior
+ * is required by qemu-test. Here is one example of problems caused by
+ * departuring from this behavior. Consider a write request that generates
+ * two subrequests, w1 and w2. If w1 succeeds but w2 fails, the data will not
+ * be written into qemu-test's truth image but the part of the data handled
+ * by w1 will be written into qemu-test's test image. As a result, their
+ * contents diverge can automated testing cannot continue.
+ */
+static int disk_io_return_code = 0;
+
+typedef struct BDRVSimState {
+int fd;
+} BDRVSimState;
+
+typedef struct SimAIOCB {
+BlockDriverAIOCB common;
+int64_t uuid;
+sim_op_t op;
+int64_t sector_num;
+QEMUIOVector *qiov;
+int nb_sectors;
+int ret;
+int64_t time;
+struct SimAIOCB *next;
+struct SimAIOCB *prev;
Use qemu-queue instead of open coding data structures.
+} SimAIOCB;
+
+static AIOPool sim_aio_pool = {
+.aiocb_size = sizeof (SimAIOCB),
+