qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Chunqiang Tang <ctang@us.ibm.com>
To: qemu-devel@nongnu.org
Cc: Chunqiang Tang <ctang@us.ibm.com>
Subject: [Qemu-devel] [PATCH 3/3] FVD: Made qemu-io working with simulation (blksim)
Date: Fri, 21 Jan 2011 17:19:15 -0500	[thread overview]
Message-ID: <1295648355-17359-3-git-send-email-ctang@us.ibm.com> (raw)
In-Reply-To: <1295648355-17359-1-git-send-email-ctang@us.ibm.com>

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 'sim' command to qemu-io, which works  with the blksim
driver. With this extension, now a developer can use qemu-io to precisely
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 Tang <ctang@us.ibm.com>
---
 qemu-io-sim.c |  109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-io.c     |   38 +++++++++++++++-----
 2 files changed, 138 insertions(+), 9 deletions(-)
 create mode 100644 qemu-io-sim.c

diff --git a/qemu-io-sim.c b/qemu-io-sim.c
new file mode 100644
index 0000000..816f8ae
--- /dev/null
+++ b/qemu-io-sim.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010-2011 IBM
+ *
+ * Authors:
+ *         Chunqiang Tang <ctang@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.
+ */
+
+/*=============================================================================
+ * qemu-io-sim works with qemu-io to perform simulated testing. The 'sim'
+ * command allows the user to control the order of disk I/O and callback
+ * activities in order to test rare race conditions. See block/blksim.c
+ * Note that in the manual mode, qemu-io's 'sim' command can only work with
+ * qemu-io's 'aio_read' and 'aio_write' commands. The automated testing mode,
+ * 'qemu-io --auto', performs a much more comprehensive fully automated test
+ * (see qemu-io-auto.c). Below is one example of using qemu-io to perform
+ * manual testing in the simulation mode.
+ 
+$ qemu-img create -f qcow2 -obacking_fmt=blksim -b base.raw test.qcow2
+$ qemu-io -f qcow2 blksim:test.qcow2
+qemu-io> aio_read 0 512
+Added READ uuid=0  filename=base.raw  sector_num=0  nb_sectors=1
+qemu-io> aio_read 0 1024
+Added READ uuid=1  filename=base.raw  sector_num=0  nb_sectors=2
+qemu-io> sim list
+uuid=0  READ           file=base.raw  sector_num=0  nb_sectors=1
+uuid=1  READ           file=base.raw  sector_num=0  nb_sectors=2
+qemu-io> aio_write 512 1024
+Added WRITE uuid=2  filename=test.qcow2  sector_num=33297  nb_sectors=2
+qemu-io> sim list
+uuid=0  READ           file=base.raw  sector_num=0  nb_sectors=1
+uuid=1  READ           file=base.raw  sector_num=0  nb_sectors=2
+uuid=2  WRITE          file=test.qcow2  sector_num=33297  nb_sectors=2
+qemu-io> sim 2
+Added WRITE_CALLBACK uuid=3  filename=test.qcow2  sector_num=33297  nb_sectors=2
+qemu-io> sim list
+uuid=0  READ           file=base.raw  sector_num=0  nb_sectors=1
+uuid=1  READ           file=base.raw  sector_num=0  nb_sectors=2
+uuid=3  CALLBACK WRITE file=test.qcow2  sector_num=33297  nb_sectors=2
+qemu-io> sim 1
+Added READ_CALLBACK uuid=4  filename=base.raw  sector_num=0  nb_sectors=2
+qemu-io> sim list
+uuid=0  READ           file=base.raw  sector_num=0  nb_sectors=1
+uuid=3  CALLBACK WRITE file=test.qcow2  sector_num=33297  nb_sectors=2
+uuid=4  CALLBACK READ  file=base.raw  sector_num=0  nb_sectors=2
+qemu-io> sim 3
+Added WRITE uuid=5  filename=test.qcow2  sector_num=528  nb_sectors=1
+qemu-io> sim list
+uuid=0  READ           file=base.raw  sector_num=0  nb_sectors=1
+uuid=4  CALLBACK READ  file=base.raw  sector_num=0  nb_sectors=2
+uuid=5  WRITE          file=test.qcow2  sector_num=528  nb_sectors=1
+
+*=============================================================================*/
+
+#include "block/blksim.h"
+
+static void sim_help (void)
+{
+    printf ("\n"
+            " sim list\t\tlist all simulation tasks\n"
+            " sim <#task> [#ret]\trun a simulation task, optionally "
+                    "using #ret as the return value of a read/write operation\n"
+            " sim all [#ret]\t\trun all tasks, optionally using #ret as "
+                    "the return value of read/write tasks\n"
+            " sim prefetch\t\tstart prefetching\n");
+}
+
+static int sim_f (int argc, char **argv)
+{
+    int ret = 0;
+
+    if (argc == 3) {
+        ret = atoi (argv[2]);
+    }
+    else if (argc != 2) {
+        sim_help ();
+        return 0;
+    }
+
+    if (strcmp (argv[1], "list") == 0) {
+        blksim_list_tasks ();
+    }
+    else if (strcmp (argv[1], "all") == 0) {
+        blksim_set_disk_io_return_code (ret);
+        int n = blksim_run_all_tasks ();
+        blksim_set_disk_io_return_code (0);
+        printf ("Executed %d tasks.\n", n);
+    }
+    else {
+        blksim_set_disk_io_return_code (ret);
+        blksim_run_task_by_uuid (atoll (argv[1]));
+        blksim_set_disk_io_return_code (0);
+    }
+
+    return 0;
+}
+
+static const cmdinfo_t sim_cmd = {
+    .name = "sim",
+    .altname = "s",
+    .cfunc = sim_f,
+    .argmin = 1,
+    .argmax = 2,
+    .args = "",
+    .oneline = "use simulation to control the order of disk I/Os and callbacks",
+    .help = sim_help,
+};
diff --git a/qemu-io.c b/qemu-io.c
index 5b24c5e..9144a6a 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1584,7 +1584,7 @@ static const cmdinfo_t close_cmd = {
 	.oneline	= "close the current open file",
 };
 
-static int openfile(char *name, int flags, int growable)
+static int openfile(char *name, const char *fmt, int flags, int growable)
 {
 	if (bs) {
 		fprintf(stderr, "file open already, try 'help close'\n");
@@ -1597,9 +1597,17 @@ static int openfile(char *name, int flags, int growable)
 			return 1;
 		}
 	} else {
+                BlockDriver *drv = NULL;
+                if (fmt && !(drv = bdrv_find_format (fmt))) {
+                        fprintf(stderr, "%s: can't find driver for format "
+                                "%s \n", progname, fmt);
+                        bs = NULL;
+                        return 1;
+                }
+
 		bs = bdrv_new("hda");
 
-		if (bdrv_open(bs, name, flags, NULL) < 0) {
+		if (bdrv_open(bs, name, flags, drv) < 0) {
 			fprintf(stderr, "%s: can't open device %s\n", progname, name);
 			bs = NULL;
 			return 1;
@@ -1636,7 +1644,7 @@ static const cmdinfo_t open_cmd = {
 	.argmin		= 1,
 	.argmax		= -1,
 	.flags		= CMD_NOFILE_OK,
-	.args		= "[-Crsn] [path]",
+	.args		= "[-Crsn] [-f <format>] [path]",
 	.oneline	= "open the file specified by path",
 	.help		= open_help,
 };
@@ -1648,8 +1656,9 @@ open_f(int argc, char **argv)
 	int readonly = 0;
 	int growable = 0;
 	int c;
+        const char *fmt = NULL;
 
-	while ((c = getopt(argc, argv, "snrg")) != EOF) {
+	while ((c = getopt(argc, argv, "snrgf:")) != EOF) {
 		switch (c) {
 		case 's':
 			flags |= BDRV_O_SNAPSHOT;
@@ -1663,6 +1672,9 @@ open_f(int argc, char **argv)
 		case 'g':
 			growable = 1;
 			break;
+		case 'f':
+                        fmt = optarg;
+			break;
 		default:
 			return command_usage(&open_cmd);
 		}
@@ -1675,7 +1687,7 @@ open_f(int argc, char **argv)
 	if (optind != argc - 1)
 		return command_usage(&open_cmd);
 
-	return openfile(argv[optind], flags, growable);
+	return openfile(argv[optind], fmt, flags, growable);
 }
 
 static int
@@ -1701,10 +1713,12 @@ init_check_command(
 	return 1;
 }
 
+#include "qemu-io-sim.c"
+
 static void usage(const char *name)
 {
 	printf(
-"Usage: %s [-h] [-V] [-rsnm] [-c cmd] ... [file]\n"
+"Usage: %s [-h] [-a] [-V] [-rsnm] [-c cmd] ... [file]\n"
 "QEMU Disk exerciser\n"
 "\n"
 "  -c, --cmd            command to execute\n"
@@ -1714,18 +1728,18 @@ static void usage(const char *name)
 "  -g, --growable       allow file to grow (only applies to protocols)\n"
 "  -m, --misalign       misalign allocations for O_DIRECT\n"
 "  -k, --native-aio     use kernel AIO implementation (on Linux only)\n"
+"  -f, --format         image format of the file\n"
 "  -h, --help           display this help and exit\n"
 "  -V, --version        output version information and exit\n"
 "\n",
 	name);
 }
 
-
 int main(int argc, char **argv)
 {
 	int readonly = 0;
 	int growable = 0;
-	const char *sopt = "hVc:rsnmgk";
+	const char *sopt = "hVc:rsnmgkaf:";
         const struct option lopt[] = {
 		{ "help", 0, NULL, 'h' },
 		{ "version", 0, NULL, 'V' },
@@ -1737,11 +1751,13 @@ int main(int argc, char **argv)
 		{ "misalign", 0, NULL, 'm' },
 		{ "growable", 0, NULL, 'g' },
 		{ "native-aio", 0, NULL, 'k' },
+		{ "format", 1, NULL, 'f' },
 		{ NULL, 0, NULL, 0 }
 	};
 	int c;
 	int opt_index = 0;
 	int flags = 0;
+        const char *fmt = NULL;
 
 	progname = basename(argv[0]);
 
@@ -1768,6 +1784,9 @@ int main(int argc, char **argv)
 		case 'k':
 			flags |= BDRV_O_NATIVE_AIO;
 			break;
+		case 'f':
+                        fmt = optarg;
+                        break;
 		case 'V':
 			printf("%s version %s\n", progname, VERSION);
 			exit(0);
@@ -1807,6 +1826,7 @@ int main(int argc, char **argv)
 	add_command(&discard_cmd);
 	add_command(&alloc_cmd);
 	add_command(&map_cmd);
+        add_command(&sim_cmd);
 
 	add_args_command(init_args_command);
 	add_check_command(init_check_command);
@@ -1817,7 +1837,7 @@ int main(int argc, char **argv)
         }
 
 	if ((argc - optind) == 1)
-		openfile(argv[optind], flags, growable);
+		openfile(argv[optind], fmt, flags, growable);
 	command_loop();
 
 	/*
-- 
1.7.0.4

  parent reply	other threads:[~2011-01-21 22:16 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-21 22:19 [Qemu-devel] [PATCH 1/3] FVD: Added support for 'qemu-img update' Chunqiang Tang
2011-01-21 22:19 ` [Qemu-devel] [PATCH 2/3] FVD: Added the simulated 'blksim' driver Chunqiang Tang
2011-01-21 22:49   ` Anthony Liguori
2011-01-22  3:09     ` Chunqiang Tang
2011-01-23 23:26       ` Anthony Liguori
2011-01-24 15:07         ` Chunqiang Tang
2011-01-23 15:26   ` Andreas Färber
2011-01-25 16:54     ` Chunqiang Tang
2011-01-21 22:19 ` Chunqiang Tang [this message]
2011-01-28  9:57 ` [Qemu-devel] [PATCH 1/3] FVD: Added support for 'qemu-img update' Stefan Hajnoczi
2011-01-28 14:51   ` Chunqiang Tang
2011-01-28 16:16     ` Stefan Hajnoczi
2011-01-28 21:26       ` Chunqiang Tang
2011-01-29 10:05         ` Stefan Hajnoczi
2011-01-31 14:49           ` Chunqiang Tang
2011-02-01 13:53             ` Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1295648355-17359-3-git-send-email-ctang@us.ibm.com \
    --to=ctang@us.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).