1
The following changes since commit 22d96eac64877c4d96f9928babb6f2fcc68faacf:
1
The following changes since commit 281f327487c9c9b1599f93c589a408bbf4a651b8:
2
2
3
Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2019-04-29 19:11:15 +0100)
3
Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.12-pull-request' into staging (2017-12-22 00:11:36 +0000)
4
4
5
are available in the Git repository at:
5
are available in the git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 54277a2aab876aba7b55c7e88e2b372691849741:
9
for you to fetch changes up to 1a63a907507fbbcfaee3f622907ec244b7eabda8:
10
10
11
block/qed: add missed coroutine_fn markers (2019-04-30 15:29:00 +0200)
11
block: Keep nodes drained between reopen_queue/multiple (2017-12-22 15:05:32 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
16
- iotests: Fix output of qemu-io related tests
17
- Don't ignore bdrv_set_aio_context() for nodes with bs->drv = NUL
18
- vmdk: Set vmdk parent backing_format to vmdk
19
- qcow2: Preallocation fixes (especially for external data files)
20
- Add linear-buffer-based APIs (as wrappers around qiov-based ones)
21
- Various code cleanups and small corner case fixes
22
15
23
----------------------------------------------------------------
16
----------------------------------------------------------------
24
Alberto Garcia (3):
17
Doug Gale (1):
25
qcow2: Fix error handling in the compression code
18
nvme: Add tracing
26
commit: Make base read-only if there is an early failure
27
iotests: Check that images are in read-only mode after block-commit
28
19
29
Eric Blake (2):
20
Edgar Kaziakhmedov (1):
30
cutils: Fix size_to_str() on 32-bit platforms
21
qcow2: get rid of qcow2_backing_read1 routine
31
qemu-img: Saner printing of large file sizes
32
22
33
Kevin Wolf (5):
23
Fam Zheng (2):
34
block: Fix AioContext switch for bs->drv == NULL
24
block: Open backing image in force share mode for size probe
35
qcow2: Avoid COW during metadata preallocation
25
block: Remove unused bdrv_requests_pending
36
qcow2: Add errp to preallocate_co()
37
qcow2: Fix full preallocation with external data file
38
qcow2: Fix qcow2_make_empty() with external data file
39
26
40
Max Reitz (2):
27
John Snow (1):
41
iotests: Perform the correct test in 082
28
iotests: fix 197 for vpc
42
qemu-img: Make create hint at protocol options
43
29
44
Sam Eiderman (1):
30
Kevin Wolf (27):
45
vmdk: Set vmdk parent backing_format to vmdk
31
block: Formats don't need CONSISTENT_READ with NO_IO
32
block: Make bdrv_drain_invoke() recursive
33
block: Call .drain_begin only once in bdrv_drain_all_begin()
34
test-bdrv-drain: Test BlockDriver callbacks for drain
35
block: bdrv_drain_recurse(): Remove unused begin parameter
36
block: Don't wait for requests in bdrv_drain*_end()
37
block: Unify order in drain functions
38
block: Don't acquire AioContext in hmp_qemu_io()
39
block: Document that x-blockdev-change breaks quorum children list
40
block: Assert drain_all is only called from main AioContext
41
block: Make bdrv_drain() driver callbacks non-recursive
42
test-bdrv-drain: Test callback for bdrv_drain
43
test-bdrv-drain: Test bs->quiesce_counter
44
blockjob: Pause job on draining any job BDS
45
test-bdrv-drain: Test drain vs. block jobs
46
block: Don't block_job_pause_all() in bdrv_drain_all()
47
block: Nested drain_end must still call callbacks
48
test-bdrv-drain: Test nested drain sections
49
block: Don't notify parents in drain call chain
50
block: Add bdrv_subtree_drained_begin/end()
51
test-bdrv-drain: Tests for bdrv_subtree_drain
52
test-bdrv-drain: Test behaviour in coroutine context
53
test-bdrv-drain: Recursive draining with multiple parents
54
block: Allow graph changes in subtree drained section
55
test-bdrv-drain: Test graph changes in drained section
56
commit: Simplify reopen of base
57
block: Keep nodes drained between reopen_queue/multiple
46
58
47
Stefano Garzarella (2):
59
Thomas Huth (3):
48
block/vhdx: Remove redundant IEC binary prefixes definition
60
block: Remove the obsolete -drive boot=on|off parameter
49
block/vhdx: Use IEC binary prefixes for size constants
61
block: Remove the deprecated -hdachs option
62
block: Mention -drive cyls/heads/secs/trans/serial/addr in deprecation chapter
50
63
51
Thomas Huth (1):
64
qapi/block-core.json | 4 +
52
tests/qemu-iotests: Fix output of qemu-io related tests
65
block/qcow2.h | 3 -
66
include/block/block.h | 15 +-
67
include/block/block_int.h | 6 +-
68
block.c | 75 ++++-
69
block/commit.c | 8 +-
70
block/io.c | 164 +++++++---
71
block/qcow2.c | 51 +--
72
block/replication.c | 6 +
73
blockdev.c | 11 -
74
blockjob.c | 22 +-
75
hmp.c | 6 -
76
hw/block/nvme.c | 349 +++++++++++++++++----
77
qemu-io-cmds.c | 3 +
78
tests/test-bdrv-drain.c | 651 +++++++++++++++++++++++++++++++++++++++
79
vl.c | 86 +-----
80
hw/block/trace-events | 93 ++++++
81
qemu-doc.texi | 29 +-
82
qemu-options.hx | 19 +-
83
tests/Makefile.include | 2 +
84
tests/qemu-iotests/197 | 4 +
85
tests/qemu-iotests/common.filter | 3 +-
86
22 files changed, 1294 insertions(+), 316 deletions(-)
87
create mode 100644 tests/test-bdrv-drain.c
53
88
54
Vladimir Sementsov-Ogievskiy (10):
55
block: introduce byte-based io helpers
56
block/qcow2: use buffer-based io
57
block/qcow: use buffer-based io
58
block/qed: use buffer-based io
59
block/parallels: use buffer-based io
60
block/backup: use buffer-based io
61
block/commit: use buffer-based io
62
block/stream: use buffer-based io
63
qemu-img: use buffer-based io
64
block/qed: add missed coroutine_fn markers
65
66
Zhengui li (1):
67
vpc: unlock Coroutine lock to make IO submit Concurrently
68
69
block/qed.h | 28 ++++---
70
block/vhdx.h | 16 ++--
71
include/block/block_int.h | 16 ++++
72
include/sysemu/block-backend.h | 19 +++++
73
block.c | 12 +--
74
block/backup.c | 14 ++--
75
block/commit.c | 8 +-
76
block/parallels.c | 14 ++--
77
block/qapi.c | 49 +++---------
78
block/qcow.c | 19 ++---
79
block/qcow2.c | 80 ++++++++++----------
80
block/qed-check.c | 4 +-
81
block/qed-table.c | 45 ++++++-----
82
block/qed.c | 11 ++-
83
block/stream.c | 4 +-
84
block/vhdx-log.c | 2 +-
85
block/vhdx.c | 7 +-
86
block/vmdk.c | 2 +
87
block/vpc.c | 4 +
88
qemu-img.c | 26 ++++---
89
util/cutils.c | 2 +-
90
tests/qemu-iotests/026.out | 168 ++++++++++++++++++++---------------------
91
tests/qemu-iotests/043.out | 6 +-
92
tests/qemu-iotests/053.out | 2 +-
93
tests/qemu-iotests/059.out | 10 +--
94
tests/qemu-iotests/060.out | 16 ++--
95
tests/qemu-iotests/061.out | 12 +--
96
tests/qemu-iotests/069.out | 2 +-
97
tests/qemu-iotests/070.out | 4 +-
98
tests/qemu-iotests/075.out | 14 ++--
99
tests/qemu-iotests/076.out | 6 +-
100
tests/qemu-iotests/078.out | 12 +--
101
tests/qemu-iotests/080.out | 40 +++++-----
102
tests/qemu-iotests/081.out | 2 +-
103
tests/qemu-iotests/082 | 5 +-
104
tests/qemu-iotests/082.out | 51 ++++++++-----
105
tests/qemu-iotests/084.out | 8 +-
106
tests/qemu-iotests/088.out | 12 +--
107
tests/qemu-iotests/089.out | 2 +-
108
tests/qemu-iotests/095.out | 4 +-
109
tests/qemu-iotests/103.out | 14 ++--
110
tests/qemu-iotests/104.out | 6 +-
111
tests/qemu-iotests/110.out | 6 +-
112
tests/qemu-iotests/114.out | 4 +-
113
tests/qemu-iotests/116.out | 14 ++--
114
tests/qemu-iotests/126.out | 4 +-
115
tests/qemu-iotests/130.out | 10 +--
116
tests/qemu-iotests/131.out | 2 +-
117
tests/qemu-iotests/133.out | 30 ++++----
118
tests/qemu-iotests/137.out | 28 +++----
119
tests/qemu-iotests/140.out | 2 +-
120
tests/qemu-iotests/143.out | 2 +-
121
tests/qemu-iotests/153.out | 32 ++++----
122
tests/qemu-iotests/187.out | 6 +-
123
tests/qemu-iotests/188.out | 2 +-
124
tests/qemu-iotests/191.out | 8 +-
125
tests/qemu-iotests/195.out | 4 +-
126
tests/qemu-iotests/197.out | 2 +-
127
tests/qemu-iotests/198.out | 4 +-
128
tests/qemu-iotests/205 | 2 +-
129
tests/qemu-iotests/206.out | 10 +--
130
tests/qemu-iotests/207.out | 12 +--
131
tests/qemu-iotests/210.out | 8 +-
132
tests/qemu-iotests/211.out | 10 +--
133
tests/qemu-iotests/212.out | 10 +--
134
tests/qemu-iotests/213.out | 10 +--
135
tests/qemu-iotests/215.out | 2 +-
136
tests/qemu-iotests/226.out | 16 ++--
137
tests/qemu-iotests/233.out | 4 +-
138
tests/qemu-iotests/237.out | 22 +++---
139
tests/qemu-iotests/242.out | 10 +--
140
tests/qemu-iotests/244.out | 10 +--
141
tests/qemu-iotests/249 | 115 ++++++++++++++++++++++++++++
142
tests/qemu-iotests/249.out | 35 +++++++++
143
tests/qemu-iotests/group | 1 +
144
75 files changed, 696 insertions(+), 519 deletions(-)
145
create mode 100755 tests/qemu-iotests/249
146
create mode 100644 tests/qemu-iotests/249.out
147
diff view generated by jsdifflib
New patch
1
Commit 1f4ad7d fixed 'qemu-img info' for raw images that are currently
2
in use as a mirror target. It is not enough for image formats, though,
3
as these still unconditionally request BLK_PERM_CONSISTENT_READ.
1
4
5
As this permission is geared towards whether the guest-visible data is
6
consistent, and has no impact on whether the metadata is sane, and
7
'qemu-img info' does not read guest-visible data (except for the raw
8
format), it makes sense to not require BLK_PERM_CONSISTENT_READ if there
9
is not going to be any guest I/O performed, regardless of image format.
10
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block.c | 6 +++++-
14
1 file changed, 5 insertions(+), 1 deletion(-)
15
16
diff --git a/block.c b/block.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block.c
19
+++ b/block.c
20
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
21
assert(role == &child_backing || role == &child_file);
22
23
if (!backing) {
24
+ int flags = bdrv_reopen_get_flags(reopen_queue, bs);
25
+
26
/* Apart from the modifications below, the same permissions are
27
* forwarded and left alone as for filters */
28
bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
29
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
30
31
/* bs->file always needs to be consistent because of the metadata. We
32
* can never allow other users to resize or write to it. */
33
- perm |= BLK_PERM_CONSISTENT_READ;
34
+ if (!(flags & BDRV_O_NO_IO)) {
35
+ perm |= BLK_PERM_CONSISTENT_READ;
36
+ }
37
shared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
38
} else {
39
/* We want consistent read from backing files if the parent needs it.
40
--
41
2.13.6
42
43
diff view generated by jsdifflib
New patch
1
From: John Snow <jsnow@redhat.com>
1
2
3
VPC has some difficulty creating geometries of particular size.
4
However, we can indeed force it to use a literal one, so let's
5
do that for the sake of test 197, which is testing some specific
6
offsets.
7
8
Signed-off-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Lukáš Doktor <ldoktor@redhat.com>
13
---
14
tests/qemu-iotests/197 | 4 ++++
15
tests/qemu-iotests/common.filter | 3 ++-
16
2 files changed, 6 insertions(+), 1 deletion(-)
17
18
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/197
21
+++ b/tests/qemu-iotests/197
22
@@ -XXX,XX +XXX,XX @@ echo '=== Copy-on-read ==='
23
echo
24
25
# Prep the images
26
+# VPC rounds image sizes to a specific geometry, force a specific size.
27
+if [ "$IMGFMT" = "vpc" ]; then
28
+ IMGOPTS=$(_optstr_add "$IMGOPTS" "force_size")
29
+fi
30
_make_test_img 4G
31
$QEMU_IO -c "write -P 55 3G 1k" "$TEST_IMG" | _filter_qemu_io
32
IMGPROTO=file IMGFMT=qcow2 IMGOPTS= TEST_IMG_FILE="$TEST_WRAP" \
33
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
34
index XXXXXXX..XXXXXXX 100644
35
--- a/tests/qemu-iotests/common.filter
36
+++ b/tests/qemu-iotests/common.filter
37
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
38
-e "s# log_size=[0-9]\\+##g" \
39
-e "s# refcount_bits=[0-9]\\+##g" \
40
-e "s# key-secret=[a-zA-Z0-9]\\+##g" \
41
- -e "s# iter-time=[0-9]\\+##g"
42
+ -e "s# iter-time=[0-9]\\+##g" \
43
+ -e "s# force_size=\\(on\\|off\\)##g"
44
}
45
46
_filter_img_info()
47
--
48
2.13.6
49
50
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
This change separates bdrv_drain_invoke(), which calls the BlockDriver
2
drain callbacks, from bdrv_drain_recurse(). Instead, the function
3
performs its own recursion now.
2
4
3
Move to _co_ versions of io functions qed_read_table() and
5
One reason for this is that bdrv_drain_recurse() can be called multiple
4
qed_write_table(), as we use qemu_co_mutex_unlock()
6
times by bdrv_drain_all_begin(), but the callbacks may only be called
7
once. The separation is necessary to fix this bug.
8
9
The other reason is that we intend to go to a model where we call all
10
driver callbacks first, and only then start polling. This is not fully
11
achieved yet with this patch, as bdrv_drain_invoke() contains a
12
BDRV_POLL_WHILE() loop for the block driver callbacks, which can still
13
call callbacks for any unrelated event. It's a step in this direction
5
anyway.
14
anyway.
6
15
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
Cc: qemu-stable@nongnu.org
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
19
---
12
block/qed-table.c | 12 +++++-------
20
block/io.c | 14 +++++++++++---
13
block/qed.c | 6 ++----
21
1 file changed, 11 insertions(+), 3 deletions(-)
14
2 files changed, 7 insertions(+), 11 deletions(-)
15
22
16
diff --git a/block/qed-table.c b/block/qed-table.c
23
diff --git a/block/io.c b/block/io.c
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qed-table.c
25
--- a/block/io.c
19
+++ b/block/qed-table.c
26
+++ b/block/io.c
20
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
21
/* Called with table_lock held. */
28
bdrv_wakeup(bs);
22
static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
29
}
30
31
+/* Recursively call BlockDriver.bdrv_co_drain_begin/end callbacks */
32
static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
23
{
33
{
24
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(
34
+ BdrvChild *child, *tmp;
25
- qiov, table->offsets, s->header.cluster_size * s->header.table_size);
35
BdrvCoDrainData data = { .bs = bs, .done = false, .begin = begin};
26
+ unsigned int bytes = s->header.cluster_size * s->header.table_size;
36
37
if (!bs->drv || (begin && !bs->drv->bdrv_co_drain_begin) ||
38
@@ -XXX,XX +XXX,XX @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
39
data.co = qemu_coroutine_create(bdrv_drain_invoke_entry, &data);
40
bdrv_coroutine_enter(bs, data.co);
41
BDRV_POLL_WHILE(bs, !data.done);
27
+
42
+
28
int noffsets;
43
+ QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
29
int i, ret;
44
+ bdrv_drain_invoke(child->bs, begin);
30
45
+ }
31
trace_qed_read_table(s, offset, table);
46
}
32
47
33
qemu_co_mutex_unlock(&s->table_lock);
48
static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
34
- ret = bdrv_preadv(s->bs->file, offset, &qiov);
49
@@ -XXX,XX +XXX,XX @@ static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
35
+ ret = bdrv_co_pread(s->bs->file, offset, bytes, table->offsets, 0);
50
BdrvChild *child, *tmp;
36
qemu_co_mutex_lock(&s->table_lock);
51
bool waited;
37
if (ret < 0) {
52
38
goto out;
53
- /* Ensure any pending metadata writes are submitted to bs->file. */
54
- bdrv_drain_invoke(bs, begin);
55
-
56
/* Wait for drained requests to finish */
57
waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
58
59
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_begin(BlockDriverState *bs)
60
bdrv_parent_drained_begin(bs);
39
}
61
}
40
62
41
/* Byteswap offsets */
63
+ bdrv_drain_invoke(bs, true);
42
- noffsets = qiov.size / sizeof(uint64_t);
64
bdrv_drain_recurse(bs, true);
43
+ noffsets = bytes / sizeof(uint64_t);
65
}
44
for (i = 0; i < noffsets; i++) {
66
45
table->offsets[i] = le64_to_cpu(table->offsets[i]);
67
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_end(BlockDriverState *bs)
46
}
68
}
47
@@ -XXX,XX +XXX,XX @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
69
48
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
70
bdrv_parent_drained_end(bs);
49
unsigned int start, end, i;
71
+ bdrv_drain_invoke(bs, false);
50
QEDTable *new_table;
72
bdrv_drain_recurse(bs, false);
51
- QEMUIOVector qiov;
73
aio_enable_external(bdrv_get_aio_context(bs));
52
size_t len_bytes;
74
}
53
int ret;
75
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
54
76
aio_context_acquire(aio_context);
55
@@ -XXX,XX +XXX,XX @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
77
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
56
len_bytes = (end - start) * sizeof(uint64_t);
78
if (aio_context == bdrv_get_aio_context(bs)) {
57
79
+ /* FIXME Calling this multiple times is wrong */
58
new_table = qemu_blockalign(s->bs, len_bytes);
80
+ bdrv_drain_invoke(bs, true);
59
- qemu_iovec_init_buf(&qiov, new_table->offsets, len_bytes);
81
waited |= bdrv_drain_recurse(bs, true);
60
82
}
61
/* Byteswap table */
83
}
62
for (i = start; i < end; i++) {
84
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
63
@@ -XXX,XX +XXX,XX @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
85
aio_context_acquire(aio_context);
64
offset += start * sizeof(uint64_t);
86
aio_enable_external(aio_context);
65
87
bdrv_parent_drained_end(bs);
66
qemu_co_mutex_unlock(&s->table_lock);
88
+ bdrv_drain_invoke(bs, false);
67
- ret = bdrv_pwritev(s->bs->file, offset, &qiov);
89
bdrv_drain_recurse(bs, false);
68
+ ret = bdrv_co_pwrite(s->bs->file, offset, len_bytes, new_table->offsets, 0);
90
aio_context_release(aio_context);
69
qemu_co_mutex_lock(&s->table_lock);
70
trace_qed_write_table_cb(s, table, flush, ret);
71
if (ret < 0) {
72
diff --git a/block/qed.c b/block/qed.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/block/qed.c
75
+++ b/block/qed.c
76
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
77
int nsectors = DIV_ROUND_UP(sizeof(QEDHeader), BDRV_SECTOR_SIZE);
78
size_t len = nsectors * BDRV_SECTOR_SIZE;
79
uint8_t *buf;
80
- QEMUIOVector qiov;
81
int ret;
82
83
assert(s->allocating_acb || s->allocating_write_reqs_plugged);
84
85
buf = qemu_blockalign(s->bs, len);
86
- qemu_iovec_init_buf(&qiov, buf, len);
87
88
- ret = bdrv_co_preadv(s->bs->file, 0, qiov.size, &qiov, 0);
89
+ ret = bdrv_co_pread(s->bs->file, 0, len, buf, 0);
90
if (ret < 0) {
91
goto out;
92
}
93
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
94
/* Update header */
95
qed_header_cpu_to_le(&s->header, (QEDHeader *) buf);
96
97
- ret = bdrv_co_pwritev(s->bs->file, 0, qiov.size, &qiov, 0);
98
+ ret = bdrv_co_pwrite(s->bs->file, 0, len, buf, 0);
99
if (ret < 0) {
100
goto out;
101
}
91
}
102
--
92
--
103
2.20.1
93
2.13.6
104
94
105
95
diff view generated by jsdifflib
1
Limiting the allocation to INT_MAX bytes isn't particularly clever
1
bdrv_drain_all_begin() used to call the .bdrv_co_drain_begin() driver
2
because it means that the final cluster will be a partial cluster which
2
callback inside its polling loop. This means that how many times it got
3
will be completed through a COW operation. This results in unnecessary
3
called for each node depended on long it had to poll the event loop.
4
data read and write requests which lead to an unwanted non-sparse
5
filesystem block for metadata preallocation.
6
4
7
Align the maximum allocation size down to the cluster size to avoid this
5
This is obviously not right and results in nodes that stay drained even
8
situation.
6
after bdrv_drain_all_end(), which calls .bdrv_co_drain_begin() once per
7
node.
8
9
Fix bdrv_drain_all_begin() to call the callback only once, too.
9
10
10
Cc: qemu-stable@nongnu.org
11
Cc: qemu-stable@nongnu.org
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
---
14
block/qcow2.c | 2 +-
15
block/io.c | 3 +--
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 2 deletions(-)
16
17
17
diff --git a/block/qcow2.c b/block/qcow2.c
18
diff --git a/block/io.c b/block/io.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.c
20
--- a/block/io.c
20
+++ b/block/qcow2.c
21
+++ b/block/io.c
21
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
22
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
22
bytes = new_length - offset;
23
aio_context_acquire(aio_context);
23
24
bdrv_parent_drained_begin(bs);
24
while (bytes) {
25
aio_disable_external(aio_context);
25
- cur_bytes = MIN(bytes, INT_MAX);
26
+ bdrv_drain_invoke(bs, true);
26
+ cur_bytes = MIN(bytes, QEMU_ALIGN_DOWN(INT_MAX, s->cluster_size));
27
aio_context_release(aio_context);
27
ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
28
28
&host_offset, &meta);
29
if (!g_slist_find(aio_ctxs, aio_context)) {
29
if (ret < 0) {
30
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
31
aio_context_acquire(aio_context);
32
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
33
if (aio_context == bdrv_get_aio_context(bs)) {
34
- /* FIXME Calling this multiple times is wrong */
35
- bdrv_drain_invoke(bs, true);
36
waited |= bdrv_drain_recurse(bs, true);
37
}
38
}
30
--
39
--
31
2.20.1
40
2.13.6
32
41
33
42
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
This adds a test case that the BlockDriver callbacks for drain are
2
called in bdrv_drained_all_begin/end(), and that both of them are called
3
exactly once.
2
4
3
This tests the fix from the previous patch.
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
---
9
tests/test-bdrv-drain.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++
10
tests/Makefile.include | 2 +
11
2 files changed, 139 insertions(+)
12
create mode 100644 tests/test-bdrv-drain.c
4
13
5
Signed-off-by: Alberto Garcia <berto@igalia.com>
14
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
tests/qemu-iotests/249 | 115 +++++++++++++++++++++++++++++++++++++
9
tests/qemu-iotests/249.out | 35 +++++++++++
10
tests/qemu-iotests/group | 1 +
11
3 files changed, 151 insertions(+)
12
create mode 100755 tests/qemu-iotests/249
13
create mode 100644 tests/qemu-iotests/249.out
14
15
diff --git a/tests/qemu-iotests/249 b/tests/qemu-iotests/249
16
new file mode 100755
17
index XXXXXXX..XXXXXXX
18
--- /dev/null
19
+++ b/tests/qemu-iotests/249
20
@@ -XXX,XX +XXX,XX @@
21
+#!/usr/bin/env bash
22
+#
23
+# Test that a backing image is put back in read-only mode after
24
+# block-commit (both when it fails and when it succeeds).
25
+#
26
+# Copyright (C) 2019 Igalia, S.L.
27
+#
28
+# This program is free software; you can redistribute it and/or modify
29
+# it under the terms of the GNU General Public License as published by
30
+# the Free Software Foundation; either version 2 of the License, or
31
+# (at your option) any later version.
32
+#
33
+# This program is distributed in the hope that it will be useful,
34
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36
+# GNU General Public License for more details.
37
+#
38
+# You should have received a copy of the GNU General Public License
39
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
40
+#
41
+
42
+# creator
43
+owner=berto@igalia.com
44
+
45
+seq="$(basename $0)"
46
+echo "QA output created by $seq"
47
+
48
+status=1    # failure is the default!
49
+
50
+_cleanup()
51
+{
52
+ _cleanup_test_img
53
+ rm -f "$TEST_IMG.base"
54
+ rm -f "$TEST_IMG.int"
55
+}
56
+trap "_cleanup; exit \$status" 0 1 2 3 15
57
+
58
+# get standard environment, filters and checks
59
+. ./common.rc
60
+. ./common.filter
61
+. ./common.qemu
62
+
63
+# Any format implementing BlockDriver.bdrv_change_backing_file
64
+_supported_fmt qcow2 qed
65
+_supported_proto file
66
+_supported_os Linux
67
+
68
+IMG_SIZE=1M
69
+
70
+# Create the images: base <- int <- active
71
+TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt
72
+TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" | _filter_imgfmt
73
+_make_test_img -b "$TEST_IMG.int" | _filter_imgfmt
74
+
75
+# Launch QEMU with these two drives:
76
+# none0: base (read-only)
77
+# none1: base <- int <- active
78
+_launch_qemu -drive if=none,file="${TEST_IMG}.base",node-name=base,read-only=on \
79
+ -drive if=none,file="${TEST_IMG}",backing.node-name=int,backing.backing=base
80
+
81
+_send_qemu_cmd $QEMU_HANDLE \
82
+ "{ 'execute': 'qmp_capabilities' }" \
83
+ 'return'
84
+
85
+echo
86
+echo '=== Send a write command to a drive opened in read-only mode (1)'
87
+echo
88
+_send_qemu_cmd $QEMU_HANDLE \
89
+ "{ 'execute': 'human-monitor-command',
90
+ 'arguments': {'command-line': 'qemu-io none0 \"aio_write 0 2k\"'}}" \
91
+ 'return'
92
+
93
+echo
94
+echo '=== Run block-commit on base using an invalid filter node name'
95
+echo
96
+_send_qemu_cmd $QEMU_HANDLE \
97
+ "{ 'execute': 'block-commit',
98
+ 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int',
99
+ 'filter-node-name': '1234'}}" \
100
+ 'error'
101
+
102
+echo
103
+echo '=== Send a write command to a drive opened in read-only mode (2)'
104
+echo
105
+_send_qemu_cmd $QEMU_HANDLE \
106
+ "{ 'execute': 'human-monitor-command',
107
+ 'arguments': {'command-line': 'qemu-io none0 \"aio_write 0 2k\"'}}" \
108
+ 'return'
109
+
110
+echo
111
+echo '=== Run block-commit on base using the default filter node name'
112
+echo
113
+_send_qemu_cmd $QEMU_HANDLE \
114
+ "{ 'execute': 'block-commit',
115
+ 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}}" \
116
+ 'return'
117
+
118
+# Wait for block-commit to finish
119
+_send_qemu_cmd $QEMU_HANDLE '' \
120
+ '"status": "null"'
121
+
122
+echo
123
+echo '=== Send a write command to a drive opened in read-only mode (3)'
124
+echo
125
+_send_qemu_cmd $QEMU_HANDLE \
126
+ "{ 'execute': 'human-monitor-command',
127
+ 'arguments': {'command-line': 'qemu-io none0 \"aio_write 0 2k\"'}}" \
128
+ 'return'
129
+
130
+_cleanup_qemu
131
+
132
+# success, all done
133
+echo "*** done"
134
+rm -f $seq.full
135
+status=0
136
diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
137
new file mode 100644
15
new file mode 100644
138
index XXXXXXX..XXXXXXX
16
index XXXXXXX..XXXXXXX
139
--- /dev/null
17
--- /dev/null
140
+++ b/tests/qemu-iotests/249.out
18
+++ b/tests/test-bdrv-drain.c
141
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
142
+QA output created by 249
20
+/*
143
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576
21
+ * Block node draining tests
144
+Formatting 'TEST_DIR/t.IMGFMT.int', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base
22
+ *
145
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.int
23
+ * Copyright (c) 2017 Kevin Wolf <kwolf@redhat.com>
146
+{"return": {}}
24
+ *
25
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
26
+ * of this software and associated documentation files (the "Software"), to deal
27
+ * in the Software without restriction, including without limitation the rights
28
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29
+ * copies of the Software, and to permit persons to whom the Software is
30
+ * furnished to do so, subject to the following conditions:
31
+ *
32
+ * The above copyright notice and this permission notice shall be included in
33
+ * all copies or substantial portions of the Software.
34
+ *
35
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
38
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41
+ * THE SOFTWARE.
42
+ */
147
+
43
+
148
+=== Send a write command to a drive opened in read-only mode (1)
44
+#include "qemu/osdep.h"
45
+#include "block/block.h"
46
+#include "sysemu/block-backend.h"
47
+#include "qapi/error.h"
149
+
48
+
150
+{"return": "Block node is read-onlyrn"}
49
+typedef struct BDRVTestState {
50
+ int drain_count;
51
+} BDRVTestState;
151
+
52
+
152
+=== Run block-commit on base using an invalid filter node name
53
+static void coroutine_fn bdrv_test_co_drain_begin(BlockDriverState *bs)
54
+{
55
+ BDRVTestState *s = bs->opaque;
56
+ s->drain_count++;
57
+}
153
+
58
+
154
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
59
+static void coroutine_fn bdrv_test_co_drain_end(BlockDriverState *bs)
155
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
60
+{
156
+{"error": {"class": "GenericError", "desc": "Invalid node name"}}
61
+ BDRVTestState *s = bs->opaque;
62
+ s->drain_count--;
63
+}
157
+
64
+
158
+=== Send a write command to a drive opened in read-only mode (2)
65
+static void bdrv_test_close(BlockDriverState *bs)
66
+{
67
+ BDRVTestState *s = bs->opaque;
68
+ g_assert_cmpint(s->drain_count, >, 0);
69
+}
159
+
70
+
160
+{"return": "Block node is read-onlyrn"}
71
+static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs,
72
+ uint64_t offset, uint64_t bytes,
73
+ QEMUIOVector *qiov, int flags)
74
+{
75
+ /* We want this request to stay until the polling loop in drain waits for
76
+ * it to complete. We need to sleep a while as bdrv_drain_invoke() comes
77
+ * first and polls its result, too, but it shouldn't accidentally complete
78
+ * this request yet. */
79
+ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000);
161
+
80
+
162
+=== Run block-commit on base using the default filter node name
81
+ return 0;
82
+}
163
+
83
+
164
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
84
+static BlockDriver bdrv_test = {
165
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
85
+ .format_name = "test",
166
+{"return": {}}
86
+ .instance_size = sizeof(BDRVTestState),
167
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
168
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
169
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
170
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
171
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
172
+
87
+
173
+=== Send a write command to a drive opened in read-only mode (3)
88
+ .bdrv_close = bdrv_test_close,
89
+ .bdrv_co_preadv = bdrv_test_co_preadv,
174
+
90
+
175
+{"return": "Block node is read-onlyrn"}
91
+ .bdrv_co_drain_begin = bdrv_test_co_drain_begin,
176
+*** done
92
+ .bdrv_co_drain_end = bdrv_test_co_drain_end,
177
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
93
+};
94
+
95
+static void aio_ret_cb(void *opaque, int ret)
96
+{
97
+ int *aio_ret = opaque;
98
+ *aio_ret = ret;
99
+}
100
+
101
+static void test_drv_cb_drain_all(void)
102
+{
103
+ BlockBackend *blk;
104
+ BlockDriverState *bs;
105
+ BDRVTestState *s;
106
+ BlockAIOCB *acb;
107
+ int aio_ret;
108
+
109
+ QEMUIOVector qiov;
110
+ struct iovec iov = {
111
+ .iov_base = NULL,
112
+ .iov_len = 0,
113
+ };
114
+ qemu_iovec_init_external(&qiov, &iov, 1);
115
+
116
+ blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
117
+ bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
118
+ &error_abort);
119
+ s = bs->opaque;
120
+ blk_insert_bs(blk, bs, &error_abort);
121
+
122
+ /* Simple bdrv_drain_all_begin/end pair, check that CBs are called */
123
+ g_assert_cmpint(s->drain_count, ==, 0);
124
+ bdrv_drain_all_begin();
125
+ g_assert_cmpint(s->drain_count, ==, 1);
126
+ bdrv_drain_all_end();
127
+ g_assert_cmpint(s->drain_count, ==, 0);
128
+
129
+ /* Now do the same while a request is pending */
130
+ aio_ret = -EINPROGRESS;
131
+ acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret);
132
+ g_assert(acb != NULL);
133
+ g_assert_cmpint(aio_ret, ==, -EINPROGRESS);
134
+
135
+ g_assert_cmpint(s->drain_count, ==, 0);
136
+ bdrv_drain_all_begin();
137
+ g_assert_cmpint(aio_ret, ==, 0);
138
+ g_assert_cmpint(s->drain_count, ==, 1);
139
+ bdrv_drain_all_end();
140
+ g_assert_cmpint(s->drain_count, ==, 0);
141
+
142
+ bdrv_unref(bs);
143
+ blk_unref(blk);
144
+}
145
+
146
+int main(int argc, char **argv)
147
+{
148
+ bdrv_init();
149
+ qemu_init_main_loop(&error_abort);
150
+
151
+ g_test_init(&argc, &argv, NULL);
152
+
153
+ g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all);
154
+
155
+ return g_test_run();
156
+}
157
diff --git a/tests/Makefile.include b/tests/Makefile.include
178
index XXXXXXX..XXXXXXX 100644
158
index XXXXXXX..XXXXXXX 100644
179
--- a/tests/qemu-iotests/group
159
--- a/tests/Makefile.include
180
+++ b/tests/qemu-iotests/group
160
+++ b/tests/Makefile.include
181
@@ -XXX,XX +XXX,XX @@
161
@@ -XXX,XX +XXX,XX @@ gcov-files-test-thread-pool-y = thread-pool.c
182
246 rw auto quick
162
gcov-files-test-hbitmap-y = util/hbitmap.c
183
247 rw auto quick
163
check-unit-y += tests/test-hbitmap$(EXESUF)
184
248 rw auto quick
164
gcov-files-test-hbitmap-y = blockjob.c
185
+249 rw auto quick
165
+check-unit-y += tests/test-bdrv-drain$(EXESUF)
166
check-unit-y += tests/test-blockjob$(EXESUF)
167
check-unit-y += tests/test-blockjob-txn$(EXESUF)
168
check-unit-y += tests/test-x86-cpuid$(EXESUF)
169
@@ -XXX,XX +XXX,XX @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
170
tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y)
171
tests/test-aio-multithread$(EXESUF): tests/test-aio-multithread.o $(test-block-obj-y)
172
tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y)
173
+tests/test-bdrv-drain$(EXESUF): tests/test-bdrv-drain.o $(test-block-obj-y) $(test-util-obj-y)
174
tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
175
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
176
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
186
--
177
--
187
2.20.1
178
2.13.6
188
179
189
180
diff view generated by jsdifflib
New patch
1
Now that the bdrv_drain_invoke() calls are pulled up to the callers of
2
bdrv_drain_recurse(), the 'begin' parameter isn't needed any more.
1
3
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
block/io.c | 12 ++++++------
8
1 file changed, 6 insertions(+), 6 deletions(-)
9
10
diff --git a/block/io.c b/block/io.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/block/io.c
13
+++ b/block/io.c
14
@@ -XXX,XX +XXX,XX @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
15
}
16
}
17
18
-static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
19
+static bool bdrv_drain_recurse(BlockDriverState *bs)
20
{
21
BdrvChild *child, *tmp;
22
bool waited;
23
@@ -XXX,XX +XXX,XX @@ static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
24
*/
25
bdrv_ref(bs);
26
}
27
- waited |= bdrv_drain_recurse(bs, begin);
28
+ waited |= bdrv_drain_recurse(bs);
29
if (in_main_loop) {
30
bdrv_unref(bs);
31
}
32
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_begin(BlockDriverState *bs)
33
}
34
35
bdrv_drain_invoke(bs, true);
36
- bdrv_drain_recurse(bs, true);
37
+ bdrv_drain_recurse(bs);
38
}
39
40
void bdrv_drained_end(BlockDriverState *bs)
41
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_end(BlockDriverState *bs)
42
43
bdrv_parent_drained_end(bs);
44
bdrv_drain_invoke(bs, false);
45
- bdrv_drain_recurse(bs, false);
46
+ bdrv_drain_recurse(bs);
47
aio_enable_external(bdrv_get_aio_context(bs));
48
}
49
50
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
51
aio_context_acquire(aio_context);
52
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
53
if (aio_context == bdrv_get_aio_context(bs)) {
54
- waited |= bdrv_drain_recurse(bs, true);
55
+ waited |= bdrv_drain_recurse(bs);
56
}
57
}
58
aio_context_release(aio_context);
59
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
60
aio_enable_external(aio_context);
61
bdrv_parent_drained_end(bs);
62
bdrv_drain_invoke(bs, false);
63
- bdrv_drain_recurse(bs, false);
64
+ bdrv_drain_recurse(bs);
65
aio_context_release(aio_context);
66
}
67
68
--
69
2.13.6
70
71
diff view generated by jsdifflib
1
make_completely_empty() is an optimisated path for bdrv_make_empty()
1
The device is drained, so there is no point in waiting for requests at
2
where completely new metadata is created inside the image file instead
2
the end of the drained section. Remove the bdrv_drain_recurse() calls
3
of going through all clusters and discarding them. For an external data
3
there.
4
file, however, we actually need to do discard operations on the data
5
file; just overwriting the qcow2 file doesn't get rid of the data.
6
4
7
The necessary slow path with an explicit discard operation already
5
The bdrv_drain_recurse() calls were introduced in commit 481cad48e5e
8
exists for other cases. Use it for external data files, too.
6
in order to call the .bdrv_co_drain_end() driver callback. This is now
7
done by a separate bdrv_drain_invoke() call.
9
8
10
Cc: qemu-stable@nongnu.org
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
12
---
14
block/qcow2.c | 7 +++++--
13
block/io.c | 2 --
15
1 file changed, 5 insertions(+), 2 deletions(-)
14
1 file changed, 2 deletions(-)
16
15
17
diff --git a/block/qcow2.c b/block/qcow2.c
16
diff --git a/block/io.c b/block/io.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.c
18
--- a/block/io.c
20
+++ b/block/qcow2.c
19
+++ b/block/io.c
21
@@ -XXX,XX +XXX,XX @@ static int qcow2_make_empty(BlockDriverState *bs)
20
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_end(BlockDriverState *bs)
22
21
23
if (s->qcow_version >= 3 && !s->snapshots && !s->nb_bitmaps &&
22
bdrv_parent_drained_end(bs);
24
3 + l1_clusters <= s->refcount_block_size &&
23
bdrv_drain_invoke(bs, false);
25
- s->crypt_method_header != QCOW_CRYPT_LUKS) {
24
- bdrv_drain_recurse(bs);
26
+ s->crypt_method_header != QCOW_CRYPT_LUKS &&
25
aio_enable_external(bdrv_get_aio_context(bs));
27
+ !has_data_file(bs)) {
26
}
28
/* The following function only works for qcow2 v3 images (it
27
29
* requires the dirty flag) and only as long as there are no
28
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
30
* features that reserve extra clusters (such as snapshots,
29
aio_enable_external(aio_context);
31
* LUKS header, or persistent bitmaps), because it completely
30
bdrv_parent_drained_end(bs);
32
* empties the image. Furthermore, the L1 table and three
31
bdrv_drain_invoke(bs, false);
33
* additional clusters (image header, refcount table, one
32
- bdrv_drain_recurse(bs);
34
- * refcount block) have to fit inside one refcount block. */
33
aio_context_release(aio_context);
35
+ * refcount block) have to fit inside one refcount block. It
36
+ * only resets the image file, i.e. does not work with an
37
+ * external data file. */
38
return make_completely_empty(bs);
39
}
34
}
40
35
41
--
36
--
42
2.20.1
37
2.13.6
43
38
44
39
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
Drain requests are propagated to child nodes, parent nodes and directly
2
to the AioContext. The order in which this happened was different
3
between all combinations of drain/drain_all and begin/end.
2
4
3
This patch fixes a few things in the way error codes are handled in
5
The correct order is to keep children only drained when their parents
4
the qcow2 compression code:
6
are also drained. This means that at the start of a drained section, the
7
AioContext needs to be drained first, the parents second and only then
8
the children. The correct order for the end of a drained section is the
9
opposite.
5
10
6
a) qcow2_co_pwritev_compressed() expects qcow2_co_compress() to only
11
This patch changes the three other functions to follow the example of
7
return -1 or -2 on failure, but this is not correct. Since the
12
bdrv_drained_begin(), which is the only one that got it right.
8
change from qcow2_compress() to qcow2_co_compress() in commit
9
ceb029cd6feccf9f7607 the new code can also return -EINVAL (although
10
there does not seem to exist any code path that would cause that
11
error in the current implementation).
12
13
13
b) -1 and -2 are ad-hoc error codes defined in qcow2_compress().
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
This patch replaces them with standard constants from errno.h.
15
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
16
---
17
block/io.c | 12 ++++++++----
18
1 file changed, 8 insertions(+), 4 deletions(-)
15
19
16
c) Both qcow2_compress() and qcow2_co_do_compress() return a negative
20
diff --git a/block/io.c b/block/io.c
17
value on failure, but qcow2_co_pwritev_compressed() stores the
18
value in an unsigned data type.
19
20
Signed-off-by: Alberto Garcia <berto@igalia.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
23
block/qcow2.c | 18 +++++++++---------
24
1 file changed, 9 insertions(+), 9 deletions(-)
25
26
diff --git a/block/qcow2.c b/block/qcow2.c
27
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
28
--- a/block/qcow2.c
22
--- a/block/io.c
29
+++ b/block/qcow2.c
23
+++ b/block/io.c
30
@@ -XXX,XX +XXX,XX @@ fail:
24
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_begin(BlockDriverState *bs)
31
* @src - source buffer, @src_size bytes
25
return;
32
*
33
* Returns: compressed size on success
34
- * -1 destination buffer is not enough to store compressed data
35
- * -2 on any other error
36
+ * -ENOMEM destination buffer is not enough to store compressed data
37
+ * -EIO on any other error
38
*/
39
static ssize_t qcow2_compress(void *dest, size_t dest_size,
40
const void *src, size_t src_size)
41
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
42
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
43
-12, 9, Z_DEFAULT_STRATEGY);
44
if (ret != Z_OK) {
45
- return -2;
46
+ return -EIO;
47
}
26
}
48
27
49
/* strm.next_in is not const in old zlib versions, such as those used on
28
+ /* Stop things in parent-to-child order */
50
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
29
if (atomic_fetch_inc(&bs->quiesce_counter) == 0) {
51
if (ret == Z_STREAM_END) {
30
aio_disable_external(bdrv_get_aio_context(bs));
52
ret = dest_size - strm.avail_out;
31
bdrv_parent_drained_begin(bs);
53
} else {
32
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_end(BlockDriverState *bs)
54
- ret = (ret == Z_OK ? -1 : -2);
33
return;
55
+ ret = (ret == Z_OK ? -ENOMEM : -EIO);
56
}
34
}
57
35
58
deflateEnd(&strm);
36
- bdrv_parent_drained_end(bs);
59
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
37
+ /* Re-enable things in child-to-parent order */
60
BDRVQcow2State *s = bs->opaque;
38
bdrv_drain_invoke(bs, false);
61
QEMUIOVector hd_qiov;
39
+ bdrv_parent_drained_end(bs);
62
int ret;
40
aio_enable_external(bdrv_get_aio_context(bs));
63
- size_t out_len;
41
}
64
+ ssize_t out_len;
42
65
uint8_t *buf, *out_buf;
43
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
66
uint64_t cluster_offset;
44
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
67
45
AioContext *aio_context = bdrv_get_aio_context(bs);
68
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
46
69
47
+ /* Stop things in parent-to-child order */
70
out_len = qcow2_co_compress(bs, out_buf, s->cluster_size - 1,
48
aio_context_acquire(aio_context);
71
buf, s->cluster_size);
49
- bdrv_parent_drained_begin(bs);
72
- if (out_len == -2) {
50
aio_disable_external(aio_context);
73
- ret = -EINVAL;
51
+ bdrv_parent_drained_begin(bs);
74
- goto fail;
52
bdrv_drain_invoke(bs, true);
75
- } else if (out_len == -1) {
53
aio_context_release(aio_context);
76
+ if (out_len == -ENOMEM) {
54
77
/* could not compress: write normal cluster */
55
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
78
ret = qcow2_co_pwritev(bs, offset, bytes, qiov, 0);
56
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
79
if (ret < 0) {
57
AioContext *aio_context = bdrv_get_aio_context(bs);
80
goto fail;
58
81
}
59
+ /* Re-enable things in child-to-parent order */
82
goto success;
60
aio_context_acquire(aio_context);
83
+ } else if (out_len < 0) {
61
- aio_enable_external(aio_context);
84
+ ret = -EINVAL;
62
- bdrv_parent_drained_end(bs);
85
+ goto fail;
63
bdrv_drain_invoke(bs, false);
64
+ bdrv_parent_drained_end(bs);
65
+ aio_enable_external(aio_context);
66
aio_context_release(aio_context);
86
}
67
}
87
68
88
qemu_co_mutex_lock(&s->lock);
89
--
69
--
90
2.20.1
70
2.13.6
91
71
92
72
diff view generated by jsdifflib
1
We'll add a bdrv_co_truncate() call in the next patch which can return
1
Commit 15afd94a047 added code to acquire and release the AioContext in
2
an Error that we don't want to discard. So add an errp parameter to
2
qemuio_command(). This means that the lock is taken twice now in the
3
preallocate_co().
3
call path from hmp_qemu_io(). This causes BDRV_POLL_WHILE() to hang for
4
any requests issued to nodes in a non-mainloop AioContext.
4
5
5
Cc: qemu-stable@nongnu.org
6
Dropping the first locking from hmp_qemu_io() fixes the problem.
7
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
10
---
9
block/qcow2.c | 11 ++++++-----
11
hmp.c | 6 ------
10
1 file changed, 6 insertions(+), 5 deletions(-)
12
1 file changed, 6 deletions(-)
11
13
12
diff --git a/block/qcow2.c b/block/qcow2.c
14
diff --git a/hmp.c b/hmp.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/block/qcow2.c
16
--- a/hmp.c
15
+++ b/block/qcow2.c
17
+++ b/hmp.c
16
@@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
18
@@ -XXX,XX +XXX,XX @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
17
* Returns: 0 on success, -errno on failure.
18
*/
19
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
20
- uint64_t new_length)
21
+ uint64_t new_length, Error **errp)
22
{
19
{
23
BDRVQcow2State *s = bs->opaque;
20
BlockBackend *blk;
24
uint64_t bytes;
21
BlockBackend *local_blk = NULL;
25
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
22
- AioContext *aio_context;
26
ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
23
const char* device = qdict_get_str(qdict, "device");
27
&host_offset, &meta);
24
const char* command = qdict_get_str(qdict, "command");
28
if (ret < 0) {
25
Error *err = NULL;
29
+ error_setg_errno(errp, -ret, "Allocating clusters failed");
26
@@ -XXX,XX +XXX,XX @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
30
return ret;
31
}
32
33
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
34
35
ret = qcow2_alloc_cluster_link_l2(bs, meta);
36
if (ret < 0) {
37
+ error_setg_errno(errp, -ret, "Mapping clusters failed");
38
qcow2_free_any_clusters(bs, meta->alloc_offset,
39
meta->nb_clusters, QCOW2_DISCARD_NEVER);
40
return ret;
41
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
42
ret = bdrv_pwrite(s->data_file, (host_offset + cur_bytes) - 1,
43
&data, 1);
44
if (ret < 0) {
45
+ error_setg_errno(errp, -ret, "Writing to EOF failed");
46
return ret;
47
}
27
}
48
}
28
}
49
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
29
50
break;
30
- aio_context = blk_get_aio_context(blk);
51
31
- aio_context_acquire(aio_context);
52
case PREALLOC_MODE_METADATA:
32
-
53
- ret = preallocate_co(bs, old_length, offset);
33
/*
54
+ ret = preallocate_co(bs, old_length, offset, errp);
34
* Notably absent: Proper permission management. This is sad, but it seems
55
if (ret < 0) {
35
* almost impossible to achieve without changing the semantics and thereby
56
- error_setg_errno(errp, -ret, "Preallocation failed");
36
@@ -XXX,XX +XXX,XX @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
57
goto fail;
37
*/
58
}
38
qemuio_command(blk, command);
59
break;
39
60
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
40
- aio_context_release(aio_context);
61
/* With a data file, preallocation means just allocating the metadata
41
-
62
* and forwarding the truncate request to the data file */
42
fail:
63
if (has_data_file(bs)) {
43
blk_unref(local_blk);
64
- ret = preallocate_co(bs, old_length, offset);
44
hmp_handle_error(mon, &err);
65
+ ret = preallocate_co(bs, old_length, offset, errp);
66
if (ret < 0) {
67
- error_setg_errno(errp, -ret, "Preallocation failed");
68
goto fail;
69
}
70
break;
71
--
45
--
72
2.20.1
46
2.13.6
73
47
74
48
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Edgar Kaziakhmedov <edgar.kaziakhmedov@virtuozzo.com>
2
2
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
3
Since bdrv_co_preadv does all neccessary checks including
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
reading after the end of the backing file, avoid duplication
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
5
of verification before bdrv_co_preadv call.
6
7
Signed-off-by: Edgar Kaziakhmedov <edgar.kaziakhmedov@virtuozzo.com>
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
11
---
8
block/qcow2.c | 9 ++-------
12
block/qcow2.h | 3 ---
9
1 file changed, 2 insertions(+), 7 deletions(-)
13
block/qcow2.c | 51 ++++++++-------------------------------------------
14
2 files changed, 8 insertions(+), 46 deletions(-)
10
15
16
diff --git a/block/qcow2.h b/block/qcow2.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2.h
19
+++ b/block/qcow2.h
20
@@ -XXX,XX +XXX,XX @@ uint32_t offset_to_reftable_index(BDRVQcow2State *s, uint64_t offset)
21
}
22
23
/* qcow2.c functions */
24
-int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
25
- int64_t sector_num, int nb_sectors);
26
-
27
int64_t qcow2_refcount_metadata_size(int64_t clusters, size_t cluster_size,
28
int refcount_order, bool generous_increase,
29
uint64_t *refblock_count);
11
diff --git a/block/qcow2.c b/block/qcow2.c
30
diff --git a/block/qcow2.c b/block/qcow2.c
12
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
13
--- a/block/qcow2.c
32
--- a/block/qcow2.c
14
+++ b/block/qcow2.c
33
+++ b/block/qcow2.c
15
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
34
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
16
uint64_t bytes, QEMUIOVector *qiov)
35
return status;
36
}
37
38
-/* handle reading after the end of the backing file */
39
-int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
40
- int64_t offset, int bytes)
41
-{
42
- uint64_t bs_size = bs->total_sectors * BDRV_SECTOR_SIZE;
43
- int n1;
44
-
45
- if ((offset + bytes) <= bs_size) {
46
- return bytes;
47
- }
48
-
49
- if (offset >= bs_size) {
50
- n1 = 0;
51
- } else {
52
- n1 = bs_size - offset;
53
- }
54
-
55
- qemu_iovec_memset(qiov, n1, 0, bytes - n1);
56
-
57
- return n1;
58
-}
59
-
60
static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
61
uint64_t bytes, QEMUIOVector *qiov,
62
int flags)
17
{
63
{
18
BDRVQcow2State *s = bs->opaque;
64
BDRVQcow2State *s = bs->opaque;
19
- QEMUIOVector hd_qiov;
65
- int offset_in_cluster, n1;
66
+ int offset_in_cluster;
20
int ret;
67
int ret;
21
ssize_t out_len;
68
unsigned int cur_bytes; /* number of bytes in current iteration */
22
uint8_t *buf, *out_buf;
69
uint64_t cluster_offset = 0;
23
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
70
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
24
goto fail;
71
case QCOW2_CLUSTER_UNALLOCATED:
25
}
72
26
73
if (bs->backing) {
27
- qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
74
- /* read from the base image */
75
- n1 = qcow2_backing_read1(bs->backing->bs, &hd_qiov,
76
- offset, cur_bytes);
77
- if (n1 > 0) {
78
- QEMUIOVector local_qiov;
28
-
79
-
29
BLKDBG_EVENT(s->data_file, BLKDBG_WRITE_COMPRESSED);
80
- qemu_iovec_init(&local_qiov, hd_qiov.niov);
30
- ret = bdrv_co_pwritev(s->data_file, cluster_offset, out_len, &hd_qiov, 0);
81
- qemu_iovec_concat(&local_qiov, &hd_qiov, 0, n1);
31
+ ret = bdrv_co_pwrite(s->data_file, cluster_offset, out_len, out_buf, 0);
82
-
32
if (ret < 0) {
83
- BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
33
goto fail;
84
- qemu_co_mutex_unlock(&s->lock);
34
}
85
- ret = bdrv_co_preadv(bs->backing, offset, n1,
35
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
86
- &local_qiov, 0);
36
int ret = 0, csize, nb_csectors;
87
- qemu_co_mutex_lock(&s->lock);
37
uint64_t coffset;
88
-
38
uint8_t *buf, *out_buf;
89
- qemu_iovec_destroy(&local_qiov);
39
- QEMUIOVector local_qiov;
90
-
40
int offset_in_cluster = offset_into_cluster(s, offset);
91
- if (ret < 0) {
41
92
- goto fail;
42
coffset = file_cluster_offset & s->cluster_offset_mask;
93
- }
43
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
94
+ BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
44
if (!buf) {
95
+ qemu_co_mutex_unlock(&s->lock);
45
return -ENOMEM;
96
+ ret = bdrv_co_preadv(bs->backing, offset, cur_bytes,
46
}
97
+ &hd_qiov, 0);
47
- qemu_iovec_init_buf(&local_qiov, buf, csize);
98
+ qemu_co_mutex_lock(&s->lock);
48
99
+ if (ret < 0) {
49
out_buf = qemu_blockalign(bs, s->cluster_size);
100
+ goto fail;
50
101
}
51
BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
102
} else {
52
- ret = bdrv_co_preadv(bs->file, coffset, csize, &local_qiov, 0);
103
/* Note: in this case, no need to wait */
53
+ ret = bdrv_co_pread(bs->file, coffset, csize, buf, 0);
54
if (ret < 0) {
55
goto fail;
56
}
57
--
104
--
58
2.20.1
105
2.13.6
59
106
60
107
diff view generated by jsdifflib
New patch
1
Removing a quorum child node with x-blockdev-change results in a quorum
2
driver state that cannot be recreated with create options because it
3
would require a list with gaps. This causes trouble in at least
4
.bdrv_refresh_filename().
1
5
6
Document this problem so that we won't accidentally mark the command
7
stable without having addressed it.
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Alberto Garcia <berto@igalia.com>
11
---
12
qapi/block-core.json | 4 ++++
13
1 file changed, 4 insertions(+)
14
15
diff --git a/qapi/block-core.json b/qapi/block-core.json
16
index XXXXXXX..XXXXXXX 100644
17
--- a/qapi/block-core.json
18
+++ b/qapi/block-core.json
19
@@ -XXX,XX +XXX,XX @@
20
# does not support all kinds of operations, all kinds of children, nor
21
# all block drivers.
22
#
23
+# FIXME Removing children from a quorum node means introducing gaps in the
24
+# child indices. This cannot be represented in the 'children' list of
25
+# BlockdevOptionsQuorum, as returned by .bdrv_refresh_filename().
26
+#
27
# Warning: The data in a new quorum child MUST be consistent with that of
28
# the rest of the array.
29
#
30
--
31
2.13.6
32
33
diff view generated by jsdifflib
New patch
1
From: Doug Gale <doug16k@gmail.com>
1
2
3
Add trace output for commands, errors, and undefined behavior.
4
Add guest error log output for undefined behavior.
5
Report invalid undefined accesses to MMIO.
6
Annotate unlikely error checks with unlikely.
7
8
Signed-off-by: Doug Gale <doug16k@gmail.com>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
hw/block/nvme.c | 349 ++++++++++++++++++++++++++++++++++++++++++--------
14
hw/block/trace-events | 93 ++++++++++++++
15
2 files changed, 390 insertions(+), 52 deletions(-)
16
17
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/block/nvme.c
20
+++ b/hw/block/nvme.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "qapi/visitor.h"
23
#include "sysemu/block-backend.h"
24
25
+#include "qemu/log.h"
26
+#include "trace.h"
27
#include "nvme.h"
28
29
+#define NVME_GUEST_ERR(trace, fmt, ...) \
30
+ do { \
31
+ (trace_##trace)(__VA_ARGS__); \
32
+ qemu_log_mask(LOG_GUEST_ERROR, #trace \
33
+ " in %s: " fmt "\n", __func__, ## __VA_ARGS__); \
34
+ } while (0)
35
+
36
static void nvme_process_sq(void *opaque);
37
38
static void nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size)
39
@@ -XXX,XX +XXX,XX @@ static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq)
40
{
41
if (cq->irq_enabled) {
42
if (msix_enabled(&(n->parent_obj))) {
43
+ trace_nvme_irq_msix(cq->vector);
44
msix_notify(&(n->parent_obj), cq->vector);
45
} else {
46
+ trace_nvme_irq_pin();
47
pci_irq_pulse(&n->parent_obj);
48
}
49
+ } else {
50
+ trace_nvme_irq_masked();
51
}
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
55
trans_len = MIN(len, trans_len);
56
int num_prps = (len >> n->page_bits) + 1;
57
58
- if (!prp1) {
59
+ if (unlikely(!prp1)) {
60
+ trace_nvme_err_invalid_prp();
61
return NVME_INVALID_FIELD | NVME_DNR;
62
} else if (n->cmbsz && prp1 >= n->ctrl_mem.addr &&
63
prp1 < n->ctrl_mem.addr + int128_get64(n->ctrl_mem.size)) {
64
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
65
}
66
len -= trans_len;
67
if (len) {
68
- if (!prp2) {
69
+ if (unlikely(!prp2)) {
70
+ trace_nvme_err_invalid_prp2_missing();
71
goto unmap;
72
}
73
if (len > n->page_size) {
74
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
75
uint64_t prp_ent = le64_to_cpu(prp_list[i]);
76
77
if (i == n->max_prp_ents - 1 && len > n->page_size) {
78
- if (!prp_ent || prp_ent & (n->page_size - 1)) {
79
+ if (unlikely(!prp_ent || prp_ent & (n->page_size - 1))) {
80
+ trace_nvme_err_invalid_prplist_ent(prp_ent);
81
goto unmap;
82
}
83
84
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
85
prp_ent = le64_to_cpu(prp_list[i]);
86
}
87
88
- if (!prp_ent || prp_ent & (n->page_size - 1)) {
89
+ if (unlikely(!prp_ent || prp_ent & (n->page_size - 1))) {
90
+ trace_nvme_err_invalid_prplist_ent(prp_ent);
91
goto unmap;
92
}
93
94
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
95
i++;
96
}
97
} else {
98
- if (prp2 & (n->page_size - 1)) {
99
+ if (unlikely(prp2 & (n->page_size - 1))) {
100
+ trace_nvme_err_invalid_prp2_align(prp2);
101
goto unmap;
102
}
103
if (qsg->nsg) {
104
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_dma_read_prp(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
105
QEMUIOVector iov;
106
uint16_t status = NVME_SUCCESS;
107
108
+ trace_nvme_dma_read(prp1, prp2);
109
+
110
if (nvme_map_prp(&qsg, &iov, prp1, prp2, len, n)) {
111
return NVME_INVALID_FIELD | NVME_DNR;
112
}
113
if (qsg.nsg > 0) {
114
- if (dma_buf_read(ptr, len, &qsg)) {
115
+ if (unlikely(dma_buf_read(ptr, len, &qsg))) {
116
+ trace_nvme_err_invalid_dma();
117
status = NVME_INVALID_FIELD | NVME_DNR;
118
}
119
qemu_sglist_destroy(&qsg);
120
} else {
121
- if (qemu_iovec_to_buf(&iov, 0, ptr, len) != len) {
122
+ if (unlikely(qemu_iovec_to_buf(&iov, 0, ptr, len) != len)) {
123
+ trace_nvme_err_invalid_dma();
124
status = NVME_INVALID_FIELD | NVME_DNR;
125
}
126
qemu_iovec_destroy(&iov);
127
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_write_zeros(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
128
uint64_t aio_slba = slba << (data_shift - BDRV_SECTOR_BITS);
129
uint32_t aio_nlb = nlb << (data_shift - BDRV_SECTOR_BITS);
130
131
- if (slba + nlb > ns->id_ns.nsze) {
132
+ if (unlikely(slba + nlb > ns->id_ns.nsze)) {
133
+ trace_nvme_err_invalid_lba_range(slba, nlb, ns->id_ns.nsze);
134
return NVME_LBA_RANGE | NVME_DNR;
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
138
int is_write = rw->opcode == NVME_CMD_WRITE ? 1 : 0;
139
enum BlockAcctType acct = is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ;
140
141
- if ((slba + nlb) > ns->id_ns.nsze) {
142
+ trace_nvme_rw(is_write ? "write" : "read", nlb, data_size, slba);
143
+
144
+ if (unlikely((slba + nlb) > ns->id_ns.nsze)) {
145
block_acct_invalid(blk_get_stats(n->conf.blk), acct);
146
+ trace_nvme_err_invalid_lba_range(slba, nlb, ns->id_ns.nsze);
147
return NVME_LBA_RANGE | NVME_DNR;
148
}
149
150
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
151
NvmeNamespace *ns;
152
uint32_t nsid = le32_to_cpu(cmd->nsid);
153
154
- if (nsid == 0 || nsid > n->num_namespaces) {
155
+ if (unlikely(nsid == 0 || nsid > n->num_namespaces)) {
156
+ trace_nvme_err_invalid_ns(nsid, n->num_namespaces);
157
return NVME_INVALID_NSID | NVME_DNR;
158
}
159
160
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
161
case NVME_CMD_READ:
162
return nvme_rw(n, ns, cmd, req);
163
default:
164
+ trace_nvme_err_invalid_opc(cmd->opcode);
165
return NVME_INVALID_OPCODE | NVME_DNR;
166
}
167
}
168
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeCmd *cmd)
169
NvmeCQueue *cq;
170
uint16_t qid = le16_to_cpu(c->qid);
171
172
- if (!qid || nvme_check_sqid(n, qid)) {
173
+ if (unlikely(!qid || nvme_check_sqid(n, qid))) {
174
+ trace_nvme_err_invalid_del_sq(qid);
175
return NVME_INVALID_QID | NVME_DNR;
176
}
177
178
+ trace_nvme_del_sq(qid);
179
+
180
sq = n->sq[qid];
181
while (!QTAILQ_EMPTY(&sq->out_req_list)) {
182
req = QTAILQ_FIRST(&sq->out_req_list);
183
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_create_sq(NvmeCtrl *n, NvmeCmd *cmd)
184
uint16_t qflags = le16_to_cpu(c->sq_flags);
185
uint64_t prp1 = le64_to_cpu(c->prp1);
186
187
- if (!cqid || nvme_check_cqid(n, cqid)) {
188
+ trace_nvme_create_sq(prp1, sqid, cqid, qsize, qflags);
189
+
190
+ if (unlikely(!cqid || nvme_check_cqid(n, cqid))) {
191
+ trace_nvme_err_invalid_create_sq_cqid(cqid);
192
return NVME_INVALID_CQID | NVME_DNR;
193
}
194
- if (!sqid || !nvme_check_sqid(n, sqid)) {
195
+ if (unlikely(!sqid || !nvme_check_sqid(n, sqid))) {
196
+ trace_nvme_err_invalid_create_sq_sqid(sqid);
197
return NVME_INVALID_QID | NVME_DNR;
198
}
199
- if (!qsize || qsize > NVME_CAP_MQES(n->bar.cap)) {
200
+ if (unlikely(!qsize || qsize > NVME_CAP_MQES(n->bar.cap))) {
201
+ trace_nvme_err_invalid_create_sq_size(qsize);
202
return NVME_MAX_QSIZE_EXCEEDED | NVME_DNR;
203
}
204
- if (!prp1 || prp1 & (n->page_size - 1)) {
205
+ if (unlikely(!prp1 || prp1 & (n->page_size - 1))) {
206
+ trace_nvme_err_invalid_create_sq_addr(prp1);
207
return NVME_INVALID_FIELD | NVME_DNR;
208
}
209
- if (!(NVME_SQ_FLAGS_PC(qflags))) {
210
+ if (unlikely(!(NVME_SQ_FLAGS_PC(qflags)))) {
211
+ trace_nvme_err_invalid_create_sq_qflags(NVME_SQ_FLAGS_PC(qflags));
212
return NVME_INVALID_FIELD | NVME_DNR;
213
}
214
sq = g_malloc0(sizeof(*sq));
215
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_del_cq(NvmeCtrl *n, NvmeCmd *cmd)
216
NvmeCQueue *cq;
217
uint16_t qid = le16_to_cpu(c->qid);
218
219
- if (!qid || nvme_check_cqid(n, qid)) {
220
+ if (unlikely(!qid || nvme_check_cqid(n, qid))) {
221
+ trace_nvme_err_invalid_del_cq_cqid(qid);
222
return NVME_INVALID_CQID | NVME_DNR;
223
}
224
225
cq = n->cq[qid];
226
- if (!QTAILQ_EMPTY(&cq->sq_list)) {
227
+ if (unlikely(!QTAILQ_EMPTY(&cq->sq_list))) {
228
+ trace_nvme_err_invalid_del_cq_notempty(qid);
229
return NVME_INVALID_QUEUE_DEL;
230
}
231
+ trace_nvme_del_cq(qid);
232
nvme_free_cq(cq, n);
233
return NVME_SUCCESS;
234
}
235
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd)
236
uint16_t qflags = le16_to_cpu(c->cq_flags);
237
uint64_t prp1 = le64_to_cpu(c->prp1);
238
239
- if (!cqid || !nvme_check_cqid(n, cqid)) {
240
+ trace_nvme_create_cq(prp1, cqid, vector, qsize, qflags,
241
+ NVME_CQ_FLAGS_IEN(qflags) != 0);
242
+
243
+ if (unlikely(!cqid || !nvme_check_cqid(n, cqid))) {
244
+ trace_nvme_err_invalid_create_cq_cqid(cqid);
245
return NVME_INVALID_CQID | NVME_DNR;
246
}
247
- if (!qsize || qsize > NVME_CAP_MQES(n->bar.cap)) {
248
+ if (unlikely(!qsize || qsize > NVME_CAP_MQES(n->bar.cap))) {
249
+ trace_nvme_err_invalid_create_cq_size(qsize);
250
return NVME_MAX_QSIZE_EXCEEDED | NVME_DNR;
251
}
252
- if (!prp1) {
253
+ if (unlikely(!prp1)) {
254
+ trace_nvme_err_invalid_create_cq_addr(prp1);
255
return NVME_INVALID_FIELD | NVME_DNR;
256
}
257
- if (vector > n->num_queues) {
258
+ if (unlikely(vector > n->num_queues)) {
259
+ trace_nvme_err_invalid_create_cq_vector(vector);
260
return NVME_INVALID_IRQ_VECTOR | NVME_DNR;
261
}
262
- if (!(NVME_CQ_FLAGS_PC(qflags))) {
263
+ if (unlikely(!(NVME_CQ_FLAGS_PC(qflags)))) {
264
+ trace_nvme_err_invalid_create_cq_qflags(NVME_CQ_FLAGS_PC(qflags));
265
return NVME_INVALID_FIELD | NVME_DNR;
266
}
267
268
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_identify_ctrl(NvmeCtrl *n, NvmeIdentify *c)
269
uint64_t prp1 = le64_to_cpu(c->prp1);
270
uint64_t prp2 = le64_to_cpu(c->prp2);
271
272
+ trace_nvme_identify_ctrl();
273
+
274
return nvme_dma_read_prp(n, (uint8_t *)&n->id_ctrl, sizeof(n->id_ctrl),
275
prp1, prp2);
276
}
277
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeIdentify *c)
278
uint64_t prp1 = le64_to_cpu(c->prp1);
279
uint64_t prp2 = le64_to_cpu(c->prp2);
280
281
- if (nsid == 0 || nsid > n->num_namespaces) {
282
+ trace_nvme_identify_ns(nsid);
283
+
284
+ if (unlikely(nsid == 0 || nsid > n->num_namespaces)) {
285
+ trace_nvme_err_invalid_ns(nsid, n->num_namespaces);
286
return NVME_INVALID_NSID | NVME_DNR;
287
}
288
289
ns = &n->namespaces[nsid - 1];
290
+
291
return nvme_dma_read_prp(n, (uint8_t *)&ns->id_ns, sizeof(ns->id_ns),
292
prp1, prp2);
293
}
294
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeIdentify *c)
295
uint16_t ret;
296
int i, j = 0;
297
298
+ trace_nvme_identify_nslist(min_nsid);
299
+
300
list = g_malloc0(data_len);
301
for (i = 0; i < n->num_namespaces; i++) {
302
if (i < min_nsid) {
303
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd)
304
case 0x02:
305
return nvme_identify_nslist(n, c);
306
default:
307
+ trace_nvme_err_invalid_identify_cns(le32_to_cpu(c->cns));
308
return NVME_INVALID_FIELD | NVME_DNR;
309
}
310
}
311
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
312
switch (dw10) {
313
case NVME_VOLATILE_WRITE_CACHE:
314
result = blk_enable_write_cache(n->conf.blk);
315
+ trace_nvme_getfeat_vwcache(result ? "enabled" : "disabled");
316
break;
317
case NVME_NUMBER_OF_QUEUES:
318
result = cpu_to_le32((n->num_queues - 2) | ((n->num_queues - 2) << 16));
319
+ trace_nvme_getfeat_numq(result);
320
break;
321
default:
322
+ trace_nvme_err_invalid_getfeat(dw10);
323
return NVME_INVALID_FIELD | NVME_DNR;
324
}
325
326
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
327
blk_set_enable_write_cache(n->conf.blk, dw11 & 1);
328
break;
329
case NVME_NUMBER_OF_QUEUES:
330
+ trace_nvme_setfeat_numq((dw11 & 0xFFFF) + 1,
331
+ ((dw11 >> 16) & 0xFFFF) + 1,
332
+ n->num_queues - 1, n->num_queues - 1);
333
req->cqe.result =
334
cpu_to_le32((n->num_queues - 2) | ((n->num_queues - 2) << 16));
335
break;
336
default:
337
+ trace_nvme_err_invalid_setfeat(dw10);
338
return NVME_INVALID_FIELD | NVME_DNR;
339
}
340
return NVME_SUCCESS;
341
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
342
case NVME_ADM_CMD_GET_FEATURES:
343
return nvme_get_feature(n, cmd, req);
344
default:
345
+ trace_nvme_err_invalid_admin_opc(cmd->opcode);
346
return NVME_INVALID_OPCODE | NVME_DNR;
347
}
348
}
349
@@ -XXX,XX +XXX,XX @@ static int nvme_start_ctrl(NvmeCtrl *n)
350
uint32_t page_bits = NVME_CC_MPS(n->bar.cc) + 12;
351
uint32_t page_size = 1 << page_bits;
352
353
- if (n->cq[0] || n->sq[0] || !n->bar.asq || !n->bar.acq ||
354
- n->bar.asq & (page_size - 1) || n->bar.acq & (page_size - 1) ||
355
- NVME_CC_MPS(n->bar.cc) < NVME_CAP_MPSMIN(n->bar.cap) ||
356
- NVME_CC_MPS(n->bar.cc) > NVME_CAP_MPSMAX(n->bar.cap) ||
357
- NVME_CC_IOCQES(n->bar.cc) < NVME_CTRL_CQES_MIN(n->id_ctrl.cqes) ||
358
- NVME_CC_IOCQES(n->bar.cc) > NVME_CTRL_CQES_MAX(n->id_ctrl.cqes) ||
359
- NVME_CC_IOSQES(n->bar.cc) < NVME_CTRL_SQES_MIN(n->id_ctrl.sqes) ||
360
- NVME_CC_IOSQES(n->bar.cc) > NVME_CTRL_SQES_MAX(n->id_ctrl.sqes) ||
361
- !NVME_AQA_ASQS(n->bar.aqa) || !NVME_AQA_ACQS(n->bar.aqa)) {
362
+ if (unlikely(n->cq[0])) {
363
+ trace_nvme_err_startfail_cq();
364
+ return -1;
365
+ }
366
+ if (unlikely(n->sq[0])) {
367
+ trace_nvme_err_startfail_sq();
368
+ return -1;
369
+ }
370
+ if (unlikely(!n->bar.asq)) {
371
+ trace_nvme_err_startfail_nbarasq();
372
+ return -1;
373
+ }
374
+ if (unlikely(!n->bar.acq)) {
375
+ trace_nvme_err_startfail_nbaracq();
376
+ return -1;
377
+ }
378
+ if (unlikely(n->bar.asq & (page_size - 1))) {
379
+ trace_nvme_err_startfail_asq_misaligned(n->bar.asq);
380
+ return -1;
381
+ }
382
+ if (unlikely(n->bar.acq & (page_size - 1))) {
383
+ trace_nvme_err_startfail_acq_misaligned(n->bar.acq);
384
+ return -1;
385
+ }
386
+ if (unlikely(NVME_CC_MPS(n->bar.cc) <
387
+ NVME_CAP_MPSMIN(n->bar.cap))) {
388
+ trace_nvme_err_startfail_page_too_small(
389
+ NVME_CC_MPS(n->bar.cc),
390
+ NVME_CAP_MPSMIN(n->bar.cap));
391
+ return -1;
392
+ }
393
+ if (unlikely(NVME_CC_MPS(n->bar.cc) >
394
+ NVME_CAP_MPSMAX(n->bar.cap))) {
395
+ trace_nvme_err_startfail_page_too_large(
396
+ NVME_CC_MPS(n->bar.cc),
397
+ NVME_CAP_MPSMAX(n->bar.cap));
398
+ return -1;
399
+ }
400
+ if (unlikely(NVME_CC_IOCQES(n->bar.cc) <
401
+ NVME_CTRL_CQES_MIN(n->id_ctrl.cqes))) {
402
+ trace_nvme_err_startfail_cqent_too_small(
403
+ NVME_CC_IOCQES(n->bar.cc),
404
+ NVME_CTRL_CQES_MIN(n->bar.cap));
405
+ return -1;
406
+ }
407
+ if (unlikely(NVME_CC_IOCQES(n->bar.cc) >
408
+ NVME_CTRL_CQES_MAX(n->id_ctrl.cqes))) {
409
+ trace_nvme_err_startfail_cqent_too_large(
410
+ NVME_CC_IOCQES(n->bar.cc),
411
+ NVME_CTRL_CQES_MAX(n->bar.cap));
412
+ return -1;
413
+ }
414
+ if (unlikely(NVME_CC_IOSQES(n->bar.cc) <
415
+ NVME_CTRL_SQES_MIN(n->id_ctrl.sqes))) {
416
+ trace_nvme_err_startfail_sqent_too_small(
417
+ NVME_CC_IOSQES(n->bar.cc),
418
+ NVME_CTRL_SQES_MIN(n->bar.cap));
419
+ return -1;
420
+ }
421
+ if (unlikely(NVME_CC_IOSQES(n->bar.cc) >
422
+ NVME_CTRL_SQES_MAX(n->id_ctrl.sqes))) {
423
+ trace_nvme_err_startfail_sqent_too_large(
424
+ NVME_CC_IOSQES(n->bar.cc),
425
+ NVME_CTRL_SQES_MAX(n->bar.cap));
426
+ return -1;
427
+ }
428
+ if (unlikely(!NVME_AQA_ASQS(n->bar.aqa))) {
429
+ trace_nvme_err_startfail_asqent_sz_zero();
430
+ return -1;
431
+ }
432
+ if (unlikely(!NVME_AQA_ACQS(n->bar.aqa))) {
433
+ trace_nvme_err_startfail_acqent_sz_zero();
434
return -1;
435
}
436
437
@@ -XXX,XX +XXX,XX @@ static int nvme_start_ctrl(NvmeCtrl *n)
438
static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
439
unsigned size)
440
{
441
+ if (unlikely(offset & (sizeof(uint32_t) - 1))) {
442
+ NVME_GUEST_ERR(nvme_ub_mmiowr_misaligned32,
443
+ "MMIO write not 32-bit aligned,"
444
+ " offset=0x%"PRIx64"", offset);
445
+ /* should be ignored, fall through for now */
446
+ }
447
+
448
+ if (unlikely(size < sizeof(uint32_t))) {
449
+ NVME_GUEST_ERR(nvme_ub_mmiowr_toosmall,
450
+ "MMIO write smaller than 32-bits,"
451
+ " offset=0x%"PRIx64", size=%u",
452
+ offset, size);
453
+ /* should be ignored, fall through for now */
454
+ }
455
+
456
switch (offset) {
457
- case 0xc:
458
+ case 0xc: /* INTMS */
459
+ if (unlikely(msix_enabled(&(n->parent_obj)))) {
460
+ NVME_GUEST_ERR(nvme_ub_mmiowr_intmask_with_msix,
461
+ "undefined access to interrupt mask set"
462
+ " when MSI-X is enabled");
463
+ /* should be ignored, fall through for now */
464
+ }
465
n->bar.intms |= data & 0xffffffff;
466
n->bar.intmc = n->bar.intms;
467
+ trace_nvme_mmio_intm_set(data & 0xffffffff,
468
+ n->bar.intmc);
469
break;
470
- case 0x10:
471
+ case 0x10: /* INTMC */
472
+ if (unlikely(msix_enabled(&(n->parent_obj)))) {
473
+ NVME_GUEST_ERR(nvme_ub_mmiowr_intmask_with_msix,
474
+ "undefined access to interrupt mask clr"
475
+ " when MSI-X is enabled");
476
+ /* should be ignored, fall through for now */
477
+ }
478
n->bar.intms &= ~(data & 0xffffffff);
479
n->bar.intmc = n->bar.intms;
480
+ trace_nvme_mmio_intm_clr(data & 0xffffffff,
481
+ n->bar.intmc);
482
break;
483
- case 0x14:
484
+ case 0x14: /* CC */
485
+ trace_nvme_mmio_cfg(data & 0xffffffff);
486
/* Windows first sends data, then sends enable bit */
487
if (!NVME_CC_EN(data) && !NVME_CC_EN(n->bar.cc) &&
488
!NVME_CC_SHN(data) && !NVME_CC_SHN(n->bar.cc))
489
@@ -XXX,XX +XXX,XX @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
490
491
if (NVME_CC_EN(data) && !NVME_CC_EN(n->bar.cc)) {
492
n->bar.cc = data;
493
- if (nvme_start_ctrl(n)) {
494
+ if (unlikely(nvme_start_ctrl(n))) {
495
+ trace_nvme_err_startfail();
496
n->bar.csts = NVME_CSTS_FAILED;
497
} else {
498
+ trace_nvme_mmio_start_success();
499
n->bar.csts = NVME_CSTS_READY;
500
}
501
} else if (!NVME_CC_EN(data) && NVME_CC_EN(n->bar.cc)) {
502
+ trace_nvme_mmio_stopped();
503
nvme_clear_ctrl(n);
504
n->bar.csts &= ~NVME_CSTS_READY;
505
}
506
if (NVME_CC_SHN(data) && !(NVME_CC_SHN(n->bar.cc))) {
507
- nvme_clear_ctrl(n);
508
- n->bar.cc = data;
509
- n->bar.csts |= NVME_CSTS_SHST_COMPLETE;
510
+ trace_nvme_mmio_shutdown_set();
511
+ nvme_clear_ctrl(n);
512
+ n->bar.cc = data;
513
+ n->bar.csts |= NVME_CSTS_SHST_COMPLETE;
514
} else if (!NVME_CC_SHN(data) && NVME_CC_SHN(n->bar.cc)) {
515
- n->bar.csts &= ~NVME_CSTS_SHST_COMPLETE;
516
- n->bar.cc = data;
517
+ trace_nvme_mmio_shutdown_cleared();
518
+ n->bar.csts &= ~NVME_CSTS_SHST_COMPLETE;
519
+ n->bar.cc = data;
520
+ }
521
+ break;
522
+ case 0x1C: /* CSTS */
523
+ if (data & (1 << 4)) {
524
+ NVME_GUEST_ERR(nvme_ub_mmiowr_ssreset_w1c_unsupported,
525
+ "attempted to W1C CSTS.NSSRO"
526
+ " but CAP.NSSRS is zero (not supported)");
527
+ } else if (data != 0) {
528
+ NVME_GUEST_ERR(nvme_ub_mmiowr_ro_csts,
529
+ "attempted to set a read only bit"
530
+ " of controller status");
531
+ }
532
+ break;
533
+ case 0x20: /* NSSR */
534
+ if (data == 0x4E564D65) {
535
+ trace_nvme_ub_mmiowr_ssreset_unsupported();
536
+ } else {
537
+ /* The spec says that writes of other values have no effect */
538
+ return;
539
}
540
break;
541
- case 0x24:
542
+ case 0x24: /* AQA */
543
n->bar.aqa = data & 0xffffffff;
544
+ trace_nvme_mmio_aqattr(data & 0xffffffff);
545
break;
546
- case 0x28:
547
+ case 0x28: /* ASQ */
548
n->bar.asq = data;
549
+ trace_nvme_mmio_asqaddr(data);
550
break;
551
- case 0x2c:
552
+ case 0x2c: /* ASQ hi */
553
n->bar.asq |= data << 32;
554
+ trace_nvme_mmio_asqaddr_hi(data, n->bar.asq);
555
break;
556
- case 0x30:
557
+ case 0x30: /* ACQ */
558
+ trace_nvme_mmio_acqaddr(data);
559
n->bar.acq = data;
560
break;
561
- case 0x34:
562
+ case 0x34: /* ACQ hi */
563
n->bar.acq |= data << 32;
564
+ trace_nvme_mmio_acqaddr_hi(data, n->bar.acq);
565
break;
566
+ case 0x38: /* CMBLOC */
567
+ NVME_GUEST_ERR(nvme_ub_mmiowr_cmbloc_reserved,
568
+ "invalid write to reserved CMBLOC"
569
+ " when CMBSZ is zero, ignored");
570
+ return;
571
+ case 0x3C: /* CMBSZ */
572
+ NVME_GUEST_ERR(nvme_ub_mmiowr_cmbsz_readonly,
573
+ "invalid write to read only CMBSZ, ignored");
574
+ return;
575
default:
576
+ NVME_GUEST_ERR(nvme_ub_mmiowr_invalid,
577
+ "invalid MMIO write,"
578
+ " offset=0x%"PRIx64", data=%"PRIx64"",
579
+ offset, data);
580
break;
581
}
582
}
583
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
584
uint8_t *ptr = (uint8_t *)&n->bar;
585
uint64_t val = 0;
586
587
+ if (unlikely(addr & (sizeof(uint32_t) - 1))) {
588
+ NVME_GUEST_ERR(nvme_ub_mmiord_misaligned32,
589
+ "MMIO read not 32-bit aligned,"
590
+ " offset=0x%"PRIx64"", addr);
591
+ /* should RAZ, fall through for now */
592
+ } else if (unlikely(size < sizeof(uint32_t))) {
593
+ NVME_GUEST_ERR(nvme_ub_mmiord_toosmall,
594
+ "MMIO read smaller than 32-bits,"
595
+ " offset=0x%"PRIx64"", addr);
596
+ /* should RAZ, fall through for now */
597
+ }
598
+
599
if (addr < sizeof(n->bar)) {
600
memcpy(&val, ptr + addr, size);
601
+ } else {
602
+ NVME_GUEST_ERR(nvme_ub_mmiord_invalid_ofs,
603
+ "MMIO read beyond last register,"
604
+ " offset=0x%"PRIx64", returning 0", addr);
605
}
606
+
607
return val;
608
}
609
610
@@ -XXX,XX +XXX,XX @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
611
{
612
uint32_t qid;
613
614
- if (addr & ((1 << 2) - 1)) {
615
+ if (unlikely(addr & ((1 << 2) - 1))) {
616
+ NVME_GUEST_ERR(nvme_ub_db_wr_misaligned,
617
+ "doorbell write not 32-bit aligned,"
618
+ " offset=0x%"PRIx64", ignoring", addr);
619
return;
620
}
621
622
if (((addr - 0x1000) >> 2) & 1) {
623
+ /* Completion queue doorbell write */
624
+
625
uint16_t new_head = val & 0xffff;
626
int start_sqs;
627
NvmeCQueue *cq;
628
629
qid = (addr - (0x1000 + (1 << 2))) >> 3;
630
- if (nvme_check_cqid(n, qid)) {
631
+ if (unlikely(nvme_check_cqid(n, qid))) {
632
+ NVME_GUEST_ERR(nvme_ub_db_wr_invalid_cq,
633
+ "completion queue doorbell write"
634
+ " for nonexistent queue,"
635
+ " sqid=%"PRIu32", ignoring", qid);
636
return;
637
}
638
639
cq = n->cq[qid];
640
- if (new_head >= cq->size) {
641
+ if (unlikely(new_head >= cq->size)) {
642
+ NVME_GUEST_ERR(nvme_ub_db_wr_invalid_cqhead,
643
+ "completion queue doorbell write value"
644
+ " beyond queue size, sqid=%"PRIu32","
645
+ " new_head=%"PRIu16", ignoring",
646
+ qid, new_head);
647
return;
648
}
649
650
@@ -XXX,XX +XXX,XX @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
651
nvme_isr_notify(n, cq);
652
}
653
} else {
654
+ /* Submission queue doorbell write */
655
+
656
uint16_t new_tail = val & 0xffff;
657
NvmeSQueue *sq;
658
659
qid = (addr - 0x1000) >> 3;
660
- if (nvme_check_sqid(n, qid)) {
661
+ if (unlikely(nvme_check_sqid(n, qid))) {
662
+ NVME_GUEST_ERR(nvme_ub_db_wr_invalid_sq,
663
+ "submission queue doorbell write"
664
+ " for nonexistent queue,"
665
+ " sqid=%"PRIu32", ignoring", qid);
666
return;
667
}
668
669
sq = n->sq[qid];
670
- if (new_tail >= sq->size) {
671
+ if (unlikely(new_tail >= sq->size)) {
672
+ NVME_GUEST_ERR(nvme_ub_db_wr_invalid_sqtail,
673
+ "submission queue doorbell write value"
674
+ " beyond queue size, sqid=%"PRIu32","
675
+ " new_tail=%"PRIu16", ignoring",
676
+ qid, new_tail);
677
return;
678
}
679
680
diff --git a/hw/block/trace-events b/hw/block/trace-events
681
index XXXXXXX..XXXXXXX 100644
682
--- a/hw/block/trace-events
683
+++ b/hw/block/trace-events
684
@@ -XXX,XX +XXX,XX @@ virtio_blk_submit_multireq(void *vdev, void *mrb, int start, int num_reqs, uint6
685
hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS %d %d %d"
686
hd_geometry_guess(void *blk, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "blk %p CHS %u %u %u trans %d"
687
688
+# hw/block/nvme.c
689
+# nvme traces for successful events
690
+nvme_irq_msix(uint32_t vector) "raising MSI-X IRQ vector %u"
691
+nvme_irq_pin(void) "pulsing IRQ pin"
692
+nvme_irq_masked(void) "IRQ is masked"
693
+nvme_dma_read(uint64_t prp1, uint64_t prp2) "DMA read, prp1=0x%"PRIx64" prp2=0x%"PRIx64""
694
+nvme_rw(char const *verb, uint32_t blk_count, uint64_t byte_count, uint64_t lba) "%s %"PRIu32" blocks (%"PRIu64" bytes) from LBA %"PRIu64""
695
+nvme_create_sq(uint64_t addr, uint16_t sqid, uint16_t cqid, uint16_t qsize, uint16_t qflags) "create submission queue, addr=0x%"PRIx64", sqid=%"PRIu16", cqid=%"PRIu16", qsize=%"PRIu16", qflags=%"PRIu16""
696
+nvme_create_cq(uint64_t addr, uint16_t cqid, uint16_t vector, uint16_t size, uint16_t qflags, int ien) "create completion queue, addr=0x%"PRIx64", cqid=%"PRIu16", vector=%"PRIu16", qsize=%"PRIu16", qflags=%"PRIu16", ien=%d"
697
+nvme_del_sq(uint16_t qid) "deleting submission queue sqid=%"PRIu16""
698
+nvme_del_cq(uint16_t cqid) "deleted completion queue, sqid=%"PRIu16""
699
+nvme_identify_ctrl(void) "identify controller"
700
+nvme_identify_ns(uint16_t ns) "identify namespace, nsid=%"PRIu16""
701
+nvme_identify_nslist(uint16_t ns) "identify namespace list, nsid=%"PRIu16""
702
+nvme_getfeat_vwcache(char const* result) "get feature volatile write cache, result=%s"
703
+nvme_getfeat_numq(int result) "get feature number of queues, result=%d"
704
+nvme_setfeat_numq(int reqcq, int reqsq, int gotcq, int gotsq) "requested cq_count=%d sq_count=%d, responding with cq_count=%d sq_count=%d"
705
+nvme_mmio_intm_set(uint64_t data, uint64_t new_mask) "wrote MMIO, interrupt mask set, data=0x%"PRIx64", new_mask=0x%"PRIx64""
706
+nvme_mmio_intm_clr(uint64_t data, uint64_t new_mask) "wrote MMIO, interrupt mask clr, data=0x%"PRIx64", new_mask=0x%"PRIx64""
707
+nvme_mmio_cfg(uint64_t data) "wrote MMIO, config controller config=0x%"PRIx64""
708
+nvme_mmio_aqattr(uint64_t data) "wrote MMIO, admin queue attributes=0x%"PRIx64""
709
+nvme_mmio_asqaddr(uint64_t data) "wrote MMIO, admin submission queue address=0x%"PRIx64""
710
+nvme_mmio_acqaddr(uint64_t data) "wrote MMIO, admin completion queue address=0x%"PRIx64""
711
+nvme_mmio_asqaddr_hi(uint64_t data, uint64_t new_addr) "wrote MMIO, admin submission queue high half=0x%"PRIx64", new_address=0x%"PRIx64""
712
+nvme_mmio_acqaddr_hi(uint64_t data, uint64_t new_addr) "wrote MMIO, admin completion queue high half=0x%"PRIx64", new_address=0x%"PRIx64""
713
+nvme_mmio_start_success(void) "setting controller enable bit succeeded"
714
+nvme_mmio_stopped(void) "cleared controller enable bit"
715
+nvme_mmio_shutdown_set(void) "shutdown bit set"
716
+nvme_mmio_shutdown_cleared(void) "shutdown bit cleared"
717
+
718
+# nvme traces for error conditions
719
+nvme_err_invalid_dma(void) "PRP/SGL is too small for transfer size"
720
+nvme_err_invalid_prplist_ent(uint64_t prplist) "PRP list entry is null or not page aligned: 0x%"PRIx64""
721
+nvme_err_invalid_prp2_align(uint64_t prp2) "PRP2 is not page aligned: 0x%"PRIx64""
722
+nvme_err_invalid_prp2_missing(void) "PRP2 is null and more data to be transferred"
723
+nvme_err_invalid_field(void) "invalid field"
724
+nvme_err_invalid_prp(void) "invalid PRP"
725
+nvme_err_invalid_sgl(void) "invalid SGL"
726
+nvme_err_invalid_ns(uint32_t ns, uint32_t limit) "invalid namespace %u not within 1-%u"
727
+nvme_err_invalid_opc(uint8_t opc) "invalid opcode 0x%"PRIx8""
728
+nvme_err_invalid_admin_opc(uint8_t opc) "invalid admin opcode 0x%"PRIx8""
729
+nvme_err_invalid_lba_range(uint64_t start, uint64_t len, uint64_t limit) "Invalid LBA start=%"PRIu64" len=%"PRIu64" limit=%"PRIu64""
730
+nvme_err_invalid_del_sq(uint16_t qid) "invalid submission queue deletion, sid=%"PRIu16""
731
+nvme_err_invalid_create_sq_cqid(uint16_t cqid) "failed creating submission queue, invalid cqid=%"PRIu16""
732
+nvme_err_invalid_create_sq_sqid(uint16_t sqid) "failed creating submission queue, invalid sqid=%"PRIu16""
733
+nvme_err_invalid_create_sq_size(uint16_t qsize) "failed creating submission queue, invalid qsize=%"PRIu16""
734
+nvme_err_invalid_create_sq_addr(uint64_t addr) "failed creating submission queue, addr=0x%"PRIx64""
735
+nvme_err_invalid_create_sq_qflags(uint16_t qflags) "failed creating submission queue, qflags=%"PRIu16""
736
+nvme_err_invalid_del_cq_cqid(uint16_t cqid) "failed deleting completion queue, cqid=%"PRIu16""
737
+nvme_err_invalid_del_cq_notempty(uint16_t cqid) "failed deleting completion queue, it is not empty, cqid=%"PRIu16""
738
+nvme_err_invalid_create_cq_cqid(uint16_t cqid) "failed creating completion queue, cqid=%"PRIu16""
739
+nvme_err_invalid_create_cq_size(uint16_t size) "failed creating completion queue, size=%"PRIu16""
740
+nvme_err_invalid_create_cq_addr(uint64_t addr) "failed creating completion queue, addr=0x%"PRIx64""
741
+nvme_err_invalid_create_cq_vector(uint16_t vector) "failed creating completion queue, vector=%"PRIu16""
742
+nvme_err_invalid_create_cq_qflags(uint16_t qflags) "failed creating completion queue, qflags=%"PRIu16""
743
+nvme_err_invalid_identify_cns(uint16_t cns) "identify, invalid cns=0x%"PRIx16""
744
+nvme_err_invalid_getfeat(int dw10) "invalid get features, dw10=0x%"PRIx32""
745
+nvme_err_invalid_setfeat(uint32_t dw10) "invalid set features, dw10=0x%"PRIx32""
746
+nvme_err_startfail_cq(void) "nvme_start_ctrl failed because there are non-admin completion queues"
747
+nvme_err_startfail_sq(void) "nvme_start_ctrl failed because there are non-admin submission queues"
748
+nvme_err_startfail_nbarasq(void) "nvme_start_ctrl failed because the admin submission queue address is null"
749
+nvme_err_startfail_nbaracq(void) "nvme_start_ctrl failed because the admin completion queue address is null"
750
+nvme_err_startfail_asq_misaligned(uint64_t addr) "nvme_start_ctrl failed because the admin submission queue address is misaligned: 0x%"PRIx64""
751
+nvme_err_startfail_acq_misaligned(uint64_t addr) "nvme_start_ctrl failed because the admin completion queue address is misaligned: 0x%"PRIx64""
752
+nvme_err_startfail_page_too_small(uint8_t log2ps, uint8_t maxlog2ps) "nvme_start_ctrl failed because the page size is too small: log2size=%u, min=%u"
753
+nvme_err_startfail_page_too_large(uint8_t log2ps, uint8_t maxlog2ps) "nvme_start_ctrl failed because the page size is too large: log2size=%u, max=%u"
754
+nvme_err_startfail_cqent_too_small(uint8_t log2ps, uint8_t maxlog2ps) "nvme_start_ctrl failed because the completion queue entry size is too small: log2size=%u, min=%u"
755
+nvme_err_startfail_cqent_too_large(uint8_t log2ps, uint8_t maxlog2ps) "nvme_start_ctrl failed because the completion queue entry size is too large: log2size=%u, max=%u"
756
+nvme_err_startfail_sqent_too_small(uint8_t log2ps, uint8_t maxlog2ps) "nvme_start_ctrl failed because the submission queue entry size is too small: log2size=%u, min=%u"
757
+nvme_err_startfail_sqent_too_large(uint8_t log2ps, uint8_t maxlog2ps) "nvme_start_ctrl failed because the submission queue entry size is too large: log2size=%u, max=%u"
758
+nvme_err_startfail_asqent_sz_zero(void) "nvme_start_ctrl failed because the admin submission queue size is zero"
759
+nvme_err_startfail_acqent_sz_zero(void) "nvme_start_ctrl failed because the admin completion queue size is zero"
760
+nvme_err_startfail(void) "setting controller enable bit failed"
761
+
762
+# Traces for undefined behavior
763
+nvme_ub_mmiowr_misaligned32(uint64_t offset) "MMIO write not 32-bit aligned, offset=0x%"PRIx64""
764
+nvme_ub_mmiowr_toosmall(uint64_t offset, unsigned size) "MMIO write smaller than 32 bits, offset=0x%"PRIx64", size=%u"
765
+nvme_ub_mmiowr_intmask_with_msix(void) "undefined access to interrupt mask set when MSI-X is enabled"
766
+nvme_ub_mmiowr_ro_csts(void) "attempted to set a read only bit of controller status"
767
+nvme_ub_mmiowr_ssreset_w1c_unsupported(void) "attempted to W1C CSTS.NSSRO but CAP.NSSRS is zero (not supported)"
768
+nvme_ub_mmiowr_ssreset_unsupported(void) "attempted NVM subsystem reset but CAP.NSSRS is zero (not supported)"
769
+nvme_ub_mmiowr_cmbloc_reserved(void) "invalid write to reserved CMBLOC when CMBSZ is zero, ignored"
770
+nvme_ub_mmiowr_cmbsz_readonly(void) "invalid write to read only CMBSZ, ignored"
771
+nvme_ub_mmiowr_invalid(uint64_t offset, uint64_t data) "invalid MMIO write, offset=0x%"PRIx64", data=0x%"PRIx64""
772
+nvme_ub_mmiord_misaligned32(uint64_t offset) "MMIO read not 32-bit aligned, offset=0x%"PRIx64""
773
+nvme_ub_mmiord_toosmall(uint64_t offset) "MMIO read smaller than 32-bits, offset=0x%"PRIx64""
774
+nvme_ub_mmiord_invalid_ofs(uint64_t offset) "MMIO read beyond last register, offset=0x%"PRIx64", returning 0"
775
+nvme_ub_db_wr_misaligned(uint64_t offset) "doorbell write not 32-bit aligned, offset=0x%"PRIx64", ignoring"
776
+nvme_ub_db_wr_invalid_cq(uint32_t qid) "completion queue doorbell write for nonexistent queue, cqid=%"PRIu32", ignoring"
777
+nvme_ub_db_wr_invalid_cqhead(uint32_t qid, uint16_t new_head) "completion queue doorbell write value beyond queue size, cqid=%"PRIu32", new_head=%"PRIu16", ignoring"
778
+nvme_ub_db_wr_invalid_sq(uint32_t qid) "submission queue doorbell write for nonexistent queue, sqid=%"PRIu32", ignoring"
779
+nvme_ub_db_wr_invalid_sqtail(uint32_t qid, uint16_t new_tail) "submission queue doorbell write value beyond queue size, sqid=%"PRIu32", new_head=%"PRIu16", ignoring"
780
+
781
# hw/block/xen_disk.c
782
xen_disk_alloc(char *name) "%s"
783
xen_disk_init(char *name) "%s"
784
--
785
2.13.6
786
787
diff view generated by jsdifflib
1
Even for block nodes with bs->drv == NULL, we can't just ignore a
1
From: Fam Zheng <famz@redhat.com>
2
bdrv_set_aio_context() call. Leaving the node in its old context can
3
mean that it's still in an iothread context in bdrv_close_all() during
4
shutdown, resulting in an attempted unlock of the AioContext lock which
5
we don't hold.
6
2
7
This is an example stack trace of a related crash:
3
Management tools create overlays of running guests with qemu-img:
8
4
9
#0 0x00007ffff59da57f in raise () at /lib64/libc.so.6
5
$ qemu-img create -b /image/in/use.qcow2 -f qcow2 /overlay/image.qcow2
10
#1 0x00007ffff59c4895 in abort () at /lib64/libc.so.6
11
#2 0x0000555555b97b1e in error_exit (err=<optimized out>, msg=msg@entry=0x555555d386d0 <__func__.19059> "qemu_mutex_unlock_impl") at util/qemu-thread-posix.c:36
12
#3 0x0000555555b97f7f in qemu_mutex_unlock_impl (mutex=mutex@entry=0x5555568002f0, file=file@entry=0x555555d378df "util/async.c", line=line@entry=507) at util/qemu-thread-posix.c:97
13
#4 0x0000555555b92f55 in aio_context_release (ctx=ctx@entry=0x555556800290) at util/async.c:507
14
#5 0x0000555555b05cf8 in bdrv_prwv_co (child=child@entry=0x7fffc80012f0, offset=offset@entry=131072, qiov=qiov@entry=0x7fffffffd4f0, is_write=is_write@entry=true, flags=flags@entry=0)
15
at block/io.c:833
16
#6 0x0000555555b060a9 in bdrv_pwritev (qiov=0x7fffffffd4f0, offset=131072, child=0x7fffc80012f0) at block/io.c:990
17
#7 0x0000555555b060a9 in bdrv_pwrite (child=0x7fffc80012f0, offset=131072, buf=<optimized out>, bytes=<optimized out>) at block/io.c:990
18
#8 0x0000555555ae172b in qcow2_cache_entry_flush (bs=bs@entry=0x555556810680, c=c@entry=0x5555568cc740, i=i@entry=0) at block/qcow2-cache.c:51
19
#9 0x0000555555ae18dd in qcow2_cache_write (bs=bs@entry=0x555556810680, c=0x5555568cc740) at block/qcow2-cache.c:248
20
#10 0x0000555555ae15de in qcow2_cache_flush (bs=0x555556810680, c=<optimized out>) at block/qcow2-cache.c:259
21
#11 0x0000555555ae16b1 in qcow2_cache_flush_dependency (c=0x5555568a1700, c=0x5555568a1700, bs=0x555556810680) at block/qcow2-cache.c:194
22
#12 0x0000555555ae16b1 in qcow2_cache_entry_flush (bs=bs@entry=0x555556810680, c=c@entry=0x5555568a1700, i=i@entry=0) at block/qcow2-cache.c:194
23
#13 0x0000555555ae18dd in qcow2_cache_write (bs=bs@entry=0x555556810680, c=0x5555568a1700) at block/qcow2-cache.c:248
24
#14 0x0000555555ae15de in qcow2_cache_flush (bs=bs@entry=0x555556810680, c=<optimized out>) at block/qcow2-cache.c:259
25
#15 0x0000555555ad242c in qcow2_inactivate (bs=bs@entry=0x555556810680) at block/qcow2.c:2124
26
#16 0x0000555555ad2590 in qcow2_close (bs=0x555556810680) at block/qcow2.c:2153
27
#17 0x0000555555ab0c62 in bdrv_close (bs=0x555556810680) at block.c:3358
28
#18 0x0000555555ab0c62 in bdrv_delete (bs=0x555556810680) at block.c:3542
29
#19 0x0000555555ab0c62 in bdrv_unref (bs=0x555556810680) at block.c:4598
30
#20 0x0000555555af4d72 in blk_remove_bs (blk=blk@entry=0x5555568103d0) at block/block-backend.c:785
31
#21 0x0000555555af4dbb in blk_remove_all_bs () at block/block-backend.c:483
32
#22 0x0000555555aae02f in bdrv_close_all () at block.c:3412
33
#23 0x00005555557f9796 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4776
34
6
35
The reproducer I used is a qcow2 image on gluster volume, where the
7
but this doesn't work anymore due to image locking:
36
virtual disk size (4 GB) is larger than the gluster volume size (64M),
37
so we can easily trigger an ENOSPC. This backend is assigned to a
38
virtio-blk device using an iothread, and then from the guest a
39
'dd if=/dev/zero of=/dev/vda bs=1G count=1' causes the VM to stop
40
because of an I/O error. qemu_gluster_co_flush_to_disk() sets
41
bs->drv = NULL on error, so when virtio-blk stops the dataplane, the
42
block nodes stay in the iothread AioContext. A 'quit' monitor command
43
issued from this paused state crashes the process.
44
8
45
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1631227
9
qemu-img: /overlay/image.qcow2: Failed to get shared "write" lock
10
Is another process using the image?
11
Could not open backing image to determine size.
12
Use the force share option to allow this use case again.
13
46
Cc: qemu-stable@nongnu.org
14
Cc: qemu-stable@nongnu.org
15
Signed-off-by: Fam Zheng <famz@redhat.com>
16
Reviewed-by: Eric Blake <eblake@redhat.com>
47
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
48
Reviewed-by: Eric Blake <eblake@redhat.com>
49
Reviewed-by: Max Reitz <mreitz@redhat.com>
50
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
51
---
18
---
52
block.c | 12 ++----------
19
block.c | 3 ++-
53
1 file changed, 2 insertions(+), 10 deletions(-)
20
1 file changed, 2 insertions(+), 1 deletion(-)
54
21
55
diff --git a/block.c b/block.c
22
diff --git a/block.c b/block.c
56
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
57
--- a/block.c
24
--- a/block.c
58
+++ b/block.c
25
+++ b/block.c
59
@@ -XXX,XX +XXX,XX @@ void bdrv_detach_aio_context(BlockDriverState *bs)
26
@@ -XXX,XX +XXX,XX @@ void bdrv_img_create(const char *filename, const char *fmt,
60
BdrvAioNotifier *baf, *baf_tmp;
27
back_flags = flags;
61
BdrvChild *child;
28
back_flags &= ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
62
29
63
- if (!bs->drv) {
30
+ backing_options = qdict_new();
64
- return;
31
if (backing_fmt) {
65
- }
32
- backing_options = qdict_new();
66
-
33
qdict_put_str(backing_options, "driver", backing_fmt);
67
assert(!bs->walking_aio_notifiers);
34
}
68
bs->walking_aio_notifiers = true;
35
+ qdict_put_bool(backing_options, BDRV_OPT_FORCE_SHARE, true);
69
QLIST_FOREACH_SAFE(baf, &bs->aio_notifiers, list, baf_tmp) {
36
70
@@ -XXX,XX +XXX,XX @@ void bdrv_detach_aio_context(BlockDriverState *bs)
37
bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
71
*/
38
&local_err);
72
bs->walking_aio_notifiers = false;
73
74
- if (bs->drv->bdrv_detach_aio_context) {
75
+ if (bs->drv && bs->drv->bdrv_detach_aio_context) {
76
bs->drv->bdrv_detach_aio_context(bs);
77
}
78
QLIST_FOREACH(child, &bs->children, next) {
79
@@ -XXX,XX +XXX,XX @@ void bdrv_attach_aio_context(BlockDriverState *bs,
80
BdrvAioNotifier *ban, *ban_tmp;
81
BdrvChild *child;
82
83
- if (!bs->drv) {
84
- return;
85
- }
86
-
87
if (bs->quiesce_counter) {
88
aio_disable_external(new_context);
89
}
90
@@ -XXX,XX +XXX,XX @@ void bdrv_attach_aio_context(BlockDriverState *bs,
91
QLIST_FOREACH(child, &bs->children, next) {
92
bdrv_attach_aio_context(child->bs, new_context);
93
}
94
- if (bs->drv->bdrv_attach_aio_context) {
95
+ if (bs->drv && bs->drv->bdrv_attach_aio_context) {
96
bs->drv->bdrv_attach_aio_context(bs, new_context);
97
}
98
99
--
39
--
100
2.20.1
40
2.13.6
101
41
102
42
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
3
It's not working anymore since QEMU v1.3.0 - time to remove it now.
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
5
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
7
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
9
---
8
block/backup.c | 14 ++++++--------
10
blockdev.c | 11 -----------
9
1 file changed, 6 insertions(+), 8 deletions(-)
11
qemu-doc.texi | 6 ------
12
2 files changed, 17 deletions(-)
10
13
11
diff --git a/block/backup.c b/block/backup.c
14
diff --git a/blockdev.c b/blockdev.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/block/backup.c
16
--- a/blockdev.c
14
+++ b/block/backup.c
17
+++ b/blockdev.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
18
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_legacy_drive_opts = {
16
void **bounce_buffer)
19
.type = QEMU_OPT_STRING,
17
{
20
.help = "chs translation (auto, lba, none)",
18
int ret;
21
},{
19
- QEMUIOVector qiov;
22
- .name = "boot",
20
BlockBackend *blk = job->common.blk;
23
- .type = QEMU_OPT_BOOL,
21
int nbytes;
24
- .help = "(deprecated, ignored)",
22
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
25
- },{
23
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
26
.name = "addr",
24
if (!*bounce_buffer) {
27
.type = QEMU_OPT_STRING,
25
*bounce_buffer = blk_blockalign(blk, job->cluster_size);
28
.help = "pci address (virtio only)",
26
}
29
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
27
- qemu_iovec_init_buf(&qiov, *bounce_buffer, nbytes);
28
29
- ret = blk_co_preadv(blk, start, qiov.size, &qiov, read_flags);
30
+ ret = blk_co_pread(blk, start, nbytes, *bounce_buffer, read_flags);
31
if (ret < 0) {
32
trace_backup_do_cow_read_fail(job, start, ret);
33
if (error_is_read) {
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
35
goto fail;
30
goto fail;
36
}
31
}
37
32
38
- if (qemu_iovec_is_zero(&qiov)) {
33
- /* Deprecated option boot=[on|off] */
39
+ if (buffer_is_zero(*bounce_buffer, nbytes)) {
34
- if (qemu_opt_get(legacy_opts, "boot") != NULL) {
40
ret = blk_co_pwrite_zeroes(job->target, start,
35
- fprintf(stderr, "qemu-kvm: boot=on|off is deprecated and will be "
41
- qiov.size, write_flags | BDRV_REQ_MAY_UNMAP);
36
- "ignored. Future versions will reject this parameter. Please "
42
+ nbytes, write_flags | BDRV_REQ_MAY_UNMAP);
37
- "update your scripts.\n");
43
} else {
38
- }
44
- ret = blk_co_pwritev(job->target, start,
39
-
45
- qiov.size, &qiov, write_flags |
40
/* Other deprecated options */
46
- (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
41
if (!qtest_enabled()) {
47
+ ret = blk_co_pwrite(job->target, start,
42
for (i = 0; i < ARRAY_SIZE(deprecated); i++) {
48
+ nbytes, *bounce_buffer, write_flags |
43
diff --git a/qemu-doc.texi b/qemu-doc.texi
49
+ (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
44
index XXXXXXX..XXXXXXX 100644
50
}
45
--- a/qemu-doc.texi
51
if (ret < 0) {
46
+++ b/qemu-doc.texi
52
trace_backup_do_cow_write_fail(job, start, ret);
47
@@ -XXX,XX +XXX,XX @@ deprecated.
48
49
@section System emulator command line arguments
50
51
-@subsection -drive boot=on|off (since 1.3.0)
52
-
53
-The ``boot=on|off'' option to the ``-drive'' argument is
54
-ignored. Applications should use the ``bootindex=N'' parameter
55
-to set an absolute ordering between devices instead.
56
-
57
@subsection -tdf (since 1.3.0)
58
59
The ``-tdf'' argument is ignored. The behaviour implemented
53
--
60
--
54
2.20.1
61
2.13.6
55
62
56
63
diff view generated by jsdifflib
New patch
1
1
From: Thomas Huth <thuth@redhat.com>
2
3
It's been marked as deprecated since QEMU v2.10.0, and so far nobody
4
complained that we should keep it, so let's remove this legacy option
5
now to simplify the code quite a bit.
6
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Markus Armbruster <armbru@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
vl.c | 86 ++-------------------------------------------------------
13
qemu-doc.texi | 8 ------
14
qemu-options.hx | 19 ++-----------
15
3 files changed, 4 insertions(+), 109 deletions(-)
16
17
diff --git a/vl.c b/vl.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/vl.c
20
+++ b/vl.c
21
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
22
const char *boot_order = NULL;
23
const char *boot_once = NULL;
24
DisplayState *ds;
25
- int cyls, heads, secs, translation;
26
QemuOpts *opts, *machine_opts;
27
- QemuOpts *hda_opts = NULL, *icount_opts = NULL, *accel_opts = NULL;
28
+ QemuOpts *icount_opts = NULL, *accel_opts = NULL;
29
QemuOptsList *olist;
30
int optind;
31
const char *optarg;
32
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
33
34
cpu_model = NULL;
35
snapshot = 0;
36
- cyls = heads = secs = 0;
37
- translation = BIOS_ATA_TRANSLATION_AUTO;
38
39
nb_nics = 0;
40
41
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
42
if (optind >= argc)
43
break;
44
if (argv[optind][0] != '-') {
45
- hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);
46
+ drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);
47
} else {
48
const QEMUOption *popt;
49
50
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
51
cpu_model = optarg;
52
break;
53
case QEMU_OPTION_hda:
54
- {
55
- char buf[256];
56
- if (cyls == 0)
57
- snprintf(buf, sizeof(buf), "%s", HD_OPTS);
58
- else
59
- snprintf(buf, sizeof(buf),
60
- "%s,cyls=%d,heads=%d,secs=%d%s",
61
- HD_OPTS , cyls, heads, secs,
62
- translation == BIOS_ATA_TRANSLATION_LBA ?
63
- ",trans=lba" :
64
- translation == BIOS_ATA_TRANSLATION_NONE ?
65
- ",trans=none" : "");
66
- drive_add(IF_DEFAULT, 0, optarg, buf);
67
- break;
68
- }
69
case QEMU_OPTION_hdb:
70
case QEMU_OPTION_hdc:
71
case QEMU_OPTION_hdd:
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
73
case QEMU_OPTION_snapshot:
74
snapshot = 1;
75
break;
76
- case QEMU_OPTION_hdachs:
77
- {
78
- const char *p;
79
- p = optarg;
80
- cyls = strtol(p, (char **)&p, 0);
81
- if (cyls < 1 || cyls > 16383)
82
- goto chs_fail;
83
- if (*p != ',')
84
- goto chs_fail;
85
- p++;
86
- heads = strtol(p, (char **)&p, 0);
87
- if (heads < 1 || heads > 16)
88
- goto chs_fail;
89
- if (*p != ',')
90
- goto chs_fail;
91
- p++;
92
- secs = strtol(p, (char **)&p, 0);
93
- if (secs < 1 || secs > 63)
94
- goto chs_fail;
95
- if (*p == ',') {
96
- p++;
97
- if (!strcmp(p, "large")) {
98
- translation = BIOS_ATA_TRANSLATION_LARGE;
99
- } else if (!strcmp(p, "rechs")) {
100
- translation = BIOS_ATA_TRANSLATION_RECHS;
101
- } else if (!strcmp(p, "none")) {
102
- translation = BIOS_ATA_TRANSLATION_NONE;
103
- } else if (!strcmp(p, "lba")) {
104
- translation = BIOS_ATA_TRANSLATION_LBA;
105
- } else if (!strcmp(p, "auto")) {
106
- translation = BIOS_ATA_TRANSLATION_AUTO;
107
- } else {
108
- goto chs_fail;
109
- }
110
- } else if (*p != '\0') {
111
- chs_fail:
112
- error_report("invalid physical CHS format");
113
- exit(1);
114
- }
115
- if (hda_opts != NULL) {
116
- qemu_opt_set_number(hda_opts, "cyls", cyls,
117
- &error_abort);
118
- qemu_opt_set_number(hda_opts, "heads", heads,
119
- &error_abort);
120
- qemu_opt_set_number(hda_opts, "secs", secs,
121
- &error_abort);
122
- if (translation == BIOS_ATA_TRANSLATION_LARGE) {
123
- qemu_opt_set(hda_opts, "trans", "large",
124
- &error_abort);
125
- } else if (translation == BIOS_ATA_TRANSLATION_RECHS) {
126
- qemu_opt_set(hda_opts, "trans", "rechs",
127
- &error_abort);
128
- } else if (translation == BIOS_ATA_TRANSLATION_LBA) {
129
- qemu_opt_set(hda_opts, "trans", "lba",
130
- &error_abort);
131
- } else if (translation == BIOS_ATA_TRANSLATION_NONE) {
132
- qemu_opt_set(hda_opts, "trans", "none",
133
- &error_abort);
134
- }
135
- }
136
- }
137
- error_report("'-hdachs' is deprecated, please use '-device"
138
- " ide-hd,cyls=c,heads=h,secs=s,...' instead");
139
- break;
140
case QEMU_OPTION_numa:
141
opts = qemu_opts_parse_noisily(qemu_find_opts("numa"),
142
optarg, true);
143
diff --git a/qemu-doc.texi b/qemu-doc.texi
144
index XXXXXXX..XXXXXXX 100644
145
--- a/qemu-doc.texi
146
+++ b/qemu-doc.texi
147
@@ -XXX,XX +XXX,XX @@ The ``--net dump'' argument is now replaced with the
148
``-object filter-dump'' argument which works in combination
149
with the modern ``-netdev`` backends instead.
150
151
-@subsection -hdachs (since 2.10.0)
152
-
153
-The ``-hdachs'' argument is now a synonym for setting
154
-the ``cyls'', ``heads'', ``secs'', and ``trans'' properties
155
-on the ``ide-hd'' device using the ``-device'' argument.
156
-The new syntax allows different settings to be provided
157
-per disk.
158
-
159
@subsection -usbdevice (since 2.10.0)
160
161
The ``-usbdevice DEV'' argument is now a synonym for setting
162
diff --git a/qemu-options.hx b/qemu-options.hx
163
index XXXXXXX..XXXXXXX 100644
164
--- a/qemu-options.hx
165
+++ b/qemu-options.hx
166
@@ -XXX,XX +XXX,XX @@ of available connectors of a given interface type.
167
@item media=@var{media}
168
This option defines the type of the media: disk or cdrom.
169
@item cyls=@var{c},heads=@var{h},secs=@var{s}[,trans=@var{t}]
170
-These options have the same definition as they have in @option{-hdachs}.
171
-These parameters are deprecated, use the corresponding parameters
172
+Force disk physical geometry and the optional BIOS translation (trans=none or
173
+lba). These parameters are deprecated, use the corresponding parameters
174
of @code{-device} instead.
175
@item snapshot=@var{snapshot}
176
@var{snapshot} is "on" or "off" and controls snapshot mode for the given drive
177
@@ -XXX,XX +XXX,XX @@ the raw disk image you use is not written back. You can however force
178
the write back by pressing @key{C-a s} (@pxref{disk_images}).
179
ETEXI
180
181
-DEF("hdachs", HAS_ARG, QEMU_OPTION_hdachs, \
182
- "-hdachs c,h,s[,t]\n" \
183
- " force hard disk 0 physical geometry and the optional BIOS\n" \
184
- " translation (t=none or lba) (usually QEMU can guess them)\n",
185
- QEMU_ARCH_ALL)
186
-STEXI
187
-@item -hdachs @var{c},@var{h},@var{s},[,@var{t}]
188
-@findex -hdachs
189
-Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <=
190
-@var{h} <= 16, 1 <= @var{s} <= 63) and optionally force the BIOS
191
-translation mode (@var{t}=none, lba or auto). Usually QEMU can guess
192
-all those parameters. This option is deprecated, please use
193
-@code{-device ide-hd,cyls=c,heads=h,secs=s,...} instead.
194
-ETEXI
195
-
196
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
197
"-fsdev fsdriver,id=id[,path=path,][security_model={mapped-xattr|mapped-file|passthrough|none}]\n"
198
" [,writeout=immediate][,readonly][,socket=socket|sock_fd=sock_fd][,fmode=fmode][,dmode=dmode]\n"
199
--
200
2.13.6
201
202
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
One of the recent commits changed the way qemu-io prints out its
3
Looks like we forgot to announce the deprecation of these options in
4
errors and warnings - they are now prefixed with the program name.
4
the corresponding chapter of the qemu-doc text, so let's do that now.
5
We've got to adapt the iotests accordingly to prevent that they
6
are failing.
7
5
8
Fixes: 99e98d7c9fc1a1639fad ("qemu-io: Use error_[gs]et_progname()")
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: John Snow <jsnow@redhat.com>
8
Reviewed-by: Markus Armbruster <armbru@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
10
---
12
tests/qemu-iotests/026.out | 168 ++++++++++++++++++-------------------
11
qemu-doc.texi | 15 +++++++++++++++
13
tests/qemu-iotests/060.out | 6 +-
12
1 file changed, 15 insertions(+)
14
tests/qemu-iotests/069.out | 2 +-
15
tests/qemu-iotests/070.out | 2 +-
16
tests/qemu-iotests/075.out | 14 ++--
17
tests/qemu-iotests/076.out | 6 +-
18
tests/qemu-iotests/078.out | 12 +--
19
tests/qemu-iotests/080.out | 40 ++++-----
20
tests/qemu-iotests/081.out | 2 +-
21
tests/qemu-iotests/088.out | 12 +--
22
tests/qemu-iotests/103.out | 14 ++--
23
tests/qemu-iotests/114.out | 2 +-
24
tests/qemu-iotests/116.out | 14 ++--
25
tests/qemu-iotests/131.out | 2 +-
26
tests/qemu-iotests/133.out | 30 +++----
27
tests/qemu-iotests/137.out | 28 +++----
28
tests/qemu-iotests/140.out | 2 +-
29
tests/qemu-iotests/143.out | 2 +-
30
tests/qemu-iotests/153.out | 30 +++----
31
tests/qemu-iotests/187.out | 6 +-
32
tests/qemu-iotests/188.out | 2 +-
33
tests/qemu-iotests/197.out | 2 +-
34
tests/qemu-iotests/205 | 2 +-
35
tests/qemu-iotests/215.out | 2 +-
36
tests/qemu-iotests/226.out | 16 ++--
37
tests/qemu-iotests/244.out | 10 +--
38
26 files changed, 214 insertions(+), 214 deletions(-)
39
13
40
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
14
diff --git a/qemu-doc.texi b/qemu-doc.texi
41
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
42
--- a/tests/qemu-iotests/026.out
16
--- a/qemu-doc.texi
43
+++ b/tests/qemu-iotests/026.out
17
+++ b/qemu-doc.texi
44
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
18
@@ -XXX,XX +XXX,XX @@ longer be directly supported in QEMU.
45
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
19
The ``-drive if=scsi'' argument is replaced by the the
46
20
``-device BUS-TYPE'' argument combined with ``-drive if=none''.
47
Event: l1_update; errno: 5; imm: off; once: off; write
21
48
-Failed to flush the L2 table cache: Input/output error
22
+@subsection -drive cyls=...,heads=...,secs=...,trans=... (since 2.10.0)
49
-Failed to flush the refcount block cache: Input/output error
23
+
50
+qemu-io: Failed to flush the L2 table cache: Input/output error
24
+The drive geometry arguments are replaced by the the geometry arguments
51
+qemu-io: Failed to flush the refcount block cache: Input/output error
25
+that can be specified with the ``-device'' parameter.
52
write failed: Input/output error
26
+
53
27
+@subsection -drive serial=... (since 2.10.0)
54
1 leaked clusters were found on the image.
28
+
55
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
29
+The drive serial argument is replaced by the the serial argument
56
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
30
+that can be specified with the ``-device'' parameter.
57
31
+
58
Event: l1_update; errno: 5; imm: off; once: off; write -b
32
+@subsection -drive addr=... (since 2.10.0)
59
-Failed to flush the L2 table cache: Input/output error
33
+
60
-Failed to flush the refcount block cache: Input/output error
34
+The drive addr argument is replaced by the the addr argument
61
+qemu-io: Failed to flush the L2 table cache: Input/output error
35
+that can be specified with the ``-device'' parameter.
62
+qemu-io: Failed to flush the refcount block cache: Input/output error
36
+
63
write failed: Input/output error
37
@subsection -net dump (since 2.10.0)
64
38
65
1 leaked clusters were found on the image.
39
The ``--net dump'' argument is now replaced with the
66
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
67
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
68
69
Event: l1_update; errno: 28; imm: off; once: off; write
70
-Failed to flush the L2 table cache: No space left on device
71
-Failed to flush the refcount block cache: No space left on device
72
+qemu-io: Failed to flush the L2 table cache: No space left on device
73
+qemu-io: Failed to flush the refcount block cache: No space left on device
74
write failed: No space left on device
75
76
1 leaked clusters were found on the image.
77
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
78
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
79
80
Event: l1_update; errno: 28; imm: off; once: off; write -b
81
-Failed to flush the L2 table cache: No space left on device
82
-Failed to flush the refcount block cache: No space left on device
83
+qemu-io: Failed to flush the L2 table cache: No space left on device
84
+qemu-io: Failed to flush the refcount block cache: No space left on device
85
write failed: No space left on device
86
87
1 leaked clusters were found on the image.
88
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
89
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
90
91
Event: l2_update; errno: 5; imm: off; once: off; write
92
-Failed to flush the L2 table cache: Input/output error
93
-Failed to flush the refcount block cache: Input/output error
94
+qemu-io: Failed to flush the L2 table cache: Input/output error
95
+qemu-io: Failed to flush the refcount block cache: Input/output error
96
write failed: Input/output error
97
98
127 leaked clusters were found on the image.
99
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
100
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
101
102
Event: l2_update; errno: 5; imm: off; once: off; write -b
103
-Failed to flush the L2 table cache: Input/output error
104
-Failed to flush the refcount block cache: Input/output error
105
+qemu-io: Failed to flush the L2 table cache: Input/output error
106
+qemu-io: Failed to flush the refcount block cache: Input/output error
107
write failed: Input/output error
108
109
127 leaked clusters were found on the image.
110
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
111
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
112
113
Event: l2_update; errno: 28; imm: off; once: off; write
114
-Failed to flush the L2 table cache: No space left on device
115
-Failed to flush the refcount block cache: No space left on device
116
+qemu-io: Failed to flush the L2 table cache: No space left on device
117
+qemu-io: Failed to flush the refcount block cache: No space left on device
118
write failed: No space left on device
119
120
127 leaked clusters were found on the image.
121
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
122
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
123
124
Event: l2_update; errno: 28; imm: off; once: off; write -b
125
-Failed to flush the L2 table cache: No space left on device
126
-Failed to flush the refcount block cache: No space left on device
127
+qemu-io: Failed to flush the L2 table cache: No space left on device
128
+qemu-io: Failed to flush the refcount block cache: No space left on device
129
write failed: No space left on device
130
131
127 leaked clusters were found on the image.
132
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
133
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
134
135
Event: l2_alloc_write; errno: 5; imm: off; once: off; write
136
-Failed to flush the L2 table cache: Input/output error
137
-Failed to flush the refcount block cache: Input/output error
138
+qemu-io: Failed to flush the L2 table cache: Input/output error
139
+qemu-io: Failed to flush the refcount block cache: Input/output error
140
write failed: Input/output error
141
No errors were found on the image.
142
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
143
144
Event: l2_alloc_write; errno: 5; imm: off; once: off; write -b
145
-Failed to flush the L2 table cache: Input/output error
146
-Failed to flush the refcount block cache: Input/output error
147
+qemu-io: Failed to flush the L2 table cache: Input/output error
148
+qemu-io: Failed to flush the refcount block cache: Input/output error
149
write failed: Input/output error
150
151
1 leaked clusters were found on the image.
152
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
153
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
154
155
Event: l2_alloc_write; errno: 28; imm: off; once: off; write
156
-Failed to flush the L2 table cache: No space left on device
157
-Failed to flush the refcount block cache: No space left on device
158
+qemu-io: Failed to flush the L2 table cache: No space left on device
159
+qemu-io: Failed to flush the refcount block cache: No space left on device
160
write failed: No space left on device
161
No errors were found on the image.
162
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
163
164
Event: l2_alloc_write; errno: 28; imm: off; once: off; write -b
165
-Failed to flush the L2 table cache: No space left on device
166
-Failed to flush the refcount block cache: No space left on device
167
+qemu-io: Failed to flush the L2 table cache: No space left on device
168
+qemu-io: Failed to flush the refcount block cache: No space left on device
169
write failed: No space left on device
170
171
1 leaked clusters were found on the image.
172
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
173
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
174
175
Event: write_aio; errno: 5; imm: off; once: off; write
176
-Failed to flush the L2 table cache: Input/output error
177
-Failed to flush the refcount block cache: Input/output error
178
+qemu-io: Failed to flush the L2 table cache: Input/output error
179
+qemu-io: Failed to flush the refcount block cache: Input/output error
180
write failed: Input/output error
181
No errors were found on the image.
182
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
183
184
Event: write_aio; errno: 5; imm: off; once: off; write -b
185
-Failed to flush the L2 table cache: Input/output error
186
-Failed to flush the refcount block cache: Input/output error
187
+qemu-io: Failed to flush the L2 table cache: Input/output error
188
+qemu-io: Failed to flush the refcount block cache: Input/output error
189
write failed: Input/output error
190
No errors were found on the image.
191
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
192
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
193
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
194
195
Event: write_aio; errno: 28; imm: off; once: off; write
196
-Failed to flush the L2 table cache: No space left on device
197
-Failed to flush the refcount block cache: No space left on device
198
+qemu-io: Failed to flush the L2 table cache: No space left on device
199
+qemu-io: Failed to flush the refcount block cache: No space left on device
200
write failed: No space left on device
201
No errors were found on the image.
202
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
203
204
Event: write_aio; errno: 28; imm: off; once: off; write -b
205
-Failed to flush the L2 table cache: No space left on device
206
-Failed to flush the refcount block cache: No space left on device
207
+qemu-io: Failed to flush the L2 table cache: No space left on device
208
+qemu-io: Failed to flush the refcount block cache: No space left on device
209
write failed: No space left on device
210
No errors were found on the image.
211
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
212
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
213
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
214
215
Event: refblock_load; errno: 5; imm: off; once: off; write
216
-Failed to flush the L2 table cache: Input/output error
217
-Failed to flush the refcount block cache: Input/output error
218
+qemu-io: Failed to flush the L2 table cache: Input/output error
219
+qemu-io: Failed to flush the refcount block cache: Input/output error
220
write failed: Input/output error
221
No errors were found on the image.
222
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
223
224
Event: refblock_load; errno: 5; imm: off; once: off; write -b
225
-Failed to flush the L2 table cache: Input/output error
226
-Failed to flush the refcount block cache: Input/output error
227
+qemu-io: Failed to flush the L2 table cache: Input/output error
228
+qemu-io: Failed to flush the refcount block cache: Input/output error
229
write failed: Input/output error
230
No errors were found on the image.
231
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
232
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
233
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
234
235
Event: refblock_load; errno: 28; imm: off; once: off; write
236
-Failed to flush the L2 table cache: No space left on device
237
-Failed to flush the refcount block cache: No space left on device
238
+qemu-io: Failed to flush the L2 table cache: No space left on device
239
+qemu-io: Failed to flush the refcount block cache: No space left on device
240
write failed: No space left on device
241
No errors were found on the image.
242
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
243
244
Event: refblock_load; errno: 28; imm: off; once: off; write -b
245
-Failed to flush the L2 table cache: No space left on device
246
-Failed to flush the refcount block cache: No space left on device
247
+qemu-io: Failed to flush the L2 table cache: No space left on device
248
+qemu-io: Failed to flush the refcount block cache: No space left on device
249
write failed: No space left on device
250
No errors were found on the image.
251
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
252
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
253
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
254
255
Event: refblock_update_part; errno: 5; imm: off; once: off; write
256
-Failed to flush the L2 table cache: Input/output error
257
-Failed to flush the refcount block cache: Input/output error
258
+qemu-io: Failed to flush the L2 table cache: Input/output error
259
+qemu-io: Failed to flush the refcount block cache: Input/output error
260
write failed: Input/output error
261
No errors were found on the image.
262
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
263
264
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
265
-Failed to flush the L2 table cache: Input/output error
266
-Failed to flush the refcount block cache: Input/output error
267
+qemu-io: Failed to flush the L2 table cache: Input/output error
268
+qemu-io: Failed to flush the refcount block cache: Input/output error
269
write failed: Input/output error
270
No errors were found on the image.
271
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
272
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
273
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
274
275
Event: refblock_update_part; errno: 28; imm: off; once: off; write
276
-Failed to flush the L2 table cache: No space left on device
277
-Failed to flush the refcount block cache: No space left on device
278
+qemu-io: Failed to flush the L2 table cache: No space left on device
279
+qemu-io: Failed to flush the refcount block cache: No space left on device
280
write failed: No space left on device
281
No errors were found on the image.
282
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
283
284
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
285
-Failed to flush the L2 table cache: No space left on device
286
-Failed to flush the refcount block cache: No space left on device
287
+qemu-io: Failed to flush the L2 table cache: No space left on device
288
+qemu-io: Failed to flush the refcount block cache: No space left on device
289
write failed: No space left on device
290
No errors were found on the image.
291
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
292
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
293
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
294
295
Event: refblock_alloc; errno: 5; imm: off; once: off; write
296
-Failed to flush the L2 table cache: Input/output error
297
-Failed to flush the refcount block cache: Input/output error
298
+qemu-io: Failed to flush the L2 table cache: Input/output error
299
+qemu-io: Failed to flush the refcount block cache: Input/output error
300
write failed: Input/output error
301
No errors were found on the image.
302
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
303
304
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
305
-Failed to flush the L2 table cache: Input/output error
306
-Failed to flush the refcount block cache: Input/output error
307
+qemu-io: Failed to flush the L2 table cache: Input/output error
308
+qemu-io: Failed to flush the refcount block cache: Input/output error
309
write failed: Input/output error
310
No errors were found on the image.
311
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
312
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
313
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
314
315
Event: refblock_alloc; errno: 28; imm: off; once: off; write
316
-Failed to flush the L2 table cache: No space left on device
317
-Failed to flush the refcount block cache: No space left on device
318
+qemu-io: Failed to flush the L2 table cache: No space left on device
319
+qemu-io: Failed to flush the refcount block cache: No space left on device
320
write failed: No space left on device
321
No errors were found on the image.
322
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
323
324
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
325
-Failed to flush the L2 table cache: No space left on device
326
-Failed to flush the refcount block cache: No space left on device
327
+qemu-io: Failed to flush the L2 table cache: No space left on device
328
+qemu-io: Failed to flush the refcount block cache: No space left on device
329
write failed: No space left on device
330
No errors were found on the image.
331
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
332
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
333
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
334
335
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write
336
-Failed to flush the L2 table cache: No space left on device
337
-Failed to flush the refcount block cache: No space left on device
338
+qemu-io: Failed to flush the L2 table cache: No space left on device
339
+qemu-io: Failed to flush the refcount block cache: No space left on device
340
write failed: No space left on device
341
342
55 leaked clusters were found on the image.
343
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
344
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
345
346
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write -b
347
-Failed to flush the L2 table cache: No space left on device
348
-Failed to flush the refcount block cache: No space left on device
349
+qemu-io: Failed to flush the L2 table cache: No space left on device
350
+qemu-io: Failed to flush the refcount block cache: No space left on device
351
write failed: No space left on device
352
353
251 leaked clusters were found on the image.
354
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
355
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
356
357
Event: refblock_alloc_write; errno: 28; imm: off; once: off; write
358
-Failed to flush the L2 table cache: No space left on device
359
-Failed to flush the refcount block cache: No space left on device
360
+qemu-io: Failed to flush the L2 table cache: No space left on device
361
+qemu-io: Failed to flush the refcount block cache: No space left on device
362
write failed: No space left on device
363
No errors were found on the image.
364
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
365
366
Event: refblock_alloc_write; errno: 28; imm: off; once: off; write -b
367
-Failed to flush the L2 table cache: No space left on device
368
-Failed to flush the refcount block cache: No space left on device
369
+qemu-io: Failed to flush the L2 table cache: No space left on device
370
+qemu-io: Failed to flush the refcount block cache: No space left on device
371
write failed: No space left on device
372
No errors were found on the image.
373
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
374
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
375
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
376
377
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
378
-Failed to flush the L2 table cache: No space left on device
379
-Failed to flush the refcount block cache: No space left on device
380
+qemu-io: Failed to flush the L2 table cache: No space left on device
381
+qemu-io: Failed to flush the refcount block cache: No space left on device
382
write failed: No space left on device
383
384
10 leaked clusters were found on the image.
385
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
386
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
387
388
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
389
-Failed to flush the L2 table cache: No space left on device
390
-Failed to flush the refcount block cache: No space left on device
391
+qemu-io: Failed to flush the L2 table cache: No space left on device
392
+qemu-io: Failed to flush the refcount block cache: No space left on device
393
write failed: No space left on device
394
395
23 leaked clusters were found on the image.
396
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
397
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
398
399
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
400
-Failed to flush the L2 table cache: No space left on device
401
-Failed to flush the refcount block cache: No space left on device
402
+qemu-io: Failed to flush the L2 table cache: No space left on device
403
+qemu-io: Failed to flush the refcount block cache: No space left on device
404
write failed: No space left on device
405
406
10 leaked clusters were found on the image.
407
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
408
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
409
410
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
411
-Failed to flush the L2 table cache: No space left on device
412
-Failed to flush the refcount block cache: No space left on device
413
+qemu-io: Failed to flush the L2 table cache: No space left on device
414
+qemu-io: Failed to flush the refcount block cache: No space left on device
415
write failed: No space left on device
416
417
23 leaked clusters were found on the image.
418
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
419
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
420
421
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write
422
-Failed to flush the L2 table cache: No space left on device
423
-Failed to flush the refcount block cache: No space left on device
424
+qemu-io: Failed to flush the L2 table cache: No space left on device
425
+qemu-io: Failed to flush the refcount block cache: No space left on device
426
write failed: No space left on device
427
428
10 leaked clusters were found on the image.
429
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
430
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
431
432
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write -b
433
-Failed to flush the L2 table cache: No space left on device
434
-Failed to flush the refcount block cache: No space left on device
435
+qemu-io: Failed to flush the L2 table cache: No space left on device
436
+qemu-io: Failed to flush the refcount block cache: No space left on device
437
write failed: No space left on device
438
439
23 leaked clusters were found on the image.
440
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
441
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
442
443
Event: l1_grow_write_table; errno: 5; imm: off; once: off
444
-Failed to flush the L2 table cache: Input/output error
445
-Failed to flush the refcount block cache: Input/output error
446
+qemu-io: Failed to flush the L2 table cache: Input/output error
447
+qemu-io: Failed to flush the refcount block cache: Input/output error
448
write failed: Input/output error
449
No errors were found on the image.
450
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
451
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
452
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
453
454
Event: l1_grow_write_table; errno: 28; imm: off; once: off
455
-Failed to flush the L2 table cache: No space left on device
456
-Failed to flush the refcount block cache: No space left on device
457
+qemu-io: Failed to flush the L2 table cache: No space left on device
458
+qemu-io: Failed to flush the refcount block cache: No space left on device
459
write failed: No space left on device
460
No errors were found on the image.
461
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
462
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
463
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
464
465
Event: l1_grow_activate_table; errno: 5; imm: off; once: off
466
-Failed to flush the L2 table cache: Input/output error
467
-Failed to flush the refcount block cache: Input/output error
468
+qemu-io: Failed to flush the L2 table cache: Input/output error
469
+qemu-io: Failed to flush the refcount block cache: Input/output error
470
write failed: Input/output error
471
472
96 leaked clusters were found on the image.
473
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
474
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
475
476
Event: l1_grow_activate_table; errno: 28; imm: off; once: off
477
-Failed to flush the L2 table cache: No space left on device
478
-Failed to flush the refcount block cache: No space left on device
479
+qemu-io: Failed to flush the L2 table cache: No space left on device
480
+qemu-io: Failed to flush the refcount block cache: No space left on device
481
write failed: No space left on device
482
483
96 leaked clusters were found on the image.
484
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
485
index XXXXXXX..XXXXXXX 100644
486
--- a/tests/qemu-iotests/060.out
487
+++ b/tests/qemu-iotests/060.out
488
@@ -XXX,XX +XXX,XX @@ Format specific information:
489
lazy refcounts: false
490
refcount bits: 16
491
corrupt: true
492
-can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
493
+qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
494
no file open, try 'help open'
495
read 512/512 bytes at offset 0
496
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
497
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
498
=== Testing zero refcount table size ===
499
500
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
501
-can't open device TEST_DIR/t.IMGFMT: Image does not contain a reference count table
502
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Image does not contain a reference count table
503
ERROR cluster 0 refcount=0 reference=1
504
ERROR cluster 3 refcount=0 reference=1
505
Rebuilding refcount structure
506
@@ -XXX,XX +XXX,XX @@ Can't get refcount for cluster 2: Input/output error
507
Can't get refcount for cluster 3: Input/output error
508
Rebuilding refcount structure
509
Repairing cluster 1 refcount=1 reference=0
510
-can't open device TEST_DIR/t.IMGFMT: Could not repair dirty image: Input/output error
511
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not repair dirty image: Input/output error
512
--- Repairing ---
513
Leaked cluster 1 refcount=1 reference=0
514
Repairing cluster 1 refcount=1 reference=0
515
diff --git a/tests/qemu-iotests/069.out b/tests/qemu-iotests/069.out
516
index XXXXXXX..XXXXXXX 100644
517
--- a/tests/qemu-iotests/069.out
518
+++ b/tests/qemu-iotests/069.out
519
@@ -XXX,XX +XXX,XX @@ QA output created by 069
520
521
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=131072
522
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file=TEST_DIR/t.IMGFMT.base
523
-can't open device TEST_DIR/t.IMGFMT: Could not open backing file: Could not open 'TEST_DIR/t.IMGFMT.base': No such file or directory
524
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open backing file: Could not open 'TEST_DIR/t.IMGFMT.base': No such file or directory
525
*** done
526
diff --git a/tests/qemu-iotests/070.out b/tests/qemu-iotests/070.out
527
index XXXXXXX..XXXXXXX 100644
528
--- a/tests/qemu-iotests/070.out
529
+++ b/tests/qemu-iotests/070.out
530
@@ -XXX,XX +XXX,XX @@
531
QA output created by 070
532
533
=== Verify open image read-only fails, due to dirty log ===
534
-can't open device TEST_DIR/iotest-dirtylog-10G-4M.vhdx: VHDX image file 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx' opened read-only, but contains a log that needs to be replayed
535
+qemu-io: can't open device TEST_DIR/iotest-dirtylog-10G-4M.vhdx: VHDX image file 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx' opened read-only, but contains a log that needs to be replayed
536
To replay the log, run:
537
qemu-img check -r all 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx'
538
=== Verify open image replays log ===
539
diff --git a/tests/qemu-iotests/075.out b/tests/qemu-iotests/075.out
540
index XXXXXXX..XXXXXXX 100644
541
--- a/tests/qemu-iotests/075.out
542
+++ b/tests/qemu-iotests/075.out
543
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 1048064
544
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
545
546
== block_size must be a multiple of 512 ==
547
-can't open device TEST_DIR/simple-pattern.cloop: block_size 513 must be a multiple of 512
548
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: block_size 513 must be a multiple of 512
549
550
== block_size cannot be zero ==
551
-can't open device TEST_DIR/simple-pattern.cloop: block_size cannot be zero
552
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: block_size cannot be zero
553
554
== huge block_size ===
555
-can't open device TEST_DIR/simple-pattern.cloop: block_size 4294966784 must be 64 MB or less
556
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: block_size 4294966784 must be 64 MB or less
557
558
== offsets_size overflow ===
559
-can't open device TEST_DIR/simple-pattern.cloop: n_blocks 4294967295 must be 536870911 or less
560
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: n_blocks 4294967295 must be 536870911 or less
561
562
== refuse images that require too many offsets ===
563
-can't open device TEST_DIR/simple-pattern.cloop: image requires too many offsets, try increasing block size
564
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: image requires too many offsets, try increasing block size
565
566
== refuse images with non-monotonically increasing offsets ==
567
-can't open device TEST_DIR/simple-pattern.cloop: offsets not monotonically increasing at index 1, image file is corrupt
568
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: offsets not monotonically increasing at index 1, image file is corrupt
569
570
== refuse images with invalid compressed block size ==
571
-can't open device TEST_DIR/simple-pattern.cloop: invalid compressed block size at index 1, image file is corrupt
572
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: invalid compressed block size at index 1, image file is corrupt
573
*** done
574
diff --git a/tests/qemu-iotests/076.out b/tests/qemu-iotests/076.out
575
index XXXXXXX..XXXXXXX 100644
576
--- a/tests/qemu-iotests/076.out
577
+++ b/tests/qemu-iotests/076.out
578
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
579
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
580
581
== Negative catalog size ==
582
-can't open device TEST_DIR/parallels-v1: Catalog too large
583
+qemu-io: can't open device TEST_DIR/parallels-v1: Catalog too large
584
585
== Overflow in catalog allocation ==
586
-can't open device TEST_DIR/parallels-v1: Catalog too large
587
+qemu-io: can't open device TEST_DIR/parallels-v1: Catalog too large
588
589
== Zero sectors per track ==
590
-can't open device TEST_DIR/parallels-v1: Invalid image: Zero sectors per track
591
+qemu-io: can't open device TEST_DIR/parallels-v1: Invalid image: Zero sectors per track
592
593
== Read from a valid v2 image ==
594
read 65536/65536 bytes at offset 0
595
diff --git a/tests/qemu-iotests/078.out b/tests/qemu-iotests/078.out
596
index XXXXXXX..XXXXXXX 100644
597
--- a/tests/qemu-iotests/078.out
598
+++ b/tests/qemu-iotests/078.out
599
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
600
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
601
602
== Negative catalog size ==
603
-can't open device TEST_DIR/empty.bochs: Catalog size is too large
604
+qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too large
605
606
== Overflow for catalog size * sizeof(uint32_t) ==
607
-can't open device TEST_DIR/empty.bochs: Catalog size is too large
608
+qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too large
609
610
== Too small catalog bitmap for image size ==
611
-can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
612
-can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
613
+qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
614
+qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
615
616
== Negative extent size ==
617
-can't open device TEST_DIR/empty.bochs: Extent size 2147483648 is too large
618
+qemu-io: can't open device TEST_DIR/empty.bochs: Extent size 2147483648 is too large
619
620
== Zero extent size ==
621
-can't open device TEST_DIR/empty.bochs: Extent size must be at least 512
622
+qemu-io: can't open device TEST_DIR/empty.bochs: Extent size must be at least 512
623
*** done
624
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
625
index XXXXXXX..XXXXXXX 100644
626
--- a/tests/qemu-iotests/080.out
627
+++ b/tests/qemu-iotests/080.out
628
@@ -XXX,XX +XXX,XX @@ QA output created by 080
629
630
== Huge header size ==
631
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
632
-can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
633
-can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
634
+qemu-io: can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
635
+qemu-io: can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
636
637
== Huge unknown header extension ==
638
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
639
-can't open device TEST_DIR/t.qcow2: Invalid backing file offset
640
-can't open device TEST_DIR/t.qcow2: Header extension too large
641
-can't open device TEST_DIR/t.qcow2: Header extension too large
642
+qemu-io: can't open device TEST_DIR/t.qcow2: Invalid backing file offset
643
+qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
644
+qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
645
646
== Huge refcount table size ==
647
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
648
-can't open device TEST_DIR/t.qcow2: Reference count table too large
649
-can't open device TEST_DIR/t.qcow2: Reference count table too large
650
+qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table too large
651
+qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table too large
652
653
== Misaligned refcount table ==
654
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
655
-can't open device TEST_DIR/t.qcow2: Reference count table offset invalid
656
+qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table offset invalid
657
658
== Huge refcount offset ==
659
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
660
-can't open device TEST_DIR/t.qcow2: Reference count table offset invalid
661
+qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table offset invalid
662
663
== Invalid snapshot table ==
664
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
665
-can't open device TEST_DIR/t.qcow2: Snapshot table too large
666
-can't open device TEST_DIR/t.qcow2: Snapshot table too large
667
-can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
668
-can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
669
+qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table too large
670
+qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table too large
671
+qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
672
+qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
673
674
== Hitting snapshot table size limit ==
675
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
676
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
677
678
== Invalid L1 table ==
679
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
680
-can't open device TEST_DIR/t.qcow2: Active L1 table too large
681
-can't open device TEST_DIR/t.qcow2: Active L1 table too large
682
-can't open device TEST_DIR/t.qcow2: Active L1 table offset invalid
683
-can't open device TEST_DIR/t.qcow2: Active L1 table offset invalid
684
+qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table too large
685
+qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table too large
686
+qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table offset invalid
687
+qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table offset invalid
688
689
== Invalid L1 table (with internal snapshot in the image) ==
690
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
691
@@ -XXX,XX +XXX,XX @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': L1 table is too small
692
693
== Invalid backing file size ==
694
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
695
-can't open device TEST_DIR/t.qcow2: Backing file name too long
696
+qemu-io: can't open device TEST_DIR/t.qcow2: Backing file name too long
697
698
== Invalid L2 entry (huge physical offset) ==
699
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
700
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 0
701
qemu-img: Failed to load snapshot: Snapshot L1 table offset invalid
702
qemu-img: Snapshot L1 table offset invalid
703
qemu-img: Failed to turn zero into data clusters: Invalid argument
704
-Failed to flush the refcount block cache: Invalid argument
705
+qemu-io: Failed to flush the refcount block cache: Invalid argument
706
write failed: Invalid argument
707
qemu-img: Snapshot L1 table offset invalid
708
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: Invalid argument
709
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 0
710
qemu-img: Failed to load snapshot: Snapshot L1 table too large
711
qemu-img: Snapshot L1 table too large
712
qemu-img: Failed to turn zero into data clusters: File too large
713
-Failed to flush the refcount block cache: File too large
714
+qemu-io: Failed to flush the refcount block cache: File too large
715
write failed: File too large
716
qemu-img: Snapshot L1 table too large
717
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: File too large
718
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
719
index XXXXXXX..XXXXXXX 100644
720
--- a/tests/qemu-iotests/081.out
721
+++ b/tests/qemu-iotests/081.out
722
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
723
10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
724
725
== checking the blkverify mode with invalid settings ==
726
-can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
727
+qemu-io: can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
728
729
== dynamically adding a child to a quorum ==
730
Testing:
731
diff --git a/tests/qemu-iotests/088.out b/tests/qemu-iotests/088.out
732
index XXXXXXX..XXXXXXX 100644
733
--- a/tests/qemu-iotests/088.out
734
+++ b/tests/qemu-iotests/088.out
735
@@ -XXX,XX +XXX,XX @@ QA output created by 088
736
737
== Invalid block size ==
738
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
739
-can't open device TEST_DIR/t.vpc: Invalid block size 0
740
-can't open device TEST_DIR/t.vpc: Invalid block size 0
741
-can't open device TEST_DIR/t.vpc: Invalid block size 128
742
-can't open device TEST_DIR/t.vpc: Invalid block size 128
743
-can't open device TEST_DIR/t.vpc: Invalid block size 305419896
744
-can't open device TEST_DIR/t.vpc: Invalid block size 305419896
745
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 0
746
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 0
747
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 128
748
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 128
749
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 305419896
750
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 305419896
751
*** done
752
diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out
753
index XXXXXXX..XXXXXXX 100644
754
--- a/tests/qemu-iotests/103.out
755
+++ b/tests/qemu-iotests/103.out
756
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 0
757
758
=== Testing invalid option combinations ===
759
760
-can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
761
-can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size
762
-can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size
763
-can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
764
-can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
765
-can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
766
-can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
767
+qemu-io: can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
768
+qemu-io: can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size
769
+qemu-io: can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size
770
+qemu-io: can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
771
+qemu-io: can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
772
+qemu-io: can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
773
+qemu-io: can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
774
775
=== Testing valid option combinations ===
776
777
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
778
index XXXXXXX..XXXXXXX 100644
779
--- a/tests/qemu-iotests/114.out
780
+++ b/tests/qemu-iotests/114.out
781
@@ -XXX,XX +XXX,XX @@ virtual size: 64M (67108864 bytes)
782
cluster_size: 65536
783
backing file: TEST_DIR/t.IMGFMT.base
784
backing file format: foo
785
-can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
786
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
787
no file open, try 'help open'
788
read 4096/4096 bytes at offset 0
789
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
790
diff --git a/tests/qemu-iotests/116.out b/tests/qemu-iotests/116.out
791
index XXXXXXX..XXXXXXX 100644
792
--- a/tests/qemu-iotests/116.out
793
+++ b/tests/qemu-iotests/116.out
794
@@ -XXX,XX +XXX,XX @@ QA output created by 116
795
796
== truncated header cluster ==
797
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
798
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
799
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
800
801
== invalid header magic ==
802
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
803
-can't open device TEST_DIR/t.qed: Image not in QED format
804
+qemu-io: can't open device TEST_DIR/t.qed: Image not in QED format
805
806
== invalid cluster size ==
807
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
808
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
809
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
810
811
== invalid table size ==
812
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
813
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
814
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
815
816
== invalid header size ==
817
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
818
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
819
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
820
821
== invalid L1 table offset ==
822
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
823
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
824
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
825
826
== invalid image size ==
827
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
828
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
829
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
830
*** done
831
diff --git a/tests/qemu-iotests/131.out b/tests/qemu-iotests/131.out
832
index XXXXXXX..XXXXXXX 100644
833
--- a/tests/qemu-iotests/131.out
834
+++ b/tests/qemu-iotests/131.out
835
@@ -XXX,XX +XXX,XX @@ read 32768/32768 bytes at offset 163840
836
read 32768/32768 bytes at offset 0
837
32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
838
== Corrupt image ==
839
-can't open device TEST_DIR/t.parallels: parallels: Image was not closed correctly; cannot be opened read/write
840
+qemu-io: can't open device TEST_DIR/t.parallels: parallels: Image was not closed correctly; cannot be opened read/write
841
ERROR image was not closed correctly
842
843
1 errors were found on the image.
844
diff --git a/tests/qemu-iotests/133.out b/tests/qemu-iotests/133.out
845
index XXXXXXX..XXXXXXX 100644
846
--- a/tests/qemu-iotests/133.out
847
+++ b/tests/qemu-iotests/133.out
848
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t
849
850
=== Check that node-name can't be changed ===
851
852
-Cannot change the option 'node-name'
853
-Cannot change the option 'node-name'
854
-Cannot change the option 'node-name'
855
+qemu-io: Cannot change the option 'node-name'
856
+qemu-io: Cannot change the option 'node-name'
857
+qemu-io: Cannot change the option 'node-name'
858
859
=== Check that unchanged node-name is okay ===
860
861
862
=== Check that driver can't be changed ===
863
864
-Cannot change the option 'driver'
865
-Cannot change the option 'driver'
866
-Cannot change the option 'driver'
867
+qemu-io: Cannot change the option 'driver'
868
+qemu-io: Cannot change the option 'driver'
869
+qemu-io: Cannot change the option 'driver'
870
871
=== Check that unchanged driver is okay ===
872
873
@@ -XXX,XX +XXX,XX @@ format name: null-co
874
875
=== Check that mixing -c/-r/-w and their corresponding options is forbidden ===
876
877
-Cannot set both -r/-w and 'read-only'
878
-Cannot set both -r/-w and 'read-only'
879
-Cannot set both -c and the cache options
880
-Cannot set both -c and the cache options
881
-Cannot set both -c and the cache options
882
+qemu-io: Cannot set both -r/-w and 'read-only'
883
+qemu-io: Cannot set both -r/-w and 'read-only'
884
+qemu-io: Cannot set both -c and the cache options
885
+qemu-io: Cannot set both -c and the cache options
886
+qemu-io: Cannot set both -c and the cache options
887
888
=== Check that invalid options are handled correctly ===
889
890
-Parameter 'read-only' expects 'on' or 'off'
891
-Parameter 'cache.no-flush' expects 'on' or 'off'
892
-Parameter 'cache.direct' expects 'on' or 'off'
893
-Parameter 'auto-read-only' expects 'on' or 'off'
894
+qemu-io: Parameter 'read-only' expects 'on' or 'off'
895
+qemu-io: Parameter 'cache.no-flush' expects 'on' or 'off'
896
+qemu-io: Parameter 'cache.direct' expects 'on' or 'off'
897
+qemu-io: Parameter 'auto-read-only' expects 'on' or 'off'
898
*** done
899
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
900
index XXXXXXX..XXXXXXX 100644
901
--- a/tests/qemu-iotests/137.out
902
+++ b/tests/qemu-iotests/137.out
903
@@ -XXX,XX +XXX,XX @@ read 33554432/33554432 bytes at offset 0
904
905
=== Try setting some invalid values ===
906
907
-Parameter 'lazy-refcounts' expects 'on' or 'off'
908
-cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
909
-l2-cache-size may not exceed cache-size
910
-refcount-cache-size may not exceed cache-size
911
-L2 cache entry size must be a power of two between 512 and the cluster size (65536)
912
-L2 cache entry size must be a power of two between 512 and the cluster size (65536)
913
-Refcount cache size too big
914
-Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-check.template' ('all')
915
-Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
916
-Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
917
-Cache clean interval too big
918
+qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
919
+qemu-io: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
920
+qemu-io: l2-cache-size may not exceed cache-size
921
+qemu-io: refcount-cache-size may not exceed cache-size
922
+qemu-io: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
923
+qemu-io: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
924
+qemu-io: Refcount cache size too big
925
+qemu-io: Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-check.template' ('all')
926
+qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
927
+qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
928
+qemu-io: Cache clean interval too big
929
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=36028797018963968
930
-L2 cache size too big
931
+qemu-io: L2 cache size too big
932
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
933
934
=== Test transaction semantics ===
935
936
-Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
937
+qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
938
wrote 512/512 bytes at offset 0
939
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
940
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
941
@@ -XXX,XX +XXX,XX @@ incompatible_features 0x0
942
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
943
wrote 65536/65536 bytes at offset 0
944
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
945
-Parameter 'lazy-refcounts' expects 'on' or 'off'
946
+qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
947
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with qcow2_header); further corruption events will be suppressed
948
write failed: Input/output error
949
*** done
950
diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
951
index XXXXXXX..XXXXXXX 100644
952
--- a/tests/qemu-iotests/140.out
953
+++ b/tests/qemu-iotests/140.out
954
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 0
955
read 65536/65536 bytes at offset 0
956
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
957
{"return": {}}
958
-can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: Requested export not available
959
+qemu-io: can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: Requested export not available
960
server reported: export 'drv' not present
961
{"return": {}}
962
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
963
diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
964
index XXXXXXX..XXXXXXX 100644
965
--- a/tests/qemu-iotests/143.out
966
+++ b/tests/qemu-iotests/143.out
967
@@ -XXX,XX +XXX,XX @@
968
QA output created by 143
969
{"return": {}}
970
{"return": {}}
971
-can't open device nbd+unix:///no_such_export?socket=TEST_DIR/nbd: Requested export not available
972
+qemu-io: can't open device nbd+unix:///no_such_export?socket=TEST_DIR/nbd: Requested export not available
973
server reported: export 'no_such_export' not present
974
{"return": {}}
975
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
976
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
977
index XXXXXXX..XXXXXXX 100644
978
--- a/tests/qemu-iotests/153.out
979
+++ b/tests/qemu-iotests/153.out
980
@@ -XXX,XX +XXX,XX @@ Is another process using the image [TEST_DIR/t.qcow2]?
981
== Running utility commands ==
982
983
_qemu_io_wrapper -c read 0 512 TEST_DIR/t.qcow2
984
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
985
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
986
Is another process using the image [TEST_DIR/t.qcow2]?
987
988
_qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
989
-can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
990
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
991
Is another process using the image [TEST_DIR/t.qcow2]?
992
993
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
994
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
995
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
996
Is another process using the image [TEST_DIR/t.qcow2]?
997
no file open, try 'help open'
998
999
_qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512
1000
-can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
1001
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
1002
Is another process using the image [TEST_DIR/t.qcow2]?
1003
no file open, try 'help open'
1004
1005
@@ -XXX,XX +XXX,XX @@ file format: IMGFMT
1006
== Running utility commands -U ==
1007
1008
_qemu_io_wrapper -U -c read 0 512 TEST_DIR/t.qcow2
1009
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1010
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1011
1012
_qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
1013
1014
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
1015
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1016
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1017
no file open, try 'help open'
1018
1019
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
1020
@@ -XXX,XX +XXX,XX @@ Is another process using the image [TEST_DIR/t.qcow2]?
1021
== Running utility commands ==
1022
1023
_qemu_io_wrapper -c read 0 512 TEST_DIR/t.qcow2
1024
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1025
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1026
Is another process using the image [TEST_DIR/t.qcow2]?
1027
1028
_qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
1029
1030
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
1031
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1032
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1033
Is another process using the image [TEST_DIR/t.qcow2]?
1034
no file open, try 'help open'
1035
1036
@@ -XXX,XX +XXX,XX @@ file format: IMGFMT
1037
== Running utility commands -U ==
1038
1039
_qemu_io_wrapper -U -c read 0 512 TEST_DIR/t.qcow2
1040
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1041
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1042
1043
_qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
1044
1045
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
1046
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1047
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1048
no file open, try 'help open'
1049
1050
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
1051
@@ -XXX,XX +XXX,XX @@ file format: IMGFMT
1052
== Running utility commands -U ==
1053
1054
_qemu_io_wrapper -U -c read 0 512 TEST_DIR/t.qcow2
1055
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1056
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1057
1058
_qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
1059
1060
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
1061
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1062
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1063
no file open, try 'help open'
1064
1065
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
1066
@@ -XXX,XX +XXX,XX @@ Adding drive
1067
{"return": "OKrn"}
1068
1069
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
1070
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1071
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1072
Is another process using the image [TEST_DIR/t.qcow2]?
1073
Creating overlay with qemu-img when the guest is running should be allowed
1074
1075
@@ -XXX,XX +XXX,XX @@ _qemu_img_wrapper info TEST_DIR/t.qcow2
1076
{"return": ""}
1077
1078
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
1079
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1080
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1081
Is another process using the image [TEST_DIR/t.qcow2]?
1082
Closing the other
1083
{"return": ""}
1084
@@ -XXX,XX +XXX,XX @@ qemu-img: --force-share/-U conflicts with image options
1085
No conflict:
1086
1087
Conflict:
1088
--U conflicts with image options
1089
+qemu-io: -U conflicts with image options
1090
*** done
1091
diff --git a/tests/qemu-iotests/187.out b/tests/qemu-iotests/187.out
1092
index XXXXXXX..XXXXXXX 100644
1093
--- a/tests/qemu-iotests/187.out
1094
+++ b/tests/qemu-iotests/187.out
1095
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
1096
1097
Start from read-only
1098
1099
-Block node is read-only
1100
+qemu-io: Block node is read-only
1101
wrote 65536/65536 bytes at offset 0
1102
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1103
-Block node is read-only
1104
+qemu-io: Block node is read-only
1105
1106
Start from read-write
1107
1108
wrote 65536/65536 bytes at offset 0
1109
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1110
-Block node is read-only
1111
+qemu-io: Block node is read-only
1112
wrote 65536/65536 bytes at offset 0
1113
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1114
*** done
1115
diff --git a/tests/qemu-iotests/188.out b/tests/qemu-iotests/188.out
1116
index XXXXXXX..XXXXXXX 100644
1117
--- a/tests/qemu-iotests/188.out
1118
+++ b/tests/qemu-iotests/188.out
1119
@@ -XXX,XX +XXX,XX @@ read 16777216/16777216 bytes at offset 0
1120
16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1121
1122
== verify open failure with wrong password ==
1123
-can't open: Invalid password, cannot unlock any keyslot
1124
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
1125
*** done
1126
diff --git a/tests/qemu-iotests/197.out b/tests/qemu-iotests/197.out
1127
index XXXXXXX..XXXXXXX 100644
1128
--- a/tests/qemu-iotests/197.out
1129
+++ b/tests/qemu-iotests/197.out
1130
@@ -XXX,XX +XXX,XX @@ read 2147483136/2147483136 bytes at offset 1024
1131
2 GiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1132
read 1024/1024 bytes at offset 3221226496
1133
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1134
-can't open device TEST_DIR/t.wrap.qcow2: Can't use copy-on-read on read-only device
1135
+qemu-io: can't open device TEST_DIR/t.wrap.qcow2: Can't use copy-on-read on read-only device
1136
2 GiB (0x80010000) bytes allocated at offset 0 bytes (0x0)
1137
1023.938 MiB (0x3fff0000) bytes not allocated at offset 2 GiB (0x80010000)
1138
64 KiB (0x10000) bytes allocated at offset 3 GiB (0xc0000000)
1139
diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
1140
index XXXXXXX..XXXXXXX 100755
1141
--- a/tests/qemu-iotests/205
1142
+++ b/tests/qemu-iotests/205
1143
@@ -XXX,XX +XXX,XX @@ class TestNbdServerRemove(iotests.QMPTestCase):
1144
1145
def assertConnectFailed(self, qemu_io_output):
1146
self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
1147
- "can't open device " + nbd_uri +
1148
+ "qemu-io: can't open device " + nbd_uri +
1149
": Requested export not available\n"
1150
"server reported: export 'exp' not present")
1151
1152
diff --git a/tests/qemu-iotests/215.out b/tests/qemu-iotests/215.out
1153
index XXXXXXX..XXXXXXX 100644
1154
--- a/tests/qemu-iotests/215.out
1155
+++ b/tests/qemu-iotests/215.out
1156
@@ -XXX,XX +XXX,XX @@ read 2147483136/2147483136 bytes at offset 1024
1157
2 GiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1158
read 1024/1024 bytes at offset 3221226496
1159
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1160
-can't open device TEST_DIR/t.wrap.qcow2: Block node is read-only
1161
+qemu-io: can't open device TEST_DIR/t.wrap.qcow2: Block node is read-only
1162
2 GiB (0x80010000) bytes allocated at offset 0 bytes (0x0)
1163
1023.938 MiB (0x3fff0000) bytes not allocated at offset 2 GiB (0x80010000)
1164
64 KiB (0x10000) bytes allocated at offset 3 GiB (0xc0000000)
1165
diff --git a/tests/qemu-iotests/226.out b/tests/qemu-iotests/226.out
1166
index XXXXXXX..XXXXXXX 100644
1167
--- a/tests/qemu-iotests/226.out
1168
+++ b/tests/qemu-iotests/226.out
1169
@@ -XXX,XX +XXX,XX @@ QA output created by 226
1170
=== Testing with driver:file ===
1171
1172
== Testing RO ==
1173
-can't open: A regular file was expected by the 'file' driver, but something else was given
1174
-warning: Opening a character device as a file using the 'file' driver is deprecated
1175
+qemu-io: can't open: A regular file was expected by the 'file' driver, but something else was given
1176
+qemu-io: warning: Opening a character device as a file using the 'file' driver is deprecated
1177
== Testing RW ==
1178
-can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1179
-warning: Opening a character device as a file using the 'file' driver is deprecated
1180
+qemu-io: can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1181
+qemu-io: warning: Opening a character device as a file using the 'file' driver is deprecated
1182
1183
=== Testing with driver:host_device ===
1184
1185
== Testing RO ==
1186
-can't open: 'host_device' driver expects either a character or block device
1187
+qemu-io: can't open: 'host_device' driver expects either a character or block device
1188
== Testing RW ==
1189
-can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1190
+qemu-io: can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1191
1192
=== Testing with driver:host_cdrom ===
1193
1194
== Testing RO ==
1195
-can't open: 'host_cdrom' driver expects either a character or block device
1196
+qemu-io: can't open: 'host_cdrom' driver expects either a character or block device
1197
== Testing RW ==
1198
-can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1199
+qemu-io: can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1200
1201
*** done
1202
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
1203
index XXXXXXX..XXXXXXX 100644
1204
--- a/tests/qemu-iotests/244.out
1205
+++ b/tests/qemu-iotests/244.out
1206
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
1207
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1208
read 65536/65536 bytes at offset 0
1209
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1210
-can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1211
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1212
no file open, try 'help open'
1213
1214
Data file required, but without data file name in the image:
1215
-can't open device TEST_DIR/t.qcow2: 'data-file' is required for this image
1216
+qemu-io: can't open device TEST_DIR/t.qcow2: 'data-file' is required for this image
1217
no file open, try 'help open'
1218
read 65536/65536 bytes at offset 0
1219
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1220
-can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1221
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1222
no file open, try 'help open'
1223
1224
Setting data-file for an image with internal data:
1225
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
1226
-can't open device TEST_DIR/t.qcow2: 'data-file' can only be set for images with an external data file
1227
+qemu-io: can't open device TEST_DIR/t.qcow2: 'data-file' can only be set for images with an external data file
1228
no file open, try 'help open'
1229
-can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1230
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1231
no file open, try 'help open'
1232
1233
=== Conflicting features ===
1234
--
40
--
1235
2.20.1
41
2.13.6
1236
42
1237
43
diff view generated by jsdifflib
1
preallocate_co() already gave the data file the full size without
1
From: Fam Zheng <famz@redhat.com>
2
forwarding the requested preallocation mode to the protocol. When
3
bdrv_co_truncate() was called later with the preallocation mode, the
4
file didn't actually grow any more, so the data file stayed unallocated
5
even if full preallocation was requested.
6
2
7
Pass the right preallocation mode to preallocate_co() and remove the
3
Signed-off-by: Fam Zheng <famz@redhat.com>
8
second bdrv_co_truncate() to fix this. As a side effect, the ugly
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
one-byte write in preallocate_co() is replaced with a truncate call,
5
---
10
now leaving the last block unallocated on the protocol level as it
6
include/block/block_int.h | 1 -
11
should be.
7
block/io.c | 18 ------------------
8
2 files changed, 19 deletions(-)
12
9
13
Cc: qemu-stable@nongnu.org
10
diff --git a/include/block/block_int.h b/include/block/block_int.h
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
16
---
17
block/qcow2.c | 41 +++++++++++++++++++++++------------------
18
1 file changed, 23 insertions(+), 18 deletions(-)
19
20
diff --git a/block/qcow2.c b/block/qcow2.c
21
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
22
--- a/block/qcow2.c
12
--- a/include/block/block_int.h
23
+++ b/block/qcow2.c
13
+++ b/include/block/block_int.h
24
@@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
14
@@ -XXX,XX +XXX,XX @@ bool blk_dev_is_tray_open(BlockBackend *blk);
25
* Returns: 0 on success, -errno on failure.
15
bool blk_dev_is_medium_locked(BlockBackend *blk);
26
*/
16
27
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
17
void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes);
28
- uint64_t new_length, Error **errp)
18
-bool bdrv_requests_pending(BlockDriverState *bs);
29
+ uint64_t new_length, PreallocMode mode,
19
30
+ Error **errp)
20
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
31
{
21
void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in);
32
BDRVQcow2State *s = bs->opaque;
22
diff --git a/block/io.c b/block/io.c
33
uint64_t bytes;
23
index XXXXXXX..XXXXXXX 100644
34
uint64_t host_offset = 0;
24
--- a/block/io.c
35
+ int64_t file_length;
25
+++ b/block/io.c
36
unsigned int cur_bytes;
26
@@ -XXX,XX +XXX,XX @@ void bdrv_disable_copy_on_read(BlockDriverState *bs)
37
int ret;
27
assert(old >= 1);
38
QCowL2Meta *meta;
28
}
39
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
29
40
* all of the allocated clusters (otherwise we get failing reads after
30
-/* Check if any requests are in-flight (including throttled requests) */
41
* EOF). Extend the image to the last allocated sector.
31
-bool bdrv_requests_pending(BlockDriverState *bs)
42
*/
32
-{
43
- if (host_offset != 0) {
33
- BdrvChild *child;
44
- uint8_t data = 0;
34
-
45
- ret = bdrv_pwrite(s->data_file, (host_offset + cur_bytes) - 1,
35
- if (atomic_read(&bs->in_flight)) {
46
- &data, 1);
36
- return true;
47
+ file_length = bdrv_getlength(s->data_file->bs);
37
- }
48
+ if (file_length < 0) {
38
-
49
+ error_setg_errno(errp, -file_length, "Could not get file size");
39
- QLIST_FOREACH(child, &bs->children, next) {
50
+ return file_length;
40
- if (bdrv_requests_pending(child->bs)) {
51
+ }
41
- return true;
52
+
53
+ if (host_offset + cur_bytes > file_length) {
54
+ if (mode == PREALLOC_MODE_METADATA) {
55
+ mode = PREALLOC_MODE_OFF;
56
+ }
57
+ ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, mode,
58
+ errp);
59
if (ret < 0) {
60
- error_setg_errno(errp, -ret, "Writing to EOF failed");
61
return ret;
62
}
63
}
64
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
65
66
switch (prealloc) {
67
case PREALLOC_MODE_OFF:
68
+ if (has_data_file(bs)) {
69
+ ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
70
+ if (ret < 0) {
71
+ goto fail;
72
+ }
73
+ }
74
break;
75
76
case PREALLOC_MODE_METADATA:
77
- ret = preallocate_co(bs, old_length, offset, errp);
78
+ ret = preallocate_co(bs, old_length, offset, prealloc, errp);
79
if (ret < 0) {
80
goto fail;
81
}
82
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
83
/* With a data file, preallocation means just allocating the metadata
84
* and forwarding the truncate request to the data file */
85
if (has_data_file(bs)) {
86
- ret = preallocate_co(bs, old_length, offset, errp);
87
+ ret = preallocate_co(bs, old_length, offset, prealloc, errp);
88
if (ret < 0) {
89
goto fail;
90
}
91
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
92
93
bs->total_sectors = offset / BDRV_SECTOR_SIZE;
94
95
- if (has_data_file(bs)) {
96
- if (prealloc == PREALLOC_MODE_METADATA) {
97
- prealloc = PREALLOC_MODE_OFF;
98
- }
99
- ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
100
- if (ret < 0) {
101
- goto fail;
102
- }
42
- }
103
- }
43
- }
104
-
44
-
105
/* write updated header.size */
45
- return false;
106
offset = cpu_to_be64(offset);
46
-}
107
ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
47
-
48
typedef struct {
49
Coroutine *co;
50
BlockDriverState *bs;
108
--
51
--
109
2.20.1
52
2.13.6
110
53
111
54
diff view generated by jsdifflib
New patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Fam Zheng <famz@redhat.com>
3
---
4
block/io.c | 6 ++++++
5
1 file changed, 6 insertions(+)
1
6
7
diff --git a/block/io.c b/block/io.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/block/io.c
10
+++ b/block/io.c
11
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
12
BdrvNextIterator it;
13
GSList *aio_ctxs = NULL, *ctx;
14
15
+ /* BDRV_POLL_WHILE() for a node can only be called from its own I/O thread
16
+ * or the main loop AioContext. We potentially use BDRV_POLL_WHILE() on
17
+ * nodes in several different AioContexts, so make sure we're in the main
18
+ * context. */
19
+ assert(qemu_get_current_aio_context() == qemu_get_aio_context());
20
+
21
block_job_pause_all();
22
23
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
24
--
25
2.13.6
26
27
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
bdrv_drained_begin() doesn't increase bs->quiesce_counter recursively
2
and also doesn't notify other parent nodes of children, which both means
3
that the child nodes are not actually drained, and bdrv_drained_begin()
4
is providing useful functionality only on a single node.
2
5
3
Disk sizes close to INT64_MAX cause overflow, for some pretty
6
To keep things consistent, we also shouldn't call the block driver
4
ridiculous output:
7
callbacks recursively.
5
8
6
$ ./nbdkit -U - memory size=$((2**63 - 512)) --run 'qemu-img info $nbd'
9
A proper recursive drain version that provides an actually working
7
image: nbd+unix://?socket=/tmp/nbdkitHSAzNz/socket
10
drained section for child nodes will be introduced later.
8
file format: raw
9
virtual size: -8388607T (9223372036854775296 bytes)
10
disk size: unavailable
11
11
12
But there's no reason to have two separate implementations of integer
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
to human-readable abbreviation, where one has overflow and stops at
13
Reviewed-by: Fam Zheng <famz@redhat.com>
14
'T', while the other avoids overflow and goes all the way to 'E'. With
14
---
15
this patch, the output now claims 8EiB instead of -8388607T, which
15
block/io.c | 16 +++++++++-------
16
really is the correct rounding of largest file size supported by qemu
16
1 file changed, 9 insertions(+), 7 deletions(-)
17
(we could go 511 bytes larger if we used byte-accurate sizing instead
18
of rounding up to the next sector boundary, but that wouldn't change
19
the human-readable result).
20
17
21
Quite a few iotests need updates to expected output to match.
18
diff --git a/block/io.c b/block/io.c
22
23
Reported-by: Richard W.M. Jones <rjones@redhat.com>
24
Signed-off-by: Eric Blake <eblake@redhat.com>
25
Tested-by: Richard W.M. Jones <rjones@redhat.com>
26
Reviewed-by: Alberto Garcia <berto@igalia.com>
27
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
28
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
29
Tested-by: Max Reitz <mreitz@redhat.com>
30
---
31
block/qapi.c | 49 +++++++++-----------------------------
32
tests/qemu-iotests/043.out | 6 ++---
33
tests/qemu-iotests/053.out | 2 +-
34
tests/qemu-iotests/059.out | 10 ++++----
35
tests/qemu-iotests/060.out | 10 ++++----
36
tests/qemu-iotests/061.out | 12 +++++-----
37
tests/qemu-iotests/070.out | 2 +-
38
tests/qemu-iotests/082.out | 26 ++++++++++----------
39
tests/qemu-iotests/084.out | 8 +++----
40
tests/qemu-iotests/089.out | 2 +-
41
tests/qemu-iotests/095.out | 4 ++--
42
tests/qemu-iotests/104.out | 6 ++---
43
tests/qemu-iotests/110.out | 6 ++---
44
tests/qemu-iotests/114.out | 2 +-
45
tests/qemu-iotests/126.out | 4 ++--
46
tests/qemu-iotests/130.out | 10 ++++----
47
tests/qemu-iotests/153.out | 2 +-
48
tests/qemu-iotests/191.out | 8 +++----
49
tests/qemu-iotests/195.out | 4 ++--
50
tests/qemu-iotests/198.out | 4 ++--
51
tests/qemu-iotests/206.out | 10 ++++----
52
tests/qemu-iotests/207.out | 12 +++++-----
53
tests/qemu-iotests/210.out | 8 +++----
54
tests/qemu-iotests/211.out | 10 ++++----
55
tests/qemu-iotests/212.out | 10 ++++----
56
tests/qemu-iotests/213.out | 10 ++++----
57
tests/qemu-iotests/233.out | 4 ++--
58
tests/qemu-iotests/237.out | 22 ++++++++---------
59
tests/qemu-iotests/242.out | 10 ++++----
60
29 files changed, 123 insertions(+), 150 deletions(-)
61
62
diff --git a/block/qapi.c b/block/qapi.c
63
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
64
--- a/block/qapi.c
20
--- a/block/io.c
65
+++ b/block/qapi.c
21
+++ b/block/io.c
66
@@ -XXX,XX +XXX,XX @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
22
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
67
return head;
68
}
23
}
69
24
70
-#define NB_SUFFIXES 4
25
/* Recursively call BlockDriver.bdrv_co_drain_begin/end callbacks */
71
-
26
-static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
72
-static char *get_human_readable_size(char *buf, int buf_size, int64_t size)
27
+static void bdrv_drain_invoke(BlockDriverState *bs, bool begin, bool recursive)
73
-{
74
- static const char suffixes[NB_SUFFIXES] = {'K', 'M', 'G', 'T'};
75
- int64_t base;
76
- int i;
77
-
78
- if (size <= 999) {
79
- snprintf(buf, buf_size, "%" PRId64, size);
80
- } else {
81
- base = 1024;
82
- for (i = 0; i < NB_SUFFIXES; i++) {
83
- if (size < (10 * base)) {
84
- snprintf(buf, buf_size, "%0.1f%c",
85
- (double)size / base,
86
- suffixes[i]);
87
- break;
88
- } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
89
- snprintf(buf, buf_size, "%" PRId64 "%c",
90
- ((size + (base >> 1)) / base),
91
- suffixes[i]);
92
- break;
93
- }
94
- base = base * 1024;
95
- }
96
- }
97
- return buf;
98
-}
99
-
100
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
101
{
28
{
102
- char buf1[128], date_buf[128], clock_buf[128];
29
BdrvChild *child, *tmp;
103
+ char date_buf[128], clock_buf[128];
30
BdrvCoDrainData data = { .bs = bs, .done = false, .begin = begin};
104
struct tm tm;
31
@@ -XXX,XX +XXX,XX @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
105
time_t ti;
32
bdrv_coroutine_enter(bs, data.co);
106
int64_t secs;
33
BDRV_POLL_WHILE(bs, !data.done);
107
+ char *sizing = NULL;
34
108
35
- QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
109
if (!sn) {
36
- bdrv_drain_invoke(child->bs, begin);
110
qemu_printf("%-10s%-20s%7s%20s%15s",
37
+ if (recursive) {
111
@@ -XXX,XX +XXX,XX @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
38
+ QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
112
(int)((secs / 60) % 60),
39
+ bdrv_drain_invoke(child->bs, begin, true);
113
(int)(secs % 60),
40
+ }
114
(int)((sn->vm_clock_nsec / 1000000) % 1000));
115
+ sizing = size_to_str(sn->vm_state_size);
116
qemu_printf("%-10s%-20s%7s%20s%15s",
117
sn->id_str, sn->name,
118
- get_human_readable_size(buf1, sizeof(buf1),
119
- sn->vm_state_size),
120
+ sizing,
121
date_buf,
122
clock_buf);
123
}
41
}
124
+ g_free(sizing);
125
}
42
}
126
43
127
static void dump_qdict(int indentation, QDict *dict);
44
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_begin(BlockDriverState *bs)
128
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
45
bdrv_parent_drained_begin(bs);
129
130
void bdrv_image_info_dump(ImageInfo *info)
131
{
132
- char size_buf[128], dsize_buf[128];
133
+ char *size_buf, *dsize_buf;
134
if (!info->has_actual_size) {
135
- snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
136
+ dsize_buf = g_strdup("unavailable");
137
} else {
138
- get_human_readable_size(dsize_buf, sizeof(dsize_buf),
139
- info->actual_size);
140
+ dsize_buf = size_to_str(info->actual_size);
141
}
46
}
142
- get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
47
143
+ size_buf = size_to_str(info->virtual_size);
48
- bdrv_drain_invoke(bs, true);
144
qemu_printf("image: %s\n"
49
+ bdrv_drain_invoke(bs, true, false);
145
"file format: %s\n"
50
bdrv_drain_recurse(bs);
146
"virtual size: %s (%" PRId64 " bytes)\n"
147
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_dump(ImageInfo *info)
148
info->filename, info->format, size_buf,
149
info->virtual_size,
150
dsize_buf);
151
+ g_free(size_buf);
152
+ g_free(dsize_buf);
153
154
if (info->has_encrypted && info->encrypted) {
155
qemu_printf("encrypted: yes\n");
156
diff --git a/tests/qemu-iotests/043.out b/tests/qemu-iotests/043.out
157
index XXXXXXX..XXXXXXX 100644
158
--- a/tests/qemu-iotests/043.out
159
+++ b/tests/qemu-iotests/043.out
160
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/
161
== finite chain of length 3 (human) ==
162
image: TEST_DIR/t.IMGFMT
163
file format: IMGFMT
164
-virtual size: 128M (134217728 bytes)
165
+virtual size: 128 MiB (134217728 bytes)
166
cluster_size: 65536
167
backing file: TEST_DIR/t.IMGFMT.2.base
168
169
image: TEST_DIR/t.IMGFMT.2.base
170
file format: IMGFMT
171
-virtual size: 128M (134217728 bytes)
172
+virtual size: 128 MiB (134217728 bytes)
173
cluster_size: 65536
174
backing file: TEST_DIR/t.IMGFMT.1.base
175
176
image: TEST_DIR/t.IMGFMT.1.base
177
file format: IMGFMT
178
-virtual size: 128M (134217728 bytes)
179
+virtual size: 128 MiB (134217728 bytes)
180
cluster_size: 65536
181
182
== finite chain of length 3 (json) ==
183
diff --git a/tests/qemu-iotests/053.out b/tests/qemu-iotests/053.out
184
index XXXXXXX..XXXXXXX 100644
185
--- a/tests/qemu-iotests/053.out
186
+++ b/tests/qemu-iotests/053.out
187
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 0
188
No errors were found on the image.
189
190
== Checking compressed image virtual disk size ==
191
-virtual size: 512 (512 bytes)
192
+virtual size: 512 B (512 bytes)
193
194
== Verifying the compressed image ==
195
read 512/512 bytes at offset 0
196
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
197
index XXXXXXX..XXXXXXX 100644
198
--- a/tests/qemu-iotests/059.out
199
+++ b/tests/qemu-iotests/059.out
200
@@ -XXX,XX +XXX,XX @@ can't open device TEST_DIR/t.vmdk: L1 size too big
201
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
202
image: TEST_DIR/t.IMGFMT
203
file format: IMGFMT
204
-virtual size: 2.0G (2147483648 bytes)
205
+virtual size: 2 GiB (2147483648 bytes)
206
207
=== Testing monolithicFlat with zeroed_grain ===
208
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
209
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicF
210
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMaxExtentFlat
211
image: TEST_DIR/t.vmdk
212
file format: vmdk
213
-virtual size: 1.0T (1073741824000 bytes)
214
-disk size: 16K
215
+virtual size: 0.977 TiB (1073741824000 bytes)
216
+disk size: 16 KiB
217
Format specific information:
218
cid: XXXXXXXX
219
parent cid: XXXXXXXX
220
@@ -XXX,XX +XXX,XX @@ can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"i
221
=== Testing version 3 ===
222
image: TEST_DIR/iotest-version3.IMGFMT
223
file format: IMGFMT
224
-virtual size: 16G (17179869184 bytes)
225
+virtual size: 16 GiB (17179869184 bytes)
226
cluster_size: 65536
227
read 512/512 bytes at offset 0
228
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
229
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 64931328
230
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat
231
image: TEST_DIR/t.IMGFMT
232
file format: IMGFMT
233
-virtual size: 4.0T (4398046511104 bytes)
234
+virtual size: 4 TiB (4398046511104 bytes)
235
wrote 512/512 bytes at offset 966367641600
236
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
237
e100000000: 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a ................
238
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
239
index XXXXXXX..XXXXXXX 100644
240
--- a/tests/qemu-iotests/060.out
241
+++ b/tests/qemu-iotests/060.out
242
@@ -XXX,XX +XXX,XX @@ write failed: Input/output error
243
incompatible_features 0x2
244
image: TEST_DIR/t.IMGFMT
245
file format: IMGFMT
246
-virtual size: 64M (67108864 bytes)
247
+virtual size: 64 MiB (67108864 bytes)
248
cluster_size: 65536
249
Format specific information:
250
compat: 1.1
251
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
252
qcow2: Marking image as corrupt: Refblock at 0xffffff00000000 is not covered by the refcount structures; further corruption events will be suppressed
253
qemu-img: Failed to discard unused refblocks: Input/output error
254
--- Checking and retrying ---
255
-virtual size: 64M (67108864 bytes)
256
+virtual size: 64 MiB (67108864 bytes)
257
No errors were found on the image.
258
Image resized.
259
-virtual size: 32M (33554432 bytes)
260
+virtual size: 32 MiB (33554432 bytes)
261
262
=== Discarding a non-covered in-bounds refblock ===
263
264
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
265
qcow2: Marking image as corrupt: Refblock at 0x1000000000 is not covered by the refcount structures; further corruption events will be suppressed
266
qemu-img: Failed to discard unused refblocks: Input/output error
267
--- Checking and retrying ---
268
-virtual size: 64M (67108864 bytes)
269
+virtual size: 64 MiB (67108864 bytes)
270
No errors were found on the image.
271
Image resized.
272
-virtual size: 32M (33554432 bytes)
273
+virtual size: 32 MiB (33554432 bytes)
274
275
=== Discarding a refblock covered by an unaligned refblock ===
276
277
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
278
index XXXXXXX..XXXXXXX 100644
279
--- a/tests/qemu-iotests/061.out
280
+++ b/tests/qemu-iotests/061.out
281
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IM
282
qemu-img: Cannot downgrade an image with a data file
283
image: TEST_DIR/t.IMGFMT
284
file format: IMGFMT
285
-virtual size: 64M (67108864 bytes)
286
+virtual size: 64 MiB (67108864 bytes)
287
cluster_size: 65536
288
Format specific information:
289
compat: 1.1
290
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IM
291
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory
292
image: TEST_DIR/t.IMGFMT
293
file format: IMGFMT
294
-virtual size: 64M (67108864 bytes)
295
+virtual size: 64 MiB (67108864 bytes)
296
cluster_size: 65536
297
Format specific information:
298
compat: 1.1
299
@@ -XXX,XX +XXX,XX @@ Format specific information:
300
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
301
image: TEST_DIR/t.IMGFMT
302
file format: IMGFMT
303
-virtual size: 64M (67108864 bytes)
304
+virtual size: 64 MiB (67108864 bytes)
305
cluster_size: 65536
306
Format specific information:
307
compat: 1.1
308
@@ -XXX,XX +XXX,XX @@ Format specific information:
309
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on
310
image: TEST_DIR/t.IMGFMT
311
file format: IMGFMT
312
-virtual size: 64M (67108864 bytes)
313
+virtual size: 64 MiB (67108864 bytes)
314
cluster_size: 65536
315
Format specific information:
316
compat: 1.1
317
@@ -XXX,XX +XXX,XX @@ Format specific information:
318
No errors were found on the image.
319
image: TEST_DIR/t.IMGFMT
320
file format: IMGFMT
321
-virtual size: 64M (67108864 bytes)
322
+virtual size: 64 MiB (67108864 bytes)
323
cluster_size: 65536
324
Format specific information:
325
compat: 1.1
326
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
327
qemu-img: data-file-raw cannot be set on existing images
328
image: TEST_DIR/t.IMGFMT
329
file format: IMGFMT
330
-virtual size: 64M (67108864 bytes)
331
+virtual size: 64 MiB (67108864 bytes)
332
cluster_size: 65536
333
Format specific information:
334
compat: 1.1
335
diff --git a/tests/qemu-iotests/070.out b/tests/qemu-iotests/070.out
336
index XXXXXXX..XXXXXXX 100644
337
--- a/tests/qemu-iotests/070.out
338
+++ b/tests/qemu-iotests/070.out
339
@@ -XXX,XX +XXX,XX @@ read 18874368/18874368 bytes at offset 0
340
=== Verify image created by Disk2VHD can be opened ===
341
image: TEST_DIR/test-disk2vhd.IMGFMT
342
file format: IMGFMT
343
-virtual size: 256M (268435456 bytes)
344
+virtual size: 256 MiB (268435456 bytes)
345
cluster_size: 2097152
346
*** done
347
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
348
index XXXXXXX..XXXXXXX 100644
349
--- a/tests/qemu-iotests/082.out
350
+++ b/tests/qemu-iotests/082.out
351
@@ -XXX,XX +XXX,XX @@ Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M
352
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
353
image: TEST_DIR/t.IMGFMT
354
file format: IMGFMT
355
-virtual size: 128M (134217728 bytes)
356
+virtual size: 128 MiB (134217728 bytes)
357
cluster_size: 65536
358
359
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
360
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on refcount_bits=16
361
image: TEST_DIR/t.IMGFMT
362
file format: IMGFMT
363
-virtual size: 128M (134217728 bytes)
364
+virtual size: 128 MiB (134217728 bytes)
365
cluster_size: 4096
366
Format specific information:
367
compat: 1.1
368
@@ -XXX,XX +XXX,XX @@ Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size
369
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on refcount_bits=16
370
image: TEST_DIR/t.IMGFMT
371
file format: IMGFMT
372
-virtual size: 128M (134217728 bytes)
373
+virtual size: 128 MiB (134217728 bytes)
374
cluster_size: 8192
375
Format specific information:
376
compat: 1.1
377
@@ -XXX,XX +XXX,XX @@ Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128
378
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off refcount_bits=16
379
image: TEST_DIR/t.IMGFMT
380
file format: IMGFMT
381
-virtual size: 128M (134217728 bytes)
382
+virtual size: 128 MiB (134217728 bytes)
383
cluster_size: 8192
384
385
=== create: help for -o ===
386
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_
387
Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
388
image: TEST_DIR/t.IMGFMT.base
389
file format: raw
390
-virtual size: 128M (134217728 bytes)
391
+virtual size: 128 MiB (134217728 bytes)
392
393
Testing: convert -O foo -O qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
394
image: TEST_DIR/t.IMGFMT.base
395
file format: IMGFMT
396
-virtual size: 128M (134217728 bytes)
397
+virtual size: 128 MiB (134217728 bytes)
398
cluster_size: 65536
399
400
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
401
image: TEST_DIR/t.IMGFMT.base
402
file format: IMGFMT
403
-virtual size: 128M (134217728 bytes)
404
+virtual size: 128 MiB (134217728 bytes)
405
cluster_size: 4096
406
Format specific information:
407
compat: 1.1
408
@@ -XXX,XX +XXX,XX @@ Format specific information:
409
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
410
image: TEST_DIR/t.IMGFMT.base
411
file format: IMGFMT
412
-virtual size: 128M (134217728 bytes)
413
+virtual size: 128 MiB (134217728 bytes)
414
cluster_size: 8192
415
Format specific information:
416
compat: 1.1
417
@@ -XXX,XX +XXX,XX @@ Format specific information:
418
Testing: convert -O qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
419
image: TEST_DIR/t.IMGFMT.base
420
file format: IMGFMT
421
-virtual size: 128M (134217728 bytes)
422
+virtual size: 128 MiB (134217728 bytes)
423
cluster_size: 8192
424
425
=== convert: help for -o ===
426
@@ -XXX,XX +XXX,XX @@ qemu-img: Cannot enable copy offloading when -c is used
427
Testing: amend -f foo -f qcow2 -o lazy_refcounts=on TEST_DIR/t.qcow2
428
image: TEST_DIR/t.IMGFMT
429
file format: IMGFMT
430
-virtual size: 128M (134217728 bytes)
431
+virtual size: 128 MiB (134217728 bytes)
432
cluster_size: 65536
433
Format specific information:
434
compat: 1.1
435
@@ -XXX,XX +XXX,XX @@ Format specific information:
436
Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2
437
image: TEST_DIR/t.IMGFMT
438
file format: IMGFMT
439
-virtual size: 130M (136314880 bytes)
440
+virtual size: 130 MiB (136314880 bytes)
441
cluster_size: 65536
442
Format specific information:
443
compat: 1.1
444
@@ -XXX,XX +XXX,XX @@ Format specific information:
445
Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2
446
image: TEST_DIR/t.IMGFMT
447
file format: IMGFMT
448
-virtual size: 132M (138412032 bytes)
449
+virtual size: 132 MiB (138412032 bytes)
450
cluster_size: 65536
451
Format specific information:
452
compat: 1.1
453
@@ -XXX,XX +XXX,XX @@ Format specific information:
454
Testing: amend -f qcow2 -o size=4M,size=148M TEST_DIR/t.qcow2
455
image: TEST_DIR/t.IMGFMT
456
file format: IMGFMT
457
-virtual size: 148M (155189248 bytes)
458
+virtual size: 148 MiB (155189248 bytes)
459
cluster_size: 65536
460
461
=== amend: help for -o ===
462
diff --git a/tests/qemu-iotests/084.out b/tests/qemu-iotests/084.out
463
index XXXXXXX..XXXXXXX 100644
464
--- a/tests/qemu-iotests/084.out
465
+++ b/tests/qemu-iotests/084.out
466
@@ -XXX,XX +XXX,XX @@ QA output created by 084
467
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
468
image: TEST_DIR/t.IMGFMT
469
file format: IMGFMT
470
-virtual size: 64M (67108864 bytes)
471
+virtual size: 64 MiB (67108864 bytes)
472
cluster_size: 1048576
473
disk image file size in bytes: 67109888
474
475
@@ -XXX,XX +XXX,XX @@ disk image file size in bytes: 67109888
476
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
477
image: TEST_DIR/t.IMGFMT
478
file format: IMGFMT
479
-virtual size: 64M (67108864 bytes)
480
+virtual size: 64 MiB (67108864 bytes)
481
cluster_size: 1048576
482
disk image file size in bytes: 1024
483
Test 1: Maximum size (512 TB - 128 MB):
484
image: TEST_DIR/t.IMGFMT
485
file format: IMGFMT
486
-virtual size: 512T (562949819203584 bytes)
487
+virtual size: 512 TiB (562949819203584 bytes)
488
cluster_size: 1048576
489
490
Test 2: Size too large (512 TB - 128 MB + 64 kB)
491
@@ -XXX,XX +XXX,XX @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': unsupported VDI image (too many bl
492
Test 5: Valid Image: 64MB, Blocks In Image 64, Block Size 1MB
493
image: TEST_DIR/t.IMGFMT
494
file format: IMGFMT
495
-virtual size: 64M (67108864 bytes)
496
+virtual size: 64 MiB (67108864 bytes)
497
cluster_size: 1048576
498
499
Test 6: Block Size != 1MB; too small test (1MB - 1)
500
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
501
index XXXXXXX..XXXXXXX 100644
502
--- a/tests/qemu-iotests/089.out
503
+++ b/tests/qemu-iotests/089.out
504
@@ -XXX,XX +XXX,XX @@ read failed: Input/output error
505
506
image: TEST_DIR/t.IMGFMT
507
file format: IMGFMT
508
-virtual size: 64M (67108864 bytes)
509
+virtual size: 64 MiB (67108864 bytes)
510
cluster_size: 65536
511
512
=== Testing option merging ===
513
diff --git a/tests/qemu-iotests/095.out b/tests/qemu-iotests/095.out
514
index XXXXXXX..XXXXXXX 100644
515
--- a/tests/qemu-iotests/095.out
516
+++ b/tests/qemu-iotests/095.out
517
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file=TEST_DIR/
518
=== Base image info before commit and resize ===
519
image: TEST_DIR/t.IMGFMT.base
520
file format: IMGFMT
521
-virtual size: 5.0M (5242880 bytes)
522
+virtual size: 5 MiB (5242880 bytes)
523
524
=== Running QEMU Live Commit Test ===
525
526
@@ -XXX,XX +XXX,XX @@ virtual size: 5.0M (5242880 bytes)
527
=== Base image info after commit and resize ===
528
image: TEST_DIR/t.IMGFMT.base
529
file format: IMGFMT
530
-virtual size: 100M (104857600 bytes)
531
+virtual size: 100 MiB (104857600 bytes)
532
*** done
533
diff --git a/tests/qemu-iotests/104.out b/tests/qemu-iotests/104.out
534
index XXXXXXX..XXXXXXX 100644
535
--- a/tests/qemu-iotests/104.out
536
+++ b/tests/qemu-iotests/104.out
537
@@ -XXX,XX +XXX,XX @@ QA output created by 104
538
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
539
image: TEST_DIR/t.IMGFMT
540
file format: IMGFMT
541
-virtual size: 1.0K (1024 bytes)
542
+virtual size: 1 KiB (1024 bytes)
543
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1234
544
image: TEST_DIR/t.IMGFMT
545
file format: IMGFMT
546
-virtual size: 1.5K (1536 bytes)
547
-***done
548
+virtual size: 1.5 KiB (1536 bytes)
549
+*** done
550
diff --git a/tests/qemu-iotests/110.out b/tests/qemu-iotests/110.out
551
index XXXXXXX..XXXXXXX 100644
552
--- a/tests/qemu-iotests/110.out
553
+++ b/tests/qemu-iotests/110.out
554
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
555
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=t.IMGFMT.base
556
image: TEST_DIR/t.IMGFMT
557
file format: IMGFMT
558
-virtual size: 64M (67108864 bytes)
559
+virtual size: 64 MiB (67108864 bytes)
560
backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base)
561
562
=== Non-reconstructable filename ===
563
564
image: json:{"driver": "IMGFMT", "file": {"set-state.0.event": "read_aio", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "set-state.0.new_state": 42}}
565
file format: IMGFMT
566
-virtual size: 64M (67108864 bytes)
567
+virtual size: 64 MiB (67108864 bytes)
568
backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base)
569
570
=== Backing name is always relative to the backed image ===
571
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=t.IMGFMT.b
572
573
image: json:{"driver": "IMGFMT", "file": {"children": [{"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.copy"}], "driver": "quorum", "vote-threshold": 1}}
574
file format: IMGFMT
575
-virtual size: 64M (67108864 bytes)
576
+virtual size: 64 MiB (67108864 bytes)
577
backing file: t.IMGFMT.base (cannot determine actual path)
578
*** done
579
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
580
index XXXXXXX..XXXXXXX 100644
581
--- a/tests/qemu-iotests/114.out
582
+++ b/tests/qemu-iotests/114.out
583
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
584
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
585
image: TEST_DIR/t.IMGFMT
586
file format: IMGFMT
587
-virtual size: 64M (67108864 bytes)
588
+virtual size: 64 MiB (67108864 bytes)
589
cluster_size: 65536
590
backing file: TEST_DIR/t.IMGFMT.base
591
backing file format: foo
592
diff --git a/tests/qemu-iotests/126.out b/tests/qemu-iotests/126.out
593
index XXXXXXX..XXXXXXX 100644
594
--- a/tests/qemu-iotests/126.out
595
+++ b/tests/qemu-iotests/126.out
596
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/image:base.IMGFMT', fmt=IMGFMT size=67108864
597
Formatting 'TEST_DIR/image:top.IMGFMT', fmt=IMGFMT size=67108864 backing_file=./image:base.IMGFMT
598
image: TEST_DIR/image:top.IMGFMT
599
file format: IMGFMT
600
-virtual size: 64M (67108864 bytes)
601
+virtual size: 64 MiB (67108864 bytes)
602
backing file: ./image:base.IMGFMT (actual path: TEST_DIR/./image:base.IMGFMT)
603
604
Formatting 'base.IMGFMT', fmt=IMGFMT size=67108864
605
Formatting 'file:image:top.IMGFMT', fmt=IMGFMT size=67108864 backing_file=base.IMGFMT
606
image: ./image:top.IMGFMT
607
file format: IMGFMT
608
-virtual size: 64M (67108864 bytes)
609
+virtual size: 64 MiB (67108864 bytes)
610
backing file: base.IMGFMT (actual path: ./base.IMGFMT)
611
*** done
612
diff --git a/tests/qemu-iotests/130.out b/tests/qemu-iotests/130.out
613
index XXXXXXX..XXXXXXX 100644
614
--- a/tests/qemu-iotests/130.out
615
+++ b/tests/qemu-iotests/130.out
616
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
617
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
618
image: TEST_DIR/t.IMGFMT
619
file format: IMGFMT
620
-virtual size: 64M (67108864 bytes)
621
+virtual size: 64 MiB (67108864 bytes)
622
623
=== HMP commit ===
624
625
@@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information
626
(qemu)
627
image: TEST_DIR/t.IMGFMT
628
file format: IMGFMT
629
-virtual size: 64M (67108864 bytes)
630
+virtual size: 64 MiB (67108864 bytes)
631
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig backing_fmt=raw
632
QEMU X.Y.Z monitor - type 'help' for more information
633
(qemu) commit testdisk
634
(qemu)
635
image: TEST_DIR/t.IMGFMT
636
file format: IMGFMT
637
-virtual size: 64M (67108864 bytes)
638
+virtual size: 64 MiB (67108864 bytes)
639
backing file: TEST_DIR/t.IMGFMT.orig
640
backing file format: raw
641
642
@@ -XXX,XX +XXX,XX @@ wrote 4096/4096 bytes at offset 0
643
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
644
image: TEST_DIR/t.IMGFMT
645
file format: IMGFMT
646
-virtual size: 64M (67108864 bytes)
647
+virtual size: 64 MiB (67108864 bytes)
648
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig backing_fmt=raw
649
wrote 4096/4096 bytes at offset 0
650
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
651
image: TEST_DIR/t.IMGFMT
652
file format: IMGFMT
653
-virtual size: 64M (67108864 bytes)
654
+virtual size: 64 MiB (67108864 bytes)
655
backing file: TEST_DIR/t.IMGFMT.orig
656
backing file format: raw
657
*** done
658
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
659
index XXXXXXX..XXXXXXX 100644
660
--- a/tests/qemu-iotests/153.out
661
+++ b/tests/qemu-iotests/153.out
662
@@ -XXX,XX +XXX,XX @@ _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
663
No conflict:
664
image: null-co://
665
file format: null-co
666
-virtual size: 1.0G (1073741824 bytes)
667
+virtual size: 1 GiB (1073741824 bytes)
668
disk size: unavailable
669
670
Conflict:
671
diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
672
index XXXXXXX..XXXXXXX 100644
673
--- a/tests/qemu-iotests/191.out
674
+++ b/tests/qemu-iotests/191.out
675
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 1048576
676
}
51
}
677
image: TEST_DIR/t.IMGFMT
52
678
file format: IMGFMT
53
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_end(BlockDriverState *bs)
679
-virtual size: 64M (67108864 bytes)
54
}
680
+virtual size: 64 MiB (67108864 bytes)
55
681
cluster_size: 65536
56
/* Re-enable things in child-to-parent order */
682
backing file: TEST_DIR/t.IMGFMT.base
57
- bdrv_drain_invoke(bs, false);
683
backing file format: IMGFMT
58
+ bdrv_drain_invoke(bs, false, false);
684
image: TEST_DIR/t.IMGFMT.ovl2
59
bdrv_parent_drained_end(bs);
685
file format: IMGFMT
60
aio_enable_external(bdrv_get_aio_context(bs));
686
-virtual size: 64M (67108864 bytes)
687
+virtual size: 64 MiB (67108864 bytes)
688
cluster_size: 65536
689
backing file: TEST_DIR/t.IMGFMT.base
690
backing file format: IMGFMT
691
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 1048576
692
}
61
}
693
image: TEST_DIR/t.IMGFMT
62
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
694
file format: IMGFMT
63
aio_context_acquire(aio_context);
695
-virtual size: 64M (67108864 bytes)
64
aio_disable_external(aio_context);
696
+virtual size: 64 MiB (67108864 bytes)
65
bdrv_parent_drained_begin(bs);
697
cluster_size: 65536
66
- bdrv_drain_invoke(bs, true);
698
backing file: TEST_DIR/t.IMGFMT.base
67
+ bdrv_drain_invoke(bs, true, true);
699
backing file format: IMGFMT
68
aio_context_release(aio_context);
700
image: TEST_DIR/t.IMGFMT.ovl2
69
701
file format: IMGFMT
70
if (!g_slist_find(aio_ctxs, aio_context)) {
702
-virtual size: 64M (67108864 bytes)
71
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
703
+virtual size: 64 MiB (67108864 bytes)
72
704
cluster_size: 65536
73
/* Re-enable things in child-to-parent order */
705
backing file: TEST_DIR/t.IMGFMT.base
74
aio_context_acquire(aio_context);
706
backing file format: IMGFMT
75
- bdrv_drain_invoke(bs, false);
707
diff --git a/tests/qemu-iotests/195.out b/tests/qemu-iotests/195.out
76
+ bdrv_drain_invoke(bs, false, true);
708
index XXXXXXX..XXXXXXX 100644
77
bdrv_parent_drained_end(bs);
709
--- a/tests/qemu-iotests/195.out
78
aio_enable_external(aio_context);
710
+++ b/tests/qemu-iotests/195.out
79
aio_context_release(aio_context);
711
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid
712
713
image: TEST_DIR/t.IMGFMT.mid
714
file format: IMGFMT
715
-virtual size: 64M (67108864 bytes)
716
+virtual size: 64 MiB (67108864 bytes)
717
cluster_size: 65536
718
backing file: /dev/null
719
backing file format: IMGFMT
720
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top
721
722
image: TEST_DIR/t.IMGFMT
723
file format: IMGFMT
724
-virtual size: 64M (67108864 bytes)
725
+virtual size: 64 MiB (67108864 bytes)
726
cluster_size: 65536
727
backing file: /dev/null
728
backing file format: IMGFMT
729
diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out
730
index XXXXXXX..XXXXXXX 100644
731
--- a/tests/qemu-iotests/198.out
732
+++ b/tests/qemu-iotests/198.out
733
@@ -XXX,XX +XXX,XX @@ read 16777216/16777216 bytes at offset 0
734
== checking image base ==
735
image: json:{"encrypt.key-secret": "sec0", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.base"}}
736
file format: IMGFMT
737
-virtual size: 16M (16777216 bytes)
738
+virtual size: 16 MiB (16777216 bytes)
739
Format specific information:
740
encrypt:
741
ivgen alg: plain64
742
@@ -XXX,XX +XXX,XX @@ Format specific information:
743
== checking image layer ==
744
image: json:{"encrypt.key-secret": "sec1", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}
745
file format: IMGFMT
746
-virtual size: 16M (16777216 bytes)
747
+virtual size: 16 MiB (16777216 bytes)
748
backing file: TEST_DIR/t.IMGFMT.base
749
Format specific information:
750
encrypt:
751
diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out
752
index XXXXXXX..XXXXXXX 100644
753
--- a/tests/qemu-iotests/206.out
754
+++ b/tests/qemu-iotests/206.out
755
@@ -XXX,XX +XXX,XX @@
756
757
image: TEST_IMG
758
file format: IMGFMT
759
-virtual size: 128M (134217728 bytes)
760
+virtual size: 128 MiB (134217728 bytes)
761
cluster_size: 65536
762
Format specific information:
763
compat: 1.1
764
@@ -XXX,XX +XXX,XX @@ Format specific information:
765
766
image: TEST_IMG
767
file format: IMGFMT
768
-virtual size: 64M (67108864 bytes)
769
+virtual size: 64 MiB (67108864 bytes)
770
cluster_size: 65536
771
Format specific information:
772
compat: 1.1
773
@@ -XXX,XX +XXX,XX @@ Format specific information:
774
775
image: TEST_IMG
776
file format: IMGFMT
777
-virtual size: 32M (33554432 bytes)
778
+virtual size: 32 MiB (33554432 bytes)
779
cluster_size: 2097152
780
Format specific information:
781
compat: 1.1
782
@@ -XXX,XX +XXX,XX @@ Format specific information:
783
784
image: TEST_IMG
785
file format: IMGFMT
786
-virtual size: 32M (33554432 bytes)
787
+virtual size: 32 MiB (33554432 bytes)
788
cluster_size: 512
789
backing file: TEST_IMG.base
790
backing file format: IMGFMT
791
@@ -XXX,XX +XXX,XX @@ Format specific information:
792
793
image: TEST_IMG
794
file format: IMGFMT
795
-virtual size: 32M (33554432 bytes)
796
+virtual size: 32 MiB (33554432 bytes)
797
encrypted: yes
798
cluster_size: 65536
799
Format specific information:
800
diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out
801
index XXXXXXX..XXXXXXX 100644
802
--- a/tests/qemu-iotests/207.out
803
+++ b/tests/qemu-iotests/207.out
804
@@ -XXX,XX +XXX,XX @@
805
806
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
807
file format: IMGFMT
808
-virtual size: 4.0M (4194304 bytes)
809
+virtual size: 4 MiB (4194304 bytes)
810
811
812
image: TEST_IMG
813
file format: IMGFMT
814
-virtual size: 4.0M (4194304 bytes)
815
+virtual size: 4 MiB (4194304 bytes)
816
817
=== Test host-key-check options ===
818
819
@@ -XXX,XX +XXX,XX @@ virtual size: 4.0M (4194304 bytes)
820
821
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
822
file format: IMGFMT
823
-virtual size: 8.0M (8388608 bytes)
824
+virtual size: 8 MiB (8388608 bytes)
825
826
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "known_hosts"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}}
827
{"return": {}}
828
@@ -XXX,XX +XXX,XX @@ virtual size: 8.0M (8388608 bytes)
829
830
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
831
file format: IMGFMT
832
-virtual size: 4.0M (4194304 bytes)
833
+virtual size: 4 MiB (4194304 bytes)
834
835
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "md5"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}}
836
{"return": {}}
837
@@ -XXX,XX +XXX,XX @@ Job failed: remote host key does not match host_key_check 'wrong'
838
839
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
840
file format: IMGFMT
841
-virtual size: 8.0M (8388608 bytes)
842
+virtual size: 8 MiB (8388608 bytes)
843
844
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "sha1"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}}
845
{"return": {}}
846
@@ -XXX,XX +XXX,XX @@ Job failed: remote host key does not match host_key_check 'wrong'
847
848
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
849
file format: IMGFMT
850
-virtual size: 4.0M (4194304 bytes)
851
+virtual size: 4 MiB (4194304 bytes)
852
853
=== Invalid path and user ===
854
855
diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out
856
index XXXXXXX..XXXXXXX 100644
857
--- a/tests/qemu-iotests/210.out
858
+++ b/tests/qemu-iotests/210.out
859
@@ -XXX,XX +XXX,XX @@
860
861
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
862
file format: IMGFMT
863
-virtual size: 128M (134217728 bytes)
864
+virtual size: 128 MiB (134217728 bytes)
865
encrypted: yes
866
Format specific information:
867
ivgen alg: plain64
868
@@ -XXX,XX +XXX,XX @@ Format specific information:
869
870
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
871
file format: IMGFMT
872
-virtual size: 64M (67108864 bytes)
873
+virtual size: 64 MiB (67108864 bytes)
874
encrypted: yes
875
Format specific information:
876
ivgen alg: plain64
877
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
878
879
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
880
file format: IMGFMT
881
-virtual size: 0 (0 bytes)
882
+virtual size: 0 B (0 bytes)
883
encrypted: yes
884
Format specific information:
885
ivgen alg: plain64
886
@@ -XXX,XX +XXX,XX @@ Job failed: The requested file size is too large
887
{"error": {"class": "GenericError", "desc": "Parameter 'size' expects a >0 size"}}
888
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
889
file format: IMGFMT
890
-virtual size: 0 (0 bytes)
891
+virtual size: 0 B (0 bytes)
892
encrypted: yes
893
Format specific information:
894
ivgen alg: plain64
895
diff --git a/tests/qemu-iotests/211.out b/tests/qemu-iotests/211.out
896
index XXXXXXX..XXXXXXX 100644
897
--- a/tests/qemu-iotests/211.out
898
+++ b/tests/qemu-iotests/211.out
899
@@ -XXX,XX +XXX,XX @@
900
901
image: TEST_IMG
902
file format: IMGFMT
903
-virtual size: 128M (134217728 bytes)
904
+virtual size: 128 MiB (134217728 bytes)
905
cluster_size: 1048576
906
907
[{ "start": 0, "length": 134217728, "depth": 0, "zero": true, "data": false}]
908
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
909
910
image: TEST_IMG
911
file format: IMGFMT
912
-virtual size: 64M (67108864 bytes)
913
+virtual size: 64 MiB (67108864 bytes)
914
cluster_size: 1048576
915
916
[{ "start": 0, "length": 67108864, "depth": 0, "zero": true, "data": false}]
917
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
918
919
image: TEST_IMG
920
file format: IMGFMT
921
-virtual size: 32M (33554432 bytes)
922
+virtual size: 32 MiB (33554432 bytes)
923
cluster_size: 1048576
924
925
[{ "start": 0, "length": 3072, "depth": 0, "zero": false, "data": true, "offset": 1024},
926
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
927
928
image: TEST_IMG
929
file format: IMGFMT
930
-virtual size: 0 (0 bytes)
931
+virtual size: 0 B (0 bytes)
932
cluster_size: 1048576
933
934
=== Maximum size ===
935
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
936
937
image: TEST_IMG
938
file format: IMGFMT
939
-virtual size: 512T (562949819203584 bytes)
940
+virtual size: 512 TiB (562949819203584 bytes)
941
cluster_size: 1048576
942
943
=== Invalid sizes ===
944
diff --git a/tests/qemu-iotests/212.out b/tests/qemu-iotests/212.out
945
index XXXXXXX..XXXXXXX 100644
946
--- a/tests/qemu-iotests/212.out
947
+++ b/tests/qemu-iotests/212.out
948
@@ -XXX,XX +XXX,XX @@
949
950
image: TEST_IMG
951
file format: IMGFMT
952
-virtual size: 128M (134217728 bytes)
953
+virtual size: 128 MiB (134217728 bytes)
954
955
=== Successful image creation (explicit defaults) ===
956
957
@@ -XXX,XX +XXX,XX @@ virtual size: 128M (134217728 bytes)
958
959
image: TEST_IMG
960
file format: IMGFMT
961
-virtual size: 64M (67108864 bytes)
962
+virtual size: 64 MiB (67108864 bytes)
963
964
=== Successful image creation (with non-default options) ===
965
966
@@ -XXX,XX +XXX,XX @@ virtual size: 64M (67108864 bytes)
967
968
image: TEST_IMG
969
file format: IMGFMT
970
-virtual size: 32M (33554432 bytes)
971
+virtual size: 32 MiB (33554432 bytes)
972
973
=== Invalid BlockdevRef ===
974
975
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
976
977
image: TEST_IMG
978
file format: IMGFMT
979
-virtual size: 0 (0 bytes)
980
+virtual size: 0 B (0 bytes)
981
982
=== Maximum size ===
983
984
@@ -XXX,XX +XXX,XX @@ virtual size: 0 (0 bytes)
985
986
image: TEST_IMG
987
file format: IMGFMT
988
-virtual size: 4096T (4503599627369984 bytes)
989
+virtual size: 4 PiB (4503599627369984 bytes)
990
991
=== Invalid sizes ===
992
993
diff --git a/tests/qemu-iotests/213.out b/tests/qemu-iotests/213.out
994
index XXXXXXX..XXXXXXX 100644
995
--- a/tests/qemu-iotests/213.out
996
+++ b/tests/qemu-iotests/213.out
997
@@ -XXX,XX +XXX,XX @@
998
999
image: TEST_IMG
1000
file format: IMGFMT
1001
-virtual size: 128M (134217728 bytes)
1002
+virtual size: 128 MiB (134217728 bytes)
1003
cluster_size: 8388608
1004
1005
=== Successful image creation (explicit defaults) ===
1006
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
1007
1008
image: TEST_IMG
1009
file format: IMGFMT
1010
-virtual size: 64M (67108864 bytes)
1011
+virtual size: 64 MiB (67108864 bytes)
1012
cluster_size: 8388608
1013
1014
=== Successful image creation (with non-default options) ===
1015
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
1016
1017
image: TEST_IMG
1018
file format: IMGFMT
1019
-virtual size: 32M (33554432 bytes)
1020
+virtual size: 32 MiB (33554432 bytes)
1021
cluster_size: 268435456
1022
1023
=== Invalid BlockdevRef ===
1024
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
1025
1026
image: TEST_IMG
1027
file format: IMGFMT
1028
-virtual size: 0 (0 bytes)
1029
+virtual size: 0 B (0 bytes)
1030
cluster_size: 8388608
1031
1032
=== Maximum size ===
1033
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
1034
1035
image: TEST_IMG
1036
file format: IMGFMT
1037
-virtual size: 64T (70368744177664 bytes)
1038
+virtual size: 64 TiB (70368744177664 bytes)
1039
cluster_size: 67108864
1040
1041
=== Invalid sizes ===
1042
diff --git a/tests/qemu-iotests/233.out b/tests/qemu-iotests/233.out
1043
index XXXXXXX..XXXXXXX 100644
1044
--- a/tests/qemu-iotests/233.out
1045
+++ b/tests/qemu-iotests/233.out
1046
@@ -XXX,XX +XXX,XX @@ server reported: Option 0x8 not permitted before TLS
1047
== check TLS works ==
1048
image: nbd://127.0.0.1:PORT
1049
file format: nbd
1050
-virtual size: 64M (67108864 bytes)
1051
+virtual size: 64 MiB (67108864 bytes)
1052
disk size: unavailable
1053
image: nbd://127.0.0.1:PORT
1054
file format: nbd
1055
-virtual size: 64M (67108864 bytes)
1056
+virtual size: 64 MiB (67108864 bytes)
1057
disk size: unavailable
1058
exports available: 1
1059
export: ''
1060
diff --git a/tests/qemu-iotests/237.out b/tests/qemu-iotests/237.out
1061
index XXXXXXX..XXXXXXX 100644
1062
--- a/tests/qemu-iotests/237.out
1063
+++ b/tests/qemu-iotests/237.out
1064
@@ -XXX,XX +XXX,XX @@
1065
1066
image: TEST_IMG
1067
file format: IMGFMT
1068
-virtual size: 5.0G (5368709120 bytes)
1069
+virtual size: 5 GiB (5368709120 bytes)
1070
cluster_size: 65536
1071
Format specific information:
1072
cid: XXXXXXXXXX
1073
@@ -XXX,XX +XXX,XX @@ Format specific information:
1074
1075
image: TEST_IMG
1076
file format: IMGFMT
1077
-virtual size: 64M (67108864 bytes)
1078
+virtual size: 64 MiB (67108864 bytes)
1079
cluster_size: 65536
1080
Format specific information:
1081
cid: XXXXXXXXXX
1082
@@ -XXX,XX +XXX,XX @@ Format specific information:
1083
1084
image: TEST_IMG
1085
file format: IMGFMT
1086
-virtual size: 32M (33554432 bytes)
1087
+virtual size: 32 MiB (33554432 bytes)
1088
cluster_size: 65536
1089
Format specific information:
1090
cid: XXXXXXXXXX
1091
@@ -XXX,XX +XXX,XX @@ Job failed: List of extents contains unused extents
1092
1093
image: TEST_IMG
1094
file format: IMGFMT
1095
-virtual size: 512 (512 bytes)
1096
+virtual size: 512 B (512 bytes)
1097
Format specific information:
1098
cid: XXXXXXXXXX
1099
parent cid: XXXXXXXXXX
1100
@@ -XXX,XX +XXX,XX @@ Format specific information:
1101
1102
image: TEST_IMG
1103
file format: IMGFMT
1104
-virtual size: 512 (512 bytes)
1105
+virtual size: 512 B (512 bytes)
1106
cluster_size: 65536
1107
Format specific information:
1108
cid: XXXXXXXXXX
1109
@@ -XXX,XX +XXX,XX @@ Format specific information:
1110
1111
image: TEST_IMG
1112
file format: IMGFMT
1113
-virtual size: 1.0G (1073741824 bytes)
1114
+virtual size: 1 GiB (1073741824 bytes)
1115
Format specific information:
1116
cid: XXXXXXXXXX
1117
parent cid: XXXXXXXXXX
1118
@@ -XXX,XX +XXX,XX @@ Format specific information:
1119
1120
image: TEST_IMG
1121
file format: IMGFMT
1122
-virtual size: 1.0G (1073741824 bytes)
1123
+virtual size: 1 GiB (1073741824 bytes)
1124
cluster_size: 65536
1125
Format specific information:
1126
cid: XXXXXXXXXX
1127
@@ -XXX,XX +XXX,XX @@ Format specific information:
1128
1129
image: TEST_IMG
1130
file format: IMGFMT
1131
-virtual size: 2.0G (2147483648 bytes)
1132
+virtual size: 2 GiB (2147483648 bytes)
1133
Format specific information:
1134
cid: XXXXXXXXXX
1135
parent cid: XXXXXXXXXX
1136
@@ -XXX,XX +XXX,XX @@ Format specific information:
1137
1138
image: TEST_IMG
1139
file format: IMGFMT
1140
-virtual size: 2.0G (2147483648 bytes)
1141
+virtual size: 2 GiB (2147483648 bytes)
1142
cluster_size: 65536
1143
Format specific information:
1144
cid: XXXXXXXXXX
1145
@@ -XXX,XX +XXX,XX @@ Format specific information:
1146
1147
image: TEST_IMG
1148
file format: IMGFMT
1149
-virtual size: 5.0G (5368709120 bytes)
1150
+virtual size: 5 GiB (5368709120 bytes)
1151
Format specific information:
1152
cid: XXXXXXXXXX
1153
parent cid: XXXXXXXXXX
1154
@@ -XXX,XX +XXX,XX @@ Format specific information:
1155
1156
image: TEST_IMG
1157
file format: IMGFMT
1158
-virtual size: 5.0G (5368709120 bytes)
1159
+virtual size: 5 GiB (5368709120 bytes)
1160
cluster_size: 65536
1161
Format specific information:
1162
cid: XXXXXXXXXX
1163
diff --git a/tests/qemu-iotests/242.out b/tests/qemu-iotests/242.out
1164
index XXXXXXX..XXXXXXX 100644
1165
--- a/tests/qemu-iotests/242.out
1166
+++ b/tests/qemu-iotests/242.out
1167
@@ -XXX,XX +XXX,XX @@ qemu-img info dump:
1168
1169
image: TEST_IMG
1170
file format: IMGFMT
1171
-virtual size: 1.0M (1048576 bytes)
1172
+virtual size: 1 MiB (1048576 bytes)
1173
cluster_size: 65536
1174
Format specific information:
1175
compat: 1.1
1176
@@ -XXX,XX +XXX,XX @@ qemu-img info dump:
1177
1178
image: TEST_IMG
1179
file format: IMGFMT
1180
-virtual size: 1.0M (1048576 bytes)
1181
+virtual size: 1 MiB (1048576 bytes)
1182
cluster_size: 65536
1183
Format specific information:
1184
compat: 1.1
1185
@@ -XXX,XX +XXX,XX @@ qemu-img info dump:
1186
1187
image: TEST_IMG
1188
file format: IMGFMT
1189
-virtual size: 1.0M (1048576 bytes)
1190
+virtual size: 1 MiB (1048576 bytes)
1191
cluster_size: 65536
1192
Format specific information:
1193
compat: 1.1
1194
@@ -XXX,XX +XXX,XX @@ qemu-img info dump:
1195
1196
image: TEST_IMG
1197
file format: IMGFMT
1198
-virtual size: 1.0M (1048576 bytes)
1199
+virtual size: 1 MiB (1048576 bytes)
1200
cluster_size: 65536
1201
Format specific information:
1202
compat: 1.1
1203
@@ -XXX,XX +XXX,XX @@ Unset the unknown bitmap flag '0x4' in the bitmap directory entry:
1204
1205
image: TEST_IMG
1206
file format: IMGFMT
1207
-virtual size: 1.0M (1048576 bytes)
1208
+virtual size: 1 MiB (1048576 bytes)
1209
cluster_size: 65536
1210
Format specific information:
1211
compat: 1.1
1212
--
80
--
1213
2.20.1
81
2.13.6
1214
82
1215
83
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
The existing test is for bdrv_drain_all_begin/end() only. Generalise the
2
test case so that it can be run for the other variants as well. At the
3
moment this is only bdrv_drain_begin/end(), but in a while, we'll add
4
another one.
2
5
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Also, add a backing file to the test node to test whether the operations
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
work recursively.
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
8
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
10
---
8
block/commit.c | 5 ++---
11
tests/test-bdrv-drain.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-----
9
1 file changed, 2 insertions(+), 3 deletions(-)
12
1 file changed, 62 insertions(+), 7 deletions(-)
10
13
11
diff --git a/block/commit.c b/block/commit.c
14
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/block/commit.c
16
--- a/tests/test-bdrv-drain.c
14
+++ b/block/commit.c
17
+++ b/tests/test-bdrv-drain.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base,
18
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_test = {
16
void *buf)
19
20
.bdrv_co_drain_begin = bdrv_test_co_drain_begin,
21
.bdrv_co_drain_end = bdrv_test_co_drain_end,
22
+
23
+ .bdrv_child_perm = bdrv_format_default_perms,
24
};
25
26
static void aio_ret_cb(void *opaque, int ret)
27
@@ -XXX,XX +XXX,XX @@ static void aio_ret_cb(void *opaque, int ret)
28
*aio_ret = ret;
29
}
30
31
-static void test_drv_cb_drain_all(void)
32
+enum drain_type {
33
+ BDRV_DRAIN_ALL,
34
+ BDRV_DRAIN,
35
+};
36
+
37
+static void do_drain_begin(enum drain_type drain_type, BlockDriverState *bs)
38
+{
39
+ switch (drain_type) {
40
+ case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); break;
41
+ case BDRV_DRAIN: bdrv_drained_begin(bs); break;
42
+ default: g_assert_not_reached();
43
+ }
44
+}
45
+
46
+static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs)
47
+{
48
+ switch (drain_type) {
49
+ case BDRV_DRAIN_ALL: bdrv_drain_all_end(); break;
50
+ case BDRV_DRAIN: bdrv_drained_end(bs); break;
51
+ default: g_assert_not_reached();
52
+ }
53
+}
54
+
55
+static void test_drv_cb_common(enum drain_type drain_type, bool recursive)
17
{
56
{
18
int ret = 0;
57
BlockBackend *blk;
19
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
58
- BlockDriverState *bs;
20
59
- BDRVTestState *s;
21
assert(bytes < SIZE_MAX);
60
+ BlockDriverState *bs, *backing;
22
61
+ BDRVTestState *s, *backing_s;
23
- ret = blk_co_preadv(bs, offset, qiov.size, &qiov, 0);
62
BlockAIOCB *acb;
24
+ ret = blk_co_pread(bs, offset, bytes, buf, 0);
63
int aio_ret;
25
if (ret < 0) {
64
26
return ret;
65
@@ -XXX,XX +XXX,XX @@ static void test_drv_cb_drain_all(void)
27
}
66
s = bs->opaque;
28
67
blk_insert_bs(blk, bs, &error_abort);
29
- ret = blk_co_pwritev(base, offset, qiov.size, &qiov, 0);
68
30
+ ret = blk_co_pwrite(base, offset, bytes, buf, 0);
69
+ backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
31
if (ret < 0) {
70
+ backing_s = backing->opaque;
32
return ret;
71
+ bdrv_set_backing_hd(bs, backing, &error_abort);
33
}
72
+
73
/* Simple bdrv_drain_all_begin/end pair, check that CBs are called */
74
g_assert_cmpint(s->drain_count, ==, 0);
75
- bdrv_drain_all_begin();
76
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
77
+
78
+ do_drain_begin(drain_type, bs);
79
+
80
g_assert_cmpint(s->drain_count, ==, 1);
81
- bdrv_drain_all_end();
82
+ g_assert_cmpint(backing_s->drain_count, ==, !!recursive);
83
+
84
+ do_drain_end(drain_type, bs);
85
+
86
g_assert_cmpint(s->drain_count, ==, 0);
87
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
88
89
/* Now do the same while a request is pending */
90
aio_ret = -EINPROGRESS;
91
@@ -XXX,XX +XXX,XX @@ static void test_drv_cb_drain_all(void)
92
g_assert_cmpint(aio_ret, ==, -EINPROGRESS);
93
94
g_assert_cmpint(s->drain_count, ==, 0);
95
- bdrv_drain_all_begin();
96
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
97
+
98
+ do_drain_begin(drain_type, bs);
99
+
100
g_assert_cmpint(aio_ret, ==, 0);
101
g_assert_cmpint(s->drain_count, ==, 1);
102
- bdrv_drain_all_end();
103
+ g_assert_cmpint(backing_s->drain_count, ==, !!recursive);
104
+
105
+ do_drain_end(drain_type, bs);
106
+
107
g_assert_cmpint(s->drain_count, ==, 0);
108
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
109
110
+ bdrv_unref(backing);
111
bdrv_unref(bs);
112
blk_unref(blk);
113
}
114
115
+static void test_drv_cb_drain_all(void)
116
+{
117
+ test_drv_cb_common(BDRV_DRAIN_ALL, true);
118
+}
119
+
120
+static void test_drv_cb_drain(void)
121
+{
122
+ test_drv_cb_common(BDRV_DRAIN, false);
123
+}
124
+
125
int main(int argc, char **argv)
126
{
127
bdrv_init();
128
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
129
g_test_init(&argc, &argv, NULL);
130
131
g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all);
132
+ g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain);
133
134
return g_test_run();
135
}
34
--
136
--
35
2.20.1
137
2.13.6
36
138
37
139
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
This is currently only working correctly for bdrv_drain(), not for
2
bdrv_drain_all(). Leave a comment for the drain_all case, we'll address
3
it later.
2
4
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
6
---
8
qemu-img.c | 13 ++++---------
7
tests/test-bdrv-drain.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
9
1 file changed, 4 insertions(+), 9 deletions(-)
8
1 file changed, 45 insertions(+)
10
9
11
diff --git a/qemu-img.c b/qemu-img.c
10
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/qemu-img.c
12
--- a/tests/test-bdrv-drain.c
14
+++ b/qemu-img.c
13
+++ b/tests/test-bdrv-drain.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_read(ImgConvertState *s, int64_t sector_num,
14
@@ -XXX,XX +XXX,XX @@ static void test_drv_cb_drain(void)
16
int nb_sectors, uint8_t *buf)
15
test_drv_cb_common(BDRV_DRAIN, false);
16
}
17
18
+static void test_quiesce_common(enum drain_type drain_type, bool recursive)
19
+{
20
+ BlockBackend *blk;
21
+ BlockDriverState *bs, *backing;
22
+
23
+ blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
24
+ bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
25
+ &error_abort);
26
+ blk_insert_bs(blk, bs, &error_abort);
27
+
28
+ backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
29
+ bdrv_set_backing_hd(bs, backing, &error_abort);
30
+
31
+ g_assert_cmpint(bs->quiesce_counter, ==, 0);
32
+ g_assert_cmpint(backing->quiesce_counter, ==, 0);
33
+
34
+ do_drain_begin(drain_type, bs);
35
+
36
+ g_assert_cmpint(bs->quiesce_counter, ==, 1);
37
+ g_assert_cmpint(backing->quiesce_counter, ==, !!recursive);
38
+
39
+ do_drain_end(drain_type, bs);
40
+
41
+ g_assert_cmpint(bs->quiesce_counter, ==, 0);
42
+ g_assert_cmpint(backing->quiesce_counter, ==, 0);
43
+
44
+ bdrv_unref(backing);
45
+ bdrv_unref(bs);
46
+ blk_unref(blk);
47
+}
48
+
49
+static void test_quiesce_drain_all(void)
50
+{
51
+ // XXX drain_all doesn't quiesce
52
+ //test_quiesce_common(BDRV_DRAIN_ALL, true);
53
+}
54
+
55
+static void test_quiesce_drain(void)
56
+{
57
+ test_quiesce_common(BDRV_DRAIN, false);
58
+}
59
+
60
int main(int argc, char **argv)
17
{
61
{
18
int n, ret;
62
bdrv_init();
19
- QEMUIOVector qiov;
63
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
20
64
g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all);
21
assert(nb_sectors <= s->buf_sectors);
65
g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain);
22
while (nb_sectors > 0) {
66
23
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_read(ImgConvertState *s, int64_t sector_num,
67
+ g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all);
24
bs_sectors = s->src_sectors[src_cur];
68
+ g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain);
25
69
+
26
n = MIN(nb_sectors, bs_sectors - (sector_num - src_cur_offset));
70
return g_test_run();
27
- qemu_iovec_init_buf(&qiov, buf, n << BDRV_SECTOR_BITS);
71
}
28
29
- ret = blk_co_preadv(
30
+ ret = blk_co_pread(
31
blk, (sector_num - src_cur_offset) << BDRV_SECTOR_BITS,
32
- n << BDRV_SECTOR_BITS, &qiov, 0);
33
+ n << BDRV_SECTOR_BITS, buf, 0);
34
if (ret < 0) {
35
return ret;
36
}
37
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
38
enum ImgConvertBlockStatus status)
39
{
40
int ret;
41
- QEMUIOVector qiov;
42
43
while (nb_sectors > 0) {
44
int n = nb_sectors;
45
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
46
(s->compressed &&
47
!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)))
48
{
49
- qemu_iovec_init_buf(&qiov, buf, n << BDRV_SECTOR_BITS);
50
-
51
- ret = blk_co_pwritev(s->target, sector_num << BDRV_SECTOR_BITS,
52
- n << BDRV_SECTOR_BITS, &qiov, flags);
53
+ ret = blk_co_pwrite(s->target, sector_num << BDRV_SECTOR_BITS,
54
+ n << BDRV_SECTOR_BITS, buf, flags);
55
if (ret < 0) {
56
return ret;
57
}
58
--
72
--
59
2.20.1
73
2.13.6
60
74
61
75
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
Block jobs already paused themselves when their main BlockBackend
2
entered a drained section. This is not good enough: We also want to
3
pause a block job and may not submit new requests if, for example, the
4
mirror target node should be drained.
2
5
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
This implements .drained_begin/end callbacks in child_job in order to
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
consider all block nodes related to the job, and removes the
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
8
BlockBackend callbacks which are unnecessary now because the root of the
9
job main BlockBackend is always referenced with a child_job, too.
10
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
12
---
8
block/parallels.c | 14 ++++++--------
13
blockjob.c | 22 +++++++++-------------
9
1 file changed, 6 insertions(+), 8 deletions(-)
14
1 file changed, 9 insertions(+), 13 deletions(-)
10
15
11
diff --git a/block/parallels.c b/block/parallels.c
16
diff --git a/blockjob.c b/blockjob.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/block/parallels.c
18
--- a/blockjob.c
14
+++ b/block/parallels.c
19
+++ b/blockjob.c
15
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
20
@@ -XXX,XX +XXX,XX @@ static char *child_job_get_parent_desc(BdrvChild *c)
16
if (bs->backing) {
21
job->id);
17
int64_t nb_cow_sectors = to_allocate * s->tracks;
22
}
18
int64_t nb_cow_bytes = nb_cow_sectors << BDRV_SECTOR_BITS;
23
19
- QEMUIOVector qiov =
24
-static const BdrvChildRole child_job = {
20
- QEMU_IOVEC_INIT_BUF(qiov, qemu_blockalign(bs, nb_cow_bytes),
25
- .get_parent_desc = child_job_get_parent_desc,
21
- nb_cow_bytes);
26
- .stay_at_node = true,
22
+ void *buf = qemu_blockalign(bs, nb_cow_bytes);
27
-};
23
28
-
24
- ret = bdrv_co_preadv(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
29
-static void block_job_drained_begin(void *opaque)
25
- nb_cow_bytes, &qiov, 0);
30
+static void child_job_drained_begin(BdrvChild *c)
26
+ ret = bdrv_co_pread(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
31
{
27
+ nb_cow_bytes, buf, 0);
32
- BlockJob *job = opaque;
28
if (ret < 0) {
33
+ BlockJob *job = c->opaque;
29
- qemu_vfree(qemu_iovec_buf(&qiov));
34
block_job_pause(job);
30
+ qemu_vfree(buf);
35
}
31
return ret;
36
32
}
37
-static void block_job_drained_end(void *opaque)
33
38
+static void child_job_drained_end(BdrvChild *c)
34
ret = bdrv_co_pwritev(bs->file, s->data_end * BDRV_SECTOR_SIZE,
39
{
35
- nb_cow_bytes, &qiov, 0);
40
- BlockJob *job = opaque;
36
- qemu_vfree(qemu_iovec_buf(&qiov));
41
+ BlockJob *job = c->opaque;
37
+ nb_cow_bytes, buf, 0);
42
block_job_resume(job);
38
+ qemu_vfree(buf);
43
}
39
if (ret < 0) {
44
40
return ret;
45
-static const BlockDevOps block_job_dev_ops = {
41
}
46
- .drained_begin = block_job_drained_begin,
47
- .drained_end = block_job_drained_end,
48
+static const BdrvChildRole child_job = {
49
+ .get_parent_desc = child_job_get_parent_desc,
50
+ .drained_begin = child_job_drained_begin,
51
+ .drained_end = child_job_drained_end,
52
+ .stay_at_node = true,
53
};
54
55
void block_job_remove_all_bdrv(BlockJob *job)
56
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
57
block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
58
bs->job = job;
59
60
- blk_set_dev_ops(blk, &block_job_dev_ops, job);
61
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
62
63
QLIST_INSERT_HEAD(&block_jobs, job, job_list);
42
--
64
--
43
2.20.1
65
2.13.6
44
66
45
67
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
Block jobs must be paused if any of the involved nodes are drained.
2
2
3
IEC binary prefixes are already defined in "qemu/units.h",
4
so we can remove redundant definitions in "block/vhdx.h".
5
6
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
4
---
11
block/vhdx.h | 6 +-----
5
tests/test-bdrv-drain.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++
12
block/vhdx.c | 3 ++-
6
1 file changed, 121 insertions(+)
13
2 files changed, 3 insertions(+), 6 deletions(-)
14
7
15
diff --git a/block/vhdx.h b/block/vhdx.h
8
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
16
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
17
--- a/block/vhdx.h
10
--- a/tests/test-bdrv-drain.c
18
+++ b/block/vhdx.h
11
+++ b/tests/test-bdrv-drain.c
19
@@ -XXX,XX +XXX,XX @@
12
@@ -XXX,XX +XXX,XX @@
20
13
21
#ifndef BLOCK_VHDX_H
14
#include "qemu/osdep.h"
22
#define BLOCK_VHDX_H
15
#include "block/block.h"
23
-
16
+#include "block/blockjob_int.h"
24
-#define KiB (1 * 1024)
17
#include "sysemu/block-backend.h"
25
-#define MiB (KiB * 1024)
18
#include "qapi/error.h"
26
-#define GiB (MiB * 1024)
19
27
-#define TiB ((uint64_t) GiB * 1024)
20
@@ -XXX,XX +XXX,XX @@ static void test_quiesce_drain(void)
28
+#include "qemu/units.h"
21
test_quiesce_common(BDRV_DRAIN, false);
29
22
}
30
#define DEFAULT_LOG_SIZE 1048576 /* 1MiB */
23
31
/* Structures and fields present in the VHDX file */
24
+
32
diff --git a/block/vhdx.c b/block/vhdx.c
25
+typedef struct TestBlockJob {
33
index XXXXXXX..XXXXXXX 100644
26
+ BlockJob common;
34
--- a/block/vhdx.c
27
+ bool should_complete;
35
+++ b/block/vhdx.c
28
+} TestBlockJob;
36
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
29
+
37
return -EINVAL;
30
+static void test_job_completed(BlockJob *job, void *opaque)
38
}
31
+{
39
if (block_size > VHDX_BLOCK_SIZE_MAX) {
32
+ block_job_completed(job, 0);
40
- error_setg(errp, "Block size must not exceed %d", VHDX_BLOCK_SIZE_MAX);
33
+}
41
+ error_setg(errp, "Block size must not exceed %" PRId64,
34
+
42
+ VHDX_BLOCK_SIZE_MAX);
35
+static void coroutine_fn test_job_start(void *opaque)
43
return -EINVAL;
36
+{
44
}
37
+ TestBlockJob *s = opaque;
45
38
+
39
+ while (!s->should_complete) {
40
+ block_job_sleep_ns(&s->common, 100000);
41
+ }
42
+
43
+ block_job_defer_to_main_loop(&s->common, test_job_completed, NULL);
44
+}
45
+
46
+static void test_job_complete(BlockJob *job, Error **errp)
47
+{
48
+ TestBlockJob *s = container_of(job, TestBlockJob, common);
49
+ s->should_complete = true;
50
+}
51
+
52
+BlockJobDriver test_job_driver = {
53
+ .instance_size = sizeof(TestBlockJob),
54
+ .start = test_job_start,
55
+ .complete = test_job_complete,
56
+};
57
+
58
+static void test_blockjob_common(enum drain_type drain_type)
59
+{
60
+ BlockBackend *blk_src, *blk_target;
61
+ BlockDriverState *src, *target;
62
+ BlockJob *job;
63
+ int ret;
64
+
65
+ src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR,
66
+ &error_abort);
67
+ blk_src = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
68
+ blk_insert_bs(blk_src, src, &error_abort);
69
+
70
+ target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
71
+ &error_abort);
72
+ blk_target = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
73
+ blk_insert_bs(blk_target, target, &error_abort);
74
+
75
+ job = block_job_create("job0", &test_job_driver, src, 0, BLK_PERM_ALL, 0,
76
+ 0, NULL, NULL, &error_abort);
77
+ block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort);
78
+ block_job_start(job);
79
+
80
+ g_assert_cmpint(job->pause_count, ==, 0);
81
+ g_assert_false(job->paused);
82
+ g_assert_false(job->busy); /* We're in block_job_sleep_ns() */
83
+
84
+ do_drain_begin(drain_type, src);
85
+
86
+ if (drain_type == BDRV_DRAIN_ALL) {
87
+ /* bdrv_drain_all() drains both src and target, and involves an
88
+ * additional block_job_pause_all() */
89
+ g_assert_cmpint(job->pause_count, ==, 3);
90
+ } else {
91
+ g_assert_cmpint(job->pause_count, ==, 1);
92
+ }
93
+ /* XXX We don't wait until the job is actually paused. Is this okay? */
94
+ /* g_assert_true(job->paused); */
95
+ g_assert_false(job->busy); /* The job is paused */
96
+
97
+ do_drain_end(drain_type, src);
98
+
99
+ g_assert_cmpint(job->pause_count, ==, 0);
100
+ g_assert_false(job->paused);
101
+ g_assert_false(job->busy); /* We're in block_job_sleep_ns() */
102
+
103
+ do_drain_begin(drain_type, target);
104
+
105
+ if (drain_type == BDRV_DRAIN_ALL) {
106
+ /* bdrv_drain_all() drains both src and target, and involves an
107
+ * additional block_job_pause_all() */
108
+ g_assert_cmpint(job->pause_count, ==, 3);
109
+ } else {
110
+ g_assert_cmpint(job->pause_count, ==, 1);
111
+ }
112
+ /* XXX We don't wait until the job is actually paused. Is this okay? */
113
+ /* g_assert_true(job->paused); */
114
+ g_assert_false(job->busy); /* The job is paused */
115
+
116
+ do_drain_end(drain_type, target);
117
+
118
+ g_assert_cmpint(job->pause_count, ==, 0);
119
+ g_assert_false(job->paused);
120
+ g_assert_false(job->busy); /* We're in block_job_sleep_ns() */
121
+
122
+ ret = block_job_complete_sync(job, &error_abort);
123
+ g_assert_cmpint(ret, ==, 0);
124
+
125
+ blk_unref(blk_src);
126
+ blk_unref(blk_target);
127
+ bdrv_unref(src);
128
+ bdrv_unref(target);
129
+}
130
+
131
+static void test_blockjob_drain_all(void)
132
+{
133
+ test_blockjob_common(BDRV_DRAIN_ALL);
134
+}
135
+
136
+static void test_blockjob_drain(void)
137
+{
138
+ test_blockjob_common(BDRV_DRAIN);
139
+}
140
+
141
int main(int argc, char **argv)
142
{
143
bdrv_init();
144
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
145
g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all);
146
g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain);
147
148
+ g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
149
+ g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain);
150
+
151
return g_test_run();
152
}
46
--
153
--
47
2.20.1
154
2.13.6
48
155
49
156
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
Block jobs are already paused using the BdrvChildRole drain callbacks,
2
so we don't need an additional block_job_pause_all() call.
2
3
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
5
---
8
block/qcow.c | 19 ++++++-------------
6
block/io.c | 4 ----
9
1 file changed, 6 insertions(+), 13 deletions(-)
7
tests/test-bdrv-drain.c | 10 ++++------
8
2 files changed, 4 insertions(+), 10 deletions(-)
10
9
11
diff --git a/block/qcow.c b/block/qcow.c
10
diff --git a/block/io.c b/block/io.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/block/qcow.c
12
--- a/block/io.c
14
+++ b/block/qcow.c
13
+++ b/block/io.c
15
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
14
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
16
int offset_in_cluster;
15
* context. */
17
int ret = 0, n;
16
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
18
uint64_t cluster_offset;
17
19
- QEMUIOVector hd_qiov;
18
- block_job_pause_all();
20
uint8_t *buf;
19
-
21
void *orig_buf;
20
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
22
21
AioContext *aio_context = bdrv_get_aio_context(bs);
23
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
22
24
if (!cluster_offset) {
23
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
25
if (bs->backing) {
24
aio_enable_external(aio_context);
26
/* read from the base image */
25
aio_context_release(aio_context);
27
- qemu_iovec_init_buf(&hd_qiov, buf, n);
28
qemu_co_mutex_unlock(&s->lock);
29
/* qcow2 emits this on bs->file instead of bs->backing */
30
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
31
- ret = bdrv_co_preadv(bs->backing, offset, n, &hd_qiov, 0);
32
+ ret = bdrv_co_pread(bs->backing, offset, n, buf, 0);
33
qemu_co_mutex_lock(&s->lock);
34
if (ret < 0) {
35
break;
36
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
37
ret = -EIO;
38
break;
39
}
40
- qemu_iovec_init_buf(&hd_qiov, buf, n);
41
qemu_co_mutex_unlock(&s->lock);
42
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
43
- ret = bdrv_co_preadv(bs->file, cluster_offset + offset_in_cluster,
44
- n, &hd_qiov, 0);
45
+ ret = bdrv_co_pread(bs->file, cluster_offset + offset_in_cluster,
46
+ n, buf, 0);
47
qemu_co_mutex_lock(&s->lock);
48
if (ret < 0) {
49
break;
50
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
51
int offset_in_cluster;
52
uint64_t cluster_offset;
53
int ret = 0, n;
54
- QEMUIOVector hd_qiov;
55
uint8_t *buf;
56
void *orig_buf;
57
58
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
59
}
60
}
61
62
- qemu_iovec_init_buf(&hd_qiov, buf, n);
63
qemu_co_mutex_unlock(&s->lock);
64
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
65
- ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
66
- n, &hd_qiov, 0);
67
+ ret = bdrv_co_pwrite(bs->file, cluster_offset + offset_in_cluster,
68
+ n, buf, 0);
69
qemu_co_mutex_lock(&s->lock);
70
if (ret < 0) {
71
break;
72
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
73
uint64_t bytes, QEMUIOVector *qiov)
74
{
75
BDRVQcowState *s = bs->opaque;
76
- QEMUIOVector hd_qiov;
77
z_stream strm;
78
int ret, out_len;
79
uint8_t *buf, *out_buf;
80
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
81
}
26
}
82
cluster_offset &= s->cluster_offset_mask;
27
-
83
28
- block_job_resume_all();
84
- qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
29
}
85
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
30
86
- ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0);
31
void bdrv_drain_all(void)
87
+ ret = bdrv_co_pwrite(bs->file, cluster_offset, out_len, out_buf, 0);
32
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
88
if (ret < 0) {
33
index XXXXXXX..XXXXXXX 100644
89
goto fail;
34
--- a/tests/test-bdrv-drain.c
35
+++ b/tests/test-bdrv-drain.c
36
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common(enum drain_type drain_type)
37
do_drain_begin(drain_type, src);
38
39
if (drain_type == BDRV_DRAIN_ALL) {
40
- /* bdrv_drain_all() drains both src and target, and involves an
41
- * additional block_job_pause_all() */
42
- g_assert_cmpint(job->pause_count, ==, 3);
43
+ /* bdrv_drain_all() drains both src and target */
44
+ g_assert_cmpint(job->pause_count, ==, 2);
45
} else {
46
g_assert_cmpint(job->pause_count, ==, 1);
47
}
48
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common(enum drain_type drain_type)
49
do_drain_begin(drain_type, target);
50
51
if (drain_type == BDRV_DRAIN_ALL) {
52
- /* bdrv_drain_all() drains both src and target, and involves an
53
- * additional block_job_pause_all() */
54
- g_assert_cmpint(job->pause_count, ==, 3);
55
+ /* bdrv_drain_all() drains both src and target */
56
+ g_assert_cmpint(job->pause_count, ==, 2);
57
} else {
58
g_assert_cmpint(job->pause_count, ==, 1);
90
}
59
}
91
--
60
--
92
2.20.1
61
2.13.6
93
62
94
63
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
bdrv_do_drained_begin() restricts the call of parent callbacks and
2
aio_disable_external() to the outermost drain section, but the block
3
driver callbacks are always called. bdrv_do_drained_end() must match
4
this behaviour, otherwise nodes stay drained even if begin/end calls
5
were balanced.
2
6
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
---
8
block/stream.c | 4 +---
9
block/io.c | 12 +++++++-----
9
1 file changed, 1 insertion(+), 3 deletions(-)
10
1 file changed, 7 insertions(+), 5 deletions(-)
10
11
11
diff --git a/block/stream.c b/block/stream.c
12
diff --git a/block/io.c b/block/io.c
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/block/stream.c
14
--- a/block/io.c
14
+++ b/block/stream.c
15
+++ b/block/io.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn stream_populate(BlockBackend *blk,
16
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_begin(BlockDriverState *bs)
16
int64_t offset, uint64_t bytes,
17
17
void *buf)
18
void bdrv_drained_end(BlockDriverState *bs)
18
{
19
{
19
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
20
+ int old_quiesce_counter;
20
-
21
+
21
assert(bytes < SIZE_MAX);
22
if (qemu_in_coroutine()) {
22
23
bdrv_co_yield_to_drain(bs, false);
23
/* Copy-on-read the unallocated clusters */
24
return;
24
- return blk_co_preadv(blk, offset, qiov.size, &qiov, BDRV_REQ_COPY_ON_READ);
25
}
25
+ return blk_co_pread(blk, offset, bytes, buf, BDRV_REQ_COPY_ON_READ);
26
assert(bs->quiesce_counter > 0);
27
- if (atomic_fetch_dec(&bs->quiesce_counter) > 1) {
28
- return;
29
- }
30
+ old_quiesce_counter = atomic_fetch_dec(&bs->quiesce_counter);
31
32
/* Re-enable things in child-to-parent order */
33
bdrv_drain_invoke(bs, false, false);
34
- bdrv_parent_drained_end(bs);
35
- aio_enable_external(bdrv_get_aio_context(bs));
36
+ if (old_quiesce_counter == 1) {
37
+ bdrv_parent_drained_end(bs);
38
+ aio_enable_external(bdrv_get_aio_context(bs));
39
+ }
26
}
40
}
27
41
28
static void stream_abort(Job *job)
42
/*
29
--
43
--
30
2.20.1
44
2.13.6
31
45
32
46
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
2
3
qemu-img create allows giving just a format and "-o help" to get a list
4
of the options supported by that format. Users may not realize that the
5
protocol level may offer even more options, which they only get to see
6
by specifying a filename.
7
8
This patch adds a note to hint at that fact.
9
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
2
---
14
qemu-img.c | 13 ++++++++++++-
3
tests/test-bdrv-drain.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
15
tests/qemu-iotests/082.out | 20 ++++++++++++++++----
4
1 file changed, 57 insertions(+)
16
2 files changed, 28 insertions(+), 5 deletions(-)
17
5
18
diff --git a/qemu-img.c b/qemu-img.c
6
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
19
index XXXXXXX..XXXXXXX 100644
7
index XXXXXXX..XXXXXXX 100644
20
--- a/qemu-img.c
8
--- a/tests/test-bdrv-drain.c
21
+++ b/qemu-img.c
9
+++ b/tests/test-bdrv-drain.c
22
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
10
@@ -XXX,XX +XXX,XX @@ static void aio_ret_cb(void *opaque, int ret)
23
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
11
enum drain_type {
24
}
12
BDRV_DRAIN_ALL,
25
13
BDRV_DRAIN,
26
- printf("Supported options:\n");
14
+ DRAIN_TYPE_MAX,
27
+ if (filename) {
15
};
28
+ printf("Supported options:\n");
16
29
+ } else {
17
static void do_drain_begin(enum drain_type drain_type, BlockDriverState *bs)
30
+ printf("Supported %s options:\n", fmt);
18
@@ -XXX,XX +XXX,XX @@ static void test_quiesce_drain(void)
31
+ }
19
test_quiesce_common(BDRV_DRAIN, false);
32
qemu_opts_print_help(create_opts, false);
20
}
33
qemu_opts_free(create_opts);
21
22
+static void test_nested(void)
23
+{
24
+ BlockBackend *blk;
25
+ BlockDriverState *bs, *backing;
26
+ BDRVTestState *s, *backing_s;
27
+ enum drain_type outer, inner;
34
+
28
+
35
+ if (!filename) {
29
+ blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
36
+ printf("\n"
30
+ bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
37
+ "The protocol level may support further options.\n"
31
+ &error_abort);
38
+ "Specify the target filename to include those options.\n");
32
+ s = bs->opaque;
33
+ blk_insert_bs(blk, bs, &error_abort);
34
+
35
+ backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
36
+ backing_s = backing->opaque;
37
+ bdrv_set_backing_hd(bs, backing, &error_abort);
38
+
39
+ for (outer = 0; outer < DRAIN_TYPE_MAX; outer++) {
40
+ for (inner = 0; inner < DRAIN_TYPE_MAX; inner++) {
41
+ /* XXX bdrv_drain_all() doesn't increase the quiesce_counter */
42
+ int bs_quiesce = (outer != BDRV_DRAIN_ALL) +
43
+ (inner != BDRV_DRAIN_ALL);
44
+ int backing_quiesce = 0;
45
+ int backing_cb_cnt = (outer != BDRV_DRAIN) +
46
+ (inner != BDRV_DRAIN);
47
+
48
+ g_assert_cmpint(bs->quiesce_counter, ==, 0);
49
+ g_assert_cmpint(backing->quiesce_counter, ==, 0);
50
+ g_assert_cmpint(s->drain_count, ==, 0);
51
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
52
+
53
+ do_drain_begin(outer, bs);
54
+ do_drain_begin(inner, bs);
55
+
56
+ g_assert_cmpint(bs->quiesce_counter, ==, bs_quiesce);
57
+ g_assert_cmpint(backing->quiesce_counter, ==, backing_quiesce);
58
+ g_assert_cmpint(s->drain_count, ==, 2);
59
+ g_assert_cmpint(backing_s->drain_count, ==, backing_cb_cnt);
60
+
61
+ do_drain_end(inner, bs);
62
+ do_drain_end(outer, bs);
63
+
64
+ g_assert_cmpint(bs->quiesce_counter, ==, 0);
65
+ g_assert_cmpint(backing->quiesce_counter, ==, 0);
66
+ g_assert_cmpint(s->drain_count, ==, 0);
67
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
68
+ }
39
+ }
69
+ }
40
+
70
+
41
return 0;
71
+ bdrv_unref(backing);
42
}
72
+ bdrv_unref(bs);
43
73
+ blk_unref(blk);
44
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
74
+}
45
index XXXXXXX..XXXXXXX 100644
46
--- a/tests/qemu-iotests/082.out
47
+++ b/tests/qemu-iotests/082.out
48
@@ -XXX,XX +XXX,XX @@ Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2 -o ,, -o help TEST_DIR
49
qemu-img: Invalid option list: ,,
50
51
Testing: create -f qcow2 -o help
52
-Supported options:
53
+Supported qcow2 options:
54
backing_file=<str> - File name of a base image
55
backing_fmt=<str> - Image format of the base image
56
cluster_size=<size> - qcow2 cluster size
57
@@ -XXX,XX +XXX,XX @@ Supported options:
58
refcount_bits=<num> - Width of a reference count entry in bits
59
size=<size> - Virtual disk size
60
61
+The protocol level may support further options.
62
+Specify the target filename to include those options.
63
+
75
+
64
Testing: create -o help
76
65
-Supported options:
77
typedef struct TestBlockJob {
66
+Supported raw options:
78
BlockJob common;
67
size=<size> - Virtual disk size
79
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
68
80
g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all);
69
+The protocol level may support further options.
81
g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain);
70
+Specify the target filename to include those options.
82
83
+ g_test_add_func("/bdrv-drain/nested", test_nested);
71
+
84
+
72
Testing: create -f bochs -o help
85
g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
73
qemu-img: Format driver 'bochs' does not support image creation
86
g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain);
74
75
@@ -XXX,XX +XXX,XX @@ Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2 -o ,, -o help TEST_DI
76
qemu-img: Invalid option list: ,,
77
78
Testing: convert -O qcow2 -o help
79
-Supported options:
80
+Supported qcow2 options:
81
backing_file=<str> - File name of a base image
82
backing_fmt=<str> - Image format of the base image
83
cluster_size=<size> - qcow2 cluster size
84
@@ -XXX,XX +XXX,XX @@ Supported options:
85
refcount_bits=<num> - Width of a reference count entry in bits
86
size=<size> - Virtual disk size
87
88
+The protocol level may support further options.
89
+Specify the target filename to include those options.
90
+
91
Testing: convert -o help
92
-Supported options:
93
+Supported raw options:
94
size=<size> - Virtual disk size
95
96
+The protocol level may support further options.
97
+Specify the target filename to include those options.
98
+
99
Testing: convert -O bochs -o help
100
qemu-img: Format driver 'bochs' does not support image creation
101
87
102
--
88
--
103
2.20.1
89
2.13.6
104
90
105
91
diff view generated by jsdifflib
New patch
1
1
This is in preparation for subtree drains, i.e. drained sections that
2
affect not only a single node, but recursively all child nodes, too.
3
4
Calling the parent callbacks for drain is pointless when we just came
5
from that parent node recursively and leads to multiple increases of
6
bs->quiesce_counter in a single drain call. Don't do it.
7
8
In order for this to work correctly, the parent callback must be called
9
for every bdrv_drain_begin/end() call, not only for the outermost one:
10
11
If we have a node N with two parents A and B, recursive draining of A
12
should cause the quiesce_counter of B to increase because its child N is
13
drained independently of B. If now B is recursively drained, too, A must
14
increase its quiesce_counter because N is drained independently of A
15
only now, even if N is going from quiesce_counter 1 to 2.
16
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
include/block/block.h | 4 ++--
20
block.c | 13 +++++++++----
21
block/io.c | 47 ++++++++++++++++++++++++++++++++++-------------
22
3 files changed, 45 insertions(+), 19 deletions(-)
23
24
diff --git a/include/block/block.h b/include/block/block.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block.h
27
+++ b/include/block/block.h
28
@@ -XXX,XX +XXX,XX @@ void bdrv_io_unplug(BlockDriverState *bs);
29
* Begin a quiesced section of all users of @bs. This is part of
30
* bdrv_drained_begin.
31
*/
32
-void bdrv_parent_drained_begin(BlockDriverState *bs);
33
+void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore);
34
35
/**
36
* bdrv_parent_drained_end:
37
@@ -XXX,XX +XXX,XX @@ void bdrv_parent_drained_begin(BlockDriverState *bs);
38
* End a quiesced section of all users of @bs. This is part of
39
* bdrv_drained_end.
40
*/
41
-void bdrv_parent_drained_end(BlockDriverState *bs);
42
+void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore);
43
44
/**
45
* bdrv_drained_begin:
46
diff --git a/block.c b/block.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/block.c
49
+++ b/block.c
50
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
51
BlockDriverState *new_bs)
52
{
53
BlockDriverState *old_bs = child->bs;
54
+ int i;
55
56
if (old_bs && new_bs) {
57
assert(bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs));
58
}
59
if (old_bs) {
60
if (old_bs->quiesce_counter && child->role->drained_end) {
61
- child->role->drained_end(child);
62
+ for (i = 0; i < old_bs->quiesce_counter; i++) {
63
+ child->role->drained_end(child);
64
+ }
65
}
66
if (child->role->detach) {
67
child->role->detach(child);
68
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
69
if (new_bs) {
70
QLIST_INSERT_HEAD(&new_bs->parents, child, next_parent);
71
if (new_bs->quiesce_counter && child->role->drained_begin) {
72
- child->role->drained_begin(child);
73
+ for (i = 0; i < new_bs->quiesce_counter; i++) {
74
+ child->role->drained_begin(child);
75
+ }
76
}
77
78
if (child->role->attach) {
79
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
80
AioContext *ctx = bdrv_get_aio_context(bs);
81
82
aio_disable_external(ctx);
83
- bdrv_parent_drained_begin(bs);
84
+ bdrv_parent_drained_begin(bs, NULL);
85
bdrv_drain(bs); /* ensure there are no in-flight requests */
86
87
while (aio_poll(ctx, false)) {
88
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
89
*/
90
aio_context_acquire(new_context);
91
bdrv_attach_aio_context(bs, new_context);
92
- bdrv_parent_drained_end(bs);
93
+ bdrv_parent_drained_end(bs, NULL);
94
aio_enable_external(ctx);
95
aio_context_release(new_context);
96
}
97
diff --git a/block/io.c b/block/io.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/block/io.c
100
+++ b/block/io.c
101
@@ -XXX,XX +XXX,XX @@
102
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
103
int64_t offset, int bytes, BdrvRequestFlags flags);
104
105
-void bdrv_parent_drained_begin(BlockDriverState *bs)
106
+void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore)
107
{
108
BdrvChild *c, *next;
109
110
QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
111
+ if (c == ignore) {
112
+ continue;
113
+ }
114
if (c->role->drained_begin) {
115
c->role->drained_begin(c);
116
}
117
}
118
}
119
120
-void bdrv_parent_drained_end(BlockDriverState *bs)
121
+void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore)
122
{
123
BdrvChild *c, *next;
124
125
QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
126
+ if (c == ignore) {
127
+ continue;
128
+ }
129
if (c->role->drained_end) {
130
c->role->drained_end(c);
131
}
132
@@ -XXX,XX +XXX,XX @@ typedef struct {
133
BlockDriverState *bs;
134
bool done;
135
bool begin;
136
+ BdrvChild *parent;
137
} BdrvCoDrainData;
138
139
static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
140
@@ -XXX,XX +XXX,XX @@ static bool bdrv_drain_recurse(BlockDriverState *bs)
141
return waited;
142
}
143
144
+static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent);
145
+static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent);
146
+
147
static void bdrv_co_drain_bh_cb(void *opaque)
148
{
149
BdrvCoDrainData *data = opaque;
150
@@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque)
151
152
bdrv_dec_in_flight(bs);
153
if (data->begin) {
154
- bdrv_drained_begin(bs);
155
+ bdrv_do_drained_begin(bs, data->parent);
156
} else {
157
- bdrv_drained_end(bs);
158
+ bdrv_do_drained_end(bs, data->parent);
159
}
160
161
data->done = true;
162
@@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque)
163
}
164
165
static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
166
- bool begin)
167
+ bool begin, BdrvChild *parent)
168
{
169
BdrvCoDrainData data;
170
171
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
172
.bs = bs,
173
.done = false,
174
.begin = begin,
175
+ .parent = parent,
176
};
177
bdrv_inc_in_flight(bs);
178
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs),
179
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
180
assert(data.done);
181
}
182
183
-void bdrv_drained_begin(BlockDriverState *bs)
184
+static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent)
185
{
186
if (qemu_in_coroutine()) {
187
- bdrv_co_yield_to_drain(bs, true);
188
+ bdrv_co_yield_to_drain(bs, true, parent);
189
return;
190
}
191
192
/* Stop things in parent-to-child order */
193
if (atomic_fetch_inc(&bs->quiesce_counter) == 0) {
194
aio_disable_external(bdrv_get_aio_context(bs));
195
- bdrv_parent_drained_begin(bs);
196
}
197
198
+ bdrv_parent_drained_begin(bs, parent);
199
bdrv_drain_invoke(bs, true, false);
200
bdrv_drain_recurse(bs);
201
}
202
203
-void bdrv_drained_end(BlockDriverState *bs)
204
+void bdrv_drained_begin(BlockDriverState *bs)
205
+{
206
+ bdrv_do_drained_begin(bs, NULL);
207
+}
208
+
209
+static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent)
210
{
211
int old_quiesce_counter;
212
213
if (qemu_in_coroutine()) {
214
- bdrv_co_yield_to_drain(bs, false);
215
+ bdrv_co_yield_to_drain(bs, false, parent);
216
return;
217
}
218
assert(bs->quiesce_counter > 0);
219
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_end(BlockDriverState *bs)
220
221
/* Re-enable things in child-to-parent order */
222
bdrv_drain_invoke(bs, false, false);
223
+ bdrv_parent_drained_end(bs, parent);
224
if (old_quiesce_counter == 1) {
225
- bdrv_parent_drained_end(bs);
226
aio_enable_external(bdrv_get_aio_context(bs));
227
}
228
}
229
230
+void bdrv_drained_end(BlockDriverState *bs)
231
+{
232
+ bdrv_do_drained_end(bs, NULL);
233
+}
234
+
235
/*
236
* Wait for pending requests to complete on a single BlockDriverState subtree,
237
* and suspend block driver's internal I/O until next request arrives.
238
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
239
/* Stop things in parent-to-child order */
240
aio_context_acquire(aio_context);
241
aio_disable_external(aio_context);
242
- bdrv_parent_drained_begin(bs);
243
+ bdrv_parent_drained_begin(bs, NULL);
244
bdrv_drain_invoke(bs, true, true);
245
aio_context_release(aio_context);
246
247
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
248
/* Re-enable things in child-to-parent order */
249
aio_context_acquire(aio_context);
250
bdrv_drain_invoke(bs, false, true);
251
- bdrv_parent_drained_end(bs);
252
+ bdrv_parent_drained_end(bs, NULL);
253
aio_enable_external(aio_context);
254
aio_context_release(aio_context);
255
}
256
--
257
2.13.6
258
259
diff view generated by jsdifflib
1
From: Sam Eiderman <shmuel.eiderman@oracle.com>
1
bdrv_drained_begin() waits for the completion of requests in the whole
2
subtree, but it only actually keeps its immediate bs parameter quiesced
3
until bdrv_drained_end().
2
4
3
Commit b69864e5a ("vmdk: Support version=3 in VMDK descriptor files")
5
Add a version that keeps the whole subtree drained. As of this commit,
4
fixed the probe function to correctly guess vmdk descriptors with
6
graph changes cannot be allowed during a subtree drained section, but
5
version=3.
7
this will be fixed soon.
6
8
7
This solves the issue where vmdk snapshot with parent vmdk descriptor
8
containing "version=3" would be treated as raw instead vmdk.
9
10
In the future case where a new vmdk version is introduced, we will again
11
experience this issue, even if the user will provide "-f vmdk" it will
12
only apply to the tip image and not to the underlying "misprobed" parent
13
image.
14
15
The code in vmdk.c already assumes that the backing file of vmdk must be
16
vmdk (see vmdk_is_cid_valid which returns 0 if backing file is not
17
vmdk).
18
19
So let's make it official by supplying the backing_format as vmdk.
20
21
Reviewed-by: Mark Kanda <mark.kanda@oracle.com>
22
Reviewed-By: Liran Alon <liran.alon@oracle.com>
23
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
24
Signed-off-by: Shmuel Eiderman <shmuel.eiderman@oracle.com>
25
Reviewed-by: Eric Blake <eblake@redhat.com>
26
Reviewed-by: Fam Zheng <fam@euphon.net>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
---
10
---
29
block/vmdk.c | 2 ++
11
include/block/block.h | 13 +++++++++++++
30
1 file changed, 2 insertions(+)
12
block/io.c | 54 ++++++++++++++++++++++++++++++++++++++++-----------
13
2 files changed, 56 insertions(+), 11 deletions(-)
31
14
32
diff --git a/block/vmdk.c b/block/vmdk.c
15
diff --git a/include/block/block.h b/include/block/block.h
33
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
34
--- a/block/vmdk.c
17
--- a/include/block/block.h
35
+++ b/block/vmdk.c
18
+++ b/include/block/block.h
36
@@ -XXX,XX +XXX,XX @@ static int vmdk_parent_open(BlockDriverState *bs)
19
@@ -XXX,XX +XXX,XX @@ void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore);
37
pstrcpy(bs->auto_backing_file, end_name - p_name + 1, p_name);
20
void bdrv_drained_begin(BlockDriverState *bs);
38
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
21
39
bs->auto_backing_file);
22
/**
40
+ pstrcpy(bs->backing_format, sizeof(bs->backing_format),
23
+ * Like bdrv_drained_begin, but recursively begins a quiesced section for
41
+ "vmdk");
24
+ * exclusive access to all child nodes as well.
25
+ *
26
+ * Graph changes are not allowed during a subtree drain section.
27
+ */
28
+void bdrv_subtree_drained_begin(BlockDriverState *bs);
29
+
30
+/**
31
* bdrv_drained_end:
32
*
33
* End a quiescent section started by bdrv_drained_begin().
34
*/
35
void bdrv_drained_end(BlockDriverState *bs);
36
37
+/**
38
+ * End a quiescent section started by bdrv_subtree_drained_begin().
39
+ */
40
+void bdrv_subtree_drained_end(BlockDriverState *bs);
41
+
42
void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
43
Error **errp);
44
void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
45
diff --git a/block/io.c b/block/io.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/io.c
48
+++ b/block/io.c
49
@@ -XXX,XX +XXX,XX @@ typedef struct {
50
BlockDriverState *bs;
51
bool done;
52
bool begin;
53
+ bool recursive;
54
BdrvChild *parent;
55
} BdrvCoDrainData;
56
57
@@ -XXX,XX +XXX,XX @@ static bool bdrv_drain_recurse(BlockDriverState *bs)
58
return waited;
59
}
60
61
-static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent);
62
-static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent);
63
+static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive,
64
+ BdrvChild *parent);
65
+static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive,
66
+ BdrvChild *parent);
67
68
static void bdrv_co_drain_bh_cb(void *opaque)
69
{
70
@@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque)
71
72
bdrv_dec_in_flight(bs);
73
if (data->begin) {
74
- bdrv_do_drained_begin(bs, data->parent);
75
+ bdrv_do_drained_begin(bs, data->recursive, data->parent);
76
} else {
77
- bdrv_do_drained_end(bs, data->parent);
78
+ bdrv_do_drained_end(bs, data->recursive, data->parent);
42
}
79
}
43
80
44
out:
81
data->done = true;
82
@@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque)
83
}
84
85
static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
86
- bool begin, BdrvChild *parent)
87
+ bool begin, bool recursive,
88
+ BdrvChild *parent)
89
{
90
BdrvCoDrainData data;
91
92
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
93
.bs = bs,
94
.done = false,
95
.begin = begin,
96
+ .recursive = recursive,
97
.parent = parent,
98
};
99
bdrv_inc_in_flight(bs);
100
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
101
assert(data.done);
102
}
103
104
-static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent)
105
+static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive,
106
+ BdrvChild *parent)
107
{
108
+ BdrvChild *child, *next;
109
+
110
if (qemu_in_coroutine()) {
111
- bdrv_co_yield_to_drain(bs, true, parent);
112
+ bdrv_co_yield_to_drain(bs, true, recursive, parent);
113
return;
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent)
117
bdrv_parent_drained_begin(bs, parent);
118
bdrv_drain_invoke(bs, true, false);
119
bdrv_drain_recurse(bs);
120
+
121
+ if (recursive) {
122
+ QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
123
+ bdrv_do_drained_begin(child->bs, true, child);
124
+ }
125
+ }
126
}
127
128
void bdrv_drained_begin(BlockDriverState *bs)
129
{
130
- bdrv_do_drained_begin(bs, NULL);
131
+ bdrv_do_drained_begin(bs, false, NULL);
132
+}
133
+
134
+void bdrv_subtree_drained_begin(BlockDriverState *bs)
135
+{
136
+ bdrv_do_drained_begin(bs, true, NULL);
137
}
138
139
-static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent)
140
+static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive,
141
+ BdrvChild *parent)
142
{
143
+ BdrvChild *child, *next;
144
int old_quiesce_counter;
145
146
if (qemu_in_coroutine()) {
147
- bdrv_co_yield_to_drain(bs, false, parent);
148
+ bdrv_co_yield_to_drain(bs, false, recursive, parent);
149
return;
150
}
151
assert(bs->quiesce_counter > 0);
152
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent)
153
if (old_quiesce_counter == 1) {
154
aio_enable_external(bdrv_get_aio_context(bs));
155
}
156
+
157
+ if (recursive) {
158
+ QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
159
+ bdrv_do_drained_end(child->bs, true, child);
160
+ }
161
+ }
162
}
163
164
void bdrv_drained_end(BlockDriverState *bs)
165
{
166
- bdrv_do_drained_end(bs, NULL);
167
+ bdrv_do_drained_end(bs, false, NULL);
168
+}
169
+
170
+void bdrv_subtree_drained_end(BlockDriverState *bs)
171
+{
172
+ bdrv_do_drained_end(bs, true, NULL);
173
}
174
175
/*
45
--
176
--
46
2.20.1
177
2.13.6
47
178
48
179
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
Add a subtree drain version to the existing test cases.
2
2
3
In the "amend" section of 082, we perform a single "convert" test
4
(namely "convert -o help"). That does not make sense, especially
5
because we have done exactly that "convert" test earlier in 082 already.
6
7
Replacing "convert" by "amend" yields an error, which is correct because
8
there is no point in "amend" having a default format. The user has to
9
either specify the format, or give a file for qemu-img to probe.
10
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: John Snow <jsnow@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
4
---
15
tests/qemu-iotests/082 | 5 ++++-
5
tests/test-bdrv-drain.c | 27 ++++++++++++++++++++++++++-
16
tests/qemu-iotests/082.out | 5 ++---
6
1 file changed, 26 insertions(+), 1 deletion(-)
17
2 files changed, 6 insertions(+), 4 deletions(-)
18
7
19
diff --git a/tests/qemu-iotests/082 b/tests/qemu-iotests/082
8
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
20
index XXXXXXX..XXXXXXX 100755
9
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/qemu-iotests/082
10
--- a/tests/test-bdrv-drain.c
22
+++ b/tests/qemu-iotests/082
11
+++ b/tests/test-bdrv-drain.c
23
@@ -XXX,XX +XXX,XX @@ run_qemu_img amend -f $IMGFMT -o backing_file="$TEST_IMG" -o ,, -o help "$TEST_I
12
@@ -XXX,XX +XXX,XX @@ static void aio_ret_cb(void *opaque, int ret)
24
13
enum drain_type {
25
# Leave out everything that isn't needed
14
BDRV_DRAIN_ALL,
26
run_qemu_img amend -f $IMGFMT -o help
15
BDRV_DRAIN,
27
-run_qemu_img convert -o help
16
+ BDRV_SUBTREE_DRAIN,
17
DRAIN_TYPE_MAX,
18
};
19
20
@@ -XXX,XX +XXX,XX @@ static void do_drain_begin(enum drain_type drain_type, BlockDriverState *bs)
21
switch (drain_type) {
22
case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); break;
23
case BDRV_DRAIN: bdrv_drained_begin(bs); break;
24
+ case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_begin(bs); break;
25
default: g_assert_not_reached();
26
}
27
}
28
@@ -XXX,XX +XXX,XX @@ static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs)
29
switch (drain_type) {
30
case BDRV_DRAIN_ALL: bdrv_drain_all_end(); break;
31
case BDRV_DRAIN: bdrv_drained_end(bs); break;
32
+ case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_end(bs); break;
33
default: g_assert_not_reached();
34
}
35
}
36
@@ -XXX,XX +XXX,XX @@ static void test_drv_cb_drain(void)
37
test_drv_cb_common(BDRV_DRAIN, false);
38
}
39
40
+static void test_drv_cb_drain_subtree(void)
41
+{
42
+ test_drv_cb_common(BDRV_SUBTREE_DRAIN, true);
43
+}
28
+
44
+
29
+# amend requires specifying either a format explicitly, or a file
45
static void test_quiesce_common(enum drain_type drain_type, bool recursive)
30
+# which it can probe
46
{
31
+run_qemu_img amend -o help
47
BlockBackend *blk;
32
48
@@ -XXX,XX +XXX,XX @@ static void test_quiesce_drain(void)
33
# Try help option for a format that does not support amendment
49
test_quiesce_common(BDRV_DRAIN, false);
34
run_qemu_img amend -f bochs -o help
50
}
35
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
51
36
index XXXXXXX..XXXXXXX 100644
52
+static void test_quiesce_drain_subtree(void)
37
--- a/tests/qemu-iotests/082.out
53
+{
38
+++ b/tests/qemu-iotests/082.out
54
+ test_quiesce_common(BDRV_SUBTREE_DRAIN, true);
39
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
55
+}
40
56
+
41
Note that not all of these options may be amendable.
57
static void test_nested(void)
42
58
{
43
-Testing: convert -o help
59
BlockBackend *blk;
44
-Supported options:
60
@@ -XXX,XX +XXX,XX @@ static void test_nested(void)
45
- size=<size> - Virtual disk size
61
/* XXX bdrv_drain_all() doesn't increase the quiesce_counter */
46
+Testing: amend -o help
62
int bs_quiesce = (outer != BDRV_DRAIN_ALL) +
47
+qemu-img: Expecting one image file name
63
(inner != BDRV_DRAIN_ALL);
48
64
- int backing_quiesce = 0;
49
Testing: amend -f bochs -o help
65
+ int backing_quiesce = (outer == BDRV_SUBTREE_DRAIN) +
50
qemu-img: Format driver 'bochs' does not support option amendment
66
+ (inner == BDRV_SUBTREE_DRAIN);
67
int backing_cb_cnt = (outer != BDRV_DRAIN) +
68
(inner != BDRV_DRAIN);
69
70
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_drain(void)
71
test_blockjob_common(BDRV_DRAIN);
72
}
73
74
+static void test_blockjob_drain_subtree(void)
75
+{
76
+ test_blockjob_common(BDRV_SUBTREE_DRAIN);
77
+}
78
+
79
int main(int argc, char **argv)
80
{
81
bdrv_init();
82
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
83
84
g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all);
85
g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain);
86
+ g_test_add_func("/bdrv-drain/driver-cb/drain_subtree",
87
+ test_drv_cb_drain_subtree);
88
89
g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all);
90
g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain);
91
+ g_test_add_func("/bdrv-drain/quiesce/drain_subtree",
92
+ test_quiesce_drain_subtree);
93
94
g_test_add_func("/bdrv-drain/nested", test_nested);
95
96
g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
97
g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain);
98
+ g_test_add_func("/bdrv-drain/blockjob/drain_subtree",
99
+ test_blockjob_drain_subtree);
100
101
return g_test_run();
102
}
51
--
103
--
52
2.20.1
104
2.13.6
53
105
54
106
diff view generated by jsdifflib
1
From: Zhengui li <lizhengui@huawei.com>
1
If bdrv_do_drained_begin/end() are called in coroutine context, they
2
first use a BH to get out of the coroutine context. Call some existing
3
tests again from a coroutine to cover this code path.
2
4
3
Concurrent IO becomes serial IO because of the qemu Coroutine lock,
4
which reduce IO performance severely.
5
6
So unlock Coroutine lock before bdrv_co_pwritev and
7
bdrv_co_preadv to fix it.
8
9
Signed-off-by: Zhengui li <lizhengui@huawei.com>
10
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
6
---
13
block/vpc.c | 4 ++++
7
tests/test-bdrv-drain.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
14
1 file changed, 4 insertions(+)
8
1 file changed, 59 insertions(+)
15
9
16
diff --git a/block/vpc.c b/block/vpc.c
10
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/block/vpc.c
12
--- a/tests/test-bdrv-drain.c
19
+++ b/block/vpc.c
13
+++ b/tests/test-bdrv-drain.c
20
@@ -XXX,XX +XXX,XX @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
14
@@ -XXX,XX +XXX,XX @@ static void aio_ret_cb(void *opaque, int ret)
21
qemu_iovec_reset(&local_qiov);
15
*aio_ret = ret;
22
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
16
}
23
17
24
+ qemu_co_mutex_unlock(&s->lock);
18
+typedef struct CallInCoroutineData {
25
ret = bdrv_co_preadv(bs->file, image_offset, n_bytes,
19
+ void (*entry)(void);
26
&local_qiov, 0);
20
+ bool done;
27
+ qemu_co_mutex_lock(&s->lock);
21
+} CallInCoroutineData;
28
if (ret < 0) {
22
+
29
goto fail;
23
+static coroutine_fn void call_in_coroutine_entry(void *opaque)
30
}
24
+{
31
@@ -XXX,XX +XXX,XX @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
25
+ CallInCoroutineData *data = opaque;
32
qemu_iovec_reset(&local_qiov);
26
+
33
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
27
+ data->entry();
34
28
+ data->done = true;
35
+ qemu_co_mutex_unlock(&s->lock);
29
+}
36
ret = bdrv_co_pwritev(bs->file, image_offset, n_bytes,
30
+
37
&local_qiov, 0);
31
+static void call_in_coroutine(void (*entry)(void))
38
+ qemu_co_mutex_lock(&s->lock);
32
+{
39
if (ret < 0) {
33
+ Coroutine *co;
40
goto fail;
34
+ CallInCoroutineData data = {
41
}
35
+ .entry = entry,
36
+ .done = false,
37
+ };
38
+
39
+ co = qemu_coroutine_create(call_in_coroutine_entry, &data);
40
+ qemu_coroutine_enter(co);
41
+ while (!data.done) {
42
+ aio_poll(qemu_get_aio_context(), true);
43
+ }
44
+}
45
+
46
enum drain_type {
47
BDRV_DRAIN_ALL,
48
BDRV_DRAIN,
49
@@ -XXX,XX +XXX,XX @@ static void test_drv_cb_drain_subtree(void)
50
test_drv_cb_common(BDRV_SUBTREE_DRAIN, true);
51
}
52
53
+static void test_drv_cb_co_drain(void)
54
+{
55
+ call_in_coroutine(test_drv_cb_drain);
56
+}
57
+
58
+static void test_drv_cb_co_drain_subtree(void)
59
+{
60
+ call_in_coroutine(test_drv_cb_drain_subtree);
61
+}
62
+
63
static void test_quiesce_common(enum drain_type drain_type, bool recursive)
64
{
65
BlockBackend *blk;
66
@@ -XXX,XX +XXX,XX @@ static void test_quiesce_drain_subtree(void)
67
test_quiesce_common(BDRV_SUBTREE_DRAIN, true);
68
}
69
70
+static void test_quiesce_co_drain(void)
71
+{
72
+ call_in_coroutine(test_quiesce_drain);
73
+}
74
+
75
+static void test_quiesce_co_drain_subtree(void)
76
+{
77
+ call_in_coroutine(test_quiesce_drain_subtree);
78
+}
79
+
80
static void test_nested(void)
81
{
82
BlockBackend *blk;
83
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
84
g_test_add_func("/bdrv-drain/driver-cb/drain_subtree",
85
test_drv_cb_drain_subtree);
86
87
+ // XXX bdrv_drain_all() doesn't work in coroutine context
88
+ g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain);
89
+ g_test_add_func("/bdrv-drain/driver-cb/co/drain_subtree",
90
+ test_drv_cb_co_drain_subtree);
91
+
92
+
93
g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all);
94
g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain);
95
g_test_add_func("/bdrv-drain/quiesce/drain_subtree",
96
test_quiesce_drain_subtree);
97
98
+ // XXX bdrv_drain_all() doesn't work in coroutine context
99
+ g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain);
100
+ g_test_add_func("/bdrv-drain/quiesce/co/drain_subtree",
101
+ test_quiesce_co_drain_subtree);
102
+
103
g_test_add_func("/bdrv-drain/nested", test_nested);
104
105
g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
42
--
106
--
43
2.20.1
107
2.13.6
44
108
45
109
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
Test that drain sections are correctly propagated through the graph.
2
2
3
When extracting a human-readable size formatter, we changed 'uint64_t
4
div' pre-patch to 'unsigned long div' post-patch. Which breaks on
5
32-bit platforms, resulting in 'inf' instead of intended values larger
6
than 999GB.
7
8
Fixes: 22951aaa
9
CC: qemu-stable@nongnu.org
10
Reported-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
4
---
15
util/cutils.c | 2 +-
5
tests/test-bdrv-drain.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
16
1 file changed, 1 insertion(+), 1 deletion(-)
6
1 file changed, 74 insertions(+)
17
7
18
diff --git a/util/cutils.c b/util/cutils.c
8
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
19
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
20
--- a/util/cutils.c
10
--- a/tests/test-bdrv-drain.c
21
+++ b/util/cutils.c
11
+++ b/tests/test-bdrv-drain.c
22
@@ -XXX,XX +XXX,XX @@ const char *qemu_ether_ntoa(const MACAddr *mac)
12
@@ -XXX,XX +XXX,XX @@ static void test_nested(void)
23
char *size_to_str(uint64_t val)
13
blk_unref(blk);
24
{
14
}
25
static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
15
26
- unsigned long div;
16
+static void test_multiparent(void)
27
+ uint64_t div;
17
+{
28
int i;
18
+ BlockBackend *blk_a, *blk_b;
29
19
+ BlockDriverState *bs_a, *bs_b, *backing;
30
/*
20
+ BDRVTestState *a_s, *b_s, *backing_s;
21
+
22
+ blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
23
+ bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
24
+ &error_abort);
25
+ a_s = bs_a->opaque;
26
+ blk_insert_bs(blk_a, bs_a, &error_abort);
27
+
28
+ blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
29
+ bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
30
+ &error_abort);
31
+ b_s = bs_b->opaque;
32
+ blk_insert_bs(blk_b, bs_b, &error_abort);
33
+
34
+ backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
35
+ backing_s = backing->opaque;
36
+ bdrv_set_backing_hd(bs_a, backing, &error_abort);
37
+ bdrv_set_backing_hd(bs_b, backing, &error_abort);
38
+
39
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
40
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
41
+ g_assert_cmpint(backing->quiesce_counter, ==, 0);
42
+ g_assert_cmpint(a_s->drain_count, ==, 0);
43
+ g_assert_cmpint(b_s->drain_count, ==, 0);
44
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
45
+
46
+ do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
47
+
48
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
49
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
50
+ g_assert_cmpint(backing->quiesce_counter, ==, 1);
51
+ g_assert_cmpint(a_s->drain_count, ==, 1);
52
+ g_assert_cmpint(b_s->drain_count, ==, 1);
53
+ g_assert_cmpint(backing_s->drain_count, ==, 1);
54
+
55
+ do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
56
+
57
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 2);
58
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 2);
59
+ g_assert_cmpint(backing->quiesce_counter, ==, 2);
60
+ g_assert_cmpint(a_s->drain_count, ==, 2);
61
+ g_assert_cmpint(b_s->drain_count, ==, 2);
62
+ g_assert_cmpint(backing_s->drain_count, ==, 2);
63
+
64
+ do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
65
+
66
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
67
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
68
+ g_assert_cmpint(backing->quiesce_counter, ==, 1);
69
+ g_assert_cmpint(a_s->drain_count, ==, 1);
70
+ g_assert_cmpint(b_s->drain_count, ==, 1);
71
+ g_assert_cmpint(backing_s->drain_count, ==, 1);
72
+
73
+ do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
74
+
75
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
76
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
77
+ g_assert_cmpint(backing->quiesce_counter, ==, 0);
78
+ g_assert_cmpint(a_s->drain_count, ==, 0);
79
+ g_assert_cmpint(b_s->drain_count, ==, 0);
80
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
81
+
82
+ bdrv_unref(backing);
83
+ bdrv_unref(bs_a);
84
+ bdrv_unref(bs_b);
85
+ blk_unref(blk_a);
86
+ blk_unref(blk_b);
87
+}
88
+
89
90
typedef struct TestBlockJob {
91
BlockJob common;
92
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
93
test_quiesce_co_drain_subtree);
94
95
g_test_add_func("/bdrv-drain/nested", test_nested);
96
+ g_test_add_func("/bdrv-drain/multiparent", test_multiparent);
97
98
g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
99
g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain);
31
--
100
--
32
2.20.1
101
2.13.6
33
102
34
103
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
We need to remember how many of the drain sections in which a node is
2
2
were recursive (i.e. subtree drain rather than node drain), so that they
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
3
can be correctly applied when children are added or removed during the
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
drained section.
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
5
6
With this change, it is safe to modify the graph even inside a
7
bdrv_subtree_drained_begin/end() section.
8
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
10
---
8
include/block/block_int.h | 16 ++++++++++++++++
11
include/block/block.h | 2 --
9
include/sysemu/block-backend.h | 19 +++++++++++++++++++
12
include/block/block_int.h | 5 +++++
10
2 files changed, 35 insertions(+)
13
block.c | 32 +++++++++++++++++++++++++++++---
11
14
block/io.c | 28 ++++++++++++++++++++++++----
15
4 files changed, 58 insertions(+), 9 deletions(-)
16
17
diff --git a/include/block/block.h b/include/block/block.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block.h
20
+++ b/include/block/block.h
21
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_begin(BlockDriverState *bs);
22
/**
23
* Like bdrv_drained_begin, but recursively begins a quiesced section for
24
* exclusive access to all child nodes as well.
25
- *
26
- * Graph changes are not allowed during a subtree drain section.
27
*/
28
void bdrv_subtree_drained_begin(BlockDriverState *bs);
29
12
diff --git a/include/block/block_int.h b/include/block/block_int.h
30
diff --git a/include/block/block_int.h b/include/block/block_int.h
13
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
14
--- a/include/block/block_int.h
32
--- a/include/block/block_int.h
15
+++ b/include/block/block_int.h
33
+++ b/include/block/block_int.h
34
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
35
36
/* Accessed with atomic ops. */
37
int quiesce_counter;
38
+ int recursive_quiesce_counter;
39
+
40
unsigned int write_gen; /* Current data generation */
41
42
/* Protected by reqs_lock. */
16
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
17
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
44
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
18
BdrvRequestFlags flags);
45
BdrvRequestFlags flags);
19
46
20
+static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
47
+void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
21
+ int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
48
+void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
22
+{
49
+
23
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
50
int get_tmp_filename(char *filename, int size);
24
+
51
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
25
+ return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
52
const char *filename);
26
+}
53
diff --git a/block.c b/block.c
27
+
54
index XXXXXXX..XXXXXXX 100644
28
+static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
55
--- a/block.c
29
+ int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
56
+++ b/block.c
30
+{
57
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_drained_end(BdrvChild *child)
31
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
58
bdrv_drained_end(bs);
32
+
59
}
33
+ return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
60
34
+}
61
+static void bdrv_child_cb_attach(BdrvChild *child)
35
+
62
+{
36
extern unsigned int bdrv_drain_all_count;
63
+ BlockDriverState *bs = child->opaque;
37
void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
64
+ bdrv_apply_subtree_drain(child, bs);
38
void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
65
+}
39
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
66
+
40
index XXXXXXX..XXXXXXX 100644
67
+static void bdrv_child_cb_detach(BdrvChild *child)
41
--- a/include/sysemu/block-backend.h
68
+{
42
+++ b/include/sysemu/block-backend.h
69
+ BlockDriverState *bs = child->opaque;
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
70
+ bdrv_unapply_subtree_drain(child, bs);
44
int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
71
+}
45
unsigned int bytes, QEMUIOVector *qiov,
72
+
46
BdrvRequestFlags flags);
73
static int bdrv_child_cb_inactivate(BdrvChild *child)
47
+
74
{
48
+static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
75
BlockDriverState *bs = child->opaque;
49
+ unsigned int bytes, void *buf,
76
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_file = {
50
+ BdrvRequestFlags flags)
77
.inherit_options = bdrv_inherited_options,
51
+{
78
.drained_begin = bdrv_child_cb_drained_begin,
52
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
79
.drained_end = bdrv_child_cb_drained_end,
53
+
80
+ .attach = bdrv_child_cb_attach,
54
+ return blk_co_preadv(blk, offset, bytes, &qiov, flags);
81
+ .detach = bdrv_child_cb_detach,
55
+}
82
.inactivate = bdrv_child_cb_inactivate,
56
+
83
};
57
+static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
84
58
+ unsigned int bytes, void *buf,
85
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_format = {
59
+ BdrvRequestFlags flags)
86
.inherit_options = bdrv_inherited_fmt_options,
60
+{
87
.drained_begin = bdrv_child_cb_drained_begin,
61
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
88
.drained_end = bdrv_child_cb_drained_end,
62
+
89
+ .attach = bdrv_child_cb_attach,
63
+ return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
90
+ .detach = bdrv_child_cb_detach,
64
+}
91
.inactivate = bdrv_child_cb_inactivate,
65
+
92
};
66
int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
93
67
int bytes, BdrvRequestFlags flags);
94
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_attach(BdrvChild *c)
68
BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
95
parent->backing_blocker);
96
bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_BACKUP_TARGET,
97
parent->backing_blocker);
98
+
99
+ bdrv_child_cb_attach(c);
100
}
101
102
static void bdrv_backing_detach(BdrvChild *c)
103
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_detach(BdrvChild *c)
104
bdrv_op_unblock_all(c->bs, parent->backing_blocker);
105
error_free(parent->backing_blocker);
106
parent->backing_blocker = NULL;
107
+
108
+ bdrv_child_cb_detach(c);
109
}
110
111
/*
112
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
113
assert(bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs));
114
}
115
if (old_bs) {
116
+ /* Detach first so that the recursive drain sections coming from @child
117
+ * are already gone and we only end the drain sections that came from
118
+ * elsewhere. */
119
+ if (child->role->detach) {
120
+ child->role->detach(child);
121
+ }
122
if (old_bs->quiesce_counter && child->role->drained_end) {
123
for (i = 0; i < old_bs->quiesce_counter; i++) {
124
child->role->drained_end(child);
125
}
126
}
127
- if (child->role->detach) {
128
- child->role->detach(child);
129
- }
130
QLIST_REMOVE(child, next_parent);
131
}
132
133
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
134
}
135
}
136
137
+ /* Attach only after starting new drained sections, so that recursive
138
+ * drain sections coming from @child don't get an extra .drained_begin
139
+ * callback. */
140
if (child->role->attach) {
141
child->role->attach(child);
142
}
143
diff --git a/block/io.c b/block/io.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/block/io.c
146
+++ b/block/io.c
147
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
148
assert(data.done);
149
}
150
151
-static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive,
152
- BdrvChild *parent)
153
+void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive,
154
+ BdrvChild *parent)
155
{
156
BdrvChild *child, *next;
157
158
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive,
159
bdrv_drain_recurse(bs);
160
161
if (recursive) {
162
+ bs->recursive_quiesce_counter++;
163
QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
164
bdrv_do_drained_begin(child->bs, true, child);
165
}
166
@@ -XXX,XX +XXX,XX @@ void bdrv_subtree_drained_begin(BlockDriverState *bs)
167
bdrv_do_drained_begin(bs, true, NULL);
168
}
169
170
-static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive,
171
- BdrvChild *parent)
172
+void bdrv_do_drained_end(BlockDriverState *bs, bool recursive,
173
+ BdrvChild *parent)
174
{
175
BdrvChild *child, *next;
176
int old_quiesce_counter;
177
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive,
178
}
179
180
if (recursive) {
181
+ bs->recursive_quiesce_counter--;
182
QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
183
bdrv_do_drained_end(child->bs, true, child);
184
}
185
@@ -XXX,XX +XXX,XX @@ void bdrv_subtree_drained_end(BlockDriverState *bs)
186
bdrv_do_drained_end(bs, true, NULL);
187
}
188
189
+void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent)
190
+{
191
+ int i;
192
+
193
+ for (i = 0; i < new_parent->recursive_quiesce_counter; i++) {
194
+ bdrv_do_drained_begin(child->bs, true, child);
195
+ }
196
+}
197
+
198
+void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent)
199
+{
200
+ int i;
201
+
202
+ for (i = 0; i < old_parent->recursive_quiesce_counter; i++) {
203
+ bdrv_do_drained_end(child->bs, true, child);
204
+ }
205
+}
206
+
207
/*
208
* Wait for pending requests to complete on a single BlockDriverState subtree,
209
* and suspend block driver's internal I/O until next request arrives.
69
--
210
--
70
2.20.1
211
2.13.6
71
212
72
213
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
3
Using IEC binary prefixes in order to make the code more readable,
4
with the exception of DEFAULT_LOG_SIZE because it's passed to
5
stringify().
6
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
2
---
12
block/vhdx.h | 10 ++++++----
3
tests/test-bdrv-drain.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++
13
block/vhdx-log.c | 2 +-
4
1 file changed, 80 insertions(+)
14
block/vhdx.c | 4 ++--
15
3 files changed, 9 insertions(+), 7 deletions(-)
16
5
17
diff --git a/block/vhdx.h b/block/vhdx.h
6
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
18
index XXXXXXX..XXXXXXX 100644
7
index XXXXXXX..XXXXXXX 100644
19
--- a/block/vhdx.h
8
--- a/tests/test-bdrv-drain.c
20
+++ b/block/vhdx.h
9
+++ b/tests/test-bdrv-drain.c
21
@@ -XXX,XX +XXX,XX @@
10
@@ -XXX,XX +XXX,XX @@ static void test_multiparent(void)
22
#include "qemu/units.h"
11
blk_unref(blk_b);
23
12
}
24
#define DEFAULT_LOG_SIZE 1048576 /* 1MiB */
13
25
+/* Note: can't use 1 * MiB, because it's passed to stringify() */
14
+static void test_graph_change(void)
15
+{
16
+ BlockBackend *blk_a, *blk_b;
17
+ BlockDriverState *bs_a, *bs_b, *backing;
18
+ BDRVTestState *a_s, *b_s, *backing_s;
26
+
19
+
27
/* Structures and fields present in the VHDX file */
20
+ blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
28
21
+ bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
29
/* The header section has the following blocks,
22
+ &error_abort);
30
@@ -XXX,XX +XXX,XX @@
23
+ a_s = bs_a->opaque;
31
* 0.........64KB...........128KB........192KB..........256KB................1MB
24
+ blk_insert_bs(blk_a, bs_a, &error_abort);
32
*/
25
+
33
26
+ blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
34
-#define VHDX_HEADER_BLOCK_SIZE (64 * 1024)
27
+ bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
35
+#define VHDX_HEADER_BLOCK_SIZE (64 * KiB)
28
+ &error_abort);
36
29
+ b_s = bs_b->opaque;
37
#define VHDX_FILE_ID_OFFSET 0
30
+ blk_insert_bs(blk_b, bs_b, &error_abort);
38
#define VHDX_HEADER1_OFFSET (VHDX_HEADER_BLOCK_SIZE * 1)
31
+
39
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED MSGUID {
32
+ backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
40
#define guid_eq(a, b) \
33
+ backing_s = backing->opaque;
41
(memcmp(&(a), &(b), sizeof(MSGUID)) == 0)
34
+ bdrv_set_backing_hd(bs_a, backing, &error_abort);
42
35
+
43
-#define VHDX_HEADER_SIZE (4 * 1024) /* although the vhdx_header struct in disk
36
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
44
+#define VHDX_HEADER_SIZE (4 * KiB) /* although the vhdx_header struct in disk
37
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
45
is only 582 bytes, for purposes of crc
38
+ g_assert_cmpint(backing->quiesce_counter, ==, 0);
46
the header is the first 4KB of the 64KB
39
+ g_assert_cmpint(a_s->drain_count, ==, 0);
47
block */
40
+ g_assert_cmpint(b_s->drain_count, ==, 0);
48
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED VHDXRegionTableEntry {
41
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
49
42
+
50
43
+ do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
51
/* ---- LOG ENTRY STRUCTURES ---- */
44
+ do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
52
-#define VHDX_LOG_MIN_SIZE (1024 * 1024)
45
+ do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
53
-#define VHDX_LOG_SECTOR_SIZE 4096
46
+ do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
54
+#define VHDX_LOG_MIN_SIZE (1 * MiB)
47
+ do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
55
+#define VHDX_LOG_SECTOR_SIZE (4 * KiB)
48
+
56
#define VHDX_LOG_HDR_SIZE 64
49
+ bdrv_set_backing_hd(bs_b, backing, &error_abort);
57
#define VHDX_LOG_SIGNATURE 0x65676f6c
50
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 5);
58
typedef struct QEMU_PACKED VHDXLogEntryHeader {
51
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 5);
59
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
52
+ g_assert_cmpint(backing->quiesce_counter, ==, 5);
60
index XXXXXXX..XXXXXXX 100644
53
+ g_assert_cmpint(a_s->drain_count, ==, 5);
61
--- a/block/vhdx-log.c
54
+ g_assert_cmpint(b_s->drain_count, ==, 5);
62
+++ b/block/vhdx-log.c
55
+ g_assert_cmpint(backing_s->drain_count, ==, 5);
63
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
56
+
64
}
57
+ bdrv_set_backing_hd(bs_b, NULL, &error_abort);
65
if (file_length < desc_entries->hdr.last_file_offset) {
58
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 3);
66
new_file_size = desc_entries->hdr.last_file_offset;
59
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 2);
67
- if (new_file_size % (1024*1024)) {
60
+ g_assert_cmpint(backing->quiesce_counter, ==, 3);
68
+ if (new_file_size % (1 * MiB)) {
61
+ g_assert_cmpint(a_s->drain_count, ==, 3);
69
/* round up to nearest 1MB boundary */
62
+ g_assert_cmpint(b_s->drain_count, ==, 2);
70
new_file_size = QEMU_ALIGN_UP(new_file_size, MiB);
63
+ g_assert_cmpint(backing_s->drain_count, ==, 3);
71
if (new_file_size > INT64_MAX) {
64
+
72
diff --git a/block/vhdx.c b/block/vhdx.c
65
+ bdrv_set_backing_hd(bs_b, backing, &error_abort);
73
index XXXXXXX..XXXXXXX 100644
66
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 5);
74
--- a/block/vhdx.c
67
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 5);
75
+++ b/block/vhdx.c
68
+ g_assert_cmpint(backing->quiesce_counter, ==, 5);
76
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
69
+ g_assert_cmpint(a_s->drain_count, ==, 5);
77
*new_offset = current_len;
70
+ g_assert_cmpint(b_s->drain_count, ==, 5);
78
71
+ g_assert_cmpint(backing_s->drain_count, ==, 5);
79
/* per the spec, the address for a block is in units of 1MB */
72
+
80
- *new_offset = ROUND_UP(*new_offset, 1024 * 1024);
73
+ do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
81
+ *new_offset = ROUND_UP(*new_offset, 1 * MiB);
74
+ do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
82
if (*new_offset > INT64_MAX) {
75
+ do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
83
return -EINVAL;
76
+ do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
84
}
77
+ do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
85
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
78
+
86
case PAYLOAD_BLOCK_FULLY_PRESENT:
79
+ g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
87
/* if the file offset address is in the header zone,
80
+ g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
88
* there is a problem */
81
+ g_assert_cmpint(backing->quiesce_counter, ==, 0);
89
- if (sinfo.file_offset < (1024 * 1024)) {
82
+ g_assert_cmpint(a_s->drain_count, ==, 0);
90
+ if (sinfo.file_offset < (1 * MiB)) {
83
+ g_assert_cmpint(b_s->drain_count, ==, 0);
91
ret = -EFAULT;
84
+ g_assert_cmpint(backing_s->drain_count, ==, 0);
92
goto error_bat_restore;
85
+
93
}
86
+ bdrv_unref(backing);
87
+ bdrv_unref(bs_a);
88
+ bdrv_unref(bs_b);
89
+ blk_unref(blk_a);
90
+ blk_unref(blk_b);
91
+}
92
+
93
94
typedef struct TestBlockJob {
95
BlockJob common;
96
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
97
98
g_test_add_func("/bdrv-drain/nested", test_nested);
99
g_test_add_func("/bdrv-drain/multiparent", test_multiparent);
100
+ g_test_add_func("/bdrv-drain/graph-change", test_graph_change);
101
102
g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
103
g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain);
94
--
104
--
95
2.20.1
105
2.13.6
96
106
97
107
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
Since commit bde70715, base is the only node that is reopened in
2
commit_start(). This means that the code, which still involves an
3
explicit BlockReopenQueue, can now be simplified by using bdrv_reopen().
2
4
3
You can reproduce this by passing an invalid filter-node-name (like
4
"1234") to block-commit. In this case the base image is put in
5
read-write mode but is never reset back to read-only.
6
7
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Fam Zheng <famz@redhat.com>
10
---
7
---
11
block/commit.c | 3 +++
8
block/commit.c | 8 +-------
12
1 file changed, 3 insertions(+)
9
1 file changed, 1 insertion(+), 7 deletions(-)
13
10
14
diff --git a/block/commit.c b/block/commit.c
11
diff --git a/block/commit.c b/block/commit.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/block/commit.c
13
--- a/block/commit.c
17
+++ b/block/commit.c
14
+++ b/block/commit.c
18
@@ -XXX,XX +XXX,XX @@ fail:
15
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
19
if (s->top) {
16
const char *filter_node_name, Error **errp)
20
blk_unref(s->top);
17
{
21
}
18
CommitBlockJob *s;
22
+ if (s->base_read_only) {
19
- BlockReopenQueue *reopen_queue = NULL;
23
+ bdrv_reopen_set_read_only(base, true, NULL);
20
int orig_base_flags;
24
+ }
21
BlockDriverState *iter;
25
job_early_fail(&s->common.job);
22
BlockDriverState *commit_top_bs = NULL;
26
/* commit_top_bs has to be replaced after deleting the block job,
23
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
27
* otherwise this would fail because of lack of permissions. */
24
/* convert base to r/w, if necessary */
25
orig_base_flags = bdrv_get_flags(base);
26
if (!(orig_base_flags & BDRV_O_RDWR)) {
27
- reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,
28
- orig_base_flags | BDRV_O_RDWR);
29
- }
30
-
31
- if (reopen_queue) {
32
- bdrv_reopen_multiple(bdrv_get_aio_context(bs), reopen_queue, &local_err);
33
+ bdrv_reopen(base, orig_base_flags | BDRV_O_RDWR, &local_err);
34
if (local_err != NULL) {
35
error_propagate(errp, local_err);
36
goto fail;
28
--
37
--
29
2.20.1
38
2.13.6
30
39
31
40
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
The bdrv_reopen*() implementation doesn't like it if the graph is
2
changed between queuing nodes for reopen and actually reopening them
3
(one of the reasons is that queuing can be recursive).
2
4
3
qed_read_table and qed_write_table use coroutine-only interfaces but
5
So instead of draining the device only in bdrv_reopen_multiple(),
4
are not marked coroutine_fn. Happily, they are called only from
6
require that callers already drained all affected nodes, and assert this
5
coroutine context, so we only need to add missed markers.
7
in bdrv_reopen_queue().
6
8
7
Reported-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Fam Zheng <famz@redhat.com>
10
---
11
---
11
block/qed.h | 28 ++++++++++++++++------------
12
block.c | 23 ++++++++++++++++-------
12
block/qed-check.c | 4 ++--
13
block/replication.c | 6 ++++++
13
block/qed-table.c | 33 ++++++++++++++++++++-------------
14
qemu-io-cmds.c | 3 +++
14
block/qed.c | 5 +++--
15
3 files changed, 25 insertions(+), 7 deletions(-)
15
4 files changed, 41 insertions(+), 29 deletions(-)
16
16
17
diff --git a/block/qed.h b/block/qed.h
17
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qed.h
19
--- a/block.c
20
+++ b/block/qed.h
20
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
21
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
22
/**
22
* returns a pointer to bs_queue, which is either the newly allocated
23
* Table I/O functions
23
* bs_queue, or the existing bs_queue being used.
24
*
25
+ * bs must be drained between bdrv_reopen_queue() and bdrv_reopen_multiple().
24
*/
26
*/
25
-int qed_read_l1_table_sync(BDRVQEDState *s);
27
static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
26
-int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
28
BlockDriverState *bs,
27
-int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
29
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
28
- unsigned int n);
30
BdrvChild *child;
29
-int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
31
QDict *old_options, *explicit_options;
30
- uint64_t offset);
32
31
-int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
33
+ /* Make sure that the caller remembered to use a drained section. This is
32
-int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
34
+ * important to avoid graph changes between the recursive queuing here and
33
- unsigned int index, unsigned int n, bool flush);
35
+ * bdrv_reopen_multiple(). */
34
-int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
36
+ assert(bs->quiesce_counter > 0);
35
- unsigned int index, unsigned int n, bool flush);
37
+
36
+int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s);
38
if (bs_queue == NULL) {
37
+int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
39
bs_queue = g_new0(BlockReopenQueue, 1);
38
+ unsigned int n);
40
QSIMPLEQ_INIT(bs_queue);
39
+int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
41
@@ -XXX,XX +XXX,XX @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
40
+ unsigned int n);
42
* If all devices prepare successfully, then the changes are committed
41
+int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
43
* to all devices.
42
+ uint64_t offset);
44
*
43
+int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
45
+ * All affected nodes must be drained between bdrv_reopen_queue() and
44
+ uint64_t offset);
46
+ * bdrv_reopen_multiple().
45
+int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
46
+ unsigned int index, unsigned int n,
47
+ bool flush);
48
+int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
49
+ unsigned int index, unsigned int n,
50
+ bool flush);
51
52
/**
53
* Cluster functions
54
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
55
/**
56
* Consistency check
57
*/
47
*/
58
-int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
48
int bdrv_reopen_multiple(AioContext *ctx, BlockReopenQueue *bs_queue, Error **errp)
59
+int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
60
61
QEDTable *qed_alloc_table(BDRVQEDState *s);
62
63
diff --git a/block/qed-check.c b/block/qed-check.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/block/qed-check.c
66
+++ b/block/qed-check.c
67
@@ -XXX,XX +XXX,XX @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
68
/**
69
* Descend tables and check each cluster is referenced once only
70
*/
71
-static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
72
+static int coroutine_fn qed_check_l1_table(QEDCheck *check, QEDTable *table)
73
{
49
{
74
BDRVQEDState *s = check->s;
50
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(AioContext *ctx, BlockReopenQueue *bs_queue, Error **er
75
unsigned int i, num_invalid_l1 = 0;
51
76
@@ -XXX,XX +XXX,XX @@ static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result)
52
assert(bs_queue != NULL);
77
}
53
78
54
- aio_context_release(ctx);
79
/* Called with table_lock held. */
55
- bdrv_drain_all_begin();
80
-int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
56
- aio_context_acquire(ctx);
81
+int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
57
-
82
{
58
QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
83
QEDCheck check = {
59
+ assert(bs_entry->state.bs->quiesce_counter > 0);
84
.s = s,
60
if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, &local_err)) {
85
diff --git a/block/qed-table.c b/block/qed-table.c
61
error_propagate(errp, local_err);
86
index XXXXXXX..XXXXXXX 100644
62
goto cleanup;
87
--- a/block/qed-table.c
63
@@ -XXX,XX +XXX,XX @@ cleanup:
88
+++ b/block/qed-table.c
64
}
89
@@ -XXX,XX +XXX,XX @@
65
g_free(bs_queue);
90
#include "qemu/bswap.h"
66
91
67
- bdrv_drain_all_end();
92
/* Called with table_lock held. */
68
-
93
-static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
94
+static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset,
95
+ QEDTable *table)
96
{
97
unsigned int bytes = s->header.cluster_size * s->header.table_size;
98
99
@@ -XXX,XX +XXX,XX @@ out:
100
*
101
* Called with table_lock held.
102
*/
103
-static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
104
- unsigned int index, unsigned int n, bool flush)
105
+static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset,
106
+ QEDTable *table, unsigned int index,
107
+ unsigned int n, bool flush)
108
{
109
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
110
unsigned int start, end, i;
111
@@ -XXX,XX +XXX,XX @@ out:
112
return ret;
69
return ret;
113
}
70
}
114
71
115
-int qed_read_l1_table_sync(BDRVQEDState *s)
72
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp)
116
+int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s)
117
{
73
{
118
return qed_read_table(s, s->header.l1_table_offset, s->l1_table);
74
int ret = -1;
119
}
75
Error *local_err = NULL;
120
76
- BlockReopenQueue *queue = bdrv_reopen_queue(NULL, bs, NULL, bdrv_flags);
121
/* Called with table_lock held. */
77
+ BlockReopenQueue *queue;
122
-int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n)
78
123
+int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
79
+ bdrv_subtree_drained_begin(bs);
124
+ unsigned int n)
80
+
125
{
81
+ queue = bdrv_reopen_queue(NULL, bs, NULL, bdrv_flags);
126
BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
82
ret = bdrv_reopen_multiple(bdrv_get_aio_context(bs), queue, &local_err);
127
return qed_write_table(s, s->header.l1_table_offset,
83
if (local_err != NULL) {
128
s->l1_table, index, n, false);
84
error_propagate(errp, local_err);
129
}
85
}
130
86
+
131
-int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
87
+ bdrv_subtree_drained_end(bs);
132
- unsigned int n)
88
+
133
+int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
134
+ unsigned int n)
135
{
136
return qed_write_l1_table(s, index, n);
137
}
138
139
/* Called with table_lock held. */
140
-int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
141
+int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
142
+ uint64_t offset)
143
{
144
int ret;
145
146
@@ -XXX,XX +XXX,XX @@ int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
147
return ret;
89
return ret;
148
}
90
}
149
91
150
-int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
92
diff --git a/block/replication.c b/block/replication.c
151
+int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
93
index XXXXXXX..XXXXXXX 100644
152
+ uint64_t offset)
94
--- a/block/replication.c
153
{
95
+++ b/block/replication.c
154
return qed_read_l2_table(s, request, offset);
96
@@ -XXX,XX +XXX,XX @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
97
new_secondary_flags = s->orig_secondary_flags;
98
}
99
100
+ bdrv_subtree_drained_begin(s->hidden_disk->bs);
101
+ bdrv_subtree_drained_begin(s->secondary_disk->bs);
102
+
103
if (orig_hidden_flags != new_hidden_flags) {
104
reopen_queue = bdrv_reopen_queue(reopen_queue, s->hidden_disk->bs, NULL,
105
new_hidden_flags);
106
@@ -XXX,XX +XXX,XX @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
107
reopen_queue, &local_err);
108
error_propagate(errp, local_err);
109
}
110
+
111
+ bdrv_subtree_drained_end(s->hidden_disk->bs);
112
+ bdrv_subtree_drained_end(s->secondary_disk->bs);
155
}
113
}
156
114
157
/* Called with table_lock held. */
115
static void backup_job_cleanup(BlockDriverState *bs)
158
-int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
116
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
159
- unsigned int index, unsigned int n, bool flush)
160
+int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
161
+ unsigned int index, unsigned int n,
162
+ bool flush)
163
{
164
BLKDBG_EVENT(s->bs->file, BLKDBG_L2_UPDATE);
165
return qed_write_table(s, request->l2_table->offset,
166
request->l2_table->table, index, n, flush);
167
}
168
169
-int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
170
- unsigned int index, unsigned int n, bool flush)
171
+int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
172
+ unsigned int index, unsigned int n,
173
+ bool flush)
174
{
175
return qed_write_l2_table(s, request, index, n, flush);
176
}
177
diff --git a/block/qed.c b/block/qed.c
178
index XXXXXXX..XXXXXXX 100644
117
index XXXXXXX..XXXXXXX 100644
179
--- a/block/qed.c
118
--- a/qemu-io-cmds.c
180
+++ b/block/qed.c
119
+++ b/qemu-io-cmds.c
181
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
120
@@ -XXX,XX +XXX,XX @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
182
}
121
opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : NULL;
183
}
122
qemu_opts_reset(&reopen_opts);
184
123
185
-static int bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result,
124
+ bdrv_subtree_drained_begin(bs);
186
- BdrvCheckMode fix)
125
brq = bdrv_reopen_queue(NULL, bs, opts, flags);
187
+static int coroutine_fn bdrv_qed_co_check(BlockDriverState *bs,
126
bdrv_reopen_multiple(bdrv_get_aio_context(bs), brq, &local_err);
188
+ BdrvCheckResult *result,
127
+ bdrv_subtree_drained_end(bs);
189
+ BdrvCheckMode fix)
128
+
190
{
129
if (local_err) {
191
BDRVQEDState *s = bs->opaque;
130
error_report_err(local_err);
192
int ret;
131
} else {
193
--
132
--
194
2.20.1
133
2.13.6
195
134
196
135
diff view generated by jsdifflib