1
The following changes since commit b2f7a038bb4c4fc5ce6b8486e8513dfd97665e2a:
1
The following changes since commit a26a98dfb9d448d7234d931ae3720feddf6f0651:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-softfloat-20181104' into staging (2018-11-05 10:32:49 +0000)
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20171006' into staging (2017-10-06 13:19:03 +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 1240ac558d348f6c7a5752b1a57c1da58e4efe3e:
9
for you to fetch changes up to fc3fd63fc0573ffd2ee569591a2e7f6c7310fd18:
10
10
11
include: Add a comment to explain the origin of sizes' lookup table (2018-11-05 15:29:59 +0100)
11
Merge remote-tracking branch 'mreitz/tags/pull-block-2017-10-06' into queue-block (2017-10-06 16:32:08 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
16
- auto-read-only option to fix commit job when used with -blockdev
17
- Fix help text related qemu-iotests failure (by improving the help text
18
and updating the reference output)
19
- quorum: Add missing checks when adding/removing child nodes
20
- Don't take address of fields in packed structs
21
- vvfat: Fix crash when reporting error about too many files in directory
22
15
23
----------------------------------------------------------------
16
----------------------------------------------------------------
24
Alberto Garcia (7):
17
Daniel P. Berrange (6):
25
block: replace "discard" literal with BDRV_OPT_DISCARD macro
18
block: use 1 MB bounce buffers for crypto instead of 16KB
26
qcow2: Get the request alignment for encrypted images from QCryptoBlock
19
crypto: expose encryption sector size in APIs
27
quorum: Remove quorum_err()
20
block: fix data type casting for crypto payload offset
28
quorum: Return an error if the blkverify mode has invalid settings
21
block: convert crypto driver to bdrv_co_preadv|pwritev
29
iotest: Test the blkverify mode of the Quorum driver
22
block: convert qcrypto_block_encrypt|decrypt to take bytes offset
30
quorum: Forbid adding children in blkverify mode
23
block: support passthrough of BDRV_REQ_FUA in crypto driver
31
iotest: Test x-blockdev-change on a Quorum
32
24
33
Cleber Rosa (1):
25
Eric Blake (27):
34
iotests: make 083 specific to raw
26
block: Typo fix in copy_on_readv()
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
35
53
36
Daniel P. Berrangé (1):
54
Kevin Wolf (6):
37
crypto: initialize sector size even when opening with no IO flag
55
block: Introduce BdrvChildRole.update_filename
56
commit: Support multiple roots above top node
57
qemu-iotests: Allow QMP pretty printing in common.qemu
58
qemu-iotests: Test commit block job where top has two parents
59
commit: Remove overlay_bs
60
Merge remote-tracking branch 'mreitz/tags/pull-block-2017-10-06' into queue-block
38
61
39
Kevin Wolf (12):
62
Max Reitz (1):
40
vpc: Don't leak opts in vpc_open()
63
iotests: Fix 195 if IMGFMT is part of TEST_DIR
41
block: Update flags in bdrv_set_read_only()
42
block: Add auto-read-only option
43
rbd: Close image in qemu_rbd_open() error path
44
block: Require auto-read-only for existing fallbacks
45
nbd: Support auto-read-only option
46
file-posix: Support auto-read-only option
47
curl: Support auto-read-only option
48
gluster: Support auto-read-only option
49
iscsi: Support auto-read-only option
50
block: Make auto-read-only=on default for -drive
51
qemu-iotests: Test auto-read-only with -drive and -blockdev
52
64
53
Leonid Bloch (2):
65
Paolo Bonzini (10):
54
vdi: Use a literal number of bytes for DEFAULT_CLUSTER_SIZE
66
qemu-iotests: remove dead code
55
include: Add a comment to explain the origin of sizes' lookup table
67
qemu-iotests: get rid of AWK_PROG
68
qemu-iotests: move "check" code out of common.rc
69
qemu-iotests: cleanup and fix search for programs
70
qemu-iotests: limit non-_PROG-suffixed variables to common.rc
71
qemu-iotests: do not include common.rc in "check"
72
qemu-iotests: disintegrate more parts of common.config
73
qemu-iotests: fix uninitialized variable
74
qemu-iotests: get rid of $iam
75
qemu-iotests: merge "check" and "common"
56
76
57
Li Qiang (1):
77
Pavel Butsykin (2):
58
block: change some function return type to bool
78
qcow2: fix return error code in qcow2_truncate()
59
79
qcow2: truncate the tail of the image file after shrinking the image
60
Max Reitz (5):
61
option: Make option help nicer to read
62
chardev: Indent list of chardevs
63
qdev-monitor: Make device options help nicer
64
object: Make option help nicer to read
65
fw_cfg: Drop newline in @file description
66
67
Peter Maydell (5):
68
block/qcow2: Don't take address of fields in packed structs
69
block/qcow: Don't take address of fields in packed structs
70
block/qcow2-bitmap: Don't take address of fields in packed structs
71
block/vhdx: Don't take address of fields in packed structs
72
block/vdi: Don't take address of fields in packed structs
73
74
Stefan Weil (1):
75
qemu-io-cmds: Fix two format strings
76
80
77
Thomas Huth (1):
81
Thomas Huth (1):
78
block/vvfat: Fix crash when reporting error about too many files in directory
82
hw/block/onenand: Remove dead code block
79
83
80
qapi/block-core.json | 7 +
84
Vladimir Sementsov-Ogievskiy (2):
81
block/vhdx.h | 12 +-
85
block/mirror: check backing in bdrv_mirror_top_refresh_filename
82
include/block/block.h | 5 +-
86
block/mirror: check backing in bdrv_mirror_top_flush
83
include/qemu/option.h | 2 +-
84
include/qemu/units.h | 18 +
85
include/sysemu/block-backend.h | 6 +-
86
block.c | 60 ++-
87
block/block-backend.c | 8 +-
88
block/bochs.c | 17 +-
89
block/cloop.c | 16 +-
90
block/curl.c | 8 +-
91
block/dmg.c | 16 +-
92
block/file-posix.c | 19 +-
93
block/gluster.c | 12 +-
94
block/iscsi.c | 8 +-
95
block/nbd-client.c | 10 +-
96
block/qcow.c | 18 +-
97
block/qcow2-bitmap.c | 24 +-
98
block/qcow2.c | 66 +--
99
block/quorum.c | 45 +-
100
block/rbd.c | 14 +-
101
block/vdi.c | 68 +--
102
block/vhdx-endian.c | 118 ++---
103
block/vhdx-log.c | 4 +-
104
block/vhdx.c | 18 +-
105
block/vpc.c | 2 +
106
block/vvfat.c | 15 +-
107
blockdev.c | 3 +-
108
chardev/char.c | 2 +-
109
crypto/block-qcow.c | 2 +
110
qdev-monitor.c | 13 +-
111
qemu-img.c | 4 +-
112
qemu-io-cmds.c | 4 +-
113
util/qemu-option.c | 32 +-
114
vl.c | 15 +-
115
tests/qemu-iotests/081 | 116 +++++
116
tests/qemu-iotests/081.out | 70 +++
117
tests/qemu-iotests/082.out | 956 ++++++++++++++++++++---------------------
118
tests/qemu-iotests/083 | 2 +-
119
tests/qemu-iotests/232 | 147 +++++++
120
tests/qemu-iotests/232.out | 59 +++
121
tests/qemu-iotests/group | 1 +
122
42 files changed, 1266 insertions(+), 776 deletions(-)
123
create mode 100755 tests/qemu-iotests/232
124
create mode 100644 tests/qemu-iotests/232.out
125
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
1
From: Max Reitz <mreitz@redhat.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
There is no good reason why there should be a newline in this
3
Signed-off-by: Eric Blake <eblake@redhat.com>
4
description, so remove it.
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
5
---
11
vl.c | 2 +-
6
block/io.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
7
1 file changed, 1 insertion(+), 1 deletion(-)
13
8
14
diff --git a/vl.c b/vl.c
9
diff --git a/block/io.c b/block/io.c
15
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
16
--- a/vl.c
11
--- a/block/io.c
17
+++ b/vl.c
12
+++ b/block/io.c
18
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_fw_cfg_opts = {
13
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
19
}, {
14
/* FIXME We cannot require callers to have write permissions when all they
20
.name = "file",
15
* are doing is a read request. If we did things right, write permissions
21
.type = QEMU_OPT_STRING,
16
* would be obtained anyway, but internally by the copy-on-read code. As
22
- .help = "Sets the name of the file from which\n"
17
- * long as it is implemented here rather than in a separat filter driver,
23
+ .help = "Sets the name of the file from which "
18
+ * long as it is implemented here rather than in a separate filter driver,
24
"the fw_cfg blob will be loaded",
19
* the copy-on-read code doesn't have its own BdrvChild, however, for which
25
}, {
20
* it could request permissions. Therefore we have to bypass the permission
26
.name = "string",
21
* system for the moment. */
27
--
22
--
28
2.19.1
23
2.13.6
29
24
30
25
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
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>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
19
---
6
block.c | 6 +++---
20
block.c | 2 +-
7
1 file changed, 3 insertions(+), 3 deletions(-)
21
1 file changed, 1 insertion(+), 1 deletion(-)
8
22
9
diff --git a/block.c b/block.c
23
diff --git a/block.c b/block.c
10
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
11
--- a/block.c
25
--- a/block.c
12
+++ b/block.c
26
+++ b/block.c
13
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
27
@@ -XXX,XX +XXX,XX @@ void bdrv_img_create(const char *filename, const char *fmt,
14
.help = "try to optimize zero writes (off, on, unmap)",
28
15
},
29
/* The size for the image must always be specified, unless we have a backing
16
{
30
* file and we have not been forbidden from opening it. */
17
- .name = "discard",
31
- size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
18
+ .name = BDRV_OPT_DISCARD,
32
+ size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, img_size);
19
.type = QEMU_OPT_STRING,
33
if (backing_file && !(flags & BDRV_O_NO_BACKING)) {
20
.help = "discard operation (ignore/off, unmap/on)",
34
BlockDriverState *bs;
21
},
35
char *full_backing = g_new0(char, PATH_MAX);
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
23
}
24
}
25
26
- discard = qemu_opt_get(opts, "discard");
27
+ discard = qemu_opt_get(opts, BDRV_OPT_DISCARD);
28
if (discard != NULL) {
29
if (bdrv_parse_discard_flags(discard, &bs->open_flags) != 0) {
30
error_setg(errp, "Invalid discard option");
31
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
32
33
update_flags_from_options(&reopen_state->flags, opts);
34
35
- discard = qemu_opt_get_del(opts, "discard");
36
+ discard = qemu_opt_get_del(opts, BDRV_OPT_DISCARD);
37
if (discard != NULL) {
38
if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) {
39
error_setg(errp, "Invalid discard option");
40
--
36
--
41
2.19.1
37
2.13.6
42
38
43
39
diff view generated by jsdifflib
New patch
1
From: Eric Blake <eblake@redhat.com>
1
2
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
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
When subdividing a bitmap serialization, the code in hbitmap.c
4
it might not be actually aligned enough for that pointer type (and
4
enforces that start/count parameters are aligned (except that
5
thus cause a crash on dereference on some host architectures). Newer
5
count can end early at end-of-bitmap). We exposed this required
6
versions of clang warn about this. Avoid the bug by not using the
6
alignment through bdrv_dirty_bitmap_serialization_align(), but
7
"modify in place" byte swapping functions.
7
forgot to actually check that we comply with it.
8
8
9
There are a few places where the in-place swap function is
9
Fortunately, qcow2 is never dividing bitmap serialization smaller
10
used on something other than a packed struct field; we convert
10
than one cluster (which is a minimum of 512 bytes); so we are
11
those anyway, for consistency.
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.
12
14
13
This patch was produced with the following spatch script:
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.
14
20
15
@@
21
Signed-off-by: Eric Blake <eblake@redhat.com>
16
expression E;
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
49
Reviewed-by: John Snow <jsnow@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>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
26
---
52
block/qcow2-bitmap.c | 24 ++++++++++++------------
27
block/qcow2-bitmap.c | 7 +++++--
53
1 file changed, 12 insertions(+), 12 deletions(-)
28
1 file changed, 5 insertions(+), 2 deletions(-)
54
29
55
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
30
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
56
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow2-bitmap.c
32
--- a/block/qcow2-bitmap.c
58
+++ b/block/qcow2-bitmap.c
33
+++ b/block/qcow2-bitmap.c
59
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
34
@@ -XXX,XX +XXX,XX @@ static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
60
size_t i;
35
static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
61
36
const BdrvDirtyBitmap *bitmap)
62
for (i = 0; i < size; ++i) {
37
{
63
- cpu_to_be64s(&bitmap_table[i]);
38
- uint32_t sector_granularity =
64
+ bitmap_table[i] = cpu_to_be64(bitmap_table[i]);
39
+ uint64_t sector_granularity =
65
}
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;
66
}
47
}
67
48
68
@@ -XXX,XX +XXX,XX @@ static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
49
/* load_bitmap_data
69
}
70
71
for (i = 0; i < tb->size; ++i) {
72
- be64_to_cpus(&table[i]);
73
+ table[i] = be64_to_cpu(table[i]);
74
ret = check_table_entry(table[i], s->cluster_size);
75
if (ret < 0) {
76
goto fail;
77
@@ -XXX,XX +XXX,XX @@ fail:
78
79
static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
80
{
81
- be64_to_cpus(&entry->bitmap_table_offset);
82
- be32_to_cpus(&entry->bitmap_table_size);
83
- be32_to_cpus(&entry->flags);
84
- be16_to_cpus(&entry->name_size);
85
- be32_to_cpus(&entry->extra_data_size);
86
+ entry->bitmap_table_offset = be64_to_cpu(entry->bitmap_table_offset);
87
+ entry->bitmap_table_size = be32_to_cpu(entry->bitmap_table_size);
88
+ entry->flags = be32_to_cpu(entry->flags);
89
+ entry->name_size = be16_to_cpu(entry->name_size);
90
+ entry->extra_data_size = be32_to_cpu(entry->extra_data_size);
91
}
92
93
static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
94
{
95
- cpu_to_be64s(&entry->bitmap_table_offset);
96
- cpu_to_be32s(&entry->bitmap_table_size);
97
- cpu_to_be32s(&entry->flags);
98
- cpu_to_be16s(&entry->name_size);
99
- cpu_to_be32s(&entry->extra_data_size);
100
+ entry->bitmap_table_offset = cpu_to_be64(entry->bitmap_table_offset);
101
+ entry->bitmap_table_size = cpu_to_be32(entry->bitmap_table_size);
102
+ entry->flags = cpu_to_be32(entry->flags);
103
+ entry->name_size = cpu_to_be16(entry->name_size);
104
+ entry->extra_data_size = cpu_to_be32(entry->extra_data_size);
105
}
106
107
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
108
--
50
--
109
2.19.1
51
2.13.6
110
52
111
53
diff view generated by jsdifflib
New patch
1
From: Eric Blake <eblake@redhat.com>
1
2
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
1
If read-only=off, but auto-read-only=on is given, just degrade to
1
From: Eric Blake <eblake@redhat.com>
2
read-only.
3
2
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>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
---
28
---
7
block/curl.c | 8 ++++----
29
include/block/dirty-bitmap.h | 2 +-
8
1 file changed, 4 insertions(+), 4 deletions(-)
30
block.c | 16 +++++++++++-----
31
block/dirty-bitmap.c | 6 +++---
32
3 files changed, 15 insertions(+), 9 deletions(-)
9
33
10
diff --git a/block/curl.c b/block/curl.c
34
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
11
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
12
--- a/block/curl.c
36
--- a/include/block/dirty-bitmap.h
13
+++ b/block/curl.c
37
+++ b/include/block/dirty-bitmap.h
14
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
38
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
15
const char *protocol_delimiter;
39
void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num);
16
int ret;
40
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
17
41
int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
18
-
42
-void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
19
- if (flags & BDRV_O_RDWR) {
43
+void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes);
20
- error_setg(errp, "curl block device does not support writes");
44
bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap);
21
- return -EROFS;
45
bool bdrv_has_readonly_bitmaps(BlockDriverState *bs);
22
+ ret = bdrv_apply_auto_read_only(bs, "curl driver does not support writes",
46
bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap);
23
+ errp);
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);
24
+ if (ret < 0) {
60
+ if (ret < 0) {
25
+ return ret;
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;
26
}
68
}
27
69
+ bdrv_dirty_bitmap_truncate(bs, offset);
28
if (!libcurl_initialized) {
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) {
29
--
101
--
30
2.19.1
102
2.13.6
31
103
32
104
diff view generated by jsdifflib
New patch
1
From: Eric Blake <eblake@redhat.com>
1
2
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
New patch
1
From: Eric Blake <eblake@redhat.com>
1
2
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
New patch
1
1
From: Eric Blake <eblake@redhat.com>
2
3
Right now, the dirty-bitmap code exposes the fact that we use
4
a scale of sector granularity in the underlying hbitmap to anything
5
that wants to serialize a dirty bitmap. It's nicer to uniformly
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
15
Signed-off-by: Eric Blake <eblake@redhat.com>
16
Reviewed-by: John Snow <jsnow@redhat.com>
17
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
18
Reviewed-by: Fam Zheng <famz@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
include/block/dirty-bitmap.h | 14 +++++++-------
22
block/dirty-bitmap.c | 37 ++++++++++++++++++++++++-------------
23
block/qcow2-bitmap.c | 22 ++++++++++++++--------
24
3 files changed, 45 insertions(+), 28 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 @@ BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
31
void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
32
33
uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
34
- uint64_t start, uint64_t count);
35
+ uint64_t offset, uint64_t bytes);
36
uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap);
37
void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
38
- uint8_t *buf, uint64_t start,
39
- uint64_t count);
40
+ uint8_t *buf, uint64_t offset,
41
+ uint64_t bytes);
42
void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
43
- uint8_t *buf, uint64_t start,
44
- uint64_t count, bool finish);
45
+ uint8_t *buf, uint64_t offset,
46
+ uint64_t bytes, bool finish);
47
void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
48
- uint64_t start, uint64_t count,
49
+ uint64_t offset, uint64_t bytes,
50
bool finish);
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
59
--- a/block/dirty-bitmap.c
60
+++ b/block/dirty-bitmap.c
61
@@ -XXX,XX +XXX,XX @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
62
}
63
64
uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
65
- uint64_t start, uint64_t count)
66
+ uint64_t offset, uint64_t bytes)
67
{
68
- return hbitmap_serialization_size(bitmap->bitmap, start, count);
69
+ assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
70
+ return hbitmap_serialization_size(bitmap->bitmap,
71
+ offset >> BDRV_SECTOR_BITS,
72
+ bytes >> BDRV_SECTOR_BITS);
73
}
74
75
uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
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
--
204
2.13.6
205
206
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
This adds some whitespace into the option help (including indentation)
3
We are gradually converting to byte-based interfaces, as they are
4
and puts angle brackets around the type names. Furthermore, the list
4
easier to reason about than sector-based. Change the qcow2 bitmap
5
name is no longer printed as part of every line, but only once in
5
helper function sectors_covered_by_bitmap_cluster(), renaming it
6
advance, and only if the caller did not print a caption already.
6
to bytes_covered_by_bitmap_cluster() in the process.
7
7
8
This patch also restores the description alignment we had before commit
8
Signed-off-by: Eric Blake <eblake@redhat.com>
9
9cbef9d68ee1d8d0, just at 24 instead of 16 characters like we used to.
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
This increase is because now we have the type and two spaces of
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
indentation before the description, and with a usual type name length of
11
Reviewed-by: Fam Zheng <famz@redhat.com>
12
three chracters, this sums up to eight additional characters -- which
13
means that we now need 24 characters to get the same amount of padding
14
for most options. Also, 24 is a third of 80, which makes it kind of a
15
round number in terminal terms.
16
17
Finally, this patch amends the reference output of iotest 082 to match
18
the changes (and thus makes it pass again).
19
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
13
---
24
include/qemu/option.h | 2 +-
14
block/qcow2-bitmap.c | 28 ++++++++++++++--------------
25
qemu-img.c | 4 +-
15
1 file changed, 14 insertions(+), 14 deletions(-)
26
util/qemu-option.c | 32 +-
27
tests/qemu-iotests/082.out | 956 ++++++++++++++++++-------------------
28
4 files changed, 507 insertions(+), 487 deletions(-)
29
16
30
diff --git a/include/qemu/option.h b/include/qemu/option.h
17
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
31
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
32
--- a/include/qemu/option.h
19
--- a/block/qcow2-bitmap.c
33
+++ b/include/qemu/option.h
20
+++ b/block/qcow2-bitmap.c
34
@@ -XXX,XX +XXX,XX @@ typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
21
@@ -XXX,XX +XXX,XX @@ static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
35
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
36
void *opaque, Error **errp);
37
void qemu_opts_print(QemuOpts *opts, const char *sep);
38
-void qemu_opts_print_help(QemuOptsList *list);
39
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
40
void qemu_opts_free(QemuOptsList *list);
41
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
42
43
diff --git a/qemu-img.c b/qemu-img.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/qemu-img.c
46
+++ b/qemu-img.c
47
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
48
}
49
50
printf("Supported options:\n");
51
- qemu_opts_print_help(create_opts);
52
+ qemu_opts_print_help(create_opts, false);
53
qemu_opts_free(create_opts);
54
return 0;
22
return 0;
55
}
23
}
56
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
24
57
assert(drv->create_opts);
25
-/* This function returns the number of disk sectors covered by a single qcow2
58
26
- * cluster of bitmap data. */
59
printf("Creation options for '%s':\n", format);
27
-static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
60
- qemu_opts_print_help(drv->create_opts);
28
- const BdrvDirtyBitmap *bitmap)
61
+ qemu_opts_print_help(drv->create_opts, false);
29
+/* Return the disk size covered by a single qcow2 cluster of bitmap data. */
62
printf("\nNote that not all of these options may be amendable.\n");
30
+static uint64_t bytes_covered_by_bitmap_cluster(const BDRVQcow2State *s,
63
return 0;
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;
64
}
44
}
65
diff --git a/util/qemu-option.c b/util/qemu-option.c
45
66
index XXXXXXX..XXXXXXX 100644
46
/* load_bitmap_data
67
--- a/util/qemu-option.c
47
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
68
+++ b/util/qemu-option.c
69
@@ -XXX,XX +XXX,XX @@ static const char *opt_type_to_string(enum QemuOptType type)
70
g_assert_not_reached();
71
}
72
73
-void qemu_opts_print_help(QemuOptsList *list)
74
+/**
75
+ * Print the list of options available in the given list. If
76
+ * @print_caption is true, a caption (including the list name, if it
77
+ * exists) is printed. The options itself will be indented, so
78
+ * @print_caption should only be set to false if the caller prints its
79
+ * own custom caption (so that the indentation makes sense).
80
+ */
81
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption)
82
{
48
{
83
QemuOptDesc *desc;
49
int ret = 0;
84
int i;
50
BDRVQcow2State *s = bs->opaque;
85
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
51
- uint64_t sector, sbc;
86
desc = list->desc;
52
+ uint64_t sector, limit, sbc;
87
while (desc && desc->name) {
53
uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
88
GString *str = g_string_new(NULL);
54
uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
89
- if (list->name) {
55
uint8_t *buf = NULL;
90
- g_string_append_printf(str, "%s.", list->name);
56
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
91
- }
92
- g_string_append_printf(str, "%s=%s", desc->name,
93
+ g_string_append_printf(str, " %s=<%s>", desc->name,
94
opt_type_to_string(desc->type));
95
if (desc->help) {
96
+ if (str->len < 24) {
97
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
98
+ }
99
g_string_append_printf(str, " - %s", desc->help);
100
}
101
g_ptr_array_add(array, g_string_free(str, false));
102
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
103
}
57
}
104
58
105
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
59
buf = g_malloc(s->cluster_size);
106
+ if (print_caption && array->len > 0) {
60
- sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
107
+ if (list->name) {
61
+ limit = bytes_covered_by_bitmap_cluster(s, bitmap);
108
+ printf("%s options:\n", list->name);
62
+ sbc = limit >> BDRV_SECTOR_BITS;
109
+ } else {
63
for (i = 0, sector = 0; i < tab_size; ++i, sector += sbc) {
110
+ printf("Options:\n");
64
uint64_t count = MIN(bm_sectors - sector, sbc);
111
+ }
65
uint64_t entry = bitmap_table[i];
112
+ } else if (array->len == 0) {
66
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
113
+ if (list->name) {
67
int ret;
114
+ printf("There are no options for %s.\n", list->name);
68
BDRVQcow2State *s = bs->opaque;
115
+ } else {
69
int64_t sector;
116
+ printf("No options available.\n");
70
- uint64_t sbc;
117
+ }
71
+ uint64_t limit, sbc;
118
+ }
72
uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
119
for (i = 0; i < array->len; i++) {
73
uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
120
printf("%s\n", (char *)array->pdata[i]);
74
const char *bm_name = bdrv_dirty_bitmap_name(bitmap);
121
}
75
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
122
@@ -XXX,XX +XXX,XX @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
76
123
opts = opts_parse(list, params, permit_abbrev, false, &invalidp, &err);
77
dbi = bdrv_dirty_iter_new(bitmap, 0);
124
if (err) {
78
buf = g_malloc(s->cluster_size);
125
if (invalidp && has_help_option(params)) {
79
- sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
126
- qemu_opts_print_help(list);
80
- assert(DIV_ROUND_UP(bm_sectors, sbc) == tb_size);
127
+ qemu_opts_print_help(list, true);
81
+ limit = bytes_covered_by_bitmap_cluster(s, bitmap);
128
error_free(err);
82
+ sbc = limit >> BDRV_SECTOR_BITS;
129
} else {
83
+ assert(DIV_ROUND_UP(bm_size, limit) == tb_size);
130
error_report_err(err);
84
131
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
85
while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
132
index XXXXXXX..XXXXXXX 100644
86
uint64_t cluster = sector / sbc;
133
--- a/tests/qemu-iotests/082.out
134
+++ b/tests/qemu-iotests/082.out
135
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
136
137
Testing: create -f qcow2 -o help TEST_DIR/t.qcow2 128M
138
Supported options:
139
-size Virtual disk size
140
-compat Compatibility level (0.10 or 1.1)
141
-backing_file File name of a base image
142
-backing_fmt Image format of the base image
143
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
144
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
145
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
146
-encrypt.cipher-alg Name of encryption cipher algorithm
147
-encrypt.cipher-mode Name of encryption cipher mode
148
-encrypt.ivgen-alg Name of IV generator algorithm
149
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
150
-encrypt.hash-alg Name of encryption hash algorithm
151
-encrypt.iter-time Time to spend in PBKDF in milliseconds
152
-cluster_size qcow2 cluster size
153
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
154
-lazy_refcounts Postpone refcount updates
155
-refcount_bits Width of a reference count entry in bits
156
-nocow Turn off copy-on-write (valid only on btrfs)
157
+ backing_file=<str> - File name of a base image
158
+ backing_fmt=<str> - Image format of the base image
159
+ cluster_size=<size> - qcow2 cluster size
160
+ compat=<str> - Compatibility level (0.10 or 1.1)
161
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
162
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
163
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
164
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
165
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
166
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
167
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
168
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
169
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
170
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
171
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
172
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
173
+ refcount_bits=<num> - Width of a reference count entry in bits
174
+ size=<size> - Virtual disk size
175
176
Testing: create -f qcow2 -o ? TEST_DIR/t.qcow2 128M
177
Supported options:
178
-size Virtual disk size
179
-compat Compatibility level (0.10 or 1.1)
180
-backing_file File name of a base image
181
-backing_fmt Image format of the base image
182
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
183
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
184
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
185
-encrypt.cipher-alg Name of encryption cipher algorithm
186
-encrypt.cipher-mode Name of encryption cipher mode
187
-encrypt.ivgen-alg Name of IV generator algorithm
188
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
189
-encrypt.hash-alg Name of encryption hash algorithm
190
-encrypt.iter-time Time to spend in PBKDF in milliseconds
191
-cluster_size qcow2 cluster size
192
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
193
-lazy_refcounts Postpone refcount updates
194
-refcount_bits Width of a reference count entry in bits
195
-nocow Turn off copy-on-write (valid only on btrfs)
196
+ backing_file=<str> - File name of a base image
197
+ backing_fmt=<str> - Image format of the base image
198
+ cluster_size=<size> - qcow2 cluster size
199
+ compat=<str> - Compatibility level (0.10 or 1.1)
200
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
201
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
202
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
203
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
204
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
205
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
206
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
207
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
208
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
209
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
210
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
211
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
212
+ refcount_bits=<num> - Width of a reference count entry in bits
213
+ size=<size> - Virtual disk size
214
215
Testing: create -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 128M
216
Supported options:
217
-size Virtual disk size
218
-compat Compatibility level (0.10 or 1.1)
219
-backing_file File name of a base image
220
-backing_fmt Image format of the base image
221
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
222
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
223
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
224
-encrypt.cipher-alg Name of encryption cipher algorithm
225
-encrypt.cipher-mode Name of encryption cipher mode
226
-encrypt.ivgen-alg Name of IV generator algorithm
227
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
228
-encrypt.hash-alg Name of encryption hash algorithm
229
-encrypt.iter-time Time to spend in PBKDF in milliseconds
230
-cluster_size qcow2 cluster size
231
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
232
-lazy_refcounts Postpone refcount updates
233
-refcount_bits Width of a reference count entry in bits
234
-nocow Turn off copy-on-write (valid only on btrfs)
235
+ backing_file=<str> - File name of a base image
236
+ backing_fmt=<str> - Image format of the base image
237
+ cluster_size=<size> - qcow2 cluster size
238
+ compat=<str> - Compatibility level (0.10 or 1.1)
239
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
240
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
241
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
242
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
243
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
244
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
245
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
246
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
247
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
248
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
249
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
250
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
251
+ refcount_bits=<num> - Width of a reference count entry in bits
252
+ size=<size> - Virtual disk size
253
254
Testing: create -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 128M
255
Supported options:
256
-size Virtual disk size
257
-compat Compatibility level (0.10 or 1.1)
258
-backing_file File name of a base image
259
-backing_fmt Image format of the base image
260
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
261
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
262
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
263
-encrypt.cipher-alg Name of encryption cipher algorithm
264
-encrypt.cipher-mode Name of encryption cipher mode
265
-encrypt.ivgen-alg Name of IV generator algorithm
266
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
267
-encrypt.hash-alg Name of encryption hash algorithm
268
-encrypt.iter-time Time to spend in PBKDF in milliseconds
269
-cluster_size qcow2 cluster size
270
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
271
-lazy_refcounts Postpone refcount updates
272
-refcount_bits Width of a reference count entry in bits
273
-nocow Turn off copy-on-write (valid only on btrfs)
274
+ backing_file=<str> - File name of a base image
275
+ backing_fmt=<str> - Image format of the base image
276
+ cluster_size=<size> - qcow2 cluster size
277
+ compat=<str> - Compatibility level (0.10 or 1.1)
278
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
279
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
280
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
281
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
282
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
283
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
284
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
285
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
286
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
287
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
288
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
289
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
290
+ refcount_bits=<num> - Width of a reference count entry in bits
291
+ size=<size> - Virtual disk size
292
293
Testing: create -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 128M
294
Supported options:
295
-size Virtual disk size
296
-compat Compatibility level (0.10 or 1.1)
297
-backing_file File name of a base image
298
-backing_fmt Image format of the base image
299
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
300
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
301
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
302
-encrypt.cipher-alg Name of encryption cipher algorithm
303
-encrypt.cipher-mode Name of encryption cipher mode
304
-encrypt.ivgen-alg Name of IV generator algorithm
305
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
306
-encrypt.hash-alg Name of encryption hash algorithm
307
-encrypt.iter-time Time to spend in PBKDF in milliseconds
308
-cluster_size qcow2 cluster size
309
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
310
-lazy_refcounts Postpone refcount updates
311
-refcount_bits Width of a reference count entry in bits
312
-nocow Turn off copy-on-write (valid only on btrfs)
313
+ backing_file=<str> - File name of a base image
314
+ backing_fmt=<str> - Image format of the base image
315
+ cluster_size=<size> - qcow2 cluster size
316
+ compat=<str> - Compatibility level (0.10 or 1.1)
317
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
318
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
319
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
320
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
321
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
322
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
323
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
324
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
325
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
326
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
327
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
328
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
329
+ refcount_bits=<num> - Width of a reference count entry in bits
330
+ size=<size> - Virtual disk size
331
332
Testing: create -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 128M
333
Supported options:
334
-size Virtual disk size
335
-compat Compatibility level (0.10 or 1.1)
336
-backing_file File name of a base image
337
-backing_fmt Image format of the base image
338
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
339
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
340
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
341
-encrypt.cipher-alg Name of encryption cipher algorithm
342
-encrypt.cipher-mode Name of encryption cipher mode
343
-encrypt.ivgen-alg Name of IV generator algorithm
344
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
345
-encrypt.hash-alg Name of encryption hash algorithm
346
-encrypt.iter-time Time to spend in PBKDF in milliseconds
347
-cluster_size qcow2 cluster size
348
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
349
-lazy_refcounts Postpone refcount updates
350
-refcount_bits Width of a reference count entry in bits
351
-nocow Turn off copy-on-write (valid only on btrfs)
352
+ backing_file=<str> - File name of a base image
353
+ backing_fmt=<str> - Image format of the base image
354
+ cluster_size=<size> - qcow2 cluster size
355
+ compat=<str> - Compatibility level (0.10 or 1.1)
356
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
357
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
358
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
359
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
360
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
361
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
362
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
363
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
364
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
365
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
366
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
367
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
368
+ refcount_bits=<num> - Width of a reference count entry in bits
369
+ size=<size> - Virtual disk size
370
371
Testing: create -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 128M
372
Supported options:
373
-size Virtual disk size
374
-compat Compatibility level (0.10 or 1.1)
375
-backing_file File name of a base image
376
-backing_fmt Image format of the base image
377
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
378
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
379
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
380
-encrypt.cipher-alg Name of encryption cipher algorithm
381
-encrypt.cipher-mode Name of encryption cipher mode
382
-encrypt.ivgen-alg Name of IV generator algorithm
383
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
384
-encrypt.hash-alg Name of encryption hash algorithm
385
-encrypt.iter-time Time to spend in PBKDF in milliseconds
386
-cluster_size qcow2 cluster size
387
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
388
-lazy_refcounts Postpone refcount updates
389
-refcount_bits Width of a reference count entry in bits
390
-nocow Turn off copy-on-write (valid only on btrfs)
391
+ backing_file=<str> - File name of a base image
392
+ backing_fmt=<str> - Image format of the base image
393
+ cluster_size=<size> - qcow2 cluster size
394
+ compat=<str> - Compatibility level (0.10 or 1.1)
395
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
396
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
397
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
398
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
399
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
400
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
401
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
402
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
403
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
404
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
405
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
406
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
407
+ refcount_bits=<num> - Width of a reference count entry in bits
408
+ size=<size> - Virtual disk size
409
410
Testing: create -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 128M
411
Supported options:
412
-size Virtual disk size
413
-compat Compatibility level (0.10 or 1.1)
414
-backing_file File name of a base image
415
-backing_fmt Image format of the base image
416
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
417
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
418
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
419
-encrypt.cipher-alg Name of encryption cipher algorithm
420
-encrypt.cipher-mode Name of encryption cipher mode
421
-encrypt.ivgen-alg Name of IV generator algorithm
422
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
423
-encrypt.hash-alg Name of encryption hash algorithm
424
-encrypt.iter-time Time to spend in PBKDF in milliseconds
425
-cluster_size qcow2 cluster size
426
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
427
-lazy_refcounts Postpone refcount updates
428
-refcount_bits Width of a reference count entry in bits
429
-nocow Turn off copy-on-write (valid only on btrfs)
430
+ backing_file=<str> - File name of a base image
431
+ backing_fmt=<str> - Image format of the base image
432
+ cluster_size=<size> - qcow2 cluster size
433
+ compat=<str> - Compatibility level (0.10 or 1.1)
434
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
435
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
436
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
437
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
438
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
439
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
440
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
441
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
442
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
443
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
444
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
445
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
446
+ refcount_bits=<num> - Width of a reference count entry in bits
447
+ size=<size> - Virtual disk size
448
449
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
450
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16
451
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
452
453
Testing: create -f qcow2 -o help
454
Supported options:
455
-size Virtual disk size
456
-compat Compatibility level (0.10 or 1.1)
457
-backing_file File name of a base image
458
-backing_fmt Image format of the base image
459
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
460
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
461
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
462
-encrypt.cipher-alg Name of encryption cipher algorithm
463
-encrypt.cipher-mode Name of encryption cipher mode
464
-encrypt.ivgen-alg Name of IV generator algorithm
465
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
466
-encrypt.hash-alg Name of encryption hash algorithm
467
-encrypt.iter-time Time to spend in PBKDF in milliseconds
468
-cluster_size qcow2 cluster size
469
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
470
-lazy_refcounts Postpone refcount updates
471
-refcount_bits Width of a reference count entry in bits
472
+ backing_file=<str> - File name of a base image
473
+ backing_fmt=<str> - Image format of the base image
474
+ cluster_size=<size> - qcow2 cluster size
475
+ compat=<str> - Compatibility level (0.10 or 1.1)
476
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
477
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
478
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
479
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
480
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
481
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
482
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
483
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
484
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
485
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
486
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
487
+ refcount_bits=<num> - Width of a reference count entry in bits
488
+ size=<size> - Virtual disk size
489
490
Testing: create -o help
491
Supported options:
492
-size Virtual disk size
493
+ size=<size> - Virtual disk size
494
495
Testing: create -f bochs -o help
496
qemu-img: Format driver 'bochs' does not support image creation
497
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
498
499
Testing: convert -O qcow2 -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
500
Supported options:
501
-size Virtual disk size
502
-compat Compatibility level (0.10 or 1.1)
503
-backing_file File name of a base image
504
-backing_fmt Image format of the base image
505
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
506
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
507
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
508
-encrypt.cipher-alg Name of encryption cipher algorithm
509
-encrypt.cipher-mode Name of encryption cipher mode
510
-encrypt.ivgen-alg Name of IV generator algorithm
511
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
512
-encrypt.hash-alg Name of encryption hash algorithm
513
-encrypt.iter-time Time to spend in PBKDF in milliseconds
514
-cluster_size qcow2 cluster size
515
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
516
-lazy_refcounts Postpone refcount updates
517
-refcount_bits Width of a reference count entry in bits
518
-nocow Turn off copy-on-write (valid only on btrfs)
519
+ backing_file=<str> - File name of a base image
520
+ backing_fmt=<str> - Image format of the base image
521
+ cluster_size=<size> - qcow2 cluster size
522
+ compat=<str> - Compatibility level (0.10 or 1.1)
523
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
524
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
525
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
526
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
527
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
528
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
529
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
530
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
531
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
532
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
533
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
534
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
535
+ refcount_bits=<num> - Width of a reference count entry in bits
536
+ size=<size> - Virtual disk size
537
538
Testing: convert -O qcow2 -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
539
Supported options:
540
-size Virtual disk size
541
-compat Compatibility level (0.10 or 1.1)
542
-backing_file File name of a base image
543
-backing_fmt Image format of the base image
544
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
545
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
546
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
547
-encrypt.cipher-alg Name of encryption cipher algorithm
548
-encrypt.cipher-mode Name of encryption cipher mode
549
-encrypt.ivgen-alg Name of IV generator algorithm
550
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
551
-encrypt.hash-alg Name of encryption hash algorithm
552
-encrypt.iter-time Time to spend in PBKDF in milliseconds
553
-cluster_size qcow2 cluster size
554
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
555
-lazy_refcounts Postpone refcount updates
556
-refcount_bits Width of a reference count entry in bits
557
-nocow Turn off copy-on-write (valid only on btrfs)
558
+ backing_file=<str> - File name of a base image
559
+ backing_fmt=<str> - Image format of the base image
560
+ cluster_size=<size> - qcow2 cluster size
561
+ compat=<str> - Compatibility level (0.10 or 1.1)
562
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
563
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
564
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
565
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
566
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
567
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
568
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
569
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
570
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
571
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
572
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
573
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
574
+ refcount_bits=<num> - Width of a reference count entry in bits
575
+ size=<size> - Virtual disk size
576
577
Testing: convert -O qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
578
Supported options:
579
-size Virtual disk size
580
-compat Compatibility level (0.10 or 1.1)
581
-backing_file File name of a base image
582
-backing_fmt Image format of the base image
583
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
584
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
585
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
586
-encrypt.cipher-alg Name of encryption cipher algorithm
587
-encrypt.cipher-mode Name of encryption cipher mode
588
-encrypt.ivgen-alg Name of IV generator algorithm
589
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
590
-encrypt.hash-alg Name of encryption hash algorithm
591
-encrypt.iter-time Time to spend in PBKDF in milliseconds
592
-cluster_size qcow2 cluster size
593
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
594
-lazy_refcounts Postpone refcount updates
595
-refcount_bits Width of a reference count entry in bits
596
-nocow Turn off copy-on-write (valid only on btrfs)
597
+ backing_file=<str> - File name of a base image
598
+ backing_fmt=<str> - Image format of the base image
599
+ cluster_size=<size> - qcow2 cluster size
600
+ compat=<str> - Compatibility level (0.10 or 1.1)
601
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
602
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
603
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
604
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
605
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
606
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
607
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
608
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
609
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
610
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
611
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
612
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
613
+ refcount_bits=<num> - Width of a reference count entry in bits
614
+ size=<size> - Virtual disk size
615
616
Testing: convert -O qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
617
Supported options:
618
-size Virtual disk size
619
-compat Compatibility level (0.10 or 1.1)
620
-backing_file File name of a base image
621
-backing_fmt Image format of the base image
622
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
623
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
624
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
625
-encrypt.cipher-alg Name of encryption cipher algorithm
626
-encrypt.cipher-mode Name of encryption cipher mode
627
-encrypt.ivgen-alg Name of IV generator algorithm
628
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
629
-encrypt.hash-alg Name of encryption hash algorithm
630
-encrypt.iter-time Time to spend in PBKDF in milliseconds
631
-cluster_size qcow2 cluster size
632
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
633
-lazy_refcounts Postpone refcount updates
634
-refcount_bits Width of a reference count entry in bits
635
-nocow Turn off copy-on-write (valid only on btrfs)
636
+ backing_file=<str> - File name of a base image
637
+ backing_fmt=<str> - Image format of the base image
638
+ cluster_size=<size> - qcow2 cluster size
639
+ compat=<str> - Compatibility level (0.10 or 1.1)
640
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
641
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
642
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
643
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
644
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
645
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
646
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
647
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
648
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
649
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
650
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
651
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
652
+ refcount_bits=<num> - Width of a reference count entry in bits
653
+ size=<size> - Virtual disk size
654
655
Testing: convert -O qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
656
Supported options:
657
-size Virtual disk size
658
-compat Compatibility level (0.10 or 1.1)
659
-backing_file File name of a base image
660
-backing_fmt Image format of the base image
661
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
662
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
663
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
664
-encrypt.cipher-alg Name of encryption cipher algorithm
665
-encrypt.cipher-mode Name of encryption cipher mode
666
-encrypt.ivgen-alg Name of IV generator algorithm
667
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
668
-encrypt.hash-alg Name of encryption hash algorithm
669
-encrypt.iter-time Time to spend in PBKDF in milliseconds
670
-cluster_size qcow2 cluster size
671
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
672
-lazy_refcounts Postpone refcount updates
673
-refcount_bits Width of a reference count entry in bits
674
-nocow Turn off copy-on-write (valid only on btrfs)
675
+ backing_file=<str> - File name of a base image
676
+ backing_fmt=<str> - Image format of the base image
677
+ cluster_size=<size> - qcow2 cluster size
678
+ compat=<str> - Compatibility level (0.10 or 1.1)
679
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
680
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
681
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
682
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
683
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
684
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
685
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
686
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
687
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
688
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
689
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
690
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
691
+ refcount_bits=<num> - Width of a reference count entry in bits
692
+ size=<size> - Virtual disk size
693
694
Testing: convert -O qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
695
Supported options:
696
-size Virtual disk size
697
-compat Compatibility level (0.10 or 1.1)
698
-backing_file File name of a base image
699
-backing_fmt Image format of the base image
700
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
701
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
702
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
703
-encrypt.cipher-alg Name of encryption cipher algorithm
704
-encrypt.cipher-mode Name of encryption cipher mode
705
-encrypt.ivgen-alg Name of IV generator algorithm
706
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
707
-encrypt.hash-alg Name of encryption hash algorithm
708
-encrypt.iter-time Time to spend in PBKDF in milliseconds
709
-cluster_size qcow2 cluster size
710
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
711
-lazy_refcounts Postpone refcount updates
712
-refcount_bits Width of a reference count entry in bits
713
-nocow Turn off copy-on-write (valid only on btrfs)
714
+ backing_file=<str> - File name of a base image
715
+ backing_fmt=<str> - Image format of the base image
716
+ cluster_size=<size> - qcow2 cluster size
717
+ compat=<str> - Compatibility level (0.10 or 1.1)
718
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
719
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
720
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
721
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
722
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
723
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
724
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
725
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
726
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
727
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
728
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
729
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
730
+ refcount_bits=<num> - Width of a reference count entry in bits
731
+ size=<size> - Virtual disk size
732
733
Testing: convert -O qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
734
Supported options:
735
-size Virtual disk size
736
-compat Compatibility level (0.10 or 1.1)
737
-backing_file File name of a base image
738
-backing_fmt Image format of the base image
739
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
740
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
741
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
742
-encrypt.cipher-alg Name of encryption cipher algorithm
743
-encrypt.cipher-mode Name of encryption cipher mode
744
-encrypt.ivgen-alg Name of IV generator algorithm
745
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
746
-encrypt.hash-alg Name of encryption hash algorithm
747
-encrypt.iter-time Time to spend in PBKDF in milliseconds
748
-cluster_size qcow2 cluster size
749
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
750
-lazy_refcounts Postpone refcount updates
751
-refcount_bits Width of a reference count entry in bits
752
-nocow Turn off copy-on-write (valid only on btrfs)
753
+ backing_file=<str> - File name of a base image
754
+ backing_fmt=<str> - Image format of the base image
755
+ cluster_size=<size> - qcow2 cluster size
756
+ compat=<str> - Compatibility level (0.10 or 1.1)
757
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
758
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
759
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
760
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
761
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
762
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
763
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
764
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
765
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
766
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
767
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
768
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
769
+ refcount_bits=<num> - Width of a reference count entry in bits
770
+ size=<size> - Virtual disk size
771
772
Testing: convert -O qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
773
Supported options:
774
-size Virtual disk size
775
-compat Compatibility level (0.10 or 1.1)
776
-backing_file File name of a base image
777
-backing_fmt Image format of the base image
778
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
779
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
780
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
781
-encrypt.cipher-alg Name of encryption cipher algorithm
782
-encrypt.cipher-mode Name of encryption cipher mode
783
-encrypt.ivgen-alg Name of IV generator algorithm
784
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
785
-encrypt.hash-alg Name of encryption hash algorithm
786
-encrypt.iter-time Time to spend in PBKDF in milliseconds
787
-cluster_size qcow2 cluster size
788
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
789
-lazy_refcounts Postpone refcount updates
790
-refcount_bits Width of a reference count entry in bits
791
-nocow Turn off copy-on-write (valid only on btrfs)
792
+ backing_file=<str> - File name of a base image
793
+ backing_fmt=<str> - Image format of the base image
794
+ cluster_size=<size> - qcow2 cluster size
795
+ compat=<str> - Compatibility level (0.10 or 1.1)
796
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
797
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
798
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
799
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
800
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
801
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
802
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
803
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
804
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
805
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
806
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
807
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
808
+ refcount_bits=<num> - Width of a reference count entry in bits
809
+ size=<size> - Virtual disk size
810
811
Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
812
qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open backing file: Could not open 'TEST_DIR/t.qcow2,help': No such file or directory
813
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
814
815
Testing: convert -O qcow2 -o help
816
Supported options:
817
-size Virtual disk size
818
-compat Compatibility level (0.10 or 1.1)
819
-backing_file File name of a base image
820
-backing_fmt Image format of the base image
821
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
822
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
823
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
824
-encrypt.cipher-alg Name of encryption cipher algorithm
825
-encrypt.cipher-mode Name of encryption cipher mode
826
-encrypt.ivgen-alg Name of IV generator algorithm
827
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
828
-encrypt.hash-alg Name of encryption hash algorithm
829
-encrypt.iter-time Time to spend in PBKDF in milliseconds
830
-cluster_size qcow2 cluster size
831
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
832
-lazy_refcounts Postpone refcount updates
833
-refcount_bits Width of a reference count entry in bits
834
+ backing_file=<str> - File name of a base image
835
+ backing_fmt=<str> - Image format of the base image
836
+ cluster_size=<size> - qcow2 cluster size
837
+ compat=<str> - Compatibility level (0.10 or 1.1)
838
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
839
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
840
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
841
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
842
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
843
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
844
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
845
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
846
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
847
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
848
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
849
+ refcount_bits=<num> - Width of a reference count entry in bits
850
+ size=<size> - Virtual disk size
851
852
Testing: convert -o help
853
Supported options:
854
-size Virtual disk size
855
+ size=<size> - Virtual disk size
856
857
Testing: convert -O bochs -o help
858
qemu-img: Format driver 'bochs' does not support image creation
859
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
860
861
Testing: amend -f qcow2 -o help TEST_DIR/t.qcow2
862
Creation options for 'qcow2':
863
-size Virtual disk size
864
-compat Compatibility level (0.10 or 1.1)
865
-backing_file File name of a base image
866
-backing_fmt Image format of the base image
867
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
868
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
869
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
870
-encrypt.cipher-alg Name of encryption cipher algorithm
871
-encrypt.cipher-mode Name of encryption cipher mode
872
-encrypt.ivgen-alg Name of IV generator algorithm
873
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
874
-encrypt.hash-alg Name of encryption hash algorithm
875
-encrypt.iter-time Time to spend in PBKDF in milliseconds
876
-cluster_size qcow2 cluster size
877
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
878
-lazy_refcounts Postpone refcount updates
879
-refcount_bits Width of a reference count entry in bits
880
+ backing_file=<str> - File name of a base image
881
+ backing_fmt=<str> - Image format of the base image
882
+ cluster_size=<size> - qcow2 cluster size
883
+ compat=<str> - Compatibility level (0.10 or 1.1)
884
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
885
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
886
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
887
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
888
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
889
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
890
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
891
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
892
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
893
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
894
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
895
+ refcount_bits=<num> - Width of a reference count entry in bits
896
+ size=<size> - Virtual disk size
897
898
Note that not all of these options may be amendable.
899
900
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
901
Creation options for 'qcow2':
902
-size Virtual disk size
903
-compat Compatibility level (0.10 or 1.1)
904
-backing_file File name of a base image
905
-backing_fmt Image format of the base image
906
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
907
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
908
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
909
-encrypt.cipher-alg Name of encryption cipher algorithm
910
-encrypt.cipher-mode Name of encryption cipher mode
911
-encrypt.ivgen-alg Name of IV generator algorithm
912
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
913
-encrypt.hash-alg Name of encryption hash algorithm
914
-encrypt.iter-time Time to spend in PBKDF in milliseconds
915
-cluster_size qcow2 cluster size
916
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
917
-lazy_refcounts Postpone refcount updates
918
-refcount_bits Width of a reference count entry in bits
919
+ backing_file=<str> - File name of a base image
920
+ backing_fmt=<str> - Image format of the base image
921
+ cluster_size=<size> - qcow2 cluster size
922
+ compat=<str> - Compatibility level (0.10 or 1.1)
923
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
924
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
925
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
926
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
927
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
928
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
929
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
930
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
931
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
932
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
933
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
934
+ refcount_bits=<num> - Width of a reference count entry in bits
935
+ size=<size> - Virtual disk size
936
937
Note that not all of these options may be amendable.
938
939
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
940
Creation options for 'qcow2':
941
-size Virtual disk size
942
-compat Compatibility level (0.10 or 1.1)
943
-backing_file File name of a base image
944
-backing_fmt Image format of the base image
945
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
946
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
947
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
948
-encrypt.cipher-alg Name of encryption cipher algorithm
949
-encrypt.cipher-mode Name of encryption cipher mode
950
-encrypt.ivgen-alg Name of IV generator algorithm
951
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
952
-encrypt.hash-alg Name of encryption hash algorithm
953
-encrypt.iter-time Time to spend in PBKDF in milliseconds
954
-cluster_size qcow2 cluster size
955
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
956
-lazy_refcounts Postpone refcount updates
957
-refcount_bits Width of a reference count entry in bits
958
+ backing_file=<str> - File name of a base image
959
+ backing_fmt=<str> - Image format of the base image
960
+ cluster_size=<size> - qcow2 cluster size
961
+ compat=<str> - Compatibility level (0.10 or 1.1)
962
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
963
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
964
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
965
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
966
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
967
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
968
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
969
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
970
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
971
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
972
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
973
+ refcount_bits=<num> - Width of a reference count entry in bits
974
+ size=<size> - Virtual disk size
975
976
Note that not all of these options may be amendable.
977
978
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
979
Creation options for 'qcow2':
980
-size Virtual disk size
981
-compat Compatibility level (0.10 or 1.1)
982
-backing_file File name of a base image
983
-backing_fmt Image format of the base image
984
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
985
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
986
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
987
-encrypt.cipher-alg Name of encryption cipher algorithm
988
-encrypt.cipher-mode Name of encryption cipher mode
989
-encrypt.ivgen-alg Name of IV generator algorithm
990
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
991
-encrypt.hash-alg Name of encryption hash algorithm
992
-encrypt.iter-time Time to spend in PBKDF in milliseconds
993
-cluster_size qcow2 cluster size
994
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
995
-lazy_refcounts Postpone refcount updates
996
-refcount_bits Width of a reference count entry in bits
997
+ backing_file=<str> - File name of a base image
998
+ backing_fmt=<str> - Image format of the base image
999
+ cluster_size=<size> - qcow2 cluster size
1000
+ compat=<str> - Compatibility level (0.10 or 1.1)
1001
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1002
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1003
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1004
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1005
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1006
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1007
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1008
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1009
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1010
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1011
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1012
+ refcount_bits=<num> - Width of a reference count entry in bits
1013
+ size=<size> - Virtual disk size
1014
1015
Note that not all of these options may be amendable.
1016
1017
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
1018
Creation options for 'qcow2':
1019
-size Virtual disk size
1020
-compat Compatibility level (0.10 or 1.1)
1021
-backing_file File name of a base image
1022
-backing_fmt Image format of the base image
1023
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1024
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1025
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1026
-encrypt.cipher-alg Name of encryption cipher algorithm
1027
-encrypt.cipher-mode Name of encryption cipher mode
1028
-encrypt.ivgen-alg Name of IV generator algorithm
1029
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1030
-encrypt.hash-alg Name of encryption hash algorithm
1031
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1032
-cluster_size qcow2 cluster size
1033
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1034
-lazy_refcounts Postpone refcount updates
1035
-refcount_bits Width of a reference count entry in bits
1036
+ backing_file=<str> - File name of a base image
1037
+ backing_fmt=<str> - Image format of the base image
1038
+ cluster_size=<size> - qcow2 cluster size
1039
+ compat=<str> - Compatibility level (0.10 or 1.1)
1040
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1041
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1042
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1043
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1044
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1045
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1046
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1047
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1048
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1049
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1050
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1051
+ refcount_bits=<num> - Width of a reference count entry in bits
1052
+ size=<size> - Virtual disk size
1053
1054
Note that not all of these options may be amendable.
1055
1056
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
1057
Creation options for 'qcow2':
1058
-size Virtual disk size
1059
-compat Compatibility level (0.10 or 1.1)
1060
-backing_file File name of a base image
1061
-backing_fmt Image format of the base image
1062
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1063
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1064
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1065
-encrypt.cipher-alg Name of encryption cipher algorithm
1066
-encrypt.cipher-mode Name of encryption cipher mode
1067
-encrypt.ivgen-alg Name of IV generator algorithm
1068
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1069
-encrypt.hash-alg Name of encryption hash algorithm
1070
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1071
-cluster_size qcow2 cluster size
1072
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1073
-lazy_refcounts Postpone refcount updates
1074
-refcount_bits Width of a reference count entry in bits
1075
+ backing_file=<str> - File name of a base image
1076
+ backing_fmt=<str> - Image format of the base image
1077
+ cluster_size=<size> - qcow2 cluster size
1078
+ compat=<str> - Compatibility level (0.10 or 1.1)
1079
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1080
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1081
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1082
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1083
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1084
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1085
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1086
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1087
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1088
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1089
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1090
+ refcount_bits=<num> - Width of a reference count entry in bits
1091
+ size=<size> - Virtual disk size
1092
1093
Note that not all of these options may be amendable.
1094
1095
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
1096
Creation options for 'qcow2':
1097
-size Virtual disk size
1098
-compat Compatibility level (0.10 or 1.1)
1099
-backing_file File name of a base image
1100
-backing_fmt Image format of the base image
1101
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1102
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1103
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1104
-encrypt.cipher-alg Name of encryption cipher algorithm
1105
-encrypt.cipher-mode Name of encryption cipher mode
1106
-encrypt.ivgen-alg Name of IV generator algorithm
1107
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1108
-encrypt.hash-alg Name of encryption hash algorithm
1109
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1110
-cluster_size qcow2 cluster size
1111
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1112
-lazy_refcounts Postpone refcount updates
1113
-refcount_bits Width of a reference count entry in bits
1114
+ backing_file=<str> - File name of a base image
1115
+ backing_fmt=<str> - Image format of the base image
1116
+ cluster_size=<size> - qcow2 cluster size
1117
+ compat=<str> - Compatibility level (0.10 or 1.1)
1118
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1119
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1120
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1121
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1122
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1123
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1124
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1125
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1126
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1127
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1128
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1129
+ refcount_bits=<num> - Width of a reference count entry in bits
1130
+ size=<size> - Virtual disk size
1131
1132
Note that not all of these options may be amendable.
1133
1134
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
1135
Creation options for 'qcow2':
1136
-size Virtual disk size
1137
-compat Compatibility level (0.10 or 1.1)
1138
-backing_file File name of a base image
1139
-backing_fmt Image format of the base image
1140
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1141
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1142
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1143
-encrypt.cipher-alg Name of encryption cipher algorithm
1144
-encrypt.cipher-mode Name of encryption cipher mode
1145
-encrypt.ivgen-alg Name of IV generator algorithm
1146
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1147
-encrypt.hash-alg Name of encryption hash algorithm
1148
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1149
-cluster_size qcow2 cluster size
1150
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1151
-lazy_refcounts Postpone refcount updates
1152
-refcount_bits Width of a reference count entry in bits
1153
+ backing_file=<str> - File name of a base image
1154
+ backing_fmt=<str> - Image format of the base image
1155
+ cluster_size=<size> - qcow2 cluster size
1156
+ compat=<str> - Compatibility level (0.10 or 1.1)
1157
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1158
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1159
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1160
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1161
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1162
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1163
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1164
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1165
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1166
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1167
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1168
+ refcount_bits=<num> - Width of a reference count entry in bits
1169
+ size=<size> - Virtual disk size
1170
1171
Note that not all of these options may be amendable.
1172
1173
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
1174
1175
Testing: amend -f qcow2 -o help
1176
Creation options for 'qcow2':
1177
-size Virtual disk size
1178
-compat Compatibility level (0.10 or 1.1)
1179
-backing_file File name of a base image
1180
-backing_fmt Image format of the base image
1181
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1182
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1183
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1184
-encrypt.cipher-alg Name of encryption cipher algorithm
1185
-encrypt.cipher-mode Name of encryption cipher mode
1186
-encrypt.ivgen-alg Name of IV generator algorithm
1187
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1188
-encrypt.hash-alg Name of encryption hash algorithm
1189
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1190
-cluster_size qcow2 cluster size
1191
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1192
-lazy_refcounts Postpone refcount updates
1193
-refcount_bits Width of a reference count entry in bits
1194
+ backing_file=<str> - File name of a base image
1195
+ backing_fmt=<str> - Image format of the base image
1196
+ cluster_size=<size> - qcow2 cluster size
1197
+ compat=<str> - Compatibility level (0.10 or 1.1)
1198
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1199
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1200
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1201
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1202
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1203
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1204
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1205
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1206
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1207
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1208
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1209
+ refcount_bits=<num> - Width of a reference count entry in bits
1210
+ size=<size> - Virtual disk size
1211
1212
Note that not all of these options may be amendable.
1213
1214
Testing: convert -o help
1215
Supported options:
1216
-size Virtual disk size
1217
+ size=<size> - Virtual disk size
1218
1219
Testing: amend -f bochs -o help
1220
qemu-img: Format driver 'bochs' does not support option amendment
1221
--
87
--
1222
2.19.1
88
2.13.6
1223
89
1224
90
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
All callers to bdrv_dirty_iter_new() passed 0 for their initial
4
it might not be actually aligned enough for that pointer type (and
4
starting point, drop that parameter.
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
5
9
There are a few places where the in-place swap function is
6
Most callers to bdrv_set_dirty_iter() were scaling a byte offset to
10
used on something other than a packed struct field; we convert
7
a sector number; the exception qcow2-bitmap will be converted later
11
those anyway, for consistency.
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.
12
11
13
This patch was produced with the following spatch script:
12
Signed-off-by: Eric Blake <eblake@redhat.com>
14
15
@@
16
expression E;
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
49
Reviewed-by: John Snow <jsnow@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>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
17
---
52
block/qcow.c | 18 +++++++++---------
18
include/block/dirty-bitmap.h | 5 ++---
53
1 file changed, 9 insertions(+), 9 deletions(-)
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(-)
54
24
55
diff --git a/block/qcow.c b/block/qcow.c
25
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
56
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow.c
27
--- a/include/block/dirty-bitmap.h
58
+++ b/block/qcow.c
28
+++ b/include/block/dirty-bitmap.h
59
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
29
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
60
if (ret < 0) {
30
void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
61
goto fail;
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)
62
}
115
}
63
- be32_to_cpus(&header.magic);
116
64
- be32_to_cpus(&header.version);
117
assert(!s->dbi);
65
- be64_to_cpus(&header.backing_file_offset);
118
- s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap, 0);
66
- be32_to_cpus(&header.backing_file_size);
119
+ s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
67
- be32_to_cpus(&header.mtime);
120
for (;;) {
68
- be64_to_cpus(&header.size);
121
uint64_t delay_ns = 0;
69
- be32_to_cpus(&header.crypt_method);
122
int64_t cnt, delta;
70
- be64_to_cpus(&header.l1_table_offset);
123
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
71
+ header.magic = be32_to_cpu(header.magic);
124
index XXXXXXX..XXXXXXX 100644
72
+ header.version = be32_to_cpu(header.version);
125
--- a/block/qcow2-bitmap.c
73
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
126
+++ b/block/qcow2-bitmap.c
74
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
127
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
75
+ header.mtime = be32_to_cpu(header.mtime);
128
return NULL;
76
+ header.size = be64_to_cpu(header.size);
77
+ header.crypt_method = be32_to_cpu(header.crypt_method);
78
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
79
80
if (header.magic != QCOW_MAGIC) {
81
error_setg(errp, "Image not in qcow format");
82
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
83
}
129
}
84
130
85
for(i = 0;i < s->l1_size; i++) {
131
- dbi = bdrv_dirty_iter_new(bitmap, 0);
86
- be64_to_cpus(&s->l1_table[i]);
132
+ dbi = bdrv_dirty_iter_new(bitmap);
87
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
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);
88
}
142
}
89
143
90
/* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */
144
*bitmap_table_size = tb_size;
91
--
145
--
92
2.19.1
146
2.13.6
93
147
94
148
diff view generated by jsdifflib
New patch
1
From: Eric Blake <eblake@redhat.com>
1
2
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
New patch
1
From: Eric Blake <eblake@redhat.com>
1
2
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
1
From: Li Qiang <liq3ea@163.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Signed-off-by: Li Qiang <liq3ea@163.com>
3
Half the callers were already scaling bytes to sectors; the other
4
Reviewed-by: Alberto Garcia <berto@igalia.com>
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>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
19
---
7
include/sysemu/block-backend.h | 6 +++---
20
include/block/dirty-bitmap.h | 4 ++--
8
block/block-backend.c | 8 ++++----
21
block/dirty-bitmap.c | 8 ++++----
9
2 files changed, 7 insertions(+), 7 deletions(-)
22
block/mirror.c | 3 +--
23
migration/block.c | 3 ++-
24
4 files changed, 9 insertions(+), 9 deletions(-)
10
25
11
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
26
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
12
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
13
--- a/include/sysemu/block-backend.h
28
--- a/include/block/dirty-bitmap.h
14
+++ b/include/sysemu/block-backend.h
29
+++ b/include/block/dirty-bitmap.h
15
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
30
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap,
16
int error);
31
/* Functions that require manual locking. */
17
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
32
void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
18
bool is_read, int error);
33
void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap);
19
-int blk_is_read_only(BlockBackend *blk);
34
-int bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
20
-int blk_is_sg(BlockBackend *blk);
35
- int64_t sector);
21
-int blk_enable_write_cache(BlockBackend *blk);
36
+bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
22
+bool blk_is_read_only(BlockBackend *blk);
37
+ int64_t offset);
23
+bool blk_is_sg(BlockBackend *blk);
38
void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
24
+bool blk_enable_write_cache(BlockBackend *blk);
39
int64_t cur_sector, int64_t nr_sectors);
25
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
40
void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
26
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
41
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
27
bool blk_is_inserted(BlockBackend *blk);
28
diff --git a/block/block-backend.c b/block/block-backend.c
29
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
30
--- a/block/block-backend.c
43
--- a/block/dirty-bitmap.c
31
+++ b/block/block-backend.c
44
+++ b/block/dirty-bitmap.c
32
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
45
@@ -XXX,XX +XXX,XX @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
33
}
34
}
46
}
35
47
36
-int blk_is_read_only(BlockBackend *blk)
48
/* Called within bdrv_dirty_bitmap_lock..unlock */
37
+bool blk_is_read_only(BlockBackend *blk)
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)
38
{
53
{
39
BlockDriverState *bs = blk_bs(blk);
54
if (bitmap) {
40
55
- return hbitmap_get(bitmap->bitmap, sector);
41
@@ -XXX,XX +XXX,XX @@ int blk_is_read_only(BlockBackend *blk)
56
+ return hbitmap_get(bitmap->bitmap, offset >> BDRV_SECTOR_BITS);
42
}
57
} else {
43
}
44
45
-int blk_is_sg(BlockBackend *blk)
46
+bool blk_is_sg(BlockBackend *blk)
47
{
48
BlockDriverState *bs = blk_bs(blk);
49
50
if (!bs) {
51
- return 0;
58
- return 0;
52
+ return false;
59
+ return false;
53
}
60
}
54
55
return bdrv_is_sg(bs);
56
}
61
}
57
62
58
-int blk_enable_write_cache(BlockBackend *blk)
63
diff --git a/block/mirror.c b/block/mirror.c
59
+bool blk_enable_write_cache(BlockBackend *blk)
64
index XXXXXXX..XXXXXXX 100644
60
{
65
--- a/block/mirror.c
61
return blk->enable_write_cache;
66
+++ b/block/mirror.c
62
}
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 {
63
--
91
--
64
2.19.1
92
2.13.6
65
93
66
94
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
The blkverify mode of Quorum can only be enabled if the number of
3
Some of the callers were already scaling bytes to sectors; others
4
children is exactly two and the value of vote-threshold is also two.
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.
5
12
6
If the user tries to enable it but the other settings are incorrect
13
Signed-off-by: Eric Blake <eblake@redhat.com>
7
then QEMU simply prints an error message to stderr and carries on
14
Reviewed-by: John Snow <jsnow@redhat.com>
8
disabling the blkverify setting.
15
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
16
Reviewed-by: Fam Zheng <famz@redhat.com>
10
This patch makes quorum_open() fail and return an error in this case.
11
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
13
Reported-by: Markus Armbruster <armbru@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
18
---
16
block/quorum.c | 13 ++++++-------
19
include/block/dirty-bitmap.h | 8 ++++----
17
1 file changed, 6 insertions(+), 7 deletions(-)
20
block/dirty-bitmap.c | 22 ++++++++++++++--------
21
block/mirror.c | 16 ++++++++--------
22
migration/block.c | 7 +++++--
23
4 files changed, 31 insertions(+), 22 deletions(-)
18
24
19
diff --git a/block/quorum.c b/block/quorum.c
25
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
20
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
21
--- a/block/quorum.c
27
--- a/include/block/dirty-bitmap.h
22
+++ b/block/quorum.c
28
+++ b/include/block/dirty-bitmap.h
23
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
29
@@ -XXX,XX +XXX,XX @@ const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap);
24
s->read_pattern = ret;
30
int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap);
25
31
DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap);
26
if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
32
void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
27
- /* is the driver in blkverify mode */
33
- int64_t cur_sector, int64_t nr_sectors);
28
- if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
34
+ int64_t offset, int64_t bytes);
29
- s->num_children == 2 && s->threshold == 2) {
35
void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
30
- s->is_blkverify = true;
36
- int64_t cur_sector, int64_t nr_sectors);
31
- } else if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false)) {
37
+ int64_t offset, int64_t bytes);
32
- fprintf(stderr, "blkverify mode is set by setting blkverify=on "
38
BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap);
33
- "and using two files with vote_threshold=2\n");
39
BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap);
34
+ s->is_blkverify = qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false);
40
void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
35
+ if (s->is_blkverify && (s->num_children != 2 || s->threshold != 2)) {
41
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap);
36
+ error_setg(&local_err, "blkverify=on can only be set if there are "
42
bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
37
+ "exactly two files and vote-threshold is 2");
43
int64_t offset);
38
+ ret = -EINVAL;
44
void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
39
+ goto exit;
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;
40
}
149
}
41
150
42
s->rewrite_corrupted = qemu_opt_get_bool(opts, QUORUM_OPT_REWRITE,
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);
43
--
187
--
44
2.19.1
188
2.13.6
45
189
46
190
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Just like in qemu_opts_print_help(), print the object name as a caption
3
Now that we have adjusted the majority of the calls this function
4
instead of on every single line, indent all options, add angle brackets
4
makes to be byte-based, it is easier to read the code if it makes
5
around types, and align the descriptions after 24 characters.
5
passes over the image using bytes rather than sectors.
6
6
7
Also, indent every object name in the list of available objects.
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
12
---
13
vl.c | 13 ++++++++++---
13
block/mirror.c | 38 ++++++++++++++------------------------
14
1 file changed, 10 insertions(+), 3 deletions(-)
14
1 file changed, 14 insertions(+), 24 deletions(-)
15
15
16
diff --git a/vl.c b/vl.c
16
diff --git a/block/mirror.c b/block/mirror.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/vl.c
18
--- a/block/mirror.c
19
+++ b/vl.c
19
+++ b/block/mirror.c
20
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
20
@@ -XXX,XX +XXX,XX @@ static void mirror_throttle(MirrorBlockJob *s)
21
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
21
22
for (l = list; l != NULL; l = l->next) {
22
static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
23
ObjectClass *oc = OBJECT_CLASS(l->data);
23
{
24
- printf("%s\n", object_class_get_name(oc));
24
- int64_t sector_num, end;
25
+ printf(" %s\n", object_class_get_name(oc));
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)
26
}
39
}
27
g_slist_free(list);
40
28
exit(0);
41
s->initial_zeroing_ongoing = true;
29
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
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;
30
}
53
}
31
54
32
str = g_string_new(NULL);
55
- mirror_do_zero_or_discard(s, sector_num * BDRV_SECTOR_SIZE,
33
- g_string_append_printf(str, "%s.%s=%s", type,
56
- nb_sectors * BDRV_SECTOR_SIZE, false);
34
- prop->name, prop->type);
57
- sector_num += nb_sectors;
35
+ g_string_append_printf(str, " %s=<%s>", prop->name, prop->type);
58
+ mirror_do_zero_or_discard(s, offset, bytes, false);
36
if (prop->description) {
59
+ offset += bytes;
37
+ if (str->len < 24) {
38
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
39
+ }
40
g_string_append_printf(str, " - %s", prop->description);
41
}
42
g_ptr_array_add(array, g_string_free(str, false));
43
}
60
}
44
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
61
45
+ if (array->len > 0) {
62
mirror_wait_for_all_io(s);
46
+ printf("%s options:\n", type);
63
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
47
+ } else {
64
}
48
+ printf("There are no options for %s.\n", type);
65
49
+ }
66
/* First part, loop on the sectors and initialize the dirty bitmap. */
50
for (i = 0; i < array->len; i++) {
67
- for (sector_num = 0; sector_num < end; ) {
51
printf("%s\n", (char *)array->pdata[i]);
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;
52
}
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
}
53
--
105
--
54
2.19.1
106
2.13.6
55
107
56
108
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
This is new code, but it is easier to read if it makes passes over
4
it might not be actually aligned enough for that pointer type (and
4
the image using bytes rather than sectors (and will get easier in
5
thus cause a crash on dereference on some host architectures). Newer
5
the future when bdrv_get_block_status is converted to byte-based).
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
6
9
There are a few places where the in-place swap function is
7
Signed-off-by: Eric Blake <eblake@redhat.com>
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
This patch was produced with the following spatch script
14
(and hand-editing to fold a few resulting overlength lines):
15
16
@@
17
expression E;
18
@@
19
-be16_to_cpus(&E);
20
+E = be16_to_cpu(E);
21
@@
22
expression E;
23
@@
24
-be32_to_cpus(&E);
25
+E = be32_to_cpu(E);
26
@@
27
expression E;
28
@@
29
-be64_to_cpus(&E);
30
+E = be64_to_cpu(E);
31
@@
32
expression E;
33
@@
34
-cpu_to_be16s(&E);
35
+E = cpu_to_be16(E);
36
@@
37
expression E;
38
@@
39
-cpu_to_be32s(&E);
40
+E = cpu_to_be32(E);
41
@@
42
expression E;
43
@@
44
-cpu_to_be64s(&E);
45
+E = cpu_to_be64(E);
46
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
49
Tested-by: John Snow <jsnow@redhat.com>
50
Reviewed-by: John Snow <jsnow@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>
51
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
52
---
12
---
53
block/qcow2.c | 64 +++++++++++++++++++++++++++------------------------
13
block/qcow2.c | 22 ++++++++++------------
54
1 file changed, 34 insertions(+), 30 deletions(-)
14
1 file changed, 10 insertions(+), 12 deletions(-)
55
15
56
diff --git a/block/qcow2.c b/block/qcow2.c
16
diff --git a/block/qcow2.c b/block/qcow2.c
57
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
58
--- a/block/qcow2.c
18
--- a/block/qcow2.c
59
+++ b/block/qcow2.c
19
+++ b/block/qcow2.c
60
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
20
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
61
"pread fail from offset %" PRIu64, offset);
21
*/
62
return 1;
22
required = virtual_size;
63
}
23
} else {
64
- be32_to_cpus(&ext.magic);
24
- int cluster_sectors = cluster_size / BDRV_SECTOR_SIZE;
65
- be32_to_cpus(&ext.len);
25
- int64_t sector_num;
66
+ ext.magic = be32_to_cpu(ext.magic);
26
+ int64_t offset;
67
+ ext.len = be32_to_cpu(ext.len);
27
int pnum = 0;
68
offset += sizeof(ext);
28
69
#ifdef DEBUG_EXT
29
- for (sector_num = 0;
70
printf("ext.magic = 0x%x\n", ext.magic);
30
- sector_num < ssize / BDRV_SECTOR_SIZE;
71
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
31
- sector_num += pnum) {
72
"Unable to read CRYPTO header extension");
32
- int nb_sectors = MIN(ssize / BDRV_SECTOR_SIZE - sector_num,
73
return ret;
33
- BDRV_REQUEST_MAX_SECTORS);
34
+ for (offset = 0; offset < ssize;
35
+ offset += pnum * BDRV_SECTOR_SIZE) {
36
+ int nb_sectors = MIN(ssize - offset,
37
+ BDRV_REQUEST_MAX_BYTES) / BDRV_SECTOR_SIZE;
38
BlockDriverState *file;
39
int64_t ret;
40
41
ret = bdrv_get_block_status_above(in_bs, NULL,
42
- sector_num, nb_sectors,
43
+ offset >> BDRV_SECTOR_BITS,
44
+ nb_sectors,
45
&pnum, &file);
46
if (ret < 0) {
47
error_setg_errno(&local_err, -ret,
48
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
49
} else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) ==
50
(BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) {
51
/* Extend pnum to end of cluster for next iteration */
52
- pnum = ROUND_UP(sector_num + pnum, cluster_sectors) -
53
- sector_num;
54
+ pnum = (ROUND_UP(offset + pnum * BDRV_SECTOR_SIZE,
55
+ cluster_size) - offset) >> BDRV_SECTOR_BITS;
56
57
/* Count clusters we've seen */
58
- required += (sector_num % cluster_sectors + pnum) *
59
- BDRV_SECTOR_SIZE;
60
+ required += offset % cluster_size + pnum * BDRV_SECTOR_SIZE;
61
}
74
}
62
}
75
- be64_to_cpus(&s->crypto_header.offset);
76
- be64_to_cpus(&s->crypto_header.length);
77
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
78
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
79
80
if ((s->crypto_header.offset % s->cluster_size) != 0) {
81
error_setg(errp, "Encryption header offset '%" PRIu64 "' is "
82
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
83
return -EINVAL;
84
}
85
86
- be32_to_cpus(&bitmaps_ext.nb_bitmaps);
87
- be64_to_cpus(&bitmaps_ext.bitmap_directory_size);
88
- be64_to_cpus(&bitmaps_ext.bitmap_directory_offset);
89
+ bitmaps_ext.nb_bitmaps = be32_to_cpu(bitmaps_ext.nb_bitmaps);
90
+ bitmaps_ext.bitmap_directory_size =
91
+ be64_to_cpu(bitmaps_ext.bitmap_directory_size);
92
+ bitmaps_ext.bitmap_directory_offset =
93
+ be64_to_cpu(bitmaps_ext.bitmap_directory_offset);
94
95
if (bitmaps_ext.nb_bitmaps > QCOW2_MAX_BITMAPS) {
96
error_setg(errp,
97
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
98
error_setg_errno(errp, -ret, "Could not read qcow2 header");
99
goto fail;
100
}
101
- be32_to_cpus(&header.magic);
102
- be32_to_cpus(&header.version);
103
- be64_to_cpus(&header.backing_file_offset);
104
- be32_to_cpus(&header.backing_file_size);
105
- be64_to_cpus(&header.size);
106
- be32_to_cpus(&header.cluster_bits);
107
- be32_to_cpus(&header.crypt_method);
108
- be64_to_cpus(&header.l1_table_offset);
109
- be32_to_cpus(&header.l1_size);
110
- be64_to_cpus(&header.refcount_table_offset);
111
- be32_to_cpus(&header.refcount_table_clusters);
112
- be64_to_cpus(&header.snapshots_offset);
113
- be32_to_cpus(&header.nb_snapshots);
114
+ header.magic = be32_to_cpu(header.magic);
115
+ header.version = be32_to_cpu(header.version);
116
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
117
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
118
+ header.size = be64_to_cpu(header.size);
119
+ header.cluster_bits = be32_to_cpu(header.cluster_bits);
120
+ header.crypt_method = be32_to_cpu(header.crypt_method);
121
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
122
+ header.l1_size = be32_to_cpu(header.l1_size);
123
+ header.refcount_table_offset = be64_to_cpu(header.refcount_table_offset);
124
+ header.refcount_table_clusters =
125
+ be32_to_cpu(header.refcount_table_clusters);
126
+ header.snapshots_offset = be64_to_cpu(header.snapshots_offset);
127
+ header.nb_snapshots = be32_to_cpu(header.nb_snapshots);
128
129
if (header.magic != QCOW_MAGIC) {
130
error_setg(errp, "Image is not in qcow2 format");
131
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
132
header.refcount_order = 4;
133
header.header_length = 72;
134
} else {
135
- be64_to_cpus(&header.incompatible_features);
136
- be64_to_cpus(&header.compatible_features);
137
- be64_to_cpus(&header.autoclear_features);
138
- be32_to_cpus(&header.refcount_order);
139
- be32_to_cpus(&header.header_length);
140
+ header.incompatible_features =
141
+ be64_to_cpu(header.incompatible_features);
142
+ header.compatible_features = be64_to_cpu(header.compatible_features);
143
+ header.autoclear_features = be64_to_cpu(header.autoclear_features);
144
+ header.refcount_order = be32_to_cpu(header.refcount_order);
145
+ header.header_length = be32_to_cpu(header.header_length);
146
147
if (header.header_length < 104) {
148
error_setg(errp, "qcow2 header too short");
149
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
150
goto fail;
151
}
152
for(i = 0;i < s->l1_size; i++) {
153
- be64_to_cpus(&s->l1_table[i]);
154
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
155
}
156
}
157
158
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
159
160
/* Full disk encryption header pointer extension */
161
if (s->crypto_header.offset != 0) {
162
- cpu_to_be64s(&s->crypto_header.offset);
163
- cpu_to_be64s(&s->crypto_header.length);
164
+ s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset);
165
+ s->crypto_header.length = cpu_to_be64(s->crypto_header.length);
166
ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER,
167
&s->crypto_header, sizeof(s->crypto_header),
168
buflen);
169
- be64_to_cpus(&s->crypto_header.offset);
170
- be64_to_cpus(&s->crypto_header.length);
171
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
172
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
173
if (ret < 0) {
174
goto fail;
175
}
63
}
176
--
64
--
177
2.19.1
65
2.13.6
178
66
179
67
diff view generated by jsdifflib
1
From: Stefan Weil <sw@weilnetz.de>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Use %zu instead of %zd for unsigned numbers.
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.
4
6
5
This fixes two error messages from the LSTM static code analyzer:
7
Signed-off-by: Eric Blake <eblake@redhat.com>
6
8
Reviewed-by: John Snow <jsnow@redhat.com>
7
This argument should be of type 'ssize_t' but is of type 'unsigned long'
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Stefan Weil <sw@weilnetz.de>
11
Reviewed-by: Fam Zheng <famz@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
---
13
qemu-io-cmds.c | 4 ++--
14
block/qcow2-bitmap.c | 22 ++++++++--------------
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
1 file changed, 8 insertions(+), 14 deletions(-)
15
16
16
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
17
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/qemu-io-cmds.c
19
--- a/block/qcow2-bitmap.c
19
+++ b/qemu-io-cmds.c
20
+++ b/block/qcow2-bitmap.c
20
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
21
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
21
memset(cmp_buf, pattern, qiov.size);
22
{
22
if (memcmp(buf, cmp_buf, qiov.size)) {
23
int ret = 0;
23
printf("Pattern verification failed at offset %"
24
BDRVQcow2State *s = bs->opaque;
24
- PRId64 ", %zd bytes\n", offset, qiov.size);
25
- uint64_t sector, limit, sbc;
25
+ PRId64 ", %zu bytes\n", offset, qiov.size);
26
+ uint64_t offset, limit;
26
ret = -EINVAL;
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);
27
}
70
}
28
g_free(cmp_buf);
29
@@ -XXX,XX +XXX,XX @@ static void aio_read_done(void *opaque, int ret)
30
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
31
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
32
printf("Pattern verification failed at offset %"
33
- PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
34
+ PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
35
}
36
g_free(cmp_buf);
37
}
71
}
38
--
72
--
39
2.19.1
73
2.13.6
40
74
41
75
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Just like in qemu_opts_print_help(), print the device name as a caption
3
Now that we have adjusted the majority of the calls this function
4
instead of on every single line, indent all options, add angle brackets
4
makes to be byte-based, it is easier to read the code if it makes
5
around types, and align the descriptions after 24 characters. Also,
5
passes over the image using bytes rather than sectors.
6
separate the descriptions with " - " instead of putting them in
7
parentheses, because that is what we do everywhere else. This does look
8
a bit funny here because basically all bits have the description
9
"on/off", but funny does not mean it is less readable.
10
6
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
iotests 165 was rather weak - on a default 64k-cluster image, where
12
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
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>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
25
---
15
qdev-monitor.c | 13 +++++++++++--
26
block/qcow2-bitmap.c | 31 ++++++++++++++++---------------
16
1 file changed, 11 insertions(+), 2 deletions(-)
27
tests/qemu-iotests/165 | 2 +-
28
2 files changed, 17 insertions(+), 16 deletions(-)
17
29
18
diff --git a/qdev-monitor.c b/qdev-monitor.c
30
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
19
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
20
--- a/qdev-monitor.c
32
--- a/block/qcow2-bitmap.c
21
+++ b/qdev-monitor.c
33
+++ b/block/qcow2-bitmap.c
22
@@ -XXX,XX +XXX,XX @@ int qdev_device_help(QemuOpts *opts)
34
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
23
goto error;
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);
24
}
99
}
25
100
26
+ if (prop_list) {
101
*bitmap_table_size = tb_size;
27
+ out_printf("%s options:\n", driver);
102
diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165
28
+ } else {
103
index XXXXXXX..XXXXXXX 100755
29
+ out_printf("There are no options for %s.\n", driver);
104
--- a/tests/qemu-iotests/165
30
+ }
105
+++ b/tests/qemu-iotests/165
31
for (prop = prop_list; prop; prop = prop->next) {
106
@@ -XXX,XX +XXX,XX @@ disk = os.path.join(iotests.test_dir, 'disk')
32
- out_printf("%s.%s=%s", driver, prop->value->name, prop->value->type);
107
disk_size = 0x40000000 # 1G
33
+ int len;
108
34
+ out_printf(" %s=<%s>%n", prop->value->name, prop->value->type, &len);
109
# regions for qemu_io: (start, count) in bytes
35
if (prop->value->has_description) {
110
-regions1 = ((0, 0x100000),
36
- out_printf(" (%s)\n", prop->value->description);
111
+regions1 = ((0x0fff00, 0x10000),
37
+ if (len < 24) {
112
(0x200000, 0x100000))
38
+ out_printf("%*s", 24 - len, "");
113
39
+ }
114
regions2 = ((0x10000000, 0x20000),
40
+ out_printf(" - %s\n", prop->value->description);
41
} else {
42
out_printf("\n");
43
}
44
--
115
--
45
2.19.1
116
2.13.6
46
117
47
118
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
The blkverify mode of Quorum only works when the number of children is
3
Both callers already had bytes available, but were scaling to
4
exactly two, so any attempt to add a new one must return an error.
4
sectors. Move the scaling to internal code. In the case of
5
bdrv_aligned_pwritev(), we are now passing the exact offset
6
rather than a rounded sector-aligned value, but that's okay
7
as long as dirty bitmap widens start/bytes to granularity
8
boundaries.
5
9
6
quorum_del_child() on the other hand doesn't need any additional check
10
Signed-off-by: Eric Blake <eblake@redhat.com>
7
because decreasing the number of children would make it go under the
11
Reviewed-by: John Snow <jsnow@redhat.com>
8
vote threshold.
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
13
Reviewed-by: Fam Zheng <famz@redhat.com>
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
11
Reported-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
15
---
14
block/quorum.c | 8 ++++++++
16
include/block/block_int.h | 2 +-
15
1 file changed, 8 insertions(+)
17
block/dirty-bitmap.c | 7 ++++---
18
block/io.c | 6 ++----
19
3 files changed, 7 insertions(+), 8 deletions(-)
16
20
17
diff --git a/block/quorum.c b/block/quorum.c
21
diff --git a/include/block/block_int.h b/include/block/block_int.h
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/block/quorum.c
23
--- a/include/block/block_int.h
20
+++ b/block/quorum.c
24
+++ b/include/block/block_int.h
21
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
25
@@ -XXX,XX +XXX,XX @@ void blk_dev_eject_request(BlockBackend *blk, bool force);
22
char indexstr[32];
26
bool blk_dev_is_tray_open(BlockBackend *blk);
27
bool blk_dev_is_medium_locked(BlockBackend *blk);
28
29
-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int64_t nr_sect);
30
+void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes);
31
bool bdrv_requests_pending(BlockDriverState *bs);
32
33
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
34
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/dirty-bitmap.c
37
+++ b/block/dirty-bitmap.c
38
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
39
hbitmap_deserialize_finish(bitmap->bitmap);
40
}
41
42
-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
43
- int64_t nr_sectors)
44
+void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
45
{
46
BdrvDirtyBitmap *bitmap;
47
+ int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
48
49
if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
50
return;
51
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
52
continue;
53
}
54
assert(!bdrv_dirty_bitmap_readonly(bitmap));
55
- hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
56
+ hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
57
+ end_sector - (offset >> BDRV_SECTOR_BITS));
58
}
59
bdrv_dirty_bitmaps_unlock(bs);
60
}
61
diff --git a/block/io.c b/block/io.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/block/io.c
64
+++ b/block/io.c
65
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
66
bool waited;
23
int ret;
67
int ret;
24
68
25
+ if (s->is_blkverify) {
69
- int64_t start_sector = offset >> BDRV_SECTOR_BITS;
26
+ error_setg(errp, "Cannot add a child to a quorum in blkverify mode");
70
int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
27
+ return;
71
uint64_t bytes_remaining = bytes;
28
+ }
72
int max_transfer;
29
+
73
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
30
assert(s->num_children <= INT_MAX / sizeof(BdrvChild *));
74
bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
31
if (s->num_children == INT_MAX / sizeof(BdrvChild *) ||
75
32
s->next_child_index == UINT_MAX) {
76
atomic_inc(&bs->write_gen);
33
@@ -XXX,XX +XXX,XX @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
77
- bdrv_set_dirty(bs, start_sector, end_sector - start_sector);
34
return;
78
+ bdrv_set_dirty(bs, offset, bytes);
35
}
79
36
80
stat64_max(&bs->wr_highest_offset, offset + bytes);
37
+ /* We know now that num_children > threshold, so blkverify must be false */
81
38
+ assert(!s->is_blkverify);
82
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
39
+
83
ret = 0;
40
bdrv_drained_begin(bs);
84
out:
41
85
atomic_inc(&bs->write_gen);
42
/* We can safely remove this child now */
86
- bdrv_set_dirty(bs, req.offset >> BDRV_SECTOR_BITS,
87
- req.bytes >> BDRV_SECTOR_BITS);
88
+ bdrv_set_dirty(bs, req.offset, req.bytes);
89
tracked_request_end(&req);
90
bdrv_dec_in_flight(bs);
91
return ret;
43
--
92
--
44
2.19.1
93
2.13.6
45
94
46
95
diff view generated by jsdifflib
New patch
1
1
From: Eric Blake <eblake@redhat.com>
2
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
1
From: Thomas Huth <thuth@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
When using the vvfat driver with a directory that contains too many files,
3
The condition of the for-loop makes sure that b is always smaller
4
QEMU currently crashes. This can be triggered like this for example:
4
than s->blocks, so the "if (b >= s->blocks)" statement is completely
5
superfluous here.
5
6
6
mkdir /tmp/vvfattest
7
Buglink: https://bugs.launchpad.net/qemu/+bug/1715007
7
cd /tmp/vvfattest
8
for ((x=0;x<=513;x++)); do mkdir $x; done
9
qemu-system-x86_64 -drive \
10
file.driver=vvfat,file.dir=.,read-only=on,media=cdrom
11
12
Seems like read_directory() is changing the mapping->path variable. Make
13
sure we use the right pointer instead.
14
15
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
11
---
18
block/vvfat.c | 4 ++--
12
hw/block/onenand.c | 4 ----
19
1 file changed, 2 insertions(+), 2 deletions(-)
13
1 file changed, 4 deletions(-)
20
14
21
diff --git a/block/vvfat.c b/block/vvfat.c
15
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
22
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
23
--- a/block/vvfat.c
17
--- a/hw/block/onenand.c
24
+++ b/block/vvfat.c
18
+++ b/hw/block/onenand.c
25
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
19
@@ -XXX,XX +XXX,XX @@ static void onenand_command(OneNANDState *s)
26
mapping = array_get(&(s->mapping), i);
20
s->intstatus |= ONEN_INT;
27
21
28
if (mapping->mode & MODE_DIRECTORY) {
22
for (b = 0; b < s->blocks; b ++) {
29
+ char *path = mapping->path;
23
- if (b >= s->blocks) {
30
mapping->begin = cluster;
24
- s->status |= ONEN_ERR_CMD;
31
if(read_directory(s, i)) {
25
- break;
32
- error_setg(errp, "Could not read directory %s",
26
- }
33
- mapping->path);
27
if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
34
+ error_setg(errp, "Could not read directory %s", path);
28
break;
35
return -1;
29
36
}
37
mapping = array_get(&(s->mapping), i);
38
--
30
--
39
2.19.1
31
2.13.6
40
32
41
33
diff view generated by jsdifflib
New patch
1
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
3
This includes shell function, shell variables and command line options
4
(randomize.awk does not exist).
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 | 28 -----------------
11
tests/qemu-iotests/common | 23 --------------
12
tests/qemu-iotests/common.config | 26 ---------------
13
tests/qemu-iotests/common.rc | 68 ----------------------------------------
14
4 files changed, 145 deletions(-)
15
16
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
17
index XXXXXXX..XXXXXXX 100755
18
--- a/tests/qemu-iotests/check
19
+++ b/tests/qemu-iotests/check
20
@@ -XXX,XX +XXX,XX @@ then
21
export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
22
fi
23
24
-# if ./qemu exists, it should be prioritized and will be chosen by common.config
25
if [[ -z "$QEMU_PROG" && ! -x './qemu' ]]
26
then
27
arch=$(uname -m 2> /dev/null)
28
@@ -XXX,XX +XXX,XX @@ _timestamp()
29
30
_wrapup()
31
{
32
- # for hangcheck ...
33
- # remove files that were used by hangcheck
34
- #
35
- [ -f "${TEST_DIR}"/check.pid ] && rm -rf "${TEST_DIR}"/check.pid
36
- [ -f "${TEST_DIR}"/check.sts ] && rm -rf "${TEST_DIR}"/check.sts
37
-
38
if $showme
39
then
40
:
41
@@ -XXX,XX +XXX,XX @@ END { if (NR > 0) {
42
43
trap "_wrapup; exit \$status" 0 1 2 3 15
44
45
-# for hangcheck ...
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
78
--- a/tests/qemu-iotests/common
79
+++ b/tests/qemu-iotests/common
80
@@ -XXX,XX +XXX,XX @@
81
# common procedures for QA scripts
82
#
83
84
-_setenvironment()
85
-{
86
- MSGVERB="text:action"
87
- export MSGVERB
88
-}
89
-
90
-rm -f "$OUTPUT_DIR/$iam.out"
91
-_setenvironment
92
-
93
-check=${check-true}
94
-
95
diff="diff -u"
96
verbose=false
97
debug=false
98
@@ -XXX,XX +XXX,XX @@ showme=false
99
sortme=false
100
expunge=true
101
have_test_arg=false
102
-randomize=false
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
--
283
2.13.6
284
285
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
tests/qemu-iotests/check | 4 ++--
8
tests/qemu-iotests/common | 2 +-
9
tests/qemu-iotests/common.config | 3 ---
10
3 files changed, 3 insertions(+), 6 deletions(-)
11
12
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
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
36
--- a/tests/qemu-iotests/common
37
+++ b/tests/qemu-iotests/common
38
@@ -XXX,XX +XXX,XX @@ testlist options
39
if $xpand
40
then
41
have_test_arg=true
42
- $AWK_PROG </dev/null '
43
+ awk </dev/null '
44
BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
45
| while read id
46
do
47
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
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
--
62
2.13.6
63
64
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
This is a static function with only one caller, so there's no need to
3
Some functions in common.rc are never used by the tests. Move
4
keep it. Inlining the code in quorum_compare() makes it much simpler.
4
them out of that file and into common, which is already included
5
only by "check".
5
6
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
Code that actually *is* common to "check" and tests can be placed in
7
Reported-by: Markus Armbruster <armbru@redhat.com>
8
common.config.
9
10
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
13
---
10
block/quorum.c | 24 +++++-------------------
14
tests/qemu-iotests/common | 25 ++++++++++++++++++++++++-
11
1 file changed, 5 insertions(+), 19 deletions(-)
15
tests/qemu-iotests/common.config | 12 ++++++++++++
16
tests/qemu-iotests/common.rc | 40 ----------------------------------------
17
3 files changed, 36 insertions(+), 41 deletions(-)
12
18
13
diff --git a/block/quorum.c b/block/quorum.c
19
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/block/quorum.c
21
--- a/tests/qemu-iotests/common
16
+++ b/block/quorum.c
22
+++ b/tests/qemu-iotests/common
17
@@ -XXX,XX +XXX,XX @@ static bool quorum_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
23
@@ -XXX,XX +XXX,XX @@
18
return true;
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
19
}
78
}
20
79
21
-static void GCC_FMT_ATTR(2, 3) quorum_err(QuorumAIOCB *acb,
80
+_optstr_add()
22
- const char *fmt, ...)
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()
23
-{
111
-{
24
- va_list ap;
112
- if [ -n "$1" ]; then
25
-
113
- echo "$1,$2"
26
- va_start(ap, fmt);
114
- else
27
- fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64 " ",
115
- echo "$2"
28
- acb->offset, acb->bytes);
116
- fi
29
- vfprintf(stderr, fmt, ap);
30
- fprintf(stderr, "\n");
31
- va_end(ap);
32
- exit(1);
33
-}
117
-}
34
-
118
-
35
-static bool quorum_compare(QuorumAIOCB *acb,
119
-_set_default_imgopts()
36
- QEMUIOVector *a,
120
-{
37
- QEMUIOVector *b)
121
- if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
38
+static bool quorum_compare(QuorumAIOCB *acb, QEMUIOVector *a, QEMUIOVector *b)
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()
39
{
130
{
40
BDRVQuorumState *s = acb->bs->opaque;
131
SAMPLE_IMG_FILE="${1%\.bz2}"
41
ssize_t offset;
132
@@ -XXX,XX +XXX,XX @@ _require_command()
42
@@ -XXX,XX +XXX,XX @@ static bool quorum_compare(QuorumAIOCB *acb,
133
[ -x "$c" ] || _notrun "$1 utility required, skipped this test"
43
if (s->is_blkverify) {
134
}
44
offset = qemu_iovec_compare(a, b);
135
45
if (offset != -1) {
136
-_full_imgfmt_details()
46
- quorum_err(acb, "contents mismatch at offset %" PRIu64,
137
-{
47
- acb->offset + offset);
138
- if [ -n "$IMGOPTS" ]; then
48
+ fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64
139
- echo "$IMGFMT ($IMGOPTS)"
49
+ " contents mismatch at offset %" PRIu64 "\n",
140
- else
50
+ acb->offset, acb->bytes, acb->offset + offset);
141
- echo "$IMGFMT"
51
+ exit(1);
142
- fi
52
}
143
-}
53
return true;
144
-
54
}
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
55
--
156
--
56
2.19.1
157
2.13.6
57
158
58
159
diff view generated by jsdifflib
New patch
1
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
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
New patch
1
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
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
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
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
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
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
1
From: Leonid Bloch <lbloch@janustech.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
The lookup table for power-of-two sizes was added in commit 540b8492618eb
3
The variable is used in "common" but defined only after the file
4
for the purpose of having convenient shortcuts for these sizes in cases
4
is sourced.
5
when the literal number has to be present at compile time, and
6
expressions as '(1 * KiB)' can not be used. One such case is the
7
stringification of sizes. Beyond that, it is convenient to use these
8
shortcuts for all power-of-two sizes, even if they don't have to be
9
literal numbers.
10
5
11
Despite its convenience, this table introduced 55 lines of "dumb" code,
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
12
the purpose and origin of which are obscure without reading the message
7
Reviewed-by: Eric Blake <eblake@redhat.com>
13
of the commit which introduced it. This patch fixes that by adding a
14
comment to the code itself with a brief explanation for the reasoning
15
behind this table. This comment includes the short AWK script that
16
generated the table, so that anyone who's interested could make sure
17
that the values in it are correct (otherwise these values look as if
18
they were typed manually).
19
20
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
9
---
23
include/qemu/units.h | 18 ++++++++++++++++++
10
tests/qemu-iotests/check | 2 --
24
1 file changed, 18 insertions(+)
11
tests/qemu-iotests/common | 2 ++
12
2 files changed, 2 insertions(+), 2 deletions(-)
25
13
26
diff --git a/include/qemu/units.h b/include/qemu/units.h
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
27
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
28
--- a/include/qemu/units.h
29
--- a/tests/qemu-iotests/common
29
+++ b/include/qemu/units.h
30
+++ b/tests/qemu-iotests/common
30
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ sortme=false
31
#define PiB (INT64_C(1) << 50)
32
expunge=true
32
#define EiB (INT64_C(1) << 60)
33
have_test_arg=false
33
34
cachemode=false
34
+/*
35
+ * The following lookup table is intended to be used when a literal string of
36
+ * the number of bytes is required (for example if it needs to be stringified).
37
+ * It can also be used for generic shortcuts of power-of-two sizes.
38
+ * This table is generated using the AWK script below:
39
+ *
40
+ * BEGIN {
41
+ * suffix="KMGTPE";
42
+ * for(i=10; i<64; i++) {
43
+ * val=2**i;
44
+ * s=substr(suffix, int(i/10), 1);
45
+ * n=2**(i%10);
46
+ * pad=21-int(log(n)/log(10));
47
+ * printf("#define S_%d%siB %*d\n", n, s, pad, val);
48
+ * }
49
+ * }
50
+ */
51
+
35
+
52
#define S_1KiB 1024
36
+tmp="${TEST_DIR}"/$$
53
#define S_2KiB 2048
37
rm -f $tmp.list $tmp.tmp $tmp.sed
54
#define S_4KiB 4096
38
39
export IMGFMT=raw
55
--
40
--
56
2.19.1
41
2.13.6
57
42
58
43
diff view generated by jsdifflib
1
From: Cleber Rosa <crosa@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
While testing the Python 3 changes which touch the 083 test, I noticed
3
The variable is almost unused, and one of the two uses is actually
4
that it would fail with qcow2. Expanding the testing, I noticed it
4
uninitialized.
5
had nothing to do with the Python 3 changes, and in fact, it would not
6
pass on anything but raw:
7
5
8
raw: pass
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9
bochs: not generic
7
Reviewed-by: Eric Blake <eblake@redhat.com>
10
cloop: not generic
11
parallels: fail
12
qcow: fail
13
qcow2: fail
14
qed: fail
15
vdi: fail
16
vhdx: fail
17
vmdk: fail
18
vpc: fail
19
luks: fail
20
21
The errors are a mixture I/O and "image not in xxx format", such as:
22
23
=== Check disconnect before data ===
24
25
Unexpected end-of-file before all bytes were read
26
-read failed: Input/output error
27
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Could not open 'nbd://127.0.0.1:PORT/foo': Input/output error
28
29
=== Check disconnect after data ===
30
31
-read 512/512 bytes at offset 0
32
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
33
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Image not in qcow format
34
35
I'm not aware if there's a quick fix, so, for the time being, it looks
36
like the honest approach is to make the test known to work on raw
37
only.
38
39
Signed-off-by: Cleber Rosa <crosa@redhat.com>
40
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
41
---
9
---
42
tests/qemu-iotests/083 | 2 +-
10
tests/qemu-iotests/check | 5 +----
43
1 file changed, 1 insertion(+), 1 deletion(-)
11
tests/qemu-iotests/common.rc | 2 +-
12
2 files changed, 2 insertions(+), 5 deletions(-)
44
13
45
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
14
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
46
index XXXXXXX..XXXXXXX 100755
15
index XXXXXXX..XXXXXXX 100755
47
--- a/tests/qemu-iotests/083
16
--- a/tests/qemu-iotests/check
48
+++ b/tests/qemu-iotests/083
17
+++ b/tests/qemu-iotests/check
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
18
@@ -XXX,XX +XXX,XX @@ interrupt=true
50
. ./common.rc
19
# by default don't output timestamps
51
. ./common.filter
20
timestamp=${TIMESTAMP:=false}
52
21
53
-_supported_fmt generic
22
-# generic initialization
54
+_supported_fmt raw
23
-iam=check
55
_supported_proto nbd
24
-
56
_supported_os Linux
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
57
44
58
--
45
--
59
2.19.1
46
2.13.6
60
47
61
48
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
This patch tests that you can add and remove drives from a Quorum
3
"check" is full of qemu-iotests--specific details. Separating it
4
using the x-blockdev-change command.
4
from "common" does not make much sense anymore.
5
5
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
---
9
tests/qemu-iotests/081 | 86 ++++++++++++++++++++++++++++++++++++++
10
tests/qemu-iotests/check | 533 +++++++++++++++++++++++++++++++++++++++++++-
10
tests/qemu-iotests/081.out | 54 ++++++++++++++++++++++++
11
tests/qemu-iotests/common | 552 ----------------------------------------------
11
2 files changed, 140 insertions(+)
12
2 files changed, 531 insertions(+), 554 deletions(-)
13
delete mode 100644 tests/qemu-iotests/common
12
14
13
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
15
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
14
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/081
17
--- a/tests/qemu-iotests/check
16
+++ b/tests/qemu-iotests/081
18
+++ b/tests/qemu-iotests/check
17
@@ -XXX,XX +XXX,XX @@ quorum="$quorum,file.children.2.driver=raw"
19
@@ -XXX,XX +XXX,XX @@ then
18
20
_init_error "failed to source common.config"
19
$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
21
fi
20
22
21
+echo
23
-# we need common
22
+echo "== dynamically adding a child to a quorum =="
24
-. "$source_iotests/common"
23
+
25
+_full_imgfmt_details()
24
+for verify in false true; do
26
+{
25
+ run_qemu <<EOF
27
+ if [ -n "$IMGOPTS" ]; then
26
+ { "execute": "qmp_capabilities" }
28
+ echo "$IMGFMT ($IMGOPTS)"
27
+ { "execute": "blockdev-add",
29
+ else
28
+ "arguments": {
30
+ echo "$IMGFMT"
29
+ "driver": "quorum",
31
+ fi
30
+ "node-name": "drive0-quorum",
32
+}
31
+ "vote-threshold": 2,
33
+
32
+ "blkverify": ${verify},
34
+_full_platform_details()
33
+ "children": [
35
+{
34
+ {
36
+ os=`uname -s`
35
+ "driver": "$IMGFMT",
37
+ host=`hostname -s`
36
+ "file": {
38
+ kernel=`uname -r`
37
+ "driver": "file",
39
+ platform=`uname -m`
38
+ "filename": "$TEST_DIR/1.raw"
40
+ echo "$os/$platform $host $kernel"
39
+ }
41
+}
40
+ },
42
+
41
+ {
43
+# $1 = prog to look for
42
+ "driver": "$IMGFMT",
44
+set_prog_path()
43
+ "file": {
45
+{
44
+ "driver": "file",
46
+ p=`command -v $1 2> /dev/null`
45
+ "filename": "$TEST_DIR/2.raw"
47
+ if [ -n "$p" -a -x "$p" ]; then
46
+ }
48
+ realpath -- "$(type -p "$p")"
47
+ }
49
+ else
48
+ ]
50
+ return 1
49
+ }
51
+ fi
50
+ }
52
+}
51
+ { "execute": "blockdev-add",
53
+
52
+ "arguments": {
54
+if [ -z "$TEST_DIR" ]; then
53
+ "node-name": "drive3",
55
+ TEST_DIR=`pwd`/scratch
54
+ "driver": "$IMGFMT",
56
+fi
55
+ "file": {
57
+
56
+ "driver": "file",
58
+if [ ! -e "$TEST_DIR" ]; then
57
+ "filename": "$TEST_DIR/2.raw"
59
+ mkdir "$TEST_DIR"
58
+ }
60
+fi
59
+ }
61
+
60
+ }
62
+diff="diff -u"
61
+ { "execute": "x-blockdev-change",
63
+verbose=false
62
+ "arguments": { "parent": "drive0-quorum",
64
+debug=false
63
+ "node": "drive3" } }
65
+group=false
64
+ { "execute": "quit" }
66
+xgroup=false
65
+EOF
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
+
66
+done
438
+done
67
+
439
+
68
+echo
440
+# Set qemu-io cache mode with $CACHEMODE we have
69
+echo "== dynamically removing a child from a quorum =="
441
+QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
70
+
442
+
71
+for verify in false true; do
443
+QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS"
72
+ for vote_threshold in 1 2; do
444
+if [ "$IMGOPTSSYNTAX" != "true" ]; then
73
+ run_qemu <<EOF
445
+ QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT"
74
+ { "execute": "qmp_capabilities" }
446
+fi
75
+ { "execute": "blockdev-add",
447
+
76
+ "arguments": {
448
+# Set default options for qemu-img create -o if they were not specified
77
+ "driver": "quorum",
449
+if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
78
+ "node-name": "drive0-quorum",
450
+ IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
79
+ "vote-threshold": ${vote_threshold},
451
+fi
80
+ "blkverify": ${verify},
452
+if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
81
+ "children": [
453
+ IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
82
+ {
454
+fi
83
+ "driver": "$IMGFMT",
455
+
84
+ "file": {
456
+if [ -z "$SAMPLE_IMG_DIR" ]; then
85
+ "driver": "file",
457
+ SAMPLE_IMG_DIR="$source_iotests/sample_images"
86
+ "filename": "$TEST_DIR/1.raw"
458
+fi
87
+ }
459
+
88
+ },
460
+export TEST_DIR
89
+ {
461
+export SAMPLE_IMG_DIR
90
+ "driver": "$IMGFMT",
462
+
91
+ "file": {
463
+if [ -s $tmp.list ]
92
+ "driver": "file",
464
+then
93
+ "filename": "$TEST_DIR/2.raw"
465
+ # found some valid test numbers ... this is good
94
+ }
466
+ :
95
+ }
467
+else
96
+ ]
468
+ if $have_test_arg
97
+ }
469
+ then
98
+ }
470
+ # had test numbers, but none in group file ... do nothing
99
+ { "execute": "x-blockdev-change",
471
+ touch $tmp.list
100
+ "arguments": { "parent": "drive0-quorum",
472
+ else
101
+ "child": "children.1" } }
473
+ # no test numbers, do everything from group file
102
+ { "execute": "quit" }
474
+ sed -n -e '/^[0-9][0-9][0-9]*/s/[ ].*//p' <"$source_iotests/group" >$tmp.list
103
+EOF
475
+ fi
104
+ done
476
+fi
105
+done
477
+
106
+
478
+# should be sort -n, but this did not work for Linux when this
107
# success, all done
479
+# was ported from IRIX
108
echo "*** done"
480
+#
109
rm -f $seq.full
481
+list=`sort $tmp.list`
110
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
482
+rm -f $tmp.list $tmp.tmp $tmp.sed
111
index XXXXXXX..XXXXXXX 100644
483
+
112
--- a/tests/qemu-iotests/081.out
484
+if [ -z "$QEMU_PROG" ]
113
+++ b/tests/qemu-iotests/081.out
485
+then
114
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
486
+ if [ -x "$build_iotests/qemu" ]; then
115
487
+ export QEMU_PROG="$build_iotests/qemu"
116
== checking the blkverify mode with invalid settings ==
488
+ elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
117
can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
489
+ export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
118
+
490
+ else
119
+== dynamically adding a child to a quorum ==
491
+ pushd "$build_root" > /dev/null
120
+Testing:
492
+ for binary in *-softmmu/qemu-system-*
121
+QMP_VERSION
493
+ do
122
+{"return": {}}
494
+ if [ -x "$binary" ]
123
+{"return": {}}
495
+ then
124
+{"return": {}}
496
+ export QEMU_PROG="$build_root/$binary"
125
+{"return": {}}
497
+ break
126
+{"return": {}}
498
+ fi
127
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
499
+ done
128
+
500
+ popd > /dev/null
129
+Testing:
501
+ [ "$QEMU_PROG" = "" ] && _init_error "qemu not found"
130
+QMP_VERSION
502
+ fi
131
+{"return": {}}
503
+fi
132
+{"return": {}}
504
+export QEMU_PROG=$(realpath -- "$(type -p "$QEMU_PROG")")
133
+{"return": {}}
505
+
134
+{"error": {"class": "GenericError", "desc": "Cannot add a child to a quorum in blkverify mode"}}
506
+if [ -z "$QEMU_IMG_PROG" ]; then
135
+{"return": {}}
507
+ if [ -x "$build_iotests/qemu-img" ]; then
136
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
508
+ export QEMU_IMG_PROG="$build_iotests/qemu-img"
137
+
509
+ elif [ -x "$build_root/qemu-img" ]; then
138
+
510
+ export QEMU_IMG_PROG="$build_root/qemu-img"
139
+== dynamically removing a child from a quorum ==
511
+ else
140
+Testing:
512
+ _init_error "qemu-img not found"
141
+QMP_VERSION
513
+ fi
142
+{"return": {}}
514
+fi
143
+{"return": {}}
515
+export QEMU_IMG_PROG=$(realpath -- "$(type -p "$QEMU_IMG_PROG")")
144
+{"return": {}}
516
+
145
+{"return": {}}
517
+if [ -z "$QEMU_IO_PROG" ]; then
146
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
518
+ if [ -x "$build_iotests/qemu-io" ]; then
147
+
519
+ export QEMU_IO_PROG="$build_iotests/qemu-io"
148
+Testing:
520
+ elif [ -x "$build_root/qemu-io" ]; then
149
+QMP_VERSION
521
+ export QEMU_IO_PROG="$build_root/qemu-io"
150
+{"return": {}}
522
+ else
151
+{"return": {}}
523
+ _init_error "qemu-io not found"
152
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
524
+ fi
153
+{"return": {}}
525
+fi
154
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
526
+export QEMU_IO_PROG=$(realpath -- "$(type -p "$QEMU_IO_PROG")")
155
+
527
+
156
+Testing:
528
+if [ -z $QEMU_NBD_PROG ]; then
157
+QMP_VERSION
529
+ if [ -x "$build_iotests/qemu-nbd" ]; then
158
+{"return": {}}
530
+ export QEMU_NBD_PROG="$build_iotests/qemu-nbd"
159
+{"error": {"class": "GenericError", "desc": "blkverify=on can only be set if there are exactly two files and vote-threshold is 2"}}
531
+ elif [ -x "$build_root/qemu-nbd" ]; then
160
+{"error": {"class": "GenericError", "desc": "Cannot find device=drive0-quorum nor node_name=drive0-quorum"}}
532
+ export QEMU_NBD_PROG="$build_root/qemu-nbd"
161
+{"return": {}}
533
+ else
162
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
534
+ _init_error "qemu-nbd not found"
163
+
535
+ fi
164
+Testing:
536
+fi
165
+QMP_VERSION
537
+export QEMU_NBD_PROG=$(realpath -- "$(type -p "$QEMU_NBD_PROG")")
166
+{"return": {}}
538
+
167
+{"return": {}}
539
+if [ -z "$QEMU_VXHS_PROG" ]; then
168
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
540
+ export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
169
+{"return": {}}
541
+fi
170
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
542
+
171
+
543
+if [ -x "$build_iotests/socket_scm_helper" ]
172
*** done
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"
173
--
1117
--
174
2.19.1
1118
2.13.6
175
1119
176
1120
diff view generated by jsdifflib
1
To fully change the read-only state of a node, we must not only change
1
There is no good reason for bdrv_drop_intermediate() to know the active
2
bs->read_only, but also update bs->open_flags.
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
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().
3
9
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
---
12
---
8
block.c | 7 +++++++
13
include/block/block_int.h | 6 ++++++
9
1 file changed, 7 insertions(+)
14
block.c | 33 ++++++++++++++++++++++++++++-----
15
2 files changed, 34 insertions(+), 5 deletions(-)
10
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;
11
diff --git a/block.c b/block.c
34
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
36
--- a/block.c
14
+++ b/block.c
37
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
38
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
16
}
39
*child_flags = flags;
17
40
}
18
bs->read_only = read_only;
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;
19
+
47
+
20
+ if (read_only) {
48
+ ret = bdrv_change_backing_file(parent, filename,
21
+ bs->open_flags &= ~BDRV_O_RDWR;
49
+ base->drv ? base->drv->format_name : "");
22
+ } else {
50
+ if (ret < 0) {
23
+ bs->open_flags |= BDRV_O_RDWR;
51
+ error_setg_errno(errp, ret, "Could not update backing file link");
24
+ }
52
+ }
25
+
53
+
26
return 0;
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;
27
}
104
}
28
105
29
--
106
--
30
2.19.1
107
2.13.6
31
108
32
109
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
This changes the commit block job to support operation in a graph where
2
there is more than a single active layer that references the top node.
2
3
3
Taking the address of a field in a packed struct is a bad idea, because
4
This involves inserting the commit filter node not only on the path
4
it might not be actually aligned enough for that pointer type (and
5
between the given active node and the top node, but between the top node
5
thus cause a crash on dereference on some host architectures). Newer
6
and all of its parents.
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
7
9
There are a few places where the in-place swap function is
8
On completion, bdrv_drop_intermediate() must consider all parents for
10
used on something other than a packed struct field; we convert
9
updating the backing file link. These parents may be backing files
11
those anyway, for consistency.
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.
12
14
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
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.
14
17
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
---
19
block/vhdx.h | 12 ++---
20
block.c | 68 ++++++++++++++++++++++++++++++++++------------------------
20
block/vhdx-endian.c | 118 ++++++++++++++++++++++----------------------
21
block/commit.c | 2 +-
21
block/vhdx-log.c | 4 +-
22
2 files changed, 41 insertions(+), 29 deletions(-)
22
block/vhdx.c | 18 +++----
23
4 files changed, 76 insertions(+), 76 deletions(-)
24
23
25
diff --git a/block/vhdx.h b/block/vhdx.h
24
diff --git a/block.c b/block.c
26
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
27
--- a/block/vhdx.h
26
--- a/block.c
28
+++ b/block/vhdx.h
27
+++ b/block.c
29
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
28
@@ -XXX,XX +XXX,XX @@ static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
30
29
const char *filename, Error **errp)
31
static inline void leguid_to_cpus(MSGUID *guid)
32
{
30
{
33
- le32_to_cpus(&guid->data1);
31
BlockDriverState *parent = c->opaque;
34
- le16_to_cpus(&guid->data2);
32
+ int orig_flags = bdrv_get_flags(parent);
35
- le16_to_cpus(&guid->data3);
33
int ret;
36
+ guid->data1 = le32_to_cpu(guid->data1);
34
37
+ guid->data2 = le16_to_cpu(guid->data2);
35
+ if (!(orig_flags & BDRV_O_RDWR)) {
38
+ guid->data3 = le16_to_cpu(guid->data3);
36
+ ret = bdrv_reopen(parent, orig_flags | BDRV_O_RDWR, errp);
37
+ if (ret < 0) {
38
+ return ret;
39
+ }
40
+ }
41
+
42
ret = bdrv_change_backing_file(parent, filename,
43
base->drv ? base->drv->format_name : "");
44
if (ret < 0) {
45
error_setg_errno(errp, ret, "Could not update backing file link");
46
}
47
48
+ if (!(orig_flags & BDRV_O_RDWR)) {
49
+ bdrv_reopen(parent, orig_flags, NULL);
50
+ }
51
+
52
return ret;
39
}
53
}
40
54
41
static inline void cpu_to_leguids(MSGUID *guid)
55
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs)
56
int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
57
BlockDriverState *base, const char *backing_file_str)
42
{
58
{
43
- cpu_to_le32s(&guid->data1);
59
- BlockDriverState *new_top_bs = NULL;
44
- cpu_to_le16s(&guid->data2);
60
+ BdrvChild *c, *next;
45
- cpu_to_le16s(&guid->data3);
61
Error *local_err = NULL;
46
+ guid->data1 = cpu_to_le32(guid->data1);
62
int ret = -EIO;
47
+ guid->data2 = cpu_to_le16(guid->data2);
63
48
+ guid->data3 = cpu_to_le16(guid->data3);
64
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
49
}
50
51
void vhdx_header_le_import(VHDXHeader *h);
52
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/block/vhdx-endian.c
55
+++ b/block/vhdx-endian.c
56
@@ -XXX,XX +XXX,XX @@ void vhdx_header_le_import(VHDXHeader *h)
57
{
58
assert(h != NULL);
59
60
- le32_to_cpus(&h->signature);
61
- le32_to_cpus(&h->checksum);
62
- le64_to_cpus(&h->sequence_number);
63
+ h->signature = le32_to_cpu(h->signature);
64
+ h->checksum = le32_to_cpu(h->checksum);
65
+ h->sequence_number = le64_to_cpu(h->sequence_number);
66
67
leguid_to_cpus(&h->file_write_guid);
68
leguid_to_cpus(&h->data_write_guid);
69
leguid_to_cpus(&h->log_guid);
70
71
- le16_to_cpus(&h->log_version);
72
- le16_to_cpus(&h->version);
73
- le32_to_cpus(&h->log_length);
74
- le64_to_cpus(&h->log_offset);
75
+ h->log_version = le16_to_cpu(h->log_version);
76
+ h->version = le16_to_cpu(h->version);
77
+ h->log_length = le32_to_cpu(h->log_length);
78
+ h->log_offset = le64_to_cpu(h->log_offset);
79
}
80
81
void vhdx_header_le_export(VHDXHeader *orig_h, VHDXHeader *new_h)
82
@@ -XXX,XX +XXX,XX @@ void vhdx_log_desc_le_import(VHDXLogDescriptor *d)
83
{
84
assert(d != NULL);
85
86
- le32_to_cpus(&d->signature);
87
- le64_to_cpus(&d->file_offset);
88
- le64_to_cpus(&d->sequence_number);
89
+ d->signature = le32_to_cpu(d->signature);
90
+ d->file_offset = le64_to_cpu(d->file_offset);
91
+ d->sequence_number = le64_to_cpu(d->sequence_number);
92
}
93
94
void vhdx_log_desc_le_export(VHDXLogDescriptor *d)
95
{
96
assert(d != NULL);
97
98
- cpu_to_le32s(&d->signature);
99
- cpu_to_le32s(&d->trailing_bytes);
100
- cpu_to_le64s(&d->leading_bytes);
101
- cpu_to_le64s(&d->file_offset);
102
- cpu_to_le64s(&d->sequence_number);
103
+ d->signature = cpu_to_le32(d->signature);
104
+ d->trailing_bytes = cpu_to_le32(d->trailing_bytes);
105
+ d->leading_bytes = cpu_to_le64(d->leading_bytes);
106
+ d->file_offset = cpu_to_le64(d->file_offset);
107
+ d->sequence_number = cpu_to_le64(d->sequence_number);
108
}
109
110
void vhdx_log_data_le_import(VHDXLogDataSector *d)
111
{
112
assert(d != NULL);
113
114
- le32_to_cpus(&d->data_signature);
115
- le32_to_cpus(&d->sequence_high);
116
- le32_to_cpus(&d->sequence_low);
117
+ d->data_signature = le32_to_cpu(d->data_signature);
118
+ d->sequence_high = le32_to_cpu(d->sequence_high);
119
+ d->sequence_low = le32_to_cpu(d->sequence_low);
120
}
121
122
void vhdx_log_data_le_export(VHDXLogDataSector *d)
123
{
124
assert(d != NULL);
125
126
- cpu_to_le32s(&d->data_signature);
127
- cpu_to_le32s(&d->sequence_high);
128
- cpu_to_le32s(&d->sequence_low);
129
+ d->data_signature = cpu_to_le32(d->data_signature);
130
+ d->sequence_high = cpu_to_le32(d->sequence_high);
131
+ d->sequence_low = cpu_to_le32(d->sequence_low);
132
}
133
134
void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr)
135
{
136
assert(hdr != NULL);
137
138
- le32_to_cpus(&hdr->signature);
139
- le32_to_cpus(&hdr->checksum);
140
- le32_to_cpus(&hdr->entry_length);
141
- le32_to_cpus(&hdr->tail);
142
- le64_to_cpus(&hdr->sequence_number);
143
- le32_to_cpus(&hdr->descriptor_count);
144
+ hdr->signature = le32_to_cpu(hdr->signature);
145
+ hdr->checksum = le32_to_cpu(hdr->checksum);
146
+ hdr->entry_length = le32_to_cpu(hdr->entry_length);
147
+ hdr->tail = le32_to_cpu(hdr->tail);
148
+ hdr->sequence_number = le64_to_cpu(hdr->sequence_number);
149
+ hdr->descriptor_count = le32_to_cpu(hdr->descriptor_count);
150
leguid_to_cpus(&hdr->log_guid);
151
- le64_to_cpus(&hdr->flushed_file_offset);
152
- le64_to_cpus(&hdr->last_file_offset);
153
+ hdr->flushed_file_offset = le64_to_cpu(hdr->flushed_file_offset);
154
+ hdr->last_file_offset = le64_to_cpu(hdr->last_file_offset);
155
}
156
157
void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr)
158
{
159
assert(hdr != NULL);
160
161
- cpu_to_le32s(&hdr->signature);
162
- cpu_to_le32s(&hdr->checksum);
163
- cpu_to_le32s(&hdr->entry_length);
164
- cpu_to_le32s(&hdr->tail);
165
- cpu_to_le64s(&hdr->sequence_number);
166
- cpu_to_le32s(&hdr->descriptor_count);
167
+ hdr->signature = cpu_to_le32(hdr->signature);
168
+ hdr->checksum = cpu_to_le32(hdr->checksum);
169
+ hdr->entry_length = cpu_to_le32(hdr->entry_length);
170
+ hdr->tail = cpu_to_le32(hdr->tail);
171
+ hdr->sequence_number = cpu_to_le64(hdr->sequence_number);
172
+ hdr->descriptor_count = cpu_to_le32(hdr->descriptor_count);
173
cpu_to_leguids(&hdr->log_guid);
174
- cpu_to_le64s(&hdr->flushed_file_offset);
175
- cpu_to_le64s(&hdr->last_file_offset);
176
+ hdr->flushed_file_offset = cpu_to_le64(hdr->flushed_file_offset);
177
+ hdr->last_file_offset = cpu_to_le64(hdr->last_file_offset);
178
}
179
180
181
@@ -XXX,XX +XXX,XX @@ void vhdx_region_header_le_import(VHDXRegionTableHeader *hdr)
182
{
183
assert(hdr != NULL);
184
185
- le32_to_cpus(&hdr->signature);
186
- le32_to_cpus(&hdr->checksum);
187
- le32_to_cpus(&hdr->entry_count);
188
+ hdr->signature = le32_to_cpu(hdr->signature);
189
+ hdr->checksum = le32_to_cpu(hdr->checksum);
190
+ hdr->entry_count = le32_to_cpu(hdr->entry_count);
191
}
192
193
void vhdx_region_header_le_export(VHDXRegionTableHeader *hdr)
194
{
195
assert(hdr != NULL);
196
197
- cpu_to_le32s(&hdr->signature);
198
- cpu_to_le32s(&hdr->checksum);
199
- cpu_to_le32s(&hdr->entry_count);
200
+ hdr->signature = cpu_to_le32(hdr->signature);
201
+ hdr->checksum = cpu_to_le32(hdr->checksum);
202
+ hdr->entry_count = cpu_to_le32(hdr->entry_count);
203
}
204
205
void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
206
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
207
assert(e != NULL);
208
209
leguid_to_cpus(&e->guid);
210
- le64_to_cpus(&e->file_offset);
211
- le32_to_cpus(&e->length);
212
- le32_to_cpus(&e->data_bits);
213
+ e->file_offset = le64_to_cpu(e->file_offset);
214
+ e->length = le32_to_cpu(e->length);
215
+ e->data_bits = le32_to_cpu(e->data_bits);
216
}
217
218
void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
219
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
220
assert(e != NULL);
221
222
cpu_to_leguids(&e->guid);
223
- cpu_to_le64s(&e->file_offset);
224
- cpu_to_le32s(&e->length);
225
- cpu_to_le32s(&e->data_bits);
226
+ e->file_offset = cpu_to_le64(e->file_offset);
227
+ e->length = cpu_to_le32(e->length);
228
+ e->data_bits = cpu_to_le32(e->data_bits);
229
}
230
231
232
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_header_le_import(VHDXMetadataTableHeader *hdr)
233
{
234
assert(hdr != NULL);
235
236
- le64_to_cpus(&hdr->signature);
237
- le16_to_cpus(&hdr->entry_count);
238
+ hdr->signature = le64_to_cpu(hdr->signature);
239
+ hdr->entry_count = le16_to_cpu(hdr->entry_count);
240
}
241
242
void vhdx_metadata_header_le_export(VHDXMetadataTableHeader *hdr)
243
{
244
assert(hdr != NULL);
245
246
- cpu_to_le64s(&hdr->signature);
247
- cpu_to_le16s(&hdr->entry_count);
248
+ hdr->signature = cpu_to_le64(hdr->signature);
249
+ hdr->entry_count = cpu_to_le16(hdr->entry_count);
250
}
251
252
void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
253
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
254
assert(e != NULL);
255
256
leguid_to_cpus(&e->item_id);
257
- le32_to_cpus(&e->offset);
258
- le32_to_cpus(&e->length);
259
- le32_to_cpus(&e->data_bits);
260
+ e->offset = le32_to_cpu(e->offset);
261
+ e->length = le32_to_cpu(e->length);
262
+ e->data_bits = le32_to_cpu(e->data_bits);
263
}
264
void vhdx_metadata_entry_le_export(VHDXMetadataTableEntry *e)
265
{
266
assert(e != NULL);
267
268
cpu_to_leguids(&e->item_id);
269
- cpu_to_le32s(&e->offset);
270
- cpu_to_le32s(&e->length);
271
- cpu_to_le32s(&e->data_bits);
272
+ e->offset = cpu_to_le32(e->offset);
273
+ e->length = cpu_to_le32(e->length);
274
+ e->data_bits = cpu_to_le32(e->data_bits);
275
}
276
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/vhdx-log.c
279
+++ b/block/vhdx-log.c
280
@@ -XXX,XX +XXX,XX @@ static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
281
/* 8 + 4084 + 4 = 4096, 1 log sector */
282
memcpy(&desc->leading_bytes, data, 8);
283
data += 8;
284
- cpu_to_le64s(&desc->leading_bytes);
285
+ desc->leading_bytes = cpu_to_le64(desc->leading_bytes);
286
memcpy(sector->data, data, 4084);
287
data += 4084;
288
memcpy(&desc->trailing_bytes, data, 4);
289
- cpu_to_le32s(&desc->trailing_bytes);
290
+ desc->trailing_bytes = cpu_to_le32(desc->trailing_bytes);
291
data += 4;
292
293
sector->sequence_high = (uint32_t) (seq >> 32);
294
diff --git a/block/vhdx.c b/block/vhdx.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/block/vhdx.c
297
+++ b/block/vhdx.c
298
@@ -XXX,XX +XXX,XX @@ uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
299
300
memset(buf + crc_offset, 0, sizeof(crc));
301
crc = crc32c(0xffffffff, buf, size);
302
- cpu_to_le32s(&crc);
303
+ crc = cpu_to_le32(crc);
304
memcpy(buf + crc_offset, &crc, sizeof(crc));
305
306
return crc;
307
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
308
goto exit;
65
goto exit;
309
}
66
}
310
67
311
- le32_to_cpus(&s->params.block_size);
68
- new_top_bs = bdrv_find_overlay(active, top);
312
- le32_to_cpus(&s->params.data_bits);
69
-
313
+ s->params.block_size = le32_to_cpu(s->params.block_size);
70
- if (new_top_bs == NULL) {
314
+ s->params.data_bits = le32_to_cpu(s->params.data_bits);
71
- /* we could not find the image above 'top', this is an error */
315
72
- goto exit;
316
73
- }
317
/* We now have the file parameters, so we can tell if this is a
74
-
318
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
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)) {
319
goto exit;
84
goto exit;
320
}
85
}
321
86
322
- le64_to_cpus(&s->virtual_disk_size);
87
/* success - we can delete the intermediate states, and link top->base */
323
- le32_to_cpus(&s->logical_sector_size);
88
- if (new_top_bs->backing->role->update_filename) {
324
- le32_to_cpus(&s->physical_sector_size);
89
- backing_file_str = backing_file_str ? backing_file_str : base->filename;
325
+ s->virtual_disk_size = le64_to_cpu(s->virtual_disk_size);
90
- ret = new_top_bs->backing->role->update_filename(new_top_bs->backing,
326
+ s->logical_sector_size = le32_to_cpu(s->logical_sector_size);
91
- base, backing_file_str,
327
+ s->physical_sector_size = le32_to_cpu(s->physical_sector_size);
92
- &local_err);
328
93
- if (ret < 0) {
329
if (s->params.block_size < VHDX_BLOCK_SIZE_MIN ||
94
- bdrv_set_backing_hd(new_top_bs, top, &error_abort);
330
s->params.block_size > VHDX_BLOCK_SIZE_MAX) {
95
+ backing_file_str = backing_file_str ? backing_file_str : base->filename;
331
@@ -XXX,XX +XXX,XX @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
96
+
332
/* endian convert, and verify populated BAT field file offsets against
97
+ QLIST_FOREACH_SAFE(c, &top->parents, next_parent, next) {
333
* region table and log entries */
98
+ /* Check whether we are allowed to switch c from top to base */
334
for (i = 0; i < s->bat_entries; i++) {
99
+ GSList *ignore_children = g_slist_prepend(NULL, c);
335
- le64_to_cpus(&s->bat[i]);
100
+ bdrv_check_update_perm(base, NULL, c->perm, c->shared_perm,
336
+ s->bat[i] = le64_to_cpu(s->bat[i]);
101
+ ignore_children, &local_err);
337
if (payblocks--) {
102
+ if (local_err) {
338
/* payload bat entries */
103
+ ret = -EPERM;
339
if ((s->bat[i] & VHDX_BAT_STATE_BIT_MASK) ==
104
+ error_report_err(local_err);
340
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_metadata(BlockBackend *blk,
105
goto exit;
341
mt_file_params->block_size = cpu_to_le32(block_size);
106
}
342
if (type == VHDX_TYPE_FIXED) {
107
- }
343
mt_file_params->data_bits |= VHDX_PARAMS_LEAVE_BLOCKS_ALLOCED;
108
+ g_slist_free(ignore_children);
344
- cpu_to_le32s(&mt_file_params->data_bits);
109
345
+ mt_file_params->data_bits = cpu_to_le32(mt_file_params->data_bits);
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);
346
}
131
}
347
132
348
vhdx_guid_generate(&mt_page83->page_83_data);
133
ret = 0;
349
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
134
diff --git a/block/commit.c b/block/commit.c
350
sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);
135
index XXXXXXX..XXXXXXX 100644
351
vhdx_update_bat_table_entry(blk_bs(blk), s, &sinfo, &unused, &unused,
136
--- a/block/commit.c
352
block_state);
137
+++ b/block/commit.c
353
- cpu_to_le64s(&s->bat[sinfo.bat_idx]);
138
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
354
+ s->bat[sinfo.bat_idx] = cpu_to_le64(s->bat[sinfo.bat_idx]);
139
error_propagate(errp, local_err);
355
sector_num += s->sectors_per_block;
140
goto fail;
356
}
141
}
357
ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
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;
358
--
147
--
359
2.19.1
148
2.13.6
360
149
361
150
diff view generated by jsdifflib
1
While we want machine interfaces like -blockdev and QMP blockdev-add to
1
QMP responses to certain commands can become quite long, which doesn't
2
add as little auto-detection as possible so that management tools are
2
only make reading them hard, but also means that the maximum line length
3
explicit about their needs, -drive is a convenience option for human
3
in patch emails can be exceeded. Allow tests to switch to QMP pretty
4
users. Enabling auto-read-only=on by default there enables users to use
4
printing, which results in more, but shorter lines.
5
read-only images for read-only guest devices without having to specify
5
6
read-only=on explicitly. If they try to attach the image to a read-write
6
We also need to make sure to keep indentation in the response for this
7
device, they will still get an error message.
7
to work as expected.
8
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
---
11
---
12
blockdev.c | 1 +
12
tests/qemu-iotests/common.qemu | 14 +++++++++++---
13
1 file changed, 1 insertion(+)
13
1 file changed, 11 insertions(+), 3 deletions(-)
14
14
15
diff --git a/blockdev.c b/blockdev.c
15
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/blockdev.c
17
--- a/tests/qemu-iotests/common.qemu
18
+++ b/blockdev.c
18
+++ b/tests/qemu-iotests/common.qemu
19
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
19
@@ -XXX,XX +XXX,XX @@ function _timed_wait_for()
20
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
20
shift
21
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
21
22
read_only ? "on" : "off");
22
QEMU_STATUS[$h]=0
23
+ qdict_set_default_str(bs_opts, BDRV_OPT_AUTO_READ_ONLY, "on");
23
- while read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
24
assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
24
+ while IFS= read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
25
25
do
26
if (runstate_check(RUN_STATE_INMIGRATE)) {
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++
27
--
66
--
28
2.19.1
67
2.13.6
29
68
30
69
diff view generated by jsdifflib
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Eric Blake <eblake@redhat.com>
3
---
2
---
4
tests/qemu-iotests/232 | 147 +++++++++++++++++++++++++++++++++++++
3
tests/qemu-iotests/191 | 153 +++++++++
5
tests/qemu-iotests/232.out | 59 +++++++++++++++
4
tests/qemu-iotests/191.out | 827 +++++++++++++++++++++++++++++++++++++++++++++
6
tests/qemu-iotests/group | 1 +
5
tests/qemu-iotests/group | 1 +
7
3 files changed, 207 insertions(+)
6
3 files changed, 981 insertions(+)
8
create mode 100755 tests/qemu-iotests/232
7
create mode 100755 tests/qemu-iotests/191
9
create mode 100644 tests/qemu-iotests/232.out
8
create mode 100644 tests/qemu-iotests/191.out
10
9
11
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
10
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
12
new file mode 100755
11
new file mode 100755
13
index XXXXXXX..XXXXXXX
12
index XXXXXXX..XXXXXXX
14
--- /dev/null
13
--- /dev/null
15
+++ b/tests/qemu-iotests/232
14
+++ b/tests/qemu-iotests/191
16
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
17
+#!/bin/bash
16
+#!/bin/bash
18
+#
17
+#
19
+# Test for auto-read-only
18
+# Test commit block job where top has two parents
20
+#
19
+#
21
+# Copyright (C) 2018 Red Hat, Inc.
20
+# Copyright (C) 2017 Red Hat, Inc.
22
+#
21
+#
23
+# This program is free software; you can redistribute it and/or modify
22
+# This program is free software; you can redistribute it and/or modify
24
+# it under the terms of the GNU General Public License as published by
23
+# it under the terms of the GNU General Public License as published by
25
+# the Free Software Foundation; either version 2 of the License, or
24
+# the Free Software Foundation; either version 2 of the License, or
26
+# (at your option) any later version.
25
+# (at your option) any later version.
...
...
39
+
38
+
40
+seq=`basename $0`
39
+seq=`basename $0`
41
+echo "QA output created by $seq"
40
+echo "QA output created by $seq"
42
+
41
+
43
+here=`pwd`
42
+here=`pwd`
44
+status=1    # failure is the default!
43
+status=1 # failure is the default!
44
+
45
+MIG_SOCKET="${TEST_DIR}/migrate"
45
+
46
+
46
+_cleanup()
47
+_cleanup()
47
+{
48
+{
49
+ rm -f "${TEST_IMG}.mid"
50
+ rm -f "${TEST_IMG}.ovl2"
51
+ rm -f "${TEST_IMG}.ovl3"
48
+ _cleanup_test_img
52
+ _cleanup_test_img
49
+ rm -f $TEST_IMG.snap
53
+ _cleanup_qemu
50
+}
54
+}
51
+trap "_cleanup; exit \$status" 0 1 2 3 15
55
+trap "_cleanup; exit \$status" 0 1 2 3 15
52
+
56
+
53
+# get standard environment, filters and checks
57
+# get standard environment, filters and checks
54
+. ./common.rc
58
+. ./common.rc
55
+. ./common.filter
59
+. ./common.filter
56
+
60
+. ./common.qemu
57
+_supported_fmt generic
61
+
62
+_supported_fmt qcow2
63
+_unsupported_imgopts compat=0.10
58
+_supported_proto file
64
+_supported_proto file
59
+_supported_os Linux
65
+_supported_os Linux
60
+
66
+
61
+function do_run_qemu()
67
+size=64M
62
+{
68
+
63
+ echo Testing: "$@"
69
+echo
64
+ (
70
+echo === Preparing and starting VM ===
65
+ if ! test -t 0; then
71
+echo
66
+ while read cmd; do
72
+
67
+ echo $cmd
73
+TEST_IMG="${TEST_IMG}.base" _make_test_img $size
68
+ done
74
+TEST_IMG="${TEST_IMG}.mid" _make_test_img -b "${TEST_IMG}.base"
69
+ fi
75
+_make_test_img -b "${TEST_IMG}.mid"
70
+ echo quit
76
+TEST_IMG="${TEST_IMG}.ovl2" _make_test_img -b "${TEST_IMG}.mid"
71
+ ) | $QEMU -nographic -monitor stdio -nodefaults "$@"
77
+
72
+ echo
78
+$QEMU_IO -c 'write -P 0x55 1M 64k' "${TEST_IMG}.mid" | _filter_qemu_io
73
+}
79
+
74
+
80
+qemu_comm_method="qmp"
75
+function run_qemu()
81
+qmp_pretty="y"
76
+{
82
+
77
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp |
83
+_launch_qemu \
78
+ _filter_generated_node_ids | _filter_imgfmt
84
+ -blockdev "driver=${IMGFMT},file.driver=file,file.filename=${TEST_IMG}.base,node-name=base" \
79
+}
85
+ -blockdev "driver=${IMGFMT},file.driver=file,file.filename=${TEST_IMG}.mid,node-name=mid,backing=base" \
80
+
86
+ -blockdev "driver=${IMGFMT},file.driver=file,file.filename=${TEST_IMG},node-name=top,backing=mid" \
81
+function run_qemu_info_block()
87
+ -blockdev "driver=${IMGFMT},file.driver=file,file.filename=${TEST_IMG}.ovl2,node-name=top2,backing=mid"
82
+{
88
+h=$QEMU_HANDLE
83
+ echo "info block -n" | run_qemu "$@" | grep -e "(file" -e "QEMU_PROG"
89
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" '^}'
84
+}
90
+
85
+
91
+echo
86
+size=128M
92
+echo === Perform commit job ===
87
+
93
+echo
88
+_make_test_img $size
94
+
89
+
95
+_send_qemu_cmd $h \
90
+echo
96
+ "{ 'execute': 'block-commit',
91
+echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
97
+ 'arguments': { 'job-id': 'commit0',
92
+echo
98
+ 'device': 'top',
93
+
99
+ 'base':'$TEST_IMG.base',
94
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
100
+ 'top': '$TEST_IMG.mid' } }" \
95
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
101
+ "BLOCK_JOB_COMPLETED"
96
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
102
+_send_qemu_cmd $h "" "^}"
97
+echo
103
+
98
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
104
+echo
99
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
105
+echo === Check that both top and top2 point to base now ===
100
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
106
+echo
101
+echo
107
+
102
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
108
+_send_qemu_cmd $h "{ 'execute': 'query-named-block-nodes' }" "^}" |
103
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
109
+ _filter_generated_node_ids
104
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
110
+
105
+
111
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "^}"
106
+echo
112
+wait=1 _cleanup_qemu
107
+echo "=== -drive with read-only image: read-only/auto-read-only combinations ==="
113
+
108
+echo
114
+_img_info
109
+
115
+TEST_IMG="$TEST_IMG.ovl2" _img_info
110
+chmod a-w $TEST_IMG
116
+
111
+
117
+
112
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
118
+echo
113
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
119
+echo === Preparing and starting VM with -drive ===
114
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
120
+echo
115
+echo
121
+
116
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
122
+TEST_IMG="${TEST_IMG}.base" _make_test_img $size
117
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
123
+TEST_IMG="${TEST_IMG}.mid" _make_test_img -b "${TEST_IMG}.base"
118
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
124
+_make_test_img -b "${TEST_IMG}.mid"
119
+echo
125
+TEST_IMG="${TEST_IMG}.ovl2" _make_test_img -b "${TEST_IMG}.mid"
120
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
126
+TEST_IMG="${TEST_IMG}.ovl3" _make_test_img -b "${TEST_IMG}.ovl2"
121
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
127
+
122
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
128
+$QEMU_IO -c 'write -P 0x55 1M 64k' "${TEST_IMG}.mid" | _filter_qemu_io
123
+
129
+
124
+echo
130
+qemu_comm_method="qmp"
125
+echo "=== -blockdev with read-write image: read-only/auto-read-only combinations ==="
131
+qmp_pretty="y"
126
+echo
132
+
127
+
133
+_launch_qemu \
128
+chmod a+w $TEST_IMG
134
+ -drive "driver=${IMGFMT},file=${TEST_IMG},node-name=top,backing.node-name=mid" \
129
+
135
+ -drive "driver=${IMGFMT},file=${TEST_IMG}.ovl3,node-name=top2,backing.backing=mid"
130
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
136
+h=$QEMU_HANDLE
131
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
137
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" '^}'
132
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
138
+
133
+echo
139
+echo
134
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
140
+echo === Perform commit job ===
135
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
141
+echo
136
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
142
+
137
+echo
143
+_send_qemu_cmd $h \
138
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
144
+ "{ 'execute': 'block-commit',
139
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
145
+ 'arguments': { 'job-id': 'commit0',
140
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
146
+ 'device': 'top',
141
+
147
+ 'base':'$TEST_IMG.base',
142
+echo
148
+ 'top': '$TEST_IMG.mid' } }" \
143
+echo "=== -blockdev with read-only image: read-only/auto-read-only combinations ==="
149
+ "BLOCK_JOB_COMPLETED"
144
+echo
150
+_send_qemu_cmd $h "" "^}"
145
+
151
+
146
+chmod a-w $TEST_IMG
152
+echo
147
+
153
+echo === Check that both top and top2 point to base now ===
148
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
154
+echo
149
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
155
+
150
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
156
+_send_qemu_cmd $h "{ 'execute': 'query-named-block-nodes' }" "^}" |
151
+echo
157
+ _filter_generated_node_ids
152
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
158
+
153
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
159
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "^}"
154
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
160
+wait=1 _cleanup_qemu
155
+echo
161
+
156
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
162
+_img_info
157
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
163
+TEST_IMG="$TEST_IMG.ovl2" _img_info
158
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
159
+
164
+
160
+# success, all done
165
+# success, all done
161
+echo "*** done"
166
+echo "*** done"
162
+rm -f $seq.full
167
+rm -f $seq.full
163
+status=0
168
+status=0
164
diff --git a/tests/qemu-iotests/232.out b/tests/qemu-iotests/232.out
169
diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
165
new file mode 100644
170
new file mode 100644
166
index XXXXXXX..XXXXXXX
171
index XXXXXXX..XXXXXXX
167
--- /dev/null
172
--- /dev/null
168
+++ b/tests/qemu-iotests/232.out
173
+++ b/tests/qemu-iotests/191.out
169
@@ -XXX,XX +XXX,XX @@
174
@@ -XXX,XX +XXX,XX @@
170
+QA output created by 232
175
+QA output created by 191
171
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
176
+
172
+
177
+=== Preparing and starting VM ===
173
+=== -drive with read-write image: read-only/auto-read-only combinations ===
178
+
174
+
179
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
175
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
180
+Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
176
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
181
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
177
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
182
+Formatting 'TEST_DIR/t.IMGFMT.ovl2', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
178
+
183
+wrote 65536/65536 bytes at offset 1048576
179
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
184
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
180
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
185
+{
181
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
186
+ "return": {
182
+
187
+ }
183
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
188
+}
184
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
189
+
185
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
190
+=== Perform commit job ===
186
+
191
+
187
+=== -drive with read-only image: read-only/auto-read-only combinations ===
192
+{
188
+
193
+ "return": {
189
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
194
+ }
190
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
195
+}
191
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
196
+{
192
+
197
+ "timestamp": {
193
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
198
+ "seconds": TIMESTAMP,
194
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
199
+ "microseconds": TIMESTAMP
195
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
200
+ },
196
+
201
+ "event": "BLOCK_JOB_COMPLETED",
197
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
202
+ "data": {
198
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
203
+ "device": "commit0",
199
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
204
+ "len": 67108864,
200
+
205
+ "offset": 67108864,
201
+=== -blockdev with read-write image: read-only/auto-read-only combinations ===
206
+ "speed": 0,
202
+
207
+ "type": "commit"
203
+node0: TEST_DIR/t.IMGFMT (file, read-only)
208
+ }
204
+node0: TEST_DIR/t.IMGFMT (file, read-only)
209
+}
205
+node0: TEST_DIR/t.IMGFMT (file, read-only)
210
+
206
+
211
+=== Check that both top and top2 point to base now ===
207
+node0: TEST_DIR/t.IMGFMT (file)
212
+
208
+node0: TEST_DIR/t.IMGFMT (file)
213
+{
209
+node0: TEST_DIR/t.IMGFMT (file)
214
+ "return": [
210
+
215
+ {
211
+node0: TEST_DIR/t.IMGFMT (file)
216
+ "iops_rd": 0,
212
+node0: TEST_DIR/t.IMGFMT (file)
217
+ "detect_zeroes": "off",
213
+node0: TEST_DIR/t.IMGFMT (file)
218
+ "image": {
214
+
219
+ "backing-image": {
215
+=== -blockdev with read-only image: read-only/auto-read-only combinations ===
220
+ "virtual-size": 67108864,
216
+
221
+ "filename": "TEST_DIR/t.qcow2.base",
217
+node0: TEST_DIR/t.IMGFMT (file, read-only)
222
+ "cluster-size": 65536,
218
+node0: TEST_DIR/t.IMGFMT (file, read-only)
223
+ "format": "qcow2",
219
+node0: TEST_DIR/t.IMGFMT (file, read-only)
224
+ "actual-size": 397312,
220
+
225
+ "format-specific": {
221
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
226
+ "type": "qcow2",
222
+node0: TEST_DIR/t.IMGFMT (file, read-only)
227
+ "data": {
223
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
228
+ "compat": "1.1",
224
+
229
+ "lazy-refcounts": false,
225
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
230
+ "refcount-bits": 16,
226
+node0: TEST_DIR/t.IMGFMT (file, read-only)
231
+ "corrupt": false
227
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
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
568
+virtual size: 64M (67108864 bytes)
569
+cluster_size: 65536
570
+backing file: TEST_DIR/t.IMGFMT.base
571
+backing file format: IMGFMT
572
+image: TEST_DIR/t.IMGFMT.ovl2
573
+file format: IMGFMT
574
+virtual size: 64M (67108864 bytes)
575
+cluster_size: 65536
576
+backing file: TEST_DIR/t.IMGFMT.base
577
+backing file format: IMGFMT
578
+
579
+=== Preparing and starting VM with -drive ===
580
+
581
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
582
+Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
583
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
584
+Formatting 'TEST_DIR/t.IMGFMT.ovl2', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
585
+Formatting 'TEST_DIR/t.IMGFMT.ovl3', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.ovl2
586
+wrote 65536/65536 bytes at offset 1048576
587
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
588
+{
589
+ "return": {
590
+ }
591
+}
592
+
593
+=== Perform commit job ===
594
+
595
+{
596
+ "return": {
597
+ }
598
+}
599
+{
600
+ "timestamp": {
601
+ "seconds": TIMESTAMP,
602
+ "microseconds": TIMESTAMP
603
+ },
604
+ "event": "BLOCK_JOB_COMPLETED",
605
+ "data": {
606
+ "device": "commit0",
607
+ "len": 67108864,
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
991
+virtual size: 64M (67108864 bytes)
992
+cluster_size: 65536
993
+backing file: TEST_DIR/t.IMGFMT.base
994
+backing file format: IMGFMT
995
+image: TEST_DIR/t.IMGFMT.ovl2
996
+file format: IMGFMT
997
+virtual size: 64M (67108864 bytes)
998
+cluster_size: 65536
999
+backing file: TEST_DIR/t.IMGFMT.base
1000
+backing file format: IMGFMT
228
+*** done
1001
+*** done
229
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
1002
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
230
index XXXXXXX..XXXXXXX 100644
1003
index XXXXXXX..XXXXXXX 100644
231
--- a/tests/qemu-iotests/group
1004
--- a/tests/qemu-iotests/group
232
+++ b/tests/qemu-iotests/group
1005
+++ b/tests/qemu-iotests/group
233
@@ -XXX,XX +XXX,XX @@
1006
@@ -XXX,XX +XXX,XX @@
234
227 auto quick
1007
188 rw auto quick
235
229 auto quick
1008
189 rw auto
236
231 auto quick
1009
190 rw auto quick
237
+232 auto quick
1010
+191 rw auto
1011
192 rw auto quick
1012
194 rw auto migration quick
1013
195 rw auto quick
238
--
1014
--
239
2.19.1
1015
2.13.6
240
1016
241
1017
diff view generated by jsdifflib
1
Some block drivers have traditionally changed their node to read-only
1
We don't need to make any assumptions about the graph layout above the
2
mode without asking the user. This behaviour has been marked deprecated
2
top node of the commit operation any more. Remove the use of
3
since 2.11, expecting users to provide an explicit read-only=on option.
3
bdrv_find_overlay() and related variables from the commit job code.
4
4
5
Now that we have auto-read-only=on, enable these drivers to make use of
5
bdrv_drop_intermediate() doesn't use the 'active' parameter any more, so
6
the option.
6
we can just drop it.
7
7
8
This is the only use of bdrv_set_read_only(), so we can make it a bit
8
The overlay node was previously added to the block job to get a
9
more specific and turn it into a bdrv_apply_auto_read_only() that is
9
BLK_PERM_GRAPH_MOD. We really need to respect those permissions in
10
more convenient for drivers to use.
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.
11
16
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
18
Reviewed-by: Eric Blake <eblake@redhat.com>
14
---
19
---
15
include/block/block.h | 3 ++-
20
include/block/block.h | 3 +--
16
block.c | 42 +++++++++++++++++++++++++++---------------
21
block.c | 6 +++--
17
block/bochs.c | 17 ++++++-----------
22
block/commit.c | 62 ++++++++++++--------------------------------------
18
block/cloop.c | 16 +++++-----------
23
tests/qemu-iotests/030 | 4 ----
19
block/dmg.c | 16 +++++-----------
24
4 files changed, 20 insertions(+), 55 deletions(-)
20
block/rbd.c | 15 ++++-----------
21
block/vvfat.c | 10 ++--------
22
7 files changed, 51 insertions(+), 68 deletions(-)
23
25
24
diff --git a/include/block/block.h b/include/block/block.h
26
diff --git a/include/block/block.h b/include/block/block.h
25
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block.h
28
--- a/include/block/block.h
27
+++ b/include/block/block.h
29
+++ b/include/block/block.h
28
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
30
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs);
29
bool bdrv_is_read_only(BlockDriverState *bs);
31
int bdrv_change_backing_file(BlockDriverState *bs,
30
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
32
const char *backing_file, const char *backing_fmt);
31
bool ignore_allow_rdw, Error **errp);
33
void bdrv_register(BlockDriver *bdrv);
32
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
34
-int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
33
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
35
- BlockDriverState *base,
34
+ Error **errp);
36
+int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
35
bool bdrv_is_writable(BlockDriverState *bs);
37
const char *backing_file_str);
36
bool bdrv_is_sg(BlockDriverState *bs);
38
BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
37
bool bdrv_is_inserted(BlockDriverState *bs);
39
BlockDriverState *bs);
38
diff --git a/block.c b/block.c
40
diff --git a/block.c b/block.c
39
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
40
--- a/block.c
42
--- a/block.c
41
+++ b/block.c
43
+++ b/block.c
42
@@ -XXX,XX +XXX,XX @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
44
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs)
43
return 0;
45
* if active == top, that is considered an error
46
*
47
*/
48
-int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
49
- BlockDriverState *base, const char *backing_file_str)
50
+int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
51
+ const char *backing_file_str)
52
{
53
BdrvChild *c, *next;
54
Error *local_err = NULL;
55
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
56
}
57
58
/* success - we can delete the intermediate states, and link top->base */
59
+ /* TODO Check graph modification op blockers (BLK_PERM_GRAPH_MOD) once
60
+ * we've figured out how they should work. */
61
backing_file_str = backing_file_str ? backing_file_str : base->filename;
62
63
QLIST_FOREACH_SAFE(c, &top->parents, next_parent, next) {
64
diff --git a/block/commit.c b/block/commit.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/block/commit.c
67
+++ b/block/commit.c
68
@@ -XXX,XX +XXX,XX @@ enum {
69
typedef struct CommitBlockJob {
70
BlockJob common;
71
RateLimit limit;
72
- BlockDriverState *active;
73
BlockDriverState *commit_top_bs;
74
BlockBackend *top;
75
BlockBackend *base;
76
BlockdevOnError on_error;
77
int base_flags;
78
- int orig_overlay_flags;
79
char *backing_file_str;
80
} CommitBlockJob;
81
82
@@ -XXX,XX +XXX,XX @@ static void commit_complete(BlockJob *job, void *opaque)
83
{
84
CommitBlockJob *s = container_of(job, CommitBlockJob, common);
85
CommitCompleteData *data = opaque;
86
- BlockDriverState *active = s->active;
87
BlockDriverState *top = blk_bs(s->top);
88
BlockDriverState *base = blk_bs(s->base);
89
- BlockDriverState *overlay_bs = bdrv_find_overlay(active, s->commit_top_bs);
90
+ BlockDriverState *commit_top_bs = s->commit_top_bs;
91
int ret = data->ret;
92
bool remove_commit_top_bs = false;
93
94
- /* Make sure overlay_bs and top stay around until bdrv_set_backing_hd() */
95
+ /* Make sure commit_top_bs and top stay around until bdrv_replace_node() */
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);
44
}
140
}
45
141
46
-/* TODO Remove (deprecated since 2.11)
142
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
47
- * Block drivers are not supposed to automatically change bs->read_only.
48
- * Instead, they should just check whether they can provide what the user
49
- * explicitly requested and error out if read-write is requested, but they can
50
- * only provide read-only access. */
51
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
52
+/*
53
+ * Called by a driver that can only provide a read-only image.
54
+ *
55
+ * Returns 0 if the node is already read-only or it could switch the node to
56
+ * read-only because BDRV_O_AUTO_RDONLY is set.
57
+ *
58
+ * Returns -EACCES if the node is read-write and BDRV_O_AUTO_RDONLY is not set
59
+ * or bdrv_can_set_read_only() forbids making the node read-only. If @errmsg
60
+ * is not NULL, it is used as the error message for the Error object.
61
+ */
62
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
63
+ Error **errp)
64
{
143
{
65
int ret = 0;
144
CommitBlockJob *s;
66
145
BlockReopenQueue *reopen_queue = NULL;
67
- ret = bdrv_can_set_read_only(bs, read_only, false, errp);
146
- int orig_overlay_flags;
147
int orig_base_flags;
148
BlockDriverState *iter;
149
- BlockDriverState *overlay_bs;
150
BlockDriverState *commit_top_bs = NULL;
151
Error *local_err = NULL;
152
int ret;
153
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
154
return;
155
}
156
157
- overlay_bs = bdrv_find_overlay(bs, top);
158
-
159
- if (overlay_bs == NULL) {
160
- error_setg(errp, "Could not find overlay image for %s:", top->filename);
161
- return;
162
- }
163
-
164
s = block_job_create(job_id, &commit_job_driver, bs, 0, BLK_PERM_ALL,
165
speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);
166
if (!s) {
167
return;
168
}
169
170
- orig_base_flags = bdrv_get_flags(base);
171
- orig_overlay_flags = bdrv_get_flags(overlay_bs);
172
-
173
- /* convert base & overlay_bs to r/w, if necessary */
174
+ /* convert base to r/w, if necessary */
175
+ orig_base_flags = bdrv_get_flags(base);
176
if (!(orig_base_flags & BDRV_O_RDWR)) {
177
reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,
178
orig_base_flags | BDRV_O_RDWR);
179
}
180
- if (!(orig_overlay_flags & BDRV_O_RDWR)) {
181
- reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,
182
- orig_overlay_flags | BDRV_O_RDWR);
183
- }
184
+
185
if (reopen_queue) {
186
bdrv_reopen_multiple(bdrv_get_aio_context(bs), reopen_queue, &local_err);
187
if (local_err != NULL) {
188
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
189
goto fail;
190
}
191
192
- /* overlay_bs must be blocked because it needs to be modified to
193
- * update the backing image string. */
194
- ret = block_job_add_bdrv(&s->common, "overlay of top", overlay_bs,
195
- BLK_PERM_GRAPH_MOD, BLK_PERM_ALL, errp);
68
- if (ret < 0) {
196
- if (ret < 0) {
69
- return ret;
197
- goto fail;
70
+ if (!(bs->open_flags & BDRV_O_RDWR)) {
198
- }
71
+ return 0;
199
-
72
+ }
200
s->base = blk_new(BLK_PERM_CONSISTENT_READ
73
+ if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
201
| BLK_PERM_WRITE
74
+ goto fail;
202
| BLK_PERM_RESIZE,
75
}
203
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
76
204
goto fail;
77
- bs->read_only = read_only;
205
}
78
-
206
79
- if (read_only) {
207
- s->active = bs;
80
- bs->open_flags &= ~BDRV_O_RDWR;
208
-
81
- } else {
209
- s->base_flags = orig_base_flags;
82
- bs->open_flags |= BDRV_O_RDWR;
210
- s->orig_overlay_flags = orig_overlay_flags;
83
+ ret = bdrv_can_set_read_only(bs, true, false, NULL);
211
-
84
+ if (ret < 0) {
212
+ s->base_flags = orig_base_flags;
85
+ goto fail;
213
s->backing_file_str = g_strdup(backing_file_str);
86
}
214
-
87
215
s->on_error = on_error;
88
+ bs->read_only = true;
216
89
+ bs->open_flags &= ~BDRV_O_RDWR;
217
trace_commit_start(bs, base, top, s);
90
+
218
@@ -XXX,XX +XXX,XX @@ fail:
91
return 0;
219
blk_unref(s->top);
92
+
220
}
93
+fail:
221
if (commit_top_bs) {
94
+ error_setg(errp, "%s", errmsg ?: "Image is read-only");
222
- bdrv_set_backing_hd(overlay_bs, top, &error_abort);
95
+ return -EACCES;
223
+ bdrv_replace_node(commit_top_bs, top, &error_abort);
224
}
225
block_job_early_fail(&s->common);
96
}
226
}
97
227
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
98
void bdrv_get_full_backing_filename_from_filename(const char *backed,
228
index XXXXXXX..XXXXXXX 100755
99
diff --git a/block/bochs.c b/block/bochs.c
229
--- a/tests/qemu-iotests/030
100
index XXXXXXX..XXXXXXX 100644
230
+++ b/tests/qemu-iotests/030
101
--- a/block/bochs.c
231
@@ -XXX,XX +XXX,XX @@ class TestParallelOps(iotests.QMPTestCase):
102
+++ b/block/bochs.c
232
result = self.vm.qmp('block-stream', device='node6', base=self.imgs[4], job_id='stream-node6-v2')
103
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
233
self.assert_qmp(result, 'error/class', 'GenericError')
104
struct bochs_header bochs;
234
105
int ret;
235
- # This fails because block-commit needs to block node6, the overlay of the 'top' image
106
236
- result = self.vm.qmp('block-stream', device='node7', base=self.imgs[5], job_id='stream-node6-v3')
107
+ /* No write support yet */
237
- self.assert_qmp(result, 'error/class', 'GenericError')
108
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
238
-
109
+ if (ret < 0) {
239
# This fails because block-commit currently blocks the active layer even if it's not used
110
+ return ret;
240
result = self.vm.qmp('block-stream', device='drive0', base=self.imgs[5], job_id='stream-drive0')
111
+ }
241
self.assert_qmp(result, 'error/class', 'GenericError')
112
+
113
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
114
false, errp);
115
if (!bs->file) {
116
return -EINVAL;
117
}
118
119
- if (!bdrv_is_read_only(bs)) {
120
- error_report("Opening bochs images without an explicit read-only=on "
121
- "option is deprecated. Future versions will refuse to "
122
- "open the image instead of automatically marking the "
123
- "image read-only.");
124
- ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
125
- if (ret < 0) {
126
- return ret;
127
- }
128
- }
129
-
130
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
131
if (ret < 0) {
132
return ret;
133
diff --git a/block/cloop.c b/block/cloop.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/block/cloop.c
136
+++ b/block/cloop.c
137
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
138
uint32_t offsets_size, max_compressed_block_size = 1, i;
139
int ret;
140
141
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
142
+ if (ret < 0) {
143
+ return ret;
144
+ }
145
+
146
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
147
false, errp);
148
if (!bs->file) {
149
return -EINVAL;
150
}
151
152
- if (!bdrv_is_read_only(bs)) {
153
- error_report("Opening cloop images without an explicit read-only=on "
154
- "option is deprecated. Future versions will refuse to "
155
- "open the image instead of automatically marking the "
156
- "image read-only.");
157
- ret = bdrv_set_read_only(bs, true, errp);
158
- if (ret < 0) {
159
- return ret;
160
- }
161
- }
162
-
163
/* read header */
164
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
165
if (ret < 0) {
166
diff --git a/block/dmg.c b/block/dmg.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/block/dmg.c
169
+++ b/block/dmg.c
170
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
171
int64_t offset;
172
int ret;
173
174
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
175
+ if (ret < 0) {
176
+ return ret;
177
+ }
178
+
179
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
180
false, errp);
181
if (!bs->file) {
182
return -EINVAL;
183
}
184
185
- if (!bdrv_is_read_only(bs)) {
186
- error_report("Opening dmg images without an explicit read-only=on "
187
- "option is deprecated. Future versions will refuse to "
188
- "open the image instead of automatically marking the "
189
- "image read-only.");
190
- ret = bdrv_set_read_only(bs, true, errp);
191
- if (ret < 0) {
192
- return ret;
193
- }
194
- }
195
-
196
block_module_load_one("dmg-bz2");
197
198
s->n_chunks = 0;
199
diff --git a/block/rbd.c b/block/rbd.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/block/rbd.c
202
+++ b/block/rbd.c
203
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
204
/* If we are using an rbd snapshot, we must be r/o, otherwise
205
* leave as-is */
206
if (s->snap != NULL) {
207
- if (!bdrv_is_read_only(bs)) {
208
- error_report("Opening rbd snapshots without an explicit "
209
- "read-only=on option is deprecated. Future versions "
210
- "will refuse to open the image instead of "
211
- "automatically marking the image read-only.");
212
- r = bdrv_set_read_only(bs, true, &local_err);
213
- if (r < 0) {
214
- rbd_close(s->image);
215
- error_propagate(errp, local_err);
216
- goto failed_open;
217
- }
218
+ r = bdrv_apply_auto_read_only(bs, "rbd snapshots are read-only", errp);
219
+ if (r < 0) {
220
+ rbd_close(s->image);
221
+ goto failed_open;
222
}
223
}
224
225
diff --git a/block/vvfat.c b/block/vvfat.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/block/vvfat.c
228
+++ b/block/vvfat.c
229
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
230
"Unable to set VVFAT to 'rw' when drive is read-only");
231
goto fail;
232
}
233
- } else if (!bdrv_is_read_only(bs)) {
234
- error_report("Opening non-rw vvfat images without an explicit "
235
- "read-only=on option is deprecated. Future versions "
236
- "will refuse to open the image instead of "
237
- "automatically marking the image read-only.");
238
- /* read only is the default for safety */
239
- ret = bdrv_set_read_only(bs, true, &local_err);
240
+ } else {
241
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
242
if (ret < 0) {
243
- error_propagate(errp, local_err);
244
goto fail;
245
}
246
}
247
--
242
--
248
2.19.1
243
2.13.6
249
244
250
245
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
If an expression is used to define DEFAULT_CLUSTER_SIZE, when compiled,
3
Make it easier to enable copy-on-read during iotests, by
4
it will be embedded as a literal expression in the binary (as the
4
exposing a new bool option to main and open.
5
default value) because it is stringified to mark the size of the default
6
value. Now this is fixed by using a defined number to define this value.
7
5
8
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
6
Signed-off-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Stefan Weil <sw@weilnetz.de>
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>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
---
12
block/vdi.c | 4 ++--
13
qemu-io.c | 15 ++++++++++++---
13
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 12 insertions(+), 3 deletions(-)
14
15
15
diff --git a/block/vdi.c b/block/vdi.c
16
diff --git a/qemu-io.c b/qemu-io.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/block/vdi.c
18
--- a/qemu-io.c
18
+++ b/block/vdi.c
19
+++ b/qemu-io.c
19
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void open_help(void)
20
#define BLOCK_OPT_STATIC "static"
21
" Opens a file for subsequent use by all of the other qemu-io commands.\n"
21
22
" -r, -- open file read-only\n"
22
#define SECTOR_SIZE 512
23
" -s, -- use snapshot file\n"
23
-#define DEFAULT_CLUSTER_SIZE (1 * MiB)
24
+" -C, -- use copy-on-read\n"
24
+#define DEFAULT_CLUSTER_SIZE S_1MiB
25
" -n, -- disable host cache, short for -t none\n"
25
26
" -U, -- force shared permissions\n"
26
#if defined(CONFIG_VDI_DEBUG)
27
" -k, -- use kernel AIO implementation (on Linux only)\n"
27
#define VDI_DEBUG 1
28
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t open_cmd = {
28
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
29
.argmin = 1,
29
goto fail;
30
.argmax = -1,
30
} else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
31
.flags = CMD_NOFILE_OK,
31
error_setg(errp, "unsupported VDI image (block size %" PRIu32
32
- .args = "[-rsnkU] [-t cache] [-d discard] [-o options] [path]",
32
- " is not %" PRIu64 ")",
33
+ .args = "[-rsCnkU] [-t cache] [-d discard] [-o options] [path]",
33
+ " is not %" PRIu32 ")",
34
.oneline = "open the file specified by path",
34
header.block_size, DEFAULT_CLUSTER_SIZE);
35
.help = open_help,
35
ret = -ENOTSUP;
36
};
36
goto fail;
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);
37
--
91
--
38
2.19.1
92
2.13.6
39
93
40
94
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
Handle a 0-length block status request up front, with a uniform
4
it might not be actually aligned enough for that pointer type (and
4
return value claiming the area is not allocated.
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
5
9
There are a few places where the in-place swap function is
6
Most callers don't pass a length of 0 to bdrv_get_block_status()
10
used on something other than a packed struct field; we convert
7
and friends; but it definitely happens with a 0-length read when
11
those anyway, for consistency.
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).
12
20
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
21
Signed-off-by: Eric Blake <eblake@redhat.com>
14
15
There are other places where we take the address of a packed member
16
in this file for other purposes than passing it to a byteswap
17
function (all the calls to qemu_uuid_*()); we leave those for now.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
24
---
23
block/vdi.c | 64 ++++++++++++++++++++++++++---------------------------
25
block/io.c | 4 ++++
24
1 file changed, 32 insertions(+), 32 deletions(-)
26
1 file changed, 4 insertions(+)
25
27
26
diff --git a/block/vdi.c b/block/vdi.c
28
diff --git a/block/io.c b/block/io.c
27
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
28
--- a/block/vdi.c
30
--- a/block/io.c
29
+++ b/block/vdi.c
31
+++ b/block/io.c
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
32
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
31
33
*pnum = 0;
32
static void vdi_header_to_cpu(VdiHeader *header)
34
return BDRV_BLOCK_EOF;
33
{
35
}
34
- le32_to_cpus(&header->signature);
36
+ if (!nb_sectors) {
35
- le32_to_cpus(&header->version);
37
+ *pnum = 0;
36
- le32_to_cpus(&header->header_size);
38
+ return 0;
37
- le32_to_cpus(&header->image_type);
39
+ }
38
- le32_to_cpus(&header->image_flags);
40
39
- le32_to_cpus(&header->offset_bmap);
41
n = total_sectors - sector_num;
40
- le32_to_cpus(&header->offset_data);
42
if (n < nb_sectors) {
41
- le32_to_cpus(&header->cylinders);
42
- le32_to_cpus(&header->heads);
43
- le32_to_cpus(&header->sectors);
44
- le32_to_cpus(&header->sector_size);
45
- le64_to_cpus(&header->disk_size);
46
- le32_to_cpus(&header->block_size);
47
- le32_to_cpus(&header->block_extra);
48
- le32_to_cpus(&header->blocks_in_image);
49
- le32_to_cpus(&header->blocks_allocated);
50
+ header->signature = le32_to_cpu(header->signature);
51
+ header->version = le32_to_cpu(header->version);
52
+ header->header_size = le32_to_cpu(header->header_size);
53
+ header->image_type = le32_to_cpu(header->image_type);
54
+ header->image_flags = le32_to_cpu(header->image_flags);
55
+ header->offset_bmap = le32_to_cpu(header->offset_bmap);
56
+ header->offset_data = le32_to_cpu(header->offset_data);
57
+ header->cylinders = le32_to_cpu(header->cylinders);
58
+ header->heads = le32_to_cpu(header->heads);
59
+ header->sectors = le32_to_cpu(header->sectors);
60
+ header->sector_size = le32_to_cpu(header->sector_size);
61
+ header->disk_size = le64_to_cpu(header->disk_size);
62
+ header->block_size = le32_to_cpu(header->block_size);
63
+ header->block_extra = le32_to_cpu(header->block_extra);
64
+ header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
65
+ header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
66
qemu_uuid_bswap(&header->uuid_image);
67
qemu_uuid_bswap(&header->uuid_last_snap);
68
qemu_uuid_bswap(&header->uuid_link);
69
@@ -XXX,XX +XXX,XX @@ static void vdi_header_to_cpu(VdiHeader *header)
70
71
static void vdi_header_to_le(VdiHeader *header)
72
{
73
- cpu_to_le32s(&header->signature);
74
- cpu_to_le32s(&header->version);
75
- cpu_to_le32s(&header->header_size);
76
- cpu_to_le32s(&header->image_type);
77
- cpu_to_le32s(&header->image_flags);
78
- cpu_to_le32s(&header->offset_bmap);
79
- cpu_to_le32s(&header->offset_data);
80
- cpu_to_le32s(&header->cylinders);
81
- cpu_to_le32s(&header->heads);
82
- cpu_to_le32s(&header->sectors);
83
- cpu_to_le32s(&header->sector_size);
84
- cpu_to_le64s(&header->disk_size);
85
- cpu_to_le32s(&header->block_size);
86
- cpu_to_le32s(&header->block_extra);
87
- cpu_to_le32s(&header->blocks_in_image);
88
- cpu_to_le32s(&header->blocks_allocated);
89
+ header->signature = cpu_to_le32(header->signature);
90
+ header->version = cpu_to_le32(header->version);
91
+ header->header_size = cpu_to_le32(header->header_size);
92
+ header->image_type = cpu_to_le32(header->image_type);
93
+ header->image_flags = cpu_to_le32(header->image_flags);
94
+ header->offset_bmap = cpu_to_le32(header->offset_bmap);
95
+ header->offset_data = cpu_to_le32(header->offset_data);
96
+ header->cylinders = cpu_to_le32(header->cylinders);
97
+ header->heads = cpu_to_le32(header->heads);
98
+ header->sectors = cpu_to_le32(header->sectors);
99
+ header->sector_size = cpu_to_le32(header->sector_size);
100
+ header->disk_size = cpu_to_le64(header->disk_size);
101
+ header->block_size = cpu_to_le32(header->block_size);
102
+ header->block_extra = cpu_to_le32(header->block_extra);
103
+ header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
104
+ header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
105
qemu_uuid_bswap(&header->uuid_image);
106
qemu_uuid_bswap(&header->uuid_last_snap);
107
qemu_uuid_bswap(&header->uuid_link);
108
--
43
--
109
2.19.1
44
2.13.6
110
45
111
46
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
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>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
29
---
6
tests/qemu-iotests/081 | 30 ++++++++++++++++++++++++++++++
30
tests/qemu-iotests/check | 10 ++++++++++
7
tests/qemu-iotests/081.out | 16 ++++++++++++++++
31
1 file changed, 10 insertions(+)
8
2 files changed, 46 insertions(+)
9
32
10
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
33
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
11
index XXXXXXX..XXXXXXX 100755
34
index XXXXXXX..XXXXXXX 100755
12
--- a/tests/qemu-iotests/081
35
--- a/tests/qemu-iotests/check
13
+++ b/tests/qemu-iotests/081
36
+++ b/tests/qemu-iotests/check
14
@@ -XXX,XX +XXX,XX @@ echo "== checking that quorum is broken =="
37
@@ -XXX,XX +XXX,XX @@ export VALGRIND_QEMU=
15
38
export IMGKEYSECRET=
16
$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
39
export IMGOPTSSYNTAX=false
17
40
18
+echo
41
+# Save current tty settings, since an aborting qemu call may leave things
19
+echo "== checking the blkverify mode with broken content =="
42
+# screwed up
43
+STTY_RESTORE=
44
+if test -t 0; then
45
+ STTY_RESTORE=$(stty -g)
46
+fi
20
+
47
+
21
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on"
48
for r
22
+quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
49
do
23
+quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
50
24
+quorum="$quorum,file.children.0.driver=raw"
51
@@ -XXX,XX +XXX,XX @@ END { if (NR > 0) {
25
+quorum="$quorum,file.children.1.driver=raw"
52
needwrap=false
26
+
53
fi
27
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
54
28
+
55
+ if test -n "$STTY_RESTORE"; then
29
+echo
56
+ stty $STTY_RESTORE
30
+echo "== writing the same data to both files =="
57
+ fi
31
+
58
rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time
32
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
59
rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts
33
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
60
rm -f $tmp.*
34
+
35
+echo
36
+echo "== checking the blkverify mode with valid content =="
37
+
38
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
39
+
40
+echo
41
+echo "== checking the blkverify mode with invalid settings =="
42
+
43
+quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
44
+quorum="$quorum,file.children.2.driver=raw"
45
+
46
+$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
47
+
48
# success, all done
49
echo "*** done"
50
rm -f $seq.full
51
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/081.out
54
+++ b/tests/qemu-iotests/081.out
55
@@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 0
56
57
== checking that quorum is broken ==
58
read failed: Input/output error
59
+
60
+== checking the blkverify mode with broken content ==
61
+quorum: offset=0 bytes=10485760 contents mismatch at offset 0
62
+
63
+== writing the same data to both files ==
64
+wrote 10485760/10485760 bytes at offset 0
65
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
66
+wrote 10485760/10485760 bytes at offset 0
67
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
68
+
69
+== checking the blkverify mode with valid content ==
70
+read 10485760/10485760 bytes at offset 0
71
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
72
+
73
+== checking the blkverify mode with invalid settings ==
74
+can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
75
*** done
76
--
61
--
77
2.19.1
62
2.13.6
78
63
79
64
diff view generated by jsdifflib
1
If a management application builds the block graph node by node, the
1
From: Eric Blake <eblake@redhat.com>
2
protocol layer doesn't inherit its read-only option from the format
3
layer any more, so it must be set explicitly.
4
2
5
Backing files should work on read-only storage, but at the same time, a
3
Make it possible to inject errors on writes performed during a
6
block job like commit should be able to reopen them read-write if they
4
read operation due to copy-on-read semantics.
7
are on read-write storage. However, without option inheritance, reopen
8
only changes the read-only option for the root node (typically the
9
format layer), but not the protocol layer, so reopening fails (the
10
format layer wants to get write permissions, but the protocol layer is
11
still read-only).
12
5
13
A simple workaround for the problem in the management tool would be to
6
Signed-off-by: Eric Blake <eblake@redhat.com>
14
open the protocol layer always read-write and to make only the format
7
Reviewed-by: Jeff Cody <jcody@redhat.com>
15
layer read-only for backing files. However, sometimes the file is
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
16
actually stored on read-only storage and we don't know whether the image
9
Reviewed-by: John Snow <jsnow@redhat.com>
17
can be opened read-write (for example, for NBD it depends on the server
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
18
we're trying to connect to). This adds an option that makes QEMU try to
19
open the image read-write, but allows it to degrade to a read-only mode
20
without returning an error.
21
22
The documentation for this option is consciously phrased in a way that
23
allows QEMU to switch to a better model eventually: Instead of trying
24
when the image is first opened, making the read-only flag dynamic and
25
changing it automatically whenever the first BLK_PERM_WRITE user is
26
attached or the last one is detached would be much more useful
27
behaviour.
28
29
Unfortunately, this more useful behaviour is also a lot harder to
30
implement, and libvirt needs a solution now before it can switch to
31
-blockdev, so let's start with this easier approach for now.
32
33
Instead of adding a new auto-read-only option, turning the existing
34
read-only into an enum (with a bool alternate for compatibility) was
35
considered, but it complicated the implementation to the point that it
36
didn't seem to be worth it.
37
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
39
Reviewed-by: Eric Blake <eblake@redhat.com>
40
---
12
---
41
qapi/block-core.json | 7 +++++++
13
qapi/block-core.json | 5 ++++-
42
include/block/block.h | 2 ++
14
block/io.c | 1 +
43
block.c | 17 +++++++++++++++++
15
2 files changed, 5 insertions(+), 1 deletion(-)
44
block/vvfat.c | 1 +
45
blockdev.c | 2 +-
46
5 files changed, 28 insertions(+), 1 deletion(-)
47
16
48
diff --git a/qapi/block-core.json b/qapi/block-core.json
17
diff --git a/qapi/block-core.json b/qapi/block-core.json
49
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
50
--- a/qapi/block-core.json
19
--- a/qapi/block-core.json
51
+++ b/qapi/block-core.json
20
+++ b/qapi/block-core.json
52
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
53
# either generally or in certain configurations. In this case,
22
#
54
# the default value does not work and the option must be
23
# @l1_shrink_free_l2_clusters: discard the l2 tables. (since 2.11)
55
# specified explicitly.
24
#
56
+# @auto-read-only: if true and @read-only is false, QEMU may automatically
25
+# @cor_write: a write due to copy-on-read (since 2.11)
57
+# decide not to open the image read-write as requested, but
26
+#
58
+# fall back to read-only instead (and switch between the modes
27
# Since: 2.9
59
+# later), e.g. depending on whether the image file is writable
28
##
60
+# or whether a writing user is attached to the node
29
{ 'enum': 'BlkdebugEvent', 'prefix': 'BLKDBG',
61
+# (default: false, since 3.1)
62
# @detect-zeroes: detect and optimize zero writes (Since 2.1)
63
# (default: off)
64
# @force-share: force share all permission on added nodes.
65
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@
66
'*discard': 'BlockdevDiscardOptions',
31
'flush_to_disk', 'pwritev_rmw_head', 'pwritev_rmw_after_head',
67
'*cache': 'BlockdevCacheOptions',
32
'pwritev_rmw_tail', 'pwritev_rmw_after_tail', 'pwritev',
68
'*read-only': 'bool',
33
'pwritev_zero', 'pwritev_done', 'empty_image_prepare',
69
+ '*auto-read-only': 'bool',
34
- 'l1_shrink_write_table', 'l1_shrink_free_l2_clusters' ] }
70
'*force-share': 'bool',
35
+ 'l1_shrink_write_table', 'l1_shrink_free_l2_clusters',
71
'*detect-zeroes': 'BlockdevDetectZeroesOptions' },
36
+ 'cor_write'] }
72
'discriminator': 'driver',
37
73
diff --git a/include/block/block.h b/include/block/block.h
38
##
39
# @BlkdebugInjectErrorOptions:
40
diff --git a/block/io.c b/block/io.c
74
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
75
--- a/include/block/block.h
42
--- a/block/io.c
76
+++ b/include/block/block.h
43
+++ b/block/io.c
77
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
44
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
78
select an appropriate protocol driver,
45
goto err;
79
ignoring the format layer */
80
#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
81
+#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening read-write fails */
82
83
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
84
85
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
86
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
87
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
88
#define BDRV_OPT_READ_ONLY "read-only"
89
+#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
90
#define BDRV_OPT_DISCARD "discard"
91
#define BDRV_OPT_FORCE_SHARE "force-share"
92
93
diff --git a/block.c b/block.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/block.c
96
+++ b/block.c
97
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
98
99
/* Inherit the read-only option from the parent if it's not set */
100
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
101
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_AUTO_READ_ONLY);
102
103
/* Our block drivers take care to send flushes and respect unmap policy,
104
* so we can default to enable both on lower layers regardless of the
105
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
106
107
/* backing files always opened read-only */
108
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
109
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
110
flags &= ~BDRV_O_COPY_ON_READ;
111
112
/* snapshot=on is handled on the top layer */
113
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
114
*flags |= BDRV_O_RDWR;
115
}
46
}
116
47
117
+ assert(qemu_opt_find(opts, BDRV_OPT_AUTO_READ_ONLY));
48
+ bdrv_debug_event(bs, BLKDBG_COR_WRITE);
118
+ if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
49
if (drv->bdrv_co_pwrite_zeroes &&
119
+ *flags |= BDRV_O_AUTO_RDONLY;
50
buffer_is_zero(bounce_buffer, iov.iov_len)) {
120
+ }
51
/* FIXME: Should we (perhaps conditionally) be setting
121
}
122
123
static void update_options_from_flags(QDict *options, int flags)
124
@@ -XXX,XX +XXX,XX @@ static void update_options_from_flags(QDict *options, int flags)
125
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
126
qdict_put_bool(options, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
127
}
128
+ if (!qdict_haskey(options, BDRV_OPT_AUTO_READ_ONLY)) {
129
+ qdict_put_bool(options, BDRV_OPT_AUTO_READ_ONLY,
130
+ flags & BDRV_O_AUTO_RDONLY);
131
+ }
132
}
133
134
static void bdrv_assign_node_name(BlockDriverState *bs,
135
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
136
.type = QEMU_OPT_BOOL,
137
.help = "Node is opened in read-only mode",
138
},
139
+ {
140
+ .name = BDRV_OPT_AUTO_READ_ONLY,
141
+ .type = QEMU_OPT_BOOL,
142
+ .help = "Node can become read-only if opening read-write fails",
143
+ },
144
{
145
.name = "detect-zeroes",
146
.type = QEMU_OPT_STRING,
147
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
148
qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
149
qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");
150
qdict_set_default_str(qdict, BDRV_OPT_READ_ONLY, "off");
151
+ qdict_set_default_str(qdict, BDRV_OPT_AUTO_READ_ONLY, "off");
152
+
153
}
154
155
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp);
156
diff --git a/block/vvfat.c b/block/vvfat.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/block/vvfat.c
159
+++ b/block/vvfat.c
160
@@ -XXX,XX +XXX,XX @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
161
int parent_flags, QDict *parent_options)
162
{
163
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
164
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
165
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
166
}
167
168
diff --git a/blockdev.c b/blockdev.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/blockdev.c
171
+++ b/blockdev.c
172
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
173
174
bdrv_flags = blk_get_open_flags_from_root_state(blk);
175
bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
176
- BDRV_O_PROTOCOL);
177
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
178
179
if (!has_read_only) {
180
read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
181
--
52
--
182
2.19.1
53
2.13.6
183
54
184
55
diff view generated by jsdifflib
New patch
1
1
From: Eric Blake <eblake@redhat.com>
2
3
Improve our braindead copy-on-read implementation. Pre-patch,
4
we have multiple issues:
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
28
Fix all of these issues by breaking up the action into a loop,
29
where each iteration is capped to sane limits. Also, querying
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
33
Note that the code has a telling comment that copy-on-read
34
should probably be a filter driver rather than a bolt-on hack
35
in io.c; but that remains a task for another day.
36
37
CC: qemu-stable@nongnu.org
38
Signed-off-by: Eric Blake <eblake@redhat.com>
39
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
40
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
41
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
42
---
43
block/io.c | 120 +++++++++++++++++++++++++++++++++++++++++--------------------
44
1 file changed, 82 insertions(+), 38 deletions(-)
45
46
diff --git a/block/io.c b/block/io.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/block/io.c
49
+++ b/block/io.c
50
@@ -XXX,XX +XXX,XX @@
51
52
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
53
54
+/* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */
55
+#define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
56
+
57
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
58
int64_t offset, int bytes, BdrvRequestFlags flags);
59
60
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
61
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
+ }
194
+
195
+ cluster_offset += pnum;
196
+ cluster_bytes -= pnum;
197
+ progress += pnum - skip_bytes;
198
+ skip_bytes = 0;
199
+ }
200
+ ret = 0;
201
202
err:
203
qemu_vfree(bounce_buffer);
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
--
225
2.13.6
226
227
diff view generated by jsdifflib
New patch
1
1
From: Eric Blake <eblake@redhat.com>
2
3
Add a test for qcow2 copy-on-read behavior, including exposure
4
for the just-fixed bugs.
5
6
The copy-on-read behavior is always to a qcow2 image, but the
7
test is careful to allow running with most image protocol/format
8
combos as the backing file being copied from (luks being the
9
exception, as it is harder to pass the right secret to all the
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>
32
---
33
tests/qemu-iotests/197 | 109 +++++++++++++++++++++++++++++++++++++++
34
tests/qemu-iotests/197.out | 26 ++++++++++
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
41
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
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
190
--- a/tests/qemu-iotests/common.filter
191
+++ b/tests/qemu-iotests/common.filter
192
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
193
sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
194
-e "s#$TEST_DIR#TEST_DIR#g" \
195
-e "s#$IMGFMT#IMGFMT#g" \
196
+ -e 's#nbd:127.0.0.1:10810#TEST_DIR/t.IMGFMT#g' \
197
-e "s# encryption=off##g" \
198
-e "s# cluster_size=[0-9]\\+##g" \
199
-e "s# table_size=[0-9]\\+##g" \
200
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
201
index XXXXXXX..XXXXXXX 100644
202
--- a/tests/qemu-iotests/group
203
+++ b/tests/qemu-iotests/group
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
--
210
2.13.6
211
212
diff view generated by jsdifflib
New patch
1
From: "Daniel P. Berrange" <berrange@redhat.com>
1
2
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
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
Reviewed-by: Alberto Garcia <berto@igalia.com>
2
3
While current encryption schemes all have a fixed sector size of
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>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
11
Message-id: 20170927125340.12360-3-berrange@redhat.com
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
---
13
---
4
block/vpc.c | 2 ++
14
crypto/blockpriv.h | 1 +
5
1 file changed, 2 insertions(+)
15
include/crypto/block.h | 15 +++++++++++++++
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(-)
6
20
7
diff --git a/block/vpc.c b/block/vpc.c
21
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
8
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
9
--- a/block/vpc.c
23
--- a/crypto/blockpriv.h
10
+++ b/block/vpc.c
24
+++ b/crypto/blockpriv.h
11
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
25
@@ -XXX,XX +XXX,XX @@ struct QCryptoBlock {
26
QCryptoHashAlgorithm kdfhash;
27
size_t niv;
28
uint64_t payload_offset; /* In bytes */
29
+ uint64_t sector_size; /* In bytes */
30
};
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
}
12
}
65
}
13
66
14
qemu_co_mutex_init(&s->lock);
67
+ block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
15
+ qemu_opts_del(opts);
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;
16
95
17
return 0;
96
return 0;
18
97
diff --git a/crypto/block.c b/crypto/block.c
19
fail:
98
index XXXXXXX..XXXXXXX 100644
20
+ qemu_opts_del(opts);
99
--- a/crypto/block.c
21
qemu_vfree(s->pagetable);
100
+++ b/crypto/block.c
22
#ifdef CACHE
101
@@ -XXX,XX +XXX,XX @@ uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block)
23
g_free(s->pageentry_u8);
102
}
103
104
105
+uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block)
106
+{
107
+ return block->sector_size;
108
+}
109
+
110
+
111
void qcrypto_block_free(QCryptoBlock *block)
112
{
113
if (!block) {
24
--
114
--
25
2.19.1
115
2.13.6
26
116
27
117
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the volume
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
read-write if we have the permissions, but instead of erroring out for
3
read-only volumes, just degrade to read-only.
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
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>
6
Reviewed-by: Eric Blake <eblake@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>
7
---
19
---
8
block/iscsi.c | 8 +++++---
20
block/crypto.c | 13 +++++++++----
9
1 file changed, 5 insertions(+), 3 deletions(-)
21
1 file changed, 9 insertions(+), 4 deletions(-)
10
22
11
diff --git a/block/iscsi.c b/block/iscsi.c
23
diff --git a/block/crypto.c b/block/crypto.c
12
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
13
--- a/block/iscsi.c
25
--- a/block/crypto.c
14
+++ b/block/iscsi.c
26
+++ b/block/crypto.c
15
@@ -XXX,XX +XXX,XX @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
27
@@ -XXX,XX +XXX,XX @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
16
/* Check the write protect flag of the LUN if we want to write */
28
PreallocMode prealloc, Error **errp)
17
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
29
{
18
iscsilun->write_protected) {
30
BlockCrypto *crypto = bs->opaque;
19
- error_setg(errp, "Cannot open a write protected LUN as read-write");
31
- size_t payload_offset =
20
- ret = -EACCES;
32
+ uint64_t payload_offset =
21
- goto out;
33
qcrypto_block_get_payload_offset(crypto->block);
22
+ ret = bdrv_apply_auto_read_only(bs, "LUN is write protected", errp);
34
+ assert(payload_offset < (INT64_MAX - offset));
23
+ if (ret < 0) {
35
24
+ goto out;
36
offset += payload_offset;
25
+ }
37
26
+ flags &= ~BDRV_O_RDWR;
38
@@ -XXX,XX +XXX,XX @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
27
}
39
uint8_t *cipher_data = NULL;
28
40
QEMUIOVector hd_qiov;
29
iscsi_readcapacity_sync(iscsilun, &local_err);
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
30
--
71
--
31
2.19.1
72
2.13.6
32
73
33
74
diff view generated by jsdifflib
New patch
1
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
3
Make the crypto driver implement the bdrv_co_preadv|pwritev
4
callbacks, and also use bdrv_co_preadv|pwritev for I/O
5
with the protocol driver beneath. This replaces sector based
6
I/O with byte based I/O, and allows us to stop assuming the
7
physical sector size matches the encryption sector size.
8
9
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
10
Message-id: 20170927125340.12360-5-berrange@redhat.com
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
block/crypto.c | 106 +++++++++++++++++++++++++++++----------------------------
16
1 file changed, 54 insertions(+), 52 deletions(-)
17
18
diff --git a/block/crypto.c b/block/crypto.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/crypto.c
21
+++ b/block/crypto.c
22
@@ -XXX,XX +XXX,XX @@ static void block_crypto_close(BlockDriverState *bs)
23
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
24
25
static coroutine_fn int
26
-block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
27
- int remaining_sectors, QEMUIOVector *qiov)
28
+block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
29
+ QEMUIOVector *qiov, int flags)
30
{
31
BlockCrypto *crypto = bs->opaque;
32
- int cur_nr_sectors; /* number of sectors in current iteration */
33
+ uint64_t cur_bytes; /* number of bytes in current iteration */
34
uint64_t bytes_done = 0;
35
uint8_t *cipher_data = NULL;
36
QEMUIOVector hd_qiov;
37
int ret = 0;
38
- uint64_t payload_offset =
39
- qcrypto_block_get_payload_offset(crypto->block) / 512;
40
- assert(payload_offset < (INT64_MAX / 512));
41
+ uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
42
+ uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
43
+ uint64_t sector_num = offset / sector_size;
44
+
45
+ assert(!flags);
46
+ assert(payload_offset < INT64_MAX);
47
+ assert(QEMU_IS_ALIGNED(offset, sector_size));
48
+ assert(QEMU_IS_ALIGNED(bytes, sector_size));
49
50
qemu_iovec_init(&hd_qiov, qiov->niov);
51
52
@@ -XXX,XX +XXX,XX @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
53
goto cleanup;
54
}
55
56
- while (remaining_sectors) {
57
- cur_nr_sectors = remaining_sectors;
58
-
59
- if (cur_nr_sectors > (BLOCK_CRYPTO_MAX_IO_SIZE / 512)) {
60
- cur_nr_sectors = (BLOCK_CRYPTO_MAX_IO_SIZE / 512);
61
- }
62
+ while (bytes) {
63
+ cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
64
65
qemu_iovec_reset(&hd_qiov);
66
- qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * 512);
67
+ qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
68
69
- ret = bdrv_co_readv(bs->file,
70
- payload_offset + sector_num,
71
- cur_nr_sectors, &hd_qiov);
72
+ ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
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
}
99
100
cleanup:
101
@@ -XXX,XX +XXX,XX @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
102
103
104
static coroutine_fn int
105
-block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
106
- int remaining_sectors, QEMUIOVector *qiov)
107
+block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
108
+ QEMUIOVector *qiov, int flags)
109
{
110
BlockCrypto *crypto = bs->opaque;
111
- int cur_nr_sectors; /* number of sectors in current iteration */
112
+ uint64_t cur_bytes; /* number of bytes in current iteration */
113
uint64_t bytes_done = 0;
114
uint8_t *cipher_data = NULL;
115
QEMUIOVector hd_qiov;
116
int ret = 0;
117
- uint64_t payload_offset =
118
- qcrypto_block_get_payload_offset(crypto->block) / 512;
119
- assert(payload_offset < (INT64_MAX / 512));
120
+ uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
121
+ uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
122
+ uint64_t sector_num = offset / sector_size;
123
+
124
+ assert(!flags);
125
+ assert(payload_offset < INT64_MAX);
126
+ assert(QEMU_IS_ALIGNED(offset, sector_size));
127
+ assert(QEMU_IS_ALIGNED(bytes, sector_size));
128
129
qemu_iovec_init(&hd_qiov, qiov->niov);
130
131
@@ -XXX,XX +XXX,XX @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
132
goto cleanup;
133
}
134
135
- while (remaining_sectors) {
136
- cur_nr_sectors = remaining_sectors;
137
+ while (bytes) {
138
+ cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
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
}
178
179
cleanup:
180
@@ -XXX,XX +XXX,XX @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
181
return ret;
182
}
183
184
+static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
185
+{
186
+ BlockCrypto *crypto = bs->opaque;
187
+ uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
188
+ bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
189
+}
190
+
191
192
static int64_t block_crypto_getlength(BlockDriverState *bs)
193
{
194
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_crypto_luks = {
195
.bdrv_truncate = block_crypto_truncate,
196
.create_opts = &block_crypto_create_opts_luks,
197
198
- .bdrv_co_readv = block_crypto_co_readv,
199
- .bdrv_co_writev = block_crypto_co_writev,
200
+ .bdrv_refresh_limits = block_crypto_refresh_limits,
201
+ .bdrv_co_preadv = block_crypto_co_preadv,
202
+ .bdrv_co_pwritev = block_crypto_co_pwritev,
203
.bdrv_getlength = block_crypto_getlength,
204
.bdrv_get_info = block_crypto_get_info_luks,
205
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
206
--
207
2.13.6
208
209
diff view generated by jsdifflib
1
From: Daniel P. Berrangé <berrange@redhat.com>
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
2
3
The qcow2 block driver expects to see a valid sector size even when it
3
Instead of sector offset, take the bytes offset when encrypting
4
has opened the crypto layer with QCRYPTO_BLOCK_OPEN_NO_IO.
4
or decrypting data.
5
5
6
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
6
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Message-id: 20170927125340.12360-6-berrange@redhat.com
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
11
---
10
crypto/block-qcow.c | 2 ++
12
crypto/blockpriv.h | 4 ++--
11
1 file changed, 2 insertions(+)
13
include/crypto/block.h | 14 ++++++++------
12
14
block/crypto.c | 12 ++++--------
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
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
189
index XXXXXXX..XXXXXXX 100644
190
--- a/block/qcow2-cluster.c
191
+++ b/block/qcow2-cluster.c
192
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
193
{
194
if (bytes && bs->encrypted) {
195
BDRVQcow2State *s = bs->opaque;
196
- int64_t sector = (s->crypt_physical_offset ?
197
+ int64_t offset = (s->crypt_physical_offset ?
198
(cluster_offset + offset_in_cluster) :
199
- (src_cluster_offset + offset_in_cluster))
200
- >> BDRV_SECTOR_BITS;
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
212
index XXXXXXX..XXXXXXX 100644
213
--- a/block/qcow2.c
214
+++ b/block/qcow2.c
215
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
216
if (qcrypto_block_decrypt(s->crypto,
217
(s->crypt_physical_offset ?
218
cluster_offset + offset_in_cluster :
219
- offset) >> BDRV_SECTOR_BITS,
220
+ offset),
221
cluster_data,
222
cur_bytes,
223
NULL) < 0) {
224
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
225
if (qcrypto_block_encrypt(s->crypto,
226
(s->crypt_physical_offset ?
227
cluster_offset + offset_in_cluster :
228
- offset) >> BDRV_SECTOR_BITS,
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
13
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
275
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
14
index XXXXXXX..XXXXXXX 100644
276
index XXXXXXX..XXXXXXX 100644
15
--- a/crypto/block-qcow.c
277
--- a/crypto/block-qcow.c
16
+++ b/crypto/block-qcow.c
278
+++ b/crypto/block-qcow.c
17
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block,
279
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_cleanup(QCryptoBlock *block)
18
Error **errp)
280
19
{
281
static int
20
if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
282
qcrypto_block_qcow_decrypt(QCryptoBlock *block,
21
+ block->sector_size = QCRYPTO_BLOCK_QCOW_SECTOR_SIZE;
283
- uint64_t startsector,
22
+ block->payload_offset = 0;
284
+ uint64_t offset,
23
return 0;
285
uint8_t *buf,
24
} else {
286
size_t len,
25
if (!options->u.qcow.key_secret) {
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
+
362
+ assert(QEMU_IS_ALIGNED(offset, sectorsize));
363
+ assert(QEMU_IS_ALIGNED(len, sectorsize));
364
365
iv = niv ? g_new0(uint8_t, niv) : NULL;
366
367
@@ -XXX,XX +XXX,XX @@ int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
368
size_t niv,
369
QCryptoIVGen *ivgen,
370
int sectorsize,
371
- uint64_t startsector,
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
+
381
+ assert(QEMU_IS_ALIGNED(offset, sectorsize));
382
+ assert(QEMU_IS_ALIGNED(len, sectorsize));
383
384
iv = niv ? g_new0(uint8_t, niv) : NULL;
385
26
--
386
--
27
2.19.1
387
2.13.6
28
388
29
389
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
read-write if we have the permissions, but instead of erroring out for
3
read-only files, just degrade to read-only.
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
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>
6
Reviewed-by: Eric Blake <eblake@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>
7
---
11
---
8
block/file-posix.c | 19 ++++++++++++++++---
12
block/crypto.c | 7 +++++--
9
1 file changed, 16 insertions(+), 3 deletions(-)
13
1 file changed, 5 insertions(+), 2 deletions(-)
10
14
11
diff --git a/block/file-posix.c b/block/file-posix.c
15
diff --git a/block/crypto.c b/block/crypto.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/block/file-posix.c
17
--- a/block/crypto.c
14
+++ b/block/file-posix.c
18
+++ b/block/crypto.c
15
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
19
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
16
20
return -EINVAL;
17
s->fd = -1;
21
}
18
fd = qemu_open(filename, s->open_flags, 0644);
22
19
- if (fd < 0) {
23
+ bs->supported_write_flags = BDRV_REQ_FUA &
20
- ret = -errno;
24
+ bs->file->bs->supported_write_flags;
21
- error_setg_errno(errp, errno, "Could not open '%s'", filename);
22
+ ret = fd < 0 ? -errno : 0;
23
+
25
+
24
+ if (ret == -EACCES || ret == -EROFS) {
26
opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
25
+ /* Try to degrade to read-only, but if it doesn't work, still use the
27
qemu_opts_absorb_qdict(opts, options, &local_err);
26
+ * normal error message. */
28
if (local_err) {
27
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
29
@@ -XXX,XX +XXX,XX @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
28
+ bdrv_flags &= ~BDRV_O_RDWR;
30
uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
29
+ raw_parse_flags(bdrv_flags, &s->open_flags);
31
uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
30
+ assert(!(s->open_flags & O_CREAT));
32
31
+ fd = qemu_open(filename, s->open_flags);
33
- assert(!flags);
32
+ ret = fd < 0 ? -errno : 0;
34
+ assert(!(flags & ~BDRV_REQ_FUA));
33
+ }
35
assert(payload_offset < INT64_MAX);
34
+ }
36
assert(QEMU_IS_ALIGNED(offset, sector_size));
35
+
37
assert(QEMU_IS_ALIGNED(bytes, sector_size));
36
+ if (ret < 0) {
38
@@ -XXX,XX +XXX,XX @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
37
+ error_setg_errno(errp, -ret, "Could not open '%s'", filename);
39
qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
38
if (ret == -EROFS) {
40
39
ret = -EACCES;
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;
40
}
46
}
41
--
47
--
42
2.19.1
48
2.13.6
43
49
44
50
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
read-write if we have the permissions, but instead of erroring out for
3
read-only files, just degrade to read-only.
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Backing may be zero after failed bdrv_attach_child in
6
Reviewed-by: Niels de Vos <ndevos@redhat.com>
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>
7
---
10
---
8
block/gluster.c | 12 ++++++++++--
11
block/mirror.c | 5 +++++
9
1 file changed, 10 insertions(+), 2 deletions(-)
12
1 file changed, 5 insertions(+)
10
13
11
diff --git a/block/gluster.c b/block/gluster.c
14
diff --git a/block/mirror.c b/block/mirror.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/block/gluster.c
16
--- a/block/mirror.c
14
+++ b/block/gluster.c
17
+++ b/block/mirror.c
15
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs,
16
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
19
17
20
static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs, QDict *opts)
18
s->fd = glfs_open(s->glfs, gconf->path, open_flags);
21
{
19
- if (!s->fd) {
22
+ if (bs->backing == NULL) {
20
- ret = -errno;
23
+ /* we can be here after failed bdrv_attach_child in
21
+ ret = s->fd ? 0 : -errno;
24
+ * bdrv_set_backing_hd */
22
+
25
+ return;
23
+ if (ret == -EACCES || ret == -EROFS) {
26
+ }
24
+ /* Try to degrade to read-only, but if it doesn't work, still use the
27
bdrv_refresh_filename(bs->backing->bs);
25
+ * normal error message. */
28
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
26
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
29
bs->backing->bs->filename);
27
+ open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
28
+ s->fd = glfs_open(s->glfs, gconf->path, open_flags);
29
+ ret = s->fd ? 0 : -errno;
30
+ }
31
}
32
33
s->supports_seek_data = qemu_gluster_test_seek(s->fd);
34
--
30
--
35
2.19.1
31
2.13.6
36
32
37
33
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Following the example of qemu_opts_print_help(), indent all entries in
3
do_run_qemu() in iotest 195 first applies _filter_imgfmt when printing
4
the list of character devices.
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.
5
15
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
17
Message-id: 20170927211334.3988-1-mreitz@redhat.com
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Reviewed-by: Eric Blake <eblake@redhat.com>
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
20
---
10
chardev/char.c | 2 +-
21
tests/qemu-iotests/195 | 7 ++++---
11
1 file changed, 1 insertion(+), 1 deletion(-)
22
1 file changed, 4 insertions(+), 3 deletions(-)
12
23
13
diff --git a/chardev/char.c b/chardev/char.c
24
diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100755
15
--- a/chardev/char.c
26
--- a/tests/qemu-iotests/195
16
+++ b/chardev/char.c
27
+++ b/tests/qemu-iotests/195
17
@@ -XXX,XX +XXX,XX @@ help_string_append(const char *name, void *opaque)
28
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
29
30
function do_run_qemu()
18
{
31
{
19
GString *str = opaque;
32
- echo Testing: "$@" | _filter_imgfmt
20
33
+ echo Testing: "$@"
21
- g_string_append_printf(str, "\n%s", name);
34
$QEMU -nographic -qmp-pretty stdio -serial none "$@"
22
+ g_string_append_printf(str, "\n %s", name);
35
echo
23
}
36
}
24
37
25
static const char *chardev_alias_translate(const char *name)
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
26
--
48
--
27
2.19.1
49
2.13.6
28
50
29
51
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
2
2
3
This doesn't have any practical effect at the moment because the
3
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
4
values of BDRV_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE and
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE are all the same (512 bytes), but
5
Reviewed-by: John Snow <jsnow@redhat.com>
6
future encryption methods could have different requirements.
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
7
Message-id: 20170929121613.25997-2-pbutsykin@virtuozzo.com
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
9
---
12
block/qcow2.c | 2 +-
10
block/qcow2.c | 4 ++--
13
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 2 insertions(+), 2 deletions(-)
14
12
15
diff --git a/block/qcow2.c b/block/qcow2.c
13
diff --git a/block/qcow2.c b/block/qcow2.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2.c
15
--- a/block/qcow2.c
18
+++ b/block/qcow2.c
16
+++ b/block/qcow2.c
19
@@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
20
18
if (old_file_size < 0) {
21
if (bs->encrypted) {
19
error_setg_errno(errp, -old_file_size,
22
/* Encryption works on a sector granularity */
20
"Failed to inquire current file length");
23
- bs->bl.request_alignment = BDRV_SECTOR_SIZE;
21
- return ret;
24
+ bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
22
+ return old_file_size;
25
}
23
}
26
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
24
27
bs->bl.pdiscard_alignment = s->cluster_size;
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,
28
--
35
--
29
2.19.1
36
2.13.6
30
37
31
38
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open a read-write NBD
1
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
2
connection if the server provides a read-write export, but instead of
3
erroring out for read-only exports, just degrade to read-only.
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Now after shrinking the image, at the end of the image file, there might be a
6
Reviewed-by: Eric Blake <eblake@redhat.com>
4
tail that probably will never be used. So we can find the last used cluster and
5
cut the tail.
6
7
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Message-id: 20170929121613.25997-3-pbutsykin@virtuozzo.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
11
---
8
block/nbd-client.c | 10 +++++-----
12
block/qcow2.h | 1 +
9
1 file changed, 5 insertions(+), 5 deletions(-)
13
block/qcow2-refcount.c | 22 ++++++++++++++++++++++
14
block/qcow2.c | 23 +++++++++++++++++++++++
15
3 files changed, 46 insertions(+)
10
16
11
diff --git a/block/nbd-client.c b/block/nbd-client.c
17
diff --git a/block/qcow2.h b/block/qcow2.h
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/block/nbd-client.c
19
--- a/block/qcow2.h
14
+++ b/block/nbd-client.c
20
+++ b/block/qcow2.h
15
@@ -XXX,XX +XXX,XX @@ int nbd_client_init(BlockDriverState *bs,
21
@@ -XXX,XX +XXX,XX @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
16
logout("Failed to negotiate with the NBD server\n");
22
BlockDriverAmendStatusCB *status_cb,
17
return ret;
23
void *cb_opaque, Error **errp);
18
}
24
int qcow2_shrink_reftable(BlockDriverState *bs);
19
- if (client->info.flags & NBD_FLAG_READ_ONLY &&
25
+int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
20
- !bdrv_is_read_only(bs)) {
26
21
- error_setg(errp,
27
/* qcow2-cluster.c functions */
22
- "request for write access conflicts with read-only export");
28
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
23
- return -EACCES;
29
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
24
+ if (client->info.flags & NBD_FLAG_READ_ONLY) {
30
index XXXXXXX..XXXXXXX 100644
25
+ ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
31
--- a/block/qcow2-refcount.c
32
+++ b/block/qcow2-refcount.c
33
@@ -XXX,XX +XXX,XX @@ out:
34
g_free(reftable_tmp);
35
return ret;
36
}
37
+
38
+int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size)
39
+{
40
+ BDRVQcow2State *s = bs->opaque;
41
+ int64_t i;
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);
26
+ if (ret < 0) {
46
+ if (ret < 0) {
47
+ fprintf(stderr, "Can't get refcount for cluster %" PRId64 ": %s\n",
48
+ i, strerror(-ret));
27
+ return ret;
49
+ return ret;
28
+ }
50
+ }
29
}
51
+ if (refcount > 0) {
30
if (client->info.flags & NBD_FLAG_SEND_FUA) {
52
+ return i;
31
bs->supported_write_flags = BDRV_REQ_FUA;
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
60
index XXXXXXX..XXXXXXX 100644
61
--- a/block/qcow2.c
62
+++ b/block/qcow2.c
63
@@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
64
new_l1_size = size_to_l1(s, offset);
65
66
if (offset < old_length) {
67
+ int64_t last_cluster, old_file_size;
68
if (prealloc != PREALLOC_MODE_OFF) {
69
error_setg(errp,
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;
74
}
75
+
76
+ old_file_size = bdrv_getlength(bs->file->bs);
77
+ if (old_file_size < 0) {
78
+ error_setg_errno(errp, -old_file_size,
79
+ "Failed to inquire current file length");
80
+ return old_file_size;
81
+ }
82
+ last_cluster = qcow2_get_last_cluster(bs, old_file_size);
83
+ if (last_cluster < 0) {
84
+ error_setg_errno(errp, -last_cluster,
85
+ "Failed to find the last cluster");
86
+ return last_cluster;
87
+ }
88
+ if ((last_cluster + 1) * s->cluster_size < old_file_size) {
89
+ ret = bdrv_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
90
+ PREALLOC_MODE_OFF, NULL);
91
+ if (ret < 0) {
92
+ warn_report("Failed to truncate the tail of the image: %s",
93
+ strerror(-ret));
94
+ ret = 0;
95
+ }
96
+ }
97
} else {
98
ret = qcow2_grow_l1_table(bs, new_l1_size, true);
99
if (ret < 0) {
32
--
100
--
33
2.19.1
101
2.13.6
34
102
35
103
diff view generated by jsdifflib
1
Commit e2b8247a322 introduced an error path in qemu_rbd_open() after
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
calling rbd_open(), but neglected to close the image again in this error
3
path. The error path should contain everything that the regular close
4
function qemu_rbd_close() contains.
5
2
6
This adds the missing rbd_close() call.
3
Backing may be zero after failed bdrv_append in mirror_start_job,
4
which leads to SIGSEGV.
7
5
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-id: 20170929152255.5431-1-vsementsov@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
9
---
11
block/rbd.c | 1 +
10
block/mirror.c | 4 ++++
12
1 file changed, 1 insertion(+)
11
1 file changed, 4 insertions(+)
13
12
14
diff --git a/block/rbd.c b/block/rbd.c
13
diff --git a/block/mirror.c b/block/mirror.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
15
--- a/block/mirror.c
17
+++ b/block/rbd.c
16
+++ b/block/mirror.c
18
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
17
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
19
"automatically marking the image read-only.");
18
20
r = bdrv_set_read_only(bs, true, &local_err);
19
static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
21
if (r < 0) {
20
{
22
+ rbd_close(s->image);
21
+ if (bs->backing == NULL) {
23
error_propagate(errp, local_err);
22
+ /* we can be here after failed bdrv_append in mirror_start_job */
24
goto failed_open;
23
+ return 0;
25
}
24
+ }
25
return bdrv_co_flush(bs->backing->bs);
26
}
27
26
--
28
--
27
2.19.1
29
2.13.6
28
30
29
31
diff view generated by jsdifflib