1
The following changes since commit a26a98dfb9d448d7234d931ae3720feddf6f0651:
1
The following changes since commit 16aaacb307ed607b9780c12702c44f0fe52edc7e:
2
2
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20171006' into staging (2017-10-06 13:19:03 +0100)
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200430' into staging (2020-04-30 14:00:36 +0100)
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 fc3fd63fc0573ffd2ee569591a2e7f6c7310fd18:
9
for you to fetch changes up to eaae29ef89d498d0eac553c77b554f310a47f809:
10
10
11
Merge remote-tracking branch 'mreitz/tags/pull-block-2017-10-06' into queue-block (2017-10-06 16:32:08 +0200)
11
qemu-storage-daemon: Fix non-string --object properties (2020-04-30 17:51:07 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches
14
Block layer patches:
15
16
- Fix resize (extending) of short overlays
17
- nvme: introduce PMR support from NVMe 1.4 spec
18
- qemu-storage-daemon: Fix non-string --object properties
15
19
16
----------------------------------------------------------------
20
----------------------------------------------------------------
17
Daniel P. Berrange (6):
21
Alberto Garcia (1):
18
block: use 1 MB bounce buffers for crypto instead of 16KB
22
qcow2: Add incompatibility note between backing files and raw external data files
19
crypto: expose encryption sector size in APIs
20
block: fix data type casting for crypto payload offset
21
block: convert crypto driver to bdrv_co_preadv|pwritev
22
block: convert qcrypto_block_encrypt|decrypt to take bytes offset
23
block: support passthrough of BDRV_REQ_FUA in crypto driver
24
23
25
Eric Blake (27):
24
Andrzej Jakowski (1):
26
block: Typo fix in copy_on_readv()
25
nvme: introduce PMR support from NVMe 1.4 spec
27
block: Make bdrv_img_create() size selection easier to read
28
hbitmap: Rename serialization_granularity to serialization_align
29
qcow2: Ensure bitmap serialization is aligned
30
dirty-bitmap: Drop unused functions
31
dirty-bitmap: Avoid size query failure during truncate
32
dirty-bitmap: Change bdrv_dirty_bitmap_size() to report bytes
33
dirty-bitmap: Track bitmap size by bytes
34
dirty-bitmap: Change bdrv_dirty_bitmap_*serialize*() to take bytes
35
qcow2: Switch sectors_covered_by_bitmap_cluster() to byte-based
36
dirty-bitmap: Set iterator start by offset, not sector
37
dirty-bitmap: Change bdrv_dirty_iter_next() to report byte offset
38
dirty-bitmap: Change bdrv_get_dirty_count() to report bytes
39
dirty-bitmap: Change bdrv_get_dirty_locked() to take bytes
40
dirty-bitmap: Change bdrv_[re]set_dirty_bitmap() to use bytes
41
mirror: Switch mirror_dirty_init() to byte-based iteration
42
qcow2: Switch qcow2_measure() to byte-based iteration
43
qcow2: Switch load_bitmap_data() to byte-based iteration
44
qcow2: Switch store_bitmap_data() to byte-based iteration
45
dirty-bitmap: Switch bdrv_set_dirty() to bytes
46
dirty-bitmap: Convert internal hbitmap size/granularity
47
qemu-io: Add -C for opening with copy-on-read
48
block: Uniform handling of 0-length bdrv_get_block_status()
49
iotests: Restore stty settings on completion
50
block: Add blkdebug hook for copy-on-read
51
block: Perform copy-on-read in loop
52
iotests: Add test 197 for covering copy-on-read
53
26
54
Kevin Wolf (6):
27
Kevin Wolf (12):
55
block: Introduce BdrvChildRole.update_filename
28
block: Add flags to BlockDriver.bdrv_co_truncate()
56
commit: Support multiple roots above top node
29
block: Add flags to bdrv(_co)_truncate()
57
qemu-iotests: Allow QMP pretty printing in common.qemu
30
block-backend: Add flags to blk_truncate()
58
qemu-iotests: Test commit block job where top has two parents
31
qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
59
commit: Remove overlay_bs
32
raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
60
Merge remote-tracking branch 'mreitz/tags/pull-block-2017-10-06' into queue-block
33
file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
34
block: truncate: Don't make backing file data visible
35
iotests: Filter testfiles out in filter_img_info()
36
iotests: Test committing to short backing file
37
qcow2: Forward ZERO_WRITE flag for full preallocation
38
qom: Factor out user_creatable_add_dict()
39
qemu-storage-daemon: Fix non-string --object properties
61
40
62
Max Reitz (1):
41
Paolo Bonzini (1):
63
iotests: Fix 195 if IMGFMT is part of TEST_DIR
42
qemu-iotests: allow qcow2 external discarded clusters to contain stale data
64
43
65
Paolo Bonzini (10):
44
docs/interop/qcow2.txt | 3 +
66
qemu-iotests: remove dead code
45
hw/block/nvme.h | 2 +
67
qemu-iotests: get rid of AWK_PROG
46
include/block/block.h | 5 +-
68
qemu-iotests: move "check" code out of common.rc
47
include/block/block_int.h | 10 +-
69
qemu-iotests: cleanup and fix search for programs
48
include/block/nvme.h | 172 ++++++++++++++++++++++++++
70
qemu-iotests: limit non-_PROG-suffixed variables to common.rc
49
include/qom/object_interfaces.h | 16 +++
71
qemu-iotests: do not include common.rc in "check"
50
include/sysemu/block-backend.h | 2 +-
72
qemu-iotests: disintegrate more parts of common.config
51
block.c | 3 +-
73
qemu-iotests: fix uninitialized variable
52
block/block-backend.c | 4 +-
74
qemu-iotests: get rid of $iam
53
block/commit.c | 4 +-
75
qemu-iotests: merge "check" and "common"
54
block/crypto.c | 7 +-
55
block/file-posix.c | 6 +-
56
block/file-win32.c | 2 +-
57
block/gluster.c | 1 +
58
block/io.c | 43 ++++++-
59
block/iscsi.c | 2 +-
60
block/mirror.c | 2 +-
61
block/nfs.c | 3 +-
62
block/parallels.c | 6 +-
63
block/qcow.c | 4 +-
64
block/qcow2-cluster.c | 2 +-
65
block/qcow2-refcount.c | 2 +-
66
block/qcow2.c | 73 +++++++++--
67
block/qed.c | 3 +-
68
block/raw-format.c | 6 +-
69
block/rbd.c | 1 +
70
block/sheepdog.c | 4 +-
71
block/ssh.c | 2 +-
72
block/vdi.c | 2 +-
73
block/vhdx-log.c | 2 +-
74
block/vhdx.c | 6 +-
75
block/vmdk.c | 8 +-
76
block/vpc.c | 2 +-
77
blockdev.c | 2 +-
78
hw/block/nvme.c | 109 ++++++++++++++++
79
qemu-img.c | 2 +-
80
qemu-io-cmds.c | 2 +-
81
qemu-storage-daemon.c | 4 +-
82
qom/object_interfaces.c | 31 +++++
83
qom/qom-qmp-cmds.c | 24 +---
84
tests/test-block-iothread.c | 9 +-
85
tests/qemu-iotests/iotests.py | 5 +-
86
hw/block/Makefile.objs | 2 +-
87
hw/block/trace-events | 4 +
88
tests/qemu-iotests/244 | 10 +-
89
tests/qemu-iotests/244.out | 9 +-
90
tests/qemu-iotests/274 | 155 +++++++++++++++++++++++
91
tests/qemu-iotests/274.out | 268 ++++++++++++++++++++++++++++++++++++++++
92
tests/qemu-iotests/group | 1 +
93
49 files changed, 951 insertions(+), 96 deletions(-)
94
create mode 100755 tests/qemu-iotests/274
95
create mode 100644 tests/qemu-iotests/274.out
76
96
77
Pavel Butsykin (2):
78
qcow2: fix return error code in qcow2_truncate()
79
qcow2: truncate the tail of the image file after shrinking the image
80
97
81
Thomas Huth (1):
82
hw/block/onenand: Remove dead code block
83
84
Vladimir Sementsov-Ogievskiy (2):
85
block/mirror: check backing in bdrv_mirror_top_refresh_filename
86
block/mirror: check backing in bdrv_mirror_top_flush
87
88
qapi/block-core.json | 5 +-
89
block/qcow2.h | 1 +
90
crypto/blockpriv.h | 5 +-
91
include/block/block.h | 3 +-
92
include/block/block_int.h | 8 +-
93
include/block/dirty-bitmap.h | 43 +-
94
include/crypto/block.h | 29 +-
95
include/qemu/hbitmap.h | 8 +-
96
block.c | 109 ++++--
97
block/backup.c | 7 +-
98
block/commit.c | 64 +--
99
block/crypto.c | 130 +++---
100
block/dirty-bitmap.c | 134 ++-----
101
block/io.c | 131 +++++--
102
block/mirror.c | 88 ++---
103
block/qcow.c | 11 +-
104
block/qcow2-bitmap.c | 62 +--
105
block/qcow2-cluster.c | 8 +-
106
block/qcow2-refcount.c | 22 ++
107
block/qcow2.c | 53 ++-
108
crypto/block-luks.c | 18 +-
109
crypto/block-qcow.c | 13 +-
110
crypto/block.c | 26 +-
111
hw/block/onenand.c | 4 -
112
migration/block.c | 12 +-
113
qemu-io.c | 15 +-
114
tests/test-hbitmap.c | 10 +-
115
util/hbitmap.c | 8 +-
116
tests/qemu-iotests/030 | 4 -
117
tests/qemu-iotests/039.out | 10 +-
118
tests/qemu-iotests/061.out | 4 +-
119
tests/qemu-iotests/137.out | 2 +-
120
tests/qemu-iotests/165 | 2 +-
121
tests/qemu-iotests/191 | 153 ++++++++
122
tests/qemu-iotests/191.out | 827 +++++++++++++++++++++++++++++++++++++++
123
tests/qemu-iotests/195 | 7 +-
124
tests/qemu-iotests/197 | 109 ++++++
125
tests/qemu-iotests/197.out | 26 ++
126
tests/qemu-iotests/check | 585 ++++++++++++++++++++++++---
127
tests/qemu-iotests/common | 459 ----------------------
128
tests/qemu-iotests/common.config | 206 +---------
129
tests/qemu-iotests/common.filter | 1 +
130
tests/qemu-iotests/common.qemu | 15 +-
131
tests/qemu-iotests/common.rc | 205 +++++-----
132
tests/qemu-iotests/group | 2 +
133
45 files changed, 2333 insertions(+), 1311 deletions(-)
134
create mode 100755 tests/qemu-iotests/191
135
create mode 100644 tests/qemu-iotests/191.out
136
create mode 100755 tests/qemu-iotests/197
137
create mode 100644 tests/qemu-iotests/197.out
138
delete mode 100644 tests/qemu-iotests/common
139
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Signed-off-by: Eric Blake <eblake@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
6
block/io.c | 2 +-
7
1 file changed, 1 insertion(+), 1 deletion(-)
8
9
diff --git a/block/io.c b/block/io.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/block/io.c
12
+++ b/block/io.c
13
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
14
/* FIXME We cannot require callers to have write permissions when all they
15
* are doing is a read request. If we did things right, write permissions
16
* would be obtained anyway, but internally by the copy-on-read code. As
17
- * long as it is implemented here rather than in a separat filter driver,
18
+ * long as it is implemented here rather than in a separate filter driver,
19
* the copy-on-read code doesn't have its own BdrvChild, however, for which
20
* it could request permissions. Therefore we have to bypass the permission
21
* system for the moment. */
22
--
23
2.13.6
24
25
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
All callers of bdrv_img_create() pass in a size, or -1 to read the
4
size from the backing file. We then set that size as the QemuOpt
5
default, which means we will reuse that default rather than the
6
final parameter to qemu_opt_get_size() several lines later. But
7
it is rather confusing to read subsequent checks of 'size == -1'
8
when it looks (without seeing the full context) like size defaults
9
to 0; it also doesn't help that a size of 0 is valid (for some
10
formats).
11
12
Rework the logic to make things more legible.
13
14
Signed-off-by: Eric Blake <eblake@redhat.com>
15
Reviewed-by: John Snow <jsnow@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Reviewed-by: Fam Zheng <famz@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
block.c | 2 +-
21
1 file changed, 1 insertion(+), 1 deletion(-)
22
23
diff --git a/block.c b/block.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block.c
26
+++ b/block.c
27
@@ -XXX,XX +XXX,XX @@ void bdrv_img_create(const char *filename, const char *fmt,
28
29
/* The size for the image must always be specified, unless we have a backing
30
* file and we have not been forbidden from opening it. */
31
- size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
32
+ size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, img_size);
33
if (backing_file && !(flags & BDRV_O_NO_BACKING)) {
34
BlockDriverState *bs;
35
char *full_backing = g_new0(char, PATH_MAX);
36
--
37
2.13.6
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
The only client of hbitmap_serialization_granularity() is dirty-bitmap's
4
bdrv_dirty_bitmap_serialization_align(). Keeping the two names consistent
5
is worthwhile, and the shorter name is more representative of what the
6
function returns (the required alignment to be used for start/count of
7
other serialization functions, where violating the alignment causes
8
assertion failures).
9
10
Signed-off-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Fam Zheng <famz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
include/qemu/hbitmap.h | 8 ++++----
17
block/dirty-bitmap.c | 2 +-
18
tests/test-hbitmap.c | 10 +++++-----
19
util/hbitmap.c | 8 ++++----
20
4 files changed, 14 insertions(+), 14 deletions(-)
21
22
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/qemu/hbitmap.h
25
+++ b/include/qemu/hbitmap.h
26
@@ -XXX,XX +XXX,XX @@ bool hbitmap_get(const HBitmap *hb, uint64_t item);
27
bool hbitmap_is_serializable(const HBitmap *hb);
28
29
/**
30
- * hbitmap_serialization_granularity:
31
+ * hbitmap_serialization_align:
32
* @hb: HBitmap to operate on.
33
*
34
- * Granularity of serialization chunks, used by other serialization functions.
35
- * For every chunk:
36
+ * Required alignment of serialization chunks, used by other serialization
37
+ * functions. For every chunk:
38
* 1. Chunk start should be aligned to this granularity.
39
* 2. Chunk size should be aligned too, except for last chunk (for which
40
* start + count == hb->size)
41
*/
42
-uint64_t hbitmap_serialization_granularity(const HBitmap *hb);
43
+uint64_t hbitmap_serialization_align(const HBitmap *hb);
44
45
/**
46
* hbitmap_serialization_size:
47
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block/dirty-bitmap.c
50
+++ b/block/dirty-bitmap.c
51
@@ -XXX,XX +XXX,XX @@ uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
52
53
uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
54
{
55
- return hbitmap_serialization_granularity(bitmap->bitmap);
56
+ return hbitmap_serialization_align(bitmap->bitmap);
57
}
58
59
void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
60
diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/tests/test-hbitmap.c
63
+++ b/tests/test-hbitmap.c
64
@@ -XXX,XX +XXX,XX @@ static void test_hbitmap_meta_one(TestHBitmapData *data, const void *unused)
65
}
66
}
67
68
-static void test_hbitmap_serialize_granularity(TestHBitmapData *data,
69
- const void *unused)
70
+static void test_hbitmap_serialize_align(TestHBitmapData *data,
71
+ const void *unused)
72
{
73
int r;
74
75
hbitmap_test_init(data, L3 * 2, 3);
76
g_assert(hbitmap_is_serializable(data->hb));
77
78
- r = hbitmap_serialization_granularity(data->hb);
79
+ r = hbitmap_serialization_align(data->hb);
80
g_assert_cmpint(r, ==, 64 << 3);
81
}
82
83
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
84
hbitmap_test_add("/hbitmap/meta/word", test_hbitmap_meta_word);
85
hbitmap_test_add("/hbitmap/meta/sector", test_hbitmap_meta_sector);
86
87
- hbitmap_test_add("/hbitmap/serialize/granularity",
88
- test_hbitmap_serialize_granularity);
89
+ hbitmap_test_add("/hbitmap/serialize/align",
90
+ test_hbitmap_serialize_align);
91
hbitmap_test_add("/hbitmap/serialize/basic",
92
test_hbitmap_serialize_basic);
93
hbitmap_test_add("/hbitmap/serialize/part",
94
diff --git a/util/hbitmap.c b/util/hbitmap.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/util/hbitmap.c
97
+++ b/util/hbitmap.c
98
@@ -XXX,XX +XXX,XX @@ bool hbitmap_is_serializable(const HBitmap *hb)
99
{
100
/* Every serialized chunk must be aligned to 64 bits so that endianness
101
* requirements can be fulfilled on both 64 bit and 32 bit hosts.
102
- * We have hbitmap_serialization_granularity() which converts this
103
+ * We have hbitmap_serialization_align() which converts this
104
* alignment requirement from bitmap bits to items covered (e.g. sectors).
105
* That value is:
106
* 64 << hb->granularity
107
* Since this value must not exceed UINT64_MAX, hb->granularity must be
108
* less than 58 (== 64 - 6, where 6 is ld(64), i.e. 1 << 6 == 64).
109
*
110
- * In order for hbitmap_serialization_granularity() to always return a
111
+ * In order for hbitmap_serialization_align() to always return a
112
* meaningful value, bitmaps that are to be serialized must have a
113
* granularity of less than 58. */
114
115
@@ -XXX,XX +XXX,XX @@ bool hbitmap_get(const HBitmap *hb, uint64_t item)
116
return (hb->levels[HBITMAP_LEVELS - 1][pos >> BITS_PER_LEVEL] & bit) != 0;
117
}
118
119
-uint64_t hbitmap_serialization_granularity(const HBitmap *hb)
120
+uint64_t hbitmap_serialization_align(const HBitmap *hb)
121
{
122
assert(hbitmap_is_serializable(hb));
123
124
@@ -XXX,XX +XXX,XX @@ static void serialization_chunk(const HBitmap *hb,
125
unsigned long **first_el, uint64_t *el_count)
126
{
127
uint64_t last = start + count - 1;
128
- uint64_t gran = hbitmap_serialization_granularity(hb);
129
+ uint64_t gran = hbitmap_serialization_align(hb);
130
131
assert((start & (gran - 1)) == 0);
132
assert((last >> hb->granularity) < hb->size);
133
--
134
2.13.6
135
136
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
When subdividing a bitmap serialization, the code in hbitmap.c
4
enforces that start/count parameters are aligned (except that
5
count can end early at end-of-bitmap). We exposed this required
6
alignment through bdrv_dirty_bitmap_serialization_align(), but
7
forgot to actually check that we comply with it.
8
9
Fortunately, qcow2 is never dividing bitmap serialization smaller
10
than one cluster (which is a minimum of 512 bytes); so we are
11
always compliant with the serialization alignment (which insists
12
that we partition at least 64 bits per chunk) because we are doing
13
at least 4k bits per chunk.
14
15
Still, it's safer to add an assertion (for the unlikely case that
16
we'd ever support a cluster smaller than 512 bytes, or if the
17
hbitmap implementation changes what it considers to be aligned),
18
rather than leaving bdrv_dirty_bitmap_serialization_align()
19
without a caller.
20
21
Signed-off-by: Eric Blake <eblake@redhat.com>
22
Reviewed-by: John Snow <jsnow@redhat.com>
23
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
24
Reviewed-by: Fam Zheng <famz@redhat.com>
25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
---
27
block/qcow2-bitmap.c | 7 +++++--
28
1 file changed, 5 insertions(+), 2 deletions(-)
29
30
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/block/qcow2-bitmap.c
33
+++ b/block/qcow2-bitmap.c
34
@@ -XXX,XX +XXX,XX @@ static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
35
static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
36
const BdrvDirtyBitmap *bitmap)
37
{
38
- uint32_t sector_granularity =
39
+ uint64_t sector_granularity =
40
bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
41
+ uint64_t sbc = sector_granularity * (s->cluster_size << 3);
42
43
- return (uint64_t)sector_granularity * (s->cluster_size << 3);
44
+ assert(QEMU_IS_ALIGNED(sbc,
45
+ bdrv_dirty_bitmap_serialization_align(bitmap)));
46
+ return sbc;
47
}
48
49
/* load_bitmap_data
50
--
51
2.13.6
52
53
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We had several functions that no one is currently using, and which
4
use sector-based interfaces. I'm trying to convert towards byte-based
5
interfaces, so it's easier to just drop the unused functions:
6
7
bdrv_dirty_bitmap_get_meta
8
bdrv_dirty_bitmap_get_meta_locked
9
bdrv_dirty_bitmap_reset_meta
10
bdrv_dirty_bitmap_meta_granularity
11
12
Signed-off-by: Eric Blake <eblake@redhat.com>
13
Reviewed-by: John Snow <jsnow@redhat.com>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
Reviewed-by: Fam Zheng <famz@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
include/block/dirty-bitmap.h | 10 ----------
19
block/dirty-bitmap.c | 44 --------------------------------------------
20
2 files changed, 54 deletions(-)
21
22
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/block/dirty-bitmap.h
25
+++ b/include/block/dirty-bitmap.h
26
@@ -XXX,XX +XXX,XX @@ void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
27
BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs);
28
uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs);
29
uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap);
30
-uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap);
31
bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap);
32
bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap);
33
const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap);
34
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
35
int64_t cur_sector, int64_t nr_sectors);
36
void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
37
int64_t cur_sector, int64_t nr_sectors);
38
-int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
39
- BdrvDirtyBitmap *bitmap, int64_t sector,
40
- int nb_sectors);
41
-int bdrv_dirty_bitmap_get_meta_locked(BlockDriverState *bs,
42
- BdrvDirtyBitmap *bitmap, int64_t sector,
43
- int nb_sectors);
44
-void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
45
- BdrvDirtyBitmap *bitmap, int64_t sector,
46
- int nb_sectors);
47
BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap);
48
BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
49
uint64_t first_sector);
50
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/dirty-bitmap.c
53
+++ b/block/dirty-bitmap.c
54
@@ -XXX,XX +XXX,XX @@ void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
55
qemu_mutex_unlock(bitmap->mutex);
56
}
57
58
-int bdrv_dirty_bitmap_get_meta_locked(BlockDriverState *bs,
59
- BdrvDirtyBitmap *bitmap, int64_t sector,
60
- int nb_sectors)
61
-{
62
- uint64_t i;
63
- int sectors_per_bit = 1 << hbitmap_granularity(bitmap->meta);
64
-
65
- /* To optimize: we can make hbitmap to internally check the range in a
66
- * coarse level, or at least do it word by word. */
67
- for (i = sector; i < sector + nb_sectors; i += sectors_per_bit) {
68
- if (hbitmap_get(bitmap->meta, i)) {
69
- return true;
70
- }
71
- }
72
- return false;
73
-}
74
-
75
-int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
76
- BdrvDirtyBitmap *bitmap, int64_t sector,
77
- int nb_sectors)
78
-{
79
- bool dirty;
80
-
81
- qemu_mutex_lock(bitmap->mutex);
82
- dirty = bdrv_dirty_bitmap_get_meta_locked(bs, bitmap, sector, nb_sectors);
83
- qemu_mutex_unlock(bitmap->mutex);
84
-
85
- return dirty;
86
-}
87
-
88
-void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
89
- BdrvDirtyBitmap *bitmap, int64_t sector,
90
- int nb_sectors)
91
-{
92
- qemu_mutex_lock(bitmap->mutex);
93
- hbitmap_reset(bitmap->meta, sector, nb_sectors);
94
- qemu_mutex_unlock(bitmap->mutex);
95
-}
96
-
97
int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
98
{
99
return bitmap->size;
100
@@ -XXX,XX +XXX,XX @@ uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
101
return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
102
}
103
104
-uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap)
105
-{
106
- return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->meta);
107
-}
108
-
109
BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
110
uint64_t first_sector)
111
{
112
--
113
2.13.6
114
115
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We've previously fixed several places where we failed to account
4
for possible errors from bdrv_nb_sectors(). Fix another one by
5
making bdrv_dirty_bitmap_truncate() take the new size from the
6
caller instead of querying itself; then adjust the sole caller
7
bdrv_truncate() to pass the size just determined by a successful
8
resize, or to reuse the size given to the original truncate
9
operation when refresh_total_sectors() was not able to confirm the
10
actual size (the two sizes can potentially differ according to
11
rounding constraints), thus avoiding sizing the bitmaps to -1.
12
This also fixes a bug where not all failure paths in
13
bdrv_truncate() would set errp.
14
15
Note that bdrv_truncate() is still a bit awkward. We may want
16
to revisit it later and clean up things to better guarantee that
17
a resize attempt either fails cleanly up front, or cannot fail
18
after guest-visible changes have been made (if temporary changes
19
are made, then they need to be cleanly rolled back). But that
20
is a task for another day; for now, the goal is the bare minimum
21
fix to ensure that just bdrv_dirty_bitmap_truncate() cannot fail.
22
23
Signed-off-by: Eric Blake <eblake@redhat.com>
24
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
25
Reviewed-by: John Snow <jsnow@redhat.com>
26
Reviewed-by: Fam Zheng <famz@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
---
29
include/block/dirty-bitmap.h | 2 +-
30
block.c | 16 +++++++++++-----
31
block/dirty-bitmap.c | 6 +++---
32
3 files changed, 15 insertions(+), 9 deletions(-)
33
34
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/block/dirty-bitmap.h
37
+++ b/include/block/dirty-bitmap.h
38
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
39
void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num);
40
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
41
int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
42
-void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
43
+void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes);
44
bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap);
45
bool bdrv_has_readonly_bitmaps(BlockDriverState *bs);
46
bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap);
47
diff --git a/block.c b/block.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block.c
50
+++ b/block.c
51
@@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
52
assert(!(bs->open_flags & BDRV_O_INACTIVE));
53
54
ret = drv->bdrv_truncate(bs, offset, prealloc, errp);
55
- if (ret == 0) {
56
- ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
57
- bdrv_dirty_bitmap_truncate(bs);
58
- bdrv_parent_cb_resize(bs);
59
- atomic_inc(&bs->write_gen);
60
+ if (ret < 0) {
61
+ return ret;
62
+ }
63
+ ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
64
+ if (ret < 0) {
65
+ error_setg_errno(errp, -ret, "Could not refresh total sector count");
66
+ } else {
67
+ offset = bs->total_sectors * BDRV_SECTOR_SIZE;
68
}
69
+ bdrv_dirty_bitmap_truncate(bs, offset);
70
+ bdrv_parent_cb_resize(bs);
71
+ atomic_inc(&bs->write_gen);
72
return ret;
73
}
74
75
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/block/dirty-bitmap.c
78
+++ b/block/dirty-bitmap.c
79
@@ -XXX,XX +XXX,XX @@
80
/*
81
* Block Dirty Bitmap
82
*
83
- * Copyright (c) 2016 Red Hat. Inc
84
+ * Copyright (c) 2016-2017 Red Hat. Inc
85
*
86
* Permission is hereby granted, free of charge, to any person obtaining a copy
87
* of this software and associated documentation files (the "Software"), to deal
88
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
89
* Truncates _all_ bitmaps attached to a BDS.
90
* Called with BQL taken.
91
*/
92
-void bdrv_dirty_bitmap_truncate(BlockDriverState *bs)
93
+void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
94
{
95
BdrvDirtyBitmap *bitmap;
96
- uint64_t size = bdrv_nb_sectors(bs);
97
+ int64_t size = DIV_ROUND_UP(bytes, BDRV_SECTOR_SIZE);
98
99
bdrv_dirty_bitmaps_lock(bs);
100
QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
101
--
102
2.13.6
103
104
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We're already reporting bytes for bdrv_dirty_bitmap_granularity();
4
mixing bytes and sectors in our return values is a recipe for
5
confusion. A later cleanup will convert dirty bitmap internals
6
to be entirely byte-based, but in the meantime, we should report
7
the bitmap size in bytes.
8
9
The only external caller in qcow2-bitmap.c is temporarily more verbose
10
(because it is still using sector-based math), but will later be
11
switched to track progress by bytes instead of sectors.
12
13
Signed-off-by: Eric Blake <eblake@redhat.com>
14
Reviewed-by: John Snow <jsnow@redhat.com>
15
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
16
Reviewed-by: Fam Zheng <famz@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block/dirty-bitmap.c | 2 +-
20
block/qcow2-bitmap.c | 14 ++++++++------
21
2 files changed, 9 insertions(+), 7 deletions(-)
22
23
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block/dirty-bitmap.c
26
+++ b/block/dirty-bitmap.c
27
@@ -XXX,XX +XXX,XX @@ void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
28
29
int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
30
{
31
- return bitmap->size;
32
+ return bitmap->size * BDRV_SECTOR_SIZE;
33
}
34
35
const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
36
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/block/qcow2-bitmap.c
39
+++ b/block/qcow2-bitmap.c
40
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
41
BDRVQcow2State *s = bs->opaque;
42
uint64_t sector, sbc;
43
uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
44
+ uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
45
uint8_t *buf = NULL;
46
uint64_t i, tab_size =
47
size_to_clusters(s,
48
- bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size));
49
+ bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_sectors));
50
51
if (tab_size != bitmap_table_size || tab_size > BME_MAX_TABLE_SIZE) {
52
return -EINVAL;
53
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
54
buf = g_malloc(s->cluster_size);
55
sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
56
for (i = 0, sector = 0; i < tab_size; ++i, sector += sbc) {
57
- uint64_t count = MIN(bm_size - sector, sbc);
58
+ uint64_t count = MIN(bm_sectors - sector, sbc);
59
uint64_t entry = bitmap_table[i];
60
uint64_t offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;
61
62
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
63
int64_t sector;
64
uint64_t sbc;
65
uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
66
+ uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
67
const char *bm_name = bdrv_dirty_bitmap_name(bitmap);
68
uint8_t *buf = NULL;
69
BdrvDirtyBitmapIter *dbi;
70
uint64_t *tb;
71
uint64_t tb_size =
72
size_to_clusters(s,
73
- bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size));
74
+ bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_sectors));
75
76
if (tb_size > BME_MAX_TABLE_SIZE ||
77
tb_size * s->cluster_size > BME_MAX_PHYS_SIZE)
78
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
79
dbi = bdrv_dirty_iter_new(bitmap, 0);
80
buf = g_malloc(s->cluster_size);
81
sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
82
- assert(DIV_ROUND_UP(bm_size, sbc) == tb_size);
83
+ assert(DIV_ROUND_UP(bm_sectors, sbc) == tb_size);
84
85
while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
86
uint64_t cluster = sector / sbc;
87
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
88
int64_t off;
89
90
sector = cluster * sbc;
91
- end = MIN(bm_size, sector + sbc);
92
+ end = MIN(bm_sectors, sector + sbc);
93
write_size =
94
bdrv_dirty_bitmap_serialization_size(bitmap, sector, end - sector);
95
assert(write_size <= s->cluster_size);
96
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
97
goto fail;
98
}
99
100
- if (end >= bm_size) {
101
+ if (end >= bm_sectors) {
102
break;
103
}
104
105
--
106
2.13.6
107
108
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are still using an internal hbitmap that tracks a size in sectors,
4
with the granularity scaled down accordingly, because it lets us
5
use a shortcut for our iterators which are currently sector-based.
6
But there's no reason we can't track the dirty bitmap size in bytes,
7
since it is (mostly) an internal-only variable (remember, the size
8
is how many bytes are covered by the bitmap, not how many bytes the
9
bitmap occupies). A later cleanup will convert dirty bitmap
10
internals to be entirely byte-based, eliminating the intermediate
11
sector rounding added here; and technically, since bdrv_getlength()
12
already rounds up to sectors, our use of DIV_ROUND_UP is more for
13
theoretical completeness than for any actual rounding.
14
15
Use is_power_of_2() while at it, instead of open-coding that.
16
17
Signed-off-by: Eric Blake <eblake@redhat.com>
18
Reviewed-by: John Snow <jsnow@redhat.com>
19
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
20
Reviewed-by: Fam Zheng <famz@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
23
block/dirty-bitmap.c | 26 ++++++++++++++------------
24
1 file changed, 14 insertions(+), 12 deletions(-)
25
26
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/block/dirty-bitmap.c
29
+++ b/block/dirty-bitmap.c
30
@@ -XXX,XX +XXX,XX @@ struct BdrvDirtyBitmap {
31
HBitmap *meta; /* Meta dirty bitmap */
32
BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
33
char *name; /* Optional non-empty unique ID */
34
- int64_t size; /* Size of the bitmap (Number of sectors) */
35
+ int64_t size; /* Size of the bitmap, in bytes */
36
bool disabled; /* Bitmap is disabled. It ignores all writes to
37
the device */
38
int active_iterators; /* How many iterators are active */
39
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
40
{
41
int64_t bitmap_size;
42
BdrvDirtyBitmap *bitmap;
43
- uint32_t sector_granularity;
44
45
- assert((granularity & (granularity - 1)) == 0);
46
+ assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
47
48
if (name && bdrv_find_dirty_bitmap(bs, name)) {
49
error_setg(errp, "Bitmap already exists: %s", name);
50
return NULL;
51
}
52
- sector_granularity = granularity >> BDRV_SECTOR_BITS;
53
- assert(sector_granularity);
54
- bitmap_size = bdrv_nb_sectors(bs);
55
+ bitmap_size = bdrv_getlength(bs);
56
if (bitmap_size < 0) {
57
error_setg_errno(errp, -bitmap_size, "could not get length of device");
58
errno = -bitmap_size;
59
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
60
}
61
bitmap = g_new0(BdrvDirtyBitmap, 1);
62
bitmap->mutex = &bs->dirty_bitmap_mutex;
63
- bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
64
+ /*
65
+ * TODO - let hbitmap track full granularity. For now, it is tracking
66
+ * only sector granularity, as a shortcut for our iterators.
67
+ */
68
+ bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap_size, BDRV_SECTOR_SIZE),
69
+ ctz32(granularity) - BDRV_SECTOR_BITS);
70
bitmap->size = bitmap_size;
71
bitmap->name = g_strdup(name);
72
bitmap->disabled = false;
73
@@ -XXX,XX +XXX,XX @@ void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
74
75
int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
76
{
77
- return bitmap->size * BDRV_SECTOR_SIZE;
78
+ return bitmap->size;
79
}
80
81
const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
82
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
83
void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
84
{
85
BdrvDirtyBitmap *bitmap;
86
- int64_t size = DIV_ROUND_UP(bytes, BDRV_SECTOR_SIZE);
87
88
bdrv_dirty_bitmaps_lock(bs);
89
QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
90
assert(!bdrv_dirty_bitmap_frozen(bitmap));
91
assert(!bitmap->active_iterators);
92
- hbitmap_truncate(bitmap->bitmap, size);
93
- bitmap->size = size;
94
+ hbitmap_truncate(bitmap->bitmap, DIV_ROUND_UP(bytes, BDRV_SECTOR_SIZE));
95
+ bitmap->size = bytes;
96
}
97
bdrv_dirty_bitmaps_unlock(bs);
98
}
99
@@ -XXX,XX +XXX,XX @@ void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
100
hbitmap_reset_all(bitmap->bitmap);
101
} else {
102
HBitmap *backup = bitmap->bitmap;
103
- bitmap->bitmap = hbitmap_alloc(bitmap->size,
104
+ bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap->size,
105
+ BDRV_SECTOR_SIZE),
106
hbitmap_granularity(backup));
107
*out = backup;
108
}
109
--
110
2.13.6
111
112
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
3
Backing files and raw external data files are mutually exclusive.
4
The documentation of the raw external data bit (in autoclear_features)
5
already indicates that, but we should also mention it on the other
6
side.
7
8
Suggested-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Alberto Garcia <berto@igalia.com>
10
Message-Id: <20200410121816.8334-1-berto@igalia.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
13
---
7
tests/qemu-iotests/check | 4 ++--
14
docs/interop/qcow2.txt | 3 +++
8
tests/qemu-iotests/common | 2 +-
15
1 file changed, 3 insertions(+)
9
tests/qemu-iotests/common.config | 3 ---
10
3 files changed, 3 insertions(+), 6 deletions(-)
11
16
12
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
17
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
13
index XXXXXXX..XXXXXXX 100755
14
--- a/tests/qemu-iotests/check
15
+++ b/tests/qemu-iotests/check
16
@@ -XXX,XX +XXX,XX @@ tmp="${TEST_DIR}"/$$
17
18
_wallclock()
19
{
20
- date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }'
21
+ date "+%H %M %S" | awk '{ print $1*3600 + $2*60 + $3 }'
22
}
23
24
_timestamp()
25
@@ -XXX,XX +XXX,XX @@ _wrapup()
26
if [ -f $TIMESTAMP_FILE -a -f $tmp.time ]
27
then
28
cat $TIMESTAMP_FILE $tmp.time \
29
- | $AWK_PROG '
30
+ | awk '
31
{ t[$1] = $2 }
32
END { if (NR > 0) {
33
for (i in t) print i " " t[i]
34
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
35
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
36
--- a/tests/qemu-iotests/common
19
--- a/docs/interop/qcow2.txt
37
+++ b/tests/qemu-iotests/common
20
+++ b/docs/interop/qcow2.txt
38
@@ -XXX,XX +XXX,XX @@ testlist options
21
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
39
if $xpand
22
is stored (NB: The string is not null terminated). 0 if the
40
then
23
image doesn't have a backing file.
41
have_test_arg=true
24
42
- $AWK_PROG </dev/null '
25
+ Note: backing files are incompatible with raw external data
43
+ awk </dev/null '
26
+ files (auto-clear feature bit 1).
44
BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
27
+
45
| while read id
28
16 - 19: backing_file_size
46
do
29
Length of the backing file name in bytes. Must not be
47
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
30
longer than 1023 bytes. Undefined if the image doesn't have
48
index XXXXXXX..XXXXXXX 100644
49
--- a/tests/qemu-iotests/common.config
50
+++ b/tests/qemu-iotests/common.config
51
@@ -XXX,XX +XXX,XX @@ _fatal()
52
exit 1
53
}
54
55
-export AWK_PROG="`set_prog_path awk`"
56
-[ "$AWK_PROG" = "" ] && _fatal "awk not found"
57
-
58
if [ -z "$QEMU_PROG" ]; then
59
export QEMU_PROG="`set_prog_path qemu`"
60
fi
61
--
31
--
62
2.13.6
32
2.25.3
63
33
64
34
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
This includes shell function, shell variables and command line options
3
Test 244 checks the expected behavior of qcow2 external data files
4
(randomize.awk does not exist).
4
with respect to zero and discarded clusters. Filesystems however
5
are free to ignore discard requests, and this seems to be the
6
case for overlayfs. Relax the tests to skip checks on the
7
external data file for discarded areas, which implies not using
8
qemu-img compare in the data_file_raw=on case.
5
9
10
This fixes docker tests on RHEL8.
11
12
Cc: Kevin Wolf <kwolf@redhat.com>
13
Cc: qemu-block@nongnu.org
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
14
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
15
Message-Id: <20200409191006.24429-1-pbonzini@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
17
---
10
tests/qemu-iotests/check | 28 -----------------
18
tests/qemu-iotests/244 | 10 ++++++++--
11
tests/qemu-iotests/common | 23 --------------
19
tests/qemu-iotests/244.out | 9 ++++++---
12
tests/qemu-iotests/common.config | 26 ---------------
20
2 files changed, 14 insertions(+), 5 deletions(-)
13
tests/qemu-iotests/common.rc | 68 ----------------------------------------
14
4 files changed, 145 deletions(-)
15
21
16
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
22
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
17
index XXXXXXX..XXXXXXX 100755
23
index XXXXXXX..XXXXXXX 100755
18
--- a/tests/qemu-iotests/check
24
--- a/tests/qemu-iotests/244
19
+++ b/tests/qemu-iotests/check
25
+++ b/tests/qemu-iotests/244
20
@@ -XXX,XX +XXX,XX @@ then
26
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
21
export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
27
echo
22
fi
28
$QEMU_IO -c 'read -P 0 0 1M' \
23
29
-c 'read -P 0x11 1M 1M' \
24
-# if ./qemu exists, it should be prioritized and will be chosen by common.config
30
- -c 'read -P 0 2M 2M' \
25
if [[ -z "$QEMU_PROG" && ! -x './qemu' ]]
31
-c 'read -P 0x11 4M 1M' \
26
then
32
-c 'read -P 0 5M 1M' \
27
arch=$(uname -m 2> /dev/null)
33
-f raw "$TEST_IMG.data" |
28
@@ -XXX,XX +XXX,XX @@ _timestamp()
34
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
29
35
-f $IMGFMT "$TEST_IMG" |
30
_wrapup()
36
_filter_qemu_io
31
{
37
32
- # for hangcheck ...
38
+# Discarded clusters are only marked as such in the qcow2 metadata, but
33
- # remove files that were used by hangcheck
39
+# they can contain stale data in the external data file. Instead, zero
34
- #
40
+# clusters must be zeroed in the external data file too.
35
- [ -f "${TEST_DIR}"/check.pid ] && rm -rf "${TEST_DIR}"/check.pid
41
echo
36
- [ -f "${TEST_DIR}"/check.sts ] && rm -rf "${TEST_DIR}"/check.sts
42
-$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.data"
37
-
43
+$QEMU_IO -c 'read -P 0 0 1M' \
38
if $showme
44
+ -c 'read -P 0x11 1M 1M' \
39
then
45
+ -c 'read -P 0 3M 3M' \
40
:
46
+ -f raw "$TEST_IMG".data |
41
@@ -XXX,XX +XXX,XX @@ END { if (NR > 0) {
47
+ _filter_qemu_io
42
48
43
trap "_wrapup; exit \$status" 0 1 2 3 15
49
echo -n "qcow2 file size after I/O: "
44
50
du -b $TEST_IMG | cut -f1
45
-# for hangcheck ...
51
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
46
-# Save pid of check in a well known place, so that hangcheck can be sure it
47
-# has the right pid (getting the pid from ps output is not reliable enough).
48
-#
49
-rm -rf "${TEST_DIR}"/check.pid
50
-echo $$ > "${TEST_DIR}"/check.pid
51
-
52
-# for hangcheck ...
53
-# Save the status of check in a well known place, so that hangcheck can be
54
-# sure to know where check is up to (getting test number from ps output is
55
-# not reliable enough since the trace stuff has been introduced).
56
-#
57
-rm -rf "${TEST_DIR}"/check.sts
58
-echo "preamble" > "${TEST_DIR}"/check.sts
59
-
60
-# don't leave old full output behind on a clean run
61
-rm -f check.full
62
-
63
[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
64
65
FULL_IMGFMT_DETAILS=`_full_imgfmt_details`
66
@@ -XXX,XX +XXX,XX @@ do
67
fi
68
rm -f core $seq.notrun
69
70
- # for hangcheck ...
71
- echo "$seq" > "${TEST_DIR}"/check.sts
72
-
73
start=`_wallclock`
74
$timestamp && printf %s " [$(date "+%T")]"
75
76
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
77
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
78
--- a/tests/qemu-iotests/common
53
--- a/tests/qemu-iotests/244.out
79
+++ b/tests/qemu-iotests/common
54
+++ b/tests/qemu-iotests/244.out
80
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 0
81
# common procedures for QA scripts
56
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
82
#
57
read 1048576/1048576 bytes at offset 1048576
83
58
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
84
-_setenvironment()
59
-read 2097152/2097152 bytes at offset 2097152
85
-{
60
-2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
86
- MSGVERB="text:action"
61
read 1048576/1048576 bytes at offset 4194304
87
- export MSGVERB
62
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
88
-}
63
read 1048576/1048576 bytes at offset 5242880
89
-
64
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
90
-rm -f "$OUTPUT_DIR/$iam.out"
65
read 4194304/4194304 bytes at offset 2097152
91
-_setenvironment
66
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
92
-
67
93
-check=${check-true}
68
-Images are identical.
94
-
69
+read 1048576/1048576 bytes at offset 0
95
diff="diff -u"
70
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
96
verbose=false
71
+read 1048576/1048576 bytes at offset 1048576
97
debug=false
72
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
98
@@ -XXX,XX +XXX,XX @@ showme=false
73
+read 3145728/3145728 bytes at offset 3145728
99
sortme=false
74
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
100
expunge=true
75
qcow2 file size after I/O: 327680
101
have_test_arg=false
76
102
-randomize=false
77
=== bdrv_co_block_status test for file and offset=0 ===
103
cachemode=false
104
rm -f $tmp.list $tmp.tmp $tmp.sed
105
106
@@ -XXX,XX +XXX,XX @@ other options
107
-n show me, do not run tests
108
-o options -o options to pass to qemu-img create/convert
109
-T output timestamps
110
- -r randomize test order
111
-c mode cache mode
112
113
testlist options
114
@@ -XXX,XX +XXX,XX @@ testlist options
115
cachemode=true
116
xpand=false
117
;;
118
- -r) # randomize test order
119
- randomize=true
120
- xpand=false
121
- ;;
122
-
123
-T) # turn on timestamp output
124
timestamp=true
125
xpand=false
126
@@ -XXX,XX +XXX,XX @@ fi
127
list=`sort $tmp.list`
128
rm -f $tmp.list $tmp.tmp $tmp.sed
129
130
-if $randomize
131
-then
132
- list=`echo $list | awk -f randomize.awk`
133
-fi
134
-
135
[ "$QEMU" = "" ] && _fatal "qemu not found"
136
[ "$QEMU_IMG" = "" ] && _fatal "qemu-img not found"
137
[ "$QEMU_IO" = "" ] && _fatal "qemu-io not found"
138
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
139
index XXXXXXX..XXXXXXX 100644
140
--- a/tests/qemu-iotests/common.config
141
+++ b/tests/qemu-iotests/common.config
142
@@ -XXX,XX +XXX,XX @@
143
# You should have received a copy of the GNU General Public License
144
# along with this program. If not, see <http://www.gnu.org/licenses/>.
145
#
146
-#
147
-# setup and check for config parameters, and in particular
148
-#
149
-# EMAIL - email of the script runner.
150
-# TEST_DIR - scratch test directory
151
-#
152
-# - These can be added to $HOST_CONFIG_DIR (witch default to ./config)
153
-# below or a separate local configuration file can be used (using
154
-# the HOST_OPTIONS variable).
155
-# - This script is shared by the stress test system and the auto-qa
156
-# system (includes both regression test and benchmark components).
157
-# - this script shouldn't make any assertions about filesystem
158
-# validity or mountedness.
159
-#
160
-
161
# all tests should use a common language setting to prevent golden
162
# output mismatches.
163
export LANG=C
164
165
PATH=".:$PATH"
166
167
-HOST=`hostname -s 2> /dev/null`
168
HOSTOS=`uname -s`
169
170
-EMAIL=root@localhost # where auto-qa will send its status messages
171
-export HOST_OPTIONS=${HOST_OPTIONS:=local.config}
172
-export CHECK_OPTIONS=${CHECK_OPTIONS:="-g auto"}
173
export PWD=`pwd`
174
175
export _QEMU_HANDLE=0
176
@@ -XXX,XX +XXX,XX @@ _fatal()
177
export AWK_PROG="`set_prog_path awk`"
178
[ "$AWK_PROG" = "" ] && _fatal "awk not found"
179
180
-export SED_PROG="`set_prog_path sed`"
181
-[ "$SED_PROG" = "" ] && _fatal "sed not found"
182
-
183
-export PS_ALL_FLAGS="-ef"
184
-
185
if [ -z "$QEMU_PROG" ]; then
186
export QEMU_PROG="`set_prog_path qemu`"
187
fi
188
@@ -XXX,XX +XXX,XX @@ fi
189
190
export QEMU_DEFAULT_MACHINE="$default_machine"
191
192
-[ -f /etc/qemu-iotest.config ] && . /etc/qemu-iotest.config
193
-
194
if [ -z "$TEST_DIR" ]; then
195
TEST_DIR=`pwd`/scratch
196
fi
197
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
198
index XXXXXXX..XXXXXXX 100644
199
--- a/tests/qemu-iotests/common.rc
200
+++ b/tests/qemu-iotests/common.rc
201
@@ -XXX,XX +XXX,XX @@ _img_info()
202
done
203
}
204
205
-_get_pids_by_name()
206
-{
207
- if [ $# -ne 1 ]
208
- then
209
- echo "Usage: _get_pids_by_name process-name" 1>&2
210
- exit 1
211
- fi
212
-
213
- # Algorithm ... all ps(1) variants have a time of the form MM:SS or
214
- # HH:MM:SS before the psargs field, use this as the search anchor.
215
- #
216
- # Matches with $1 (process-name) occur if the first psarg is $1
217
- # or ends in /$1 ... the matching uses sed's regular expressions,
218
- # so passing a regex into $1 will work.
219
-
220
- ps $PS_ALL_FLAGS \
221
- | sed -n \
222
- -e 's/$/ /' \
223
- -e 's/[ ][ ]*/ /g' \
224
- -e 's/^ //' \
225
- -e 's/^[^ ]* //' \
226
- -e "/[0-9]:[0-9][0-9] *[^ ]*\/$1 /s/ .*//p" \
227
- -e "/[0-9]:[0-9][0-9] *$1 /s/ .*//p"
228
-}
229
-
230
-# fqdn for localhost
231
-#
232
-_get_fqdn()
233
-{
234
- host=`hostname`
235
- $NSLOOKUP_PROG $host | $AWK_PROG '{ if ($1 == "Name:") print $2 }'
236
-}
237
-
238
-# check if run as root
239
-#
240
-_need_to_be_root()
241
-{
242
- id=`id | $SED_PROG -e 's/(.*//' -e 's/.*=//'`
243
- if [ "$id" -ne 0 ]
244
- then
245
- echo "Arrgh ... you need to be root (not uid=$id) to run this test"
246
- exit 1
247
- fi
248
-}
249
-
250
# bail out, setting up .notrun file
251
#
252
_notrun()
253
@@ -XXX,XX +XXX,XX @@ _full_platform_details()
254
echo "$os/$platform $host $kernel"
255
}
256
257
-_link_out_file()
258
-{
259
- if [ -z "$1" ]; then
260
- echo Error must pass \$seq.
261
- exit
262
- fi
263
- rm -f $1
264
- if [ "`uname`" == "IRIX64" ] || [ "`uname`" == "IRIX" ]; then
265
- ln -s $1.irix $1
266
- elif [ "`uname`" == "Linux" ]; then
267
- ln -s $1.linux $1
268
- else
269
- echo Error test $seq does not run on the operating system: `uname`
270
- exit
271
- fi
272
-}
273
-
274
-_die()
275
-{
276
- echo $@
277
- exit 1
278
-}
279
-
280
# make sure this script returns success
281
true
282
--
78
--
283
2.13.6
79
2.25.3
284
80
285
81
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
This adds a new BdrvRequestFlags parameter to the .bdrv_co_truncate()
2
2
driver callbacks, and a supported_truncate_flags field in
3
Both callers already had bytes available, but were scaling to
3
BlockDriverState that allows drivers to advertise support for request
4
sectors. Move the scaling to internal code. In the case of
4
flags in the context of truncate.
5
bdrv_aligned_pwritev(), we are now passing the exact offset
5
6
rather than a rounded sector-aligned value, but that's okay
6
For now, we always pass 0 and no drivers declare support for any flag.
7
as long as dirty bitmap widens start/bytes to granularity
7
8
boundaries.
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Signed-off-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Alberto Garcia <berto@igalia.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20200424125448.63318-2-kwolf@redhat.com>
13
Reviewed-by: Fam Zheng <famz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
14
---
16
include/block/block_int.h | 2 +-
15
include/block/block_int.h | 10 +++++++++-
17
block/dirty-bitmap.c | 7 ++++---
16
block/crypto.c | 3 ++-
18
block/io.c | 6 ++----
17
block/file-posix.c | 2 +-
19
3 files changed, 7 insertions(+), 8 deletions(-)
18
block/file-win32.c | 2 +-
19
block/gluster.c | 1 +
20
block/io.c | 8 +++++++-
21
block/iscsi.c | 2 +-
22
block/nfs.c | 3 ++-
23
block/qcow2.c | 2 +-
24
block/qed.c | 1 +
25
block/raw-format.c | 2 +-
26
block/rbd.c | 1 +
27
block/sheepdog.c | 4 ++--
28
block/ssh.c | 2 +-
29
tests/test-block-iothread.c | 3 ++-
30
15 files changed, 33 insertions(+), 13 deletions(-)
20
31
21
diff --git a/include/block/block_int.h b/include/block/block_int.h
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
22
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
23
--- a/include/block/block_int.h
34
--- a/include/block/block_int.h
24
+++ b/include/block/block_int.h
35
+++ b/include/block/block_int.h
25
@@ -XXX,XX +XXX,XX @@ void blk_dev_eject_request(BlockBackend *blk, bool force);
36
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
26
bool blk_dev_is_tray_open(BlockBackend *blk);
37
*/
27
bool blk_dev_is_medium_locked(BlockBackend *blk);
38
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
28
39
bool exact, PreallocMode prealloc,
29
-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int64_t nr_sect);
40
- Error **errp);
30
+void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes);
41
+ BdrvRequestFlags flags, Error **errp);
31
bool bdrv_requests_pending(BlockDriverState *bs);
42
32
43
int64_t (*bdrv_getlength)(BlockDriverState *bs);
33
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
44
bool has_variable_length;
34
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
35
index XXXXXXX..XXXXXXX 100644
46
/* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
36
--- a/block/dirty-bitmap.c
47
* BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
37
+++ b/block/dirty-bitmap.c
48
unsigned int supported_zero_flags;
38
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
49
+ /*
39
hbitmap_deserialize_finish(bitmap->bitmap);
50
+ * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
40
}
51
+ *
41
52
+ * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
42
-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
53
+ * that any added space reads as all zeros. If this can't be guaranteed,
43
- int64_t nr_sectors)
54
+ * the operation must fail.
44
+void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
55
+ */
45
{
56
+ unsigned int supported_truncate_flags;
46
BdrvDirtyBitmap *bitmap;
57
47
+ int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
58
/* the following member gives a name to every node on the bs graph. */
48
59
char node_name[32];
49
if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
60
diff --git a/block/crypto.c b/block/crypto.c
50
return;
61
index XXXXXXX..XXXXXXX 100644
51
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
62
--- a/block/crypto.c
52
continue;
63
+++ b/block/crypto.c
53
}
64
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
54
assert(!bdrv_dirty_bitmap_readonly(bitmap));
65
55
- hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
66
static int coroutine_fn
56
+ hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
67
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
57
+ end_sector - (offset >> BDRV_SECTOR_BITS));
68
- PreallocMode prealloc, Error **errp)
58
}
69
+ PreallocMode prealloc, BdrvRequestFlags flags,
59
bdrv_dirty_bitmaps_unlock(bs);
70
+ Error **errp)
60
}
71
{
72
BlockCrypto *crypto = bs->opaque;
73
uint64_t payload_offset =
74
diff --git a/block/file-posix.c b/block/file-posix.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/file-posix.c
77
+++ b/block/file-posix.c
78
@@ -XXX,XX +XXX,XX @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
79
80
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
81
bool exact, PreallocMode prealloc,
82
- Error **errp)
83
+ BdrvRequestFlags flags, Error **errp)
84
{
85
BDRVRawState *s = bs->opaque;
86
struct stat st;
87
diff --git a/block/file-win32.c b/block/file-win32.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/file-win32.c
90
+++ b/block/file-win32.c
91
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
92
93
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
94
bool exact, PreallocMode prealloc,
95
- Error **errp)
96
+ BdrvRequestFlags flags, Error **errp)
97
{
98
BDRVRawState *s = bs->opaque;
99
LONG low, high;
100
diff --git a/block/gluster.c b/block/gluster.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/block/gluster.c
103
+++ b/block/gluster.c
104
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
105
int64_t offset,
106
bool exact,
107
PreallocMode prealloc,
108
+ BdrvRequestFlags flags,
109
Error **errp)
110
{
111
BDRVGlusterState *s = bs->opaque;
61
diff --git a/block/io.c b/block/io.c
112
diff --git a/block/io.c b/block/io.c
62
index XXXXXXX..XXXXXXX 100644
113
index XXXXXXX..XXXXXXX 100644
63
--- a/block/io.c
114
--- a/block/io.c
64
+++ b/block/io.c
115
+++ b/block/io.c
65
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
66
bool waited;
117
BlockDriverState *bs = child->bs;
118
BlockDriver *drv = bs->drv;
119
BdrvTrackedRequest req;
120
+ BdrvRequestFlags flags = 0;
121
int64_t old_size, new_bytes;
67
int ret;
122
int ret;
68
123
69
- int64_t start_sector = offset >> BDRV_SECTOR_BITS;
124
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
70
int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
125
}
71
uint64_t bytes_remaining = bytes;
126
72
int max_transfer;
127
if (drv->bdrv_co_truncate) {
73
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
128
- ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
74
bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
129
+ if (flags & ~bs->supported_truncate_flags) {
75
130
+ error_setg(errp, "Block driver does not support requested flags");
76
atomic_inc(&bs->write_gen);
131
+ ret = -ENOTSUP;
77
- bdrv_set_dirty(bs, start_sector, end_sector - start_sector);
132
+ goto out;
78
+ bdrv_set_dirty(bs, offset, bytes);
133
+ }
79
134
+ ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
80
stat64_max(&bs->wr_highest_offset, offset + bytes);
135
} else if (bs->file && drv->is_filter) {
81
136
ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
82
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
137
} else {
83
ret = 0;
138
diff --git a/block/iscsi.c b/block/iscsi.c
84
out:
139
index XXXXXXX..XXXXXXX 100644
85
atomic_inc(&bs->write_gen);
140
--- a/block/iscsi.c
86
- bdrv_set_dirty(bs, req.offset >> BDRV_SECTOR_BITS,
141
+++ b/block/iscsi.c
87
- req.bytes >> BDRV_SECTOR_BITS);
142
@@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
88
+ bdrv_set_dirty(bs, req.offset, req.bytes);
143
89
tracked_request_end(&req);
144
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
90
bdrv_dec_in_flight(bs);
145
bool exact, PreallocMode prealloc,
91
return ret;
146
- Error **errp)
147
+ BdrvRequestFlags flags, Error **errp)
148
{
149
IscsiLun *iscsilun = bs->opaque;
150
int64_t cur_length;
151
diff --git a/block/nfs.c b/block/nfs.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/block/nfs.c
154
+++ b/block/nfs.c
155
@@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
156
157
static int coroutine_fn
158
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
159
- PreallocMode prealloc, Error **errp)
160
+ PreallocMode prealloc, BdrvRequestFlags flags,
161
+ Error **errp)
162
{
163
NFSClient *client = bs->opaque;
164
int ret;
165
diff --git a/block/qcow2.c b/block/qcow2.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/block/qcow2.c
168
+++ b/block/qcow2.c
169
@@ -XXX,XX +XXX,XX @@ fail:
170
171
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
172
bool exact, PreallocMode prealloc,
173
- Error **errp)
174
+ BdrvRequestFlags flags, Error **errp)
175
{
176
BDRVQcow2State *s = bs->opaque;
177
uint64_t old_length;
178
diff --git a/block/qed.c b/block/qed.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/qed.c
181
+++ b/block/qed.c
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
183
int64_t offset,
184
bool exact,
185
PreallocMode prealloc,
186
+ BdrvRequestFlags flags,
187
Error **errp)
188
{
189
BDRVQEDState *s = bs->opaque;
190
diff --git a/block/raw-format.c b/block/raw-format.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/block/raw-format.c
193
+++ b/block/raw-format.c
194
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
195
196
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
197
bool exact, PreallocMode prealloc,
198
- Error **errp)
199
+ BdrvRequestFlags flags, Error **errp)
200
{
201
BDRVRawState *s = bs->opaque;
202
203
diff --git a/block/rbd.c b/block/rbd.c
204
index XXXXXXX..XXXXXXX 100644
205
--- a/block/rbd.c
206
+++ b/block/rbd.c
207
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
208
int64_t offset,
209
bool exact,
210
PreallocMode prealloc,
211
+ BdrvRequestFlags flags,
212
Error **errp)
213
{
214
int r;
215
diff --git a/block/sheepdog.c b/block/sheepdog.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/block/sheepdog.c
218
+++ b/block/sheepdog.c
219
@@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs)
220
221
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
222
bool exact, PreallocMode prealloc,
223
- Error **errp)
224
+ BdrvRequestFlags flags, Error **errp)
225
{
226
BDRVSheepdogState *s = bs->opaque;
227
int ret, fd;
228
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
229
230
assert(!flags);
231
if (offset > s->inode.vdi_size) {
232
- ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
233
+ ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
234
if (ret < 0) {
235
return ret;
236
}
237
diff --git a/block/ssh.c b/block/ssh.c
238
index XXXXXXX..XXXXXXX 100644
239
--- a/block/ssh.c
240
+++ b/block/ssh.c
241
@@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs)
242
243
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
244
bool exact, PreallocMode prealloc,
245
- Error **errp)
246
+ BdrvRequestFlags flags, Error **errp)
247
{
248
BDRVSSHState *s = bs->opaque;
249
250
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
251
index XXXXXXX..XXXXXXX 100644
252
--- a/tests/test-block-iothread.c
253
+++ b/tests/test-block-iothread.c
254
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
255
256
static int coroutine_fn
257
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
258
- PreallocMode prealloc, Error **errp)
259
+ PreallocMode prealloc, BdrvRequestFlags flags,
260
+ Error **errp)
261
{
262
return 0;
263
}
92
--
264
--
93
2.13.6
265
2.25.3
94
266
95
267
diff view generated by jsdifflib
1
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
1
Now that block drivers can support flags for .bdrv_co_truncate, expose
2
the parameter in the node level interfaces bdrv_co_truncate() and
3
bdrv_truncate().
2
4
3
Now after shrinking the image, at the end of the image file, there might be a
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
tail that probably will never be used. So we can find the last used cluster and
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
cut the tail.
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-Id: <20200424125448.63318-3-kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
include/block/block.h | 5 +++--
13
block/block-backend.c | 2 +-
14
block/crypto.c | 2 +-
15
block/io.c | 12 +++++++-----
16
block/parallels.c | 6 +++---
17
block/qcow.c | 4 ++--
18
block/qcow2-refcount.c | 2 +-
19
block/qcow2.c | 15 +++++++++------
20
block/raw-format.c | 2 +-
21
block/vhdx-log.c | 2 +-
22
block/vhdx.c | 2 +-
23
block/vmdk.c | 2 +-
24
tests/test-block-iothread.c | 6 +++---
25
13 files changed, 34 insertions(+), 28 deletions(-)
6
26
7
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
27
diff --git a/include/block/block.h b/include/block/block.h
8
Reviewed-by: John Snow <jsnow@redhat.com>
28
index XXXXXXX..XXXXXXX 100644
9
Message-id: 20170929121613.25997-3-pbutsykin@virtuozzo.com
29
--- a/include/block/block.h
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
30
+++ b/include/block/block.h
11
---
31
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
12
block/qcow2.h | 1 +
32
void bdrv_refresh_filename(BlockDriverState *bs);
13
block/qcow2-refcount.c | 22 ++++++++++++++++++++++
33
14
block/qcow2.c | 23 +++++++++++++++++++++++
34
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
15
3 files changed, 46 insertions(+)
35
- PreallocMode prealloc, Error **errp);
16
36
+ PreallocMode prealloc, BdrvRequestFlags flags,
17
diff --git a/block/qcow2.h b/block/qcow2.h
37
+ Error **errp);
18
index XXXXXXX..XXXXXXX 100644
38
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
19
--- a/block/qcow2.h
39
- PreallocMode prealloc, Error **errp);
20
+++ b/block/qcow2.h
40
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
21
@@ -XXX,XX +XXX,XX @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
41
22
BlockDriverAmendStatusCB *status_cb,
42
int64_t bdrv_nb_sectors(BlockDriverState *bs);
23
void *cb_opaque, Error **errp);
43
int64_t bdrv_getlength(BlockDriverState *bs);
24
int qcow2_shrink_reftable(BlockDriverState *bs);
44
diff --git a/block/block-backend.c b/block/block-backend.c
25
+int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
45
index XXXXXXX..XXXXXXX 100644
26
46
--- a/block/block-backend.c
27
/* qcow2-cluster.c functions */
47
+++ b/block/block-backend.c
28
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
48
@@ -XXX,XX +XXX,XX @@ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
49
return -ENOMEDIUM;
50
}
51
52
- return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
53
+ return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
54
}
55
56
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
57
diff --git a/block/crypto.c b/block/crypto.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/crypto.c
60
+++ b/block/crypto.c
61
@@ -XXX,XX +XXX,XX @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
62
63
offset += payload_offset;
64
65
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
66
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
67
}
68
69
static void block_crypto_close(BlockDriverState *bs)
70
diff --git a/block/io.c b/block/io.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/io.c
73
+++ b/block/io.c
74
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
75
* 'offset' bytes in length.
76
*/
77
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
78
- PreallocMode prealloc, Error **errp)
79
+ PreallocMode prealloc, BdrvRequestFlags flags,
80
+ Error **errp)
81
{
82
BlockDriverState *bs = child->bs;
83
BlockDriver *drv = bs->drv;
84
BdrvTrackedRequest req;
85
- BdrvRequestFlags flags = 0;
86
int64_t old_size, new_bytes;
87
int ret;
88
89
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
90
}
91
ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
92
} else if (bs->file && drv->is_filter) {
93
- ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
94
+ ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
95
} else {
96
error_setg(errp, "Image format driver does not support resize");
97
ret = -ENOTSUP;
98
@@ -XXX,XX +XXX,XX @@ typedef struct TruncateCo {
99
int64_t offset;
100
bool exact;
101
PreallocMode prealloc;
102
+ BdrvRequestFlags flags;
103
Error **errp;
104
int ret;
105
} TruncateCo;
106
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
107
{
108
TruncateCo *tco = opaque;
109
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
110
- tco->prealloc, tco->errp);
111
+ tco->prealloc, tco->flags, tco->errp);
112
aio_wait_kick();
113
}
114
115
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
116
- PreallocMode prealloc, Error **errp)
117
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
118
{
119
Coroutine *co;
120
TruncateCo tco = {
121
@@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
122
.offset = offset,
123
.exact = exact,
124
.prealloc = prealloc,
125
+ .flags = flags,
126
.errp = errp,
127
.ret = NOT_DONE,
128
};
129
diff --git a/block/parallels.c b/block/parallels.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/block/parallels.c
132
+++ b/block/parallels.c
133
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
134
} else {
135
ret = bdrv_truncate(bs->file,
136
(s->data_end + space) << BDRV_SECTOR_BITS,
137
- false, PREALLOC_MODE_OFF, NULL);
138
+ false, PREALLOC_MODE_OFF, 0, NULL);
139
}
140
if (ret < 0) {
141
return ret;
142
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
143
* That means we have to pass exact=true.
144
*/
145
ret = bdrv_truncate(bs->file, res->image_end_offset, true,
146
- PREALLOC_MODE_OFF, &local_err);
147
+ PREALLOC_MODE_OFF, 0, &local_err);
148
if (ret < 0) {
149
error_report_err(local_err);
150
res->check_errors++;
151
@@ -XXX,XX +XXX,XX @@ static void parallels_close(BlockDriverState *bs)
152
153
/* errors are ignored, so we might as well pass exact=true */
154
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true,
155
- PREALLOC_MODE_OFF, NULL);
156
+ PREALLOC_MODE_OFF, 0, NULL);
157
}
158
159
g_free(s->bat_dirty_bmap);
160
diff --git a/block/qcow.c b/block/qcow.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/block/qcow.c
163
+++ b/block/qcow.c
164
@@ -XXX,XX +XXX,XX @@ static int get_cluster_offset(BlockDriverState *bs,
165
return -E2BIG;
166
}
167
ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
168
- false, PREALLOC_MODE_OFF, NULL);
169
+ false, PREALLOC_MODE_OFF, 0, NULL);
170
if (ret < 0) {
171
return ret;
172
}
173
@@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs)
174
l1_length) < 0)
175
return -1;
176
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, false,
177
- PREALLOC_MODE_OFF, NULL);
178
+ PREALLOC_MODE_OFF, 0, NULL);
179
if (ret < 0)
180
return ret;
181
29
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
182
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
30
index XXXXXXX..XXXXXXX 100644
183
index XXXXXXX..XXXXXXX 100644
31
--- a/block/qcow2-refcount.c
184
--- a/block/qcow2-refcount.c
32
+++ b/block/qcow2-refcount.c
185
+++ b/block/qcow2-refcount.c
33
@@ -XXX,XX +XXX,XX @@ out:
186
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
34
g_free(reftable_tmp);
187
}
35
return ret;
188
36
}
189
ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
37
+
190
- PREALLOC_MODE_OFF, &local_err);
38
+int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size)
191
+ PREALLOC_MODE_OFF, 0, &local_err);
39
+{
192
if (ret < 0) {
40
+ BDRVQcow2State *s = bs->opaque;
193
error_report_err(local_err);
41
+ int64_t i;
194
goto resize_fail;
42
+
43
+ for (i = size_to_clusters(s, size) - 1; i >= 0; i--) {
44
+ uint64_t refcount;
45
+ int ret = qcow2_get_refcount(bs, i, &refcount);
46
+ if (ret < 0) {
47
+ fprintf(stderr, "Can't get refcount for cluster %" PRId64 ": %s\n",
48
+ i, strerror(-ret));
49
+ return ret;
50
+ }
51
+ if (refcount > 0) {
52
+ return i;
53
+ }
54
+ }
55
+ qcow2_signal_corruption(bs, true, -1, -1,
56
+ "There are no references in the refcount table.");
57
+ return -EIO;
58
+}
59
diff --git a/block/qcow2.c b/block/qcow2.c
195
diff --git a/block/qcow2.c b/block/qcow2.c
60
index XXXXXXX..XXXXXXX 100644
196
index XXXXXXX..XXXXXXX 100644
61
--- a/block/qcow2.c
197
--- a/block/qcow2.c
62
+++ b/block/qcow2.c
198
+++ b/block/qcow2.c
63
@@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
199
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
64
new_l1_size = size_to_l1(s, offset);
200
mode = PREALLOC_MODE_OFF;
65
201
}
66
if (offset < old_length) {
202
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, false,
67
+ int64_t last_cluster, old_file_size;
203
- mode, errp);
68
if (prealloc != PREALLOC_MODE_OFF) {
204
+ mode, 0, errp);
69
error_setg(errp,
205
if (ret < 0) {
70
"Preallocation can't be used for shrinking an image");
71
@@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
72
"Failed to discard unused refblocks");
73
return ret;
206
return ret;
74
}
207
}
75
+
208
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
76
+ old_file_size = bdrv_getlength(bs->file->bs);
209
* always fulfilled, so there is no need to pass it on.)
77
+ if (old_file_size < 0) {
210
*/
78
+ error_setg_errno(errp, -old_file_size,
211
bdrv_co_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
79
+ "Failed to inquire current file length");
212
- false, PREALLOC_MODE_OFF, &local_err);
80
+ return old_file_size;
213
+ false, PREALLOC_MODE_OFF, 0, &local_err);
81
+ }
214
if (local_err) {
82
+ last_cluster = qcow2_get_last_cluster(bs, old_file_size);
215
warn_reportf_err(local_err,
83
+ if (last_cluster < 0) {
216
"Failed to truncate the tail of the image: ");
84
+ error_setg_errno(errp, -last_cluster,
217
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
85
+ "Failed to find the last cluster");
218
* file should be resized to the exact target size, too,
86
+ return last_cluster;
219
* so we pass @exact here.
87
+ }
220
*/
88
+ if ((last_cluster + 1) * s->cluster_size < old_file_size) {
221
- ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, errp);
89
+ ret = bdrv_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
222
+ ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 0,
90
+ PREALLOC_MODE_OFF, NULL);
223
+ errp);
91
+ if (ret < 0) {
224
if (ret < 0) {
92
+ warn_report("Failed to truncate the tail of the image: %s",
225
goto fail;
93
+ strerror(-ret));
226
}
94
+ ret = 0;
227
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
95
+ }
228
new_file_size = allocation_start +
96
+ }
229
nb_new_data_clusters * s->cluster_size;
97
} else {
230
/* Image file grows, so @exact does not matter */
98
ret = qcow2_grow_l1_table(bs, new_l1_size, true);
231
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, errp);
232
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
233
+ errp);
99
if (ret < 0) {
234
if (ret < 0) {
235
error_prepend(errp, "Failed to resize underlying file: ");
236
qcow2_free_clusters(bs, allocation_start,
237
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
238
if (len < 0) {
239
return len;
240
}
241
- return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
242
+ return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, 0,
243
+ NULL);
244
}
245
246
if (offset_into_cluster(s, offset)) {
247
@@ -XXX,XX +XXX,XX @@ static int make_completely_empty(BlockDriverState *bs)
248
}
249
250
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, false,
251
- PREALLOC_MODE_OFF, &local_err);
252
+ PREALLOC_MODE_OFF, 0, &local_err);
253
if (ret < 0) {
254
error_report_err(local_err);
255
goto fail;
256
diff --git a/block/raw-format.c b/block/raw-format.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/block/raw-format.c
259
+++ b/block/raw-format.c
260
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
261
262
s->size = offset;
263
offset += s->offset;
264
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
265
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
266
}
267
268
static void raw_eject(BlockDriverState *bs, bool eject_flag)
269
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/block/vhdx-log.c
272
+++ b/block/vhdx-log.c
273
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
274
goto exit;
275
}
276
ret = bdrv_truncate(bs->file, new_file_size, false,
277
- PREALLOC_MODE_OFF, NULL);
278
+ PREALLOC_MODE_OFF, 0, NULL);
279
if (ret < 0) {
280
goto exit;
281
}
282
diff --git a/block/vhdx.c b/block/vhdx.c
283
index XXXXXXX..XXXXXXX 100644
284
--- a/block/vhdx.c
285
+++ b/block/vhdx.c
286
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
287
}
288
289
return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
290
- PREALLOC_MODE_OFF, NULL);
291
+ PREALLOC_MODE_OFF, 0, NULL);
292
}
293
294
/*
295
diff --git a/block/vmdk.c b/block/vmdk.c
296
index XXXXXXX..XXXXXXX 100644
297
--- a/block/vmdk.c
298
+++ b/block/vmdk.c
299
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
300
}
301
length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
302
ret = bdrv_truncate(s->extents[i].file, length, false,
303
- PREALLOC_MODE_OFF, NULL);
304
+ PREALLOC_MODE_OFF, 0, NULL);
305
if (ret < 0) {
306
return ret;
307
}
308
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/tests/test-block-iothread.c
311
+++ b/tests/test-block-iothread.c
312
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_truncate(BdrvChild *c)
313
int ret;
314
315
/* Normal success path */
316
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
317
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
318
g_assert_cmpint(ret, ==, 0);
319
320
/* Early error: Negative offset */
321
- ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
322
+ ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, 0, NULL);
323
g_assert_cmpint(ret, ==, -EINVAL);
324
325
/* Error: Read-only image */
326
c->bs->read_only = true;
327
c->bs->open_flags &= ~BDRV_O_RDWR;
328
329
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
330
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
331
g_assert_cmpint(ret, ==, -EACCES);
332
333
c->bs->read_only = false;
100
--
334
--
101
2.13.6
335
2.25.3
102
336
103
337
diff view generated by jsdifflib
1
We don't need to make any assumptions about the graph layout above the
1
Now that node level interface bdrv_truncate() supports passing request
2
top node of the commit operation any more. Remove the use of
2
flags to the block driver, expose this on the BlockBackend level, too.
3
bdrv_find_overlay() and related variables from the commit job code.
4
5
bdrv_drop_intermediate() doesn't use the 'active' parameter any more, so
6
we can just drop it.
7
8
The overlay node was previously added to the block job to get a
9
BLK_PERM_GRAPH_MOD. We really need to respect those permissions in
10
bdrv_drop_intermediate() now, but as long as we haven't figured out yet
11
how BLK_PERM_GRAPH_MOD is actually supposed to work, just leave a TODO
12
comment there.
13
14
With this change, it is now possible to perform another block job on an
15
overlay node without conflicts. qemu-iotests 030 is changed accordingly.
16
3
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20200424125448.63318-4-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
10
---
20
include/block/block.h | 3 +--
11
include/sysemu/block-backend.h | 2 +-
21
block.c | 6 +++--
12
block.c | 3 ++-
22
block/commit.c | 62 ++++++++++++--------------------------------------
13
block/block-backend.c | 4 ++--
23
tests/qemu-iotests/030 | 4 ----
14
block/commit.c | 4 ++--
24
4 files changed, 20 insertions(+), 55 deletions(-)
15
block/crypto.c | 2 +-
25
16
block/mirror.c | 2 +-
26
diff --git a/include/block/block.h b/include/block/block.h
17
block/qcow2.c | 4 ++--
27
index XXXXXXX..XXXXXXX 100644
18
block/qed.c | 2 +-
28
--- a/include/block/block.h
19
block/vdi.c | 2 +-
29
+++ b/include/block/block.h
20
block/vhdx.c | 4 ++--
30
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs);
21
block/vmdk.c | 6 +++---
31
int bdrv_change_backing_file(BlockDriverState *bs,
22
block/vpc.c | 2 +-
32
const char *backing_file, const char *backing_fmt);
23
blockdev.c | 2 +-
33
void bdrv_register(BlockDriver *bdrv);
24
qemu-img.c | 2 +-
34
-int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
25
qemu-io-cmds.c | 2 +-
35
- BlockDriverState *base,
26
15 files changed, 22 insertions(+), 21 deletions(-)
36
+int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
27
37
const char *backing_file_str);
28
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
38
BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
29
index XXXXXXX..XXXXXXX 100644
39
BlockDriverState *bs);
30
--- a/include/sysemu/block-backend.h
31
+++ b/include/sysemu/block-backend.h
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
33
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
34
int bytes);
35
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
36
- PreallocMode prealloc, Error **errp);
37
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
38
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
39
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
40
int64_t pos, int size);
40
diff --git a/block.c b/block.c
41
diff --git a/block.c b/block.c
41
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
42
--- a/block.c
43
--- a/block.c
43
+++ b/block.c
44
+++ b/block.c
44
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs)
45
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
45
* if active == top, that is considered an error
46
int64_t size;
46
*
47
int ret;
47
*/
48
48
-int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
49
- ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
49
- BlockDriverState *base, const char *backing_file_str)
50
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
50
+int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
51
+ &local_err);
51
+ const char *backing_file_str)
52
if (ret < 0 && ret != -ENOTSUP) {
53
error_propagate(errp, local_err);
54
return ret;
55
diff --git a/block/block-backend.c b/block/block-backend.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block/block-backend.c
58
+++ b/block/block-backend.c
59
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
60
}
61
62
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
63
- PreallocMode prealloc, Error **errp)
64
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
52
{
65
{
53
BdrvChild *c, *next;
66
if (!blk_is_available(blk)) {
54
Error *local_err = NULL;
67
error_setg(errp, "No medium inserted");
55
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
68
return -ENOMEDIUM;
56
}
69
}
57
70
58
/* success - we can delete the intermediate states, and link top->base */
71
- return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
59
+ /* TODO Check graph modification op blockers (BLK_PERM_GRAPH_MOD) once
72
+ return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
60
+ * we've figured out how they should work. */
73
}
61
backing_file_str = backing_file_str ? backing_file_str : base->filename;
74
62
75
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
63
QLIST_FOREACH_SAFE(c, &top->parents, next_parent, next) {
64
diff --git a/block/commit.c b/block/commit.c
76
diff --git a/block/commit.c b/block/commit.c
65
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
66
--- a/block/commit.c
78
--- a/block/commit.c
67
+++ b/block/commit.c
79
+++ b/block/commit.c
68
@@ -XXX,XX +XXX,XX @@ enum {
80
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
69
typedef struct CommitBlockJob {
81
}
70
BlockJob common;
82
71
RateLimit limit;
83
if (base_len < len) {
72
- BlockDriverState *active;
84
- ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
73
BlockDriverState *commit_top_bs;
85
+ ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
74
BlockBackend *top;
86
if (ret) {
75
BlockBackend *base;
87
goto out;
76
BlockdevOnError on_error;
88
}
77
int base_flags;
89
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
78
- int orig_overlay_flags;
90
* grow the backing file image if possible. If not possible,
79
char *backing_file_str;
91
* we must return an error */
80
} CommitBlockJob;
92
if (length > backing_length) {
81
93
- ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF,
82
@@ -XXX,XX +XXX,XX @@ static void commit_complete(BlockJob *job, void *opaque)
94
+ ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
83
{
95
&local_err);
84
CommitBlockJob *s = container_of(job, CommitBlockJob, common);
96
if (ret < 0) {
85
CommitCompleteData *data = opaque;
97
error_report_err(local_err);
86
- BlockDriverState *active = s->active;
98
diff --git a/block/crypto.c b/block/crypto.c
87
BlockDriverState *top = blk_bs(s->top);
99
index XXXXXXX..XXXXXXX 100644
88
BlockDriverState *base = blk_bs(s->base);
100
--- a/block/crypto.c
89
- BlockDriverState *overlay_bs = bdrv_find_overlay(active, s->commit_top_bs);
101
+++ b/block/crypto.c
90
+ BlockDriverState *commit_top_bs = s->commit_top_bs;
102
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
91
int ret = data->ret;
103
* which will be used by the crypto header
92
bool remove_commit_top_bs = false;
104
*/
93
105
return blk_truncate(data->blk, data->size + headerlen, false,
94
- /* Make sure overlay_bs and top stay around until bdrv_set_backing_hd() */
106
- data->prealloc, errp);
95
+ /* Make sure commit_top_bs and top stay around until bdrv_replace_node() */
107
+ data->prealloc, 0, errp);
96
bdrv_ref(top);
97
- if (overlay_bs) {
98
- bdrv_ref(overlay_bs);
99
- }
100
+ bdrv_ref(commit_top_bs);
101
102
/* Remove base node parent that still uses BLK_PERM_WRITE/RESIZE before
103
* the normal backing chain can be restored. */
104
@@ -XXX,XX +XXX,XX @@ static void commit_complete(BlockJob *job, void *opaque)
105
106
if (!block_job_is_cancelled(&s->common) && ret == 0) {
107
/* success */
108
- ret = bdrv_drop_intermediate(active, s->commit_top_bs, base,
109
+ ret = bdrv_drop_intermediate(s->commit_top_bs, base,
110
s->backing_file_str);
111
- } else if (overlay_bs) {
112
+ } else {
113
/* XXX Can (or should) we somehow keep 'consistent read' blocked even
114
* after the failed/cancelled commit job is gone? If we already wrote
115
* something to base, the intermediate images aren't valid any more. */
116
@@ -XXX,XX +XXX,XX @@ static void commit_complete(BlockJob *job, void *opaque)
117
if (s->base_flags != bdrv_get_flags(base)) {
118
bdrv_reopen(base, s->base_flags, NULL);
119
}
120
- if (overlay_bs && s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
121
- bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
122
- }
123
g_free(s->backing_file_str);
124
blk_unref(s->top);
125
126
@@ -XXX,XX +XXX,XX @@ static void commit_complete(BlockJob *job, void *opaque)
127
* filter driver from the backing chain. Do this as the final step so that
128
* the 'consistent read' permission can be granted. */
129
if (remove_commit_top_bs) {
130
- bdrv_set_backing_hd(overlay_bs, top, &error_abort);
131
+ bdrv_child_try_set_perm(commit_top_bs->backing, 0, BLK_PERM_ALL,
132
+ &error_abort);
133
+ bdrv_replace_node(commit_top_bs, backing_bs(commit_top_bs),
134
+ &error_abort);
135
}
136
137
- bdrv_unref(overlay_bs);
138
+ bdrv_unref(commit_top_bs);
139
bdrv_unref(top);
140
}
108
}
141
109
142
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
110
143
{
111
diff --git a/block/mirror.c b/block/mirror.c
144
CommitBlockJob *s;
112
index XXXXXXX..XXXXXXX 100644
145
BlockReopenQueue *reopen_queue = NULL;
113
--- a/block/mirror.c
146
- int orig_overlay_flags;
114
+++ b/block/mirror.c
147
int orig_base_flags;
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
148
BlockDriverState *iter;
116
149
- BlockDriverState *overlay_bs;
117
if (s->bdev_length > base_length) {
150
BlockDriverState *commit_top_bs = NULL;
118
ret = blk_truncate(s->target, s->bdev_length, false,
151
Error *local_err = NULL;
119
- PREALLOC_MODE_OFF, NULL);
152
int ret;
120
+ PREALLOC_MODE_OFF, 0, NULL);
153
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
121
if (ret < 0) {
154
return;
122
goto immediate_exit;
155
}
123
}
156
124
diff --git a/block/qcow2.c b/block/qcow2.c
157
- overlay_bs = bdrv_find_overlay(bs, top);
125
index XXXXXXX..XXXXXXX 100644
158
-
126
--- a/block/qcow2.c
159
- if (overlay_bs == NULL) {
127
+++ b/block/qcow2.c
160
- error_setg(errp, "Could not find overlay image for %s:", top->filename);
128
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
161
- return;
129
162
- }
130
/* Okay, now that we have a valid image, let's give it the right size */
163
-
131
ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
164
s = block_job_create(job_id, &commit_job_driver, bs, 0, BLK_PERM_ALL,
132
- errp);
165
speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);
133
+ 0, errp);
166
if (!s) {
134
if (ret < 0) {
167
return;
135
error_prepend(errp, "Could not resize image: ");
168
}
136
goto out;
169
137
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
170
- orig_base_flags = bdrv_get_flags(base);
138
* Amending image options should ensure that the image has
171
- orig_overlay_flags = bdrv_get_flags(overlay_bs);
139
* exactly the given new values, so pass exact=true here.
172
-
140
*/
173
- /* convert base & overlay_bs to r/w, if necessary */
141
- ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, errp);
174
+ /* convert base to r/w, if necessary */
142
+ ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, 0, errp);
175
+ orig_base_flags = bdrv_get_flags(base);
143
blk_unref(blk);
176
if (!(orig_base_flags & BDRV_O_RDWR)) {
144
if (ret < 0) {
177
reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,
145
return ret;
178
orig_base_flags | BDRV_O_RDWR);
146
diff --git a/block/qed.c b/block/qed.c
179
}
147
index XXXXXXX..XXXXXXX 100644
180
- if (!(orig_overlay_flags & BDRV_O_RDWR)) {
148
--- a/block/qed.c
181
- reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,
149
+++ b/block/qed.c
182
- orig_overlay_flags | BDRV_O_RDWR);
150
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
183
- }
151
* The QED format associates file length with allocation status,
184
+
152
* so a new file (which is empty) must have a length of 0.
185
if (reopen_queue) {
153
*/
186
bdrv_reopen_multiple(bdrv_get_aio_context(bs), reopen_queue, &local_err);
154
- ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, errp);
187
if (local_err != NULL) {
155
+ ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
188
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
156
if (ret < 0) {
189
goto fail;
157
goto out;
190
}
158
}
191
159
diff --git a/block/vdi.c b/block/vdi.c
192
- /* overlay_bs must be blocked because it needs to be modified to
160
index XXXXXXX..XXXXXXX 100644
193
- * update the backing image string. */
161
--- a/block/vdi.c
194
- ret = block_job_add_bdrv(&s->common, "overlay of top", overlay_bs,
162
+++ b/block/vdi.c
195
- BLK_PERM_GRAPH_MOD, BLK_PERM_ALL, errp);
163
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
196
- if (ret < 0) {
164
197
- goto fail;
165
if (image_type == VDI_TYPE_STATIC) {
198
- }
166
ret = blk_truncate(blk, offset + blocks * block_size, false,
199
-
167
- PREALLOC_MODE_OFF, errp);
200
s->base = blk_new(BLK_PERM_CONSISTENT_READ
168
+ PREALLOC_MODE_OFF, 0, errp);
201
| BLK_PERM_WRITE
169
if (ret < 0) {
202
| BLK_PERM_RESIZE,
170
error_prepend(errp, "Failed to statically allocate file");
203
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
171
goto exit;
204
goto fail;
172
diff --git a/block/vhdx.c b/block/vhdx.c
205
}
173
index XXXXXXX..XXXXXXX 100644
206
174
--- a/block/vhdx.c
207
- s->active = bs;
175
+++ b/block/vhdx.c
208
-
176
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
209
- s->base_flags = orig_base_flags;
177
/* All zeroes, so we can just extend the file - the end of the BAT
210
- s->orig_overlay_flags = orig_overlay_flags;
178
* is the furthest thing we have written yet */
211
-
179
ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
212
+ s->base_flags = orig_base_flags;
180
- errp);
213
s->backing_file_str = g_strdup(backing_file_str);
181
+ 0, errp);
214
-
182
if (ret < 0) {
215
s->on_error = on_error;
183
goto exit;
216
184
}
217
trace_commit_start(bs, base, top, s);
185
} else if (type == VHDX_TYPE_FIXED) {
218
@@ -XXX,XX +XXX,XX @@ fail:
186
ret = blk_truncate(blk, data_file_offset + image_size, false,
219
blk_unref(s->top);
187
- PREALLOC_MODE_OFF, errp);
220
}
188
+ PREALLOC_MODE_OFF, 0, errp);
221
if (commit_top_bs) {
189
if (ret < 0) {
222
- bdrv_set_backing_hd(overlay_bs, top, &error_abort);
190
goto exit;
223
+ bdrv_replace_node(commit_top_bs, top, &error_abort);
191
}
224
}
192
diff --git a/block/vmdk.c b/block/vmdk.c
225
block_job_early_fail(&s->common);
193
index XXXXXXX..XXXXXXX 100644
226
}
194
--- a/block/vmdk.c
227
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
195
+++ b/block/vmdk.c
228
index XXXXXXX..XXXXXXX 100755
196
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
229
--- a/tests/qemu-iotests/030
197
int gd_buf_size;
230
+++ b/tests/qemu-iotests/030
198
231
@@ -XXX,XX +XXX,XX @@ class TestParallelOps(iotests.QMPTestCase):
199
if (flat) {
232
result = self.vm.qmp('block-stream', device='node6', base=self.imgs[4], job_id='stream-node6-v2')
200
- ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
233
self.assert_qmp(result, 'error/class', 'GenericError')
201
+ ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
234
202
goto exit;
235
- # This fails because block-commit needs to block node6, the overlay of the 'top' image
203
}
236
- result = self.vm.qmp('block-stream', device='node7', base=self.imgs[5], job_id='stream-node6-v3')
204
magic = cpu_to_be32(VMDK4_MAGIC);
237
- self.assert_qmp(result, 'error/class', 'GenericError')
205
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
238
-
206
}
239
# This fails because block-commit currently blocks the active layer even if it's not used
207
240
result = self.vm.qmp('block-stream', device='drive0', base=self.imgs[5], job_id='stream-drive0')
208
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
241
self.assert_qmp(result, 'error/class', 'GenericError')
209
- PREALLOC_MODE_OFF, errp);
210
+ PREALLOC_MODE_OFF, 0, errp);
211
if (ret < 0) {
212
goto exit;
213
}
214
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
215
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
216
* for description file */
217
if (desc_offset == 0) {
218
- ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
219
+ ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
220
if (ret < 0) {
221
goto exit;
222
}
223
diff --git a/block/vpc.c b/block/vpc.c
224
index XXXXXXX..XXXXXXX 100644
225
--- a/block/vpc.c
226
+++ b/block/vpc.c
227
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
228
/* Add footer to total size */
229
total_size += HEADER_SIZE;
230
231
- ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
232
+ ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
233
if (ret < 0) {
234
return ret;
235
}
236
diff --git a/blockdev.c b/blockdev.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/blockdev.c
239
+++ b/blockdev.c
240
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
241
}
242
243
bdrv_drained_begin(bs);
244
- ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
245
+ ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
246
bdrv_drained_end(bs);
247
248
out:
249
diff --git a/qemu-img.c b/qemu-img.c
250
index XXXXXXX..XXXXXXX 100644
251
--- a/qemu-img.c
252
+++ b/qemu-img.c
253
@@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv)
254
* resizing, so pass @exact=true. It is of no use to report
255
* success when the image has not actually been resized.
256
*/
257
- ret = blk_truncate(blk, total_size, true, prealloc, &err);
258
+ ret = blk_truncate(blk, total_size, true, prealloc, 0, &err);
259
if (!ret) {
260
qprintf(quiet, "Image resized.\n");
261
} else {
262
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
263
index XXXXXXX..XXXXXXX 100644
264
--- a/qemu-io-cmds.c
265
+++ b/qemu-io-cmds.c
266
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
267
* exact=true. It is better to err on the "emit more errors" side
268
* than to be overly permissive.
269
*/
270
- ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, &local_err);
271
+ ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, 0, &local_err);
272
if (ret < 0) {
273
error_report_err(local_err);
274
return ret;
242
--
275
--
243
2.13.6
276
2.25.3
244
277
245
278
diff view generated by jsdifflib
1
From: "Daniel P. Berrange" <berrange@redhat.com>
1
If BDRV_REQ_ZERO_WRITE is set and we're extending the image, calling
2
qcow2_cluster_zeroize() with flags=0 does the right thing: It doesn't
3
undo any previous preallocation, but just adds the zero flag to all
4
relevant L2 entries. If an external data file is in use, a write_zeroes
5
request to the data file is made instead.
2
6
3
Instead of sector offset, take the bytes offset when encrypting
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
or decrypting data.
8
Message-Id: <20200424125448.63318-5-kwolf@redhat.com>
5
6
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
7
Message-id: 20170927125340.12360-6-berrange@redhat.com
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
---
12
crypto/blockpriv.h | 4 ++--
13
block/qcow2-cluster.c | 2 +-
13
include/crypto/block.h | 14 ++++++++------
14
block/qcow2.c | 34 ++++++++++++++++++++++++++++++++++
14
block/crypto.c | 12 ++++--------
15
2 files changed, 35 insertions(+), 1 deletion(-)
15
block/qcow.c | 11 +++++++----
16
block/qcow2-cluster.c | 8 +++-----
17
block/qcow2.c | 4 ++--
18
crypto/block-luks.c | 12 ++++++++----
19
crypto/block-qcow.c | 12 ++++++++----
20
crypto/block.c | 20 ++++++++++++++------
21
9 files changed, 56 insertions(+), 41 deletions(-)
22
16
23
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/crypto/blockpriv.h
26
+++ b/crypto/blockpriv.h
27
@@ -XXX,XX +XXX,XX @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher,
28
size_t niv,
29
QCryptoIVGen *ivgen,
30
int sectorsize,
31
- uint64_t startsector,
32
+ uint64_t offset,
33
uint8_t *buf,
34
size_t len,
35
Error **errp);
36
@@ -XXX,XX +XXX,XX @@ int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
37
size_t niv,
38
QCryptoIVGen *ivgen,
39
int sectorsize,
40
- uint64_t startsector,
41
+ uint64_t offset,
42
uint8_t *buf,
43
size_t len,
44
Error **errp);
45
diff --git a/include/crypto/block.h b/include/crypto/block.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/include/crypto/block.h
48
+++ b/include/crypto/block.h
49
@@ -XXX,XX +XXX,XX @@ QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
50
/**
51
* @qcrypto_block_decrypt:
52
* @block: the block encryption object
53
- * @startsector: the sector from which @buf was read
54
+ * @offset: the position at which @iov was read
55
* @buf: the buffer to decrypt
56
* @len: the length of @buf in bytes
57
* @errp: pointer to a NULL-initialized error object
58
*
59
* Decrypt @len bytes of cipher text in @buf, writing
60
- * plain text back into @buf
61
+ * plain text back into @buf. @len and @offset must be
62
+ * a multiple of the encryption format sector size.
63
*
64
* Returns 0 on success, -1 on failure
65
*/
66
int qcrypto_block_decrypt(QCryptoBlock *block,
67
- uint64_t startsector,
68
+ uint64_t offset,
69
uint8_t *buf,
70
size_t len,
71
Error **errp);
72
@@ -XXX,XX +XXX,XX @@ int qcrypto_block_decrypt(QCryptoBlock *block,
73
/**
74
* @qcrypto_block_encrypt:
75
* @block: the block encryption object
76
- * @startsector: the sector to which @buf will be written
77
+ * @offset: the position at which @iov will be written
78
* @buf: the buffer to decrypt
79
* @len: the length of @buf in bytes
80
* @errp: pointer to a NULL-initialized error object
81
*
82
* Encrypt @len bytes of plain text in @buf, writing
83
- * cipher text back into @buf
84
+ * cipher text back into @buf. @len and @offset must be
85
+ * a multiple of the encryption format sector size.
86
*
87
* Returns 0 on success, -1 on failure
88
*/
89
int qcrypto_block_encrypt(QCryptoBlock *block,
90
- uint64_t startsector,
91
+ uint64_t offset,
92
uint8_t *buf,
93
size_t len,
94
Error **errp);
95
diff --git a/block/crypto.c b/block/crypto.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/block/crypto.c
98
+++ b/block/crypto.c
99
@@ -XXX,XX +XXX,XX @@ block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
100
int ret = 0;
101
uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
102
uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
103
- uint64_t sector_num = offset / sector_size;
104
105
assert(!flags);
106
assert(payload_offset < INT64_MAX);
107
@@ -XXX,XX +XXX,XX @@ block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
108
goto cleanup;
109
}
110
111
- if (qcrypto_block_decrypt(crypto->block, sector_num, cipher_data,
112
- cur_bytes, NULL) < 0) {
113
+ if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
114
+ cipher_data, cur_bytes, NULL) < 0) {
115
ret = -EIO;
116
goto cleanup;
117
}
118
119
qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
120
121
- sector_num += cur_bytes / sector_size;
122
bytes -= cur_bytes;
123
bytes_done += cur_bytes;
124
}
125
@@ -XXX,XX +XXX,XX @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
126
int ret = 0;
127
uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
128
uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
129
- uint64_t sector_num = offset / sector_size;
130
131
assert(!flags);
132
assert(payload_offset < INT64_MAX);
133
@@ -XXX,XX +XXX,XX @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
134
135
qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
136
137
- if (qcrypto_block_encrypt(crypto->block, sector_num, cipher_data,
138
- cur_bytes, NULL) < 0) {
139
+ if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
140
+ cipher_data, cur_bytes, NULL) < 0) {
141
ret = -EIO;
142
goto cleanup;
143
}
144
@@ -XXX,XX +XXX,XX @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
145
goto cleanup;
146
}
147
148
- sector_num += cur_bytes / sector_size;
149
bytes -= cur_bytes;
150
bytes_done += cur_bytes;
151
}
152
diff --git a/block/qcow.c b/block/qcow.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/block/qcow.c
155
+++ b/block/qcow.c
156
@@ -XXX,XX +XXX,XX @@ static int get_cluster_offset(BlockDriverState *bs,
157
for(i = 0; i < s->cluster_sectors; i++) {
158
if (i < n_start || i >= n_end) {
159
memset(s->cluster_data, 0x00, 512);
160
- if (qcrypto_block_encrypt(s->crypto, start_sect + i,
161
+ if (qcrypto_block_encrypt(s->crypto,
162
+ (start_sect + i) *
163
+ BDRV_SECTOR_SIZE,
164
s->cluster_data,
165
BDRV_SECTOR_SIZE,
166
NULL) < 0) {
167
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
168
}
169
if (bs->encrypted) {
170
assert(s->crypto);
171
- if (qcrypto_block_decrypt(s->crypto, sector_num, buf,
172
+ if (qcrypto_block_decrypt(s->crypto,
173
+ sector_num * BDRV_SECTOR_SIZE, buf,
174
n * BDRV_SECTOR_SIZE, NULL) < 0) {
175
ret = -EIO;
176
break;
177
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
178
}
179
if (bs->encrypted) {
180
assert(s->crypto);
181
- if (qcrypto_block_encrypt(s->crypto, sector_num, buf,
182
- n * BDRV_SECTOR_SIZE, NULL) < 0) {
183
+ if (qcrypto_block_encrypt(s->crypto, sector_num * BDRV_SECTOR_SIZE,
184
+ buf, n * BDRV_SECTOR_SIZE, NULL) < 0) {
185
ret = -EIO;
186
break;
187
}
188
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
17
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
189
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
190
--- a/block/qcow2-cluster.c
19
--- a/block/qcow2-cluster.c
191
+++ b/block/qcow2-cluster.c
20
+++ b/block/qcow2-cluster.c
192
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
21
@@ -XXX,XX +XXX,XX @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
193
{
22
/* Caller must pass aligned values, except at image end */
194
if (bytes && bs->encrypted) {
23
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
195
BDRVQcow2State *s = bs->opaque;
24
assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) ||
196
- int64_t sector = (s->crypt_physical_offset ?
25
- end_offset == bs->total_sectors << BDRV_SECTOR_BITS);
197
+ int64_t offset = (s->crypt_physical_offset ?
26
+ end_offset >= bs->total_sectors << BDRV_SECTOR_BITS);
198
(cluster_offset + offset_in_cluster) :
27
199
- (src_cluster_offset + offset_in_cluster))
28
/* The zero flag is only supported by version 3 and newer */
200
- >> BDRV_SECTOR_BITS;
29
if (s->qcow_version < 3) {
201
+ (src_cluster_offset + offset_in_cluster));
202
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
203
assert((bytes & ~BDRV_SECTOR_MASK) == 0);
204
assert(s->crypto);
205
- if (qcrypto_block_encrypt(s->crypto, sector, buffer,
206
- bytes, NULL) < 0) {
207
+ if (qcrypto_block_encrypt(s->crypto, offset, buffer, bytes, NULL) < 0) {
208
return false;
209
}
210
}
211
diff --git a/block/qcow2.c b/block/qcow2.c
30
diff --git a/block/qcow2.c b/block/qcow2.c
212
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
213
--- a/block/qcow2.c
32
--- a/block/qcow2.c
214
+++ b/block/qcow2.c
33
+++ b/block/qcow2.c
215
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
216
if (qcrypto_block_decrypt(s->crypto,
35
217
(s->crypt_physical_offset ?
36
bs->supported_zero_flags = header.version >= 3 ?
218
cluster_offset + offset_in_cluster :
37
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
219
- offset) >> BDRV_SECTOR_BITS,
38
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
220
+ offset),
39
221
cluster_data,
40
/* Repair image if dirty */
222
cur_bytes,
41
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
223
NULL) < 0) {
42
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
224
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
43
g_assert_not_reached();
225
if (qcrypto_block_encrypt(s->crypto,
44
}
226
(s->crypt_physical_offset ?
45
227
cluster_offset + offset_in_cluster :
46
+ if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
228
- offset) >> BDRV_SECTOR_BITS,
47
+ uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
229
+ offset),
230
cluster_data,
231
cur_bytes, NULL) < 0) {
232
ret = -EIO;
233
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/crypto/block-luks.c
236
+++ b/crypto/block-luks.c
237
@@ -XXX,XX +XXX,XX @@ static void qcrypto_block_luks_cleanup(QCryptoBlock *block)
238
239
static int
240
qcrypto_block_luks_decrypt(QCryptoBlock *block,
241
- uint64_t startsector,
242
+ uint64_t offset,
243
uint8_t *buf,
244
size_t len,
245
Error **errp)
246
{
247
+ assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE));
248
+ assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE));
249
return qcrypto_block_decrypt_helper(block->cipher,
250
block->niv, block->ivgen,
251
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
252
- startsector, buf, len, errp);
253
+ offset, buf, len, errp);
254
}
255
256
257
static int
258
qcrypto_block_luks_encrypt(QCryptoBlock *block,
259
- uint64_t startsector,
260
+ uint64_t offset,
261
uint8_t *buf,
262
size_t len,
263
Error **errp)
264
{
265
+ assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE));
266
+ assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE));
267
return qcrypto_block_encrypt_helper(block->cipher,
268
block->niv, block->ivgen,
269
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
270
- startsector, buf, len, errp);
271
+ offset, buf, len, errp);
272
}
273
274
275
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
276
index XXXXXXX..XXXXXXX 100644
277
--- a/crypto/block-qcow.c
278
+++ b/crypto/block-qcow.c
279
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_cleanup(QCryptoBlock *block)
280
281
static int
282
qcrypto_block_qcow_decrypt(QCryptoBlock *block,
283
- uint64_t startsector,
284
+ uint64_t offset,
285
uint8_t *buf,
286
size_t len,
287
Error **errp)
288
{
289
+ assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
290
+ assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
291
return qcrypto_block_decrypt_helper(block->cipher,
292
block->niv, block->ivgen,
293
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE,
294
- startsector, buf, len, errp);
295
+ offset, buf, len, errp);
296
}
297
298
299
static int
300
qcrypto_block_qcow_encrypt(QCryptoBlock *block,
301
- uint64_t startsector,
302
+ uint64_t offset,
303
uint8_t *buf,
304
size_t len,
305
Error **errp)
306
{
307
+ assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
308
+ assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
309
return qcrypto_block_encrypt_helper(block->cipher,
310
block->niv, block->ivgen,
311
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE,
312
- startsector, buf, len, errp);
313
+ offset, buf, len, errp);
314
}
315
316
317
diff --git a/crypto/block.c b/crypto/block.c
318
index XXXXXXX..XXXXXXX 100644
319
--- a/crypto/block.c
320
+++ b/crypto/block.c
321
@@ -XXX,XX +XXX,XX @@ QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
322
323
324
int qcrypto_block_decrypt(QCryptoBlock *block,
325
- uint64_t startsector,
326
+ uint64_t offset,
327
uint8_t *buf,
328
size_t len,
329
Error **errp)
330
{
331
- return block->driver->decrypt(block, startsector, buf, len, errp);
332
+ return block->driver->decrypt(block, offset, buf, len, errp);
333
}
334
335
336
int qcrypto_block_encrypt(QCryptoBlock *block,
337
- uint64_t startsector,
338
+ uint64_t offset,
339
uint8_t *buf,
340
size_t len,
341
Error **errp)
342
{
343
- return block->driver->encrypt(block, startsector, buf, len, errp);
344
+ return block->driver->encrypt(block, offset, buf, len, errp);
345
}
346
347
348
@@ -XXX,XX +XXX,XX @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher,
349
size_t niv,
350
QCryptoIVGen *ivgen,
351
int sectorsize,
352
- uint64_t startsector,
353
+ uint64_t offset,
354
uint8_t *buf,
355
size_t len,
356
Error **errp)
357
{
358
uint8_t *iv;
359
int ret = -1;
360
+ uint64_t startsector = offset / sectorsize;
361
+
48
+
362
+ assert(QEMU_IS_ALIGNED(offset, sectorsize));
49
+ /*
363
+ assert(QEMU_IS_ALIGNED(len, sectorsize));
50
+ * Use zero clusters as much as we can. qcow2_cluster_zeroize()
364
51
+ * requires a cluster-aligned start. The end may be unaligned if it is
365
iv = niv ? g_new0(uint8_t, niv) : NULL;
52
+ * at the end of the image (which it is here).
366
53
+ */
367
@@ -XXX,XX +XXX,XX @@ int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
54
+ ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
368
size_t niv,
55
+ if (ret < 0) {
369
QCryptoIVGen *ivgen,
56
+ error_setg_errno(errp, -ret, "Failed to zero out new clusters");
370
int sectorsize,
57
+ goto fail;
371
- uint64_t startsector,
58
+ }
372
+ uint64_t offset,
373
uint8_t *buf,
374
size_t len,
375
Error **errp)
376
{
377
uint8_t *iv;
378
int ret = -1;
379
+ uint64_t startsector = offset / sectorsize;
380
+
59
+
381
+ assert(QEMU_IS_ALIGNED(offset, sectorsize));
60
+ /* Write explicit zeros for the unaligned head */
382
+ assert(QEMU_IS_ALIGNED(len, sectorsize));
61
+ if (zero_start > old_length) {
383
62
+ uint64_t len = zero_start - old_length;
384
iv = niv ? g_new0(uint8_t, niv) : NULL;
63
+ uint8_t *buf = qemu_blockalign0(bs, len);
385
64
+ QEMUIOVector qiov;
65
+ qemu_iovec_init_buf(&qiov, buf, len);
66
+
67
+ qemu_co_mutex_unlock(&s->lock);
68
+ ret = qcow2_co_pwritev_part(bs, old_length, len, &qiov, 0, 0);
69
+ qemu_co_mutex_lock(&s->lock);
70
+
71
+ qemu_vfree(buf);
72
+ if (ret < 0) {
73
+ error_setg_errno(errp, -ret, "Failed to zero out the new area");
74
+ goto fail;
75
+ }
76
+ }
77
+ }
78
+
79
if (prealloc != PREALLOC_MODE_OFF) {
80
/* Flush metadata before actually changing the image size */
81
ret = qcow2_write_caches(bs);
386
--
82
--
387
2.13.6
83
2.25.3
388
84
389
85
diff view generated by jsdifflib
1
From: "Daniel P. Berrange" <berrange@redhat.com>
1
The raw format driver can simply forward the flag and let its bs->file
2
child take care of actually providing the zeros.
2
3
3
While current encryption schemes all have a fixed sector size of
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
512 bytes, this is not guaranteed to be the case in future. Expose
5
the sector size in the APIs so the block layer can remove assumptions
6
about fixed 512 byte sectors.
7
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Message-id: 20170927125340.12360-3-berrange@redhat.com
8
Message-Id: <20200424125448.63318-6-kwolf@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
10
---
14
crypto/blockpriv.h | 1 +
11
block/raw-format.c | 4 +++-
15
include/crypto/block.h | 15 +++++++++++++++
12
1 file changed, 3 insertions(+), 1 deletion(-)
16
crypto/block-luks.c | 6 ++++--
17
crypto/block-qcow.c | 1 +
18
crypto/block.c | 6 ++++++
19
5 files changed, 27 insertions(+), 2 deletions(-)
20
13
21
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
14
diff --git a/block/raw-format.c b/block/raw-format.c
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/crypto/blockpriv.h
16
--- a/block/raw-format.c
24
+++ b/crypto/blockpriv.h
17
+++ b/block/raw-format.c
25
@@ -XXX,XX +XXX,XX @@ struct QCryptoBlock {
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
26
QCryptoHashAlgorithm kdfhash;
19
27
size_t niv;
20
s->size = offset;
28
uint64_t payload_offset; /* In bytes */
21
offset += s->offset;
29
+ uint64_t sector_size; /* In bytes */
22
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
30
};
23
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
31
32
struct QCryptoBlockDriver {
33
diff --git a/include/crypto/block.h b/include/crypto/block.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/crypto/block.h
36
+++ b/include/crypto/block.h
37
@@ -XXX,XX +XXX,XX @@ QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block);
38
uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block);
39
40
/**
41
+ * qcrypto_block_get_sector_size:
42
+ * @block: the block encryption object
43
+ *
44
+ * Get the size of sectors used for payload encryption. A new
45
+ * IV is used at the start of each sector. The encryption
46
+ * sector size is not required to match the sector size of the
47
+ * underlying storage. For example LUKS will always use a 512
48
+ * byte sector size, even if the volume is on a disk with 4k
49
+ * sectors.
50
+ *
51
+ * Returns: the sector in bytes
52
+ */
53
+uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block);
54
+
55
+/**
56
* qcrypto_block_free:
57
* @block: the block encryption object
58
*
59
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/crypto/block-luks.c
62
+++ b/crypto/block-luks.c
63
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_open(QCryptoBlock *block,
64
}
65
}
66
67
+ block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
68
block->payload_offset = luks->header.payload_offset *
69
- QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
70
+ block->sector_size;
71
72
luks->cipher_alg = cipheralg;
73
luks->cipher_mode = ciphermode;
74
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block,
75
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) *
76
QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
77
78
+ block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
79
block->payload_offset = luks->header.payload_offset *
80
- QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
81
+ block->sector_size;
82
83
/* Reserve header space to match payload offset */
84
initfunc(block, block->payload_offset, opaque, &local_err);
85
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/crypto/block-qcow.c
88
+++ b/crypto/block-qcow.c
89
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_init(QCryptoBlock *block,
90
goto fail;
91
}
92
93
+ block->sector_size = QCRYPTO_BLOCK_QCOW_SECTOR_SIZE;
94
block->payload_offset = 0;
95
96
return 0;
97
diff --git a/crypto/block.c b/crypto/block.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/crypto/block.c
100
+++ b/crypto/block.c
101
@@ -XXX,XX +XXX,XX @@ uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block)
102
}
24
}
103
25
104
26
static void raw_eject(BlockDriverState *bs, bool eject_flag)
105
+uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block)
27
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
106
+{
28
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
107
+ return block->sector_size;
29
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
108
+}
30
bs->file->bs->supported_zero_flags);
109
+
31
+ bs->supported_truncate_flags = bs->file->bs->supported_truncate_flags &
110
+
32
+ BDRV_REQ_ZERO_WRITE;
111
void qcrypto_block_free(QCryptoBlock *block)
33
112
{
34
if (bs->probed && !bdrv_is_read_only(bs)) {
113
if (!block) {
35
bdrv_refresh_filename(bs->file->bs);
114
--
36
--
115
2.13.6
37
2.25.3
116
38
117
39
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
For regular files, we always get BDRV_REQ_ZERO_WRITE behaviour from the
2
OS, so we can advertise the flag and just ignore it.
2
3
3
Handle a 0-length block status request up front, with a uniform
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
return value claiming the area is not allocated.
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
6
Most callers don't pass a length of 0 to bdrv_get_block_status()
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
and friends; but it definitely happens with a 0-length read when
8
Message-Id: <20200424125448.63318-7-kwolf@redhat.com>
8
copy-on-read is enabled. While we could audit all callers to
9
ensure that they never make a 0-length request, and then assert
10
that fact, it was just as easy to fix things to always report
11
success (as long as the callers are careful to not go into an
12
infinite loop). However, we had inconsistent behavior on whether
13
the status is reported as allocated or defers to the backing
14
layer, depending on what callbacks the driver implements, and
15
possibly wasting quite a few CPU cycles to get to that answer.
16
Consistently reporting unallocated up front doesn't really hurt
17
anything, and makes it easier both for callers (0-length requests
18
now have well-defined behavior) and for drivers (drivers don't
19
have to deal with 0-length requests).
20
21
Signed-off-by: Eric Blake <eblake@redhat.com>
22
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
24
---
10
---
25
block/io.c | 4 ++++
11
block/file-posix.c | 4 ++++
26
1 file changed, 4 insertions(+)
12
1 file changed, 4 insertions(+)
27
13
28
diff --git a/block/io.c b/block/io.c
14
diff --git a/block/file-posix.c b/block/file-posix.c
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/block/io.c
16
--- a/block/file-posix.c
31
+++ b/block/io.c
17
+++ b/block/file-posix.c
32
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
18
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
33
*pnum = 0;
19
#endif
34
return BDRV_BLOCK_EOF;
20
35
}
21
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
36
+ if (!nb_sectors) {
22
+ if (S_ISREG(st.st_mode)) {
37
+ *pnum = 0;
23
+ /* When extending regular files, we get zeros from the OS */
38
+ return 0;
24
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
39
+ }
25
+ }
40
26
ret = 0;
41
n = total_sectors - sector_num;
27
fail:
42
if (n < nb_sectors) {
28
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
43
--
29
--
44
2.13.6
30
2.25.3
45
31
46
32
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
When extending the size of an image that has a backing file larger than
2
its old size, make sure that the backing file data doesn't become
3
visible in the guest, but the added area is properly zeroed out.
2
4
3
Improve our braindead copy-on-read implementation. Pre-patch,
5
Consider the following scenario where the overlay is shorter than its
4
we have multiple issues:
6
backing file:
5
- we create a bounce buffer and perform a write for the entire
6
request, even if the active image already has 99% of the
7
clusters occupied, and really only needs to copy-on-read the
8
remaining 1% of the clusters
9
- our bounce buffer was as large as the read request, and can
10
needlessly exhaust our memory by using double the memory of
11
the request size (the original request plus our bounce buffer),
12
rather than a capped maximum overhead beyond the original
13
- if a driver has a max_transfer limit, we are bypassing the
14
normal code in bdrv_aligned_preadv() that fragments to that
15
limit, and instead attempt to read the entire buffer from the
16
driver in one go, which some drivers may assert on
17
- a client can request a large request of nearly 2G such that
18
rounding the request out to cluster boundaries results in a
19
byte count larger than 2G. While this cannot exceed 32 bits,
20
it DOES have some follow-on problems:
21
-- the call to bdrv_driver_pread() can assert for exceeding
22
BDRV_REQUEST_MAX_BYTES, if the driver is old and lacks
23
.bdrv_co_preadv
24
-- if the buffer is all zeroes, the subsequent call to
25
bdrv_co_do_pwrite_zeroes is a no-op due to a negative size,
26
which means we did not actually copy on read
27
7
28
Fix all of these issues by breaking up the action into a loop,
8
base.qcow2: AAAAAAAA
29
where each iteration is capped to sane limits. Also, querying
9
overlay.qcow2: BBBB
30
the allocation status allows us to optimize: when data is
31
already present in the active layer, we don't need to bounce.
32
10
33
Note that the code has a telling comment that copy-on-read
11
When resizing (extending) overlay.qcow2, the new blocks should not stay
34
should probably be a filter driver rather than a bolt-on hack
12
unallocated and make the additional As from base.qcow2 visible like
35
in io.c; but that remains a task for another day.
13
before this patch, but zeros should be read.
36
14
37
CC: qemu-stable@nongnu.org
15
A similar case happens with the various variants of a commit job when an
38
Signed-off-by: Eric Blake <eblake@redhat.com>
16
intermediate file is short (- for unallocated):
39
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
40
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
18
base.qcow2: A-A-AAAA
19
mid.qcow2: BB-B
20
top.qcow2: C--C--C-
21
22
After commit top.qcow2 to mid.qcow2, the following happens:
23
24
mid.qcow2: CB-C00C0 (correct result)
25
mid.qcow2: CB-C--C- (before this fix)
26
27
Without the fix, blocks that previously read as zeros on top.qcow2
28
suddenly turn into A.
29
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
32
Message-Id: <20200424125448.63318-8-kwolf@redhat.com>
33
Reviewed-by: Max Reitz <mreitz@redhat.com>
41
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
42
---
35
---
43
block/io.c | 120 +++++++++++++++++++++++++++++++++++++++++--------------------
36
block/io.c | 25 +++++++++++++++++++++++++
44
1 file changed, 82 insertions(+), 38 deletions(-)
37
1 file changed, 25 insertions(+)
45
38
46
diff --git a/block/io.c b/block/io.c
39
diff --git a/block/io.c b/block/io.c
47
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
48
--- a/block/io.c
41
--- a/block/io.c
49
+++ b/block/io.c
42
+++ b/block/io.c
50
@@ -XXX,XX +XXX,XX @@
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
51
44
goto out;
52
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
45
}
53
46
54
+/* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */
47
+ /*
55
+#define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
48
+ * If the image has a backing file that is large enough that it would
49
+ * provide data for the new area, we cannot leave it unallocated because
50
+ * then the backing file content would become visible. Instead, zero-fill
51
+ * the new area.
52
+ *
53
+ * Note that if the image has a backing file, but was opened without the
54
+ * backing file, taking care of keeping things consistent with that backing
55
+ * file is the user's responsibility.
56
+ */
57
+ if (new_bytes && bs->backing) {
58
+ int64_t backing_len;
56
+
59
+
57
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
60
+ backing_len = bdrv_getlength(backing_bs(bs));
58
int64_t offset, int bytes, BdrvRequestFlags flags);
61
+ if (backing_len < 0) {
59
62
+ ret = backing_len;
60
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
63
+ error_setg_errno(errp, -ret, "Could not get backing file size");
61
64
+ goto out;
62
BlockDriver *drv = bs->drv;
63
struct iovec iov;
64
- QEMUIOVector bounce_qiov;
65
+ QEMUIOVector local_qiov;
66
int64_t cluster_offset;
67
unsigned int cluster_bytes;
68
size_t skip_bytes;
69
int ret;
70
+ int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
71
+ BDRV_REQUEST_MAX_BYTES);
72
+ unsigned int progress = 0;
73
74
/* FIXME We cannot require callers to have write permissions when all they
75
* are doing is a read request. If we did things right, write permissions
76
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
77
// assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
78
79
/* Cover entire cluster so no additional backing file I/O is required when
80
- * allocating cluster in the image file.
81
+ * allocating cluster in the image file. Note that this value may exceed
82
+ * BDRV_REQUEST_MAX_BYTES (even when the original read did not), which
83
+ * is one reason we loop rather than doing it all at once.
84
*/
85
bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);
86
+ skip_bytes = offset - cluster_offset;
87
88
trace_bdrv_co_do_copy_on_readv(bs, offset, bytes,
89
cluster_offset, cluster_bytes);
90
91
- iov.iov_len = cluster_bytes;
92
- iov.iov_base = bounce_buffer = qemu_try_blockalign(bs, iov.iov_len);
93
+ bounce_buffer = qemu_try_blockalign(bs,
94
+ MIN(MIN(max_transfer, cluster_bytes),
95
+ MAX_BOUNCE_BUFFER));
96
if (bounce_buffer == NULL) {
97
ret = -ENOMEM;
98
goto err;
99
}
100
101
- qemu_iovec_init_external(&bounce_qiov, &iov, 1);
102
+ while (cluster_bytes) {
103
+ int64_t pnum;
104
105
- ret = bdrv_driver_preadv(bs, cluster_offset, cluster_bytes,
106
- &bounce_qiov, 0);
107
- if (ret < 0) {
108
- goto err;
109
- }
110
+ ret = bdrv_is_allocated(bs, cluster_offset,
111
+ MIN(cluster_bytes, max_transfer), &pnum);
112
+ if (ret < 0) {
113
+ /* Safe to treat errors in querying allocation as if
114
+ * unallocated; we'll probably fail again soon on the
115
+ * read, but at least that will set a decent errno.
116
+ */
117
+ pnum = MIN(cluster_bytes, max_transfer);
118
+ }
119
120
- bdrv_debug_event(bs, BLKDBG_COR_WRITE);
121
- if (drv->bdrv_co_pwrite_zeroes &&
122
- buffer_is_zero(bounce_buffer, iov.iov_len)) {
123
- /* FIXME: Should we (perhaps conditionally) be setting
124
- * BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy
125
- * that still correctly reads as zero? */
126
- ret = bdrv_co_do_pwrite_zeroes(bs, cluster_offset, cluster_bytes, 0);
127
- } else {
128
- /* This does not change the data on the disk, it is not necessary
129
- * to flush even in cache=writethrough mode.
130
- */
131
- ret = bdrv_driver_pwritev(bs, cluster_offset, cluster_bytes,
132
- &bounce_qiov, 0);
133
- }
134
+ assert(skip_bytes < pnum);
135
136
- if (ret < 0) {
137
- /* It might be okay to ignore write errors for guest requests. If this
138
- * is a deliberate copy-on-read then we don't want to ignore the error.
139
- * Simply report it in all cases.
140
- */
141
- goto err;
142
- }
143
+ if (ret <= 0) {
144
+ /* Must copy-on-read; use the bounce buffer */
145
+ iov.iov_base = bounce_buffer;
146
+ iov.iov_len = pnum = MIN(pnum, MAX_BOUNCE_BUFFER);
147
+ qemu_iovec_init_external(&local_qiov, &iov, 1);
148
149
- skip_bytes = offset - cluster_offset;
150
- qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes, bytes);
151
+ ret = bdrv_driver_preadv(bs, cluster_offset, pnum,
152
+ &local_qiov, 0);
153
+ if (ret < 0) {
154
+ goto err;
155
+ }
156
+
157
+ bdrv_debug_event(bs, BLKDBG_COR_WRITE);
158
+ if (drv->bdrv_co_pwrite_zeroes &&
159
+ buffer_is_zero(bounce_buffer, pnum)) {
160
+ /* FIXME: Should we (perhaps conditionally) be setting
161
+ * BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy
162
+ * that still correctly reads as zero? */
163
+ ret = bdrv_co_do_pwrite_zeroes(bs, cluster_offset, pnum, 0);
164
+ } else {
165
+ /* This does not change the data on the disk, it is not
166
+ * necessary to flush even in cache=writethrough mode.
167
+ */
168
+ ret = bdrv_driver_pwritev(bs, cluster_offset, pnum,
169
+ &local_qiov, 0);
170
+ }
171
+
172
+ if (ret < 0) {
173
+ /* It might be okay to ignore write errors for guest
174
+ * requests. If this is a deliberate copy-on-read
175
+ * then we don't want to ignore the error. Simply
176
+ * report it in all cases.
177
+ */
178
+ goto err;
179
+ }
180
+
181
+ qemu_iovec_from_buf(qiov, progress, bounce_buffer + skip_bytes,
182
+ pnum - skip_bytes);
183
+ } else {
184
+ /* Read directly into the destination */
185
+ qemu_iovec_init(&local_qiov, qiov->niov);
186
+ qemu_iovec_concat(&local_qiov, qiov, progress, pnum - skip_bytes);
187
+ ret = bdrv_driver_preadv(bs, offset + progress, local_qiov.size,
188
+ &local_qiov, 0);
189
+ qemu_iovec_destroy(&local_qiov);
190
+ if (ret < 0) {
191
+ goto err;
192
+ }
193
+ }
65
+ }
194
+
66
+
195
+ cluster_offset += pnum;
67
+ if (backing_len > old_size) {
196
+ cluster_bytes -= pnum;
68
+ flags |= BDRV_REQ_ZERO_WRITE;
197
+ progress += pnum - skip_bytes;
69
+ }
198
+ skip_bytes = 0;
199
+ }
70
+ }
200
+ ret = 0;
71
+
201
72
if (drv->bdrv_co_truncate) {
202
err:
73
if (flags & ~bs->supported_truncate_flags) {
203
qemu_vfree(bounce_buffer);
74
error_setg(errp, "Block driver does not support requested flags");
204
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_readv(BdrvChild *child, int64_t sector_num,
205
return bdrv_co_do_readv(child, sector_num, nb_sectors, qiov, 0);
206
}
207
208
-/* Maximum buffer for write zeroes fallback, in bytes */
209
-#define MAX_WRITE_ZEROES_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
210
-
211
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
212
int64_t offset, int bytes, BdrvRequestFlags flags)
213
{
214
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
215
int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX);
216
int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
217
bs->bl.request_alignment);
218
- int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
219
- MAX_WRITE_ZEROES_BOUNCE_BUFFER);
220
+ int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER);
221
222
assert(alignment % bs->bl.request_alignment == 0);
223
head = offset % alignment;
224
--
75
--
225
2.13.6
76
2.25.3
226
77
227
78
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
We want to keep TEST_IMG for the full path of the main test image, but
2
filter_testfiles() must be called for other test images before replacing
3
other things like the image format because the test directory path could
4
contain the format as a substring.
2
5
3
Add a test for qcow2 copy-on-read behavior, including exposure
6
Insert a filter_testfiles() call between both.
4
for the just-fixed bugs.
5
7
6
The copy-on-read behavior is always to a qcow2 image, but the
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
test is careful to allow running with most image protocol/format
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
combos as the backing file being copied from (luks being the
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
exception, as it is harder to pass the right secret to all the
11
Message-Id: <20200424125448.63318-9-kwolf@redhat.com>
10
right places). In fact, for './check nbd', this appears to be
11
the first time we've had a qcow2 image wrapping NBD, requiring
12
an additional line in _filter_img_create to match the similar
13
line in _filter_img_info.
14
15
Invoking blkdebug to prove we don't write too much took some
16
effort to get working; and it requires that $TEST_WRAP (based
17
on $TEST_DIR) not be subject to word splitting. We may decide
18
later to have the entire iotests suite use relative rather than
19
absolute names, to avoid problems inherited by the absolute
20
name of $PWD or $TEST_DIR, at which point the sanity check in
21
this commit could be simplified.
22
23
This test requires at least 2G of consecutive memory to succeed;
24
as such, it is prone to spurious failures, particularly on
25
32-bit machines under load. This situation is detected and
26
triggers an early exit to skip the test, rather than a failure.
27
To manually provoke this setup on a beefier machine, I used:
28
$ (ulimit -S -v 1000000; ./check -qcow2 197)
29
30
Signed-off-by: Eric Blake <eblake@redhat.com>
31
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
32
---
13
---
33
tests/qemu-iotests/197 | 109 +++++++++++++++++++++++++++++++++++++++
14
tests/qemu-iotests/iotests.py | 5 +++--
34
tests/qemu-iotests/197.out | 26 ++++++++++
15
1 file changed, 3 insertions(+), 2 deletions(-)
35
tests/qemu-iotests/common.filter | 1 +
36
tests/qemu-iotests/group | 1 +
37
4 files changed, 137 insertions(+)
38
create mode 100755 tests/qemu-iotests/197
39
create mode 100644 tests/qemu-iotests/197.out
40
16
41
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
17
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
42
new file mode 100755
43
index XXXXXXX..XXXXXXX
44
--- /dev/null
45
+++ b/tests/qemu-iotests/197
46
@@ -XXX,XX +XXX,XX @@
47
+#!/bin/bash
48
+#
49
+# Test case for copy-on-read into qcow2
50
+#
51
+# Copyright (C) 2017 Red Hat, Inc.
52
+#
53
+# This program is free software; you can redistribute it and/or modify
54
+# it under the terms of the GNU General Public License as published by
55
+# the Free Software Foundation; either version 2 of the License, or
56
+# (at your option) any later version.
57
+#
58
+# This program is distributed in the hope that it will be useful,
59
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
60
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61
+# GNU General Public License for more details.
62
+#
63
+# You should have received a copy of the GNU General Public License
64
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
65
+#
66
+
67
+# creator
68
+owner=eblake@redhat.com
69
+
70
+seq="$(basename $0)"
71
+echo "QA output created by $seq"
72
+
73
+here="$PWD"
74
+status=1 # failure is the default!
75
+
76
+# get standard environment, filters and checks
77
+. ./common.rc
78
+. ./common.filter
79
+
80
+TEST_WRAP="$TEST_DIR/t.wrap.qcow2"
81
+BLKDBG_CONF="$TEST_DIR/blkdebug.conf"
82
+
83
+# Sanity check: our use of blkdebug fails if $TEST_DIR contains spaces
84
+# or other problems
85
+case "$TEST_DIR" in
86
+ *[^-_a-zA-Z0-9/]*)
87
+ _notrun "Suspicious TEST_DIR='$TEST_DIR', cowardly refusing to run" ;;
88
+esac
89
+
90
+_cleanup()
91
+{
92
+ _cleanup_test_img
93
+ rm -f "$BLKDBG_CONF"
94
+}
95
+trap "_cleanup; exit \$status" 0 1 2 3 15
96
+
97
+# Test is supported for any backing file; but we force qcow2 for our wrapper.
98
+_supported_fmt generic
99
+_supported_proto generic
100
+_supported_os Linux
101
+# LUKS support may be possible, but it complicates things.
102
+_unsupported_fmt luks
103
+
104
+echo
105
+echo '=== Copy-on-read ==='
106
+echo
107
+
108
+# Prep the images
109
+_make_test_img 4G
110
+$QEMU_IO -c "write -P 55 3G 1k" "$TEST_IMG" | _filter_qemu_io
111
+IMGPROTO=file IMGFMT=qcow2 IMGOPTS= TEST_IMG_FILE="$TEST_WRAP" \
112
+ _make_test_img -F "$IMGFMT" -b "$TEST_IMG" | _filter_img_create
113
+$QEMU_IO -f qcow2 -c "write -z -u 1M 64k" "$TEST_WRAP" | _filter_qemu_io
114
+
115
+# Ensure that a read of two clusters, but where one is already allocated,
116
+# does not re-write the allocated cluster
117
+cat > "$BLKDBG_CONF" <<EOF
118
+[inject-error]
119
+event = "cor_write"
120
+sector = "2048"
121
+EOF
122
+$QEMU_IO -c "open -C \
123
+ -o driver=blkdebug,config=$BLKDBG_CONF,image.driver=qcow2 $TEST_WRAP" \
124
+ -c "read -P 0 1M 128k" | _filter_qemu_io
125
+
126
+# Read the areas we want copied. A zero-length read should still be a
127
+# no-op. The next read is under 2G, but aligned so that rounding to
128
+# clusters copies more than 2G of zeroes. The final read will pick up
129
+# the non-zero data in the same cluster. Since a 2G read may exhaust
130
+# memory on some machines (particularly 32-bit), we skip the test if
131
+# that fails due to memory pressure.
132
+$QEMU_IO -f qcow2 -C -c "read 0 0" "$TEST_WRAP" | _filter_qemu_io
133
+output=$($QEMU_IO -f qcow2 -C -c "read -P 0 1k $((2*1024*1024*1024 - 512))" \
134
+ "$TEST_WRAP" 2>&1 | _filter_qemu_io)
135
+case $output in
136
+ *allocate*)
137
+ _notrun "Insufficent memory to run test" ;;
138
+ *) printf '%s\n' "$output" ;;
139
+esac
140
+$QEMU_IO -f qcow2 -C -c "read -P 0 $((3*1024*1024*1024 + 1024)) 1k" \
141
+ "$TEST_WRAP" | _filter_qemu_io
142
+
143
+# Copy-on-read is incompatible with read-only
144
+$QEMU_IO -f qcow2 -C -r "$TEST_WRAP" 2>&1 | _filter_testdir
145
+
146
+# Break the backing chain, and show that images are identical, and that
147
+# we properly copied over explicit zeros.
148
+$QEMU_IMG rebase -u -b "" -f qcow2 "$TEST_WRAP"
149
+$QEMU_IO -f qcow2 -c map "$TEST_WRAP"
150
+_check_test_img
151
+$QEMU_IMG compare -f $IMGFMT -F qcow2 "$TEST_IMG" "$TEST_WRAP"
152
+
153
+# success, all done
154
+echo '*** done'
155
+status=0
156
diff --git a/tests/qemu-iotests/197.out b/tests/qemu-iotests/197.out
157
new file mode 100644
158
index XXXXXXX..XXXXXXX
159
--- /dev/null
160
+++ b/tests/qemu-iotests/197.out
161
@@ -XXX,XX +XXX,XX @@
162
+QA output created by 197
163
+
164
+=== Copy-on-read ===
165
+
166
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296
167
+wrote 1024/1024 bytes at offset 3221225472
168
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
169
+Formatting 'TEST_DIR/t.wrap.IMGFMT', fmt=IMGFMT size=4294967296 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
170
+wrote 65536/65536 bytes at offset 1048576
171
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
172
+read 131072/131072 bytes at offset 1048576
173
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
174
+read 0/0 bytes at offset 0
175
+0 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
176
+read 2147483136/2147483136 bytes at offset 1024
177
+2 GiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
178
+read 1024/1024 bytes at offset 3221226496
179
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
180
+can't open device TEST_DIR/t.wrap.qcow2: Can't use copy-on-read on read-only device
181
+2 GiB (0x80010000) bytes allocated at offset 0 bytes (0x0)
182
+1023.938 MiB (0x3fff0000) bytes not allocated at offset 2 GiB (0x80010000)
183
+64 KiB (0x10000) bytes allocated at offset 3 GiB (0xc0000000)
184
+1023.938 MiB (0x3fff0000) bytes not allocated at offset 3 GiB (0xc0010000)
185
+No errors were found on the image.
186
+Images are identical.
187
+*** done
188
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
189
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
190
--- a/tests/qemu-iotests/common.filter
19
--- a/tests/qemu-iotests/iotests.py
191
+++ b/tests/qemu-iotests/common.filter
20
+++ b/tests/qemu-iotests/iotests.py
192
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
21
@@ -XXX,XX +XXX,XX @@ def filter_img_info(output, filename):
193
sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
22
for line in output.split('\n'):
194
-e "s#$TEST_DIR#TEST_DIR#g" \
23
if 'disk size' in line or 'actual-size' in line:
195
-e "s#$IMGFMT#IMGFMT#g" \
24
continue
196
+ -e 's#nbd:127.0.0.1:10810#TEST_DIR/t.IMGFMT#g' \
25
- line = line.replace(filename, 'TEST_IMG') \
197
-e "s# encryption=off##g" \
26
- .replace(imgfmt, 'IMGFMT')
198
-e "s# cluster_size=[0-9]\\+##g" \
27
+ line = line.replace(filename, 'TEST_IMG')
199
-e "s# table_size=[0-9]\\+##g" \
28
+ line = filter_testfiles(line)
200
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
29
+ line = line.replace(imgfmt, 'IMGFMT')
201
index XXXXXXX..XXXXXXX 100644
30
line = re.sub('iters: [0-9]+', 'iters: XXX', line)
202
--- a/tests/qemu-iotests/group
31
line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
203
+++ b/tests/qemu-iotests/group
32
line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
204
@@ -XXX,XX +XXX,XX @@
205
192 rw auto quick
206
194 rw auto migration quick
207
195 rw auto quick
208
+197 rw auto quick
209
--
33
--
210
2.13.6
34
2.25.3
211
35
212
36
diff view generated by jsdifflib
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Message-Id: <20200424125448.63318-10-kwolf@redhat.com>
3
Reviewed-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
---
6
---
3
tests/qemu-iotests/191 | 153 +++++++++
7
tests/qemu-iotests/274 | 155 +++++++++++++++++++++
4
tests/qemu-iotests/191.out | 827 +++++++++++++++++++++++++++++++++++++++++++++
8
tests/qemu-iotests/274.out | 268 +++++++++++++++++++++++++++++++++++++
5
tests/qemu-iotests/group | 1 +
9
tests/qemu-iotests/group | 1 +
6
3 files changed, 981 insertions(+)
10
3 files changed, 424 insertions(+)
7
create mode 100755 tests/qemu-iotests/191
11
create mode 100755 tests/qemu-iotests/274
8
create mode 100644 tests/qemu-iotests/191.out
12
create mode 100644 tests/qemu-iotests/274.out
9
13
10
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
14
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
11
new file mode 100755
15
new file mode 100755
12
index XXXXXXX..XXXXXXX
16
index XXXXXXX..XXXXXXX
13
--- /dev/null
17
--- /dev/null
14
+++ b/tests/qemu-iotests/191
18
+++ b/tests/qemu-iotests/274
15
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
16
+#!/bin/bash
20
+#!/usr/bin/env python3
17
+#
21
+#
18
+# Test commit block job where top has two parents
22
+# Copyright (C) 2019 Red Hat, Inc.
19
+#
20
+# Copyright (C) 2017 Red Hat, Inc.
21
+#
23
+#
22
+# This program is free software; you can redistribute it and/or modify
24
+# This program is free software; you can redistribute it and/or modify
23
+# it under the terms of the GNU General Public License as published by
25
+# it under the terms of the GNU General Public License as published by
24
+# the Free Software Foundation; either version 2 of the License, or
26
+# the Free Software Foundation; either version 2 of the License, or
25
+# (at your option) any later version.
27
+# (at your option) any later version.
...
...
30
+# GNU General Public License for more details.
32
+# GNU General Public License for more details.
31
+#
33
+#
32
+# You should have received a copy of the GNU General Public License
34
+# You should have received a copy of the GNU General Public License
33
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
35
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
34
+#
36
+#
35
+
37
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
36
+# creator
38
+#
37
+owner=kwolf@redhat.com
39
+# Some tests for short backing files and short overlays
38
+
40
+
39
+seq=`basename $0`
41
+import iotests
40
+echo "QA output created by $seq"
42
+
41
+
43
+iotests.verify_image_format(supported_fmts=['qcow2'])
42
+here=`pwd`
44
+iotests.verify_platform(['linux'])
43
+status=1 # failure is the default!
45
+
44
+
46
+size_short = 1 * 1024 * 1024
45
+MIG_SOCKET="${TEST_DIR}/migrate"
47
+size_long = 2 * 1024 * 1024
46
+
48
+size_diff = size_long - size_short
47
+_cleanup()
49
+
48
+{
50
+def create_chain() -> None:
49
+ rm -f "${TEST_IMG}.mid"
51
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
50
+ rm -f "${TEST_IMG}.ovl2"
52
+ str(size_long))
51
+ rm -f "${TEST_IMG}.ovl3"
53
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid,
52
+ _cleanup_test_img
54
+ str(size_short))
53
+ _cleanup_qemu
55
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top,
54
+}
56
+ str(size_long))
55
+trap "_cleanup; exit \$status" 0 1 2 3 15
57
+
56
+
58
+ iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)
57
+# get standard environment, filters and checks
59
+
58
+. ./common.rc
60
+def create_vm() -> iotests.VM:
59
+. ./common.filter
61
+ vm = iotests.VM()
60
+. ./common.qemu
62
+ vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
61
+
63
+ vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
62
+_supported_fmt qcow2
64
+ vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
63
+_unsupported_imgopts compat=0.10
65
+ vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
64
+_supported_proto file
66
+ % iotests.imgfmt)
65
+_supported_os Linux
67
+ vm.add_drive(top, 'backing=mid,node-name=top')
66
+
68
+ return vm
67
+size=64M
69
+
68
+
70
+with iotests.FilePath('base') as base, \
69
+echo
71
+ iotests.FilePath('mid') as mid, \
70
+echo === Preparing and starting VM ===
72
+ iotests.FilePath('top') as top:
71
+echo
73
+
72
+
74
+ iotests.log('== Commit tests ==')
73
+TEST_IMG="${TEST_IMG}.base" _make_test_img $size
75
+
74
+TEST_IMG="${TEST_IMG}.mid" _make_test_img -b "${TEST_IMG}.base"
76
+ create_chain()
75
+_make_test_img -b "${TEST_IMG}.mid"
77
+
76
+TEST_IMG="${TEST_IMG}.ovl2" _make_test_img -b "${TEST_IMG}.mid"
78
+ iotests.log('=== Check visible data ===')
77
+
79
+
78
+$QEMU_IO -c 'write -P 0x55 1M 64k' "${TEST_IMG}.mid" | _filter_qemu_io
80
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
79
+
81
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)
80
+qemu_comm_method="qmp"
82
+
81
+qmp_pretty="y"
83
+ iotests.log('=== Checking allocation status ===')
82
+
84
+
83
+_launch_qemu \
85
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
84
+ -blockdev "driver=${IMGFMT},file.driver=file,file.filename=${TEST_IMG}.base,node-name=base" \
86
+ '-c', 'alloc %d %d' % (size_short, size_diff),
85
+ -blockdev "driver=${IMGFMT},file.driver=file,file.filename=${TEST_IMG}.mid,node-name=mid,backing=base" \
87
+ base)
86
+ -blockdev "driver=${IMGFMT},file.driver=file,file.filename=${TEST_IMG},node-name=top,backing=mid" \
88
+
87
+ -blockdev "driver=${IMGFMT},file.driver=file,file.filename=${TEST_IMG}.ovl2,node-name=top2,backing=mid"
89
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
88
+h=$QEMU_HANDLE
90
+ '-c', 'alloc %d %d' % (size_short, size_diff),
89
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" '^}'
91
+ mid)
90
+
92
+
91
+echo
93
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
92
+echo === Perform commit job ===
94
+ '-c', 'alloc %d %d' % (size_short, size_diff),
93
+echo
95
+ top)
94
+
96
+
95
+_send_qemu_cmd $h \
97
+ iotests.log('=== Checking map ===')
96
+ "{ 'execute': 'block-commit',
98
+
97
+ 'arguments': { 'job-id': 'commit0',
99
+ iotests.qemu_img_log('map', '--output=json', base)
98
+ 'device': 'top',
100
+ iotests.qemu_img_log('map', '--output=human', base)
99
+ 'base':'$TEST_IMG.base',
101
+ iotests.qemu_img_log('map', '--output=json', mid)
100
+ 'top': '$TEST_IMG.mid' } }" \
102
+ iotests.qemu_img_log('map', '--output=human', mid)
101
+ "BLOCK_JOB_COMPLETED"
103
+ iotests.qemu_img_log('map', '--output=json', top)
102
+_send_qemu_cmd $h "" "^}"
104
+ iotests.qemu_img_log('map', '--output=human', top)
103
+
105
+
104
+echo
106
+ iotests.log('=== Testing qemu-img commit (top -> mid) ===')
105
+echo === Check that both top and top2 point to base now ===
107
+
106
+echo
108
+ iotests.qemu_img_log('commit', top)
107
+
109
+ iotests.img_info_log(mid)
108
+_send_qemu_cmd $h "{ 'execute': 'query-named-block-nodes' }" "^}" |
110
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
109
+ _filter_generated_node_ids
111
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
110
+
112
+
111
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "^}"
113
+ iotests.log('=== Testing HMP commit (top -> mid) ===')
112
+wait=1 _cleanup_qemu
114
+
113
+
115
+ create_chain()
114
+_img_info
116
+ with create_vm() as vm:
115
+TEST_IMG="$TEST_IMG.ovl2" _img_info
117
+ vm.launch()
116
+
118
+ vm.qmp_log('human-monitor-command', command_line='commit drive0')
117
+
119
+
118
+echo
120
+ iotests.img_info_log(mid)
119
+echo === Preparing and starting VM with -drive ===
121
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
120
+echo
122
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
121
+
123
+
122
+TEST_IMG="${TEST_IMG}.base" _make_test_img $size
124
+ iotests.log('=== Testing QMP active commit (top -> mid) ===')
123
+TEST_IMG="${TEST_IMG}.mid" _make_test_img -b "${TEST_IMG}.base"
125
+
124
+_make_test_img -b "${TEST_IMG}.mid"
126
+ create_chain()
125
+TEST_IMG="${TEST_IMG}.ovl2" _make_test_img -b "${TEST_IMG}.mid"
127
+ with create_vm() as vm:
126
+TEST_IMG="${TEST_IMG}.ovl3" _make_test_img -b "${TEST_IMG}.ovl2"
128
+ vm.launch()
127
+
129
+ vm.qmp_log('block-commit', device='top', base_node='mid',
128
+$QEMU_IO -c 'write -P 0x55 1M 64k' "${TEST_IMG}.mid" | _filter_qemu_io
130
+ job_id='job0', auto_dismiss=False)
129
+
131
+ vm.run_job('job0', wait=5)
130
+qemu_comm_method="qmp"
132
+
131
+qmp_pretty="y"
133
+ iotests.img_info_log(mid)
132
+
134
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
133
+_launch_qemu \
135
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
134
+ -drive "driver=${IMGFMT},file=${TEST_IMG},node-name=top,backing.node-name=mid" \
136
+
135
+ -drive "driver=${IMGFMT},file=${TEST_IMG}.ovl3,node-name=top2,backing.backing=mid"
137
+
136
+h=$QEMU_HANDLE
138
+ iotests.log('== Resize tests ==')
137
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" '^}'
139
+
138
+
140
+ # Use different sizes for different allocation modes:
139
+echo
141
+ #
140
+echo === Perform commit job ===
142
+ # We want to have at least one test where 32 bit truncation in the size of
141
+echo
143
+ # the overlapping area becomes visible. This is covered by the
142
+
144
+ # prealloc='off' case (1G to 6G is an overlap of 5G).
143
+_send_qemu_cmd $h \
145
+ #
144
+ "{ 'execute': 'block-commit',
146
+ # However, we can only do this for modes that don't preallocate data
145
+ 'arguments': { 'job-id': 'commit0',
147
+ # because otherwise we might run out of space on the test host.
146
+ 'device': 'top',
148
+ #
147
+ 'base':'$TEST_IMG.base',
149
+ # We also want to test some unaligned combinations.
148
+ 'top': '$TEST_IMG.mid' } }" \
150
+ for (prealloc, base_size, top_size_old, top_size_new, off) in [
149
+ "BLOCK_JOB_COMPLETED"
151
+ ('off', '6G', '1G', '8G', '5G'),
150
+_send_qemu_cmd $h "" "^}"
152
+ ('metadata', '32G', '30G', '33G', '31G'),
151
+
153
+ ('falloc', '10M', '5M', '15M', '9M'),
152
+echo
154
+ ('full', '16M', '8M', '12M', '11M'),
153
+echo === Check that both top and top2 point to base now ===
155
+ ('off', '384k', '253k', '512k', '253k'),
154
+echo
156
+ ('off', '400k', '256k', '512k', '336k'),
155
+
157
+ ('off', '512k', '256k', '500k', '436k')]:
156
+_send_qemu_cmd $h "{ 'execute': 'query-named-block-nodes' }" "^}" |
158
+
157
+ _filter_generated_node_ids
159
+ iotests.log('=== preallocation=%s ===' % prealloc)
158
+
160
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
159
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "^}"
161
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top,
160
+wait=1 _cleanup_qemu
162
+ top_size_old)
161
+
163
+ iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)
162
+_img_info
164
+
163
+TEST_IMG="$TEST_IMG.ovl2" _img_info
165
+ # After this, top_size_old to base_size should be allocated/zeroed.
164
+
166
+ #
165
+# success, all done
167
+ # In theory, leaving base_size to top_size_new unallocated would be
166
+echo "*** done"
168
+ # correct, but in practice, if we zero out anything, we zero out
167
+rm -f $seq.full
169
+ # everything up to top_size_new.
168
+status=0
170
+ iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
169
diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
171
+ '--preallocation', prealloc, top, top_size_new)
172
+ iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
173
+ iotests.qemu_io_log('-c', 'map', top)
174
+ iotests.qemu_img_log('map', '--output=json', top)
175
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
170
new file mode 100644
176
new file mode 100644
171
index XXXXXXX..XXXXXXX
177
index XXXXXXX..XXXXXXX
172
--- /dev/null
178
--- /dev/null
173
+++ b/tests/qemu-iotests/191.out
179
+++ b/tests/qemu-iotests/274.out
174
@@ -XXX,XX +XXX,XX @@
180
@@ -XXX,XX +XXX,XX @@
175
+QA output created by 191
181
+== Commit tests ==
176
+
182
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
177
+=== Preparing and starting VM ===
183
+
178
+
184
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
179
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
185
+
180
+Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
186
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
181
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
187
+
182
+Formatting 'TEST_DIR/t.IMGFMT.ovl2', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
188
+wrote 2097152/2097152 bytes at offset 0
183
+wrote 65536/65536 bytes at offset 1048576
189
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
184
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
190
+
185
+{
191
+=== Check visible data ===
186
+ "return": {
192
+read 1048576/1048576 bytes at offset 0
187
+ }
193
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
188
+}
194
+
189
+
195
+read 1048576/1048576 bytes at offset 1048576
190
+=== Perform commit job ===
196
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
191
+
197
+
192
+{
198
+=== Checking allocation status ===
193
+ "return": {
199
+1048576/1048576 bytes allocated at offset 0 bytes
194
+ }
200
+1048576/1048576 bytes allocated at offset 1 MiB
195
+}
201
+
196
+{
202
+0/1048576 bytes allocated at offset 0 bytes
197
+ "timestamp": {
203
+0/0 bytes allocated at offset 1 MiB
198
+ "seconds": TIMESTAMP,
204
+
199
+ "microseconds": TIMESTAMP
205
+0/1048576 bytes allocated at offset 0 bytes
200
+ },
206
+0/1048576 bytes allocated at offset 1 MiB
201
+ "event": "BLOCK_JOB_COMPLETED",
207
+
202
+ "data": {
208
+=== Checking map ===
203
+ "device": "commit0",
209
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": 327680}]
204
+ "len": 67108864,
210
+
205
+ "offset": 67108864,
211
+Offset Length Mapped to File
206
+ "speed": 0,
212
+0 0x200000 0x50000 TEST_DIR/PID-base
207
+ "type": "commit"
213
+
208
+ }
214
+[{ "start": 0, "length": 1048576, "depth": 1, "zero": false, "data": true, "offset": 327680}]
209
+}
215
+
210
+
216
+Offset Length Mapped to File
211
+=== Check that both top and top2 point to base now ===
217
+0 0x100000 0x50000 TEST_DIR/PID-base
212
+
218
+
213
+{
219
+[{ "start": 0, "length": 1048576, "depth": 2, "zero": false, "data": true, "offset": 327680},
214
+ "return": [
220
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": true, "data": false}]
215
+ {
221
+
216
+ "iops_rd": 0,
222
+Offset Length Mapped to File
217
+ "detect_zeroes": "off",
223
+0 0x100000 0x50000 TEST_DIR/PID-base
218
+ "image": {
224
+
219
+ "backing-image": {
225
+=== Testing qemu-img commit (top -> mid) ===
220
+ "virtual-size": 67108864,
226
+Image committed.
221
+ "filename": "TEST_DIR/t.qcow2.base",
227
+
222
+ "cluster-size": 65536,
228
+image: TEST_IMG
223
+ "format": "qcow2",
224
+ "actual-size": 397312,
225
+ "format-specific": {
226
+ "type": "qcow2",
227
+ "data": {
228
+ "compat": "1.1",
229
+ "lazy-refcounts": false,
230
+ "refcount-bits": 16,
231
+ "corrupt": false
232
+ }
233
+ },
234
+ "dirty-flag": false
235
+ },
236
+ "backing-filename-format": "qcow2",
237
+ "virtual-size": 67108864,
238
+ "filename": "TEST_DIR/t.qcow2.ovl2",
239
+ "cluster-size": 65536,
240
+ "format": "qcow2",
241
+ "actual-size": 200704,
242
+ "format-specific": {
243
+ "type": "qcow2",
244
+ "data": {
245
+ "compat": "1.1",
246
+ "lazy-refcounts": false,
247
+ "refcount-bits": 16,
248
+ "corrupt": false
249
+ }
250
+ },
251
+ "full-backing-filename": "TEST_DIR/t.qcow2.base",
252
+ "backing-filename": "TEST_DIR/t.qcow2.base",
253
+ "dirty-flag": false
254
+ },
255
+ "iops_wr": 0,
256
+ "ro": false,
257
+ "node-name": "top2",
258
+ "backing_file_depth": 1,
259
+ "drv": "qcow2",
260
+ "iops": 0,
261
+ "bps_wr": 0,
262
+ "write_threshold": 0,
263
+ "backing_file": "TEST_DIR/t.qcow2.base",
264
+ "encrypted": false,
265
+ "bps": 0,
266
+ "bps_rd": 0,
267
+ "cache": {
268
+ "no-flush": false,
269
+ "direct": false,
270
+ "writeback": true
271
+ },
272
+ "file": "TEST_DIR/t.qcow2.ovl2",
273
+ "encryption_key_missing": false
274
+ },
275
+ {
276
+ "iops_rd": 0,
277
+ "detect_zeroes": "off",
278
+ "image": {
279
+ "virtual-size": 197120,
280
+ "filename": "TEST_DIR/t.qcow2.ovl2",
281
+ "format": "file",
282
+ "actual-size": 200704,
283
+ "dirty-flag": false
284
+ },
285
+ "iops_wr": 0,
286
+ "ro": false,
287
+ "node-name": "NODE_NAME",
288
+ "backing_file_depth": 0,
289
+ "drv": "file",
290
+ "iops": 0,
291
+ "bps_wr": 0,
292
+ "write_threshold": 0,
293
+ "encrypted": false,
294
+ "bps": 0,
295
+ "bps_rd": 0,
296
+ "cache": {
297
+ "no-flush": false,
298
+ "direct": false,
299
+ "writeback": true
300
+ },
301
+ "file": "TEST_DIR/t.qcow2.ovl2",
302
+ "encryption_key_missing": false
303
+ },
304
+ {
305
+ "iops_rd": 0,
306
+ "detect_zeroes": "off",
307
+ "image": {
308
+ "backing-image": {
309
+ "virtual-size": 67108864,
310
+ "filename": "TEST_DIR/t.qcow2.base",
311
+ "cluster-size": 65536,
312
+ "format": "qcow2",
313
+ "actual-size": 397312,
314
+ "format-specific": {
315
+ "type": "qcow2",
316
+ "data": {
317
+ "compat": "1.1",
318
+ "lazy-refcounts": false,
319
+ "refcount-bits": 16,
320
+ "corrupt": false
321
+ }
322
+ },
323
+ "dirty-flag": false
324
+ },
325
+ "backing-filename-format": "qcow2",
326
+ "virtual-size": 67108864,
327
+ "filename": "TEST_DIR/t.qcow2",
328
+ "cluster-size": 65536,
329
+ "format": "qcow2",
330
+ "actual-size": 200704,
331
+ "format-specific": {
332
+ "type": "qcow2",
333
+ "data": {
334
+ "compat": "1.1",
335
+ "lazy-refcounts": false,
336
+ "refcount-bits": 16,
337
+ "corrupt": false
338
+ }
339
+ },
340
+ "full-backing-filename": "TEST_DIR/t.qcow2.base",
341
+ "backing-filename": "TEST_DIR/t.qcow2.base",
342
+ "dirty-flag": false
343
+ },
344
+ "iops_wr": 0,
345
+ "ro": false,
346
+ "node-name": "top",
347
+ "backing_file_depth": 1,
348
+ "drv": "qcow2",
349
+ "iops": 0,
350
+ "bps_wr": 0,
351
+ "write_threshold": 0,
352
+ "backing_file": "TEST_DIR/t.qcow2.base",
353
+ "encrypted": false,
354
+ "bps": 0,
355
+ "bps_rd": 0,
356
+ "cache": {
357
+ "no-flush": false,
358
+ "direct": false,
359
+ "writeback": true
360
+ },
361
+ "file": "TEST_DIR/t.qcow2",
362
+ "encryption_key_missing": false
363
+ },
364
+ {
365
+ "iops_rd": 0,
366
+ "detect_zeroes": "off",
367
+ "image": {
368
+ "virtual-size": 197120,
369
+ "filename": "TEST_DIR/t.qcow2",
370
+ "format": "file",
371
+ "actual-size": 200704,
372
+ "dirty-flag": false
373
+ },
374
+ "iops_wr": 0,
375
+ "ro": false,
376
+ "node-name": "NODE_NAME",
377
+ "backing_file_depth": 0,
378
+ "drv": "file",
379
+ "iops": 0,
380
+ "bps_wr": 0,
381
+ "write_threshold": 0,
382
+ "encrypted": false,
383
+ "bps": 0,
384
+ "bps_rd": 0,
385
+ "cache": {
386
+ "no-flush": false,
387
+ "direct": false,
388
+ "writeback": true
389
+ },
390
+ "file": "TEST_DIR/t.qcow2",
391
+ "encryption_key_missing": false
392
+ },
393
+ {
394
+ "iops_rd": 0,
395
+ "detect_zeroes": "off",
396
+ "image": {
397
+ "backing-image": {
398
+ "virtual-size": 67108864,
399
+ "filename": "TEST_DIR/t.qcow2.base",
400
+ "cluster-size": 65536,
401
+ "format": "qcow2",
402
+ "actual-size": 397312,
403
+ "format-specific": {
404
+ "type": "qcow2",
405
+ "data": {
406
+ "compat": "1.1",
407
+ "lazy-refcounts": false,
408
+ "refcount-bits": 16,
409
+ "corrupt": false
410
+ }
411
+ },
412
+ "dirty-flag": false
413
+ },
414
+ "backing-filename-format": "qcow2",
415
+ "virtual-size": 67108864,
416
+ "filename": "TEST_DIR/t.qcow2.mid",
417
+ "cluster-size": 65536,
418
+ "format": "qcow2",
419
+ "actual-size": 397312,
420
+ "format-specific": {
421
+ "type": "qcow2",
422
+ "data": {
423
+ "compat": "1.1",
424
+ "lazy-refcounts": false,
425
+ "refcount-bits": 16,
426
+ "corrupt": false
427
+ }
428
+ },
429
+ "full-backing-filename": "TEST_DIR/t.qcow2.base",
430
+ "backing-filename": "TEST_DIR/t.qcow2.base",
431
+ "dirty-flag": false
432
+ },
433
+ "iops_wr": 0,
434
+ "ro": false,
435
+ "node-name": "mid",
436
+ "backing_file_depth": 1,
437
+ "drv": "qcow2",
438
+ "iops": 0,
439
+ "bps_wr": 0,
440
+ "write_threshold": 0,
441
+ "backing_file": "TEST_DIR/t.qcow2.base",
442
+ "encrypted": false,
443
+ "bps": 0,
444
+ "bps_rd": 0,
445
+ "cache": {
446
+ "no-flush": false,
447
+ "direct": false,
448
+ "writeback": true
449
+ },
450
+ "file": "TEST_DIR/t.qcow2.mid",
451
+ "encryption_key_missing": false
452
+ },
453
+ {
454
+ "iops_rd": 0,
455
+ "detect_zeroes": "off",
456
+ "image": {
457
+ "virtual-size": 393216,
458
+ "filename": "TEST_DIR/t.qcow2.mid",
459
+ "format": "file",
460
+ "actual-size": 397312,
461
+ "dirty-flag": false
462
+ },
463
+ "iops_wr": 0,
464
+ "ro": false,
465
+ "node-name": "NODE_NAME",
466
+ "backing_file_depth": 0,
467
+ "drv": "file",
468
+ "iops": 0,
469
+ "bps_wr": 0,
470
+ "write_threshold": 0,
471
+ "encrypted": false,
472
+ "bps": 0,
473
+ "bps_rd": 0,
474
+ "cache": {
475
+ "no-flush": false,
476
+ "direct": false,
477
+ "writeback": true
478
+ },
479
+ "file": "TEST_DIR/t.qcow2.mid",
480
+ "encryption_key_missing": false
481
+ },
482
+ {
483
+ "iops_rd": 0,
484
+ "detect_zeroes": "off",
485
+ "image": {
486
+ "virtual-size": 67108864,
487
+ "filename": "TEST_DIR/t.qcow2.base",
488
+ "cluster-size": 65536,
489
+ "format": "qcow2",
490
+ "actual-size": 397312,
491
+ "format-specific": {
492
+ "type": "qcow2",
493
+ "data": {
494
+ "compat": "1.1",
495
+ "lazy-refcounts": false,
496
+ "refcount-bits": 16,
497
+ "corrupt": false
498
+ }
499
+ },
500
+ "dirty-flag": false
501
+ },
502
+ "iops_wr": 0,
503
+ "ro": false,
504
+ "node-name": "base",
505
+ "backing_file_depth": 0,
506
+ "drv": "qcow2",
507
+ "iops": 0,
508
+ "bps_wr": 0,
509
+ "write_threshold": 0,
510
+ "encrypted": false,
511
+ "bps": 0,
512
+ "bps_rd": 0,
513
+ "cache": {
514
+ "no-flush": false,
515
+ "direct": false,
516
+ "writeback": true
517
+ },
518
+ "file": "TEST_DIR/t.qcow2.base",
519
+ "encryption_key_missing": false
520
+ },
521
+ {
522
+ "iops_rd": 0,
523
+ "detect_zeroes": "off",
524
+ "image": {
525
+ "virtual-size": 393216,
526
+ "filename": "TEST_DIR/t.qcow2.base",
527
+ "format": "file",
528
+ "actual-size": 397312,
529
+ "dirty-flag": false
530
+ },
531
+ "iops_wr": 0,
532
+ "ro": false,
533
+ "node-name": "NODE_NAME",
534
+ "backing_file_depth": 0,
535
+ "drv": "file",
536
+ "iops": 0,
537
+ "bps_wr": 0,
538
+ "write_threshold": 0,
539
+ "encrypted": false,
540
+ "bps": 0,
541
+ "bps_rd": 0,
542
+ "cache": {
543
+ "no-flush": false,
544
+ "direct": false,
545
+ "writeback": true
546
+ },
547
+ "file": "TEST_DIR/t.qcow2.base",
548
+ "encryption_key_missing": false
549
+ }
550
+ ]
551
+}
552
+{
553
+ "return": {
554
+ }
555
+}
556
+{
557
+ "timestamp": {
558
+ "seconds": TIMESTAMP,
559
+ "microseconds": TIMESTAMP
560
+ },
561
+ "event": "SHUTDOWN",
562
+ "data": {
563
+ "guest": false
564
+ }
565
+}
566
+image: TEST_DIR/t.IMGFMT
567
+file format: IMGFMT
229
+file format: IMGFMT
568
+virtual size: 64M (67108864 bytes)
230
+virtual size: 2 MiB (2097152 bytes)
569
+cluster_size: 65536
231
+cluster_size: 65536
570
+backing file: TEST_DIR/t.IMGFMT.base
232
+backing file: TEST_DIR/PID-base
571
+backing file format: IMGFMT
233
+Format specific information:
572
+image: TEST_DIR/t.IMGFMT.ovl2
234
+ compat: 1.1
235
+ lazy refcounts: false
236
+ refcount bits: 16
237
+ corrupt: false
238
+
239
+read 1048576/1048576 bytes at offset 0
240
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
241
+
242
+read 1048576/1048576 bytes at offset 1048576
243
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
244
+
245
+=== Testing HMP commit (top -> mid) ===
246
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
247
+
248
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
249
+
250
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
251
+
252
+wrote 2097152/2097152 bytes at offset 0
253
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
254
+
255
+{"execute": "human-monitor-command", "arguments": {"command-line": "commit drive0"}}
256
+{"return": ""}
257
+image: TEST_IMG
573
+file format: IMGFMT
258
+file format: IMGFMT
574
+virtual size: 64M (67108864 bytes)
259
+virtual size: 2 MiB (2097152 bytes)
575
+cluster_size: 65536
260
+cluster_size: 65536
576
+backing file: TEST_DIR/t.IMGFMT.base
261
+backing file: TEST_DIR/PID-base
577
+backing file format: IMGFMT
262
+Format specific information:
578
+
263
+ compat: 1.1
579
+=== Preparing and starting VM with -drive ===
264
+ lazy refcounts: false
580
+
265
+ refcount bits: 16
581
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
266
+ corrupt: false
582
+Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
267
+
583
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
268
+read 1048576/1048576 bytes at offset 0
584
+Formatting 'TEST_DIR/t.IMGFMT.ovl2', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
269
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
585
+Formatting 'TEST_DIR/t.IMGFMT.ovl3', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.ovl2
270
+
586
+wrote 65536/65536 bytes at offset 1048576
271
+read 1048576/1048576 bytes at offset 1048576
587
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
272
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
588
+{
273
+
589
+ "return": {
274
+=== Testing QMP active commit (top -> mid) ===
590
+ }
275
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
591
+}
276
+
592
+
277
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
593
+=== Perform commit job ===
278
+
594
+
279
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
595
+{
280
+
596
+ "return": {
281
+wrote 2097152/2097152 bytes at offset 0
597
+ }
282
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
598
+}
283
+
599
+{
284
+{"execute": "block-commit", "arguments": {"auto-dismiss": false, "base-node": "mid", "device": "top", "job-id": "job0"}}
600
+ "timestamp": {
285
+{"return": {}}
601
+ "seconds": TIMESTAMP,
286
+{"execute": "job-complete", "arguments": {"id": "job0"}}
602
+ "microseconds": TIMESTAMP
287
+{"return": {}}
603
+ },
288
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
604
+ "event": "BLOCK_JOB_COMPLETED",
289
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
605
+ "data": {
290
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
606
+ "device": "commit0",
291
+{"return": {}}
607
+ "len": 67108864,
292
+image: TEST_IMG
608
+ "offset": 67108864,
609
+ "speed": 0,
610
+ "type": "commit"
611
+ }
612
+}
613
+
614
+=== Check that both top and top2 point to base now ===
615
+
616
+{
617
+ "return": [
618
+ {
619
+ "iops_rd": 0,
620
+ "detect_zeroes": "off",
621
+ "image": {
622
+ "backing-image": {
623
+ "virtual-size": 67108864,
624
+ "filename": "TEST_DIR/t.qcow2.base",
625
+ "cluster-size": 65536,
626
+ "format": "qcow2",
627
+ "actual-size": 397312,
628
+ "format-specific": {
629
+ "type": "qcow2",
630
+ "data": {
631
+ "compat": "1.1",
632
+ "lazy-refcounts": false,
633
+ "refcount-bits": 16,
634
+ "corrupt": false
635
+ }
636
+ },
637
+ "dirty-flag": false
638
+ },
639
+ "backing-filename-format": "qcow2",
640
+ "virtual-size": 67108864,
641
+ "filename": "TEST_DIR/t.qcow2.ovl2",
642
+ "cluster-size": 65536,
643
+ "format": "qcow2",
644
+ "actual-size": 200704,
645
+ "format-specific": {
646
+ "type": "qcow2",
647
+ "data": {
648
+ "compat": "1.1",
649
+ "lazy-refcounts": false,
650
+ "refcount-bits": 16,
651
+ "corrupt": false
652
+ }
653
+ },
654
+ "full-backing-filename": "TEST_DIR/t.qcow2.base",
655
+ "backing-filename": "TEST_DIR/t.qcow2.base",
656
+ "dirty-flag": false
657
+ },
658
+ "iops_wr": 0,
659
+ "ro": true,
660
+ "node-name": "NODE_NAME",
661
+ "backing_file_depth": 1,
662
+ "drv": "qcow2",
663
+ "iops": 0,
664
+ "bps_wr": 0,
665
+ "write_threshold": 0,
666
+ "backing_file": "TEST_DIR/t.qcow2.base",
667
+ "encrypted": false,
668
+ "bps": 0,
669
+ "bps_rd": 0,
670
+ "cache": {
671
+ "no-flush": false,
672
+ "direct": false,
673
+ "writeback": true
674
+ },
675
+ "file": "TEST_DIR/t.qcow2.ovl2",
676
+ "encryption_key_missing": false
677
+ },
678
+ {
679
+ "iops_rd": 0,
680
+ "detect_zeroes": "off",
681
+ "image": {
682
+ "virtual-size": 197120,
683
+ "filename": "TEST_DIR/t.qcow2.ovl2",
684
+ "format": "file",
685
+ "actual-size": 200704,
686
+ "dirty-flag": false
687
+ },
688
+ "iops_wr": 0,
689
+ "ro": true,
690
+ "node-name": "NODE_NAME",
691
+ "backing_file_depth": 0,
692
+ "drv": "file",
693
+ "iops": 0,
694
+ "bps_wr": 0,
695
+ "write_threshold": 0,
696
+ "encrypted": false,
697
+ "bps": 0,
698
+ "bps_rd": 0,
699
+ "cache": {
700
+ "no-flush": false,
701
+ "direct": false,
702
+ "writeback": true
703
+ },
704
+ "file": "TEST_DIR/t.qcow2.ovl2",
705
+ "encryption_key_missing": false
706
+ },
707
+ {
708
+ "iops_rd": 0,
709
+ "detect_zeroes": "off",
710
+ "image": {
711
+ "backing-image": {
712
+ "backing-image": {
713
+ "virtual-size": 67108864,
714
+ "filename": "TEST_DIR/t.qcow2.base",
715
+ "cluster-size": 65536,
716
+ "format": "qcow2",
717
+ "actual-size": 397312,
718
+ "format-specific": {
719
+ "type": "qcow2",
720
+ "data": {
721
+ "compat": "1.1",
722
+ "lazy-refcounts": false,
723
+ "refcount-bits": 16,
724
+ "corrupt": false
725
+ }
726
+ },
727
+ "dirty-flag": false
728
+ },
729
+ "backing-filename-format": "qcow2",
730
+ "virtual-size": 67108864,
731
+ "filename": "TEST_DIR/t.qcow2.ovl2",
732
+ "cluster-size": 65536,
733
+ "format": "qcow2",
734
+ "actual-size": 200704,
735
+ "format-specific": {
736
+ "type": "qcow2",
737
+ "data": {
738
+ "compat": "1.1",
739
+ "lazy-refcounts": false,
740
+ "refcount-bits": 16,
741
+ "corrupt": false
742
+ }
743
+ },
744
+ "full-backing-filename": "TEST_DIR/t.qcow2.base",
745
+ "backing-filename": "TEST_DIR/t.qcow2.base",
746
+ "dirty-flag": false
747
+ },
748
+ "backing-filename-format": "qcow2",
749
+ "virtual-size": 67108864,
750
+ "filename": "TEST_DIR/t.qcow2.ovl3",
751
+ "cluster-size": 65536,
752
+ "format": "qcow2",
753
+ "actual-size": 200704,
754
+ "format-specific": {
755
+ "type": "qcow2",
756
+ "data": {
757
+ "compat": "1.1",
758
+ "lazy-refcounts": false,
759
+ "refcount-bits": 16,
760
+ "corrupt": false
761
+ }
762
+ },
763
+ "full-backing-filename": "TEST_DIR/t.qcow2.ovl2",
764
+ "backing-filename": "TEST_DIR/t.qcow2.ovl2",
765
+ "dirty-flag": false
766
+ },
767
+ "iops_wr": 0,
768
+ "ro": false,
769
+ "node-name": "top2",
770
+ "backing_file_depth": 2,
771
+ "drv": "qcow2",
772
+ "iops": 0,
773
+ "bps_wr": 0,
774
+ "write_threshold": 0,
775
+ "backing_file": "TEST_DIR/t.qcow2.ovl2",
776
+ "encrypted": false,
777
+ "bps": 0,
778
+ "bps_rd": 0,
779
+ "cache": {
780
+ "no-flush": false,
781
+ "direct": false,
782
+ "writeback": true
783
+ },
784
+ "file": "TEST_DIR/t.qcow2.ovl3",
785
+ "encryption_key_missing": false
786
+ },
787
+ {
788
+ "iops_rd": 0,
789
+ "detect_zeroes": "off",
790
+ "image": {
791
+ "virtual-size": 197120,
792
+ "filename": "TEST_DIR/t.qcow2.ovl3",
793
+ "format": "file",
794
+ "actual-size": 200704,
795
+ "dirty-flag": false
796
+ },
797
+ "iops_wr": 0,
798
+ "ro": false,
799
+ "node-name": "NODE_NAME",
800
+ "backing_file_depth": 0,
801
+ "drv": "file",
802
+ "iops": 0,
803
+ "bps_wr": 0,
804
+ "write_threshold": 0,
805
+ "encrypted": false,
806
+ "bps": 0,
807
+ "bps_rd": 0,
808
+ "cache": {
809
+ "no-flush": false,
810
+ "direct": false,
811
+ "writeback": true
812
+ },
813
+ "file": "TEST_DIR/t.qcow2.ovl3",
814
+ "encryption_key_missing": false
815
+ },
816
+ {
817
+ "iops_rd": 0,
818
+ "detect_zeroes": "off",
819
+ "image": {
820
+ "virtual-size": 67108864,
821
+ "filename": "TEST_DIR/t.qcow2.base",
822
+ "cluster-size": 65536,
823
+ "format": "qcow2",
824
+ "actual-size": 397312,
825
+ "format-specific": {
826
+ "type": "qcow2",
827
+ "data": {
828
+ "compat": "1.1",
829
+ "lazy-refcounts": false,
830
+ "refcount-bits": 16,
831
+ "corrupt": false
832
+ }
833
+ },
834
+ "dirty-flag": false
835
+ },
836
+ "iops_wr": 0,
837
+ "ro": true,
838
+ "node-name": "NODE_NAME",
839
+ "backing_file_depth": 0,
840
+ "drv": "qcow2",
841
+ "iops": 0,
842
+ "bps_wr": 0,
843
+ "write_threshold": 0,
844
+ "encrypted": false,
845
+ "bps": 0,
846
+ "bps_rd": 0,
847
+ "cache": {
848
+ "no-flush": false,
849
+ "direct": false,
850
+ "writeback": true
851
+ },
852
+ "file": "TEST_DIR/t.qcow2.base",
853
+ "encryption_key_missing": false
854
+ },
855
+ {
856
+ "iops_rd": 0,
857
+ "detect_zeroes": "off",
858
+ "image": {
859
+ "virtual-size": 393216,
860
+ "filename": "TEST_DIR/t.qcow2.base",
861
+ "format": "file",
862
+ "actual-size": 397312,
863
+ "dirty-flag": false
864
+ },
865
+ "iops_wr": 0,
866
+ "ro": true,
867
+ "node-name": "NODE_NAME",
868
+ "backing_file_depth": 0,
869
+ "drv": "file",
870
+ "iops": 0,
871
+ "bps_wr": 0,
872
+ "write_threshold": 0,
873
+ "encrypted": false,
874
+ "bps": 0,
875
+ "bps_rd": 0,
876
+ "cache": {
877
+ "no-flush": false,
878
+ "direct": false,
879
+ "writeback": true
880
+ },
881
+ "file": "TEST_DIR/t.qcow2.base",
882
+ "encryption_key_missing": false
883
+ },
884
+ {
885
+ "iops_rd": 0,
886
+ "detect_zeroes": "off",
887
+ "image": {
888
+ "backing-image": {
889
+ "virtual-size": 67108864,
890
+ "filename": "TEST_DIR/t.qcow2.base",
891
+ "cluster-size": 65536,
892
+ "format": "qcow2",
893
+ "actual-size": 397312,
894
+ "format-specific": {
895
+ "type": "qcow2",
896
+ "data": {
897
+ "compat": "1.1",
898
+ "lazy-refcounts": false,
899
+ "refcount-bits": 16,
900
+ "corrupt": false
901
+ }
902
+ },
903
+ "dirty-flag": false
904
+ },
905
+ "backing-filename-format": "qcow2",
906
+ "virtual-size": 67108864,
907
+ "filename": "TEST_DIR/t.qcow2",
908
+ "cluster-size": 65536,
909
+ "format": "qcow2",
910
+ "actual-size": 200704,
911
+ "format-specific": {
912
+ "type": "qcow2",
913
+ "data": {
914
+ "compat": "1.1",
915
+ "lazy-refcounts": false,
916
+ "refcount-bits": 16,
917
+ "corrupt": false
918
+ }
919
+ },
920
+ "full-backing-filename": "TEST_DIR/t.qcow2.base",
921
+ "backing-filename": "TEST_DIR/t.qcow2.base",
922
+ "dirty-flag": false
923
+ },
924
+ "iops_wr": 0,
925
+ "ro": false,
926
+ "node-name": "top",
927
+ "backing_file_depth": 1,
928
+ "drv": "qcow2",
929
+ "iops": 0,
930
+ "bps_wr": 0,
931
+ "write_threshold": 0,
932
+ "backing_file": "TEST_DIR/t.qcow2.base",
933
+ "encrypted": false,
934
+ "bps": 0,
935
+ "bps_rd": 0,
936
+ "cache": {
937
+ "no-flush": false,
938
+ "direct": false,
939
+ "writeback": true
940
+ },
941
+ "file": "TEST_DIR/t.qcow2",
942
+ "encryption_key_missing": false
943
+ },
944
+ {
945
+ "iops_rd": 0,
946
+ "detect_zeroes": "off",
947
+ "image": {
948
+ "virtual-size": 197120,
949
+ "filename": "TEST_DIR/t.qcow2",
950
+ "format": "file",
951
+ "actual-size": 200704,
952
+ "dirty-flag": false
953
+ },
954
+ "iops_wr": 0,
955
+ "ro": false,
956
+ "node-name": "NODE_NAME",
957
+ "backing_file_depth": 0,
958
+ "drv": "file",
959
+ "iops": 0,
960
+ "bps_wr": 0,
961
+ "write_threshold": 0,
962
+ "encrypted": false,
963
+ "bps": 0,
964
+ "bps_rd": 0,
965
+ "cache": {
966
+ "no-flush": false,
967
+ "direct": false,
968
+ "writeback": true
969
+ },
970
+ "file": "TEST_DIR/t.qcow2",
971
+ "encryption_key_missing": false
972
+ }
973
+ ]
974
+}
975
+{
976
+ "return": {
977
+ }
978
+}
979
+{
980
+ "timestamp": {
981
+ "seconds": TIMESTAMP,
982
+ "microseconds": TIMESTAMP
983
+ },
984
+ "event": "SHUTDOWN",
985
+ "data": {
986
+ "guest": false
987
+ }
988
+}
989
+image: TEST_DIR/t.IMGFMT
990
+file format: IMGFMT
293
+file format: IMGFMT
991
+virtual size: 64M (67108864 bytes)
294
+virtual size: 2 MiB (2097152 bytes)
992
+cluster_size: 65536
295
+cluster_size: 65536
993
+backing file: TEST_DIR/t.IMGFMT.base
296
+backing file: TEST_DIR/PID-base
994
+backing file format: IMGFMT
297
+Format specific information:
995
+image: TEST_DIR/t.IMGFMT.ovl2
298
+ compat: 1.1
996
+file format: IMGFMT
299
+ lazy refcounts: false
997
+virtual size: 64M (67108864 bytes)
300
+ refcount bits: 16
998
+cluster_size: 65536
301
+ corrupt: false
999
+backing file: TEST_DIR/t.IMGFMT.base
302
+
1000
+backing file format: IMGFMT
303
+read 1048576/1048576 bytes at offset 0
1001
+*** done
304
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
305
+
306
+read 1048576/1048576 bytes at offset 1048576
307
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
308
+
309
+== Resize tests ==
310
+=== preallocation=off ===
311
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
312
+
313
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
314
+
315
+wrote 65536/65536 bytes at offset 5368709120
316
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
317
+
318
+Image resized.
319
+
320
+read 65536/65536 bytes at offset 5368709120
321
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
322
+
323
+1 GiB (0x40000000) bytes not allocated at offset 0 bytes (0x0)
324
+7 GiB (0x1c0000000) bytes allocated at offset 1 GiB (0x40000000)
325
+
326
+[{ "start": 0, "length": 1073741824, "depth": 1, "zero": true, "data": false},
327
+{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
328
+
329
+=== preallocation=metadata ===
330
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
331
+
332
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
333
+
334
+wrote 65536/65536 bytes at offset 33285996544
335
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
336
+
337
+Image resized.
338
+
339
+read 65536/65536 bytes at offset 33285996544
340
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
341
+
342
+30 GiB (0x780000000) bytes not allocated at offset 0 bytes (0x0)
343
+3 GiB (0xc0000000) bytes allocated at offset 30 GiB (0x780000000)
344
+
345
+[{ "start": 0, "length": 32212254720, "depth": 1, "zero": true, "data": false},
346
+{ "start": 32212254720, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 327680},
347
+{ "start": 32749125632, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 537264128},
348
+{ "start": 33285996544, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1074200576},
349
+{ "start": 33822867456, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1611137024},
350
+{ "start": 34359738368, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2148139008},
351
+{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
352
+
353
+=== preallocation=falloc ===
354
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
355
+
356
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
357
+
358
+wrote 65536/65536 bytes at offset 9437184
359
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
360
+
361
+Image resized.
362
+
363
+read 65536/65536 bytes at offset 9437184
364
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
365
+
366
+5 MiB (0x500000) bytes not allocated at offset 0 bytes (0x0)
367
+10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
368
+
369
+[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
370
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
371
+
372
+=== preallocation=full ===
373
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
374
+
375
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
376
+
377
+wrote 65536/65536 bytes at offset 11534336
378
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
379
+
380
+Image resized.
381
+
382
+read 65536/65536 bytes at offset 11534336
383
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
384
+
385
+8 MiB (0x800000) bytes not allocated at offset 0 bytes (0x0)
386
+4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
387
+
388
+[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
389
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
390
+
391
+=== preallocation=off ===
392
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
393
+
394
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
395
+
396
+wrote 65536/65536 bytes at offset 259072
397
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
398
+
399
+Image resized.
400
+
401
+read 65536/65536 bytes at offset 259072
402
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
403
+
404
+192 KiB (0x30000) bytes not allocated at offset 0 bytes (0x0)
405
+320 KiB (0x50000) bytes allocated at offset 192 KiB (0x30000)
406
+
407
+[{ "start": 0, "length": 196608, "depth": 1, "zero": true, "data": false},
408
+{ "start": 196608, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 327680},
409
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
410
+
411
+=== preallocation=off ===
412
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16
413
+
414
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
415
+
416
+wrote 65536/65536 bytes at offset 344064
417
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
418
+
419
+Image resized.
420
+
421
+read 65536/65536 bytes at offset 344064
422
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
423
+
424
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
425
+256 KiB (0x40000) bytes allocated at offset 256 KiB (0x40000)
426
+
427
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
428
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
429
+
430
+=== preallocation=off ===
431
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16
432
+
433
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
434
+
435
+wrote 65536/65536 bytes at offset 446464
436
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
437
+
438
+Image resized.
439
+
440
+read 65536/65536 bytes at offset 446464
441
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
442
+
443
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
444
+244 KiB (0x3d000) bytes allocated at offset 256 KiB (0x40000)
445
+
446
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
447
+{ "start": 262144, "length": 249856, "depth": 0, "zero": true, "data": false}]
448
+
1002
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
449
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
1003
index XXXXXXX..XXXXXXX 100644
450
index XXXXXXX..XXXXXXX 100644
1004
--- a/tests/qemu-iotests/group
451
--- a/tests/qemu-iotests/group
1005
+++ b/tests/qemu-iotests/group
452
+++ b/tests/qemu-iotests/group
1006
@@ -XXX,XX +XXX,XX @@
453
@@ -XXX,XX +XXX,XX @@
1007
188 rw auto quick
454
270 rw backing quick
1008
189 rw auto
455
272 rw
1009
190 rw auto quick
456
273 backing quick
1010
+191 rw auto
457
+274 rw backing
1011
192 rw auto quick
458
277 rw quick
1012
194 rw auto migration quick
459
279 rw backing quick
1013
195 rw auto quick
460
280 rw migration quick
1014
--
461
--
1015
2.13.6
462
2.25.3
1016
463
1017
464
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
2
image is possibly preallocated and then the zero flag is added to all
3
clusters. This means that a copy-on-write operation may be needed when
4
writing to these clusters, despite having used preallocation, negating
5
one of the major benefits of preallocation.
2
6
3
This is new code, but it is easier to read if it makes passes over
7
Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
4
the image using bytes rather than sectors (and will get easier in
8
and if the protocol driver can ensure that the new area reads as zeros,
5
the future when bdrv_get_block_status is converted to byte-based).
9
we can skip setting the zero flag in the qcow2 layer.
6
10
7
Signed-off-by: Eric Blake <eblake@redhat.com>
11
Unfortunately, the same approach doesn't work for metadata
8
Reviewed-by: John Snow <jsnow@redhat.com>
12
preallocation, so we'll still set the zero flag there.
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
10
Reviewed-by: Fam Zheng <famz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
19
---
13
block/qcow2.c | 22 ++++++++++------------
20
block/qcow2.c | 22 +++++++++++++++++++---
14
1 file changed, 10 insertions(+), 12 deletions(-)
21
tests/qemu-iotests/274.out | 4 ++--
22
2 files changed, 21 insertions(+), 5 deletions(-)
15
23
16
diff --git a/block/qcow2.c b/block/qcow2.c
24
diff --git a/block/qcow2.c b/block/qcow2.c
17
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2.c
26
--- a/block/qcow2.c
19
+++ b/block/qcow2.c
27
+++ b/block/qcow2.c
20
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
21
*/
29
/* Allocate the data area */
22
required = virtual_size;
30
new_file_size = allocation_start +
23
} else {
31
nb_new_data_clusters * s->cluster_size;
24
- int cluster_sectors = cluster_size / BDRV_SECTOR_SIZE;
32
- /* Image file grows, so @exact does not matter */
25
- int64_t sector_num;
33
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
26
+ int64_t offset;
34
- errp);
27
int pnum = 0;
35
+ /*
28
36
+ * Image file grows, so @exact does not matter.
29
- for (sector_num = 0;
37
+ *
30
- sector_num < ssize / BDRV_SECTOR_SIZE;
38
+ * If we need to zero out the new area, try first whether the protocol
31
- sector_num += pnum) {
39
+ * driver can already take care of this.
32
- int nb_sectors = MIN(ssize / BDRV_SECTOR_SIZE - sector_num,
40
+ */
33
- BDRV_REQUEST_MAX_SECTORS);
41
+ if (flags & BDRV_REQ_ZERO_WRITE) {
34
+ for (offset = 0; offset < ssize;
42
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
35
+ offset += pnum * BDRV_SECTOR_SIZE) {
43
+ BDRV_REQ_ZERO_WRITE, NULL);
36
+ int nb_sectors = MIN(ssize - offset,
44
+ if (ret >= 0) {
37
+ BDRV_REQUEST_MAX_BYTES) / BDRV_SECTOR_SIZE;
45
+ flags &= ~BDRV_REQ_ZERO_WRITE;
38
BlockDriverState *file;
46
+ }
39
int64_t ret;
47
+ } else {
40
48
+ ret = -1;
41
ret = bdrv_get_block_status_above(in_bs, NULL,
49
+ }
42
- sector_num, nb_sectors,
50
+ if (ret < 0) {
43
+ offset >> BDRV_SECTOR_BITS,
51
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
44
+ nb_sectors,
52
+ errp);
45
&pnum, &file);
53
+ }
46
if (ret < 0) {
54
if (ret < 0) {
47
error_setg_errno(&local_err, -ret,
55
error_prepend(errp, "Failed to resize underlying file: ");
48
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
56
qcow2_free_clusters(bs, allocation_start,
49
} else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) ==
57
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
50
(BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) {
58
index XXXXXXX..XXXXXXX 100644
51
/* Extend pnum to end of cluster for next iteration */
59
--- a/tests/qemu-iotests/274.out
52
- pnum = ROUND_UP(sector_num + pnum, cluster_sectors) -
60
+++ b/tests/qemu-iotests/274.out
53
- sector_num;
61
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
54
+ pnum = (ROUND_UP(offset + pnum * BDRV_SECTOR_SIZE,
62
10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
55
+ cluster_size) - offset) >> BDRV_SECTOR_BITS;
63
56
64
[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
57
/* Count clusters we've seen */
65
-{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
58
- required += (sector_num % cluster_sectors + pnum) *
66
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
59
- BDRV_SECTOR_SIZE;
67
60
+ required += offset % cluster_size + pnum * BDRV_SECTOR_SIZE;
68
=== preallocation=full ===
61
}
69
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
62
}
70
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
63
}
71
4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
72
73
[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
74
-{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
75
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
76
77
=== preallocation=off ===
78
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
64
--
79
--
65
2.13.6
80
2.25.3
66
81
67
82
diff view generated by jsdifflib
1
From: "Daniel P. Berrange" <berrange@redhat.com>
1
From: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
2
2
3
Make the crypto driver implement the bdrv_co_preadv|pwritev
3
This patch introduces support for PMR that has been defined as part of NVMe 1.4
4
callbacks, and also use bdrv_co_preadv|pwritev for I/O
4
spec. User can now specify a pmrdev option that should point to HostMemoryBackend.
5
with the protocol driver beneath. This replaces sector based
5
pmrdev memory region will subsequently be exposed as PCI BAR 2 in emulated NVMe
6
I/O with byte based I/O, and allows us to stop assuming the
6
device. Guest OS can perform mmio read and writes to the PMR region that will stay
7
physical sector size matches the encryption sector size.
7
persistent across system reboot.
8
8
9
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
9
Signed-off-by: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
10
Message-id: 20170927125340.12360-5-berrange@redhat.com
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20200330164656.9348-1-andrzej.jakowski@linux.intel.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
Reviewed-by: Keith Busch <kbusch@kernel.org>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
---
15
block/crypto.c | 106 +++++++++++++++++++++++++++++----------------------------
16
hw/block/nvme.h | 2 +
16
1 file changed, 54 insertions(+), 52 deletions(-)
17
include/block/nvme.h | 172 +++++++++++++++++++++++++++++++++++++++++
18
hw/block/nvme.c | 109 ++++++++++++++++++++++++++
19
hw/block/Makefile.objs | 2 +-
20
hw/block/trace-events | 4 +
21
5 files changed, 288 insertions(+), 1 deletion(-)
17
22
18
diff --git a/block/crypto.c b/block/crypto.c
23
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/block/crypto.c
25
--- a/hw/block/nvme.h
21
+++ b/block/crypto.c
26
+++ b/hw/block/nvme.h
22
@@ -XXX,XX +XXX,XX @@ static void block_crypto_close(BlockDriverState *bs)
27
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl {
23
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
28
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
24
29
25
static coroutine_fn int
30
char *serial;
26
-block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
31
+ HostMemoryBackend *pmrdev;
27
- int remaining_sectors, QEMUIOVector *qiov)
32
+
28
+block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
33
NvmeNamespace *namespaces;
29
+ QEMUIOVector *qiov, int flags)
34
NvmeSQueue **sq;
30
{
35
NvmeCQueue **cq;
31
BlockCrypto *crypto = bs->opaque;
36
diff --git a/include/block/nvme.h b/include/block/nvme.h
32
- int cur_nr_sectors; /* number of sectors in current iteration */
37
index XXXXXXX..XXXXXXX 100644
33
+ uint64_t cur_bytes; /* number of bytes in current iteration */
38
--- a/include/block/nvme.h
34
uint64_t bytes_done = 0;
39
+++ b/include/block/nvme.h
35
uint8_t *cipher_data = NULL;
40
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar {
36
QEMUIOVector hd_qiov;
41
uint64_t acq;
37
int ret = 0;
42
uint32_t cmbloc;
38
- uint64_t payload_offset =
43
uint32_t cmbsz;
39
- qcrypto_block_get_payload_offset(crypto->block) / 512;
44
+ uint8_t padding[3520]; /* not used by QEMU */
40
- assert(payload_offset < (INT64_MAX / 512));
45
+ uint32_t pmrcap;
41
+ uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
46
+ uint32_t pmrctl;
42
+ uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
47
+ uint32_t pmrsts;
43
+ uint64_t sector_num = offset / sector_size;
48
+ uint32_t pmrebs;
44
+
49
+ uint32_t pmrswtp;
45
+ assert(!flags);
50
+ uint32_t pmrmsc;
46
+ assert(payload_offset < INT64_MAX);
51
} NvmeBar;
47
+ assert(QEMU_IS_ALIGNED(offset, sector_size));
52
48
+ assert(QEMU_IS_ALIGNED(bytes, sector_size));
53
enum NvmeCapShift {
49
54
@@ -XXX,XX +XXX,XX @@ enum NvmeCapShift {
50
qemu_iovec_init(&hd_qiov, qiov->niov);
55
CAP_CSS_SHIFT = 37,
51
56
CAP_MPSMIN_SHIFT = 48,
52
@@ -XXX,XX +XXX,XX @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
57
CAP_MPSMAX_SHIFT = 52,
53
goto cleanup;
58
+ CAP_PMR_SHIFT = 56,
59
};
60
61
enum NvmeCapMask {
62
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
63
CAP_CSS_MASK = 0xff,
64
CAP_MPSMIN_MASK = 0xf,
65
CAP_MPSMAX_MASK = 0xf,
66
+ CAP_PMR_MASK = 0x1,
67
};
68
69
#define NVME_CAP_MQES(cap) (((cap) >> CAP_MQES_SHIFT) & CAP_MQES_MASK)
70
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
71
<< CAP_MPSMIN_SHIFT)
72
#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
73
<< CAP_MPSMAX_SHIFT)
74
+#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
75
+ << CAP_PMR_SHIFT)
76
77
enum NvmeCcShift {
78
CC_EN_SHIFT = 0,
79
@@ -XXX,XX +XXX,XX @@ enum NvmeCmbszMask {
80
#define NVME_CMBSZ_GETSIZE(cmbsz) \
81
(NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz))))
82
83
+enum NvmePmrcapShift {
84
+ PMRCAP_RDS_SHIFT = 3,
85
+ PMRCAP_WDS_SHIFT = 4,
86
+ PMRCAP_BIR_SHIFT = 5,
87
+ PMRCAP_PMRTU_SHIFT = 8,
88
+ PMRCAP_PMRWBM_SHIFT = 10,
89
+ PMRCAP_PMRTO_SHIFT = 16,
90
+ PMRCAP_CMSS_SHIFT = 24,
91
+};
92
+
93
+enum NvmePmrcapMask {
94
+ PMRCAP_RDS_MASK = 0x1,
95
+ PMRCAP_WDS_MASK = 0x1,
96
+ PMRCAP_BIR_MASK = 0x7,
97
+ PMRCAP_PMRTU_MASK = 0x3,
98
+ PMRCAP_PMRWBM_MASK = 0xf,
99
+ PMRCAP_PMRTO_MASK = 0xff,
100
+ PMRCAP_CMSS_MASK = 0x1,
101
+};
102
+
103
+#define NVME_PMRCAP_RDS(pmrcap) \
104
+ ((pmrcap >> PMRCAP_RDS_SHIFT) & PMRCAP_RDS_MASK)
105
+#define NVME_PMRCAP_WDS(pmrcap) \
106
+ ((pmrcap >> PMRCAP_WDS_SHIFT) & PMRCAP_WDS_MASK)
107
+#define NVME_PMRCAP_BIR(pmrcap) \
108
+ ((pmrcap >> PMRCAP_BIR_SHIFT) & PMRCAP_BIR_MASK)
109
+#define NVME_PMRCAP_PMRTU(pmrcap) \
110
+ ((pmrcap >> PMRCAP_PMRTU_SHIFT) & PMRCAP_PMRTU_MASK)
111
+#define NVME_PMRCAP_PMRWBM(pmrcap) \
112
+ ((pmrcap >> PMRCAP_PMRWBM_SHIFT) & PMRCAP_PMRWBM_MASK)
113
+#define NVME_PMRCAP_PMRTO(pmrcap) \
114
+ ((pmrcap >> PMRCAP_PMRTO_SHIFT) & PMRCAP_PMRTO_MASK)
115
+#define NVME_PMRCAP_CMSS(pmrcap) \
116
+ ((pmrcap >> PMRCAP_CMSS_SHIFT) & PMRCAP_CMSS_MASK)
117
+
118
+#define NVME_PMRCAP_SET_RDS(pmrcap, val) \
119
+ (pmrcap |= (uint64_t)(val & PMRCAP_RDS_MASK) << PMRCAP_RDS_SHIFT)
120
+#define NVME_PMRCAP_SET_WDS(pmrcap, val) \
121
+ (pmrcap |= (uint64_t)(val & PMRCAP_WDS_MASK) << PMRCAP_WDS_SHIFT)
122
+#define NVME_PMRCAP_SET_BIR(pmrcap, val) \
123
+ (pmrcap |= (uint64_t)(val & PMRCAP_BIR_MASK) << PMRCAP_BIR_SHIFT)
124
+#define NVME_PMRCAP_SET_PMRTU(pmrcap, val) \
125
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTU_MASK) << PMRCAP_PMRTU_SHIFT)
126
+#define NVME_PMRCAP_SET_PMRWBM(pmrcap, val) \
127
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRWBM_MASK) << PMRCAP_PMRWBM_SHIFT)
128
+#define NVME_PMRCAP_SET_PMRTO(pmrcap, val) \
129
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTO_MASK) << PMRCAP_PMRTO_SHIFT)
130
+#define NVME_PMRCAP_SET_CMSS(pmrcap, val) \
131
+ (pmrcap |= (uint64_t)(val & PMRCAP_CMSS_MASK) << PMRCAP_CMSS_SHIFT)
132
+
133
+enum NvmePmrctlShift {
134
+ PMRCTL_EN_SHIFT = 0,
135
+};
136
+
137
+enum NvmePmrctlMask {
138
+ PMRCTL_EN_MASK = 0x1,
139
+};
140
+
141
+#define NVME_PMRCTL_EN(pmrctl) ((pmrctl >> PMRCTL_EN_SHIFT) & PMRCTL_EN_MASK)
142
+
143
+#define NVME_PMRCTL_SET_EN(pmrctl, val) \
144
+ (pmrctl |= (uint64_t)(val & PMRCTL_EN_MASK) << PMRCTL_EN_SHIFT)
145
+
146
+enum NvmePmrstsShift {
147
+ PMRSTS_ERR_SHIFT = 0,
148
+ PMRSTS_NRDY_SHIFT = 8,
149
+ PMRSTS_HSTS_SHIFT = 9,
150
+ PMRSTS_CBAI_SHIFT = 12,
151
+};
152
+
153
+enum NvmePmrstsMask {
154
+ PMRSTS_ERR_MASK = 0xff,
155
+ PMRSTS_NRDY_MASK = 0x1,
156
+ PMRSTS_HSTS_MASK = 0x7,
157
+ PMRSTS_CBAI_MASK = 0x1,
158
+};
159
+
160
+#define NVME_PMRSTS_ERR(pmrsts) \
161
+ ((pmrsts >> PMRSTS_ERR_SHIFT) & PMRSTS_ERR_MASK)
162
+#define NVME_PMRSTS_NRDY(pmrsts) \
163
+ ((pmrsts >> PMRSTS_NRDY_SHIFT) & PMRSTS_NRDY_MASK)
164
+#define NVME_PMRSTS_HSTS(pmrsts) \
165
+ ((pmrsts >> PMRSTS_HSTS_SHIFT) & PMRSTS_HSTS_MASK)
166
+#define NVME_PMRSTS_CBAI(pmrsts) \
167
+ ((pmrsts >> PMRSTS_CBAI_SHIFT) & PMRSTS_CBAI_MASK)
168
+
169
+#define NVME_PMRSTS_SET_ERR(pmrsts, val) \
170
+ (pmrsts |= (uint64_t)(val & PMRSTS_ERR_MASK) << PMRSTS_ERR_SHIFT)
171
+#define NVME_PMRSTS_SET_NRDY(pmrsts, val) \
172
+ (pmrsts |= (uint64_t)(val & PMRSTS_NRDY_MASK) << PMRSTS_NRDY_SHIFT)
173
+#define NVME_PMRSTS_SET_HSTS(pmrsts, val) \
174
+ (pmrsts |= (uint64_t)(val & PMRSTS_HSTS_MASK) << PMRSTS_HSTS_SHIFT)
175
+#define NVME_PMRSTS_SET_CBAI(pmrsts, val) \
176
+ (pmrsts |= (uint64_t)(val & PMRSTS_CBAI_MASK) << PMRSTS_CBAI_SHIFT)
177
+
178
+enum NvmePmrebsShift {
179
+ PMREBS_PMRSZU_SHIFT = 0,
180
+ PMREBS_RBB_SHIFT = 4,
181
+ PMREBS_PMRWBZ_SHIFT = 8,
182
+};
183
+
184
+enum NvmePmrebsMask {
185
+ PMREBS_PMRSZU_MASK = 0xf,
186
+ PMREBS_RBB_MASK = 0x1,
187
+ PMREBS_PMRWBZ_MASK = 0xffffff,
188
+};
189
+
190
+#define NVME_PMREBS_PMRSZU(pmrebs) \
191
+ ((pmrebs >> PMREBS_PMRSZU_SHIFT) & PMREBS_PMRSZU_MASK)
192
+#define NVME_PMREBS_RBB(pmrebs) \
193
+ ((pmrebs >> PMREBS_RBB_SHIFT) & PMREBS_RBB_MASK)
194
+#define NVME_PMREBS_PMRWBZ(pmrebs) \
195
+ ((pmrebs >> PMREBS_PMRWBZ_SHIFT) & PMREBS_PMRWBZ_MASK)
196
+
197
+#define NVME_PMREBS_SET_PMRSZU(pmrebs, val) \
198
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRSZU_MASK) << PMREBS_PMRSZU_SHIFT)
199
+#define NVME_PMREBS_SET_RBB(pmrebs, val) \
200
+ (pmrebs |= (uint64_t)(val & PMREBS_RBB_MASK) << PMREBS_RBB_SHIFT)
201
+#define NVME_PMREBS_SET_PMRWBZ(pmrebs, val) \
202
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRWBZ_MASK) << PMREBS_PMRWBZ_SHIFT)
203
+
204
+enum NvmePmrswtpShift {
205
+ PMRSWTP_PMRSWTU_SHIFT = 0,
206
+ PMRSWTP_PMRSWTV_SHIFT = 8,
207
+};
208
+
209
+enum NvmePmrswtpMask {
210
+ PMRSWTP_PMRSWTU_MASK = 0xf,
211
+ PMRSWTP_PMRSWTV_MASK = 0xffffff,
212
+};
213
+
214
+#define NVME_PMRSWTP_PMRSWTU(pmrswtp) \
215
+ ((pmrswtp >> PMRSWTP_PMRSWTU_SHIFT) & PMRSWTP_PMRSWTU_MASK)
216
+#define NVME_PMRSWTP_PMRSWTV(pmrswtp) \
217
+ ((pmrswtp >> PMRSWTP_PMRSWTV_SHIFT) & PMRSWTP_PMRSWTV_MASK)
218
+
219
+#define NVME_PMRSWTP_SET_PMRSWTU(pmrswtp, val) \
220
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTU_MASK) << PMRSWTP_PMRSWTU_SHIFT)
221
+#define NVME_PMRSWTP_SET_PMRSWTV(pmrswtp, val) \
222
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTV_MASK) << PMRSWTP_PMRSWTV_SHIFT)
223
+
224
+enum NvmePmrmscShift {
225
+ PMRMSC_CMSE_SHIFT = 1,
226
+ PMRMSC_CBA_SHIFT = 12,
227
+};
228
+
229
+enum NvmePmrmscMask {
230
+ PMRMSC_CMSE_MASK = 0x1,
231
+ PMRMSC_CBA_MASK = 0xfffffffffffff,
232
+};
233
+
234
+#define NVME_PMRMSC_CMSE(pmrmsc) \
235
+ ((pmrmsc >> PMRMSC_CMSE_SHIFT) & PMRMSC_CMSE_MASK)
236
+#define NVME_PMRMSC_CBA(pmrmsc) \
237
+ ((pmrmsc >> PMRMSC_CBA_SHIFT) & PMRMSC_CBA_MASK)
238
+
239
+#define NVME_PMRMSC_SET_CMSE(pmrmsc, val) \
240
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CMSE_MASK) << PMRMSC_CMSE_SHIFT)
241
+#define NVME_PMRMSC_SET_CBA(pmrmsc, val) \
242
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT)
243
+
244
typedef struct NvmeCmd {
245
uint8_t opcode;
246
uint8_t fuse;
247
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/hw/block/nvme.c
250
+++ b/hw/block/nvme.c
251
@@ -XXX,XX +XXX,XX @@
252
* -drive file=<file>,if=none,id=<drive_id>
253
* -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \
254
* cmb_size_mb=<cmb_size_mb[optional]>, \
255
+ * [pmrdev=<mem_backend_file_id>,] \
256
* num_queues=<N[optional]>
257
*
258
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
259
* offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
260
+ *
261
+ * cmb_size_mb= and pmrdev= options are mutually exclusive due to limitation
262
+ * in available BAR's. cmb_size_mb= will take precedence over pmrdev= when
263
+ * both provided.
264
+ * Enabling pmr emulation can be achieved by pointing to memory-backend-file.
265
+ * For example:
266
+ * -object memory-backend-file,id=<mem_id>,share=on,mem-path=<file_path>, \
267
+ * size=<size> .... -device nvme,...,pmrdev=<mem_id>
268
*/
269
270
#include "qemu/osdep.h"
271
@@ -XXX,XX +XXX,XX @@
272
#include "sysemu/sysemu.h"
273
#include "qapi/error.h"
274
#include "qapi/visitor.h"
275
+#include "sysemu/hostmem.h"
276
#include "sysemu/block-backend.h"
277
+#include "exec/ram_addr.h"
278
279
#include "qemu/log.h"
280
#include "qemu/module.h"
281
@@ -XXX,XX +XXX,XX @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
282
NVME_GUEST_ERR(nvme_ub_mmiowr_cmbsz_readonly,
283
"invalid write to read only CMBSZ, ignored");
284
return;
285
+ case 0xE00: /* PMRCAP */
286
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrcap_readonly,
287
+ "invalid write to PMRCAP register, ignored");
288
+ return;
289
+ case 0xE04: /* TODO PMRCTL */
290
+ break;
291
+ case 0xE08: /* PMRSTS */
292
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrsts_readonly,
293
+ "invalid write to PMRSTS register, ignored");
294
+ return;
295
+ case 0xE0C: /* PMREBS */
296
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrebs_readonly,
297
+ "invalid write to PMREBS register, ignored");
298
+ return;
299
+ case 0xE10: /* PMRSWTP */
300
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrswtp_readonly,
301
+ "invalid write to PMRSWTP register, ignored");
302
+ return;
303
+ case 0xE14: /* TODO PMRMSC */
304
+ break;
305
default:
306
NVME_GUEST_ERR(nvme_ub_mmiowr_invalid,
307
"invalid MMIO write,"
308
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
54
}
309
}
55
310
56
- while (remaining_sectors) {
311
if (addr < sizeof(n->bar)) {
57
- cur_nr_sectors = remaining_sectors;
312
+ /*
58
-
313
+ * When PMRWBM bit 1 is set then read from
59
- if (cur_nr_sectors > (BLOCK_CRYPTO_MAX_IO_SIZE / 512)) {
314
+ * from PMRSTS should ensure prior writes
60
- cur_nr_sectors = (BLOCK_CRYPTO_MAX_IO_SIZE / 512);
315
+ * made it to persistent media
61
- }
316
+ */
62
+ while (bytes) {
317
+ if (addr == 0xE08 &&
63
+ cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
318
+ (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
64
319
+ qemu_ram_writeback(n->pmrdev->mr.ram_block,
65
qemu_iovec_reset(&hd_qiov);
320
+ 0, n->pmrdev->size);
66
- qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * 512);
321
+ }
67
+ qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
322
memcpy(&val, ptr + addr, size);
68
323
} else {
69
- ret = bdrv_co_readv(bs->file,
324
NVME_GUEST_ERR(nvme_ub_mmiord_invalid_ofs,
70
- payload_offset + sector_num,
325
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
71
- cur_nr_sectors, &hd_qiov);
326
error_setg(errp, "serial property not set");
72
+ ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
327
return;
73
+ cur_bytes, &hd_qiov, 0);
74
if (ret < 0) {
75
goto cleanup;
76
}
77
78
- if (qcrypto_block_decrypt(crypto->block,
79
- sector_num,
80
- cipher_data, cur_nr_sectors * 512,
81
- NULL) < 0) {
82
+ if (qcrypto_block_decrypt(crypto->block, sector_num, cipher_data,
83
+ cur_bytes, NULL) < 0) {
84
ret = -EIO;
85
goto cleanup;
86
}
87
88
- qemu_iovec_from_buf(qiov, bytes_done,
89
- cipher_data, cur_nr_sectors * 512);
90
+ qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
91
92
- remaining_sectors -= cur_nr_sectors;
93
- sector_num += cur_nr_sectors;
94
- bytes_done += cur_nr_sectors * 512;
95
+ sector_num += cur_bytes / sector_size;
96
+ bytes -= cur_bytes;
97
+ bytes_done += cur_bytes;
98
}
328
}
99
329
+
100
cleanup:
330
+ if (!n->cmb_size_mb && n->pmrdev) {
101
@@ -XXX,XX +XXX,XX @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
331
+ if (host_memory_backend_is_mapped(n->pmrdev)) {
102
332
+ char *path = object_get_canonical_path_component(OBJECT(n->pmrdev));
103
333
+ error_setg(errp, "can't use already busy memdev: %s", path);
104
static coroutine_fn int
334
+ g_free(path);
105
-block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
335
+ return;
106
- int remaining_sectors, QEMUIOVector *qiov)
336
+ }
107
+block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
337
+
108
+ QEMUIOVector *qiov, int flags)
338
+ if (!is_power_of_2(n->pmrdev->size)) {
109
{
339
+ error_setg(errp, "pmr backend size needs to be power of 2 in size");
110
BlockCrypto *crypto = bs->opaque;
340
+ return;
111
- int cur_nr_sectors; /* number of sectors in current iteration */
341
+ }
112
+ uint64_t cur_bytes; /* number of bytes in current iteration */
342
+
113
uint64_t bytes_done = 0;
343
+ host_memory_backend_set_mapped(n->pmrdev, true);
114
uint8_t *cipher_data = NULL;
344
+ }
115
QEMUIOVector hd_qiov;
345
+
116
int ret = 0;
346
blkconf_blocksizes(&n->conf);
117
- uint64_t payload_offset =
347
if (!blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
118
- qcrypto_block_get_payload_offset(crypto->block) / 512;
348
false, errp)) {
119
- assert(payload_offset < (INT64_MAX / 512));
349
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
120
+ uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
350
PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
121
+ uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
351
PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem);
122
+ uint64_t sector_num = offset / sector_size;
352
123
+
353
+ } else if (n->pmrdev) {
124
+ assert(!flags);
354
+ /* Controller Capabilities register */
125
+ assert(payload_offset < INT64_MAX);
355
+ NVME_CAP_SET_PMRS(n->bar.cap, 1);
126
+ assert(QEMU_IS_ALIGNED(offset, sector_size));
356
+
127
+ assert(QEMU_IS_ALIGNED(bytes, sector_size));
357
+ /* PMR Capabities register */
128
358
+ n->bar.pmrcap = 0;
129
qemu_iovec_init(&hd_qiov, qiov->niov);
359
+ NVME_PMRCAP_SET_RDS(n->bar.pmrcap, 0);
130
360
+ NVME_PMRCAP_SET_WDS(n->bar.pmrcap, 0);
131
@@ -XXX,XX +XXX,XX @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
361
+ NVME_PMRCAP_SET_BIR(n->bar.pmrcap, 2);
132
goto cleanup;
362
+ NVME_PMRCAP_SET_PMRTU(n->bar.pmrcap, 0);
363
+ /* Turn on bit 1 support */
364
+ NVME_PMRCAP_SET_PMRWBM(n->bar.pmrcap, 0x02);
365
+ NVME_PMRCAP_SET_PMRTO(n->bar.pmrcap, 0);
366
+ NVME_PMRCAP_SET_CMSS(n->bar.pmrcap, 0);
367
+
368
+ /* PMR Control register */
369
+ n->bar.pmrctl = 0;
370
+ NVME_PMRCTL_SET_EN(n->bar.pmrctl, 0);
371
+
372
+ /* PMR Status register */
373
+ n->bar.pmrsts = 0;
374
+ NVME_PMRSTS_SET_ERR(n->bar.pmrsts, 0);
375
+ NVME_PMRSTS_SET_NRDY(n->bar.pmrsts, 0);
376
+ NVME_PMRSTS_SET_HSTS(n->bar.pmrsts, 0);
377
+ NVME_PMRSTS_SET_CBAI(n->bar.pmrsts, 0);
378
+
379
+ /* PMR Elasticity Buffer Size register */
380
+ n->bar.pmrebs = 0;
381
+ NVME_PMREBS_SET_PMRSZU(n->bar.pmrebs, 0);
382
+ NVME_PMREBS_SET_RBB(n->bar.pmrebs, 0);
383
+ NVME_PMREBS_SET_PMRWBZ(n->bar.pmrebs, 0);
384
+
385
+ /* PMR Sustained Write Throughput register */
386
+ n->bar.pmrswtp = 0;
387
+ NVME_PMRSWTP_SET_PMRSWTU(n->bar.pmrswtp, 0);
388
+ NVME_PMRSWTP_SET_PMRSWTV(n->bar.pmrswtp, 0);
389
+
390
+ /* PMR Memory Space Control register */
391
+ n->bar.pmrmsc = 0;
392
+ NVME_PMRMSC_SET_CMSE(n->bar.pmrmsc, 0);
393
+ NVME_PMRMSC_SET_CBA(n->bar.pmrmsc, 0);
394
+
395
+ pci_register_bar(pci_dev, NVME_PMRCAP_BIR(n->bar.pmrcap),
396
+ PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
397
+ PCI_BASE_ADDRESS_MEM_PREFETCH, &n->pmrdev->mr);
133
}
398
}
134
399
135
- while (remaining_sectors) {
400
for (i = 0; i < n->num_namespaces; i++) {
136
- cur_nr_sectors = remaining_sectors;
401
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
137
+ while (bytes) {
402
if (n->cmb_size_mb) {
138
+ cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
403
g_free(n->cmbuf);
139
140
- if (cur_nr_sectors > (BLOCK_CRYPTO_MAX_IO_SIZE / 512)) {
141
- cur_nr_sectors = (BLOCK_CRYPTO_MAX_IO_SIZE / 512);
142
- }
143
-
144
- qemu_iovec_to_buf(qiov, bytes_done,
145
- cipher_data, cur_nr_sectors * 512);
146
+ qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
147
148
- if (qcrypto_block_encrypt(crypto->block,
149
- sector_num,
150
- cipher_data, cur_nr_sectors * 512,
151
- NULL) < 0) {
152
+ if (qcrypto_block_encrypt(crypto->block, sector_num, cipher_data,
153
+ cur_bytes, NULL) < 0) {
154
ret = -EIO;
155
goto cleanup;
156
}
157
158
qemu_iovec_reset(&hd_qiov);
159
- qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * 512);
160
+ qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
161
162
- ret = bdrv_co_writev(bs->file,
163
- payload_offset + sector_num,
164
- cur_nr_sectors, &hd_qiov);
165
+ ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
166
+ cur_bytes, &hd_qiov, 0);
167
if (ret < 0) {
168
goto cleanup;
169
}
170
171
- remaining_sectors -= cur_nr_sectors;
172
- sector_num += cur_nr_sectors;
173
- bytes_done += cur_nr_sectors * 512;
174
+ sector_num += cur_bytes / sector_size;
175
+ bytes -= cur_bytes;
176
+ bytes_done += cur_bytes;
177
}
404
}
178
405
+
179
cleanup:
406
+ if (n->pmrdev) {
180
@@ -XXX,XX +XXX,XX @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
407
+ host_memory_backend_set_mapped(n->pmrdev, false);
181
return ret;
408
+ }
409
msix_uninit_exclusive_bar(pci_dev);
182
}
410
}
183
411
184
+static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
412
static Property nvme_props[] = {
185
+{
413
DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf),
186
+ BlockCrypto *crypto = bs->opaque;
414
+ DEFINE_PROP_LINK("pmrdev", NvmeCtrl, pmrdev, TYPE_MEMORY_BACKEND,
187
+ uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
415
+ HostMemoryBackend *),
188
+ bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
416
DEFINE_PROP_STRING("serial", NvmeCtrl, serial),
189
+}
417
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0),
190
+
418
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, num_queues, 64),
191
419
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
192
static int64_t block_crypto_getlength(BlockDriverState *bs)
420
index XXXXXXX..XXXXXXX 100644
193
{
421
--- a/hw/block/Makefile.objs
194
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_crypto_luks = {
422
+++ b/hw/block/Makefile.objs
195
.bdrv_truncate = block_crypto_truncate,
423
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
196
.create_opts = &block_crypto_create_opts_luks,
424
common-obj-$(CONFIG_XEN) += xen-block.o
197
425
common-obj-$(CONFIG_ECC) += ecc.o
198
- .bdrv_co_readv = block_crypto_co_readv,
426
common-obj-$(CONFIG_ONENAND) += onenand.o
199
- .bdrv_co_writev = block_crypto_co_writev,
427
-common-obj-$(CONFIG_NVME_PCI) += nvme.o
200
+ .bdrv_refresh_limits = block_crypto_refresh_limits,
428
common-obj-$(CONFIG_SWIM) += swim.o
201
+ .bdrv_co_preadv = block_crypto_co_preadv,
429
202
+ .bdrv_co_pwritev = block_crypto_co_pwritev,
430
common-obj-$(CONFIG_SH4) += tc58128.o
203
.bdrv_getlength = block_crypto_getlength,
431
204
.bdrv_get_info = block_crypto_get_info_luks,
432
obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o
205
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
433
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
434
+obj-$(CONFIG_NVME_PCI) += nvme.o
435
436
obj-y += dataplane/
437
diff --git a/hw/block/trace-events b/hw/block/trace-events
438
index XXXXXXX..XXXXXXX 100644
439
--- a/hw/block/trace-events
440
+++ b/hw/block/trace-events
441
@@ -XXX,XX +XXX,XX @@ nvme_ub_mmiowr_ssreset_w1c_unsupported(void) "attempted to W1C CSTS.NSSRO but CA
442
nvme_ub_mmiowr_ssreset_unsupported(void) "attempted NVM subsystem reset but CAP.NSSRS is zero (not supported)"
443
nvme_ub_mmiowr_cmbloc_reserved(void) "invalid write to reserved CMBLOC when CMBSZ is zero, ignored"
444
nvme_ub_mmiowr_cmbsz_readonly(void) "invalid write to read only CMBSZ, ignored"
445
+nvme_ub_mmiowr_pmrcap_readonly(void) "invalid write to read only PMRCAP, ignored"
446
+nvme_ub_mmiowr_pmrsts_readonly(void) "invalid write to read only PMRSTS, ignored"
447
+nvme_ub_mmiowr_pmrebs_readonly(void) "invalid write to read only PMREBS, ignored"
448
+nvme_ub_mmiowr_pmrswtp_readonly(void) "invalid write to read only PMRSWTP, ignored"
449
nvme_ub_mmiowr_invalid(uint64_t offset, uint64_t data) "invalid MMIO write, offset=0x%"PRIx64", data=0x%"PRIx64""
450
nvme_ub_mmiord_misaligned32(uint64_t offset) "MMIO read not 32-bit aligned, offset=0x%"PRIx64""
451
nvme_ub_mmiord_toosmall(uint64_t offset) "MMIO read smaller than 32-bits, offset=0x%"PRIx64""
206
--
452
--
207
2.13.6
453
2.25.3
208
454
209
455
diff view generated by jsdifflib
1
This changes the commit block job to support operation in a graph where
1
The QMP handler qmp_object_add() and the implementation of --object in
2
there is more than a single active layer that references the top node.
2
qemu-storage-daemon can share most of the code. Currently,
3
qemu-storage-daemon calls qmp_object_add(), but this is not correct
4
because different visitors need to be used.
3
5
4
This involves inserting the commit filter node not only on the path
6
As a first step towards a fix, make qmp_object_add() a wrapper around a
5
between the given active node and the top node, but between the top node
7
new function user_creatable_add_dict() that can get an additional
6
and all of its parents.
8
parameter. The handling of "props" is only required for compatibility
7
9
and not required for the qemu-storage-daemon command line, so it stays
8
On completion, bdrv_drop_intermediate() must consider all parents for
10
in qmp_object_add().
9
updating the backing file link. These parents may be backing files
10
themselves and as such read-only; reopen them temporarily if necessary.
11
Previously this was achieved by the bdrv_reopen() calls in the commit
12
block job that made overlay_bs read-write for the whole duration of the
13
block job, even though write access is only needed on completion.
14
15
Now that we consider all parents, overlay_bs is meaningless. It is left
16
in place in this commit, but we'll remove it soon.
17
11
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
13
---
20
block.c | 68 ++++++++++++++++++++++++++++++++++------------------------
14
include/qom/object_interfaces.h | 12 ++++++++++++
21
block/commit.c | 2 +-
15
qom/object_interfaces.c | 27 +++++++++++++++++++++++++++
22
2 files changed, 41 insertions(+), 29 deletions(-)
16
qom/qom-qmp-cmds.c | 24 +-----------------------
17
3 files changed, 40 insertions(+), 23 deletions(-)
23
18
24
diff --git a/block.c b/block.c
19
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
25
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
26
--- a/block.c
21
--- a/include/qom/object_interfaces.h
27
+++ b/block.c
22
+++ b/include/qom/object_interfaces.h
28
@@ -XXX,XX +XXX,XX @@ static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
23
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
29
const char *filename, Error **errp)
24
const QDict *qdict,
25
Visitor *v, Error **errp);
26
27
+/**
28
+ * user_creatable_add_dict:
29
+ * @qdict: the object definition
30
+ * @errp: if an error occurs, a pointer to an area to store the error
31
+ *
32
+ * Create an instance of the user creatable object that is defined by
33
+ * @qdict. The object type is taken from the QDict key 'qom-type', its
34
+ * ID from the key 'id'. The remaining entries in @qdict are used to
35
+ * initialize the object properties.
36
+ */
37
+void user_creatable_add_dict(QDict *qdict, Error **errp);
38
+
39
/**
40
* user_creatable_add_opts:
41
* @opts: the object definition
42
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/qom/object_interfaces.c
45
+++ b/qom/object_interfaces.c
46
@@ -XXX,XX +XXX,XX @@
47
#include "qapi/qmp/qerror.h"
48
#include "qapi/qmp/qjson.h"
49
#include "qapi/qmp/qstring.h"
50
+#include "qapi/qobject-input-visitor.h"
51
#include "qom/object_interfaces.h"
52
#include "qemu/help_option.h"
53
#include "qemu/module.h"
54
@@ -XXX,XX +XXX,XX @@ out:
55
return obj;
56
}
57
58
+void user_creatable_add_dict(QDict *qdict, Error **errp)
59
+{
60
+ Visitor *v;
61
+ Object *obj;
62
+ g_autofree char *type = NULL;
63
+ g_autofree char *id = NULL;
64
+
65
+ type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
66
+ if (!type) {
67
+ error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
68
+ return;
69
+ }
70
+ qdict_del(qdict, "qom-type");
71
+
72
+ id = g_strdup(qdict_get_try_str(qdict, "id"));
73
+ if (!id) {
74
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
75
+ return;
76
+ }
77
+ qdict_del(qdict, "id");
78
+
79
+ v = qobject_input_visitor_new(QOBJECT(qdict));
80
+ obj = user_creatable_add_type(type, id, qdict, v, errp);
81
+ visit_free(v);
82
+ object_unref(obj);
83
+}
84
85
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
30
{
86
{
31
BlockDriverState *parent = c->opaque;
87
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
32
+ int orig_flags = bdrv_get_flags(parent);
88
index XXXXXXX..XXXXXXX 100644
33
int ret;
89
--- a/qom/qom-qmp-cmds.c
34
90
+++ b/qom/qom-qmp-cmds.c
35
+ if (!(orig_flags & BDRV_O_RDWR)) {
91
@@ -XXX,XX +XXX,XX @@
36
+ ret = bdrv_reopen(parent, orig_flags | BDRV_O_RDWR, errp);
92
#include "qapi/qapi-commands-qom.h"
37
+ if (ret < 0) {
93
#include "qapi/qmp/qdict.h"
38
+ return ret;
94
#include "qapi/qmp/qerror.h"
39
+ }
95
-#include "qapi/qobject-input-visitor.h"
40
+ }
96
#include "qemu/cutils.h"
41
+
97
#include "qom/object_interfaces.h"
42
ret = bdrv_change_backing_file(parent, filename,
98
#include "qom/qom-qobject.h"
43
base->drv ? base->drv->format_name : "");
99
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
44
if (ret < 0) {
100
{
45
error_setg_errno(errp, ret, "Could not update backing file link");
101
QObject *props;
102
QDict *pdict;
103
- Visitor *v;
104
- Object *obj;
105
- g_autofree char *type = NULL;
106
- g_autofree char *id = NULL;
107
-
108
- type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
109
- if (!type) {
110
- error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
111
- return;
112
- }
113
- qdict_del(qdict, "qom-type");
114
-
115
- id = g_strdup(qdict_get_try_str(qdict, "id"));
116
- if (!id) {
117
- error_setg(errp, QERR_MISSING_PARAMETER, "id");
118
- return;
119
- }
120
- qdict_del(qdict, "id");
121
122
props = qdict_get(qdict, "props");
123
if (props) {
124
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
125
qobject_unref(pdict);
46
}
126
}
47
127
48
+ if (!(orig_flags & BDRV_O_RDWR)) {
128
- v = qobject_input_visitor_new(QOBJECT(qdict));
49
+ bdrv_reopen(parent, orig_flags, NULL);
129
- obj = user_creatable_add_type(type, id, qdict, v, errp);
50
+ }
130
- visit_free(v);
51
+
131
- object_unref(obj);
52
return ret;
132
+ user_creatable_add_dict(qdict, errp);
53
}
133
}
54
134
55
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs)
135
void qmp_object_del(const char *id, Error **errp)
56
int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
57
BlockDriverState *base, const char *backing_file_str)
58
{
59
- BlockDriverState *new_top_bs = NULL;
60
+ BdrvChild *c, *next;
61
Error *local_err = NULL;
62
int ret = -EIO;
63
64
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
65
goto exit;
66
}
67
68
- new_top_bs = bdrv_find_overlay(active, top);
69
-
70
- if (new_top_bs == NULL) {
71
- /* we could not find the image above 'top', this is an error */
72
- goto exit;
73
- }
74
-
75
- /* special case of new_top_bs->backing->bs already pointing to base - nothing
76
- * to do, no intermediate images */
77
- if (backing_bs(new_top_bs) == base) {
78
- ret = 0;
79
- goto exit;
80
- }
81
-
82
/* Make sure that base is in the backing chain of top */
83
if (!bdrv_chain_contains(top, base)) {
84
goto exit;
85
}
86
87
/* success - we can delete the intermediate states, and link top->base */
88
- if (new_top_bs->backing->role->update_filename) {
89
- backing_file_str = backing_file_str ? backing_file_str : base->filename;
90
- ret = new_top_bs->backing->role->update_filename(new_top_bs->backing,
91
- base, backing_file_str,
92
- &local_err);
93
- if (ret < 0) {
94
- bdrv_set_backing_hd(new_top_bs, top, &error_abort);
95
+ backing_file_str = backing_file_str ? backing_file_str : base->filename;
96
+
97
+ QLIST_FOREACH_SAFE(c, &top->parents, next_parent, next) {
98
+ /* Check whether we are allowed to switch c from top to base */
99
+ GSList *ignore_children = g_slist_prepend(NULL, c);
100
+ bdrv_check_update_perm(base, NULL, c->perm, c->shared_perm,
101
+ ignore_children, &local_err);
102
+ if (local_err) {
103
+ ret = -EPERM;
104
+ error_report_err(local_err);
105
goto exit;
106
}
107
- }
108
+ g_slist_free(ignore_children);
109
110
- bdrv_set_backing_hd(new_top_bs, base, &local_err);
111
- if (local_err) {
112
- ret = -EPERM;
113
- error_report_err(local_err);
114
- goto exit;
115
+ /* If so, update the backing file path in the image file */
116
+ if (c->role->update_filename) {
117
+ ret = c->role->update_filename(c, base, backing_file_str,
118
+ &local_err);
119
+ if (ret < 0) {
120
+ bdrv_abort_perm_update(base);
121
+ error_report_err(local_err);
122
+ goto exit;
123
+ }
124
+ }
125
+
126
+ /* Do the actual switch in the in-memory graph.
127
+ * Completes bdrv_check_update_perm() transaction internally. */
128
+ bdrv_ref(base);
129
+ bdrv_replace_child(c, base);
130
+ bdrv_unref(top);
131
}
132
133
ret = 0;
134
diff --git a/block/commit.c b/block/commit.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/block/commit.c
137
+++ b/block/commit.c
138
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
139
error_propagate(errp, local_err);
140
goto fail;
141
}
142
- bdrv_set_backing_hd(overlay_bs, commit_top_bs, &local_err);
143
+ bdrv_replace_node(top, commit_top_bs, &local_err);
144
if (local_err) {
145
bdrv_unref(commit_top_bs);
146
commit_top_bs = NULL;
147
--
136
--
148
2.13.6
137
2.25.3
149
138
150
139
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
After processing the option string with the keyval parser, we get a
2
QDict that contains only strings. This QDict must be fed to a keyval
3
visitor which converts the strings into the right data types.
2
4
3
Right now, the dirty-bitmap code exposes the fact that we use
5
qmp_object_add(), however, uses the normal QObject input visitor, which
4
a scale of sector granularity in the underlying hbitmap to anything
6
expects a QDict where all properties already have the QType that matches
5
that wants to serialize a dirty bitmap. It's nicer to uniformly
7
the data type required by the QOM object type.
6
expose bytes as our dirty-bitmap interface, matching the previous
7
change to bitmap size. The only caller to serialization is currently
8
qcow2-cluster.c, which becomes a bit more verbose because it is still
9
tracking sectors for other reasons, but a later patch will fix that
10
to more uniformly use byte offsets everywhere. Likewise, within
11
dirty-bitmap, we have to add more assertions that we are not
12
truncating incorrectly, which can go away once the internal hbitmap
13
is byte-based rather than sector-based.
14
8
15
Signed-off-by: Eric Blake <eblake@redhat.com>
9
Change the --object implementation in qemu-storage-daemon so that it
16
Reviewed-by: John Snow <jsnow@redhat.com>
10
doesn't call qmp_object_add(), but calls user_creatable_add_dict()
17
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
directly instead and pass it a new keyval boolean that decides which
18
Reviewed-by: Fam Zheng <famz@redhat.com>
12
visitor must be used.
13
14
Reported-by: Coiby Xu <coiby.xu@gmail.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
16
---
21
include/block/dirty-bitmap.h | 14 +++++++-------
17
include/qom/object_interfaces.h | 6 +++++-
22
block/dirty-bitmap.c | 37 ++++++++++++++++++++++++-------------
18
qemu-storage-daemon.c | 4 +---
23
block/qcow2-bitmap.c | 22 ++++++++++++++--------
19
qom/object_interfaces.c | 8 ++++++--
24
3 files changed, 45 insertions(+), 28 deletions(-)
20
qom/qom-qmp-cmds.c | 2 +-
21
4 files changed, 13 insertions(+), 7 deletions(-)
25
22
26
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
23
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
27
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
28
--- a/include/block/dirty-bitmap.h
25
--- a/include/qom/object_interfaces.h
29
+++ b/include/block/dirty-bitmap.h
26
+++ b/include/qom/object_interfaces.h
30
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
27
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
31
void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
28
/**
32
29
* user_creatable_add_dict:
33
uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
30
* @qdict: the object definition
34
- uint64_t start, uint64_t count);
31
+ * @keyval: if true, use a keyval visitor for processing @qdict (i.e.
35
+ uint64_t offset, uint64_t bytes);
32
+ * assume that all @qdict values are strings); otherwise, use
36
uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap);
33
+ * the normal QObject visitor (i.e. assume all @qdict values
37
void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
34
+ * have the QType expected by the QOM object type)
38
- uint8_t *buf, uint64_t start,
35
* @errp: if an error occurs, a pointer to an area to store the error
39
- uint64_t count);
36
*
40
+ uint8_t *buf, uint64_t offset,
37
* Create an instance of the user creatable object that is defined by
41
+ uint64_t bytes);
38
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
42
void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
39
* ID from the key 'id'. The remaining entries in @qdict are used to
43
- uint8_t *buf, uint64_t start,
40
* initialize the object properties.
44
- uint64_t count, bool finish);
41
*/
45
+ uint8_t *buf, uint64_t offset,
42
-void user_creatable_add_dict(QDict *qdict, Error **errp);
46
+ uint64_t bytes, bool finish);
43
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
47
void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
44
48
- uint64_t start, uint64_t count,
45
/**
49
+ uint64_t offset, uint64_t bytes,
46
* user_creatable_add_opts:
50
bool finish);
47
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
51
void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
52
- uint64_t start, uint64_t count,
53
+ uint64_t offset, uint64_t bytes,
54
bool finish);
55
void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
56
57
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
58
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
59
--- a/block/dirty-bitmap.c
49
--- a/qemu-storage-daemon.c
60
+++ b/block/dirty-bitmap.c
50
+++ b/qemu-storage-daemon.c
61
@@ -XXX,XX +XXX,XX @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
51
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
52
QemuOpts *opts;
53
const char *type;
54
QDict *args;
55
- QObject *ret_data = NULL;
56
57
/* FIXME The keyval parser rejects 'help' arguments, so we must
58
* unconditionall try QemuOpts first. */
59
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
60
qemu_opts_del(opts);
61
62
args = keyval_parse(optarg, "qom-type", &error_fatal);
63
- qmp_object_add(args, &ret_data, &error_fatal);
64
+ user_creatable_add_dict(args, true, &error_fatal);
65
qobject_unref(args);
66
- qobject_unref(ret_data);
67
break;
68
}
69
default:
70
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/qom/object_interfaces.c
73
+++ b/qom/object_interfaces.c
74
@@ -XXX,XX +XXX,XX @@ out:
75
return obj;
62
}
76
}
63
77
64
uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
78
-void user_creatable_add_dict(QDict *qdict, Error **errp)
65
- uint64_t start, uint64_t count)
79
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
66
+ uint64_t offset, uint64_t bytes)
67
{
80
{
68
- return hbitmap_serialization_size(bitmap->bitmap, start, count);
81
Visitor *v;
69
+ assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
82
Object *obj;
70
+ return hbitmap_serialization_size(bitmap->bitmap,
83
@@ -XXX,XX +XXX,XX @@ void user_creatable_add_dict(QDict *qdict, Error **errp)
71
+ offset >> BDRV_SECTOR_BITS,
84
}
72
+ bytes >> BDRV_SECTOR_BITS);
85
qdict_del(qdict, "id");
86
87
- v = qobject_input_visitor_new(QOBJECT(qdict));
88
+ if (keyval) {
89
+ v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
90
+ } else {
91
+ v = qobject_input_visitor_new(QOBJECT(qdict));
92
+ }
93
obj = user_creatable_add_type(type, id, qdict, v, errp);
94
visit_free(v);
95
object_unref(obj);
96
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/qom/qom-qmp-cmds.c
99
+++ b/qom/qom-qmp-cmds.c
100
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
101
qobject_unref(pdict);
102
}
103
104
- user_creatable_add_dict(qdict, errp);
105
+ user_creatable_add_dict(qdict, false, errp);
73
}
106
}
74
107
75
uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
108
void qmp_object_del(const char *id, Error **errp)
76
{
77
- return hbitmap_serialization_align(bitmap->bitmap);
78
+ return hbitmap_serialization_align(bitmap->bitmap) * BDRV_SECTOR_SIZE;
79
}
80
81
void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
82
- uint8_t *buf, uint64_t start,
83
- uint64_t count)
84
+ uint8_t *buf, uint64_t offset,
85
+ uint64_t bytes)
86
{
87
- hbitmap_serialize_part(bitmap->bitmap, buf, start, count);
88
+ assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
89
+ hbitmap_serialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
90
+ bytes >> BDRV_SECTOR_BITS);
91
}
92
93
void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
94
- uint8_t *buf, uint64_t start,
95
- uint64_t count, bool finish)
96
+ uint8_t *buf, uint64_t offset,
97
+ uint64_t bytes, bool finish)
98
{
99
- hbitmap_deserialize_part(bitmap->bitmap, buf, start, count, finish);
100
+ assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
101
+ hbitmap_deserialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
102
+ bytes >> BDRV_SECTOR_BITS, finish);
103
}
104
105
void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
106
- uint64_t start, uint64_t count,
107
+ uint64_t offset, uint64_t bytes,
108
bool finish)
109
{
110
- hbitmap_deserialize_zeroes(bitmap->bitmap, start, count, finish);
111
+ assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
112
+ hbitmap_deserialize_zeroes(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
113
+ bytes >> BDRV_SECTOR_BITS, finish);
114
}
115
116
void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
117
- uint64_t start, uint64_t count,
118
+ uint64_t offset, uint64_t bytes,
119
bool finish)
120
{
121
- hbitmap_deserialize_ones(bitmap->bitmap, start, count, finish);
122
+ assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
123
+ hbitmap_deserialize_ones(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
124
+ bytes >> BDRV_SECTOR_BITS, finish);
125
}
126
127
void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
128
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/block/qcow2-bitmap.c
131
+++ b/block/qcow2-bitmap.c
132
@@ -XXX,XX +XXX,XX @@ static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
133
bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
134
uint64_t sbc = sector_granularity * (s->cluster_size << 3);
135
136
- assert(QEMU_IS_ALIGNED(sbc,
137
+ assert(QEMU_IS_ALIGNED(sbc << BDRV_SECTOR_BITS,
138
bdrv_dirty_bitmap_serialization_align(bitmap)));
139
return sbc;
140
}
141
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
142
uint8_t *buf = NULL;
143
uint64_t i, tab_size =
144
size_to_clusters(s,
145
- bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_sectors));
146
+ bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size));
147
148
if (tab_size != bitmap_table_size || tab_size > BME_MAX_TABLE_SIZE) {
149
return -EINVAL;
150
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
151
152
if (offset == 0) {
153
if (entry & BME_TABLE_ENTRY_FLAG_ALL_ONES) {
154
- bdrv_dirty_bitmap_deserialize_ones(bitmap, sector, count,
155
+ bdrv_dirty_bitmap_deserialize_ones(bitmap,
156
+ sector * BDRV_SECTOR_SIZE,
157
+ count * BDRV_SECTOR_SIZE,
158
false);
159
} else {
160
/* No need to deserialize zeros because the dirty bitmap is
161
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
162
if (ret < 0) {
163
goto finish;
164
}
165
- bdrv_dirty_bitmap_deserialize_part(bitmap, buf, sector, count,
166
+ bdrv_dirty_bitmap_deserialize_part(bitmap, buf,
167
+ sector * BDRV_SECTOR_SIZE,
168
+ count * BDRV_SECTOR_SIZE,
169
false);
170
}
171
}
172
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
173
uint64_t *tb;
174
uint64_t tb_size =
175
size_to_clusters(s,
176
- bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_sectors));
177
+ bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size));
178
179
if (tb_size > BME_MAX_TABLE_SIZE ||
180
tb_size * s->cluster_size > BME_MAX_PHYS_SIZE)
181
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
182
183
sector = cluster * sbc;
184
end = MIN(bm_sectors, sector + sbc);
185
- write_size =
186
- bdrv_dirty_bitmap_serialization_size(bitmap, sector, end - sector);
187
+ write_size = bdrv_dirty_bitmap_serialization_size(bitmap,
188
+ sector * BDRV_SECTOR_SIZE, (end - sector) * BDRV_SECTOR_SIZE);
189
assert(write_size <= s->cluster_size);
190
191
off = qcow2_alloc_clusters(bs, s->cluster_size);
192
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
193
}
194
tb[cluster] = off;
195
196
- bdrv_dirty_bitmap_serialize_part(bitmap, buf, sector, end - sector);
197
+ bdrv_dirty_bitmap_serialize_part(bitmap, buf,
198
+ sector * BDRV_SECTOR_SIZE,
199
+ (end - sector) * BDRV_SECTOR_SIZE);
200
if (write_size < s->cluster_size) {
201
memset(buf + write_size, 0, s->cluster_size - write_size);
202
}
203
--
109
--
204
2.13.6
110
2.25.3
205
111
206
112
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Change the qcow2 bitmap
5
helper function sectors_covered_by_bitmap_cluster(), renaming it
6
to bytes_covered_by_bitmap_cluster() in the process.
7
8
Signed-off-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Reviewed-by: Fam Zheng <famz@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/qcow2-bitmap.c | 28 ++++++++++++++--------------
15
1 file changed, 14 insertions(+), 14 deletions(-)
16
17
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-bitmap.c
20
+++ b/block/qcow2-bitmap.c
21
@@ -XXX,XX +XXX,XX @@ static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
22
return 0;
23
}
24
25
-/* This function returns the number of disk sectors covered by a single qcow2
26
- * cluster of bitmap data. */
27
-static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
28
- const BdrvDirtyBitmap *bitmap)
29
+/* Return the disk size covered by a single qcow2 cluster of bitmap data. */
30
+static uint64_t bytes_covered_by_bitmap_cluster(const BDRVQcow2State *s,
31
+ const BdrvDirtyBitmap *bitmap)
32
{
33
- uint64_t sector_granularity =
34
- bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
35
- uint64_t sbc = sector_granularity * (s->cluster_size << 3);
36
+ uint64_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
37
+ uint64_t limit = granularity * (s->cluster_size << 3);
38
39
- assert(QEMU_IS_ALIGNED(sbc << BDRV_SECTOR_BITS,
40
+ assert(QEMU_IS_ALIGNED(limit,
41
bdrv_dirty_bitmap_serialization_align(bitmap)));
42
- return sbc;
43
+ return limit;
44
}
45
46
/* load_bitmap_data
47
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
48
{
49
int ret = 0;
50
BDRVQcow2State *s = bs->opaque;
51
- uint64_t sector, sbc;
52
+ uint64_t sector, limit, sbc;
53
uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
54
uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
55
uint8_t *buf = NULL;
56
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
57
}
58
59
buf = g_malloc(s->cluster_size);
60
- sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
61
+ limit = bytes_covered_by_bitmap_cluster(s, bitmap);
62
+ sbc = limit >> BDRV_SECTOR_BITS;
63
for (i = 0, sector = 0; i < tab_size; ++i, sector += sbc) {
64
uint64_t count = MIN(bm_sectors - sector, sbc);
65
uint64_t entry = bitmap_table[i];
66
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
67
int ret;
68
BDRVQcow2State *s = bs->opaque;
69
int64_t sector;
70
- uint64_t sbc;
71
+ uint64_t limit, sbc;
72
uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
73
uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
74
const char *bm_name = bdrv_dirty_bitmap_name(bitmap);
75
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
76
77
dbi = bdrv_dirty_iter_new(bitmap, 0);
78
buf = g_malloc(s->cluster_size);
79
- sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
80
- assert(DIV_ROUND_UP(bm_sectors, sbc) == tb_size);
81
+ limit = bytes_covered_by_bitmap_cluster(s, bitmap);
82
+ sbc = limit >> BDRV_SECTOR_BITS;
83
+ assert(DIV_ROUND_UP(bm_size, limit) == tb_size);
84
85
while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
86
uint64_t cluster = sector / sbc;
87
--
88
2.13.6
89
90
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
All callers to bdrv_dirty_iter_new() passed 0 for their initial
4
starting point, drop that parameter.
5
6
Most callers to bdrv_set_dirty_iter() were scaling a byte offset to
7
a sector number; the exception qcow2-bitmap will be converted later
8
to use byte rather than sector iteration. Move the scaling to occur
9
internally to dirty bitmap code instead, so that callers now pass
10
in bytes.
11
12
Signed-off-by: Eric Blake <eblake@redhat.com>
13
Reviewed-by: John Snow <jsnow@redhat.com>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
Reviewed-by: Fam Zheng <famz@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
include/block/dirty-bitmap.h | 5 ++---
19
block/backup.c | 5 ++---
20
block/dirty-bitmap.c | 9 ++++-----
21
block/mirror.c | 4 ++--
22
block/qcow2-bitmap.c | 4 ++--
23
5 files changed, 12 insertions(+), 15 deletions(-)
24
25
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/block/dirty-bitmap.h
28
+++ b/include/block/dirty-bitmap.h
29
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
30
void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
31
int64_t cur_sector, int64_t nr_sectors);
32
BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap);
33
-BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
34
- uint64_t first_sector);
35
+BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap);
36
void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
37
38
uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
39
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
40
void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
41
int64_t cur_sector, int64_t nr_sectors);
42
int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
43
-void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num);
44
+void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t offset);
45
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
46
int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
47
void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes);
48
diff --git a/block/backup.c b/block/backup.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/block/backup.c
51
+++ b/block/backup.c
52
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
53
54
granularity = bdrv_dirty_bitmap_granularity(job->sync_bitmap);
55
clusters_per_iter = MAX((granularity / job->cluster_size), 1);
56
- dbi = bdrv_dirty_iter_new(job->sync_bitmap, 0);
57
+ dbi = bdrv_dirty_iter_new(job->sync_bitmap);
58
59
/* Find the next dirty sector(s) */
60
while ((offset = bdrv_dirty_iter_next(dbi) * BDRV_SECTOR_SIZE) >= 0) {
61
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
62
/* If the bitmap granularity is smaller than the backup granularity,
63
* we need to advance the iterator pointer to the next cluster. */
64
if (granularity < job->cluster_size) {
65
- bdrv_set_dirty_iter(dbi,
66
- cluster * job->cluster_size / BDRV_SECTOR_SIZE);
67
+ bdrv_set_dirty_iter(dbi, cluster * job->cluster_size);
68
}
69
70
last_cluster = cluster - 1;
71
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/block/dirty-bitmap.c
74
+++ b/block/dirty-bitmap.c
75
@@ -XXX,XX +XXX,XX @@ uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
76
return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
77
}
78
79
-BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
80
- uint64_t first_sector)
81
+BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
82
{
83
BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
84
- hbitmap_iter_init(&iter->hbi, bitmap->bitmap, first_sector);
85
+ hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
86
iter->bitmap = bitmap;
87
bitmap->active_iterators++;
88
return iter;
89
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
90
/**
91
* Advance a BdrvDirtyBitmapIter to an arbitrary offset.
92
*/
93
-void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t sector_num)
94
+void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
95
{
96
- hbitmap_iter_init(&iter->hbi, iter->hbi.hb, sector_num);
97
+ hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset >> BDRV_SECTOR_BITS);
98
}
99
100
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
101
diff --git a/block/mirror.c b/block/mirror.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/block/mirror.c
104
+++ b/block/mirror.c
105
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
106
next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
107
if (next_dirty > next_offset || next_dirty < 0) {
108
/* The bitmap iterator's cache is stale, refresh it */
109
- bdrv_set_dirty_iter(s->dbi, next_offset >> BDRV_SECTOR_BITS);
110
+ bdrv_set_dirty_iter(s->dbi, next_offset);
111
next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
112
}
113
assert(next_dirty == next_offset);
114
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
115
}
116
117
assert(!s->dbi);
118
- s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap, 0);
119
+ s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
120
for (;;) {
121
uint64_t delay_ns = 0;
122
int64_t cnt, delta;
123
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/block/qcow2-bitmap.c
126
+++ b/block/qcow2-bitmap.c
127
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
128
return NULL;
129
}
130
131
- dbi = bdrv_dirty_iter_new(bitmap, 0);
132
+ dbi = bdrv_dirty_iter_new(bitmap);
133
buf = g_malloc(s->cluster_size);
134
limit = bytes_covered_by_bitmap_cluster(s, bitmap);
135
sbc = limit >> BDRV_SECTOR_BITS;
136
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
137
break;
138
}
139
140
- bdrv_set_dirty_iter(dbi, end);
141
+ bdrv_set_dirty_iter(dbi, end * BDRV_SECTOR_SIZE);
142
}
143
144
*bitmap_table_size = tb_size;
145
--
146
2.13.6
147
148
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Thanks to recent cleanups, most callers were scaling a return value
4
of sectors into bytes (the exception, in qcow2-bitmap, will be
5
converted to byte-based iteration later). Update the interface to
6
do the scaling internally instead.
7
8
In qcow2-bitmap, the code was specifically checking for an error
9
return of -1. To avoid a regression, we either have to make sure
10
we continue to return -1 (rather than a scaled -512) on error, or
11
we have to fix the caller to treat all negative values as error
12
rather than just one magic value. It's easy enough to make both
13
changes at the same time, even though either one in isolation
14
would work.
15
16
Signed-off-by: Eric Blake <eblake@redhat.com>
17
Reviewed-by: John Snow <jsnow@redhat.com>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
19
Reviewed-by: Fam Zheng <famz@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
---
22
block/backup.c | 2 +-
23
block/dirty-bitmap.c | 3 ++-
24
block/mirror.c | 8 ++++----
25
block/qcow2-bitmap.c | 2 +-
26
4 files changed, 8 insertions(+), 7 deletions(-)
27
28
diff --git a/block/backup.c b/block/backup.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/backup.c
31
+++ b/block/backup.c
32
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
33
dbi = bdrv_dirty_iter_new(job->sync_bitmap);
34
35
/* Find the next dirty sector(s) */
36
- while ((offset = bdrv_dirty_iter_next(dbi) * BDRV_SECTOR_SIZE) >= 0) {
37
+ while ((offset = bdrv_dirty_iter_next(dbi)) >= 0) {
38
cluster = offset / job->cluster_size;
39
40
/* Fake progress updates for any clusters we skipped */
41
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block/dirty-bitmap.c
44
+++ b/block/dirty-bitmap.c
45
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
46
47
int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
48
{
49
- return hbitmap_iter_next(&iter->hbi);
50
+ int64_t ret = hbitmap_iter_next(&iter->hbi);
51
+ return ret < 0 ? -1 : ret * BDRV_SECTOR_SIZE;
52
}
53
54
/* Called within bdrv_dirty_bitmap_lock..unlock */
55
diff --git a/block/mirror.c b/block/mirror.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block/mirror.c
58
+++ b/block/mirror.c
59
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
60
int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);
61
62
bdrv_dirty_bitmap_lock(s->dirty_bitmap);
63
- offset = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
64
+ offset = bdrv_dirty_iter_next(s->dbi);
65
if (offset < 0) {
66
bdrv_set_dirty_iter(s->dbi, 0);
67
- offset = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
68
+ offset = bdrv_dirty_iter_next(s->dbi);
69
trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap) *
70
BDRV_SECTOR_SIZE);
71
assert(offset >= 0);
72
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
73
break;
74
}
75
76
- next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
77
+ next_dirty = bdrv_dirty_iter_next(s->dbi);
78
if (next_dirty > next_offset || next_dirty < 0) {
79
/* The bitmap iterator's cache is stale, refresh it */
80
bdrv_set_dirty_iter(s->dbi, next_offset);
81
- next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
82
+ next_dirty = bdrv_dirty_iter_next(s->dbi);
83
}
84
assert(next_dirty == next_offset);
85
nb_chunks++;
86
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/block/qcow2-bitmap.c
89
+++ b/block/qcow2-bitmap.c
90
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
91
sbc = limit >> BDRV_SECTOR_BITS;
92
assert(DIV_ROUND_UP(bm_size, limit) == tb_size);
93
94
- while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
95
+ while ((sector = bdrv_dirty_iter_next(dbi) >> BDRV_SECTOR_BITS) >= 0) {
96
uint64_t cluster = sector / sbc;
97
uint64_t end, write_size;
98
int64_t off;
99
--
100
2.13.6
101
102
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Thanks to recent cleanups, all callers were scaling a return value
4
of sectors into bytes; do the scaling internally instead.
5
6
Signed-off-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: John Snow <jsnow@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Fam Zheng <famz@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/dirty-bitmap.c | 4 ++--
13
block/mirror.c | 16 ++++++----------
14
migration/block.c | 2 +-
15
3 files changed, 9 insertions(+), 13 deletions(-)
16
17
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/dirty-bitmap.c
20
+++ b/block/dirty-bitmap.c
21
@@ -XXX,XX +XXX,XX @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
22
QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
23
BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
24
BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
25
- info->count = bdrv_get_dirty_count(bm) << BDRV_SECTOR_BITS;
26
+ info->count = bdrv_get_dirty_count(bm);
27
info->granularity = bdrv_dirty_bitmap_granularity(bm);
28
info->has_name = !!bm->name;
29
info->name = g_strdup(bm->name);
30
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
31
32
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
33
{
34
- return hbitmap_count(bitmap->bitmap);
35
+ return hbitmap_count(bitmap->bitmap) << BDRV_SECTOR_BITS;
36
}
37
38
int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
39
diff --git a/block/mirror.c b/block/mirror.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/block/mirror.c
42
+++ b/block/mirror.c
43
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
44
if (offset < 0) {
45
bdrv_set_dirty_iter(s->dbi, 0);
46
offset = bdrv_dirty_iter_next(s->dbi);
47
- trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap) *
48
- BDRV_SECTOR_SIZE);
49
+ trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap));
50
assert(offset >= 0);
51
}
52
bdrv_dirty_bitmap_unlock(s->dirty_bitmap);
53
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
54
55
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
56
/* s->common.offset contains the number of bytes already processed so
57
- * far, cnt is the number of dirty sectors remaining and
58
+ * far, cnt is the number of dirty bytes remaining and
59
* s->bytes_in_flight is the number of bytes currently being
60
* processed; together those are the current total operation length */
61
- s->common.len = s->common.offset + s->bytes_in_flight +
62
- cnt * BDRV_SECTOR_SIZE;
63
+ s->common.len = s->common.offset + s->bytes_in_flight + cnt;
64
65
/* Note that even when no rate limit is applied we need to yield
66
* periodically with no pending I/O so that bdrv_drain_all() returns.
67
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
68
s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
69
if (s->in_flight >= MAX_IN_FLIGHT || s->buf_free_count == 0 ||
70
(cnt == 0 && s->in_flight > 0)) {
71
- trace_mirror_yield(s, cnt * BDRV_SECTOR_SIZE,
72
- s->buf_free_count, s->in_flight);
73
+ trace_mirror_yield(s, cnt, s->buf_free_count, s->in_flight);
74
mirror_wait_for_io(s);
75
continue;
76
} else if (cnt != 0) {
77
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
78
* whether to switch to target check one last time if I/O has
79
* come in the meanwhile, and if not flush the data to disk.
80
*/
81
- trace_mirror_before_drain(s, cnt * BDRV_SECTOR_SIZE);
82
+ trace_mirror_before_drain(s, cnt);
83
84
bdrv_drained_begin(bs);
85
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
86
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
87
}
88
89
ret = 0;
90
- trace_mirror_before_sleep(s, cnt * BDRV_SECTOR_SIZE,
91
- s->synced, delay_ns);
92
+ trace_mirror_before_sleep(s, cnt, s->synced, delay_ns);
93
if (!s->synced) {
94
block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
95
if (block_job_is_cancelled(&s->common)) {
96
diff --git a/migration/block.c b/migration/block.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/migration/block.c
99
+++ b/migration/block.c
100
@@ -XXX,XX +XXX,XX @@ static int64_t get_remaining_dirty(void)
101
aio_context_release(blk_get_aio_context(bmds->blk));
102
}
103
104
- return dirty << BDRV_SECTOR_BITS;
105
+ return dirty;
106
}
107
108
109
--
110
2.13.6
111
112
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Half the callers were already scaling bytes to sectors; the other
4
half can eventually be simplified to use byte iteration. Both
5
callers were already using the result as a bool, so make that
6
explicit. Making the change also makes it easier for a future
7
dirty-bitmap patch to offload scaling over to the internal hbitmap.
8
9
Remember, asking whether a byte is dirty is effectively asking
10
whether the entire granularity containing the byte is dirty, since
11
we only track dirtiness by granularity.
12
13
Signed-off-by: Eric Blake <eblake@redhat.com>
14
Reviewed-by: John Snow <jsnow@redhat.com>
15
Reviewed-by: Juan Quintela <quintela@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Reviewed-by: Fam Zheng <famz@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
include/block/dirty-bitmap.h | 4 ++--
21
block/dirty-bitmap.c | 8 ++++----
22
block/mirror.c | 3 +--
23
migration/block.c | 3 ++-
24
4 files changed, 9 insertions(+), 9 deletions(-)
25
26
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/block/dirty-bitmap.h
29
+++ b/include/block/dirty-bitmap.h
30
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap,
31
/* Functions that require manual locking. */
32
void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
33
void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap);
34
-int bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
35
- int64_t sector);
36
+bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
37
+ int64_t offset);
38
void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
39
int64_t cur_sector, int64_t nr_sectors);
40
void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
41
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block/dirty-bitmap.c
44
+++ b/block/dirty-bitmap.c
45
@@ -XXX,XX +XXX,XX @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
46
}
47
48
/* Called within bdrv_dirty_bitmap_lock..unlock */
49
-int bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
50
- int64_t sector)
51
+bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
52
+ int64_t offset)
53
{
54
if (bitmap) {
55
- return hbitmap_get(bitmap->bitmap, sector);
56
+ return hbitmap_get(bitmap->bitmap, offset >> BDRV_SECTOR_BITS);
57
} else {
58
- return 0;
59
+ return false;
60
}
61
}
62
63
diff --git a/block/mirror.c b/block/mirror.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/block/mirror.c
66
+++ b/block/mirror.c
67
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
68
int64_t next_offset = offset + nb_chunks * s->granularity;
69
int64_t next_chunk = next_offset / s->granularity;
70
if (next_offset >= s->bdev_length ||
71
- !bdrv_get_dirty_locked(source, s->dirty_bitmap,
72
- next_offset >> BDRV_SECTOR_BITS)) {
73
+ !bdrv_get_dirty_locked(source, s->dirty_bitmap, next_offset)) {
74
break;
75
}
76
if (test_bit(next_chunk, s->in_flight_bitmap)) {
77
diff --git a/migration/block.c b/migration/block.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/migration/block.c
80
+++ b/migration/block.c
81
@@ -XXX,XX +XXX,XX @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
82
blk_mig_unlock();
83
}
84
bdrv_dirty_bitmap_lock(bmds->dirty_bitmap);
85
- if (bdrv_get_dirty_locked(bs, bmds->dirty_bitmap, sector)) {
86
+ if (bdrv_get_dirty_locked(bs, bmds->dirty_bitmap,
87
+ sector * BDRV_SECTOR_SIZE)) {
88
if (total_sectors - sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
89
nr_sectors = total_sectors - sector;
90
} else {
91
--
92
2.13.6
93
94
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Some of the callers were already scaling bytes to sectors; others
4
can be easily converted to pass byte offsets, all in our shift
5
towards a consistent byte interface everywhere. Making the change
6
will also make it easier to write the hold-out callers to use byte
7
rather than sectors for their iterations; it also makes it easier
8
for a future dirty-bitmap patch to offload scaling over to the
9
internal hbitmap. Although all callers happen to pass
10
sector-aligned values, make the internal scaling robust to any
11
sub-sector requests.
12
13
Signed-off-by: Eric Blake <eblake@redhat.com>
14
Reviewed-by: John Snow <jsnow@redhat.com>
15
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
16
Reviewed-by: Fam Zheng <famz@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
include/block/dirty-bitmap.h | 8 ++++----
20
block/dirty-bitmap.c | 22 ++++++++++++++--------
21
block/mirror.c | 16 ++++++++--------
22
migration/block.c | 7 +++++--
23
4 files changed, 31 insertions(+), 22 deletions(-)
24
25
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/block/dirty-bitmap.h
28
+++ b/include/block/dirty-bitmap.h
29
@@ -XXX,XX +XXX,XX @@ const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap);
30
int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap);
31
DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap);
32
void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
33
- int64_t cur_sector, int64_t nr_sectors);
34
+ int64_t offset, int64_t bytes);
35
void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
36
- int64_t cur_sector, int64_t nr_sectors);
37
+ int64_t offset, int64_t bytes);
38
BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap);
39
BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap);
40
void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
41
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap);
42
bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
43
int64_t offset);
44
void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
45
- int64_t cur_sector, int64_t nr_sectors);
46
+ int64_t offset, int64_t bytes);
47
void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
48
- int64_t cur_sector, int64_t nr_sectors);
49
+ int64_t offset, int64_t bytes);
50
int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
51
void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t offset);
52
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
53
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/block/dirty-bitmap.c
56
+++ b/block/dirty-bitmap.c
57
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
58
59
/* Called within bdrv_dirty_bitmap_lock..unlock */
60
void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
61
- int64_t cur_sector, int64_t nr_sectors)
62
+ int64_t offset, int64_t bytes)
63
{
64
+ int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
65
+
66
assert(bdrv_dirty_bitmap_enabled(bitmap));
67
assert(!bdrv_dirty_bitmap_readonly(bitmap));
68
- hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
69
+ hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
70
+ end_sector - (offset >> BDRV_SECTOR_BITS));
71
}
72
73
void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
74
- int64_t cur_sector, int64_t nr_sectors)
75
+ int64_t offset, int64_t bytes)
76
{
77
bdrv_dirty_bitmap_lock(bitmap);
78
- bdrv_set_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors);
79
+ bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
80
bdrv_dirty_bitmap_unlock(bitmap);
81
}
82
83
/* Called within bdrv_dirty_bitmap_lock..unlock */
84
void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
85
- int64_t cur_sector, int64_t nr_sectors)
86
+ int64_t offset, int64_t bytes)
87
{
88
+ int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
89
+
90
assert(bdrv_dirty_bitmap_enabled(bitmap));
91
assert(!bdrv_dirty_bitmap_readonly(bitmap));
92
- hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
93
+ hbitmap_reset(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
94
+ end_sector - (offset >> BDRV_SECTOR_BITS));
95
}
96
97
void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
98
- int64_t cur_sector, int64_t nr_sectors)
99
+ int64_t offset, int64_t bytes)
100
{
101
bdrv_dirty_bitmap_lock(bitmap);
102
- bdrv_reset_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors);
103
+ bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
104
bdrv_dirty_bitmap_unlock(bitmap);
105
}
106
107
diff --git a/block/mirror.c b/block/mirror.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/block/mirror.c
110
+++ b/block/mirror.c
111
@@ -XXX,XX +XXX,XX @@ static void mirror_write_complete(void *opaque, int ret)
112
if (ret < 0) {
113
BlockErrorAction action;
114
115
- bdrv_set_dirty_bitmap(s->dirty_bitmap, op->offset >> BDRV_SECTOR_BITS,
116
- op->bytes >> BDRV_SECTOR_BITS);
117
+ bdrv_set_dirty_bitmap(s->dirty_bitmap, op->offset, op->bytes);
118
action = mirror_error_action(s, false, -ret);
119
if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
120
s->ret = ret;
121
@@ -XXX,XX +XXX,XX @@ static void mirror_read_complete(void *opaque, int ret)
122
if (ret < 0) {
123
BlockErrorAction action;
124
125
- bdrv_set_dirty_bitmap(s->dirty_bitmap, op->offset >> BDRV_SECTOR_BITS,
126
- op->bytes >> BDRV_SECTOR_BITS);
127
+ bdrv_set_dirty_bitmap(s->dirty_bitmap, op->offset, op->bytes);
128
action = mirror_error_action(s, true, -ret);
129
if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
130
s->ret = ret;
131
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
132
* calling bdrv_get_block_status_above could yield - if some blocks are
133
* marked dirty in this window, we need to know.
134
*/
135
- bdrv_reset_dirty_bitmap_locked(s->dirty_bitmap, offset >> BDRV_SECTOR_BITS,
136
- nb_chunks * sectors_per_chunk);
137
+ bdrv_reset_dirty_bitmap_locked(s->dirty_bitmap, offset,
138
+ nb_chunks * s->granularity);
139
bdrv_dirty_bitmap_unlock(s->dirty_bitmap);
140
141
bitmap_set(s->in_flight_bitmap, offset / s->granularity, nb_chunks);
142
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
143
144
if (base == NULL && !bdrv_has_zero_init(target_bs)) {
145
if (!bdrv_can_write_zeroes_with_unmap(target_bs)) {
146
- bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, end);
147
+ bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length);
148
return 0;
149
}
150
151
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
152
n = count >> BDRV_SECTOR_BITS;
153
assert(n > 0);
154
if (ret == 1) {
155
- bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
156
+ bdrv_set_dirty_bitmap(s->dirty_bitmap,
157
+ sector_num * BDRV_SECTOR_SIZE,
158
+ n * BDRV_SECTOR_SIZE);
159
}
160
sector_num += n;
161
}
162
diff --git a/migration/block.c b/migration/block.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/migration/block.c
165
+++ b/migration/block.c
166
@@ -XXX,XX +XXX,XX @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
167
blk->aiocb = blk_aio_preadv(bb, cur_sector * BDRV_SECTOR_SIZE, &blk->qiov,
168
0, blk_mig_read_cb, blk);
169
170
- bdrv_reset_dirty_bitmap(bmds->dirty_bitmap, cur_sector, nr_sectors);
171
+ bdrv_reset_dirty_bitmap(bmds->dirty_bitmap, cur_sector * BDRV_SECTOR_SIZE,
172
+ nr_sectors * BDRV_SECTOR_SIZE);
173
aio_context_release(blk_get_aio_context(bmds->blk));
174
qemu_mutex_unlock_iothread();
175
176
@@ -XXX,XX +XXX,XX @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
177
} else {
178
nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
179
}
180
- bdrv_reset_dirty_bitmap_locked(bmds->dirty_bitmap, sector, nr_sectors);
181
+ bdrv_reset_dirty_bitmap_locked(bmds->dirty_bitmap,
182
+ sector * BDRV_SECTOR_SIZE,
183
+ nr_sectors * BDRV_SECTOR_SIZE);
184
bdrv_dirty_bitmap_unlock(bmds->dirty_bitmap);
185
186
blk = g_new(BlkMigBlock, 1);
187
--
188
2.13.6
189
190
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Now that we have adjusted the majority of the calls this function
4
makes to be byte-based, it is easier to read the code if it makes
5
passes over the image using bytes rather than sectors.
6
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/mirror.c | 38 ++++++++++++++------------------------
14
1 file changed, 14 insertions(+), 24 deletions(-)
15
16
diff --git a/block/mirror.c b/block/mirror.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/mirror.c
19
+++ b/block/mirror.c
20
@@ -XXX,XX +XXX,XX @@ static void mirror_throttle(MirrorBlockJob *s)
21
22
static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
23
{
24
- int64_t sector_num, end;
25
+ int64_t offset;
26
BlockDriverState *base = s->base;
27
BlockDriverState *bs = s->source;
28
BlockDriverState *target_bs = blk_bs(s->target);
29
- int ret, n;
30
+ int ret;
31
int64_t count;
32
33
- end = s->bdev_length / BDRV_SECTOR_SIZE;
34
-
35
if (base == NULL && !bdrv_has_zero_init(target_bs)) {
36
if (!bdrv_can_write_zeroes_with_unmap(target_bs)) {
37
bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length);
38
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
39
}
40
41
s->initial_zeroing_ongoing = true;
42
- for (sector_num = 0; sector_num < end; ) {
43
- int nb_sectors = MIN(end - sector_num,
44
- QEMU_ALIGN_DOWN(INT_MAX, s->granularity) >> BDRV_SECTOR_BITS);
45
+ for (offset = 0; offset < s->bdev_length; ) {
46
+ int bytes = MIN(s->bdev_length - offset,
47
+ QEMU_ALIGN_DOWN(INT_MAX, s->granularity));
48
49
mirror_throttle(s);
50
51
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
52
continue;
53
}
54
55
- mirror_do_zero_or_discard(s, sector_num * BDRV_SECTOR_SIZE,
56
- nb_sectors * BDRV_SECTOR_SIZE, false);
57
- sector_num += nb_sectors;
58
+ mirror_do_zero_or_discard(s, offset, bytes, false);
59
+ offset += bytes;
60
}
61
62
mirror_wait_for_all_io(s);
63
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
64
}
65
66
/* First part, loop on the sectors and initialize the dirty bitmap. */
67
- for (sector_num = 0; sector_num < end; ) {
68
+ for (offset = 0; offset < s->bdev_length; ) {
69
/* Just to make sure we are not exceeding int limit. */
70
- int nb_sectors = MIN(INT_MAX >> BDRV_SECTOR_BITS,
71
- end - sector_num);
72
+ int bytes = MIN(s->bdev_length - offset,
73
+ QEMU_ALIGN_DOWN(INT_MAX, s->granularity));
74
75
mirror_throttle(s);
76
77
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
78
return 0;
79
}
80
81
- ret = bdrv_is_allocated_above(bs, base, sector_num * BDRV_SECTOR_SIZE,
82
- nb_sectors * BDRV_SECTOR_SIZE, &count);
83
+ ret = bdrv_is_allocated_above(bs, base, offset, bytes, &count);
84
if (ret < 0) {
85
return ret;
86
}
87
88
- /* TODO: Relax this once bdrv_is_allocated_above and dirty
89
- * bitmaps no longer require sector alignment. */
90
- assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
91
- n = count >> BDRV_SECTOR_BITS;
92
- assert(n > 0);
93
+ assert(count);
94
if (ret == 1) {
95
- bdrv_set_dirty_bitmap(s->dirty_bitmap,
96
- sector_num * BDRV_SECTOR_SIZE,
97
- n * BDRV_SECTOR_SIZE);
98
+ bdrv_set_dirty_bitmap(s->dirty_bitmap, offset, count);
99
}
100
- sector_num += n;
101
+ offset += count;
102
}
103
return 0;
104
}
105
--
106
2.13.6
107
108
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Now that we have adjusted the majority of the calls this function
4
makes to be byte-based, it is easier to read the code if it makes
5
passes over the image using bytes rather than sectors.
6
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Reviewed-by: Fam Zheng <famz@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/qcow2-bitmap.c | 22 ++++++++--------------
15
1 file changed, 8 insertions(+), 14 deletions(-)
16
17
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-bitmap.c
20
+++ b/block/qcow2-bitmap.c
21
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
22
{
23
int ret = 0;
24
BDRVQcow2State *s = bs->opaque;
25
- uint64_t sector, limit, sbc;
26
+ uint64_t offset, limit;
27
uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
28
- uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
29
uint8_t *buf = NULL;
30
uint64_t i, tab_size =
31
size_to_clusters(s,
32
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
33
34
buf = g_malloc(s->cluster_size);
35
limit = bytes_covered_by_bitmap_cluster(s, bitmap);
36
- sbc = limit >> BDRV_SECTOR_BITS;
37
- for (i = 0, sector = 0; i < tab_size; ++i, sector += sbc) {
38
- uint64_t count = MIN(bm_sectors - sector, sbc);
39
+ for (i = 0, offset = 0; i < tab_size; ++i, offset += limit) {
40
+ uint64_t count = MIN(bm_size - offset, limit);
41
uint64_t entry = bitmap_table[i];
42
- uint64_t offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;
43
+ uint64_t data_offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;
44
45
assert(check_table_entry(entry, s->cluster_size) == 0);
46
47
- if (offset == 0) {
48
+ if (data_offset == 0) {
49
if (entry & BME_TABLE_ENTRY_FLAG_ALL_ONES) {
50
- bdrv_dirty_bitmap_deserialize_ones(bitmap,
51
- sector * BDRV_SECTOR_SIZE,
52
- count * BDRV_SECTOR_SIZE,
53
+ bdrv_dirty_bitmap_deserialize_ones(bitmap, offset, count,
54
false);
55
} else {
56
/* No need to deserialize zeros because the dirty bitmap is
57
* already cleared */
58
}
59
} else {
60
- ret = bdrv_pread(bs->file, offset, buf, s->cluster_size);
61
+ ret = bdrv_pread(bs->file, data_offset, buf, s->cluster_size);
62
if (ret < 0) {
63
goto finish;
64
}
65
- bdrv_dirty_bitmap_deserialize_part(bitmap, buf,
66
- sector * BDRV_SECTOR_SIZE,
67
- count * BDRV_SECTOR_SIZE,
68
+ bdrv_dirty_bitmap_deserialize_part(bitmap, buf, offset, count,
69
false);
70
}
71
}
72
--
73
2.13.6
74
75
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Now that we have adjusted the majority of the calls this function
4
makes to be byte-based, it is easier to read the code if it makes
5
passes over the image using bytes rather than sectors.
6
7
iotests 165 was rather weak - on a default 64k-cluster image, where
8
bitmap granularity also defaults to 64k bytes, a single cluster of
9
the bitmap table thus covers (64*1024*8) bits which each cover 64k
10
bytes, or 32G of image space. But the test only uses a 1G image,
11
so it cannot trigger any more than one loop of the code in
12
store_bitmap_data(); and it was writing to the first cluster. In
13
order to test that we are properly aligning which portions of the
14
bitmap are being written to the file, we really want to test a case
15
where the first dirty bit returned by bdrv_dirty_iter_next() is not
16
aligned to the start of a cluster, which we can do by modifying the
17
test to write data that doesn't happen to fall in the first cluster
18
of the image.
19
20
Signed-off-by: Eric Blake <eblake@redhat.com>
21
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
22
Reviewed-by: John Snow <jsnow@redhat.com>
23
Reviewed-by: Fam Zheng <famz@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
block/qcow2-bitmap.c | 31 ++++++++++++++++---------------
27
tests/qemu-iotests/165 | 2 +-
28
2 files changed, 17 insertions(+), 16 deletions(-)
29
30
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/block/qcow2-bitmap.c
33
+++ b/block/qcow2-bitmap.c
34
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
35
{
36
int ret;
37
BDRVQcow2State *s = bs->opaque;
38
- int64_t sector;
39
- uint64_t limit, sbc;
40
+ int64_t offset;
41
+ uint64_t limit;
42
uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
43
- uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
44
const char *bm_name = bdrv_dirty_bitmap_name(bitmap);
45
uint8_t *buf = NULL;
46
BdrvDirtyBitmapIter *dbi;
47
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
48
dbi = bdrv_dirty_iter_new(bitmap);
49
buf = g_malloc(s->cluster_size);
50
limit = bytes_covered_by_bitmap_cluster(s, bitmap);
51
- sbc = limit >> BDRV_SECTOR_BITS;
52
assert(DIV_ROUND_UP(bm_size, limit) == tb_size);
53
54
- while ((sector = bdrv_dirty_iter_next(dbi) >> BDRV_SECTOR_BITS) >= 0) {
55
- uint64_t cluster = sector / sbc;
56
+ while ((offset = bdrv_dirty_iter_next(dbi)) >= 0) {
57
+ uint64_t cluster = offset / limit;
58
uint64_t end, write_size;
59
int64_t off;
60
61
- sector = cluster * sbc;
62
- end = MIN(bm_sectors, sector + sbc);
63
- write_size = bdrv_dirty_bitmap_serialization_size(bitmap,
64
- sector * BDRV_SECTOR_SIZE, (end - sector) * BDRV_SECTOR_SIZE);
65
+ /*
66
+ * We found the first dirty offset, but want to write out the
67
+ * entire cluster of the bitmap that includes that offset,
68
+ * including any leading zero bits.
69
+ */
70
+ offset = QEMU_ALIGN_DOWN(offset, limit);
71
+ end = MIN(bm_size, offset + limit);
72
+ write_size = bdrv_dirty_bitmap_serialization_size(bitmap, offset,
73
+ end - offset);
74
assert(write_size <= s->cluster_size);
75
76
off = qcow2_alloc_clusters(bs, s->cluster_size);
77
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
78
}
79
tb[cluster] = off;
80
81
- bdrv_dirty_bitmap_serialize_part(bitmap, buf,
82
- sector * BDRV_SECTOR_SIZE,
83
- (end - sector) * BDRV_SECTOR_SIZE);
84
+ bdrv_dirty_bitmap_serialize_part(bitmap, buf, offset, end - offset);
85
if (write_size < s->cluster_size) {
86
memset(buf + write_size, 0, s->cluster_size - write_size);
87
}
88
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
89
goto fail;
90
}
91
92
- if (end >= bm_sectors) {
93
+ if (end >= bm_size) {
94
break;
95
}
96
97
- bdrv_set_dirty_iter(dbi, end * BDRV_SECTOR_SIZE);
98
+ bdrv_set_dirty_iter(dbi, end);
99
}
100
101
*bitmap_table_size = tb_size;
102
diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165
103
index XXXXXXX..XXXXXXX 100755
104
--- a/tests/qemu-iotests/165
105
+++ b/tests/qemu-iotests/165
106
@@ -XXX,XX +XXX,XX @@ disk = os.path.join(iotests.test_dir, 'disk')
107
disk_size = 0x40000000 # 1G
108
109
# regions for qemu_io: (start, count) in bytes
110
-regions1 = ((0, 0x100000),
111
+regions1 = ((0x0fff00, 0x10000),
112
(0x200000, 0x100000))
113
114
regions2 = ((0x10000000, 0x20000),
115
--
116
2.13.6
117
118
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Now that all callers are using byte-based interfaces, there's no
4
reason for our internal hbitmap to remain with sector-based
5
granularity. It also simplifies our internal scaling, since we
6
already know that hbitmap widens requests out to granularity
7
boundaries.
8
9
Signed-off-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Fam Zheng <famz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/dirty-bitmap.c | 62 +++++++++++++++-------------------------------------
16
1 file changed, 18 insertions(+), 44 deletions(-)
17
18
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/dirty-bitmap.c
21
+++ b/block/dirty-bitmap.c
22
@@ -XXX,XX +XXX,XX @@
23
*/
24
struct BdrvDirtyBitmap {
25
QemuMutex *mutex;
26
- HBitmap *bitmap; /* Dirty sector bitmap implementation */
27
+ HBitmap *bitmap; /* Dirty bitmap implementation */
28
HBitmap *meta; /* Meta dirty bitmap */
29
BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
30
char *name; /* Optional non-empty unique ID */
31
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
32
}
33
bitmap = g_new0(BdrvDirtyBitmap, 1);
34
bitmap->mutex = &bs->dirty_bitmap_mutex;
35
- /*
36
- * TODO - let hbitmap track full granularity. For now, it is tracking
37
- * only sector granularity, as a shortcut for our iterators.
38
- */
39
- bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap_size, BDRV_SECTOR_SIZE),
40
- ctz32(granularity) - BDRV_SECTOR_BITS);
41
+ bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
42
bitmap->size = bitmap_size;
43
bitmap->name = g_strdup(name);
44
bitmap->disabled = false;
45
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
46
QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
47
assert(!bdrv_dirty_bitmap_frozen(bitmap));
48
assert(!bitmap->active_iterators);
49
- hbitmap_truncate(bitmap->bitmap, DIV_ROUND_UP(bytes, BDRV_SECTOR_SIZE));
50
+ hbitmap_truncate(bitmap->bitmap, bytes);
51
bitmap->size = bytes;
52
}
53
bdrv_dirty_bitmaps_unlock(bs);
54
@@ -XXX,XX +XXX,XX @@ bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
55
int64_t offset)
56
{
57
if (bitmap) {
58
- return hbitmap_get(bitmap->bitmap, offset >> BDRV_SECTOR_BITS);
59
+ return hbitmap_get(bitmap->bitmap, offset);
60
} else {
61
return false;
62
}
63
@@ -XXX,XX +XXX,XX @@ uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
64
65
uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
66
{
67
- return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
68
+ return 1U << hbitmap_granularity(bitmap->bitmap);
69
}
70
71
BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
72
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
73
74
int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
75
{
76
- int64_t ret = hbitmap_iter_next(&iter->hbi);
77
- return ret < 0 ? -1 : ret * BDRV_SECTOR_SIZE;
78
+ return hbitmap_iter_next(&iter->hbi);
79
}
80
81
/* Called within bdrv_dirty_bitmap_lock..unlock */
82
void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
83
int64_t offset, int64_t bytes)
84
{
85
- int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
86
-
87
assert(bdrv_dirty_bitmap_enabled(bitmap));
88
assert(!bdrv_dirty_bitmap_readonly(bitmap));
89
- hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
90
- end_sector - (offset >> BDRV_SECTOR_BITS));
91
+ hbitmap_set(bitmap->bitmap, offset, bytes);
92
}
93
94
void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
95
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
96
void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
97
int64_t offset, int64_t bytes)
98
{
99
- int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
100
-
101
assert(bdrv_dirty_bitmap_enabled(bitmap));
102
assert(!bdrv_dirty_bitmap_readonly(bitmap));
103
- hbitmap_reset(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
104
- end_sector - (offset >> BDRV_SECTOR_BITS));
105
+ hbitmap_reset(bitmap->bitmap, offset, bytes);
106
}
107
108
void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
109
@@ -XXX,XX +XXX,XX @@ void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
110
hbitmap_reset_all(bitmap->bitmap);
111
} else {
112
HBitmap *backup = bitmap->bitmap;
113
- bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap->size,
114
- BDRV_SECTOR_SIZE),
115
+ bitmap->bitmap = hbitmap_alloc(bitmap->size,
116
hbitmap_granularity(backup));
117
*out = backup;
118
}
119
@@ -XXX,XX +XXX,XX @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
120
uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
121
uint64_t offset, uint64_t bytes)
122
{
123
- assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
124
- return hbitmap_serialization_size(bitmap->bitmap,
125
- offset >> BDRV_SECTOR_BITS,
126
- bytes >> BDRV_SECTOR_BITS);
127
+ return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
128
}
129
130
uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
131
{
132
- return hbitmap_serialization_align(bitmap->bitmap) * BDRV_SECTOR_SIZE;
133
+ return hbitmap_serialization_align(bitmap->bitmap);
134
}
135
136
void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
137
uint8_t *buf, uint64_t offset,
138
uint64_t bytes)
139
{
140
- assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
141
- hbitmap_serialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
142
- bytes >> BDRV_SECTOR_BITS);
143
+ hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
144
}
145
146
void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
147
uint8_t *buf, uint64_t offset,
148
uint64_t bytes, bool finish)
149
{
150
- assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
151
- hbitmap_deserialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
152
- bytes >> BDRV_SECTOR_BITS, finish);
153
+ hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
154
}
155
156
void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
157
uint64_t offset, uint64_t bytes,
158
bool finish)
159
{
160
- assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
161
- hbitmap_deserialize_zeroes(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
162
- bytes >> BDRV_SECTOR_BITS, finish);
163
+ hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
164
}
165
166
void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
167
uint64_t offset, uint64_t bytes,
168
bool finish)
169
{
170
- assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
171
- hbitmap_deserialize_ones(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
172
- bytes >> BDRV_SECTOR_BITS, finish);
173
+ hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
174
}
175
176
void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
177
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
178
void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
179
{
180
BdrvDirtyBitmap *bitmap;
181
- int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
182
183
if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
184
return;
185
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
186
continue;
187
}
188
assert(!bdrv_dirty_bitmap_readonly(bitmap));
189
- hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
190
- end_sector - (offset >> BDRV_SECTOR_BITS));
191
+ hbitmap_set(bitmap->bitmap, offset, bytes);
192
}
193
bdrv_dirty_bitmaps_unlock(bs);
194
}
195
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
196
*/
197
void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
198
{
199
- hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset >> BDRV_SECTOR_BITS);
200
+ hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
201
}
202
203
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
204
{
205
- return hbitmap_count(bitmap->bitmap) << BDRV_SECTOR_BITS;
206
+ return hbitmap_count(bitmap->bitmap);
207
}
208
209
int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
210
--
211
2.13.6
212
213
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
The condition of the for-loop makes sure that b is always smaller
4
than s->blocks, so the "if (b >= s->blocks)" statement is completely
5
superfluous here.
6
7
Buglink: https://bugs.launchpad.net/qemu/+bug/1715007
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
hw/block/onenand.c | 4 ----
13
1 file changed, 4 deletions(-)
14
15
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/block/onenand.c
18
+++ b/hw/block/onenand.c
19
@@ -XXX,XX +XXX,XX @@ static void onenand_command(OneNANDState *s)
20
s->intstatus |= ONEN_INT;
21
22
for (b = 0; b < s->blocks; b ++) {
23
- if (b >= s->blocks) {
24
- s->status |= ONEN_ERR_CMD;
25
- break;
26
- }
27
if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
28
break;
29
30
--
31
2.13.6
32
33
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
Some functions in common.rc are never used by the tests. Move
4
them out of that file and into common, which is already included
5
only by "check".
6
7
Code that actually *is* common to "check" and tests can be placed in
8
common.config.
9
10
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
tests/qemu-iotests/common | 25 ++++++++++++++++++++++++-
15
tests/qemu-iotests/common.config | 12 ++++++++++++
16
tests/qemu-iotests/common.rc | 40 ----------------------------------------
17
3 files changed, 36 insertions(+), 41 deletions(-)
18
19
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/qemu-iotests/common
22
+++ b/tests/qemu-iotests/common
23
@@ -XXX,XX +XXX,XX @@
24
# common procedures for QA scripts
25
#
26
27
+_full_imgfmt_details()
28
+{
29
+ if [ -n "$IMGOPTS" ]; then
30
+ echo "$IMGFMT ($IMGOPTS)"
31
+ else
32
+ echo "$IMGFMT"
33
+ fi
34
+}
35
+
36
+_full_platform_details()
37
+{
38
+ os=`uname -s`
39
+ host=`hostname -s`
40
+ kernel=`uname -r`
41
+ platform=`uname -m`
42
+ echo "$os/$platform $host $kernel"
43
+}
44
+
45
diff="diff -u"
46
verbose=false
47
debug=false
48
@@ -XXX,XX +XXX,XX @@ if [ "$IMGOPTSSYNTAX" != "true" ]; then
49
fi
50
51
# Set default options for qemu-img create -o if they were not specified
52
-_set_default_imgopts
53
+if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
54
+ IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
55
+fi
56
+if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
57
+ IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
58
+fi
59
60
if [ -s $tmp.list ]
61
then
62
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
63
index XXXXXXX..XXXXXXX 100644
64
--- a/tests/qemu-iotests/common.config
65
+++ b/tests/qemu-iotests/common.config
66
@@ -XXX,XX +XXX,XX @@ export PWD=`pwd`
67
68
export _QEMU_HANDLE=0
69
70
+# make sure we have a standard umask
71
+umask 022
72
+
73
# $1 = prog to look for, $2* = default pathnames if not found in $PATH
74
set_prog_path()
75
{
76
@@ -XXX,XX +XXX,XX @@ set_prog_path()
77
return 1
78
}
79
80
+_optstr_add()
81
+{
82
+ if [ -n "$1" ]; then
83
+ echo "$1,$2"
84
+ else
85
+ echo "$2"
86
+ fi
87
+}
88
+
89
_fatal()
90
{
91
echo "$*"
92
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
93
index XXXXXXX..XXXXXXX 100644
94
--- a/tests/qemu-iotests/common.rc
95
+++ b/tests/qemu-iotests/common.rc
96
@@ -XXX,XX +XXX,XX @@ then
97
fi
98
fi
99
100
-# make sure we have a standard umask
101
-umask 022
102
-
103
if [ "$IMGOPTSSYNTAX" = "true" ]; then
104
DRIVER="driver=$IMGFMT"
105
if [ "$IMGFMT" = "luks" ]; then
106
@@ -XXX,XX +XXX,XX @@ else
107
fi
108
ORIG_TEST_IMG="$TEST_IMG"
109
110
-_optstr_add()
111
-{
112
- if [ -n "$1" ]; then
113
- echo "$1,$2"
114
- else
115
- echo "$2"
116
- fi
117
-}
118
-
119
-_set_default_imgopts()
120
-{
121
- if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
122
- IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
123
- fi
124
- if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
125
- IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
126
- fi
127
-}
128
-
129
_use_sample_img()
130
{
131
SAMPLE_IMG_FILE="${1%\.bz2}"
132
@@ -XXX,XX +XXX,XX @@ _require_command()
133
[ -x "$c" ] || _notrun "$1 utility required, skipped this test"
134
}
135
136
-_full_imgfmt_details()
137
-{
138
- if [ -n "$IMGOPTS" ]; then
139
- echo "$IMGFMT ($IMGOPTS)"
140
- else
141
- echo "$IMGFMT"
142
- fi
143
-}
144
-
145
-_full_platform_details()
146
-{
147
- os=`uname -s`
148
- host=`hostname -s`
149
- kernel=`uname -r`
150
- platform=`uname -m`
151
- echo "$os/$platform $host $kernel"
152
-}
153
-
154
# make sure this script returns success
155
true
156
--
157
2.13.6
158
159
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
Instead of ./check failing when a binary is missing, we try each test
4
case now and each one fails with tons of test case diffs. Also, all the
5
variables were initialized by "check" prior to "common" being sourced,
6
and then (uselessly) checked for emptiness again in "check".
7
8
Centralize the search for programs in "common" (which will soon be
9
one with "check"), including the "realpath" invocation which can be done
10
just once in "check" rather than in the tests.
11
12
For qnio_server, move the detection to "common", simplifying
13
set_prog_path to stop handling the unused second argument, and
14
embedding the "realpath" pass.
15
16
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
17
Reviewed-by: Eric Blake <eblake@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
tests/qemu-iotests/check | 41 ---------------------
21
tests/qemu-iotests/common | 77 +++++++++++++++++++++++++++++++++++++---
22
tests/qemu-iotests/common.config | 61 +------------------------------
23
3 files changed, 73 insertions(+), 106 deletions(-)
24
25
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
26
index XXXXXXX..XXXXXXX 100755
27
--- a/tests/qemu-iotests/check
28
+++ b/tests/qemu-iotests/check
29
@@ -XXX,XX +XXX,XX @@ fi
30
31
build_root="$build_iotests/../.."
32
33
-if [ -x "$build_iotests/socket_scm_helper" ]
34
-then
35
- export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
36
-fi
37
-
38
-if [[ -z "$QEMU_PROG" && ! -x './qemu' ]]
39
-then
40
- arch=$(uname -m 2> /dev/null)
41
-
42
- if [[ -n $arch && -x "$build_root/$arch-softmmu/qemu-system-$arch" ]]
43
- then
44
- export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
45
- else
46
- pushd "$build_root" > /dev/null
47
- for binary in *-softmmu/qemu-system-*
48
- do
49
- if [ -x "$binary" ]
50
- then
51
- export QEMU_PROG="$build_root/$binary"
52
- break
53
- fi
54
- done
55
- popd > /dev/null
56
- fi
57
-fi
58
-
59
-if [[ -z $QEMU_IMG_PROG && -x "$build_root/qemu-img" && ! -x './qemu-img' ]]
60
-then
61
- export QEMU_IMG_PROG="$build_root/qemu-img"
62
-fi
63
-
64
-if [[ -z $QEMU_IO_PROG && -x "$build_root/qemu-io" && ! -x './qemu-io' ]]
65
-then
66
- export QEMU_IO_PROG="$build_root/qemu-io"
67
-fi
68
-
69
-if [[ -z $QEMU_NBD_PROG && -x "$build_root/qemu-nbd" && ! -x './qemu-nbd' ]]
70
-then
71
- export QEMU_NBD_PROG="$build_root/qemu-nbd"
72
-fi
73
-
74
# we need common.env
75
if ! . "$build_iotests/common.env"
76
then
77
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
78
index XXXXXXX..XXXXXXX 100644
79
--- a/tests/qemu-iotests/common
80
+++ b/tests/qemu-iotests/common
81
@@ -XXX,XX +XXX,XX @@ _full_platform_details()
82
echo "$os/$platform $host $kernel"
83
}
84
85
+# $1 = prog to look for
86
+set_prog_path()
87
+{
88
+ p=`command -v $1 2> /dev/null`
89
+ if [ -n "$p" -a -x "$p" ]; then
90
+ realpath -- "$(type -p "$p")"
91
+ else
92
+ return 1
93
+ fi
94
+}
95
+
96
diff="diff -u"
97
verbose=false
98
debug=false
99
@@ -XXX,XX +XXX,XX @@ fi
100
list=`sort $tmp.list`
101
rm -f $tmp.list $tmp.tmp $tmp.sed
102
103
-[ "$QEMU" = "" ] && _fatal "qemu not found"
104
-[ "$QEMU_IMG" = "" ] && _fatal "qemu-img not found"
105
-[ "$QEMU_IO" = "" ] && _fatal "qemu-io not found"
106
+if [ -z "$QEMU_PROG" ]
107
+then
108
+ if [ -x "$build_iotests/qemu" ]; then
109
+ export QEMU_PROG="$build_iotests/qemu"
110
+ elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
111
+ export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
112
+ else
113
+ pushd "$build_root" > /dev/null
114
+ for binary in *-softmmu/qemu-system-*
115
+ do
116
+ if [ -x "$binary" ]
117
+ then
118
+ export QEMU_PROG="$build_root/$binary"
119
+ break
120
+ fi
121
+ done
122
+ popd > /dev/null
123
+ [ "$QEMU_PROG" = "" ] && _init_error "qemu not found"
124
+ fi
125
+fi
126
+export QEMU_PROG=$(realpath -- "$(type -p "$QEMU_PROG")")
127
+
128
+if [ -z "$QEMU_IMG_PROG" ]; then
129
+ if [ -x "$build_iotests/qemu-img" ]; then
130
+ export QEMU_IMG_PROG="$build_iotests/qemu-img"
131
+ elif [ -x "$build_root/qemu-img" ]; then
132
+ export QEMU_IMG_PROG="$build_root/qemu-img"
133
+ else
134
+ _init_error "qemu-img not found"
135
+ fi
136
+fi
137
+export QEMU_IMG_PROG=$(realpath -- "$(type -p "$QEMU_IMG_PROG")")
138
+
139
+if [ -z "$QEMU_IO_PROG" ]; then
140
+ if [ -x "$build_iotests/qemu-io" ]; then
141
+ export QEMU_IO_PROG="$build_iotests/qemu-io"
142
+ elif [ -x "$build_root/qemu-io" ]; then
143
+ export QEMU_IO_PROG="$build_root/qemu-io"
144
+ else
145
+ _init_error "qemu-io not found"
146
+ fi
147
+fi
148
+export QEMU_IO_PROG=$(realpath -- "$(type -p "$QEMU_IO_PROG")")
149
150
-if [ "$IMGPROTO" = "nbd" ] ; then
151
- [ "$QEMU_NBD" = "" ] && _fatal "qemu-nbd not found"
152
+if [ -z $QEMU_NBD_PROG ]; then
153
+ if [ -x "$build_iotests/qemu-nbd" ]; then
154
+ export QEMU_NBD_PROG="$build_iotests/qemu-nbd"
155
+ elif [ -x "$build_root/qemu-nbd" ]; then
156
+ export QEMU_NBD_PROG="$build_root/qemu-nbd"
157
+ else
158
+ _init_error "qemu-nbd not found"
159
+ fi
160
+fi
161
+export QEMU_NBD_PROG=$(realpath -- "$(type -p "$QEMU_NBD_PROG")")
162
+
163
+if [ -z "$QEMU_VXHS_PROG" ]; then
164
+ export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
165
+fi
166
+
167
+if [ -x "$build_iotests/socket_scm_helper" ]
168
+then
169
+ export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
170
fi
171
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
172
index XXXXXXX..XXXXXXX 100644
173
--- a/tests/qemu-iotests/common.config
174
+++ b/tests/qemu-iotests/common.config
175
@@ -XXX,XX +XXX,XX @@ export LANG=C
176
PATH=".:$PATH"
177
178
HOSTOS=`uname -s`
179
+arch=`uname -m`
180
181
export PWD=`pwd`
182
183
@@ -XXX,XX +XXX,XX @@ export _QEMU_HANDLE=0
184
# make sure we have a standard umask
185
umask 022
186
187
-# $1 = prog to look for, $2* = default pathnames if not found in $PATH
188
-set_prog_path()
189
-{
190
- p=`command -v $1 2> /dev/null`
191
- if [ -n "$p" -a -x "$p" ]; then
192
- echo $p
193
- return 0
194
- fi
195
- p=$1
196
-
197
- shift
198
- for f; do
199
- if [ -x $f ]; then
200
- echo $f
201
- return 0
202
- fi
203
- done
204
-
205
- echo ""
206
- return 1
207
-}
208
-
209
_optstr_add()
210
{
211
if [ -n "$1" ]; then
212
@@ -XXX,XX +XXX,XX @@ _optstr_add()
213
fi
214
}
215
216
-_fatal()
217
-{
218
- echo "$*"
219
- status=1
220
- exit 1
221
-}
222
-
223
-if [ -z "$QEMU_PROG" ]; then
224
- export QEMU_PROG="`set_prog_path qemu`"
225
-fi
226
-
227
-if [ -z "$QEMU_IMG_PROG" ]; then
228
- export QEMU_IMG_PROG="`set_prog_path qemu-img`"
229
-fi
230
-
231
-if [ -z "$QEMU_IO_PROG" ]; then
232
- export QEMU_IO_PROG="`set_prog_path qemu-io`"
233
-fi
234
-
235
-if [ -z "$QEMU_NBD_PROG" ]; then
236
- export QEMU_NBD_PROG="`set_prog_path qemu-nbd`"
237
-fi
238
-
239
-if [ -z "$QEMU_VXHS_PROG" ]; then
240
- export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
241
-fi
242
-
243
-export QEMU_PROG=$(realpath -- "$(type -p "$QEMU_PROG")")
244
-export QEMU_IMG_PROG=$(realpath -- "$(type -p "$QEMU_IMG_PROG")")
245
-export QEMU_IO_PROG=$(realpath -- "$(type -p "$QEMU_IO_PROG")")
246
-export QEMU_NBD_PROG=$(realpath -- "$(type -p "$QEMU_NBD_PROG")")
247
-
248
-# This program is not built as part of qemu but (possibly) provided by the
249
-# system, so it may not be present at all
250
-if [ -n "$QEMU_VXHS_PROG" ]; then
251
- export QEMU_VXHS_PROG=$(realpath -- "$(type -p "$QEMU_VXHS_PROG")")
252
-fi
253
-
254
_qemu_wrapper()
255
{
256
(
257
--
258
2.13.6
259
260
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
These are never used by "check", with one exception that does not need
4
$QEMU_OPTIONS. Keep them in common.rc, which will be soon included only
5
by the tests.
6
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
tests/qemu-iotests/039.out | 10 +++---
12
tests/qemu-iotests/061.out | 4 +--
13
tests/qemu-iotests/137.out | 2 +-
14
tests/qemu-iotests/common.config | 69 ++--------------------------------------
15
tests/qemu-iotests/common.rc | 65 +++++++++++++++++++++++++++++++++++++
16
5 files changed, 75 insertions(+), 75 deletions(-)
17
18
diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out
19
index XXXXXXX..XXXXXXX 100644
20
--- a/tests/qemu-iotests/039.out
21
+++ b/tests/qemu-iotests/039.out
22
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
23
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
24
wrote 512/512 bytes at offset 0
25
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
26
-./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
27
+./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
28
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
29
else
30
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
31
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
32
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
33
wrote 512/512 bytes at offset 0
34
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
35
-./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
36
+./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
37
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
38
else
39
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
40
@@ -XXX,XX +XXX,XX @@ incompatible_features 0x0
41
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
42
wrote 512/512 bytes at offset 0
43
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
44
-./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
45
+./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
46
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
47
else
48
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
49
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
50
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
51
wrote 512/512 bytes at offset 0
52
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
53
-./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
54
+./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
55
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
56
else
57
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
58
@@ -XXX,XX +XXX,XX @@ Data may be corrupted, or further writes to the image may corrupt it.
59
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
60
wrote 512/512 bytes at offset 0
61
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
62
-./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
63
+./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
64
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
65
else
66
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
67
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
68
index XXXXXXX..XXXXXXX 100644
69
--- a/tests/qemu-iotests/061.out
70
+++ b/tests/qemu-iotests/061.out
71
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
72
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
73
wrote 131072/131072 bytes at offset 0
74
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
75
-./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
76
+./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
77
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
78
else
79
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
80
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
81
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
82
wrote 131072/131072 bytes at offset 0
83
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
84
-./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
85
+./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
86
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
87
else
88
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
89
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
90
index XXXXXXX..XXXXXXX 100644
91
--- a/tests/qemu-iotests/137.out
92
+++ b/tests/qemu-iotests/137.out
93
@@ -XXX,XX +XXX,XX @@ Cache clean interval too big
94
Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
95
wrote 512/512 bytes at offset 0
96
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
97
-./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
98
+./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
99
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
100
else
101
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
102
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
103
index XXXXXXX..XXXXXXX 100644
104
--- a/tests/qemu-iotests/common.config
105
+++ b/tests/qemu-iotests/common.config
106
@@ -XXX,XX +XXX,XX @@ _optstr_add()
107
fi
108
}
109
110
-_qemu_wrapper()
111
-{
112
- (
113
- if [ -n "${QEMU_NEED_PID}" ]; then
114
- echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
115
- fi
116
- exec "$QEMU_PROG" $QEMU_OPTIONS "$@"
117
- )
118
-}
119
-
120
-_qemu_img_wrapper()
121
-{
122
- (exec "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS "$@")
123
-}
124
-
125
-_qemu_io_wrapper()
126
-{
127
- local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
128
- local QEMU_IO_ARGS="$QEMU_IO_OPTIONS"
129
- if [ "$IMGOPTSSYNTAX" = "true" ]; then
130
- QEMU_IO_ARGS="--image-opts $QEMU_IO_ARGS"
131
- if [ -n "$IMGKEYSECRET" ]; then
132
- QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS"
133
- fi
134
- fi
135
- local RETVAL
136
- (
137
- if [ "${VALGRIND_QEMU}" == "y" ]; then
138
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
139
- else
140
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
141
- fi
142
- )
143
- RETVAL=$?
144
- if [ "${VALGRIND_QEMU}" == "y" ]; then
145
- if [ $RETVAL == 99 ]; then
146
- cat "${VALGRIND_LOGFILE}"
147
- fi
148
- rm -f "${VALGRIND_LOGFILE}"
149
- fi
150
- (exit $RETVAL)
151
-}
152
-
153
-_qemu_nbd_wrapper()
154
-{
155
- (
156
- echo $BASHPID > "${QEMU_TEST_DIR}/qemu-nbd.pid"
157
- exec "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS "$@"
158
- )
159
-}
160
-
161
-_qemu_vxhs_wrapper()
162
-{
163
- (
164
- echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
165
- exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
166
- )
167
-}
168
-
169
-export QEMU=_qemu_wrapper
170
-export QEMU_IMG=_qemu_img_wrapper
171
-export QEMU_IO=_qemu_io_wrapper
172
-export QEMU_NBD=_qemu_nbd_wrapper
173
-export QEMU_VXHS=_qemu_vxhs_wrapper
174
-
175
QEMU_IMG_EXTRA_ARGS=
176
if [ "$IMGOPTSSYNTAX" = "true" ]; then
177
QEMU_IMG_EXTRA_ARGS="--image-opts $QEMU_IMG_EXTRA_ARGS"
178
@@ -XXX,XX +XXX,XX @@ fi
179
export QEMU_IMG_EXTRA_ARGS
180
181
182
-default_machine=$($QEMU -machine help | sed -n '/(default)/ s/ .*//p')
183
-default_alias_machine=$($QEMU -machine help | \
184
+default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
185
+default_alias_machine=$($QEMU_PROG -machine help | \
186
sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
187
if [[ "$default_alias_machine" ]]; then
188
default_machine="$default_alias_machine"
189
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
190
index XXXXXXX..XXXXXXX 100644
191
--- a/tests/qemu-iotests/common.rc
192
+++ b/tests/qemu-iotests/common.rc
193
@@ -XXX,XX +XXX,XX @@ then
194
fi
195
fi
196
197
+_qemu_wrapper()
198
+{
199
+ (
200
+ if [ -n "${QEMU_NEED_PID}" ]; then
201
+ echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
202
+ fi
203
+ exec "$QEMU_PROG" $QEMU_OPTIONS "$@"
204
+ )
205
+}
206
+
207
+_qemu_img_wrapper()
208
+{
209
+ (exec "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS "$@")
210
+}
211
+
212
+_qemu_io_wrapper()
213
+{
214
+ local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
215
+ local QEMU_IO_ARGS="$QEMU_IO_OPTIONS"
216
+ if [ "$IMGOPTSSYNTAX" = "true" ]; then
217
+ QEMU_IO_ARGS="--image-opts $QEMU_IO_ARGS"
218
+ if [ -n "$IMGKEYSECRET" ]; then
219
+ QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS"
220
+ fi
221
+ fi
222
+ local RETVAL
223
+ (
224
+ if [ "${VALGRIND_QEMU}" == "y" ]; then
225
+ exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
226
+ else
227
+ exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
228
+ fi
229
+ )
230
+ RETVAL=$?
231
+ if [ "${VALGRIND_QEMU}" == "y" ]; then
232
+ if [ $RETVAL == 99 ]; then
233
+ cat "${VALGRIND_LOGFILE}"
234
+ fi
235
+ rm -f "${VALGRIND_LOGFILE}"
236
+ fi
237
+ (exit $RETVAL)
238
+}
239
+
240
+_qemu_nbd_wrapper()
241
+{
242
+ (
243
+ echo $BASHPID > "${QEMU_TEST_DIR}/qemu-nbd.pid"
244
+ exec "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS "$@"
245
+ )
246
+}
247
+
248
+_qemu_vxhs_wrapper()
249
+{
250
+ (
251
+ echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
252
+ exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
253
+ )
254
+}
255
+
256
+export QEMU=_qemu_wrapper
257
+export QEMU_IMG=_qemu_img_wrapper
258
+export QEMU_IO=_qemu_io_wrapper
259
+export QEMU_NBD=_qemu_nbd_wrapper
260
+export QEMU_VXHS=_qemu_vxhs_wrapper
261
+
262
if [ "$IMGOPTSSYNTAX" = "true" ]; then
263
DRIVER="driver=$IMGFMT"
264
if [ "$IMGFMT" = "luks" ]; then
265
--
266
2.13.6
267
268
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
It only provides functions used by the test programs.
4
5
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
tests/qemu-iotests/check | 6 ------
10
tests/qemu-iotests/common.rc | 13 +++++--------
11
2 files changed, 5 insertions(+), 14 deletions(-)
12
13
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
14
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/check
16
+++ b/tests/qemu-iotests/check
17
@@ -XXX,XX +XXX,XX @@ then
18
_init_error "failed to source common.config"
19
fi
20
21
-# we need common.rc
22
-if ! . "$source_iotests/common.rc"
23
-then
24
- _init_error "failed to source common.rc"
25
-fi
26
-
27
# we need common
28
. "$source_iotests/common"
29
30
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
31
index XXXXXXX..XXXXXXX 100644
32
--- a/tests/qemu-iotests/common.rc
33
+++ b/tests/qemu-iotests/common.rc
34
@@ -XXX,XX +XXX,XX @@ poke_file()
35
printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
36
}
37
38
-# we need common.config
39
-if [ "$iam" != "check" ]
40
-then
41
- if ! . ./common.config
42
- then
43
- echo "$iam: failed to source common.config"
44
- exit 1
45
- fi
46
+
47
+if ! . ./common.config
48
+ then
49
+ echo "$iam: failed to source common.config"
50
+ exit 1
51
fi
52
53
_qemu_wrapper()
54
--
55
2.13.6
56
57
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
Split "check" parts from tests part.
4
5
For the directory setup, the actual computation of directories goes
6
in "check", while the sanity checks go in the tests.
7
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
tests/qemu-iotests/common | 24 ++++++++++++++++++++
13
tests/qemu-iotests/common.config | 49 ----------------------------------------
14
tests/qemu-iotests/common.qemu | 1 +
15
tests/qemu-iotests/common.rc | 25 ++++++++++++++++++++
16
4 files changed, 50 insertions(+), 49 deletions(-)
17
18
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
19
index XXXXXXX..XXXXXXX 100644
20
--- a/tests/qemu-iotests/common
21
+++ b/tests/qemu-iotests/common
22
@@ -XXX,XX +XXX,XX @@ set_prog_path()
23
fi
24
}
25
26
+if [ -z "$TEST_DIR" ]; then
27
+ TEST_DIR=`pwd`/scratch
28
+fi
29
+
30
+if [ ! -e "$TEST_DIR" ]; then
31
+ mkdir "$TEST_DIR"
32
+fi
33
+
34
diff="diff -u"
35
verbose=false
36
debug=false
37
@@ -XXX,XX +XXX,XX @@ if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null
38
IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
39
fi
40
41
+if [ -z "$SAMPLE_IMG_DIR" ]; then
42
+ SAMPLE_IMG_DIR="$source_iotests/sample_images"
43
+fi
44
+
45
+export TEST_DIR
46
+export SAMPLE_IMG_DIR
47
+
48
if [ -s $tmp.list ]
49
then
50
# found some valid test numbers ... this is good
51
@@ -XXX,XX +XXX,XX @@ if [ -x "$build_iotests/socket_scm_helper" ]
52
then
53
export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
54
fi
55
+
56
+default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
57
+default_alias_machine=$($QEMU_PROG -machine help | \
58
+ sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
59
+if [[ "$default_alias_machine" ]]; then
60
+ default_machine="$default_alias_machine"
61
+fi
62
+
63
+export QEMU_DEFAULT_MACHINE="$default_machine"
64
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tests/qemu-iotests/common.config
67
+++ b/tests/qemu-iotests/common.config
68
@@ -XXX,XX +XXX,XX @@ arch=`uname -m`
69
70
export PWD=`pwd`
71
72
-export _QEMU_HANDLE=0
73
-
74
# make sure we have a standard umask
75
umask 022
76
77
@@ -XXX,XX +XXX,XX @@ _optstr_add()
78
fi
79
}
80
81
-QEMU_IMG_EXTRA_ARGS=
82
-if [ "$IMGOPTSSYNTAX" = "true" ]; then
83
- QEMU_IMG_EXTRA_ARGS="--image-opts $QEMU_IMG_EXTRA_ARGS"
84
- if [ -n "$IMGKEYSECRET" ]; then
85
- QEMU_IMG_EXTRA_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IMG_EXTRA_ARGS"
86
- fi
87
-fi
88
-export QEMU_IMG_EXTRA_ARGS
89
-
90
-
91
-default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
92
-default_alias_machine=$($QEMU_PROG -machine help | \
93
- sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
94
-if [[ "$default_alias_machine" ]]; then
95
- default_machine="$default_alias_machine"
96
-fi
97
-
98
-export QEMU_DEFAULT_MACHINE="$default_machine"
99
-
100
-if [ -z "$TEST_DIR" ]; then
101
- TEST_DIR=`pwd`/scratch
102
-fi
103
-
104
-QEMU_TEST_DIR="${TEST_DIR}"
105
-
106
-if [ ! -e "$TEST_DIR" ]; then
107
- mkdir "$TEST_DIR"
108
-fi
109
-
110
-if [ ! -d "$TEST_DIR" ]; then
111
- echo "common.config: Error: \$TEST_DIR ($TEST_DIR) is not a directory"
112
- exit 1
113
-fi
114
-
115
-export TEST_DIR
116
-
117
-if [ -z "$SAMPLE_IMG_DIR" ]; then
118
- SAMPLE_IMG_DIR="$source_iotests/sample_images"
119
-fi
120
-
121
-if [ ! -d "$SAMPLE_IMG_DIR" ]; then
122
- echo "common.config: Error: \$SAMPLE_IMG_DIR ($SAMPLE_IMG_DIR) is not a directory"
123
- exit 1
124
-fi
125
-
126
-export SAMPLE_IMG_DIR
127
-
128
# make sure this script returns success
129
true
130
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
131
index XXXXXXX..XXXXXXX 100644
132
--- a/tests/qemu-iotests/common.qemu
133
+++ b/tests/qemu-iotests/common.qemu
134
@@ -XXX,XX +XXX,XX @@ QEMU_FIFO_IN="${QEMU_TEST_DIR}/qmp-in-$$"
135
QEMU_FIFO_OUT="${QEMU_TEST_DIR}/qmp-out-$$"
136
137
QEMU_HANDLE=0
138
+export _QEMU_HANDLE=0
139
140
# If bash version is >= 4.1, these will be overwritten and dynamic
141
# file descriptor values assigned.
142
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/tests/qemu-iotests/common.rc
145
+++ b/tests/qemu-iotests/common.rc
146
@@ -XXX,XX +XXX,XX @@ export QEMU_VXHS=_qemu_vxhs_wrapper
147
148
if [ "$IMGOPTSSYNTAX" = "true" ]; then
149
DRIVER="driver=$IMGFMT"
150
+ QEMU_IMG_EXTRA_ARGS="--image-opts $QEMU_IMG_EXTRA_ARGS"
151
+ if [ -n "$IMGKEYSECRET" ]; then
152
+ QEMU_IMG_EXTRA_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IMG_EXTRA_ARGS"
153
+ fi
154
if [ "$IMGFMT" = "luks" ]; then
155
DRIVER="$DRIVER,key-secret=keysec0"
156
fi
157
@@ -XXX,XX +XXX,XX @@ if [ "$IMGOPTSSYNTAX" = "true" ]; then
158
TEST_IMG="$DRIVER,file.driver=$IMGPROTO,file.filename=$TEST_DIR/t.$IMGFMT"
159
fi
160
else
161
+ QEMU_IMG_EXTRA_ARGS=
162
if [ "$IMGPROTO" = "file" ]; then
163
TEST_IMG=$TEST_DIR/t.$IMGFMT
164
elif [ "$IMGPROTO" = "nbd" ]; then
165
@@ -XXX,XX +XXX,XX @@ else
166
fi
167
ORIG_TEST_IMG="$TEST_IMG"
168
169
+if [ -z "$TEST_DIR" ]; then
170
+ TEST_DIR=`pwd`/scratch
171
+fi
172
+
173
+QEMU_TEST_DIR="${TEST_DIR}"
174
+
175
+if [ ! -e "$TEST_DIR" ]; then
176
+ mkdir "$TEST_DIR"
177
+fi
178
+
179
+if [ ! -d "$TEST_DIR" ]; then
180
+ echo "common.config: Error: \$TEST_DIR ($TEST_DIR) is not a directory"
181
+ exit 1
182
+fi
183
+
184
+if [ ! -d "$SAMPLE_IMG_DIR" ]; then
185
+ echo "common.config: Error: \$SAMPLE_IMG_DIR ($SAMPLE_IMG_DIR) is not a directory"
186
+ exit 1
187
+fi
188
+
189
_use_sample_img()
190
{
191
SAMPLE_IMG_FILE="${1%\.bz2}"
192
--
193
2.13.6
194
195
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
The variable is used in "common" but defined only after the file
4
is sourced.
5
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
tests/qemu-iotests/check | 2 --
11
tests/qemu-iotests/common | 2 ++
12
2 files changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
15
index XXXXXXX..XXXXXXX 100755
16
--- a/tests/qemu-iotests/check
17
+++ b/tests/qemu-iotests/check
18
@@ -XXX,XX +XXX,XX @@ fi
19
20
TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT
21
22
-tmp="${TEST_DIR}"/$$
23
-
24
_wallclock()
25
{
26
date "+%H %M %S" | awk '{ print $1*3600 + $2*60 + $3 }'
27
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
28
index XXXXXXX..XXXXXXX 100644
29
--- a/tests/qemu-iotests/common
30
+++ b/tests/qemu-iotests/common
31
@@ -XXX,XX +XXX,XX @@ sortme=false
32
expunge=true
33
have_test_arg=false
34
cachemode=false
35
+
36
+tmp="${TEST_DIR}"/$$
37
rm -f $tmp.list $tmp.tmp $tmp.sed
38
39
export IMGFMT=raw
40
--
41
2.13.6
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
The variable is almost unused, and one of the two uses is actually
4
uninitialized.
5
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
tests/qemu-iotests/check | 5 +----
11
tests/qemu-iotests/common.rc | 2 +-
12
2 files changed, 2 insertions(+), 5 deletions(-)
13
14
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
15
index XXXXXXX..XXXXXXX 100755
16
--- a/tests/qemu-iotests/check
17
+++ b/tests/qemu-iotests/check
18
@@ -XXX,XX +XXX,XX @@ interrupt=true
19
# by default don't output timestamps
20
timestamp=${TIMESTAMP:=false}
21
22
-# generic initialization
23
-iam=check
24
-
25
_init_error()
26
{
27
- echo "$iam: $1" >&2
28
+ echo "check: $1" >&2
29
exit 1
30
}
31
32
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/tests/qemu-iotests/common.rc
35
+++ b/tests/qemu-iotests/common.rc
36
@@ -XXX,XX +XXX,XX @@ poke_file()
37
38
if ! . ./common.config
39
then
40
- echo "$iam: failed to source common.config"
41
+ echo "$0: failed to source common.config"
42
exit 1
43
fi
44
45
--
46
2.13.6
47
48
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
"check" is full of qemu-iotests--specific details. Separating it
4
from "common" does not make much sense anymore.
5
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
tests/qemu-iotests/check | 533 +++++++++++++++++++++++++++++++++++++++++++-
11
tests/qemu-iotests/common | 552 ----------------------------------------------
12
2 files changed, 531 insertions(+), 554 deletions(-)
13
delete mode 100644 tests/qemu-iotests/common
14
15
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/check
18
+++ b/tests/qemu-iotests/check
19
@@ -XXX,XX +XXX,XX @@ then
20
_init_error "failed to source common.config"
21
fi
22
23
-# we need common
24
-. "$source_iotests/common"
25
+_full_imgfmt_details()
26
+{
27
+ if [ -n "$IMGOPTS" ]; then
28
+ echo "$IMGFMT ($IMGOPTS)"
29
+ else
30
+ echo "$IMGFMT"
31
+ fi
32
+}
33
+
34
+_full_platform_details()
35
+{
36
+ os=`uname -s`
37
+ host=`hostname -s`
38
+ kernel=`uname -r`
39
+ platform=`uname -m`
40
+ echo "$os/$platform $host $kernel"
41
+}
42
+
43
+# $1 = prog to look for
44
+set_prog_path()
45
+{
46
+ p=`command -v $1 2> /dev/null`
47
+ if [ -n "$p" -a -x "$p" ]; then
48
+ realpath -- "$(type -p "$p")"
49
+ else
50
+ return 1
51
+ fi
52
+}
53
+
54
+if [ -z "$TEST_DIR" ]; then
55
+ TEST_DIR=`pwd`/scratch
56
+fi
57
+
58
+if [ ! -e "$TEST_DIR" ]; then
59
+ mkdir "$TEST_DIR"
60
+fi
61
+
62
+diff="diff -u"
63
+verbose=false
64
+debug=false
65
+group=false
66
+xgroup=false
67
+imgopts=false
68
+showme=false
69
+sortme=false
70
+expunge=true
71
+have_test_arg=false
72
+cachemode=false
73
+
74
+tmp="${TEST_DIR}"/$$
75
+rm -f $tmp.list $tmp.tmp $tmp.sed
76
+
77
+export IMGFMT=raw
78
+export IMGFMT_GENERIC=true
79
+export IMGPROTO=file
80
+export IMGOPTS=""
81
+export CACHEMODE="writeback"
82
+export QEMU_IO_OPTIONS=""
83
+export QEMU_IO_OPTIONS_NO_FMT=""
84
+export CACHEMODE_IS_DEFAULT=true
85
+export QEMU_OPTIONS="-nodefaults -machine accel=qtest"
86
+export VALGRIND_QEMU=
87
+export IMGKEYSECRET=
88
+export IMGOPTSSYNTAX=false
89
+
90
+for r
91
+do
92
+
93
+ if $group
94
+ then
95
+ # arg after -g
96
+ group_list=`sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
97
+s/ .*//p
98
+}'`
99
+ if [ -z "$group_list" ]
100
+ then
101
+ echo "Group \"$r\" is empty or not defined?"
102
+ exit 1
103
+ fi
104
+ [ ! -s $tmp.list ] && touch $tmp.list
105
+ for t in $group_list
106
+ do
107
+ if grep -s "^$t\$" $tmp.list >/dev/null
108
+ then
109
+ :
110
+ else
111
+ echo "$t" >>$tmp.list
112
+ fi
113
+ done
114
+ group=false
115
+ continue
116
+
117
+ elif $xgroup
118
+ then
119
+ # arg after -x
120
+ # Populate $tmp.list with all tests
121
+ awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list 2>/dev/null
122
+ group_list=`sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
123
+s/ .*//p
124
+}'`
125
+ if [ -z "$group_list" ]
126
+ then
127
+ echo "Group \"$r\" is empty or not defined?"
128
+ exit 1
129
+ fi
130
+ numsed=0
131
+ rm -f $tmp.sed
132
+ for t in $group_list
133
+ do
134
+ if [ $numsed -gt 100 ]
135
+ then
136
+ sed -f $tmp.sed <$tmp.list >$tmp.tmp
137
+ mv $tmp.tmp $tmp.list
138
+ numsed=0
139
+ rm -f $tmp.sed
140
+ fi
141
+ echo "/^$t\$/d" >>$tmp.sed
142
+ numsed=`expr $numsed + 1`
143
+ done
144
+ sed -f $tmp.sed <$tmp.list >$tmp.tmp
145
+ mv $tmp.tmp $tmp.list
146
+ xgroup=false
147
+ continue
148
+
149
+ elif $imgopts
150
+ then
151
+ IMGOPTS="$r"
152
+ imgopts=false
153
+ continue
154
+ elif $cachemode
155
+ then
156
+ CACHEMODE="$r"
157
+ CACHEMODE_IS_DEFAULT=false
158
+ cachemode=false
159
+ continue
160
+ fi
161
+
162
+ xpand=true
163
+ case "$r"
164
+ in
165
+
166
+ -\? | -h | --help) # usage
167
+ echo "Usage: $0 [options] [testlist]"'
168
+
169
+common options
170
+ -v verbose
171
+ -d debug
172
+
173
+image format options
174
+ -raw test raw (default)
175
+ -bochs test bochs
176
+ -cloop test cloop
177
+ -parallels test parallels
178
+ -qcow test qcow
179
+ -qcow2 test qcow2
180
+ -qed test qed
181
+ -vdi test vdi
182
+ -vpc test vpc
183
+ -vhdx test vhdx
184
+ -vmdk test vmdk
185
+ -luks test luks
186
+
187
+image protocol options
188
+ -file test file (default)
189
+ -rbd test rbd
190
+ -sheepdog test sheepdog
191
+ -nbd test nbd
192
+ -ssh test ssh
193
+ -nfs test nfs
194
+ -vxhs test vxhs
195
+
196
+other options
197
+ -xdiff graphical mode diff
198
+ -nocache use O_DIRECT on backing file
199
+ -misalign misalign memory allocations
200
+ -n show me, do not run tests
201
+ -o options -o options to pass to qemu-img create/convert
202
+ -T output timestamps
203
+ -c mode cache mode
204
+
205
+testlist options
206
+ -g group[,group...] include tests from these groups
207
+ -x group[,group...] exclude tests from these groups
208
+ NNN include test NNN
209
+ NNN-NNN include test range (eg. 012-021)
210
+'
211
+ exit 0
212
+ ;;
213
+
214
+ -raw)
215
+ IMGFMT=raw
216
+ xpand=false
217
+ ;;
218
+
219
+ -bochs)
220
+ IMGFMT=bochs
221
+ IMGFMT_GENERIC=false
222
+ xpand=false
223
+ ;;
224
+
225
+ -cloop)
226
+ IMGFMT=cloop
227
+ IMGFMT_GENERIC=false
228
+ xpand=false
229
+ ;;
230
+
231
+ -parallels)
232
+ IMGFMT=parallels
233
+ IMGFMT_GENERIC=false
234
+ xpand=false
235
+ ;;
236
+
237
+ -qcow)
238
+ IMGFMT=qcow
239
+ xpand=false
240
+ ;;
241
+
242
+ -qcow2)
243
+ IMGFMT=qcow2
244
+ xpand=false
245
+ ;;
246
+
247
+ -luks)
248
+ IMGOPTSSYNTAX=true
249
+ IMGFMT=luks
250
+ IMGKEYSECRET=123456
251
+ xpand=false
252
+ ;;
253
+
254
+ -qed)
255
+ IMGFMT=qed
256
+ xpand=false
257
+ ;;
258
+
259
+ -vdi)
260
+ IMGFMT=vdi
261
+ xpand=false
262
+ ;;
263
+
264
+ -vmdk)
265
+ IMGFMT=vmdk
266
+ xpand=false
267
+ ;;
268
+
269
+ -vpc)
270
+ IMGFMT=vpc
271
+ xpand=false
272
+ ;;
273
+
274
+ -vhdx)
275
+ IMGFMT=vhdx
276
+ xpand=false
277
+ ;;
278
+
279
+ -file)
280
+ IMGPROTO=file
281
+ xpand=false
282
+ ;;
283
+
284
+ -rbd)
285
+ IMGPROTO=rbd
286
+ xpand=false
287
+ ;;
288
+
289
+ -sheepdog)
290
+ IMGPROTO=sheepdog
291
+ xpand=false
292
+ ;;
293
+
294
+ -nbd)
295
+ IMGPROTO=nbd
296
+ xpand=false
297
+ ;;
298
+
299
+ -vxhs)
300
+ IMGPROTO=vxhs
301
+ xpand=false
302
+ ;;
303
+
304
+ -ssh)
305
+ IMGPROTO=ssh
306
+ xpand=false
307
+ ;;
308
+
309
+ -nfs)
310
+ IMGPROTO=nfs
311
+ xpand=false
312
+ ;;
313
+
314
+ -nocache)
315
+ CACHEMODE="none"
316
+ CACHEMODE_IS_DEFAULT=false
317
+ xpand=false
318
+ ;;
319
+
320
+ -misalign)
321
+ QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --misalign"
322
+ xpand=false
323
+ ;;
324
+
325
+ -valgrind)
326
+ VALGRIND_QEMU='y'
327
+ xpand=false
328
+ ;;
329
+
330
+ -g) # -g group ... pick from group file
331
+ group=true
332
+ xpand=false
333
+ ;;
334
+
335
+ -xdiff) # graphical diff mode
336
+ xpand=false
337
+
338
+ if [ ! -z "$DISPLAY" ]
339
+ then
340
+ command -v xdiff >/dev/null 2>&1 && diff=xdiff
341
+ command -v gdiff >/dev/null 2>&1 && diff=gdiff
342
+ command -v tkdiff >/dev/null 2>&1 && diff=tkdiff
343
+ command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
344
+ fi
345
+ ;;
346
+
347
+ -n) # show me, don't do it
348
+ showme=true
349
+ xpand=false
350
+ ;;
351
+ -o)
352
+ imgopts=true
353
+ xpand=false
354
+ ;;
355
+ -c)
356
+ cachemode=true
357
+ xpand=false
358
+ ;;
359
+ -T) # turn on timestamp output
360
+ timestamp=true
361
+ xpand=false
362
+ ;;
363
+
364
+ -v)
365
+ verbose=true
366
+ xpand=false
367
+ ;;
368
+ -d)
369
+ debug=true
370
+ xpand=false
371
+ ;;
372
+ -x) # -x group ... exclude from group file
373
+ xgroup=true
374
+ xpand=false
375
+ ;;
376
+ '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
377
+ echo "No tests?"
378
+ status=1
379
+ exit $status
380
+ ;;
381
+
382
+ [0-9]*-[0-9]*)
383
+ eval `echo $r | sed -e 's/^/start=/' -e 's/-/ end=/'`
384
+ ;;
385
+
386
+ [0-9]*-)
387
+ eval `echo $r | sed -e 's/^/start=/' -e 's/-//'`
388
+ end=`echo [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] | sed -e 's/\[0-9]//g' -e 's/ *$//' -e 's/.* //'`
389
+ if [ -z "$end" ]
390
+ then
391
+ echo "No tests in range \"$r\"?"
392
+ status=1
393
+ exit $status
394
+ fi
395
+ ;;
396
+
397
+ *)
398
+ start=$r
399
+ end=$r
400
+ ;;
401
+
402
+ esac
403
+
404
+ # get rid of leading 0s as can be interpreted as octal
405
+ start=`echo $start | sed 's/^0*//'`
406
+ end=`echo $end | sed 's/^0*//'`
407
+
408
+ if $xpand
409
+ then
410
+ have_test_arg=true
411
+ awk </dev/null '
412
+BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
413
+ | while read id
414
+ do
415
+ if grep -s "^$id " "$source_iotests/group" >/dev/null
416
+ then
417
+ # in group file ... OK
418
+ echo $id >>$tmp.list
419
+ else
420
+ if [ -f expunged ] && $expunge && egrep "^$id([ ]|\$)" expunged >/dev/null
421
+ then
422
+ # expunged ... will be reported, but not run, later
423
+ echo $id >>$tmp.list
424
+ else
425
+ # oops
426
+ if [ "$start" == "$end" -a "$id" == "$end" ]
427
+ then
428
+ echo "$id - unknown test"
429
+ exit 1
430
+ else
431
+ echo "$id - unknown test, ignored"
432
+ fi
433
+ fi
434
+ fi
435
+ done || exit 1
436
+ fi
437
+
438
+done
439
+
440
+# Set qemu-io cache mode with $CACHEMODE we have
441
+QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
442
+
443
+QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS"
444
+if [ "$IMGOPTSSYNTAX" != "true" ]; then
445
+ QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT"
446
+fi
447
+
448
+# Set default options for qemu-img create -o if they were not specified
449
+if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
450
+ IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
451
+fi
452
+if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
453
+ IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
454
+fi
455
+
456
+if [ -z "$SAMPLE_IMG_DIR" ]; then
457
+ SAMPLE_IMG_DIR="$source_iotests/sample_images"
458
+fi
459
+
460
+export TEST_DIR
461
+export SAMPLE_IMG_DIR
462
+
463
+if [ -s $tmp.list ]
464
+then
465
+ # found some valid test numbers ... this is good
466
+ :
467
+else
468
+ if $have_test_arg
469
+ then
470
+ # had test numbers, but none in group file ... do nothing
471
+ touch $tmp.list
472
+ else
473
+ # no test numbers, do everything from group file
474
+ sed -n -e '/^[0-9][0-9][0-9]*/s/[ ].*//p' <"$source_iotests/group" >$tmp.list
475
+ fi
476
+fi
477
+
478
+# should be sort -n, but this did not work for Linux when this
479
+# was ported from IRIX
480
+#
481
+list=`sort $tmp.list`
482
+rm -f $tmp.list $tmp.tmp $tmp.sed
483
+
484
+if [ -z "$QEMU_PROG" ]
485
+then
486
+ if [ -x "$build_iotests/qemu" ]; then
487
+ export QEMU_PROG="$build_iotests/qemu"
488
+ elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
489
+ export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
490
+ else
491
+ pushd "$build_root" > /dev/null
492
+ for binary in *-softmmu/qemu-system-*
493
+ do
494
+ if [ -x "$binary" ]
495
+ then
496
+ export QEMU_PROG="$build_root/$binary"
497
+ break
498
+ fi
499
+ done
500
+ popd > /dev/null
501
+ [ "$QEMU_PROG" = "" ] && _init_error "qemu not found"
502
+ fi
503
+fi
504
+export QEMU_PROG=$(realpath -- "$(type -p "$QEMU_PROG")")
505
+
506
+if [ -z "$QEMU_IMG_PROG" ]; then
507
+ if [ -x "$build_iotests/qemu-img" ]; then
508
+ export QEMU_IMG_PROG="$build_iotests/qemu-img"
509
+ elif [ -x "$build_root/qemu-img" ]; then
510
+ export QEMU_IMG_PROG="$build_root/qemu-img"
511
+ else
512
+ _init_error "qemu-img not found"
513
+ fi
514
+fi
515
+export QEMU_IMG_PROG=$(realpath -- "$(type -p "$QEMU_IMG_PROG")")
516
+
517
+if [ -z "$QEMU_IO_PROG" ]; then
518
+ if [ -x "$build_iotests/qemu-io" ]; then
519
+ export QEMU_IO_PROG="$build_iotests/qemu-io"
520
+ elif [ -x "$build_root/qemu-io" ]; then
521
+ export QEMU_IO_PROG="$build_root/qemu-io"
522
+ else
523
+ _init_error "qemu-io not found"
524
+ fi
525
+fi
526
+export QEMU_IO_PROG=$(realpath -- "$(type -p "$QEMU_IO_PROG")")
527
+
528
+if [ -z $QEMU_NBD_PROG ]; then
529
+ if [ -x "$build_iotests/qemu-nbd" ]; then
530
+ export QEMU_NBD_PROG="$build_iotests/qemu-nbd"
531
+ elif [ -x "$build_root/qemu-nbd" ]; then
532
+ export QEMU_NBD_PROG="$build_root/qemu-nbd"
533
+ else
534
+ _init_error "qemu-nbd not found"
535
+ fi
536
+fi
537
+export QEMU_NBD_PROG=$(realpath -- "$(type -p "$QEMU_NBD_PROG")")
538
+
539
+if [ -z "$QEMU_VXHS_PROG" ]; then
540
+ export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
541
+fi
542
+
543
+if [ -x "$build_iotests/socket_scm_helper" ]
544
+then
545
+ export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
546
+fi
547
+
548
+default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
549
+default_alias_machine=$($QEMU_PROG -machine help | \
550
+ sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
551
+if [[ "$default_alias_machine" ]]; then
552
+ default_machine="$default_alias_machine"
553
+fi
554
+
555
+export QEMU_DEFAULT_MACHINE="$default_machine"
556
557
TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT
558
559
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
560
deleted file mode 100644
561
index XXXXXXX..XXXXXXX
562
--- a/tests/qemu-iotests/common
563
+++ /dev/null
564
@@ -XXX,XX +XXX,XX @@
565
-#!/bin/bash
566
-#
567
-# Copyright (C) 2009 Red Hat, Inc.
568
-# Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
569
-#
570
-# This program is free software; you can redistribute it and/or
571
-# modify it under the terms of the GNU General Public License as
572
-# published by the Free Software Foundation.
573
-#
574
-# This program is distributed in the hope that it would be useful,
575
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
576
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
577
-# GNU General Public License for more details.
578
-#
579
-# You should have received a copy of the GNU General Public License
580
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
581
-#
582
-#
583
-# common procedures for QA scripts
584
-#
585
-
586
-_full_imgfmt_details()
587
-{
588
- if [ -n "$IMGOPTS" ]; then
589
- echo "$IMGFMT ($IMGOPTS)"
590
- else
591
- echo "$IMGFMT"
592
- fi
593
-}
594
-
595
-_full_platform_details()
596
-{
597
- os=`uname -s`
598
- host=`hostname -s`
599
- kernel=`uname -r`
600
- platform=`uname -m`
601
- echo "$os/$platform $host $kernel"
602
-}
603
-
604
-# $1 = prog to look for
605
-set_prog_path()
606
-{
607
- p=`command -v $1 2> /dev/null`
608
- if [ -n "$p" -a -x "$p" ]; then
609
- realpath -- "$(type -p "$p")"
610
- else
611
- return 1
612
- fi
613
-}
614
-
615
-if [ -z "$TEST_DIR" ]; then
616
- TEST_DIR=`pwd`/scratch
617
-fi
618
-
619
-if [ ! -e "$TEST_DIR" ]; then
620
- mkdir "$TEST_DIR"
621
-fi
622
-
623
-diff="diff -u"
624
-verbose=false
625
-debug=false
626
-group=false
627
-xgroup=false
628
-imgopts=false
629
-showme=false
630
-sortme=false
631
-expunge=true
632
-have_test_arg=false
633
-cachemode=false
634
-
635
-tmp="${TEST_DIR}"/$$
636
-rm -f $tmp.list $tmp.tmp $tmp.sed
637
-
638
-export IMGFMT=raw
639
-export IMGFMT_GENERIC=true
640
-export IMGPROTO=file
641
-export IMGOPTS=""
642
-export CACHEMODE="writeback"
643
-export QEMU_IO_OPTIONS=""
644
-export QEMU_IO_OPTIONS_NO_FMT=""
645
-export CACHEMODE_IS_DEFAULT=true
646
-export QEMU_OPTIONS="-nodefaults -machine accel=qtest"
647
-export VALGRIND_QEMU=
648
-export IMGKEYSECRET=
649
-export IMGOPTSSYNTAX=false
650
-
651
-for r
652
-do
653
-
654
- if $group
655
- then
656
- # arg after -g
657
- group_list=`sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
658
-s/ .*//p
659
-}'`
660
- if [ -z "$group_list" ]
661
- then
662
- echo "Group \"$r\" is empty or not defined?"
663
- exit 1
664
- fi
665
- [ ! -s $tmp.list ] && touch $tmp.list
666
- for t in $group_list
667
- do
668
- if grep -s "^$t\$" $tmp.list >/dev/null
669
- then
670
- :
671
- else
672
- echo "$t" >>$tmp.list
673
- fi
674
- done
675
- group=false
676
- continue
677
-
678
- elif $xgroup
679
- then
680
- # arg after -x
681
- # Populate $tmp.list with all tests
682
- awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list 2>/dev/null
683
- group_list=`sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
684
-s/ .*//p
685
-}'`
686
- if [ -z "$group_list" ]
687
- then
688
- echo "Group \"$r\" is empty or not defined?"
689
- exit 1
690
- fi
691
- numsed=0
692
- rm -f $tmp.sed
693
- for t in $group_list
694
- do
695
- if [ $numsed -gt 100 ]
696
- then
697
- sed -f $tmp.sed <$tmp.list >$tmp.tmp
698
- mv $tmp.tmp $tmp.list
699
- numsed=0
700
- rm -f $tmp.sed
701
- fi
702
- echo "/^$t\$/d" >>$tmp.sed
703
- numsed=`expr $numsed + 1`
704
- done
705
- sed -f $tmp.sed <$tmp.list >$tmp.tmp
706
- mv $tmp.tmp $tmp.list
707
- xgroup=false
708
- continue
709
-
710
- elif $imgopts
711
- then
712
- IMGOPTS="$r"
713
- imgopts=false
714
- continue
715
- elif $cachemode
716
- then
717
- CACHEMODE="$r"
718
- CACHEMODE_IS_DEFAULT=false
719
- cachemode=false
720
- continue
721
- fi
722
-
723
- xpand=true
724
- case "$r"
725
- in
726
-
727
- -\? | -h | --help) # usage
728
- echo "Usage: $0 [options] [testlist]"'
729
-
730
-common options
731
- -v verbose
732
- -d debug
733
-
734
-image format options
735
- -raw test raw (default)
736
- -bochs test bochs
737
- -cloop test cloop
738
- -parallels test parallels
739
- -qcow test qcow
740
- -qcow2 test qcow2
741
- -qed test qed
742
- -vdi test vdi
743
- -vpc test vpc
744
- -vhdx test vhdx
745
- -vmdk test vmdk
746
- -luks test luks
747
-
748
-image protocol options
749
- -file test file (default)
750
- -rbd test rbd
751
- -sheepdog test sheepdog
752
- -nbd test nbd
753
- -ssh test ssh
754
- -nfs test nfs
755
- -vxhs test vxhs
756
-
757
-other options
758
- -xdiff graphical mode diff
759
- -nocache use O_DIRECT on backing file
760
- -misalign misalign memory allocations
761
- -n show me, do not run tests
762
- -o options -o options to pass to qemu-img create/convert
763
- -T output timestamps
764
- -c mode cache mode
765
-
766
-testlist options
767
- -g group[,group...] include tests from these groups
768
- -x group[,group...] exclude tests from these groups
769
- NNN include test NNN
770
- NNN-NNN include test range (eg. 012-021)
771
-'
772
- exit 0
773
- ;;
774
-
775
- -raw)
776
- IMGFMT=raw
777
- xpand=false
778
- ;;
779
-
780
- -bochs)
781
- IMGFMT=bochs
782
- IMGFMT_GENERIC=false
783
- xpand=false
784
- ;;
785
-
786
- -cloop)
787
- IMGFMT=cloop
788
- IMGFMT_GENERIC=false
789
- xpand=false
790
- ;;
791
-
792
- -parallels)
793
- IMGFMT=parallels
794
- IMGFMT_GENERIC=false
795
- xpand=false
796
- ;;
797
-
798
- -qcow)
799
- IMGFMT=qcow
800
- xpand=false
801
- ;;
802
-
803
- -qcow2)
804
- IMGFMT=qcow2
805
- xpand=false
806
- ;;
807
-
808
- -luks)
809
- IMGOPTSSYNTAX=true
810
- IMGFMT=luks
811
- IMGKEYSECRET=123456
812
- xpand=false
813
- ;;
814
-
815
- -qed)
816
- IMGFMT=qed
817
- xpand=false
818
- ;;
819
-
820
- -vdi)
821
- IMGFMT=vdi
822
- xpand=false
823
- ;;
824
-
825
- -vmdk)
826
- IMGFMT=vmdk
827
- xpand=false
828
- ;;
829
-
830
- -vpc)
831
- IMGFMT=vpc
832
- xpand=false
833
- ;;
834
-
835
- -vhdx)
836
- IMGFMT=vhdx
837
- xpand=false
838
- ;;
839
-
840
- -file)
841
- IMGPROTO=file
842
- xpand=false
843
- ;;
844
-
845
- -rbd)
846
- IMGPROTO=rbd
847
- xpand=false
848
- ;;
849
-
850
- -sheepdog)
851
- IMGPROTO=sheepdog
852
- xpand=false
853
- ;;
854
-
855
- -nbd)
856
- IMGPROTO=nbd
857
- xpand=false
858
- ;;
859
-
860
- -vxhs)
861
- IMGPROTO=vxhs
862
- xpand=false
863
- ;;
864
-
865
- -ssh)
866
- IMGPROTO=ssh
867
- xpand=false
868
- ;;
869
-
870
- -nfs)
871
- IMGPROTO=nfs
872
- xpand=false
873
- ;;
874
-
875
- -nocache)
876
- CACHEMODE="none"
877
- CACHEMODE_IS_DEFAULT=false
878
- xpand=false
879
- ;;
880
-
881
- -misalign)
882
- QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --misalign"
883
- xpand=false
884
- ;;
885
-
886
- -valgrind)
887
- VALGRIND_QEMU='y'
888
- xpand=false
889
- ;;
890
-
891
- -g) # -g group ... pick from group file
892
- group=true
893
- xpand=false
894
- ;;
895
-
896
- -xdiff) # graphical diff mode
897
- xpand=false
898
-
899
- if [ ! -z "$DISPLAY" ]
900
- then
901
- command -v xdiff >/dev/null 2>&1 && diff=xdiff
902
- command -v gdiff >/dev/null 2>&1 && diff=gdiff
903
- command -v tkdiff >/dev/null 2>&1 && diff=tkdiff
904
- command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
905
- fi
906
- ;;
907
-
908
- -n) # show me, don't do it
909
- showme=true
910
- xpand=false
911
- ;;
912
- -o)
913
- imgopts=true
914
- xpand=false
915
- ;;
916
- -c)
917
- cachemode=true
918
- xpand=false
919
- ;;
920
- -T) # turn on timestamp output
921
- timestamp=true
922
- xpand=false
923
- ;;
924
-
925
- -v)
926
- verbose=true
927
- xpand=false
928
- ;;
929
- -d)
930
- debug=true
931
- xpand=false
932
- ;;
933
- -x) # -x group ... exclude from group file
934
- xgroup=true
935
- xpand=false
936
- ;;
937
- '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
938
- echo "No tests?"
939
- status=1
940
- exit $status
941
- ;;
942
-
943
- [0-9]*-[0-9]*)
944
- eval `echo $r | sed -e 's/^/start=/' -e 's/-/ end=/'`
945
- ;;
946
-
947
- [0-9]*-)
948
- eval `echo $r | sed -e 's/^/start=/' -e 's/-//'`
949
- end=`echo [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] | sed -e 's/\[0-9]//g' -e 's/ *$//' -e 's/.* //'`
950
- if [ -z "$end" ]
951
- then
952
- echo "No tests in range \"$r\"?"
953
- status=1
954
- exit $status
955
- fi
956
- ;;
957
-
958
- *)
959
- start=$r
960
- end=$r
961
- ;;
962
-
963
- esac
964
-
965
- # get rid of leading 0s as can be interpreted as octal
966
- start=`echo $start | sed 's/^0*//'`
967
- end=`echo $end | sed 's/^0*//'`
968
-
969
- if $xpand
970
- then
971
- have_test_arg=true
972
- awk </dev/null '
973
-BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
974
- | while read id
975
- do
976
- if grep -s "^$id " "$source_iotests/group" >/dev/null
977
- then
978
- # in group file ... OK
979
- echo $id >>$tmp.list
980
- else
981
- if [ -f expunged ] && $expunge && egrep "^$id([ ]|\$)" expunged >/dev/null
982
- then
983
- # expunged ... will be reported, but not run, later
984
- echo $id >>$tmp.list
985
- else
986
- # oops
987
- if [ "$start" == "$end" -a "$id" == "$end" ]
988
- then
989
- echo "$id - unknown test"
990
- exit 1
991
- else
992
- echo "$id - unknown test, ignored"
993
- fi
994
- fi
995
- fi
996
- done || exit 1
997
- fi
998
-
999
-done
1000
-
1001
-# Set qemu-io cache mode with $CACHEMODE we have
1002
-QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
1003
-
1004
-QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS"
1005
-if [ "$IMGOPTSSYNTAX" != "true" ]; then
1006
- QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT"
1007
-fi
1008
-
1009
-# Set default options for qemu-img create -o if they were not specified
1010
-if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
1011
- IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
1012
-fi
1013
-if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
1014
- IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
1015
-fi
1016
-
1017
-if [ -z "$SAMPLE_IMG_DIR" ]; then
1018
- SAMPLE_IMG_DIR="$source_iotests/sample_images"
1019
-fi
1020
-
1021
-export TEST_DIR
1022
-export SAMPLE_IMG_DIR
1023
-
1024
-if [ -s $tmp.list ]
1025
-then
1026
- # found some valid test numbers ... this is good
1027
- :
1028
-else
1029
- if $have_test_arg
1030
- then
1031
- # had test numbers, but none in group file ... do nothing
1032
- touch $tmp.list
1033
- else
1034
- # no test numbers, do everything from group file
1035
- sed -n -e '/^[0-9][0-9][0-9]*/s/[ ].*//p' <"$source_iotests/group" >$tmp.list
1036
- fi
1037
-fi
1038
-
1039
-# should be sort -n, but this did not work for Linux when this
1040
-# was ported from IRIX
1041
-#
1042
-list=`sort $tmp.list`
1043
-rm -f $tmp.list $tmp.tmp $tmp.sed
1044
-
1045
-if [ -z "$QEMU_PROG" ]
1046
-then
1047
- if [ -x "$build_iotests/qemu" ]; then
1048
- export QEMU_PROG="$build_iotests/qemu"
1049
- elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
1050
- export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
1051
- else
1052
- pushd "$build_root" > /dev/null
1053
- for binary in *-softmmu/qemu-system-*
1054
- do
1055
- if [ -x "$binary" ]
1056
- then
1057
- export QEMU_PROG="$build_root/$binary"
1058
- break
1059
- fi
1060
- done
1061
- popd > /dev/null
1062
- [ "$QEMU_PROG" = "" ] && _init_error "qemu not found"
1063
- fi
1064
-fi
1065
-export QEMU_PROG=$(realpath -- "$(type -p "$QEMU_PROG")")
1066
-
1067
-if [ -z "$QEMU_IMG_PROG" ]; then
1068
- if [ -x "$build_iotests/qemu-img" ]; then
1069
- export QEMU_IMG_PROG="$build_iotests/qemu-img"
1070
- elif [ -x "$build_root/qemu-img" ]; then
1071
- export QEMU_IMG_PROG="$build_root/qemu-img"
1072
- else
1073
- _init_error "qemu-img not found"
1074
- fi
1075
-fi
1076
-export QEMU_IMG_PROG=$(realpath -- "$(type -p "$QEMU_IMG_PROG")")
1077
-
1078
-if [ -z "$QEMU_IO_PROG" ]; then
1079
- if [ -x "$build_iotests/qemu-io" ]; then
1080
- export QEMU_IO_PROG="$build_iotests/qemu-io"
1081
- elif [ -x "$build_root/qemu-io" ]; then
1082
- export QEMU_IO_PROG="$build_root/qemu-io"
1083
- else
1084
- _init_error "qemu-io not found"
1085
- fi
1086
-fi
1087
-export QEMU_IO_PROG=$(realpath -- "$(type -p "$QEMU_IO_PROG")")
1088
-
1089
-if [ -z $QEMU_NBD_PROG ]; then
1090
- if [ -x "$build_iotests/qemu-nbd" ]; then
1091
- export QEMU_NBD_PROG="$build_iotests/qemu-nbd"
1092
- elif [ -x "$build_root/qemu-nbd" ]; then
1093
- export QEMU_NBD_PROG="$build_root/qemu-nbd"
1094
- else
1095
- _init_error "qemu-nbd not found"
1096
- fi
1097
-fi
1098
-export QEMU_NBD_PROG=$(realpath -- "$(type -p "$QEMU_NBD_PROG")")
1099
-
1100
-if [ -z "$QEMU_VXHS_PROG" ]; then
1101
- export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
1102
-fi
1103
-
1104
-if [ -x "$build_iotests/socket_scm_helper" ]
1105
-then
1106
- export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
1107
-fi
1108
-
1109
-default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
1110
-default_alias_machine=$($QEMU_PROG -machine help | \
1111
- sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
1112
-if [[ "$default_alias_machine" ]]; then
1113
- default_machine="$default_alias_machine"
1114
-fi
1115
-
1116
-export QEMU_DEFAULT_MACHINE="$default_machine"
1117
--
1118
2.13.6
1119
1120
diff view generated by jsdifflib
Deleted patch
1
There is no good reason for bdrv_drop_intermediate() to know the active
2
layer above the subchain it is operating on - even more so, because
3
the assumption that there is a single active layer above it is not
4
generally true.
5
1
6
In order to prepare removal of the active parameter, use a BdrvChildRole
7
callback to update the backing file string in the overlay image instead
8
of directly calling bdrv_change_backing_file().
9
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
---
13
include/block/block_int.h | 6 ++++++
14
block.c | 33 ++++++++++++++++++++++++++++-----
15
2 files changed, 34 insertions(+), 5 deletions(-)
16
17
diff --git a/include/block/block_int.h b/include/block/block_int.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block_int.h
20
+++ b/include/block/block_int.h
21
@@ -XXX,XX +XXX,XX @@ struct BdrvChildRole {
22
23
void (*attach)(BdrvChild *child);
24
void (*detach)(BdrvChild *child);
25
+
26
+ /* Notifies the parent that the filename of its child has changed (e.g.
27
+ * because the direct child was removed from the backing chain), so that it
28
+ * can update its reference. */
29
+ int (*update_filename)(BdrvChild *child, BlockDriverState *new_base,
30
+ const char *filename, Error **errp);
31
};
32
33
extern const BdrvChildRole child_file;
34
diff --git a/block.c b/block.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block.c
37
+++ b/block.c
38
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
39
*child_flags = flags;
40
}
41
42
+static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
43
+ const char *filename, Error **errp)
44
+{
45
+ BlockDriverState *parent = c->opaque;
46
+ int ret;
47
+
48
+ ret = bdrv_change_backing_file(parent, filename,
49
+ base->drv ? base->drv->format_name : "");
50
+ if (ret < 0) {
51
+ error_setg_errno(errp, ret, "Could not update backing file link");
52
+ }
53
+
54
+ return ret;
55
+}
56
+
57
const BdrvChildRole child_backing = {
58
.get_parent_desc = bdrv_child_get_parent_desc,
59
.attach = bdrv_backing_attach,
60
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_backing = {
61
.drained_begin = bdrv_child_cb_drained_begin,
62
.drained_end = bdrv_child_cb_drained_end,
63
.inactivate = bdrv_child_cb_inactivate,
64
+ .update_filename = bdrv_backing_update_filename,
65
};
66
67
static int bdrv_open_flags(BlockDriverState *bs, int flags)
68
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
69
Error *local_err = NULL;
70
int ret = -EIO;
71
72
+ bdrv_ref(top);
73
+
74
if (!top->drv || !base->drv) {
75
goto exit;
76
}
77
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
78
}
79
80
/* success - we can delete the intermediate states, and link top->base */
81
- backing_file_str = backing_file_str ? backing_file_str : base->filename;
82
- ret = bdrv_change_backing_file(new_top_bs, backing_file_str,
83
- base->drv ? base->drv->format_name : "");
84
- if (ret) {
85
- goto exit;
86
+ if (new_top_bs->backing->role->update_filename) {
87
+ backing_file_str = backing_file_str ? backing_file_str : base->filename;
88
+ ret = new_top_bs->backing->role->update_filename(new_top_bs->backing,
89
+ base, backing_file_str,
90
+ &local_err);
91
+ if (ret < 0) {
92
+ bdrv_set_backing_hd(new_top_bs, top, &error_abort);
93
+ goto exit;
94
+ }
95
}
96
97
bdrv_set_backing_hd(new_top_bs, base, &local_err);
98
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
99
100
ret = 0;
101
exit:
102
+ bdrv_unref(top);
103
return ret;
104
}
105
106
--
107
2.13.6
108
109
diff view generated by jsdifflib
Deleted patch
1
QMP responses to certain commands can become quite long, which doesn't
2
only make reading them hard, but also means that the maximum line length
3
in patch emails can be exceeded. Allow tests to switch to QMP pretty
4
printing, which results in more, but shorter lines.
5
1
6
We also need to make sure to keep indentation in the response for this
7
to work as expected.
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
---
12
tests/qemu-iotests/common.qemu | 14 +++++++++++---
13
1 file changed, 11 insertions(+), 3 deletions(-)
14
15
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qemu-iotests/common.qemu
18
+++ b/tests/qemu-iotests/common.qemu
19
@@ -XXX,XX +XXX,XX @@ function _timed_wait_for()
20
shift
21
22
QEMU_STATUS[$h]=0
23
- while read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
24
+ while IFS= read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
25
do
26
if [ -z "${silent}" ]; then
27
echo "${resp}" | _filter_testdir | _filter_qemu \
28
| _filter_qemu_io | _filter_qmp | _filter_hmp
29
fi
30
- grep -q "${*}" < <(echo ${resp})
31
+ grep -q "${*}" < <(echo "${resp}")
32
if [ $? -eq 0 ]; then
33
return
34
fi
35
@@ -XXX,XX +XXX,XX @@ function _send_qemu_cmd()
36
# $qemu_comm_method: set this variable to 'monitor' (case insensitive)
37
# to use the QEMU HMP monitor for communication.
38
# Otherwise, the default of QMP is used.
39
+# $qmp_pretty: Set this variable to 'y' to enable QMP pretty printing.
40
# $keep_stderr: Set this variable to 'y' to keep QEMU's stderr output on stderr.
41
# If this variable is empty, stderr will be redirected to stdout.
42
# Returns:
43
@@ -XXX,XX +XXX,XX @@ function _launch_qemu()
44
comm="-monitor stdio"
45
else
46
local qemu_comm_method="qmp"
47
- comm="-monitor none -qmp stdio"
48
+ if [ "$qmp_pretty" = "y" ]; then
49
+ comm="-monitor none -qmp-pretty stdio"
50
+ else
51
+ comm="-monitor none -qmp stdio"
52
+ fi
53
fi
54
55
fifo_out=${QEMU_FIFO_OUT}_${_QEMU_HANDLE}
56
@@ -XXX,XX +XXX,XX @@ function _launch_qemu()
57
then
58
# Don't print response, since it has version information in it
59
silent=yes _timed_wait_for ${_QEMU_HANDLE} "capabilities"
60
+ if [ "$qmp_pretty" = "y" ]; then
61
+ silent=yes _timed_wait_for ${_QEMU_HANDLE} "^}"
62
+ fi
63
fi
64
QEMU_HANDLE=${_QEMU_HANDLE}
65
let _QEMU_HANDLE++
66
--
67
2.13.6
68
69
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Make it easier to enable copy-on-read during iotests, by
4
exposing a new bool option to main and open.
5
6
Signed-off-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Jeff Cody <jcody@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
qemu-io.c | 15 ++++++++++++---
14
1 file changed, 12 insertions(+), 3 deletions(-)
15
16
diff --git a/qemu-io.c b/qemu-io.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/qemu-io.c
19
+++ b/qemu-io.c
20
@@ -XXX,XX +XXX,XX @@ static void open_help(void)
21
" Opens a file for subsequent use by all of the other qemu-io commands.\n"
22
" -r, -- open file read-only\n"
23
" -s, -- use snapshot file\n"
24
+" -C, -- use copy-on-read\n"
25
" -n, -- disable host cache, short for -t none\n"
26
" -U, -- force shared permissions\n"
27
" -k, -- use kernel AIO implementation (on Linux only)\n"
28
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t open_cmd = {
29
.argmin = 1,
30
.argmax = -1,
31
.flags = CMD_NOFILE_OK,
32
- .args = "[-rsnkU] [-t cache] [-d discard] [-o options] [path]",
33
+ .args = "[-rsCnkU] [-t cache] [-d discard] [-o options] [path]",
34
.oneline = "open the file specified by path",
35
.help = open_help,
36
};
37
@@ -XXX,XX +XXX,XX @@ static int open_f(BlockBackend *blk, int argc, char **argv)
38
QDict *opts;
39
bool force_share = false;
40
41
- while ((c = getopt(argc, argv, "snro:kt:d:U")) != -1) {
42
+ while ((c = getopt(argc, argv, "snCro:kt:d:U")) != -1) {
43
switch (c) {
44
case 's':
45
flags |= BDRV_O_SNAPSHOT;
46
@@ -XXX,XX +XXX,XX @@ static int open_f(BlockBackend *blk, int argc, char **argv)
47
flags |= BDRV_O_NOCACHE;
48
writethrough = false;
49
break;
50
+ case 'C':
51
+ flags |= BDRV_O_COPY_ON_READ;
52
+ break;
53
case 'r':
54
readonly = 1;
55
break;
56
@@ -XXX,XX +XXX,XX @@ static void usage(const char *name)
57
" -r, --read-only export read-only\n"
58
" -s, --snapshot use snapshot file\n"
59
" -n, --nocache disable host cache, short for -t none\n"
60
+" -C, --copy-on-read enable copy-on-read\n"
61
" -m, --misalign misalign allocations for O_DIRECT\n"
62
" -k, --native-aio use kernel AIO implementation (on Linux only)\n"
63
" -t, --cache=MODE use the given cache mode for the image\n"
64
@@ -XXX,XX +XXX,XX @@ static QemuOptsList file_opts = {
65
int main(int argc, char **argv)
66
{
67
int readonly = 0;
68
- const char *sopt = "hVc:d:f:rsnmkt:T:U";
69
+ const char *sopt = "hVc:d:f:rsnCmkt:T:U";
70
const struct option lopt[] = {
71
{ "help", no_argument, NULL, 'h' },
72
{ "version", no_argument, NULL, 'V' },
73
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
74
{ "read-only", no_argument, NULL, 'r' },
75
{ "snapshot", no_argument, NULL, 's' },
76
{ "nocache", no_argument, NULL, 'n' },
77
+ { "copy-on-read", no_argument, NULL, 'C' },
78
{ "misalign", no_argument, NULL, 'm' },
79
{ "native-aio", no_argument, NULL, 'k' },
80
{ "discard", required_argument, NULL, 'd' },
81
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
82
flags |= BDRV_O_NOCACHE;
83
writethrough = false;
84
break;
85
+ case 'C':
86
+ flags |= BDRV_O_COPY_ON_READ;
87
+ break;
88
case 'd':
89
if (bdrv_parse_discard_flags(optarg, &flags) < 0) {
90
error_report("Invalid discard option: %s", optarg);
91
--
92
2.13.6
93
94
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Executing qemu with a terminal as stdin will temporarily alter stty
4
settings on that terminal (for example, disabling echo), because of
5
how we run both the monitor and any multiplexing with guest input.
6
Normally, qemu restores the original settings on exit; but if an
7
iotest triggers qemu to abort in the middle, we can be left with
8
the altered terminal setup. This can make life very annoying when
9
debugging an iotest failure (not everyone remembers the trick of
10
blind-typing 'stty sane' without echo, and some people prefer
11
terminal settings that are slightly different than the defaults
12
picked by 'stty sane').
13
14
It is possible to avoid qemu corrupting the terminal by not passing
15
a terminal to qemu's stdin in the first place (as in, use
16
'./check ... </dev/null'), but that's extra typing to have to
17
remember. But running 'exec </dev/null' in the harness seems like
18
it might be too heavy of a hammer. So I instead went the the
19
solution of saving and restoring the stty settings, only when the
20
harness detects that it is run interactively.
21
22
I tested this patch by forcing an allocation failure (I can't
23
guarantee that this particular limit will work on all setups, but
24
it shows the idea):
25
$ (ulimit -S -v 500000; ./check -qcow2 1)
26
27
Signed-off-by: Eric Blake <eblake@redhat.com>
28
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
29
---
30
tests/qemu-iotests/check | 10 ++++++++++
31
1 file changed, 10 insertions(+)
32
33
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
34
index XXXXXXX..XXXXXXX 100755
35
--- a/tests/qemu-iotests/check
36
+++ b/tests/qemu-iotests/check
37
@@ -XXX,XX +XXX,XX @@ export VALGRIND_QEMU=
38
export IMGKEYSECRET=
39
export IMGOPTSSYNTAX=false
40
41
+# Save current tty settings, since an aborting qemu call may leave things
42
+# screwed up
43
+STTY_RESTORE=
44
+if test -t 0; then
45
+ STTY_RESTORE=$(stty -g)
46
+fi
47
+
48
for r
49
do
50
51
@@ -XXX,XX +XXX,XX @@ END { if (NR > 0) {
52
needwrap=false
53
fi
54
55
+ if test -n "$STTY_RESTORE"; then
56
+ stty $STTY_RESTORE
57
+ fi
58
rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time
59
rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts
60
rm -f $tmp.*
61
--
62
2.13.6
63
64
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Make it possible to inject errors on writes performed during a
4
read operation due to copy-on-read semantics.
5
6
Signed-off-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Jeff Cody <jcody@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
qapi/block-core.json | 5 ++++-
14
block/io.c | 1 +
15
2 files changed, 5 insertions(+), 1 deletion(-)
16
17
diff --git a/qapi/block-core.json b/qapi/block-core.json
18
index XXXXXXX..XXXXXXX 100644
19
--- a/qapi/block-core.json
20
+++ b/qapi/block-core.json
21
@@ -XXX,XX +XXX,XX @@
22
#
23
# @l1_shrink_free_l2_clusters: discard the l2 tables. (since 2.11)
24
#
25
+# @cor_write: a write due to copy-on-read (since 2.11)
26
+#
27
# Since: 2.9
28
##
29
{ 'enum': 'BlkdebugEvent', 'prefix': 'BLKDBG',
30
@@ -XXX,XX +XXX,XX @@
31
'flush_to_disk', 'pwritev_rmw_head', 'pwritev_rmw_after_head',
32
'pwritev_rmw_tail', 'pwritev_rmw_after_tail', 'pwritev',
33
'pwritev_zero', 'pwritev_done', 'empty_image_prepare',
34
- 'l1_shrink_write_table', 'l1_shrink_free_l2_clusters' ] }
35
+ 'l1_shrink_write_table', 'l1_shrink_free_l2_clusters',
36
+ 'cor_write'] }
37
38
##
39
# @BlkdebugInjectErrorOptions:
40
diff --git a/block/io.c b/block/io.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/block/io.c
43
+++ b/block/io.c
44
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
45
goto err;
46
}
47
48
+ bdrv_debug_event(bs, BLKDBG_COR_WRITE);
49
if (drv->bdrv_co_pwrite_zeroes &&
50
buffer_is_zero(bounce_buffer, iov.iov_len)) {
51
/* FIXME: Should we (perhaps conditionally) be setting
52
--
53
2.13.6
54
55
diff view generated by jsdifflib
Deleted patch
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
1
3
Using 16KB bounce buffers creates a significant performance
4
penalty for I/O to encrypted volumes on storage which high
5
I/O latency (rotating rust & network drives), because it
6
triggers lots of fairly small I/O operations.
7
8
On tests with rotating rust, and cache=none|directsync,
9
write speed increased from 2MiB/s to 32MiB/s, on a par
10
with that achieved by the in-kernel luks driver. With
11
other cache modes the in-kernel driver is still notably
12
faster because it is able to report completion of the
13
I/O request before any encryption is done, while the
14
in-QEMU driver must encrypt the data before completion.
15
16
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
17
Message-id: 20170927125340.12360-2-berrange@redhat.com
18
Reviewed-by: Eric Blake <eblake@redhat.com>
19
Reviewed-by: Max Reitz <mreitz@redhat.com>
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
---
22
block/crypto.c | 28 +++++++++++++++-------------
23
1 file changed, 15 insertions(+), 13 deletions(-)
24
25
diff --git a/block/crypto.c b/block/crypto.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/block/crypto.c
28
+++ b/block/crypto.c
29
@@ -XXX,XX +XXX,XX @@ static void block_crypto_close(BlockDriverState *bs)
30
}
31
32
33
-#define BLOCK_CRYPTO_MAX_SECTORS 32
34
+/*
35
+ * 1 MB bounce buffer gives good performance / memory tradeoff
36
+ * when using cache=none|directsync.
37
+ */
38
+#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
39
40
static coroutine_fn int
41
block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
42
@@ -XXX,XX +XXX,XX @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
43
44
qemu_iovec_init(&hd_qiov, qiov->niov);
45
46
- /* Bounce buffer so we have a linear mem region for
47
- * entire sector. XXX optimize so we avoid bounce
48
- * buffer in case that qiov->niov == 1
49
+ /* Bounce buffer because we don't wish to expose cipher text
50
+ * in qiov which points to guest memory.
51
*/
52
cipher_data =
53
- qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * 512,
54
+ qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
55
qiov->size));
56
if (cipher_data == NULL) {
57
ret = -ENOMEM;
58
@@ -XXX,XX +XXX,XX @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
59
while (remaining_sectors) {
60
cur_nr_sectors = remaining_sectors;
61
62
- if (cur_nr_sectors > BLOCK_CRYPTO_MAX_SECTORS) {
63
- cur_nr_sectors = BLOCK_CRYPTO_MAX_SECTORS;
64
+ if (cur_nr_sectors > (BLOCK_CRYPTO_MAX_IO_SIZE / 512)) {
65
+ cur_nr_sectors = (BLOCK_CRYPTO_MAX_IO_SIZE / 512);
66
}
67
68
qemu_iovec_reset(&hd_qiov);
69
@@ -XXX,XX +XXX,XX @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
70
71
qemu_iovec_init(&hd_qiov, qiov->niov);
72
73
- /* Bounce buffer so we have a linear mem region for
74
- * entire sector. XXX optimize so we avoid bounce
75
- * buffer in case that qiov->niov == 1
76
+ /* Bounce buffer because we're not permitted to touch
77
+ * contents of qiov - it points to guest memory.
78
*/
79
cipher_data =
80
- qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * 512,
81
+ qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
82
qiov->size));
83
if (cipher_data == NULL) {
84
ret = -ENOMEM;
85
@@ -XXX,XX +XXX,XX @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
86
while (remaining_sectors) {
87
cur_nr_sectors = remaining_sectors;
88
89
- if (cur_nr_sectors > BLOCK_CRYPTO_MAX_SECTORS) {
90
- cur_nr_sectors = BLOCK_CRYPTO_MAX_SECTORS;
91
+ if (cur_nr_sectors > (BLOCK_CRYPTO_MAX_IO_SIZE / 512)) {
92
+ cur_nr_sectors = (BLOCK_CRYPTO_MAX_IO_SIZE / 512);
93
}
94
95
qemu_iovec_to_buf(qiov, bytes_done,
96
--
97
2.13.6
98
99
diff view generated by jsdifflib
Deleted patch
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
1
3
The crypto APIs report the offset of the data payload as an uint64_t
4
type, but the block driver is casting to size_t or ssize_t which will
5
potentially truncate.
6
7
Most of the block APIs use int64_t for offsets meanwhile, so even if
8
using uint64_t in the crypto block driver we are still at risk of
9
truncation.
10
11
Change the block crypto driver to use uint64_t, but add asserts that
12
the value is less than INT64_MAX.
13
14
Reviewed-by: Max Reitz <mreitz@redhat.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
17
Message-id: 20170927125340.12360-4-berrange@redhat.com
18
Signed-off-by: Max Reitz <mreitz@redhat.com>
19
---
20
block/crypto.c | 13 +++++++++----
21
1 file changed, 9 insertions(+), 4 deletions(-)
22
23
diff --git a/block/crypto.c b/block/crypto.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block/crypto.c
26
+++ b/block/crypto.c
27
@@ -XXX,XX +XXX,XX @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
28
PreallocMode prealloc, Error **errp)
29
{
30
BlockCrypto *crypto = bs->opaque;
31
- size_t payload_offset =
32
+ uint64_t payload_offset =
33
qcrypto_block_get_payload_offset(crypto->block);
34
+ assert(payload_offset < (INT64_MAX - offset));
35
36
offset += payload_offset;
37
38
@@ -XXX,XX +XXX,XX @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
39
uint8_t *cipher_data = NULL;
40
QEMUIOVector hd_qiov;
41
int ret = 0;
42
- size_t payload_offset =
43
+ uint64_t payload_offset =
44
qcrypto_block_get_payload_offset(crypto->block) / 512;
45
+ assert(payload_offset < (INT64_MAX / 512));
46
47
qemu_iovec_init(&hd_qiov, qiov->niov);
48
49
@@ -XXX,XX +XXX,XX @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
50
uint8_t *cipher_data = NULL;
51
QEMUIOVector hd_qiov;
52
int ret = 0;
53
- size_t payload_offset =
54
+ uint64_t payload_offset =
55
qcrypto_block_get_payload_offset(crypto->block) / 512;
56
+ assert(payload_offset < (INT64_MAX / 512));
57
58
qemu_iovec_init(&hd_qiov, qiov->niov);
59
60
@@ -XXX,XX +XXX,XX @@ static int64_t block_crypto_getlength(BlockDriverState *bs)
61
BlockCrypto *crypto = bs->opaque;
62
int64_t len = bdrv_getlength(bs->file->bs);
63
64
- ssize_t offset = qcrypto_block_get_payload_offset(crypto->block);
65
+ uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
66
+ assert(offset < INT64_MAX);
67
+ assert(offset < len);
68
69
len -= offset;
70
71
--
72
2.13.6
73
74
diff view generated by jsdifflib
Deleted patch
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
1
3
The BDRV_REQ_FUA flag can trivially be allowed in the crypt driver
4
as a passthrough to the underlying block driver.
5
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
9
Message-id: 20170927125340.12360-7-berrange@redhat.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
block/crypto.c | 7 +++++--
13
1 file changed, 5 insertions(+), 2 deletions(-)
14
15
diff --git a/block/crypto.c b/block/crypto.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/crypto.c
18
+++ b/block/crypto.c
19
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
20
return -EINVAL;
21
}
22
23
+ bs->supported_write_flags = BDRV_REQ_FUA &
24
+ bs->file->bs->supported_write_flags;
25
+
26
opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
27
qemu_opts_absorb_qdict(opts, options, &local_err);
28
if (local_err) {
29
@@ -XXX,XX +XXX,XX @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
30
uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
31
uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
32
33
- assert(!flags);
34
+ assert(!(flags & ~BDRV_REQ_FUA));
35
assert(payload_offset < INT64_MAX);
36
assert(QEMU_IS_ALIGNED(offset, sector_size));
37
assert(QEMU_IS_ALIGNED(bytes, sector_size));
38
@@ -XXX,XX +XXX,XX @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
39
qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
40
41
ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
42
- cur_bytes, &hd_qiov, 0);
43
+ cur_bytes, &hd_qiov, flags);
44
if (ret < 0) {
45
goto cleanup;
46
}
47
--
48
2.13.6
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Backing may be zero after failed bdrv_attach_child in
4
bdrv_set_backing_hd, which leads to SIGSEGV.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-id: 20170928120300.58164-1-vsementsov@virtuozzo.com
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
block/mirror.c | 5 +++++
12
1 file changed, 5 insertions(+)
13
14
diff --git a/block/mirror.c b/block/mirror.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/mirror.c
17
+++ b/block/mirror.c
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs,
19
20
static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs, QDict *opts)
21
{
22
+ if (bs->backing == NULL) {
23
+ /* we can be here after failed bdrv_attach_child in
24
+ * bdrv_set_backing_hd */
25
+ return;
26
+ }
27
bdrv_refresh_filename(bs->backing->bs);
28
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
29
bs->backing->bs->filename);
30
--
31
2.13.6
32
33
diff view generated by jsdifflib
Deleted patch
1
From: Max Reitz <mreitz@redhat.com>
2
1
3
do_run_qemu() in iotest 195 first applies _filter_imgfmt when printing
4
qemu's command line and _filter_testdir only afterwards. Therefore, if
5
the image format is part of the test directory path, _filter_testdir
6
will no longer apply and the actual output will differ from the
7
reference output even in case of success.
8
9
For example, TEST_DIR might be "/tmp/test-qcow2", in which case
10
_filter_imgfmt first transforms this to "/tmp/test-IMGFMT" which is no
11
longer recognized as the TEST_DIR by _filter_testdir.
12
13
Fix this by not applying _filter_imgfmt in do_run_qemu() but in
14
run_qemu() instead, and only after _filter_testdir.
15
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
17
Message-id: 20170927211334.3988-1-mreitz@redhat.com
18
Reviewed-by: Eric Blake <eblake@redhat.com>
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
20
---
21
tests/qemu-iotests/195 | 7 ++++---
22
1 file changed, 4 insertions(+), 3 deletions(-)
23
24
diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195
25
index XXXXXXX..XXXXXXX 100755
26
--- a/tests/qemu-iotests/195
27
+++ b/tests/qemu-iotests/195
28
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
29
30
function do_run_qemu()
31
{
32
- echo Testing: "$@" | _filter_imgfmt
33
+ echo Testing: "$@"
34
$QEMU -nographic -qmp-pretty stdio -serial none "$@"
35
echo
36
}
37
38
function run_qemu()
39
{
40
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp \
41
- | _filter_qemu_io | _filter_generated_node_ids
42
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_imgfmt | _filter_qemu \
43
+ | _filter_qmp | _filter_qemu_io \
44
+ | _filter_generated_node_ids
45
}
46
47
size=64M
48
--
49
2.13.6
50
51
diff view generated by jsdifflib
Deleted patch
1
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
2
1
3
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Reviewed-by: John Snow <jsnow@redhat.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20170929121613.25997-2-pbutsykin@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/qcow2.c | 4 ++--
11
1 file changed, 2 insertions(+), 2 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 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
18
if (old_file_size < 0) {
19
error_setg_errno(errp, -old_file_size,
20
"Failed to inquire current file length");
21
- return ret;
22
+ return old_file_size;
23
}
24
25
nb_new_data_clusters = DIV_ROUND_UP(offset - old_length,
26
@@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
27
if (allocation_start < 0) {
28
error_setg_errno(errp, -allocation_start,
29
"Failed to resize refcount structures");
30
- return -allocation_start;
31
+ return allocation_start;
32
}
33
34
clusters_allocated = qcow2_alloc_clusters_at(bs, allocation_start,
35
--
36
2.13.6
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Backing may be zero after failed bdrv_append in mirror_start_job,
4
which leads to SIGSEGV.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-id: 20170929152255.5431-1-vsementsov@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/mirror.c | 4 ++++
11
1 file changed, 4 insertions(+)
12
13
diff --git a/block/mirror.c b/block/mirror.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/mirror.c
16
+++ b/block/mirror.c
17
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
18
19
static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
20
{
21
+ if (bs->backing == NULL) {
22
+ /* we can be here after failed bdrv_append in mirror_start_job */
23
+ return 0;
24
+ }
25
return bdrv_co_flush(bs->backing->bs);
26
}
27
28
--
29
2.13.6
30
31
diff view generated by jsdifflib