* [Qemu-devel] [PATCH 0/6] blkdebug/qcow2/qemu-iotests: Add some AIO testing
@ 2012-12-06 13:32 Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 1/6] blkdebug: Allow usage without config file Kevin Wolf
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Kevin Wolf @ 2012-12-06 13:32 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, stefanha
The few existing test cases that involve AIO depend on luck for getting the
right order of requests so that they really test interesting cases. This series
allows a more systematic approach by stopping and resuming AIO requests at
given points.
Kevin Wolf (6):
blkdebug: Allow usage without config file
blkdebug: Factor out remove_rule()
blkdebug: Implement suspend/resume of AIO requests
qemu-io: Add AIO debugging commands
qcow2: Move BLKDBG_EVENT out of the lock
qemu-iotests: Test concurrent cluster allocations
block.c | 39 ++++++++
block.h | 5 +
block/blkdebug.c | 128 +++++++++++++++++++++++++-
block/qcow2.c | 2 +-
block_int.h | 6 ++
qemu-io.c | 64 +++++++++++++
tests/qemu-iotests/046 | 215 ++++++++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/046.out | 163 +++++++++++++++++++++++++++++++++
tests/qemu-iotests/group | 1 +
9 files changed, 617 insertions(+), 6 deletions(-)
create mode 100755 tests/qemu-iotests/046
create mode 100644 tests/qemu-iotests/046.out
--
1.7.6.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 1/6] blkdebug: Allow usage without config file
2012-12-06 13:32 [Qemu-devel] [PATCH 0/6] blkdebug/qcow2/qemu-iotests: Add some AIO testing Kevin Wolf
@ 2012-12-06 13:32 ` Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 2/6] blkdebug: Factor out remove_rule() Kevin Wolf
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Kevin Wolf @ 2012-12-06 13:32 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, stefanha
As soon as new rules can be set during runtime, as introduced by the
next patch, blkdebug makes sense even without a config file.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/blkdebug.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index d61ece8..c9041ec 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -240,6 +240,11 @@ static int read_config(BDRVBlkdebugState *s, const char *filename)
int ret;
struct add_rule_data d;
+ /* Allow usage without config file */
+ if (!*filename) {
+ return 0;
+ }
+
f = fopen(filename, "r");
if (f == NULL) {
return -errno;
--
1.7.6.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 2/6] blkdebug: Factor out remove_rule()
2012-12-06 13:32 [Qemu-devel] [PATCH 0/6] blkdebug/qcow2/qemu-iotests: Add some AIO testing Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 1/6] blkdebug: Allow usage without config file Kevin Wolf
@ 2012-12-06 13:32 ` Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 3/6] blkdebug: Implement suspend/resume of AIO requests Kevin Wolf
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Kevin Wolf @ 2012-12-06 13:32 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, stefanha
The cleanup work to remove a rule depends on the type of the rule. It's
easy for the existing rules as there is no data that must be cleaned up
and is specific to a type yet, but the next patch will change this.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/blkdebug.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index c9041ec..859792b 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -234,6 +234,18 @@ static int add_rule(QemuOpts *opts, void *opaque)
return 0;
}
+static void remove_rule(BlkdebugRule *rule)
+{
+ switch (rule->action) {
+ case ACTION_INJECT_ERROR:
+ case ACTION_SET_STATE:
+ break;
+ }
+
+ QLIST_REMOVE(rule, next);
+ g_free(rule);
+}
+
static int read_config(BDRVBlkdebugState *s, const char *filename)
{
FILE *f;
@@ -402,8 +414,7 @@ static void blkdebug_close(BlockDriverState *bs)
for (i = 0; i < BLKDBG_EVENT_MAX; i++) {
QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) {
- QLIST_REMOVE(rule, next);
- g_free(rule);
+ remove_rule(rule);
}
}
}
--
1.7.6.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 3/6] blkdebug: Implement suspend/resume of AIO requests
2012-12-06 13:32 [Qemu-devel] [PATCH 0/6] blkdebug/qcow2/qemu-iotests: Add some AIO testing Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 1/6] blkdebug: Allow usage without config file Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 2/6] blkdebug: Factor out remove_rule() Kevin Wolf
@ 2012-12-06 13:32 ` Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 4/6] qemu-io: Add AIO debugging commands Kevin Wolf
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Kevin Wolf @ 2012-12-06 13:32 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, stefanha
This allows more systematic AIO testing. The patch adds three new
operations to blkdebug:
* Setting a "breakpoint" on a blkdebug event. The next request that
triggers this breakpoint is suspended and is tagged with a name.
The breakpoint is removed after a request has triggered it.
* A suspended request (identified by it's tag) can be resumed
* It's possible to check whether a suspended request with a given
tag exists. This can be used for waiting for an event.
Ideally, we would instead tag requests right when they are created and
set breakpoints for individual requests. However, at this point the
block layer doesn't allow this easily, and breakpoints that trigger for
any request already allow a lot of useful testing.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/blkdebug.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 105 insertions(+), 3 deletions(-)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 859792b..294e983 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -29,8 +29,10 @@
typedef struct BDRVBlkdebugState {
int state;
int new_state;
+
QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_EVENT_MAX];
QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
+ QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs;
} BDRVBlkdebugState;
typedef struct BlkdebugAIOCB {
@@ -39,6 +41,12 @@ typedef struct BlkdebugAIOCB {
int ret;
} BlkdebugAIOCB;
+typedef struct BlkdebugSuspendedReq {
+ Coroutine *co;
+ char *tag;
+ QLIST_ENTRY(BlkdebugSuspendedReq) next;
+} BlkdebugSuspendedReq;
+
static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb);
static const AIOCBInfo blkdebug_aiocb_info = {
@@ -49,6 +57,7 @@ static const AIOCBInfo blkdebug_aiocb_info = {
enum {
ACTION_INJECT_ERROR,
ACTION_SET_STATE,
+ ACTION_SUSPEND,
};
typedef struct BlkdebugRule {
@@ -65,6 +74,9 @@ typedef struct BlkdebugRule {
struct {
int new_state;
} set_state;
+ struct {
+ char *tag;
+ } suspend;
} options;
QLIST_ENTRY(BlkdebugRule) next;
QSIMPLEQ_ENTRY(BlkdebugRule) active_next;
@@ -226,6 +238,11 @@ static int add_rule(QemuOpts *opts, void *opaque)
rule->options.set_state.new_state =
qemu_opt_get_number(opts, "new_state", 0);
break;
+
+ case ACTION_SUSPEND:
+ rule->options.suspend.tag =
+ g_strdup(qemu_opt_get(opts, "tag"));
+ break;
};
/* Add the rule */
@@ -240,6 +257,9 @@ static void remove_rule(BlkdebugRule *rule)
case ACTION_INJECT_ERROR:
case ACTION_SET_STATE:
break;
+ case ACTION_SUSPEND:
+ g_free(rule->options.suspend.tag);
+ break;
}
QLIST_REMOVE(rule, next);
@@ -406,6 +426,7 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
}
+
static void blkdebug_close(BlockDriverState *bs)
{
BDRVBlkdebugState *s = bs->opaque;
@@ -419,6 +440,27 @@ static void blkdebug_close(BlockDriverState *bs)
}
}
+static void suspend_request(BlockDriverState *bs, BlkdebugRule *rule)
+{
+ BDRVBlkdebugState *s = bs->opaque;
+ BlkdebugSuspendedReq r;
+
+ r = (BlkdebugSuspendedReq) {
+ .co = qemu_coroutine_self(),
+ .tag = g_strdup(rule->options.suspend.tag),
+ };
+
+ remove_rule(rule);
+ QLIST_INSERT_HEAD(&s->suspended_reqs, &r, next);
+
+ printf("blkdebug: Suspended request '%s'\n", r.tag);
+ qemu_coroutine_yield();
+ printf("blkdebug: Resuming request '%s'\n", r.tag);
+
+ QLIST_REMOVE(&r, next);
+ g_free(r.tag);
+}
+
static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
bool injected)
{
@@ -442,6 +484,10 @@ static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
case ACTION_SET_STATE:
s->new_state = rule->options.set_state.new_state;
break;
+
+ case ACTION_SUSPEND:
+ suspend_request(bs, rule);
+ break;
}
return injected;
}
@@ -449,19 +495,72 @@ static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
static void blkdebug_debug_event(BlockDriverState *bs, BlkDebugEvent event)
{
BDRVBlkdebugState *s = bs->opaque;
- struct BlkdebugRule *rule;
+ struct BlkdebugRule *rule, *next;
bool injected;
assert((int)event >= 0 && event < BLKDBG_EVENT_MAX);
injected = false;
s->new_state = s->state;
- QLIST_FOREACH(rule, &s->rules[event], next) {
+ QLIST_FOREACH_SAFE(rule, &s->rules[event], next, next) {
injected = process_rule(bs, rule, injected);
}
s->state = s->new_state;
}
+static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event,
+ const char *tag)
+{
+ BDRVBlkdebugState *s = bs->opaque;
+ struct BlkdebugRule *rule;
+ BlkDebugEvent blkdebug_event;
+
+ if (get_event_by_name(event, &blkdebug_event) < 0) {
+ return -ENOENT;
+ }
+
+
+ rule = g_malloc(sizeof(*rule));
+ *rule = (struct BlkdebugRule) {
+ .event = blkdebug_event,
+ .action = ACTION_SUSPEND,
+ .state = 0,
+ .options.suspend.tag = g_strdup(tag),
+ };
+
+ QLIST_INSERT_HEAD(&s->rules[blkdebug_event], rule, next);
+
+ return 0;
+}
+
+static int blkdebug_debug_resume(BlockDriverState *bs, const char *tag)
+{
+ BDRVBlkdebugState *s = bs->opaque;
+ BlkdebugSuspendedReq *r;
+
+ QLIST_FOREACH(r, &s->suspended_reqs, next) {
+ if (!strcmp(r->tag, tag)) {
+ qemu_coroutine_enter(r->co, NULL);
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+
+
+static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
+{
+ BDRVBlkdebugState *s = bs->opaque;
+ BlkdebugSuspendedReq *r;
+
+ QLIST_FOREACH(r, &s->suspended_reqs, next) {
+ if (!strcmp(r->tag, tag)) {
+ return true;
+ }
+ }
+ return false;
+}
+
static int64_t blkdebug_getlength(BlockDriverState *bs)
{
return bdrv_getlength(bs->file);
@@ -480,7 +579,10 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_aio_readv = blkdebug_aio_readv,
.bdrv_aio_writev = blkdebug_aio_writev,
- .bdrv_debug_event = blkdebug_debug_event,
+ .bdrv_debug_event = blkdebug_debug_event,
+ .bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
+ .bdrv_debug_resume = blkdebug_debug_resume,
+ .bdrv_debug_is_suspended = blkdebug_debug_is_suspended,
};
static void bdrv_blkdebug_init(void)
--
1.7.6.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 4/6] qemu-io: Add AIO debugging commands
2012-12-06 13:32 [Qemu-devel] [PATCH 0/6] blkdebug/qcow2/qemu-iotests: Add some AIO testing Kevin Wolf
` (2 preceding siblings ...)
2012-12-06 13:32 ` [Qemu-devel] [PATCH 3/6] blkdebug: Implement suspend/resume of AIO requests Kevin Wolf
@ 2012-12-06 13:32 ` Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 5/6] qcow2: Move BLKDBG_EVENT out of the lock Kevin Wolf
2012-12-06 13:33 ` [Qemu-devel] [PATCH 6/6] qemu-iotests: Test concurrent cluster allocations Kevin Wolf
5 siblings, 0 replies; 7+ messages in thread
From: Kevin Wolf @ 2012-12-06 13:32 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, stefanha
This makes the blkdebug suspend/resume functionality available in
qemu-io. Use it like this:
$ ./qemu-io blkdebug::/tmp/test.qcow2
qemu-io> break write_aio req_a
qemu-io> aio_write 0 4k
qemu-io> blkdebug: Suspended request 'req_a'
qemu-io> resume req_a
blkdebug: Resuming request 'req_a'
qemu-io> wrote 4096/4096 bytes at offset 0
4 KiB, 1 ops; 0:00:30.71 (133.359788 bytes/sec and 0.0326 ops/sec)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 39 +++++++++++++++++++++++++++++++++++
block.h | 5 ++++
block_int.h | 6 +++++
qemu-io.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 114 insertions(+), 0 deletions(-)
diff --git a/block.c b/block.c
index b3faf3a..0668c4b 100644
--- a/block.c
+++ b/block.c
@@ -3045,7 +3045,46 @@ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
}
drv->bdrv_debug_event(bs, event);
+}
+
+int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
+ const char *tag)
+{
+ while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) {
+ bs = bs->file;
+ }
+
+ if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) {
+ return bs->drv->bdrv_debug_breakpoint(bs, event, tag);
+ }
+
+ return -ENOTSUP;
+}
+
+int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
+{
+ while (bs && bs->drv && !bs->drv->bdrv_debug_resume) {
+ bs = bs->file;
+ }
+ if (bs && bs->drv && bs->drv->bdrv_debug_resume) {
+ return bs->drv->bdrv_debug_resume(bs, tag);
+ }
+
+ return -ENOTSUP;
+}
+
+bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
+{
+ while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) {
+ bs = bs->file;
+ }
+
+ if (bs && bs->drv && bs->drv->bdrv_debug_is_suspended) {
+ return bs->drv->bdrv_debug_is_suspended(bs, tag);
+ }
+
+ return false;
}
/**************************************************************/
diff --git a/block.h b/block.h
index 24bea09..893448a 100644
--- a/block.h
+++ b/block.h
@@ -431,4 +431,9 @@ typedef enum {
#define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt)
void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event);
+int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
+ const char *tag);
+int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
+bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
+
#endif
diff --git a/block_int.h b/block_int.h
index 9deedb8..bf3f79b 100644
--- a/block_int.h
+++ b/block_int.h
@@ -190,6 +190,12 @@ struct BlockDriver {
void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
+ /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
+ int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
+ const char *tag);
+ int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
+ bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
+
/*
* Returns 1 if newly created images are guaranteed to contain only
* zeros, 0 otherwise.
diff --git a/qemu-io.c b/qemu-io.c
index b4b0898..1637773 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1671,6 +1671,67 @@ static const cmdinfo_t map_cmd = {
.oneline = "prints the allocated areas of a file",
};
+static int break_f(int argc, char **argv)
+{
+ int ret;
+
+ ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]);
+ if (ret < 0) {
+ printf("Could not set breakpoint: %s\n", strerror(-ret));
+ }
+
+ return 0;
+}
+
+static const cmdinfo_t break_cmd = {
+ .name = "break",
+ .argmin = 2,
+ .argmax = 2,
+ .cfunc = break_f,
+ .args = "event tag",
+ .oneline = "sets a breakpoint on event and tags the stopped "
+ "request as tag",
+};
+
+static int resume_f(int argc, char **argv)
+{
+ int ret;
+
+ ret = bdrv_debug_resume(bs, argv[1]);
+ if (ret < 0) {
+ printf("Could not resume request: %s\n", strerror(-ret));
+ }
+
+ return 0;
+}
+
+static const cmdinfo_t resume_cmd = {
+ .name = "resume",
+ .argmin = 1,
+ .argmax = 1,
+ .cfunc = resume_f,
+ .args = "tag",
+ .oneline = "resumes the request tagged as tag",
+};
+
+static int wait_break_f(int argc, char **argv)
+{
+ while (!bdrv_debug_is_suspended(bs, argv[1])) {
+ qemu_aio_wait();
+ }
+
+ return 0;
+}
+
+static const cmdinfo_t wait_break_cmd = {
+ .name = "wait_break",
+ .argmin = 1,
+ .argmax = 1,
+ .cfunc = wait_break_f,
+ .args = "tag",
+ .oneline = "waits for the suspension of a request",
+};
+
static int abort_f(int argc, char **argv)
{
abort();
@@ -1934,6 +1995,9 @@ int main(int argc, char **argv)
add_command(&discard_cmd);
add_command(&alloc_cmd);
add_command(&map_cmd);
+ add_command(&break_cmd);
+ add_command(&resume_cmd);
+ add_command(&wait_break_cmd);
add_command(&abort_cmd);
add_args_command(init_args_command);
--
1.7.6.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 5/6] qcow2: Move BLKDBG_EVENT out of the lock
2012-12-06 13:32 [Qemu-devel] [PATCH 0/6] blkdebug/qcow2/qemu-iotests: Add some AIO testing Kevin Wolf
` (3 preceding siblings ...)
2012-12-06 13:32 ` [Qemu-devel] [PATCH 4/6] qemu-io: Add AIO debugging commands Kevin Wolf
@ 2012-12-06 13:32 ` Kevin Wolf
2012-12-06 13:33 ` [Qemu-devel] [PATCH 6/6] qemu-iotests: Test concurrent cluster allocations Kevin Wolf
5 siblings, 0 replies; 7+ messages in thread
From: Kevin Wolf @ 2012-12-06 13:32 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, stefanha
We want to use these events to suspend requests for testing concurrent
AIO requests. Suspending requests while they are holding the CoMutex is
rather boring for this purpose.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index c1ff31f..0a08ec7 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -835,8 +835,8 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
cur_nr_sectors * 512);
}
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
qemu_co_mutex_unlock(&s->lock);
+ BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
trace_qcow2_writev_data(qemu_coroutine_self(),
(cluster_offset >> 9) + index_in_cluster);
ret = bdrv_co_writev(bs->file,
--
1.7.6.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 6/6] qemu-iotests: Test concurrent cluster allocations
2012-12-06 13:32 [Qemu-devel] [PATCH 0/6] blkdebug/qcow2/qemu-iotests: Add some AIO testing Kevin Wolf
` (4 preceding siblings ...)
2012-12-06 13:32 ` [Qemu-devel] [PATCH 5/6] qcow2: Move BLKDBG_EVENT out of the lock Kevin Wolf
@ 2012-12-06 13:33 ` Kevin Wolf
5 siblings, 0 replies; 7+ messages in thread
From: Kevin Wolf @ 2012-12-06 13:33 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, stefanha
This adds some first tests for qcow2's dependency handling when two
parallel write requests access the same cluster.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
tests/qemu-iotests/046 | 215 ++++++++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/046.out | 163 +++++++++++++++++++++++++++++++++
tests/qemu-iotests/group | 1 +
3 files changed, 379 insertions(+), 0 deletions(-)
create mode 100755 tests/qemu-iotests/046
create mode 100644 tests/qemu-iotests/046.out
diff --git a/tests/qemu-iotests/046 b/tests/qemu-iotests/046
new file mode 100755
index 0000000..e0176f4
--- /dev/null
+++ b/tests/qemu-iotests/046
@@ -0,0 +1,215 @@
+#!/bin/bash
+#
+# Test concurrent cluster allocations
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+CLUSTER_SIZE=64k
+size=128M
+
+echo
+echo "== creating backing file for COW tests =="
+
+_make_test_img $size
+
+function backing_io()
+{
+ local offset=$1
+ local sectors=$2
+ local op=$3
+ local pattern=0
+ local cur_sec=0
+
+ for i in $(seq 0 $((sectors - 1))); do
+ cur_sec=$((offset / 65536 + i))
+ pattern=$(( ( (cur_sec % 128) + (cur_sec / 128)) % 128 ))
+
+ echo "$op -P $pattern $((cur_sec * 64))k 64k"
+ done
+}
+
+backing_io 0 16 write | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+mv $TEST_IMG $TEST_IMG.base
+
+_make_test_img -b $TEST_IMG.base 6G
+
+echo
+echo "== Some concurrent requests touching the same cluster =="
+
+function overlay_io()
+{
+# Allocate middle of cluster 1, then write to somewhere before and after it
+cat <<EOF
+break write_aio A
+aio_write -P 10 0x18000 0x2000
+wait_break A
+
+aio_write -P 11 0x12000 0x2000
+aio_write -P 12 0x1c000 0x2000
+
+resume A
+aio_flush
+EOF
+
+# Sequential write case: Alloc middle of cluster 2, then write overlapping
+# to next cluster
+cat <<EOF
+break write_aio A
+aio_write -P 20 0x28000 0x2000
+wait_break A
+aio_write -P 21 0x2a000 0x10000
+resume A
+aio_flush
+EOF
+
+# The same with a gap between both requests
+cat <<EOF
+break write_aio A
+aio_write -P 40 0x48000 0x2000
+wait_break A
+aio_write -P 41 0x4c000 0x10000
+resume A
+aio_flush
+EOF
+
+# Sequential write, but the next cluster is already allocated
+cat <<EOF
+write -P 70 0x76000 0x8000
+aio_flush
+break write_aio A
+aio_write -P 60 0x66000 0x2000
+wait_break A
+aio_write -P 61 0x6a000 0xe000
+resume A
+aio_flush
+EOF
+
+# Sequential write, but the next cluster is already allocated
+# and phyiscally in the right position
+cat <<EOF
+write -P 89 0x80000 0x1000
+write -P 90 0x96000 0x8000
+aio_flush
+discard 0x80000 0x10000
+aio_flush
+break write_aio A
+aio_write -P 80 0x86000 0x2000
+wait_break A
+aio_write -P 81 0x8a000 0xe000
+resume A
+aio_flush
+EOF
+
+# Sequential write, and the next cluster is compressed
+cat <<EOF
+write -P 109 0xa0000 0x1000
+write -c -P 110 0xb0000 0x10000
+aio_flush
+discard 0xa0000 0x10000
+aio_flush
+break write_aio A
+aio_write -P 100 0xa6000 0x2000
+wait_break A
+aio_write -P 101 0xaa000 0xe000
+resume A
+aio_flush
+EOF
+}
+
+overlay_io | $QEMU_IO blkdebug::$TEST_IMG | _filter_qemu_io |\
+ sed -e 's/bytes at offset [0-9]*/bytes at offset XXX/g'
+
+echo
+echo "== Verify image content =="
+
+function verify_io()
+{
+ echo read -P 0 0 0x10000
+
+ echo read -P 1 0x10000 0x2000
+ echo read -P 11 0x12000 0x2000
+ echo read -P 1 0x14000 0x4000
+ echo read -P 10 0x18000 0x2000
+ echo read -P 1 0x1a000 0x2000
+ echo read -P 12 0x1c000 0x2000
+ echo read -P 1 0x1e000 0x2000
+
+ echo read -P 2 0x20000 0x8000
+ echo read -P 20 0x28000 0x2000
+ echo read -P 21 0x2a000 0x10000
+ echo read -P 3 0x3a000 0x6000
+
+ echo read -P 4 0x40000 0x8000
+ echo read -P 40 0x48000 0x2000
+ echo read -P 4 0x4a000 0x2000
+ echo read -P 41 0x4c000 0x10000
+ echo read -P 5 0x5c000 0x4000
+
+ echo read -P 6 0x60000 0x6000
+ echo read -P 60 0x66000 0x2000
+ echo read -P 6 0x68000 0x2000
+ echo read -P 61 0x6a000 0xe000
+ echo read -P 70 0x78000 0x6000
+ echo read -P 7 0x7e000 0x2000
+
+ echo read -P 8 0x80000 0x6000
+ echo read -P 80 0x86000 0x2000
+ echo read -P 8 0x88000 0x2000
+ echo read -P 81 0x8a000 0xe000
+ echo read -P 90 0x98000 0x6000
+ echo read -P 9 0x9e000 0x2000
+
+ echo read -P 10 0xa0000 0x6000
+ echo read -P 100 0xa6000 0x2000
+ echo read -P 10 0xa8000 0x2000
+ echo read -P 101 0xaa000 0xe000
+ echo read -P 110 0xb8000 0x8000
+}
+
+verify_io | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/046.out b/tests/qemu-iotests/046.out
new file mode 100644
index 0000000..565360f
--- /dev/null
+++ b/tests/qemu-iotests/046.out
@@ -0,0 +1,163 @@
+QA output created by 046
+
+== creating backing file for COW tests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+qemu-io> wrote 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 131072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 196608
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 262144
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 327680
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 393216
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 458752
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 524288
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 589824
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 655360
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 720896
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 786432
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 851968
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 917504
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 983040
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+
+== Some concurrent requests touching the same cluster ==
+qemu-io> qemu-io> qemu-io> blkdebug: Suspended request 'A'
+qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A'
+qemu-io> wrote 8192/8192 bytes at offset XXX
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 8192/8192 bytes at offset XXX
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 8192/8192 bytes at offset XXX
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> qemu-io> blkdebug: Suspended request 'A'
+qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A'
+qemu-io> wrote 8192/8192 bytes at offset XXX
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> qemu-io> blkdebug: Suspended request 'A'
+qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A'
+qemu-io> wrote 8192/8192 bytes at offset XXX
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 32768/32768 bytes at offset XXX
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> qemu-io> qemu-io> blkdebug: Suspended request 'A'
+qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A'
+qemu-io> wrote 8192/8192 bytes at offset XXX
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 57344/57344 bytes at offset XXX
+56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 4096/4096 bytes at offset XXX
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 32768/32768 bytes at offset XXX
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> qemu-io> discard 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> qemu-io> qemu-io> blkdebug: Suspended request 'A'
+qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A'
+qemu-io> wrote 8192/8192 bytes at offset XXX
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 57344/57344 bytes at offset XXX
+56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 4096/4096 bytes at offset XXX
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> qemu-io> discard 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> qemu-io> qemu-io> blkdebug: Suspended request 'A'
+qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A'
+qemu-io> wrote 8192/8192 bytes at offset XXX
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 57344/57344 bytes at offset XXX
+56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io>
+== Verify image content ==
+qemu-io> read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 65536
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 73728
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 16384/16384 bytes at offset 81920
+16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 98304
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 106496
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 114688
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 122880
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 131072
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 163840
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 65536/65536 bytes at offset 172032
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 24576/24576 bytes at offset 237568
+24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 262144
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 294912
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 303104
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 65536/65536 bytes at offset 311296
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 16384/16384 bytes at offset 376832
+16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 24576/24576 bytes at offset 393216
+24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 417792
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 425984
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 57344/57344 bytes at offset 434176
+56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 24576/24576 bytes at offset 491520
+24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 516096
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 24576/24576 bytes at offset 524288
+24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 548864
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 557056
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 57344/57344 bytes at offset 565248
+56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 24576/24576 bytes at offset 622592
+24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 647168
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 24576/24576 bytes at offset 655360
+24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 679936
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 8192/8192 bytes at offset 688128
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 57344/57344 bytes at offset 696320
+56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 753664
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> No errors were found on the image.
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 74a1852..580a2ee 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -53,3 +53,4 @@
045 rw auto
044 rw auto
045 rw auto
+046 rw auto aio
--
1.7.6.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-12-06 13:33 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-06 13:32 [Qemu-devel] [PATCH 0/6] blkdebug/qcow2/qemu-iotests: Add some AIO testing Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 1/6] blkdebug: Allow usage without config file Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 2/6] blkdebug: Factor out remove_rule() Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 3/6] blkdebug: Implement suspend/resume of AIO requests Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 4/6] qemu-io: Add AIO debugging commands Kevin Wolf
2012-12-06 13:32 ` [Qemu-devel] [PATCH 5/6] qcow2: Move BLKDBG_EVENT out of the lock Kevin Wolf
2012-12-06 13:33 ` [Qemu-devel] [PATCH 6/6] qemu-iotests: Test concurrent cluster allocations Kevin Wolf
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).