1
The following changes since commit e4ae62b802cec437f877f2cadc4ef059cc0eca76:
1
The following changes since commit 418fa86dd465b4fd8394373cf83db8fa65d7611c:
2
2
3
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2018-03-09 17:28:16 +0000)
3
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-040220-1' into staging (2020-02-04 18:55:06 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/stefanha/qemu.git tags/block-pull-request
7
https://github.com/XanClic/qemu.git tags/pull-block-2020-02-06
8
8
9
for you to fetch changes up to 7376eda7c2e0451e819e81bd05fabc56a9deb946:
9
for you to fetch changes up to a541fcc27c98b96da187c7d4573f3270f3ddd283:
10
10
11
block: make BDRV_POLL_WHILE() re-entrancy safe (2018-03-12 11:07:37 +0000)
11
iotests: add test for backup-top failure on permission activation (2020-02-06 13:47:45 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
15
- Drop BDRV_SECTOR_SIZE from qcow2
16
- Allow Python iotests to be added to the auto group
17
(and add some)
18
- Fix for the backup job
19
- Fix memleak in bdrv_refresh_filename()
20
- Use GStrings in two places for greater efficiency (than manually
21
handling string allocation)
14
22
15
----------------------------------------------------------------
23
----------------------------------------------------------------
24
Alberto Garcia (8):
25
qcow2: Assert that host cluster offsets fit in L2 table entries
26
block: Use a GString in bdrv_perm_names()
27
qcow2: Use a GString in report_unsupported_feature()
28
qcow2: Don't round the L1 table allocation up to the sector size
29
qcow2: Tighten cluster_offset alignment assertions
30
qcow2: Use bs->bl.request_alignment when updating an L1 entry
31
qcow2: Don't require aligned offsets in qcow2_co_copy_range_from()
32
qcow2: Use BDRV_SECTOR_SIZE instead of the hardcoded value
16
33
17
Stefan Hajnoczi (1):
34
John Snow (1):
18
block: make BDRV_POLL_WHILE() re-entrancy safe
35
iotests: remove 'linux' from default supported platforms
19
36
20
include/block/aio-wait.h | 61 ++++++++++++++++++++++++------------------------
37
Pan Nengyuan (1):
21
util/aio-wait.c | 2 +-
38
block: fix memleaks in bdrv_refresh_filename
22
2 files changed, 31 insertions(+), 32 deletions(-)
39
40
Thomas Huth (5):
41
iotests: Test 041 only works on certain systems
42
iotests: Test 183 does not work on macOS and OpenBSD
43
iotests: Check for the availability of the required devices in 267 and
44
127
45
iotests: Skip Python-based tests if QEMU does not support virtio-blk
46
iotests: Enable more tests in the 'auto' group to improve test
47
coverage
48
49
Vladimir Sementsov-Ogievskiy (2):
50
block/backup-top: fix failure path
51
iotests: add test for backup-top failure on permission activation
52
53
block.c | 12 +++--
54
block/backup-top.c | 21 ++++----
55
block/qcow2-cluster.c | 44 +++++++++++------
56
block/qcow2-refcount.c | 2 +-
57
block/qcow2-snapshot.c | 3 +-
58
block/qcow2.c | 46 ++++++++----------
59
tests/qemu-iotests/041 | 3 +-
60
tests/qemu-iotests/127 | 2 +
61
tests/qemu-iotests/183 | 1 +
62
tests/qemu-iotests/267 | 2 +
63
tests/qemu-iotests/283 | 92 +++++++++++++++++++++++++++++++++++
64
tests/qemu-iotests/283.out | 8 +++
65
tests/qemu-iotests/check | 12 ++++-
66
tests/qemu-iotests/common.rc | 14 ++++++
67
tests/qemu-iotests/group | 15 +++---
68
tests/qemu-iotests/iotests.py | 16 ++++--
69
16 files changed, 220 insertions(+), 73 deletions(-)
70
create mode 100644 tests/qemu-iotests/283
71
create mode 100644 tests/qemu-iotests/283.out
23
72
24
--
73
--
25
2.14.3
74
2.24.1
26
75
27
76
diff view generated by jsdifflib
New patch
1
From: Alberto Garcia <berto@igalia.com>
1
2
3
The standard cluster descriptor in L2 table entries has a field to
4
store the host cluster offset. When we need to get that offset from an
5
entry we use L2E_OFFSET_MASK to ensure that we only use the bits that
6
belong to that field.
7
8
But while that mask is used every time we read from an L2 entry, it
9
is never used when we write to it. Due to the QCOW_MAX_CLUSTER_OFFSET
10
limit set in the cluster allocation code QEMU can never produce
11
offsets that don't fit in that field so any such offset would indicate
12
a bug in QEMU.
13
14
Compressed cluster descriptors contain two fields (host cluster offset
15
and size of the compressed data) and the situation with them is
16
similar. In this case the masks are not constant but are stored in the
17
csize_mask and cluster_offset_mask fields of BDRVQcow2State.
18
19
Signed-off-by: Alberto Garcia <berto@igalia.com>
20
Reviewed-by: Eric Blake <eblake@redhat.com>
21
Message-id: 20200113161146.20099-1-berto@igalia.com
22
Signed-off-by: Max Reitz <mreitz@redhat.com>
23
---
24
block/qcow2-cluster.c | 14 ++++++++++++--
25
1 file changed, 12 insertions(+), 2 deletions(-)
26
27
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/block/qcow2-cluster.c
30
+++ b/block/qcow2-cluster.c
31
@@ -XXX,XX +XXX,XX @@ int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
32
(cluster_offset + compressed_size - 1) / QCOW2_COMPRESSED_SECTOR_SIZE -
33
(cluster_offset / QCOW2_COMPRESSED_SECTOR_SIZE);
34
35
+ /* The offset and size must fit in their fields of the L2 table entry */
36
+ assert((cluster_offset & s->cluster_offset_mask) == cluster_offset);
37
+ assert((nb_csectors & s->csize_mask) == nb_csectors);
38
+
39
cluster_offset |= QCOW_OFLAG_COMPRESSED |
40
((uint64_t)nb_csectors << s->csize_shift);
41
42
@@ -XXX,XX +XXX,XX @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
43
44
assert(l2_index + m->nb_clusters <= s->l2_slice_size);
45
for (i = 0; i < m->nb_clusters; i++) {
46
+ uint64_t offset = cluster_offset + (i << s->cluster_bits);
47
/* if two concurrent writes happen to the same unallocated cluster
48
* each write allocates separate cluster and writes data concurrently.
49
* The first one to complete updates l2 table with pointer to its
50
@@ -XXX,XX +XXX,XX @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
51
old_cluster[j++] = l2_slice[l2_index + i];
52
}
53
54
- l2_slice[l2_index + i] = cpu_to_be64((cluster_offset +
55
- (i << s->cluster_bits)) | QCOW_OFLAG_COPIED);
56
+ /* The offset must fit in the offset field of the L2 table entry */
57
+ assert((offset & L2E_OFFSET_MASK) == offset);
58
+
59
+ l2_slice[l2_index + i] = cpu_to_be64(offset | QCOW_OFLAG_COPIED);
60
}
61
62
63
@@ -XXX,XX +XXX,XX @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
64
goto fail;
65
}
66
67
+ /* The offset must fit in the offset field */
68
+ assert((offset & L2E_OFFSET_MASK) == offset);
69
+
70
if (l2_refcount > 1) {
71
/* For shared L2 tables, set the refcount accordingly
72
* (it is already 1 and needs to be l2_refcount) */
73
--
74
2.24.1
75
76
diff view generated by jsdifflib
New patch
1
From: Alberto Garcia <berto@igalia.com>
1
2
3
This is a bit more efficient than having to allocate and free memory
4
for each new permission.
5
6
The default size (30) is enough for "consistent read, write, resize".
7
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
9
Message-id: 20200110171518.22168-1-berto@igalia.com
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
block.c | 11 ++++++-----
14
1 file changed, 6 insertions(+), 5 deletions(-)
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 @@ char *bdrv_perm_names(uint64_t perm)
21
{ 0, NULL }
22
};
23
24
- char *result = g_strdup("");
25
+ GString *result = g_string_sized_new(30);
26
struct perm_name *p;
27
28
for (p = permissions; p->name; p++) {
29
if (perm & p->perm) {
30
- char *old = result;
31
- result = g_strdup_printf("%s%s%s", old, *old ? ", " : "", p->name);
32
- g_free(old);
33
+ if (result->len > 0) {
34
+ g_string_append(result, ", ");
35
+ }
36
+ g_string_append(result, p->name);
37
}
38
}
39
40
- return result;
41
+ return g_string_free(result, FALSE);
42
}
43
44
/*
45
--
46
2.24.1
47
48
diff view generated by jsdifflib
New patch
1
From: Pan Nengyuan <pannengyuan@huawei.com>
1
2
3
If we call the qmp 'query-block' while qemu is working on
4
'block-commit', it will cause memleaks, the memory leak stack is as
5
follow:
6
7
Indirect leak of 12360 byte(s) in 3 object(s) allocated from:
8
#0 0x7f80f0b6d970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970)
9
#1 0x7f80ee86049d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d)
10
#2 0x55ea95b5bb67 in qdict_new /mnt/sdb/qemu-4.2.0-rc0/qobject/qdict.c:29
11
#3 0x55ea956cd043 in bdrv_refresh_filename /mnt/sdb/qemu-4.2.0-rc0/block.c:6427
12
#4 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu-4.2.0-rc0/block.c:6399
13
#5 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu-4.2.0-rc0/block.c:6399
14
#6 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu-4.2.0-rc0/block.c:6399
15
#7 0x55ea958818ea in bdrv_block_device_info /mnt/sdb/qemu-4.2.0-rc0/block/qapi.c:56
16
#8 0x55ea958879de in bdrv_query_info /mnt/sdb/qemu-4.2.0-rc0/block/qapi.c:392
17
#9 0x55ea9588b58f in qmp_query_block /mnt/sdb/qemu-4.2.0-rc0/block/qapi.c:578
18
#10 0x55ea95567392 in qmp_marshal_query_block qapi/qapi-commands-block-core.c:95
19
20
Indirect leak of 4120 byte(s) in 1 object(s) allocated from:
21
#0 0x7f80f0b6d970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970)
22
#1 0x7f80ee86049d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d)
23
#2 0x55ea95b5bb67 in qdict_new /mnt/sdb/qemu-4.2.0-rc0/qobject/qdict.c:29
24
#3 0x55ea956cd043 in bdrv_refresh_filename /mnt/sdb/qemu-4.2.0-rc0/block.c:6427
25
#4 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu-4.2.0-rc0/block.c:6399
26
#5 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu-4.2.0-rc0/block.c:6399
27
#6 0x55ea9569f301 in bdrv_backing_attach /mnt/sdb/qemu-4.2.0-rc0/block.c:1064
28
#7 0x55ea956a99dd in bdrv_replace_child_noperm /mnt/sdb/qemu-4.2.0-rc0/block.c:2283
29
#8 0x55ea956b9b53 in bdrv_replace_node /mnt/sdb/qemu-4.2.0-rc0/block.c:4196
30
#9 0x55ea956b9e49 in bdrv_append /mnt/sdb/qemu-4.2.0-rc0/block.c:4236
31
#10 0x55ea958c3472 in commit_start /mnt/sdb/qemu-4.2.0-rc0/block/commit.c:306
32
#11 0x55ea94b68ab0 in qmp_block_commit /mnt/sdb/qemu-4.2.0-rc0/blockdev.c:3459
33
#12 0x55ea9556a7a7 in qmp_marshal_block_commit qapi/qapi-commands-block-core.c:407
34
35
Fixes: bb808d5f5c0978828a974d547e6032402c339555
36
Reported-by: Euler Robot <euler.robot@huawei.com>
37
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
38
Message-id: 20200116085600.24056-1-pannengyuan@huawei.com
39
Signed-off-by: Max Reitz <mreitz@redhat.com>
40
---
41
block.c | 1 +
42
1 file changed, 1 insertion(+)
43
44
diff --git a/block.c b/block.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/block.c
47
+++ b/block.c
48
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_filename(BlockDriverState *bs)
49
child->bs->exact_filename);
50
pstrcpy(bs->filename, sizeof(bs->filename), child->bs->filename);
51
52
+ qobject_unref(bs->full_open_options);
53
bs->full_open_options = qobject_ref(child->bs->full_open_options);
54
55
return;
56
--
57
2.24.1
58
59
diff view generated by jsdifflib
New patch
1
From: Alberto Garcia <berto@igalia.com>
1
2
3
This is a bit more efficient than having to allocate and free memory
4
for each item.
5
6
The default size (60) is enough for all the existing incompatible
7
features or the "Unknown incompatible feature" message.
8
9
Suggested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20200115135626.19442-1-berto@igalia.com
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
17
block/qcow2.c | 23 +++++++++++------------
18
1 file changed, 11 insertions(+), 12 deletions(-)
19
20
diff --git a/block/qcow2.c b/block/qcow2.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/qcow2.c
23
+++ b/block/qcow2.c
24
@@ -XXX,XX +XXX,XX @@ static void cleanup_unknown_header_ext(BlockDriverState *bs)
25
static void report_unsupported_feature(Error **errp, Qcow2Feature *table,
26
uint64_t mask)
27
{
28
- char *features = g_strdup("");
29
- char *old;
30
+ g_autoptr(GString) features = g_string_sized_new(60);
31
32
while (table && table->name[0] != '\0') {
33
if (table->type == QCOW2_FEAT_TYPE_INCOMPATIBLE) {
34
if (mask & (1ULL << table->bit)) {
35
- old = features;
36
- features = g_strdup_printf("%s%s%.46s", old, *old ? ", " : "",
37
- table->name);
38
- g_free(old);
39
+ if (features->len > 0) {
40
+ g_string_append(features, ", ");
41
+ }
42
+ g_string_append_printf(features, "%.46s", table->name);
43
mask &= ~(1ULL << table->bit);
44
}
45
}
46
@@ -XXX,XX +XXX,XX @@ static void report_unsupported_feature(Error **errp, Qcow2Feature *table,
47
}
48
49
if (mask) {
50
- old = features;
51
- features = g_strdup_printf("%s%sUnknown incompatible feature: %" PRIx64,
52
- old, *old ? ", " : "", mask);
53
- g_free(old);
54
+ if (features->len > 0) {
55
+ g_string_append(features, ", ");
56
+ }
57
+ g_string_append_printf(features,
58
+ "Unknown incompatible feature: %" PRIx64, mask);
59
}
60
61
- error_setg(errp, "Unsupported qcow2 feature(s): %s", features);
62
- g_free(features);
63
+ error_setg(errp, "Unsupported qcow2 feature(s): %s", features->str);
64
}
65
66
/*
67
--
68
2.24.1
69
70
diff view generated by jsdifflib
New patch
1
From: John Snow <jsnow@redhat.com>
1
2
3
verify_platform will check an explicit whitelist and blacklist instead.
4
The default will now be assumed to be allowed to run anywhere.
5
6
For tests that do not specify their platforms explicitly, this has the effect of
7
enabling these tests on non-linux platforms. For tests that always specified
8
linux explicitly, there is no change.
9
10
For Python tests on FreeBSD at least; only seven python tests fail:
11
045 147 149 169 194 199 211
12
13
045 and 149 appear to be misconfigurations,
14
147 and 194 are the AF_UNIX path too long error,
15
169 and 199 are bitmap migration bugs, and
16
211 is a bug that shows up on Linux platforms, too.
17
18
This is at least good evidence that these tests are not Linux-only. If
19
they aren't suitable for other platforms, they should be disabled on a
20
per-platform basis as appropriate.
21
22
Therefore, let's switch these on and deal with the failures.
23
24
Reviewed-by: Max Reitz <mreitz@redhat.com>
25
Signed-off-by: John Snow <jsnow@redhat.com>
26
Message-id: 20200121095205.26323-2-thuth@redhat.com
27
Signed-off-by: Max Reitz <mreitz@redhat.com>
28
---
29
tests/qemu-iotests/iotests.py | 16 +++++++++++-----
30
1 file changed, 11 insertions(+), 5 deletions(-)
31
32
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
33
index XXXXXXX..XXXXXXX 100644
34
--- a/tests/qemu-iotests/iotests.py
35
+++ b/tests/qemu-iotests/iotests.py
36
@@ -XXX,XX +XXX,XX @@ def verify_protocol(supported=[], unsupported=[]):
37
if not_sup or (imgproto in unsupported):
38
notrun('not suitable for this protocol: %s' % imgproto)
39
40
-def verify_platform(supported_oses=['linux']):
41
- if True not in [sys.platform.startswith(x) for x in supported_oses]:
42
- notrun('not suitable for this OS: %s' % sys.platform)
43
+def verify_platform(supported=None, unsupported=None):
44
+ if unsupported is not None:
45
+ if any((sys.platform.startswith(x) for x in unsupported)):
46
+ notrun('not suitable for this OS: %s' % sys.platform)
47
+
48
+ if supported is not None:
49
+ if not any((sys.platform.startswith(x) for x in supported)):
50
+ notrun('not suitable for this OS: %s' % sys.platform)
51
52
def verify_cache_mode(supported_cache_modes=[]):
53
if supported_cache_modes and (cachemode not in supported_cache_modes):
54
@@ -XXX,XX +XXX,XX @@ def execute_unittest(output, verbosity, debug):
55
sys.stderr.write(out)
56
57
def execute_test(test_function=None,
58
- supported_fmts=[], supported_oses=['linux'],
59
+ supported_fmts=[],
60
+ supported_platforms=None,
61
supported_cache_modes=[], supported_aio_modes={},
62
unsupported_fmts=[], supported_protocols=[],
63
unsupported_protocols=[]):
64
@@ -XXX,XX +XXX,XX @@ def execute_test(test_function=None,
65
verbosity = 1
66
verify_image_format(supported_fmts, unsupported_fmts)
67
verify_protocol(supported_protocols, unsupported_protocols)
68
- verify_platform(supported_oses)
69
+ verify_platform(supported=supported_platforms)
70
verify_cache_mode(supported_cache_modes)
71
verify_aio_mode(supported_aio_modes)
72
73
--
74
2.24.1
75
76
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
041 works fine on Linux, FreeBSD, NetBSD and OpenBSD, but fails on macOS.
4
Let's mark it as only supported on the systems where we know that it is
5
working fine.
6
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Message-id: 20200121095205.26323-3-thuth@redhat.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
tests/qemu-iotests/041 | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/041
18
+++ b/tests/qemu-iotests/041
19
@@ -XXX,XX +XXX,XX @@ class TestOrphanedSource(iotests.QMPTestCase):
20
21
if __name__ == '__main__':
22
iotests.main(supported_fmts=['qcow2', 'qed'],
23
- supported_protocols=['file'])
24
+ supported_protocols=['file'],
25
+ supported_platforms=['linux', 'freebsd', 'netbsd', 'openbsd'])
26
--
27
2.24.1
28
29
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
In the long run, we might want to add test 183 to the "auto" group
4
(but it still fails occasionally, so we cannot do that yet). However,
5
when running 183 in Cirrus-CI on macOS, or with our vm-build-openbsd
6
target, it currently always fails with an "Timeout waiting for return
7
on handle 0" error.
8
9
Let's mark it as supported only on systems where the test is working
10
most of the time (i.e. Linux, FreeBSD and NetBSD).
11
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
Signed-off-by: Thomas Huth <thuth@redhat.com>
14
Message-id: 20200121095205.26323-4-thuth@redhat.com
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
17
tests/qemu-iotests/183 | 1 +
18
1 file changed, 1 insertion(+)
19
20
diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
21
index XXXXXXX..XXXXXXX 100755
22
--- a/tests/qemu-iotests/183
23
+++ b/tests/qemu-iotests/183
24
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
25
. ./common.filter
26
. ./common.qemu
27
28
+_supported_os Linux FreeBSD NetBSD
29
_supported_fmt qcow2 raw qed quorum
30
_supported_proto file
31
32
--
33
2.24.1
34
35
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
We are going to enable 127 in the "auto" group, but it only works if
4
virtio-scsi and scsi-hd are available - which is not the case with
5
QEMU binaries like qemu-system-tricore for example, so we need a
6
proper check for the availability of these devices here.
7
8
A very similar problem exists in iotest 267 - it has been added to
9
the "auto" group already, but requires virtio-blk and thus currently
10
fails with qemu-system-tricore for example. Let's also add aproper
11
check there.
12
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
Signed-off-by: Thomas Huth <thuth@redhat.com>
15
Message-id: 20200121095205.26323-5-thuth@redhat.com
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
17
---
18
tests/qemu-iotests/127 | 2 ++
19
tests/qemu-iotests/267 | 2 ++
20
tests/qemu-iotests/common.rc | 14 ++++++++++++++
21
3 files changed, 18 insertions(+)
22
23
diff --git a/tests/qemu-iotests/127 b/tests/qemu-iotests/127
24
index XXXXXXX..XXXXXXX 100755
25
--- a/tests/qemu-iotests/127
26
+++ b/tests/qemu-iotests/127
27
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
28
_supported_fmt qcow2
29
_supported_proto file
30
31
+_require_devices virtio-scsi scsi-hd
32
+
33
IMG_SIZE=64K
34
35
_make_test_img $IMG_SIZE
36
diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267
37
index XXXXXXX..XXXXXXX 100755
38
--- a/tests/qemu-iotests/267
39
+++ b/tests/qemu-iotests/267
40
@@ -XXX,XX +XXX,XX @@ _require_drivers copy-on-read
41
# and generally impossible with external data files
42
_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
43
44
+_require_devices virtio-blk
45
+
46
do_run_qemu()
47
{
48
echo Testing: "$@"
49
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
50
index XXXXXXX..XXXXXXX 100644
51
--- a/tests/qemu-iotests/common.rc
52
+++ b/tests/qemu-iotests/common.rc
53
@@ -XXX,XX +XXX,XX @@ _require_large_file()
54
rm "$TEST_IMG"
55
}
56
57
+# Check that a set of devices is available in the QEMU binary
58
+#
59
+_require_devices()
60
+{
61
+ available=$($QEMU -M none -device help | \
62
+ grep ^name | sed -e 's/^name "//' -e 's/".*$//')
63
+ for device
64
+ do
65
+ if ! echo "$available" | grep -q "$device" ; then
66
+ _notrun "$device not available"
67
+ fi
68
+ done
69
+}
70
+
71
# make sure this script returns success
72
true
73
--
74
2.24.1
75
76
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
We are going to enable some of the python-based tests in the "auto" group,
4
and these tests require virtio-blk to work properly. Running iotests
5
without virtio-blk likely does not make too much sense anyway, so instead
6
of adding a check for the availability of virtio-blk to each and every
7
test (which does not sound very appealing), let's rather add a check for
8
this a central spot in the "check" script instead (so that it is still
9
possible to run "make check" for qemu-system-tricore for example).
10
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
12
Message-id: 20200121095205.26323-6-thuth@redhat.com
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
tests/qemu-iotests/check | 12 ++++++++++--
16
1 file changed, 10 insertions(+), 2 deletions(-)
17
18
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/check
21
+++ b/tests/qemu-iotests/check
22
@@ -XXX,XX +XXX,XX @@ fi
23
python_usable=false
24
if $PYTHON -c 'import sys; sys.exit(0 if sys.version_info >= (3,6) else 1)'
25
then
26
- python_usable=true
27
+ # Our python framework also requires virtio-blk
28
+ if "$QEMU_PROG" -M none -device help | grep -q virtio-blk >/dev/null 2>&1
29
+ then
30
+ python_usable=true
31
+ else
32
+ python_unusable_because="Missing virtio-blk in QEMU binary"
33
+ fi
34
+else
35
+ python_unusable_because="Unsupported Python version"
36
fi
37
38
default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
39
@@ -XXX,XX +XXX,XX @@ do
40
run_command="$PYTHON $seq"
41
else
42
run_command="false"
43
- echo "Unsupported Python version" > $seq.notrun
44
+ echo "$python_unusable_because" > $seq.notrun
45
fi
46
else
47
run_command="./$seq"
48
--
49
2.24.1
50
51
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
According to Kevin, tests 030, 040 and 041 are among the most valuable
4
tests that we have, so we should always run them if possible, even if
5
they take a little bit longer.
6
7
According to Max, it would be good to have a test for iothreads and
8
migration. 127 and 256 seem to be good candidates for iothreads. For
9
migration, let's enable 181 and 203 (which also tests iothreads).
10
(091 would be a good candidate for migration, too, but Alex Bennée
11
reported that this test fails on ZFS file systems, so it can't be
12
included yet)
13
14
Reviewed-by: Max Reitz <mreitz@redhat.com>
15
Signed-off-by: Thomas Huth <thuth@redhat.com>
16
Message-id: 20200121095205.26323-7-thuth@redhat.com
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
---
19
tests/qemu-iotests/group | 14 +++++++-------
20
1 file changed, 7 insertions(+), 7 deletions(-)
21
22
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
23
index XXXXXXX..XXXXXXX 100644
24
--- a/tests/qemu-iotests/group
25
+++ b/tests/qemu-iotests/group
26
@@ -XXX,XX +XXX,XX @@
27
027 rw auto quick
28
028 rw backing quick
29
029 rw auto quick
30
-030 rw backing
31
+030 rw auto backing
32
031 rw auto quick
33
032 rw auto quick
34
033 rw auto quick
35
@@ -XXX,XX +XXX,XX @@
36
037 rw auto backing quick
37
038 rw auto backing quick
38
039 rw auto quick
39
-040 rw
40
-041 rw backing
41
+040 rw auto
42
+041 rw auto backing
43
042 rw auto quick
44
043 rw auto backing
45
044 rw
46
@@ -XXX,XX +XXX,XX @@
47
124 rw backing
48
125 rw
49
126 rw auto backing
50
-127 rw backing quick
51
+127 rw auto backing quick
52
128 rw quick
53
129 rw quick
54
130 rw quick
55
@@ -XXX,XX +XXX,XX @@
56
177 rw auto quick
57
178 img
58
179 rw auto quick
59
-181 rw migration
60
+181 rw auto migration
61
182 rw quick
62
183 rw migration
63
184 rw auto quick
64
@@ -XXX,XX +XXX,XX @@
65
200 rw
66
201 rw migration
67
202 rw quick
68
-203 rw migration
69
+203 rw auto migration
70
204 rw quick
71
205 rw quick
72
206 rw
73
@@ -XXX,XX +XXX,XX @@
74
253 rw quick
75
254 rw backing quick
76
255 rw quick
77
-256 rw quick
78
+256 rw auto quick
79
257 rw
80
258 rw quick
81
260 rw quick
82
--
83
2.24.1
84
85
diff view generated by jsdifflib
New patch
1
From: Alberto Garcia <berto@igalia.com>
1
2
3
The L1 table is read from disk using the byte-based bdrv_pread() and
4
is never accessed beyond its last element, so there's no need to
5
allocate more memory than that.
6
7
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-id: b2e27214ec7b03a585931bcf383ee1ac3a641a10.1579374329.git.berto@igalia.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
block/qcow2-cluster.c | 5 ++---
13
block/qcow2-refcount.c | 2 +-
14
block/qcow2-snapshot.c | 3 +--
15
block/qcow2.c | 2 +-
16
4 files changed, 5 insertions(+), 7 deletions(-)
17
18
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2-cluster.c
21
+++ b/block/qcow2-cluster.c
22
@@ -XXX,XX +XXX,XX @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
23
#endif
24
25
new_l1_size2 = sizeof(uint64_t) * new_l1_size;
26
- new_l1_table = qemu_try_blockalign(bs->file->bs,
27
- ROUND_UP(new_l1_size2, 512));
28
+ new_l1_table = qemu_try_blockalign(bs->file->bs, new_l1_size2);
29
if (new_l1_table == NULL) {
30
return -ENOMEM;
31
}
32
- memset(new_l1_table, 0, ROUND_UP(new_l1_size2, 512));
33
+ memset(new_l1_table, 0, new_l1_size2);
34
35
if (s->l1_size) {
36
memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
37
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/block/qcow2-refcount.c
40
+++ b/block/qcow2-refcount.c
41
@@ -XXX,XX +XXX,XX @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
42
* l1_table_offset when it is the current s->l1_table_offset! Be careful
43
* when changing this! */
44
if (l1_table_offset != s->l1_table_offset) {
45
- l1_table = g_try_malloc0(ROUND_UP(l1_size2, 512));
46
+ l1_table = g_try_malloc0(l1_size2);
47
if (l1_size2 && l1_table == NULL) {
48
ret = -ENOMEM;
49
goto fail;
50
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/qcow2-snapshot.c
53
+++ b/block/qcow2-snapshot.c
54
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs,
55
return ret;
56
}
57
new_l1_bytes = sn->l1_size * sizeof(uint64_t);
58
- new_l1_table = qemu_try_blockalign(bs->file->bs,
59
- ROUND_UP(new_l1_bytes, 512));
60
+ new_l1_table = qemu_try_blockalign(bs->file->bs, new_l1_bytes);
61
if (new_l1_table == NULL) {
62
return -ENOMEM;
63
}
64
diff --git a/block/qcow2.c b/block/qcow2.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/block/qcow2.c
67
+++ b/block/qcow2.c
68
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
69
70
if (s->l1_size > 0) {
71
s->l1_table = qemu_try_blockalign(bs->file->bs,
72
- ROUND_UP(s->l1_size * sizeof(uint64_t), 512));
73
+ s->l1_size * sizeof(uint64_t));
74
if (s->l1_table == NULL) {
75
error_setg(errp, "Could not allocate L1 table");
76
ret = -ENOMEM;
77
--
78
2.24.1
79
80
diff view generated by jsdifflib
New patch
1
From: Alberto Garcia <berto@igalia.com>
1
2
3
qcow2_alloc_cluster_offset() and qcow2_get_cluster_offset() always
4
return offsets that are cluster-aligned so don't just check that they
5
are sector-aligned.
6
7
The check in qcow2_co_preadv_task() is also replaced by an assertion
8
for the same reason.
9
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Message-id: 558ba339965f858bede4c73ce3f50f0c0493597d.1579374329.git.berto@igalia.com
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
block/qcow2.c | 9 +++------
16
1 file changed, 3 insertions(+), 6 deletions(-)
17
18
diff --git a/block/qcow2.c b/block/qcow2.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2.c
21
+++ b/block/qcow2.c
22
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
23
offset, bytes, qiov, qiov_offset);
24
25
case QCOW2_CLUSTER_NORMAL:
26
- if ((file_cluster_offset & 511) != 0) {
27
- return -EIO;
28
- }
29
-
30
+ assert(offset_into_cluster(s, file_cluster_offset) == 0);
31
if (bs->encrypted) {
32
return qcow2_co_preadv_encrypted(bs, file_cluster_offset,
33
offset, bytes, qiov, qiov_offset);
34
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part(
35
goto out_locked;
36
}
37
38
- assert((cluster_offset & 511) == 0);
39
+ assert(offset_into_cluster(s, cluster_offset) == 0);
40
41
ret = qcow2_pre_write_overlap_check(bs, 0,
42
cluster_offset + offset_in_cluster,
43
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_to(BlockDriverState *bs,
44
goto fail;
45
}
46
47
- assert((cluster_offset & 511) == 0);
48
+ assert(offset_into_cluster(s, cluster_offset) == 0);
49
50
ret = qcow2_pre_write_overlap_check(bs, 0,
51
cluster_offset + offset_in_cluster, cur_bytes, true);
52
--
53
2.24.1
54
55
diff view generated by jsdifflib
New patch
1
From: Alberto Garcia <berto@igalia.com>
1
2
3
When updating an L1 entry the qcow2 driver writes a (512-byte) sector
4
worth of data to avoid a read-modify-write cycle. Instead of always
5
writing 512 bytes we should follow the alignment requirements of the
6
storage backend.
7
8
(the only exception is when the alignment is larger than the cluster
9
size because then we could be overwriting data after the L1 table)
10
11
Signed-off-by: Alberto Garcia <berto@igalia.com>
12
Message-id: 71f34d4ae4b367b32fb36134acbf4f4f7ee681f4.1579374329.git.berto@igalia.com
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
block/qcow2-cluster.c | 25 +++++++++++++++----------
17
1 file changed, 15 insertions(+), 10 deletions(-)
18
19
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/qcow2-cluster.c
22
+++ b/block/qcow2-cluster.c
23
@@ -XXX,XX +XXX,XX @@ static int l2_load(BlockDriverState *bs, uint64_t offset,
24
}
25
26
/*
27
- * Writes one sector of the L1 table to the disk (can't update single entries
28
- * and we really don't want bdrv_pread to perform a read-modify-write)
29
+ * Writes an L1 entry to disk (note that depending on the alignment
30
+ * requirements this function may write more that just one entry in
31
+ * order to prevent bdrv_pwrite from performing a read-modify-write)
32
*/
33
-#define L1_ENTRIES_PER_SECTOR (512 / 8)
34
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
35
{
36
BDRVQcow2State *s = bs->opaque;
37
- uint64_t buf[L1_ENTRIES_PER_SECTOR] = { 0 };
38
int l1_start_index;
39
int i, ret;
40
+ int bufsize = MAX(sizeof(uint64_t),
41
+ MIN(bs->file->bs->bl.request_alignment, s->cluster_size));
42
+ int nentries = bufsize / sizeof(uint64_t);
43
+ g_autofree uint64_t *buf = g_try_new0(uint64_t, nentries);
44
45
- l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
46
- for (i = 0; i < L1_ENTRIES_PER_SECTOR && l1_start_index + i < s->l1_size;
47
- i++)
48
- {
49
+ if (buf == NULL) {
50
+ return -ENOMEM;
51
+ }
52
+
53
+ l1_start_index = QEMU_ALIGN_DOWN(l1_index, nentries);
54
+ for (i = 0; i < MIN(nentries, s->l1_size - l1_start_index); i++) {
55
buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
56
}
57
58
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1,
59
- s->l1_table_offset + 8 * l1_start_index, sizeof(buf), false);
60
+ s->l1_table_offset + 8 * l1_start_index, bufsize, false);
61
if (ret < 0) {
62
return ret;
63
}
64
@@ -XXX,XX +XXX,XX @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
65
BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
66
ret = bdrv_pwrite_sync(bs->file,
67
s->l1_table_offset + 8 * l1_start_index,
68
- buf, sizeof(buf));
69
+ buf, bufsize);
70
if (ret < 0) {
71
return ret;
72
}
73
--
74
2.24.1
75
76
diff view generated by jsdifflib
New patch
1
From: Alberto Garcia <berto@igalia.com>
1
2
3
qemu-img's convert_co_copy_range() operates at the sector level and
4
block_copy() operates at the cluster level so this condition is always
5
true, but it is not necessary to restrict this here, so let's leave it
6
to the driver implementation return an error if there is any.
7
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
9
Message-id: a4264aaee656910c84161a2965f7a501437379ca.1579374329.git.berto@igalia.com
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
block/qcow2.c | 4 ----
14
1 file changed, 4 deletions(-)
15
16
diff --git a/block/qcow2.c b/block/qcow2.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2.c
19
+++ b/block/qcow2.c
20
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_from(BlockDriverState *bs,
21
case QCOW2_CLUSTER_NORMAL:
22
child = s->data_file;
23
copy_offset += offset_into_cluster(s, src_offset);
24
- if ((copy_offset & 511) != 0) {
25
- ret = -EIO;
26
- goto out;
27
- }
28
break;
29
30
default:
31
--
32
2.24.1
33
34
diff view generated by jsdifflib
New patch
1
From: Alberto Garcia <berto@igalia.com>
1
2
3
This replaces all remaining instances in the qcow2 code.
4
5
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Message-id: b5f74b606c2d9873b12d29acdb7fd498029c4025.1579374329.git.berto@igalia.com
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/qcow2.c | 8 +++++---
11
1 file changed, 5 insertions(+), 3 deletions(-)
12
13
diff --git a/block/qcow2.c b/block/qcow2.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/qcow2.c
16
+++ b/block/qcow2.c
17
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
18
19
/* Validate options and set default values */
20
if (!QEMU_IS_ALIGNED(qcow2_opts->size, BDRV_SECTOR_SIZE)) {
21
- error_setg(errp, "Image size must be a multiple of 512 bytes");
22
+ error_setg(errp, "Image size must be a multiple of %u bytes",
23
+ (unsigned) BDRV_SECTOR_SIZE);
24
ret = -EINVAL;
25
goto out;
26
}
27
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
28
return -ENOTSUP;
29
}
30
31
- if (offset & 511) {
32
- error_setg(errp, "The new size must be a multiple of 512");
33
+ if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
34
+ error_setg(errp, "The new size must be a multiple of %u",
35
+ (unsigned) BDRV_SECTOR_SIZE);
36
return -EINVAL;
37
}
38
39
--
40
2.24.1
41
42
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
We can't access top after call bdrv_backup_top_drop, as it is already
4
freed at this time.
5
6
Also, no needs to unref target child by hand, it will be unrefed on
7
bdrv_close() automatically.
8
9
So, just do bdrv_backup_top_drop if append succeed and one bdrv_unref
10
otherwise.
11
12
Note, that in !appended case bdrv_unref(top) moved into drained section
13
on source. It doesn't really matter, but just for code simplicity.
14
15
Fixes: 7df7868b96404
16
Cc: qemu-stable@nongnu.org # v4.2.0
17
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Reviewed-by: Max Reitz <mreitz@redhat.com>
19
Message-id: 20200121142802.21467-2-vsementsov@virtuozzo.com
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
---
22
block/backup-top.c | 21 ++++++++++++---------
23
1 file changed, 12 insertions(+), 9 deletions(-)
24
25
diff --git a/block/backup-top.c b/block/backup-top.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/block/backup-top.c
28
+++ b/block/backup-top.c
29
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
30
BlockDriverState *top = bdrv_new_open_driver(&bdrv_backup_top_filter,
31
filter_node_name,
32
BDRV_O_RDWR, errp);
33
+ bool appended = false;
34
35
if (!top) {
36
return NULL;
37
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
38
bdrv_append(top, source, &local_err);
39
if (local_err) {
40
error_prepend(&local_err, "Cannot append backup-top filter: ");
41
- goto append_failed;
42
+ goto fail;
43
}
44
+ appended = true;
45
46
/*
47
* bdrv_append() finished successfully, now we can require permissions
48
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
49
if (local_err) {
50
error_prepend(&local_err,
51
"Cannot set permissions for backup-top filter: ");
52
- goto failed_after_append;
53
+ goto fail;
54
}
55
56
state->bcs = block_copy_state_new(top->backing, state->target,
57
cluster_size, write_flags, &local_err);
58
if (local_err) {
59
error_prepend(&local_err, "Cannot create block-copy-state: ");
60
- goto failed_after_append;
61
+ goto fail;
62
}
63
*bcs = state->bcs;
64
65
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
66
67
return top;
68
69
-failed_after_append:
70
- state->active = false;
71
- bdrv_backup_top_drop(top);
72
+fail:
73
+ if (appended) {
74
+ state->active = false;
75
+ bdrv_backup_top_drop(top);
76
+ } else {
77
+ bdrv_unref(top);
78
+ }
79
80
-append_failed:
81
bdrv_drained_end(source);
82
- bdrv_unref_child(top, state->target);
83
- bdrv_unref(top);
84
error_propagate(errp, local_err);
85
86
return NULL;
87
--
88
2.24.1
89
90
diff view generated by jsdifflib
1
Nested BDRV_POLL_WHILE() calls can occur. Currently
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
assert(!wait_->wakeup) fails in AIO_WAIT_WHILE() when this happens.
3
2
4
This patch converts the bool wait_->need_kick flag to an unsigned
3
This test checks that bug is really fixed by previous commit.
5
wait_->num_waiters counter.
6
4
7
Nesting works correctly because outer AIO_WAIT_WHILE() callers evaluate
5
Cc: qemu-stable@nongnu.org # v4.2.0
8
the condition again after the inner caller completes (invoking the inner
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
caller counts as aio_poll() progress).
7
Message-id: 20200121142802.21467-3-vsementsov@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
tests/qemu-iotests/283 | 92 ++++++++++++++++++++++++++++++++++++++
11
tests/qemu-iotests/283.out | 8 ++++
12
tests/qemu-iotests/group | 1 +
13
3 files changed, 101 insertions(+)
14
create mode 100644 tests/qemu-iotests/283
15
create mode 100644 tests/qemu-iotests/283.out
10
16
11
Reported-by: "fuweiwei (C)" <fuweiwei2@huawei.com>
17
diff --git a/tests/qemu-iotests/283 b/tests/qemu-iotests/283
12
Reviewed-by: Eric Blake <eblake@redhat.com>
18
new file mode 100644
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
index XXXXXXX..XXXXXXX
14
Message-id: 20180307124619.6218-1-stefanha@redhat.com
20
--- /dev/null
15
Cc: Paolo Bonzini <pbonzini@redhat.com>
21
+++ b/tests/qemu-iotests/283
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
22
@@ -XXX,XX +XXX,XX @@
17
---
23
+#!/usr/bin/env python
18
include/block/aio-wait.h | 61 ++++++++++++++++++++++++------------------------
24
+#
19
util/aio-wait.c | 2 +-
25
+# Test for backup-top filter permission activation failure
20
2 files changed, 31 insertions(+), 32 deletions(-)
26
+#
21
27
+# Copyright (c) 2019 Virtuozzo International GmbH.
22
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
28
+#
29
+# This program is free software; you can redistribute it and/or modify
30
+# it under the terms of the GNU General Public License as published by
31
+# the Free Software Foundation; either version 2 of the License, or
32
+# (at your option) any later version.
33
+#
34
+# This program is distributed in the hope that it will be useful,
35
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
36
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37
+# GNU General Public License for more details.
38
+#
39
+# You should have received a copy of the GNU General Public License
40
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
41
+#
42
+
43
+import iotests
44
+
45
+# The test is unrelated to formats, restrict it to qcow2 to avoid extra runs
46
+iotests.verify_image_format(supported_fmts=['qcow2'])
47
+
48
+size = 1024 * 1024
49
+
50
+""" Test description
51
+
52
+When performing a backup, all writes on the source subtree must go through the
53
+backup-top filter so it can copy all data to the target before it is changed.
54
+backup-top filter is appended above source node, to achieve this thing, so all
55
+parents of source node are handled. A configuration with side parents of source
56
+sub-tree with write permission is unsupported (we'd have append several
57
+backup-top filter like nodes to handle such parents). The test create an
58
+example of such configuration and checks that a backup is then not allowed
59
+(blockdev-backup command should fail).
60
+
61
+The configuration:
62
+
63
+ ┌────────┐ target ┌─────────────┐
64
+ │ target │ ◀─────── │ backup_top │
65
+ └────────┘ └─────────────┘
66
+ │
67
+ │ backing
68
+ ▼
69
+ ┌─────────────┐
70
+ │ source │
71
+ └─────────────┘
72
+ │
73
+ │ file
74
+ ▼
75
+ ┌─────────────┐ write perm ┌───────┐
76
+ │ base │ ◀──────────── │ other │
77
+ └─────────────┘ └───────┘
78
+
79
+On activation (see .active field of backup-top state in block/backup-top.c),
80
+backup-top is going to unshare write permission on its source child. Write
81
+unsharing will be propagated to the "source->base" link and will conflict with
82
+other node write permission. So permission update will fail and backup job will
83
+not be started.
84
+
85
+Note, that the only thing which prevents backup of running on such
86
+configuration is default permission propagation scheme. It may be altered by
87
+different block drivers, so backup will run in invalid configuration. But
88
+something is better than nothing. Also, before the previous commit (commit
89
+preceding this test creation), starting backup on such configuration led to
90
+crash, so current "something" is a lot better, and this test actual goal is
91
+to check that crash is fixed :)
92
+"""
93
+
94
+vm = iotests.VM()
95
+vm.launch()
96
+
97
+vm.qmp_log('blockdev-add', **{'node-name': 'target', 'driver': 'null-co'})
98
+
99
+vm.qmp_log('blockdev-add', **{
100
+ 'node-name': 'source',
101
+ 'driver': 'blkdebug',
102
+ 'image': {'node-name': 'base', 'driver': 'null-co', 'size': size}
103
+})
104
+
105
+vm.qmp_log('blockdev-add', **{
106
+ 'node-name': 'other',
107
+ 'driver': 'blkdebug',
108
+ 'image': 'base',
109
+ 'take-child-perms': ['write']
110
+})
111
+
112
+vm.qmp_log('blockdev-backup', sync='full', device='source', target='target')
113
+
114
+vm.shutdown()
115
diff --git a/tests/qemu-iotests/283.out b/tests/qemu-iotests/283.out
116
new file mode 100644
117
index XXXXXXX..XXXXXXX
118
--- /dev/null
119
+++ b/tests/qemu-iotests/283.out
120
@@ -XXX,XX +XXX,XX @@
121
+{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "target"}}
122
+{"return": {}}
123
+{"execute": "blockdev-add", "arguments": {"driver": "blkdebug", "image": {"driver": "null-co", "node-name": "base", "size": 1048576}, "node-name": "source"}}
124
+{"return": {}}
125
+{"execute": "blockdev-add", "arguments": {"driver": "blkdebug", "image": "base", "node-name": "other", "take-child-perms": ["write"]}}
126
+{"return": {}}
127
+{"execute": "blockdev-backup", "arguments": {"device": "source", "sync": "full", "target": "target"}}
128
+{"error": {"class": "GenericError", "desc": "Cannot set permissions for backup-top filter: Conflicts with use by other as 'image', which uses 'write' on base"}}
129
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
23
index XXXXXXX..XXXXXXX 100644
130
index XXXXXXX..XXXXXXX 100644
24
--- a/include/block/aio-wait.h
131
--- a/tests/qemu-iotests/group
25
+++ b/include/block/aio-wait.h
132
+++ b/tests/qemu-iotests/group
26
@@ -XXX,XX +XXX,XX @@
133
@@ -XXX,XX +XXX,XX @@
27
* }
134
279 rw backing quick
28
*/
135
280 rw migration quick
29
typedef struct {
136
281 rw quick
30
- /* Is the main loop waiting for a kick? Accessed with atomic ops. */
137
+283 auto quick
31
- bool need_kick;
32
+ /* Number of waiting AIO_WAIT_WHILE() callers. Accessed with atomic ops. */
33
+ unsigned num_waiters;
34
} AioWait;
35
36
/**
37
@@ -XXX,XX +XXX,XX @@ typedef struct {
38
* wait on conditions between two IOThreads since that could lead to deadlock,
39
* go via the main loop instead.
40
*/
41
-#define AIO_WAIT_WHILE(wait, ctx, cond) ({ \
42
- bool waited_ = false; \
43
- bool busy_ = true; \
44
- AioWait *wait_ = (wait); \
45
- AioContext *ctx_ = (ctx); \
46
- if (in_aio_context_home_thread(ctx_)) { \
47
- while ((cond) || busy_) { \
48
- busy_ = aio_poll(ctx_, (cond)); \
49
- waited_ |= !!(cond) | busy_; \
50
- } \
51
- } else { \
52
- assert(qemu_get_current_aio_context() == \
53
- qemu_get_aio_context()); \
54
- assert(!wait_->need_kick); \
55
- /* Set wait_->need_kick before evaluating cond. */ \
56
- atomic_mb_set(&wait_->need_kick, true); \
57
- while (busy_) { \
58
- if ((cond)) { \
59
- waited_ = busy_ = true; \
60
- aio_context_release(ctx_); \
61
- aio_poll(qemu_get_aio_context(), true); \
62
- aio_context_acquire(ctx_); \
63
- } else { \
64
- busy_ = aio_poll(ctx_, false); \
65
- waited_ |= busy_; \
66
- } \
67
- } \
68
- atomic_set(&wait_->need_kick, false); \
69
- } \
70
+#define AIO_WAIT_WHILE(wait, ctx, cond) ({ \
71
+ bool waited_ = false; \
72
+ bool busy_ = true; \
73
+ AioWait *wait_ = (wait); \
74
+ AioContext *ctx_ = (ctx); \
75
+ if (in_aio_context_home_thread(ctx_)) { \
76
+ while ((cond) || busy_) { \
77
+ busy_ = aio_poll(ctx_, (cond)); \
78
+ waited_ |= !!(cond) | busy_; \
79
+ } \
80
+ } else { \
81
+ assert(qemu_get_current_aio_context() == \
82
+ qemu_get_aio_context()); \
83
+ /* Increment wait_->num_waiters before evaluating cond. */ \
84
+ atomic_inc(&wait_->num_waiters); \
85
+ while (busy_) { \
86
+ if ((cond)) { \
87
+ waited_ = busy_ = true; \
88
+ aio_context_release(ctx_); \
89
+ aio_poll(qemu_get_aio_context(), true); \
90
+ aio_context_acquire(ctx_); \
91
+ } else { \
92
+ busy_ = aio_poll(ctx_, false); \
93
+ waited_ |= busy_; \
94
+ } \
95
+ } \
96
+ atomic_dec(&wait_->num_waiters); \
97
+ } \
98
waited_; })
99
100
/**
101
diff --git a/util/aio-wait.c b/util/aio-wait.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/util/aio-wait.c
104
+++ b/util/aio-wait.c
105
@@ -XXX,XX +XXX,XX @@ static void dummy_bh_cb(void *opaque)
106
void aio_wait_kick(AioWait *wait)
107
{
108
/* The barrier (or an atomic op) is in the caller. */
109
- if (atomic_read(&wait->need_kick)) {
110
+ if (atomic_read(&wait->num_waiters)) {
111
aio_bh_schedule_oneshot(qemu_get_aio_context(), dummy_bh_cb, NULL);
112
}
113
}
114
--
138
--
115
2.14.3
139
2.24.1
116
140
117
141
diff view generated by jsdifflib