1
The following changes since commit 19eb2d4e736dc895f31fbd6b520e514f10cc08e0:
1
The following changes since commit 63011373ad22c794a013da69663c03f1297a5c56:
2
2
3
Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging (2019-05-07 10:43:32 +0100)
3
Merge tag 'pull-riscv-to-apply-20231012-1' of https://github.com/alistair23/qemu into staging (2023-10-12 10:24:44 -0400)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://git.xanclic.moe/XanClic/qemu.git tags/pull-block-2019-05-07
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to 1278dce7927301bf3d004a40061dbd2c1e0846a8:
9
for you to fetch changes up to 071d6d107db2e26dde9bb15457c74956c88ec5b4:
10
10
11
iotests: Fix iotests 110 and 126 (2019-05-07 17:14:21 +0200)
11
virtio-blk: don't start dataplane during the stop of dataplane (2023-10-16 15:39:13 -0400)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Pull request
15
- Fixes to qcow2's implementation of qemu-img check
15
16
- Our SSH driver now supports bdrv_refresh_filename()
16
Contains a virtio-blk IOThread fix.
17
- Miscellaneous fixes
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
Alberto Garcia (2):
21
block: Assert that drv->bdrv_child_perm is set in bdrv_child_perm()
22
commit: Use bdrv_append() in commit_start()
23
19
24
Andrey Shinkevich (1):
20
hujian (1):
25
qcow2: discard bitmap when removed
21
virtio-blk: don't start dataplane during the stop of dataplane
26
22
27
Max Reitz (3):
23
hw/block/virtio-blk.c | 2 +-
28
block/ssh: Implement .bdrv_refresh_filename()
24
1 file changed, 1 insertion(+), 1 deletion(-)
29
block/ssh: Implement .bdrv_dirname()
30
iotests: Fix iotests 110 and 126
31
32
Vladimir Sementsov-Ogievskiy (5):
33
qcow2-refcount: fix check_oflag_copied
34
qcow2-refcount: avoid eating RAM
35
qcow2-refcount: check_refcounts_l2: reduce ignored overlaps
36
qcow2-refcount: check_refcounts_l2: don't count fixed cluster as
37
allocated
38
qcow2-refcount: don't mask corruptions under internal errors
39
40
block.c | 9 ++--
41
block/commit.c | 11 +----
42
block/qcow2-bitmap.c | 2 +-
43
block/qcow2-refcount.c | 80 ++++++++++++++++++++++-------------
44
block/ssh.c | 73 +++++++++++++++++++++++++++++---
45
tests/qemu-iotests/110 | 10 +++--
46
tests/qemu-iotests/126 | 10 +++--
47
tests/qemu-iotests/138 | 12 +++---
48
tests/qemu-iotests/138.out | 5 ++-
49
tests/qemu-iotests/207 | 10 ++---
50
tests/qemu-iotests/207.out | 10 ++---
51
tests/qemu-iotests/common.rc | 2 +-
52
tests/qemu-iotests/iotests.py | 2 +-
53
13 files changed, 159 insertions(+), 77 deletions(-)
54
25
55
--
26
--
56
2.20.1
27
2.41.0
57
58
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Increase corruptions_fixed only after successful fix.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20190227131433.197063-2-vsementsov@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/qcow2-refcount.c | 8 ++++----
11
1 file changed, 4 insertions(+), 4 deletions(-)
12
13
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/qcow2-refcount.c
16
+++ b/block/qcow2-refcount.c
17
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
18
for (i = 0; i < s->l1_size; i++) {
19
uint64_t l1_entry = s->l1_table[i];
20
uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;
21
- bool l2_dirty = false;
22
+ int l2_dirty = 0;
23
24
if (!l2_offset) {
25
continue;
26
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
27
l2_table[j] = cpu_to_be64(refcount == 1
28
? l2_entry | QCOW_OFLAG_COPIED
29
: l2_entry & ~QCOW_OFLAG_COPIED);
30
- l2_dirty = true;
31
- res->corruptions_fixed++;
32
+ l2_dirty++;
33
} else {
34
res->corruptions++;
35
}
36
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
37
}
38
}
39
40
- if (l2_dirty) {
41
+ if (l2_dirty > 0) {
42
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,
43
l2_offset, s->cluster_size,
44
false);
45
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
46
res->check_errors++;
47
goto fail;
48
}
49
+ res->corruptions_fixed += l2_dirty;
50
}
51
}
52
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
qcow2_inc_refcounts_imrt() (through realloc_refcount_array()) can eat
4
an unpredictable amount of memory on corrupted table entries, which are
5
referencing regions far beyond the end of file.
6
7
Prevent this, by skipping such regions from further processing.
8
9
Interesting that iotest 138 checks exactly the behavior which we fix
10
here. So, change the test appropriately.
11
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
Message-id: 20190227131433.197063-3-vsementsov@virtuozzo.com
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
17
block/qcow2-refcount.c | 19 +++++++++++++++++++
18
tests/qemu-iotests/138 | 12 +++++-------
19
tests/qemu-iotests/138.out | 5 ++++-
20
3 files changed, 28 insertions(+), 8 deletions(-)
21
22
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/qcow2-refcount.c
25
+++ b/block/qcow2-refcount.c
26
@@ -XXX,XX +XXX,XX @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
27
{
28
BDRVQcow2State *s = bs->opaque;
29
uint64_t start, last, cluster_offset, k, refcount;
30
+ int64_t file_len;
31
int ret;
32
33
if (size <= 0) {
34
return 0;
35
}
36
37
+ file_len = bdrv_getlength(bs->file->bs);
38
+ if (file_len < 0) {
39
+ return file_len;
40
+ }
41
+
42
+ /*
43
+ * Last cluster of qcow2 image may be semi-allocated, so it may be OK to
44
+ * reference some space after file end but it should be less than one
45
+ * cluster.
46
+ */
47
+ if (offset + size - file_len >= s->cluster_size) {
48
+ fprintf(stderr, "ERROR: counting reference for region exceeding the "
49
+ "end of the file by one cluster or more: offset 0x%" PRIx64
50
+ " size 0x%" PRIx64 "\n", offset, size);
51
+ res->corruptions++;
52
+ return 0;
53
+ }
54
+
55
start = start_of_cluster(s, offset);
56
last = start_of_cluster(s, offset + size - 1);
57
for(cluster_offset = start; cluster_offset <= last;
58
diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138
59
index XXXXXXX..XXXXXXX 100755
60
--- a/tests/qemu-iotests/138
61
+++ b/tests/qemu-iotests/138
62
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
63
# Put the data cluster at a multiple of 2 TB, resulting in the image apparently
64
# having a multiple of 2^32 clusters
65
# (To be more specific: It is at 32 PB)
66
-poke_file "$TEST_IMG" 2048 "\x80\x80\x00\x00\x00\x00\x00\x00"
67
+poke_file "$TEST_IMG" $((2048 + 8)) "\x00\x80\x00\x00\x00\x00\x00\x00"
68
69
# An offset of 32 PB results in qemu-img check having to allocate an in-memory
70
-# refcount table of 128 TB (16 bit refcounts, 512 byte clusters).
71
-# This should be generally too much for any system and thus fail.
72
-# What this test is checking is that the qcow2 driver actually tries to allocate
73
-# such a large amount of memory (and is consequently aborting) instead of having
74
-# truncated the cluster count somewhere (which would result in much less memory
75
-# being allocated and then a segfault occurring).
76
+# refcount table of 128 TB (16 bit refcounts, 512 byte clusters), if qemu-img
77
+# don't check that referenced data cluster is far beyond the end of file.
78
+# But starting from 4.0, qemu-img does this check, and instead of "Cannot
79
+# allocate memory", we have an error showing that l2 entry is invalid.
80
_check_test_img
81
82
# success, all done
83
diff --git a/tests/qemu-iotests/138.out b/tests/qemu-iotests/138.out
84
index XXXXXXX..XXXXXXX 100644
85
--- a/tests/qemu-iotests/138.out
86
+++ b/tests/qemu-iotests/138.out
87
@@ -XXX,XX +XXX,XX @@ QA output created by 138
88
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=512
89
wrote 512/512 bytes at offset 0
90
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
91
-qemu-img: Check failed: Cannot allocate memory
92
+ERROR: counting reference for region exceeding the end of the file by one cluster or more: offset 0x80000000000000 size 0x200
93
+
94
+1 errors were found on the image.
95
+Data may be corrupted, or further writes to the image may corrupt it.
96
*** done
97
--
98
2.20.1
99
100
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Reduce number of structures ignored in overlap check: when checking
4
active table ignore active tables, when checking inactive table ignore
5
inactive ones.
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-id: 20190227131433.197063-4-vsementsov@virtuozzo.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
block/qcow2-refcount.c | 16 +++++++++-------
13
1 file changed, 9 insertions(+), 7 deletions(-)
14
15
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2-refcount.c
18
+++ b/block/qcow2-refcount.c
19
@@ -XXX,XX +XXX,XX @@ enum {
20
static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
21
void **refcount_table,
22
int64_t *refcount_table_size, int64_t l2_offset,
23
- int flags, BdrvCheckMode fix)
24
+ int flags, BdrvCheckMode fix, bool active)
25
{
26
BDRVQcow2State *s = bs->opaque;
27
uint64_t *l2_table, l2_entry;
28
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
29
if (fix & BDRV_FIX_ERRORS) {
30
uint64_t l2e_offset =
31
l2_offset + (uint64_t)i * sizeof(uint64_t);
32
+ int ign = active ? QCOW2_OL_ACTIVE_L2 :
33
+ QCOW2_OL_INACTIVE_L2;
34
35
l2_entry = QCOW_OFLAG_ZERO;
36
l2_table[i] = cpu_to_be64(l2_entry);
37
- ret = qcow2_pre_write_overlap_check(bs,
38
- QCOW2_OL_ACTIVE_L2 | QCOW2_OL_INACTIVE_L2,
39
+ ret = qcow2_pre_write_overlap_check(bs, ign,
40
l2e_offset, sizeof(uint64_t), false);
41
if (ret < 0) {
42
fprintf(stderr, "ERROR: Overlap check failed\n");
43
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs,
44
void **refcount_table,
45
int64_t *refcount_table_size,
46
int64_t l1_table_offset, int l1_size,
47
- int flags, BdrvCheckMode fix)
48
+ int flags, BdrvCheckMode fix, bool active)
49
{
50
BDRVQcow2State *s = bs->opaque;
51
uint64_t *l1_table = NULL, l2_offset, l1_size2;
52
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs,
53
/* Process and check L2 entries */
54
ret = check_refcounts_l2(bs, res, refcount_table,
55
refcount_table_size, l2_offset, flags,
56
- fix);
57
+ fix, active);
58
if (ret < 0) {
59
goto fail;
60
}
61
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
62
/* current L1 table */
63
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
64
s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO,
65
- fix);
66
+ fix, true);
67
if (ret < 0) {
68
return ret;
69
}
70
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
71
continue;
72
}
73
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
74
- sn->l1_table_offset, sn->l1_size, 0, fix);
75
+ sn->l1_table_offset, sn->l1_size, 0, fix,
76
+ false);
77
if (ret < 0) {
78
return ret;
79
}
80
--
81
2.20.1
82
83
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Do not count a cluster which is fixed to be ZERO as allocated.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20190227131433.197063-5-vsementsov@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/qcow2-refcount.c | 18 +++++++++---------
11
1 file changed, 9 insertions(+), 9 deletions(-)
12
13
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/qcow2-refcount.c
16
+++ b/block/qcow2-refcount.c
17
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
18
{
19
uint64_t offset = l2_entry & L2E_OFFSET_MASK;
20
21
- if (flags & CHECK_FRAG_INFO) {
22
- res->bfi.allocated_clusters++;
23
- if (next_contiguous_offset &&
24
- offset != next_contiguous_offset) {
25
- res->bfi.fragmented_clusters++;
26
- }
27
- next_contiguous_offset = offset + s->cluster_size;
28
- }
29
-
30
/* Correct offsets are cluster aligned */
31
if (offset_into_cluster(s, offset)) {
32
if (qcow2_get_cluster_type(bs, l2_entry) ==
33
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
34
}
35
}
36
37
+ if (flags & CHECK_FRAG_INFO) {
38
+ res->bfi.allocated_clusters++;
39
+ if (next_contiguous_offset &&
40
+ offset != next_contiguous_offset) {
41
+ res->bfi.fragmented_clusters++;
42
+ }
43
+ next_contiguous_offset = offset + s->cluster_size;
44
+ }
45
+
46
/* Mark cluster as used */
47
if (!has_data_file(bs)) {
48
ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table,
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
No reasons for not reporting found corruptions as corruptions in case
4
of some internal errors, especially in case of just failed to fix l2
5
entry (and in this case, missed corruptions may influence comparing
6
logic, when we calculate difference between corruptions fields of two
7
results)
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-id: 20190227131433.197063-6-vsementsov@virtuozzo.com
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
block/qcow2-refcount.c | 19 +++++++++----------
15
1 file changed, 9 insertions(+), 10 deletions(-)
16
17
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-refcount.c
20
+++ b/block/qcow2-refcount.c
21
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
22
23
/* Correct offsets are cluster aligned */
24
if (offset_into_cluster(s, offset)) {
25
+ res->corruptions++;
26
+
27
if (qcow2_get_cluster_type(bs, l2_entry) ==
28
QCOW2_CLUSTER_ZERO_ALLOC)
29
{
30
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
31
/* Do not abort, continue checking the rest of this
32
* L2 table's entries */
33
} else {
34
+ res->corruptions--;
35
res->corruptions_fixed++;
36
/* Skip marking the cluster as used
37
* (it is unused now) */
38
continue;
39
}
40
- } else {
41
- res->corruptions++;
42
}
43
} else {
44
fprintf(stderr, "ERROR offset=%" PRIx64 ": Data cluster is "
45
"not properly aligned; L2 entry corrupted.\n", offset);
46
- res->corruptions++;
47
}
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
51
continue;
52
}
53
if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {
54
+ res->corruptions++;
55
fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "
56
"l1_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
57
repair ? "Repairing" : "ERROR", i, l1_entry, refcount);
58
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
59
res->check_errors++;
60
goto fail;
61
}
62
+ res->corruptions--;
63
res->corruptions_fixed++;
64
- } else {
65
- res->corruptions++;
66
}
67
}
68
69
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
70
}
71
}
72
if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
73
+ res->corruptions++;
74
fprintf(stderr, "%s OFLAG_COPIED data cluster: "
75
"l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
76
repair ? "Repairing" : "ERROR", l2_entry, refcount);
77
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
78
? l2_entry | QCOW_OFLAG_COPIED
79
: l2_entry & ~QCOW_OFLAG_COPIED);
80
l2_dirty++;
81
- } else {
82
- res->corruptions++;
83
}
84
}
85
}
86
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
87
res->check_errors++;
88
goto fail;
89
}
90
+ res->corruptions -= l2_dirty;
91
res->corruptions_fixed += l2_dirty;
92
}
93
}
94
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
95
}
96
97
if (cluster >= *nb_clusters) {
98
+ res->corruptions++;
99
fprintf(stderr, "%s refcount block %" PRId64 " is outside image\n",
100
fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
101
102
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
103
goto resize_fail;
104
}
105
106
+ res->corruptions--;
107
res->corruptions_fixed++;
108
ret = qcow2_inc_refcounts_imrt(bs, res,
109
refcount_table, nb_clusters,
110
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
111
continue;
112
113
resize_fail:
114
- res->corruptions++;
115
*rebuild = true;
116
fprintf(stderr, "ERROR could not resize image: %s\n",
117
strerror(-ret));
118
- } else {
119
- res->corruptions++;
120
}
121
continue;
122
}
123
--
124
2.20.1
125
126
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: hujian <hu.jian@zte.com.cn>
2
2
3
Bitmap data may take a lot of disk space, so it's better to discard it
3
During the stop of dataplane for virtio-blk, virtio_bus_cleanup_host_notifier() is be
4
always.
4
called to clean up notifier at the end, if polled ioeventfd, virtio_blk_handle_output()
5
is used to handle io request. But due to s->dataplane_disabled is false, it will be
6
returned directly, which drops io request.
7
Backtrace:
8
->virtio_blk_data_plane_stop
9
->virtio_bus_cleanup_host_notifier
10
->virtio_queue_host_notifier_read
11
->virtio_queue_notify_vq
12
->vq->handle_output
13
->virtio_blk_handle_output
14
->if (s->dataplane && !s->dataplane_stoped)
15
->if (!s->dataplane_disabled)
16
->return *
17
->virtio_blk_handle_output_do
18
The above problem can occur when using "virsh reset" cmdline to reset guest, while
19
guest does io.
20
To fix this problem, don't try to start dataplane if s->stopping is true, and io would
21
be handled by virtio_blk_handle_vq().
5
22
6
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
23
Signed-off-by: hujian <hu.jian@zte.com.cn>
7
Message-id: 1551346019-293202-1-git-send-email-andrey.shinkevich@virtuozzo.com
24
Message-id: 202310111414266586398@zte.com.cn
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
25
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
[mreitz: Use the commit message proposed by Vladimir]
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
26
---
12
block/qcow2-bitmap.c | 2 +-
27
hw/block/virtio-blk.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
28
1 file changed, 1 insertion(+), 1 deletion(-)
14
29
15
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
30
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
16
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2-bitmap.c
32
--- a/hw/block/virtio-blk.c
18
+++ b/block/qcow2-bitmap.c
33
+++ b/hw/block/virtio-blk.c
19
@@ -XXX,XX +XXX,XX @@ static void clear_bitmap_table(BlockDriverState *bs, uint64_t *bitmap_table,
34
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
20
continue;
35
{
21
}
36
VirtIOBlock *s = (VirtIOBlock *)vdev;
22
37
23
- qcow2_free_clusters(bs, addr, s->cluster_size, QCOW2_DISCARD_OTHER);
38
- if (s->dataplane && !s->dataplane_started) {
24
+ qcow2_free_clusters(bs, addr, s->cluster_size, QCOW2_DISCARD_ALWAYS);
39
+ if (s->dataplane && !s->dataplane_started && !s->stopping) {
25
bitmap_table[i] = 0;
40
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
26
}
41
* dataplane here instead of waiting for .set_status().
27
}
42
*/
28
--
43
--
29
2.20.1
44
2.41.0
30
31
diff view generated by jsdifflib
Deleted patch
1
This requires some changes to keep iotests 104 and 207 working.
2
1
3
qemu-img info in 104 will now return a filename including the user name
4
and the port, which need to be filtered by adjusting REMOTE_TEST_DIR in
5
common.rc. This additional information has to be marked optional,
6
however (which is simple as REMOTE_TEST_DIR is a regex), because
7
otherwise 197 and 215 would fail: They use it (indirectly) to filter
8
qemu-img create output which contains a backing filename they have
9
passed to it -- which probably does not contain a user name or port
10
number.
11
12
The problem in 207 is a nice one to have: qemu-img info used to return
13
json:{} filenames, but with this patch it returns nice plain ones. We
14
now need to adjust the filtering to hide the user name (and port number
15
while we are at it). The simplest way to do this is to include both in
16
iotests.remote_filename() so that bdrv_refresh_filename() will not
17
change it, and then iotests.img_info_log() will filter it correctly
18
automatically.
19
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Tested-by: Richard W.M. Jones <rjones@redhat.com>
22
Message-id: 20190225190828.17726-2-mreitz@redhat.com
23
Signed-off-by: Max Reitz <mreitz@redhat.com>
24
---
25
block/ssh.c | 52 +++++++++++++++++++++++++++++++----
26
tests/qemu-iotests/207 | 10 +++----
27
tests/qemu-iotests/207.out | 10 +++----
28
tests/qemu-iotests/common.rc | 2 +-
29
tests/qemu-iotests/iotests.py | 2 +-
30
5 files changed, 59 insertions(+), 17 deletions(-)
31
32
diff --git a/block/ssh.c b/block/ssh.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/block/ssh.c
35
+++ b/block/ssh.c
36
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVSSHState {
37
38
/* Used to warn if 'flush' is not supported. */
39
bool unsafe_flush_warning;
40
+
41
+ /*
42
+ * Store the user name for ssh_refresh_filename() because the
43
+ * default depends on the system you are on -- therefore, when we
44
+ * generate a filename, it should always contain the user name we
45
+ * are actually using.
46
+ */
47
+ char *user;
48
} BDRVSSHState;
49
50
static void ssh_state_init(BDRVSSHState *s)
51
@@ -XXX,XX +XXX,XX @@ static void ssh_state_init(BDRVSSHState *s)
52
53
static void ssh_state_free(BDRVSSHState *s)
54
{
55
+ g_free(s->user);
56
+
57
if (s->sftp_handle) {
58
libssh2_sftp_close(s->sftp_handle);
59
}
60
@@ -XXX,XX +XXX,XX @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts,
61
int ssh_flags, int creat_mode, Error **errp)
62
{
63
int r, ret;
64
- const char *user;
65
long port = 0;
66
67
if (opts->has_user) {
68
- user = opts->user;
69
+ s->user = g_strdup(opts->user);
70
} else {
71
- user = g_get_user_name();
72
- if (!user) {
73
+ s->user = g_strdup(g_get_user_name());
74
+ if (!s->user) {
75
error_setg_errno(errp, errno, "Can't get user name");
76
ret = -errno;
77
goto err;
78
@@ -XXX,XX +XXX,XX @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts,
79
}
80
81
/* Authenticate. */
82
- ret = authenticate(s, user, errp);
83
+ ret = authenticate(s, s->user, errp);
84
if (ret < 0) {
85
goto err;
86
}
87
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
88
return ssh_grow_file(s, offset, errp);
89
}
90
91
+static void ssh_refresh_filename(BlockDriverState *bs)
92
+{
93
+ BDRVSSHState *s = bs->opaque;
94
+ const char *path, *host_key_check;
95
+ int ret;
96
+
97
+ /*
98
+ * None of these options can be represented in a plain "host:port"
99
+ * format, so if any was given, we have to abort.
100
+ */
101
+ if (s->inet->has_ipv4 || s->inet->has_ipv6 || s->inet->has_to ||
102
+ s->inet->has_numeric)
103
+ {
104
+ return;
105
+ }
106
+
107
+ path = qdict_get_try_str(bs->full_open_options, "path");
108
+ assert(path); /* mandatory option */
109
+
110
+ host_key_check = qdict_get_try_str(bs->full_open_options, "host_key_check");
111
+
112
+ ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
113
+ "ssh://%s@%s:%s%s%s%s",
114
+ s->user, s->inet->host, s->inet->port, path,
115
+ host_key_check ? "?host_key_check=" : "",
116
+ host_key_check ?: "");
117
+ if (ret >= sizeof(bs->exact_filename)) {
118
+ /* An overflow makes the filename unusable, so do not report any */
119
+ bs->exact_filename[0] = '\0';
120
+ }
121
+}
122
+
123
static const char *const ssh_strong_runtime_opts[] = {
124
"host",
125
"port",
126
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ssh = {
127
.bdrv_getlength = ssh_getlength,
128
.bdrv_co_truncate = ssh_co_truncate,
129
.bdrv_co_flush_to_disk = ssh_co_flush,
130
+ .bdrv_refresh_filename = ssh_refresh_filename,
131
.create_opts = &ssh_create_opts,
132
.strong_runtime_opts = ssh_strong_runtime_opts,
133
};
134
diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207
135
index XXXXXXX..XXXXXXX 100755
136
--- a/tests/qemu-iotests/207
137
+++ b/tests/qemu-iotests/207
138
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
139
'size': 4194304 })
140
vm.shutdown()
141
142
- iotests.img_info_log(remote_path, filter_path=disk_path)
143
+ iotests.img_info_log(remote_path)
144
iotests.log("")
145
iotests.img_info_log(disk_path)
146
147
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
148
'size': 8388608 })
149
vm.shutdown()
150
151
- iotests.img_info_log(remote_path, filter_path=disk_path)
152
+ iotests.img_info_log(remote_path)
153
154
vm.launch()
155
blockdev_create(vm, { 'driver': 'ssh',
156
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
157
'size': 4194304 })
158
vm.shutdown()
159
160
- iotests.img_info_log(remote_path, filter_path=disk_path)
161
+ iotests.img_info_log(remote_path)
162
163
md5_key = subprocess.check_output(
164
'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
165
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
166
'size': 8388608 })
167
vm.shutdown()
168
169
- iotests.img_info_log(remote_path, filter_path=disk_path)
170
+ iotests.img_info_log(remote_path)
171
172
sha1_key = subprocess.check_output(
173
'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
174
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
175
'size': 4194304 })
176
vm.shutdown()
177
178
- iotests.img_info_log(remote_path, filter_path=disk_path)
179
+ iotests.img_info_log(remote_path)
180
181
#
182
# Invalid path and user
183
diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out
184
index XXXXXXX..XXXXXXX 100644
185
--- a/tests/qemu-iotests/207.out
186
+++ b/tests/qemu-iotests/207.out
187
@@ -XXX,XX +XXX,XX @@
188
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
189
{"return": {}}
190
191
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
192
+image: TEST_IMG
193
file format: IMGFMT
194
virtual size: 4 MiB (4194304 bytes)
195
196
@@ -XXX,XX +XXX,XX @@ virtual size: 4 MiB (4194304 bytes)
197
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
198
{"return": {}}
199
200
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
201
+image: TEST_IMG
202
file format: IMGFMT
203
virtual size: 8 MiB (8388608 bytes)
204
205
@@ -XXX,XX +XXX,XX @@ virtual size: 8 MiB (8388608 bytes)
206
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
207
{"return": {}}
208
209
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
210
+image: TEST_IMG
211
file format: IMGFMT
212
virtual size: 4 MiB (4194304 bytes)
213
214
@@ -XXX,XX +XXX,XX @@ Job failed: remote host key does not match host_key_check 'wrong'
215
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
216
{"return": {}}
217
218
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
219
+image: TEST_IMG
220
file format: IMGFMT
221
virtual size: 8 MiB (8388608 bytes)
222
223
@@ -XXX,XX +XXX,XX @@ Job failed: remote host key does not match host_key_check 'wrong'
224
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
225
{"return": {}}
226
227
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
228
+image: TEST_IMG
229
file format: IMGFMT
230
virtual size: 4 MiB (4194304 bytes)
231
232
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
233
index XXXXXXX..XXXXXXX 100644
234
--- a/tests/qemu-iotests/common.rc
235
+++ b/tests/qemu-iotests/common.rc
236
@@ -XXX,XX +XXX,XX @@ else
237
TEST_IMG="nbd:127.0.0.1:10810"
238
elif [ "$IMGPROTO" = "ssh" ]; then
239
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
240
- REMOTE_TEST_DIR="ssh://127.0.0.1$TEST_DIR"
241
+ REMOTE_TEST_DIR="ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?$TEST_DIR"
242
TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE"
243
elif [ "$IMGPROTO" = "nfs" ]; then
244
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
245
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
246
index XXXXXXX..XXXXXXX 100644
247
--- a/tests/qemu-iotests/iotests.py
248
+++ b/tests/qemu-iotests/iotests.py
249
@@ -XXX,XX +XXX,XX @@ def remote_filename(path):
250
if imgproto == 'file':
251
return path
252
elif imgproto == 'ssh':
253
- return "ssh://127.0.0.1%s" % (path)
254
+ return "ssh://%s@127.0.0.1:22%s" % (os.environ.get('USER'), path)
255
else:
256
raise Exception("Protocol %s not supported" % (imgproto))
257
258
--
259
2.20.1
260
261
diff view generated by jsdifflib
Deleted patch
1
ssh_bdrv_dirname() is basically the generic bdrv_dirname(), except it
2
takes care not to silently chop off any query string (i.e.,
3
host_key_check).
4
1
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Tested-by: Richard W.M. Jones <rjones@redhat.com>
7
Message-id: 20190225190828.17726-3-mreitz@redhat.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/ssh.c | 21 +++++++++++++++++++++
11
1 file changed, 21 insertions(+)
12
13
diff --git a/block/ssh.c b/block/ssh.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/ssh.c
16
+++ b/block/ssh.c
17
@@ -XXX,XX +XXX,XX @@ static void ssh_refresh_filename(BlockDriverState *bs)
18
}
19
}
20
21
+static char *ssh_bdrv_dirname(BlockDriverState *bs, Error **errp)
22
+{
23
+ if (qdict_haskey(bs->full_open_options, "host_key_check")) {
24
+ /*
25
+ * We cannot generate a simple prefix if we would have to
26
+ * append a query string.
27
+ */
28
+ error_setg(errp,
29
+ "Cannot generate a base directory with host_key_check set");
30
+ return NULL;
31
+ }
32
+
33
+ if (bs->exact_filename[0] == '\0') {
34
+ error_setg(errp, "Cannot generate a base directory for this ssh node");
35
+ return NULL;
36
+ }
37
+
38
+ return path_combine(bs->exact_filename, "");
39
+}
40
+
41
static const char *const ssh_strong_runtime_opts[] = {
42
"host",
43
"port",
44
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ssh = {
45
.bdrv_co_truncate = ssh_co_truncate,
46
.bdrv_co_flush_to_disk = ssh_co_flush,
47
.bdrv_refresh_filename = ssh_refresh_filename,
48
+ .bdrv_dirname = ssh_bdrv_dirname,
49
.create_opts = &ssh_create_opts,
50
.strong_runtime_opts = ssh_strong_runtime_opts,
51
};
52
--
53
2.20.1
54
55
diff view generated by jsdifflib
Deleted patch
1
From: Alberto Garcia <berto@igalia.com>
2
1
3
There is no need to check for this because all block drivers that have
4
children implement bdrv_child_perm and all callers already ensure that
5
bs->drv is set.
6
7
Furthermore, if this check would fail then the callers would end up
8
with uninitialized values for nperm and nshared.
9
10
This patch replaces the check with an assertion.
11
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
13
Message-id: 20190404112953.4058-1-berto@igalia.com
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
block.c | 9 ++++-----
17
1 file changed, 4 insertions(+), 5 deletions(-)
18
19
diff --git a/block.c b/block.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block.c
22
+++ b/block.c
23
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
24
uint64_t parent_perm, uint64_t parent_shared,
25
uint64_t *nperm, uint64_t *nshared)
26
{
27
- if (bs->drv && bs->drv->bdrv_child_perm) {
28
- bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
29
- parent_perm, parent_shared,
30
- nperm, nshared);
31
- }
32
+ assert(bs->drv && bs->drv->bdrv_child_perm);
33
+ bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
34
+ parent_perm, parent_shared,
35
+ nperm, nshared);
36
/* TODO Take force_share from reopen_queue */
37
if (child_bs && child_bs->force_share) {
38
*nshared = BLK_PERM_ALL;
39
--
40
2.20.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Alberto Garcia <berto@igalia.com>
2
1
3
This function combines bdrv_set_backing_hd() and bdrv_replace_node()
4
so we can use it to simplify the code a bit in commit_start().
5
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
Message-id: 20190403143748.9790-1-berto@igalia.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/commit.c | 11 +----------
11
1 file changed, 1 insertion(+), 10 deletions(-)
12
13
diff --git a/block/commit.c b/block/commit.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/commit.c
16
+++ b/block/commit.c
17
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
18
commit_top_bs->total_sectors = top->total_sectors;
19
bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(top));
20
21
- bdrv_set_backing_hd(commit_top_bs, top, &local_err);
22
+ bdrv_append(commit_top_bs, top, &local_err);
23
if (local_err) {
24
- bdrv_unref(commit_top_bs);
25
- commit_top_bs = NULL;
26
- error_propagate(errp, local_err);
27
- goto fail;
28
- }
29
- bdrv_replace_node(top, commit_top_bs, &local_err);
30
- if (local_err) {
31
- bdrv_unref(commit_top_bs);
32
commit_top_bs = NULL;
33
error_propagate(errp, local_err);
34
goto fail;
35
}
36
37
s->commit_top_bs = commit_top_bs;
38
- bdrv_unref(commit_top_bs);
39
40
/* Block all nodes between top and base, because they will
41
* disappear from the chain after this operation. */
42
--
43
2.20.1
44
45
diff view generated by jsdifflib
Deleted patch
1
A recent patch results in qemu-img reporting the backing file format of
2
vmdk images as vmdk. This broke iotests 110 and 126.
3
1
4
Fixes: 7502be838e2fb62cc00f9e55f632e0b88ead5e6e
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Message-id: 20190415154129.31021-1-mreitz@redhat.com
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
9
tests/qemu-iotests/110 | 10 +++++++---
10
tests/qemu-iotests/126 | 10 +++++++---
11
2 files changed, 14 insertions(+), 6 deletions(-)
12
13
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
14
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/110
16
+++ b/tests/qemu-iotests/110
17
@@ -XXX,XX +XXX,XX @@ TEST_IMG="$TEST_IMG.base" _make_test_img 64M
18
_make_test_img -b "$TEST_IMG_REL.base" 64M
19
# qemu should be able to reconstruct the filename, so relative backing names
20
# should work
21
+# (We have to filter the backing file format because vmdk always
22
+# reports it (as vmdk), whereas other image formats would do so only
23
+# with the backing_fmt creation option, which neither vmdk nor qcow
24
+# support)
25
TEST_IMG="json:{'driver':'$IMGFMT','file':{'driver':'file','filename':'$TEST_IMG'}}" \
26
- _img_info | _filter_img_info
27
+ _img_info | _filter_img_info | grep -v 'backing file format'
28
29
echo
30
echo '=== Non-reconstructable filename ==='
31
@@ -XXX,XX +XXX,XX @@ TEST_IMG="json:{
32
}
33
]
34
}
35
-}" _img_info | _filter_img_info
36
+}" _img_info | _filter_img_info | grep -v 'backing file format'
37
38
echo
39
echo '=== Backing name is always relative to the backed image ==='
40
@@ -XXX,XX +XXX,XX @@ TEST_IMG="json:{
41
}
42
]
43
}
44
-}" _img_info | _filter_img_info
45
+}" _img_info | _filter_img_info | grep -v 'backing file format'
46
47
48
# success, all done
49
diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
50
index XXXXXXX..XXXXXXX 100755
51
--- a/tests/qemu-iotests/126
52
+++ b/tests/qemu-iotests/126
53
@@ -XXX,XX +XXX,XX @@ TOP_IMG="$TEST_DIR/image:top.$IMGFMT"
54
TEST_IMG=$BASE_IMG _make_test_img 64M
55
TEST_IMG=$TOP_IMG _make_test_img -b ./image:base.$IMGFMT
56
57
-# The default cluster size depends on the image format
58
-TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size'
59
+# (1) The default cluster size depends on the image format
60
+# (2) vmdk only supports vmdk backing files, so it always reports the
61
+# format of its backing file as such (but neither it nor qcow
62
+# support the backing_fmt creation option, so we cannot use that to
63
+# harmonize the output across all image formats this test supports)
64
+TEST_IMG=$TOP_IMG _img_info | grep -ve 'cluster_size' -e 'backing file format'
65
66
_rm_test_img "$BASE_IMG"
67
_rm_test_img "$TOP_IMG"
68
@@ -XXX,XX +XXX,XX @@ TOP_IMG="file:image:top.$IMGFMT"
69
TEST_IMG=$BASE_IMG _make_test_img 64M
70
TEST_IMG=$TOP_IMG _make_test_img -b "$BASE_IMG"
71
72
-TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size'
73
+TEST_IMG=$TOP_IMG _img_info | grep -ve 'cluster_size' -e 'backing file format'
74
75
_rm_test_img "$BASE_IMG"
76
_rm_test_img "image:top.$IMGFMT"
77
--
78
2.20.1
79
80
diff view generated by jsdifflib