1
The following changes since commit 23919ddfd56135cad3cb468a8f54d5a595f024f4:
1
The following changes since commit 75ee62ac606bfc9eb59310b9446df3434bf6e8c2:
2
2
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20190827' into staging (2019-08-27 15:52:36 +0100)
3
Merge remote-tracking branch 'remotes/ehabkost-gl/tags/x86-next-pull-request' into staging (2020-12-17 18:53:36 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/XanClic/qemu.git tags/pull-block-2019-08-27
7
https://github.com/XanClic/qemu.git tags/pull-block-2020-12-18
8
8
9
for you to fetch changes up to bb043c056cffcc2f3ce88bfdaf2e76e455c09e2c:
9
for you to fetch changes up to 0e72078128229bf9efb542e396ab44bf91b91340:
10
10
11
iotests: Unify cache mode quoting (2019-08-27 19:48:44 +0200)
11
iotests: Fix _send_qemu_cmd with bash 5.1 (2020-12-18 12:47:38 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Block patches:
15
- qemu-io now accepts a file to read a write pattern from
15
- New block filter: preallocate (which, on writes beyond an image file's
16
- Ensure that raw files have their first block allocated so we can probe
16
end, allocates big chunks of data so that such post-EOF writes will
17
the O_DIRECT alignment if necessary
17
occur less frequently)
18
- Various fixes
18
- write-zeroes and block-status support for Quorum
19
- Implementation of truncate for the nvme block driver similarly to the
20
existing implementations for host block devices and iscsi devices
21
- Block layer refactoring: Drop the tighten_restrictions concept in the
22
block permission functions
23
- iotest fixes
19
24
20
----------------------------------------------------------------
25
----------------------------------------------------------------
21
Denis Plotnikov (1):
26
Alberto Garcia (2):
22
qemu-io: add pattern file for write command
27
quorum: Implement bdrv_co_block_status()
28
quorum: Implement bdrv_co_pwrite_zeroes()
23
29
24
Max Reitz (7):
30
Max Reitz (2):
25
iotests: Fix _filter_img_create()
31
iotests/102: Pass $QEMU_HANDLE to _send_qemu_cmd
26
vmdk: Use bdrv_dirname() for relative extent paths
32
iotests: Fix _send_qemu_cmd with bash 5.1
27
iotests: Keep testing broken relative extent paths
28
vmdk: Reject invalid compressed writes
29
iotests: Disable broken streamOptimized tests
30
iotests: Disable 110 for vmdk.twoGbMaxExtentSparse
31
iotests: Disable 126 for flat vmdk subformats
32
33
33
Nir Soffer (3):
34
Philippe Mathieu-Daudé (1):
34
block: posix: Always allocate the first block
35
block/nvme: Implement fake truncate() coroutine
35
iotests: Test allocate_first_block() with O_DIRECT
36
iotests: Unify cache mode quoting
37
36
38
Stefan Hajnoczi (1):
37
Vladimir Sementsov-Ogievskiy (25):
39
file-posix: fix request_alignment typo
38
block: add bdrv_refresh_perms() helper
39
block: bdrv_set_perm() drop redundant parameters.
40
block: bdrv_child_set_perm() drop redundant parameters.
41
block: drop tighten_restrictions
42
block: simplify comment to BDRV_REQ_SERIALISING
43
block/io.c: drop assertion on double waiting for request serialisation
44
block/io: split out bdrv_find_conflicting_request
45
block/io: bdrv_wait_serialising_requests_locked: drop extra bs arg
46
block: bdrv_mark_request_serialising: split non-waiting function
47
block: introduce BDRV_REQ_NO_WAIT flag
48
block: bdrv_check_perm(): process children anyway
49
block: introduce preallocate filter
50
qemu-io: add preallocate mode parameter for truncate command
51
iotests: qemu_io_silent: support --image-opts
52
iotests.py: execute_setup_common(): add required_fmts argument
53
iotests: add 298 to test new preallocate filter driver
54
scripts/simplebench: fix grammar: s/successed/succeeded/
55
scripts/simplebench: support iops
56
scripts/simplebench: use standard deviation for +- error
57
simplebench: rename ascii() to results_to_text()
58
simplebench: move results_to_text() into separate file
59
simplebench/results_to_text: improve view of the table
60
simplebench/results_to_text: add difference line to the table
61
simplebench/results_to_text: make executable
62
scripts/simplebench: add bench_prealloc.py
40
63
41
Thomas Huth (2):
64
docs/system/qemu-block-drivers.rst.inc | 26 ++
42
iotests: Check for enabled drivers before testing them
65
qapi/block-core.json | 20 +-
43
tests/check-block: Skip iotests when sanitizers are enabled
66
include/block/block.h | 20 +-
44
67
include/block/block_int.h | 3 +-
45
Vladimir Sementsov-Ogievskiy (1):
68
block.c | 185 +++-----
46
block: fix permission update in bdrv_replace_node
69
block/file-posix.c | 2 +-
47
70
block/io.c | 130 +++---
48
block.c | 5 +-
71
block/nvme.c | 24 ++
49
block/file-posix.c | 53 +++++++++-
72
block/preallocate.c | 559 +++++++++++++++++++++++++
50
block/vmdk.c | 64 ++++++++----
73
block/quorum.c | 88 +++-
51
qemu-io-cmds.c | 99 +++++++++++++++++--
74
qemu-io-cmds.c | 46 +-
52
tests/check-block.sh | 5 +
75
block/meson.build | 1 +
53
tests/qemu-iotests/002 | 1 +
76
scripts/simplebench/bench-example.py | 3 +-
54
tests/qemu-iotests/003 | 1 +
77
scripts/simplebench/bench_prealloc.py | 132 ++++++
55
tests/qemu-iotests/005 | 3 +-
78
scripts/simplebench/bench_write_req.py | 3 +-
56
tests/qemu-iotests/009 | 1 +
79
scripts/simplebench/results_to_text.py | 126 ++++++
57
tests/qemu-iotests/010 | 1 +
80
scripts/simplebench/simplebench.py | 66 ++-
58
tests/qemu-iotests/011 | 1 +
81
tests/qemu-iotests/085.out | 167 ++++++--
59
tests/qemu-iotests/017 | 3 +-
82
tests/qemu-iotests/094.out | 10 +-
60
tests/qemu-iotests/018 | 3 +-
83
tests/qemu-iotests/095.out | 4 +-
61
tests/qemu-iotests/019 | 3 +-
84
tests/qemu-iotests/102 | 2 +-
62
tests/qemu-iotests/020 | 3 +-
85
tests/qemu-iotests/102.out | 2 +-
63
tests/qemu-iotests/026 | 4 +-
86
tests/qemu-iotests/109.out | 88 +++-
64
tests/qemu-iotests/027 | 1 +
87
tests/qemu-iotests/117.out | 13 +-
65
tests/qemu-iotests/032 | 1 +
88
tests/qemu-iotests/127.out | 12 +-
66
tests/qemu-iotests/033 | 1 +
89
tests/qemu-iotests/140.out | 10 +-
67
tests/qemu-iotests/034 | 3 +-
90
tests/qemu-iotests/141.out | 128 ++++--
68
tests/qemu-iotests/037 | 3 +-
91
tests/qemu-iotests/143.out | 4 +-
69
tests/qemu-iotests/039 | 4 +-
92
tests/qemu-iotests/144.out | 28 +-
70
tests/qemu-iotests/052 | 2 +-
93
tests/qemu-iotests/153.out | 18 +-
71
tests/qemu-iotests/059 | 34 ++++++-
94
tests/qemu-iotests/156.out | 39 +-
72
tests/qemu-iotests/059.out | 26 +++--
95
tests/qemu-iotests/161.out | 18 +-
73
tests/qemu-iotests/063 | 3 +-
96
tests/qemu-iotests/173.out | 25 +-
74
tests/qemu-iotests/071 | 1 +
97
tests/qemu-iotests/182.out | 42 +-
75
tests/qemu-iotests/072 | 1 +
98
tests/qemu-iotests/183.out | 19 +-
76
tests/qemu-iotests/081 | 4 +-
99
tests/qemu-iotests/185.out | 45 +-
77
tests/qemu-iotests/091 | 4 +-
100
tests/qemu-iotests/191.out | 12 +-
78
tests/qemu-iotests/099 | 1 +
101
tests/qemu-iotests/223.out | 92 ++--
79
tests/qemu-iotests/105 | 3 +-
102
tests/qemu-iotests/229.out | 13 +-
80
tests/qemu-iotests/110 | 3 +-
103
tests/qemu-iotests/249.out | 16 +-
81
tests/qemu-iotests/120 | 1 +
104
tests/qemu-iotests/298 | 186 ++++++++
82
tests/qemu-iotests/126 | 2 +
105
tests/qemu-iotests/298.out | 5 +
83
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
106
tests/qemu-iotests/308.out | 103 ++++-
84
tests/qemu-iotests/150.out.raw | 12 +++
107
tests/qemu-iotests/312 | 159 +++++++
85
tests/qemu-iotests/162 | 4 +-
108
tests/qemu-iotests/312.out | 81 ++++
86
tests/qemu-iotests/175 | 47 +++++++--
109
tests/qemu-iotests/common.qemu | 11 +-
87
tests/qemu-iotests/175.out | 16 ++-
110
tests/qemu-iotests/group | 2 +
88
tests/qemu-iotests/178.out.qcow2 | 4 +-
111
tests/qemu-iotests/iotests.py | 16 +-
89
tests/qemu-iotests/184 | 1 +
112
48 files changed, 2357 insertions(+), 447 deletions(-)
90
tests/qemu-iotests/186 | 1 +
113
create mode 100644 block/preallocate.c
91
tests/qemu-iotests/197 | 1 +
114
create mode 100755 scripts/simplebench/bench_prealloc.py
92
tests/qemu-iotests/215 | 1 +
115
create mode 100755 scripts/simplebench/results_to_text.py
93
tests/qemu-iotests/221.out | 12 ++-
116
create mode 100644 tests/qemu-iotests/298
94
tests/qemu-iotests/251 | 1 +
117
create mode 100644 tests/qemu-iotests/298.out
95
tests/qemu-iotests/253.out | 12 ++-
118
create mode 100755 tests/qemu-iotests/312
96
tests/qemu-iotests/common.filter | 4 +-
119
create mode 100644 tests/qemu-iotests/312.out
97
tests/qemu-iotests/common.rc | 14 +++
98
50 files changed, 391 insertions(+), 87 deletions(-)
99
rename tests/qemu-iotests/{150.out => 150.out.qcow2} (100%)
100
create mode 100644 tests/qemu-iotests/150.out.raw
101
120
102
--
121
--
103
2.21.0
122
2.29.2
104
123
105
124
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
It is possible to enable only a subset of the block drivers with the
3
Make separate function for common pattern.
4
"--block-drv-rw-whitelist" option of the "configure" script. All other
5
drivers are marked as unusable (or only included as read-only with the
6
"--block-drv-ro-whitelist" option). If an iotest is now using such a
7
disabled block driver, it is failing - which is bad, since at least the
8
tests in the "auto" group should be able to deal with this situation.
9
Thus let's introduce a "_require_drivers" function that can be used by
10
the shell tests to check for the availability of certain drivers first,
11
and marks the test as "not run" if one of the drivers is missing.
12
4
13
This patch mainly targets the test in the "auto" group which should
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
never fail in such a case, but also improves some of the other tests
6
Message-Id: <20201106124241.16950-5-vsementsov@virtuozzo.com>
15
along the way. Note that we also assume that the "qcow2" and "file"
7
[mreitz: Squashed in
16
drivers are always available - otherwise it does not make sense to
8
https://lists.nongnu.org/archive/html/qemu-block/2020-11/msg00299.html]
17
run "make check-block" at all (which only tests with qcow2 by default).
18
19
Signed-off-by: Thomas Huth <thuth@redhat.com>
20
Message-id: 20190823133552.11680-1-thuth@redhat.com
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
---
10
---
23
tests/qemu-iotests/071 | 1 +
11
block.c | 61 +++++++++++++++++++++++++++++----------------------------
24
tests/qemu-iotests/081 | 4 +---
12
1 file changed, 31 insertions(+), 30 deletions(-)
25
tests/qemu-iotests/099 | 1 +
26
tests/qemu-iotests/120 | 1 +
27
tests/qemu-iotests/162 | 4 +---
28
tests/qemu-iotests/184 | 1 +
29
tests/qemu-iotests/186 | 1 +
30
tests/qemu-iotests/common.rc | 14 ++++++++++++++
31
8 files changed, 21 insertions(+), 6 deletions(-)
32
13
33
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
14
diff --git a/block.c b/block.c
34
index XXXXXXX..XXXXXXX 100755
15
index XXXXXXX..XXXXXXX 100644
35
--- a/tests/qemu-iotests/071
16
--- a/block.c
36
+++ b/tests/qemu-iotests/071
17
+++ b/block.c
37
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
18
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_abort_perm_update(BdrvChild *c)
38
19
bdrv_abort_perm_update(c->bs);
39
_supported_fmt qcow2
40
_supported_proto file
41
+_require_drivers blkdebug blkverify
42
43
do_run_qemu()
44
{
45
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
46
index XXXXXXX..XXXXXXX 100755
47
--- a/tests/qemu-iotests/081
48
+++ b/tests/qemu-iotests/081
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
50
_supported_fmt raw
51
_supported_proto file
52
_supported_os Linux
53
+_require_drivers quorum
54
55
do_run_qemu()
56
{
57
@@ -XXX,XX +XXX,XX @@ run_qemu()
58
| _filter_qemu_io | _filter_generated_node_ids
59
}
20
}
60
21
61
-test_quorum=$($QEMU_IMG --help|grep quorum)
22
+static int bdrv_refresh_perms(BlockDriverState *bs, bool *tighten_restrictions,
62
-[ "$test_quorum" = "" ] && _supported_fmt quorum
23
+ Error **errp)
63
-
64
quorum="driver=raw,file.driver=quorum,file.vote-threshold=2"
65
quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
66
quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
67
diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099
68
index XXXXXXX..XXXXXXX 100755
69
--- a/tests/qemu-iotests/099
70
+++ b/tests/qemu-iotests/099
71
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
72
_supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc
73
_supported_proto file
74
_supported_os Linux
75
+_require_drivers blkdebug blkverify
76
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
77
"subformat=twoGbMaxExtentSparse"
78
79
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
80
index XXXXXXX..XXXXXXX 100755
81
--- a/tests/qemu-iotests/120
82
+++ b/tests/qemu-iotests/120
83
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
84
_supported_fmt generic
85
_supported_proto file
86
_unsupported_fmt luks
87
+_require_drivers raw
88
89
_make_test_img 64M
90
91
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
92
index XXXXXXX..XXXXXXX 100755
93
--- a/tests/qemu-iotests/162
94
+++ b/tests/qemu-iotests/162
95
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
96
. ./common.filter
97
98
_supported_fmt generic
99
-
100
-test_ssh=$($QEMU_IMG --help | grep '^Supported formats:.* ssh\( \|$\)')
101
-[ "$test_ssh" = "" ] && _notrun "ssh support required"
102
+_require_drivers ssh
103
104
echo
105
echo '=== NBD ==='
106
diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184
107
index XXXXXXX..XXXXXXX 100755
108
--- a/tests/qemu-iotests/184
109
+++ b/tests/qemu-iotests/184
110
@@ -XXX,XX +XXX,XX @@ trap "exit \$status" 0 1 2 3 15
111
. ./common.filter
112
113
_supported_os Linux
114
+_require_drivers throttle
115
116
do_run_qemu()
117
{
118
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
119
index XXXXXXX..XXXXXXX 100755
120
--- a/tests/qemu-iotests/186
121
+++ b/tests/qemu-iotests/186
122
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
123
124
_supported_fmt qcow2
125
_supported_proto file
126
+_require_drivers null-co
127
128
if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
129
_notrun "Requires a PC machine"
130
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
131
index XXXXXXX..XXXXXXX 100644
132
--- a/tests/qemu-iotests/common.rc
133
+++ b/tests/qemu-iotests/common.rc
134
@@ -XXX,XX +XXX,XX @@ _require_command()
135
[ -x "$c" ] || _notrun "$1 utility required, skipped this test"
136
}
137
138
+# Check that a set of drivers has been whitelisted in the QEMU binary
139
+#
140
+_require_drivers()
141
+{
24
+{
142
+ available=$($QEMU -drive format=help | \
25
+ int ret;
143
+ sed -e '/Supported formats:/!d' -e 's/Supported formats://')
26
+ uint64_t perm, shared_perm;
144
+ for driver
27
+
145
+ do
28
+ bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
146
+ if ! echo "$available" | grep -q " $driver\( \|$\)"; then
29
+ ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL,
147
+ _notrun "$driver not available"
30
+ tighten_restrictions, errp);
148
+ fi
31
+ if (ret < 0) {
149
+ done
32
+ bdrv_abort_perm_update(bs);
33
+ return ret;
34
+ }
35
+ bdrv_set_perm(bs, perm, shared_perm);
36
+
37
+ return 0;
150
+}
38
+}
151
+
39
+
152
# make sure this script returns success
40
int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
153
true
41
Error **errp)
42
{
43
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
44
}
45
46
if (old_bs) {
47
- /* Update permissions for old node. This is guaranteed to succeed
48
- * because we're just taking a parent away, so we're loosening
49
- * restrictions. */
50
bool tighten_restrictions;
51
- int ret;
52
53
- bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm);
54
- ret = bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL,
55
- &tighten_restrictions, NULL);
56
+ /*
57
+ * Update permissions for old node. We're just taking a parent away, so
58
+ * we're loosening restrictions. Errors of permission update are not
59
+ * fatal in this case, ignore them.
60
+ */
61
+ bdrv_refresh_perms(old_bs, &tighten_restrictions, NULL);
62
assert(tighten_restrictions == false);
63
- if (ret < 0) {
64
- /* We only tried to loosen restrictions, so errors are not fatal */
65
- bdrv_abort_perm_update(old_bs);
66
- } else {
67
- bdrv_set_perm(old_bs, perm, shared_perm);
68
- }
69
70
/* When the parent requiring a non-default AioContext is removed, the
71
* node moves back to the main AioContext */
72
@@ -XXX,XX +XXX,XX @@ void bdrv_init_with_whitelist(void)
73
int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
74
{
75
BdrvChild *child, *parent;
76
- uint64_t perm, shared_perm;
77
Error *local_err = NULL;
78
int ret;
79
BdrvDirtyBitmap *bm;
80
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
81
*/
82
if (bs->open_flags & BDRV_O_INACTIVE) {
83
bs->open_flags &= ~BDRV_O_INACTIVE;
84
- bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
85
- ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, errp);
86
+ ret = bdrv_refresh_perms(bs, NULL, errp);
87
if (ret < 0) {
88
- bdrv_abort_perm_update(bs);
89
bs->open_flags |= BDRV_O_INACTIVE;
90
return ret;
91
}
92
- bdrv_set_perm(bs, perm, shared_perm);
93
94
if (bs->drv->bdrv_co_invalidate_cache) {
95
bs->drv->bdrv_co_invalidate_cache(bs, &local_err);
96
@@ -XXX,XX +XXX,XX @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
97
{
98
BdrvChild *child, *parent;
99
bool tighten_restrictions;
100
- uint64_t perm, shared_perm;
101
int ret;
102
103
if (!bs->drv) {
104
@@ -XXX,XX +XXX,XX @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
105
106
bs->open_flags |= BDRV_O_INACTIVE;
107
108
- /* Update permissions, they may differ for inactive nodes */
109
- bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
110
- ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL,
111
- &tighten_restrictions, NULL);
112
+ /*
113
+ * Update permissions, they may differ for inactive nodes.
114
+ * We only tried to loosen restrictions, so errors are not fatal, ignore
115
+ * them.
116
+ */
117
+ bdrv_refresh_perms(bs, &tighten_restrictions, NULL);
118
assert(tighten_restrictions == false);
119
- if (ret < 0) {
120
- /* We only tried to loosen restrictions, so errors are not fatal */
121
- bdrv_abort_perm_update(bs);
122
- } else {
123
- bdrv_set_perm(bs, perm, shared_perm);
124
- }
125
-
126
127
/* Recursively inactivate children */
128
QLIST_FOREACH(child, &bs->children, next) {
154
--
129
--
155
2.21.0
130
2.29.2
156
131
157
132
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
It's wrong to OR shared permissions. It may lead to crash on further
3
We should never set permissions other than cumulative permissions of
4
permission updates.
4
parents. During bdrv_reopen_multiple() we _check_ for synthetic
5
Also, no needs to consider previously calculated permissions, as at
5
permissions but when we do _set_ the graph is already updated.
6
this point we already bind all new parents and bdrv_get_cumulative_perm
6
Add an assertion to bdrv_reopen_multiple(), other cases are more
7
result is enough. So fix the bug by just set permissions by
7
obvious.
8
bdrv_get_cumulative_perm result.
9
10
Bug was introduced in long ago 234ac1a9025, in 2.9.
11
8
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Message-id: 20190824100740.61635-1-vsementsov@virtuozzo.com
10
Message-Id: <20201106124241.16950-6-vsementsov@virtuozzo.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
13
---
16
block.c | 5 ++---
14
block.c | 29 +++++++++++++++--------------
17
1 file changed, 2 insertions(+), 3 deletions(-)
15
1 file changed, 15 insertions(+), 14 deletions(-)
18
16
19
diff --git a/block.c b/block.c
17
diff --git a/block.c b/block.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/block.c
19
--- a/block.c
22
+++ b/block.c
20
+++ b/block.c
23
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
21
@@ -XXX,XX +XXX,XX @@ static void bdrv_abort_perm_update(BlockDriverState *bs)
22
}
23
}
24
25
-static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms,
26
- uint64_t cumulative_shared_perms)
27
+static void bdrv_set_perm(BlockDriverState *bs)
24
{
28
{
25
BdrvChild *c, *next;
29
+ uint64_t cumulative_perms, cumulative_shared_perms;
26
GSList *list = NULL, *p;
30
BlockDriver *drv = bs->drv;
27
- uint64_t old_perm, old_shared;
31
BdrvChild *c;
28
uint64_t perm = 0, shared = BLK_PERM_ALL;
32
29
int ret;
33
@@ -XXX,XX +XXX,XX @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms,
30
34
return;
31
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
35
}
36
37
+ bdrv_get_cumulative_perm(bs, &cumulative_perms, &cumulative_shared_perms);
38
+
39
/* Update this node */
40
if (drv->bdrv_set_perm) {
41
drv->bdrv_set_perm(bs, cumulative_perms, cumulative_shared_perms);
42
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
43
44
static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared)
45
{
46
- uint64_t cumulative_perms, cumulative_shared_perms;
47
-
48
c->has_backup_perm = false;
49
50
c->perm = perm;
51
c->shared_perm = shared;
52
53
- bdrv_get_cumulative_perm(c->bs, &cumulative_perms,
54
- &cumulative_shared_perms);
55
- bdrv_set_perm(c->bs, cumulative_perms, cumulative_shared_perms);
56
+ bdrv_set_perm(c->bs);
57
}
58
59
static void bdrv_child_abort_perm_update(BdrvChild *c)
60
@@ -XXX,XX +XXX,XX @@ static int bdrv_refresh_perms(BlockDriverState *bs, bool *tighten_restrictions,
61
bdrv_abort_perm_update(bs);
62
return ret;
63
}
64
- bdrv_set_perm(bs, perm, shared_perm);
65
+ bdrv_set_perm(bs);
66
67
return 0;
68
}
69
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
70
static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
71
{
72
BlockDriverState *old_bs = child->bs;
73
- uint64_t perm, shared_perm;
74
75
/* Asserts that child->frozen == false */
76
bdrv_replace_child_noperm(child, new_bs);
77
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
78
* restrictions.
79
*/
80
if (new_bs) {
81
- bdrv_get_cumulative_perm(new_bs, &perm, &shared_perm);
82
- bdrv_set_perm(new_bs, perm, shared_perm);
83
+ bdrv_set_perm(new_bs);
84
}
85
86
if (old_bs) {
87
@@ -XXX,XX +XXX,XX @@ cleanup_perm:
88
}
89
90
if (ret == 0) {
91
- bdrv_set_perm(state->bs, state->perm, state->shared_perm);
92
+ uint64_t perm, shared;
93
+
94
+ bdrv_get_cumulative_perm(state->bs, &perm, &shared);
95
+ assert(perm == state->perm);
96
+ assert(shared == state->shared_perm);
97
+
98
+ bdrv_set_perm(state->bs);
99
} else {
100
bdrv_abort_perm_update(state->bs);
101
if (state->replace_backing_bs && state->new_backing_bs) {
102
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_node_common(BlockDriverState *from,
32
bdrv_unref(from);
103
bdrv_unref(from);
33
}
104
}
34
105
35
- bdrv_get_cumulative_perm(to, &old_perm, &old_shared);
106
- bdrv_get_cumulative_perm(to, &perm, &shared);
36
- bdrv_set_perm(to, old_perm | perm, old_shared | shared);
107
- bdrv_set_perm(to, perm, shared);
37
+ bdrv_get_cumulative_perm(to, &perm, &shared);
108
+ bdrv_set_perm(to);
38
+ bdrv_set_perm(to, perm, shared);
39
109
40
out:
110
out:
41
g_slist_free(list);
111
g_slist_free(list);
42
--
112
--
43
2.21.0
113
2.29.2
44
114
45
115
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
We must set the permission used for _check_. Assert that we have
4
backup and drop extra arguments.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20201106124241.16950-7-vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
block.c | 15 ++++-----------
12
1 file changed, 4 insertions(+), 11 deletions(-)
13
14
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
17
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
19
GSList *ignore_children,
20
bool *tighten_restrictions, Error **errp);
21
static void bdrv_child_abort_perm_update(BdrvChild *c);
22
-static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
23
+static void bdrv_child_set_perm(BdrvChild *c);
24
25
typedef struct BlockReopenQueueEntry {
26
bool prepared;
27
@@ -XXX,XX +XXX,XX @@ static void bdrv_set_perm(BlockDriverState *bs)
28
29
/* Update all children */
30
QLIST_FOREACH(c, &bs->children, next) {
31
- uint64_t cur_perm, cur_shared;
32
- bdrv_child_perm(bs, c->bs, c, c->role, NULL,
33
- cumulative_perms, cumulative_shared_perms,
34
- &cur_perm, &cur_shared);
35
- bdrv_child_set_perm(c, cur_perm, cur_shared);
36
+ bdrv_child_set_perm(c);
37
}
38
}
39
40
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
41
return 0;
42
}
43
44
-static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared)
45
+static void bdrv_child_set_perm(BdrvChild *c)
46
{
47
c->has_backup_perm = false;
48
49
- c->perm = perm;
50
- c->shared_perm = shared;
51
-
52
bdrv_set_perm(c->bs);
53
}
54
55
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
56
return ret;
57
}
58
59
- bdrv_child_set_perm(c, perm, shared);
60
+ bdrv_child_set_perm(c);
61
62
return 0;
63
}
64
--
65
2.29.2
66
67
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
The only users of this thing are:
4
1. bdrv_child_try_set_perm, to ignore failures on loosen restrictions
5
2. assertion in bdrv_replace_child
6
3. assertion in bdrv_inactivate_recurse
7
8
Assertions are not enough reason for overcomplication the permission
9
update system. So, look at bdrv_child_try_set_perm.
10
11
We are interested in tighten_restrictions only on failure. But on
12
failure this field is not reliable: we may fail in the middle of
13
permission update, some nodes are not touched and we don't know should
14
their permissions be tighten or not. So, we rely on the fact that if we
15
loose restrictions on some node (or BdrvChild), we'll not tighten
16
restriction in the whole subtree as part of this update (assertions 2
17
and 3 rely on this fact as well). And, if we rely on this fact anyway,
18
we can just check it on top, and don't pass additional pointer through
19
the whole recursive infrastructure.
20
21
Note also, that further patches will fix real bugs in permission update
22
system, so now is good time to simplify it, as a help for further
23
refactorings.
24
25
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
26
Message-Id: <20201106124241.16950-8-vsementsov@virtuozzo.com>
27
[mreitz: Fixed rebase conflict]
28
Signed-off-by: Max Reitz <mreitz@redhat.com>
29
---
30
block.c | 89 +++++++++++----------------------------------------------
31
1 file changed, 17 insertions(+), 72 deletions(-)
32
33
diff --git a/block.c b/block.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block.c
36
+++ b/block.c
37
@@ -XXX,XX +XXX,XX @@ static int bdrv_fill_options(QDict **options, const char *filename,
38
39
static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
40
uint64_t perm, uint64_t shared,
41
- GSList *ignore_children,
42
- bool *tighten_restrictions, Error **errp);
43
+ GSList *ignore_children, Error **errp);
44
static void bdrv_child_abort_perm_update(BdrvChild *c);
45
static void bdrv_child_set_perm(BdrvChild *c);
46
47
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
48
* permissions of all its parents. This involves checking whether all necessary
49
* permission changes to child nodes can be performed.
50
*
51
- * Will set *tighten_restrictions to true if and only if new permissions have to
52
- * be taken or currently shared permissions are to be unshared. Otherwise,
53
- * errors are not fatal as long as the caller accepts that the restrictions
54
- * remain tighter than they need to be. The caller still has to abort the
55
- * transaction.
56
- * @tighten_restrictions cannot be used together with @q: When reopening, we may
57
- * encounter fatal errors even though no restrictions are to be tightened. For
58
- * example, changing a node from RW to RO will fail if the WRITE permission is
59
- * to be kept.
60
- *
61
* A call to this function must always be followed by a call to bdrv_set_perm()
62
* or bdrv_abort_perm_update().
63
*/
64
static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
65
uint64_t cumulative_perms,
66
uint64_t cumulative_shared_perms,
67
- GSList *ignore_children,
68
- bool *tighten_restrictions, Error **errp)
69
+ GSList *ignore_children, Error **errp)
70
{
71
BlockDriver *drv = bs->drv;
72
BdrvChild *c;
73
int ret;
74
75
- assert(!q || !tighten_restrictions);
76
-
77
- if (tighten_restrictions) {
78
- uint64_t current_perms, current_shared;
79
- uint64_t added_perms, removed_shared_perms;
80
-
81
- bdrv_get_cumulative_perm(bs, &current_perms, &current_shared);
82
-
83
- added_perms = cumulative_perms & ~current_perms;
84
- removed_shared_perms = current_shared & ~cumulative_shared_perms;
85
-
86
- *tighten_restrictions = added_perms || removed_shared_perms;
87
- }
88
-
89
/* Write permissions never work with read-only images */
90
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
91
!bdrv_is_writable_after_reopen(bs, q))
92
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
93
/* Check all children */
94
QLIST_FOREACH(c, &bs->children, next) {
95
uint64_t cur_perm, cur_shared;
96
- bool child_tighten_restr;
97
98
bdrv_child_perm(bs, c->bs, c, c->role, q,
99
cumulative_perms, cumulative_shared_perms,
100
&cur_perm, &cur_shared);
101
ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared, ignore_children,
102
- tighten_restrictions ? &child_tighten_restr
103
- : NULL,
104
errp);
105
- if (tighten_restrictions) {
106
- *tighten_restrictions |= child_tighten_restr;
107
- }
108
if (ret < 0) {
109
return ret;
110
}
111
@@ -XXX,XX +XXX,XX @@ char *bdrv_perm_names(uint64_t perm)
112
* set, the BdrvChild objects in this list are ignored in the calculations;
113
* this allows checking permission updates for an existing reference.
114
*
115
- * See bdrv_check_perm() for the semantics of @tighten_restrictions.
116
- *
117
* Needs to be followed by a call to either bdrv_set_perm() or
118
* bdrv_abort_perm_update(). */
119
static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
120
uint64_t new_used_perm,
121
uint64_t new_shared_perm,
122
GSList *ignore_children,
123
- bool *tighten_restrictions,
124
Error **errp)
125
{
126
BdrvChild *c;
127
uint64_t cumulative_perms = new_used_perm;
128
uint64_t cumulative_shared_perms = new_shared_perm;
129
130
- assert(!q || !tighten_restrictions);
131
132
/* There is no reason why anyone couldn't tolerate write_unchanged */
133
assert(new_shared_perm & BLK_PERM_WRITE_UNCHANGED);
134
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
135
char *user = bdrv_child_user_desc(c);
136
char *perm_names = bdrv_perm_names(new_used_perm & ~c->shared_perm);
137
138
- if (tighten_restrictions) {
139
- *tighten_restrictions = true;
140
- }
141
-
142
error_setg(errp, "Conflicts with use by %s as '%s', which does not "
143
"allow '%s' on %s",
144
user, c->name, perm_names, bdrv_get_node_name(c->bs));
145
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
146
char *user = bdrv_child_user_desc(c);
147
char *perm_names = bdrv_perm_names(c->perm & ~new_shared_perm);
148
149
- if (tighten_restrictions) {
150
- *tighten_restrictions = true;
151
- }
152
-
153
error_setg(errp, "Conflicts with use by %s as '%s', which uses "
154
"'%s' on %s",
155
user, c->name, perm_names, bdrv_get_node_name(c->bs));
156
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
157
}
158
159
return bdrv_check_perm(bs, q, cumulative_perms, cumulative_shared_perms,
160
- ignore_children, tighten_restrictions, errp);
161
+ ignore_children, errp);
162
}
163
164
/* Needs to be followed by a call to either bdrv_child_set_perm() or
165
* bdrv_child_abort_perm_update(). */
166
static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
167
uint64_t perm, uint64_t shared,
168
- GSList *ignore_children,
169
- bool *tighten_restrictions, Error **errp)
170
+ GSList *ignore_children, Error **errp)
171
{
172
int ret;
173
174
ignore_children = g_slist_prepend(g_slist_copy(ignore_children), c);
175
- ret = bdrv_check_update_perm(c->bs, q, perm, shared, ignore_children,
176
- tighten_restrictions, errp);
177
+ ret = bdrv_check_update_perm(c->bs, q, perm, shared, ignore_children, errp);
178
g_slist_free(ignore_children);
179
180
if (ret < 0) {
181
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_abort_perm_update(BdrvChild *c)
182
bdrv_abort_perm_update(c->bs);
183
}
184
185
-static int bdrv_refresh_perms(BlockDriverState *bs, bool *tighten_restrictions,
186
- Error **errp)
187
+static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
188
{
189
int ret;
190
uint64_t perm, shared_perm;
191
192
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
193
- ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL,
194
- tighten_restrictions, errp);
195
+ ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, errp);
196
if (ret < 0) {
197
bdrv_abort_perm_update(bs);
198
return ret;
199
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
200
{
201
Error *local_err = NULL;
202
int ret;
203
- bool tighten_restrictions;
204
205
- ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL,
206
- &tighten_restrictions, &local_err);
207
+ ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL, &local_err);
208
if (ret < 0) {
209
bdrv_child_abort_perm_update(c);
210
- if (tighten_restrictions) {
211
+ if ((perm & ~c->perm) || (c->shared_perm & ~shared)) {
212
+ /* tighten permissions */
213
error_propagate(errp, local_err);
214
} else {
215
/*
216
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
217
}
218
219
if (old_bs) {
220
- bool tighten_restrictions;
221
-
222
/*
223
* Update permissions for old node. We're just taking a parent away, so
224
* we're loosening restrictions. Errors of permission update are not
225
* fatal in this case, ignore them.
226
*/
227
- bdrv_refresh_perms(old_bs, &tighten_restrictions, NULL);
228
- assert(tighten_restrictions == false);
229
+ bdrv_refresh_perms(old_bs, NULL);
230
231
/* When the parent requiring a non-default AioContext is removed, the
232
* node moves back to the main AioContext */
233
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
234
Error *local_err = NULL;
235
int ret;
236
237
- ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, NULL,
238
- errp);
239
+ ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, errp);
240
if (ret < 0) {
241
bdrv_abort_perm_update(child_bs);
242
bdrv_unref(child_bs);
243
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
244
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
245
BDRVReopenState *state = &bs_entry->state;
246
ret = bdrv_check_perm(state->bs, bs_queue, state->perm,
247
- state->shared_perm, NULL, NULL, errp);
248
+ state->shared_perm, NULL, errp);
249
if (ret < 0) {
250
goto cleanup_perm;
251
}
252
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
253
bs_queue, state->perm, state->shared_perm,
254
&nperm, &nshared);
255
ret = bdrv_check_update_perm(state->new_backing_bs, NULL,
256
- nperm, nshared, NULL, NULL, errp);
257
+ nperm, nshared, NULL, errp);
258
if (ret < 0) {
259
goto cleanup_perm;
260
}
261
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_node_common(BlockDriverState *from,
262
263
/* Check whether the required permissions can be granted on @to, ignoring
264
* all BdrvChild in @list so that they can't block themselves. */
265
- ret = bdrv_check_update_perm(to, NULL, perm, shared, list, NULL, errp);
266
+ ret = bdrv_check_update_perm(to, NULL, perm, shared, list, errp);
267
if (ret < 0) {
268
bdrv_abort_perm_update(to);
269
goto out;
270
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
271
*/
272
if (bs->open_flags & BDRV_O_INACTIVE) {
273
bs->open_flags &= ~BDRV_O_INACTIVE;
274
- ret = bdrv_refresh_perms(bs, NULL, errp);
275
+ ret = bdrv_refresh_perms(bs, errp);
276
if (ret < 0) {
277
bs->open_flags |= BDRV_O_INACTIVE;
278
return ret;
279
@@ -XXX,XX +XXX,XX @@ static bool bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
280
static int bdrv_inactivate_recurse(BlockDriverState *bs)
281
{
282
BdrvChild *child, *parent;
283
- bool tighten_restrictions;
284
int ret;
285
286
if (!bs->drv) {
287
@@ -XXX,XX +XXX,XX @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
288
* We only tried to loosen restrictions, so errors are not fatal, ignore
289
* them.
290
*/
291
- bdrv_refresh_perms(bs, &tighten_restrictions, NULL);
292
- assert(tighten_restrictions == false);
293
+ bdrv_refresh_perms(bs, NULL);
294
295
/* Recursively inactivate children */
296
QLIST_FOREACH(child, &bs->children, next) {
297
--
298
2.29.2
299
300
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
1. BDRV_REQ_NO_SERIALISING doesn't exist already, don't mention it.
4
5
2. We are going to add one more user of BDRV_REQ_SERIALISING, so
6
comment about backup becomes a bit confusing here. The use case in
7
backup is documented in block/backup.c, so let's just drop
8
duplication here.
9
10
3. The fact that BDRV_REQ_SERIALISING is only for write requests is
11
omitted. Add a note.
12
13
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Reviewed-by: Alberto Garcia <berto@igalia.com>
16
Message-Id: <20201021145859.11201-2-vsementsov@virtuozzo.com>
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
---
19
include/block/block.h | 11 +----------
20
1 file changed, 1 insertion(+), 10 deletions(-)
21
22
diff --git a/include/block/block.h b/include/block/block.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/block/block.h
25
+++ b/include/block/block.h
26
@@ -XXX,XX +XXX,XX @@ typedef enum {
27
* content. */
28
BDRV_REQ_WRITE_UNCHANGED = 0x40,
29
30
- /*
31
- * BDRV_REQ_SERIALISING forces request serialisation for writes.
32
- * It is used to ensure that writes to the backing file of a backup process
33
- * target cannot race with a read of the backup target that defers to the
34
- * backing file.
35
- *
36
- * Note, that BDRV_REQ_SERIALISING is _not_ opposite in meaning to
37
- * BDRV_REQ_NO_SERIALISING. A more descriptive name for the latter might be
38
- * _DO_NOT_WAIT_FOR_SERIALISING, except that is too long.
39
- */
40
+ /* Forces request serialisation. Use only with write requests. */
41
BDRV_REQ_SERIALISING = 0x80,
42
43
/* Execute the request only if the operation can be offloaded or otherwise
44
--
45
2.29.2
46
47
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
The comments states, that on misaligned request we should have already
4
been waiting. But for bdrv_padding_rmw_read, we called
5
bdrv_mark_request_serialising with align = request_alignment, and now
6
we serialise with align = cluster_size. So we may have to wait again
7
with larger alignment.
8
9
Note, that the only user of BDRV_REQ_SERIALISING is backup which issues
10
cluster-aligned requests, so seems the assertion should not fire for
11
now. But it's wrong anyway.
12
13
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
15
Message-Id: <20201021145859.11201-3-vsementsov@virtuozzo.com>
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
17
---
18
block/io.c | 11 +----------
19
1 file changed, 1 insertion(+), 10 deletions(-)
20
21
diff --git a/block/io.c b/block/io.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/block/io.c
24
+++ b/block/io.c
25
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
26
BdrvTrackedRequest *req, int flags)
27
{
28
BlockDriverState *bs = child->bs;
29
- bool waited;
30
int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
31
32
if (bs->read_only) {
33
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
34
assert(!(flags & ~BDRV_REQ_MASK));
35
36
if (flags & BDRV_REQ_SERIALISING) {
37
- waited = bdrv_mark_request_serialising(req, bdrv_get_cluster_size(bs));
38
- /*
39
- * For a misaligned request we should have already waited earlier,
40
- * because we come after bdrv_padding_rmw_read which must be called
41
- * with the request already marked as serialising.
42
- */
43
- assert(!waited ||
44
- (req->offset == req->overlap_offset &&
45
- req->bytes == req->overlap_bytes));
46
+ bdrv_mark_request_serialising(req, bdrv_get_cluster_size(bs));
47
} else {
48
bdrv_wait_serialising_requests(req);
49
}
50
--
51
2.29.2
52
53
diff view generated by jsdifflib
1
This makes iotest 033 pass with e.g. subformat=monolithicFlat. It also
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
turns a former error in 059 into success.
3
2
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
To be reused in separate.
5
Message-id: 20190815153638.4600-3-mreitz@redhat.com
4
6
Reviewed-by: John Snow <jsnow@redhat.com>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Message-Id: <20201021145859.11201-4-vsementsov@virtuozzo.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
9
---
9
block/vmdk.c | 54 ++++++++++++++++++++++++--------------
10
block/io.c | 71 +++++++++++++++++++++++++++++++-----------------------
10
tests/qemu-iotests/059 | 7 +++--
11
1 file changed, 41 insertions(+), 30 deletions(-)
11
tests/qemu-iotests/059.out | 4 ++-
12
3 files changed, 42 insertions(+), 23 deletions(-)
13
12
14
diff --git a/block/vmdk.c b/block/vmdk.c
13
diff --git a/block/io.c b/block/io.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/block/vmdk.c
15
--- a/block/io.c
17
+++ b/block/vmdk.c
16
+++ b/block/io.c
18
@@ -XXX,XX +XXX,XX @@ static const char *next_line(const char *s)
17
@@ -XXX,XX +XXX,XX @@ static bool tracked_request_overlaps(BdrvTrackedRequest *req,
18
return true;
19
}
19
}
20
20
21
static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
21
+/* Called with self->bs->reqs_lock held */
22
- const char *desc_file_path, QDict *options,
22
+static BdrvTrackedRequest *
23
- Error **errp)
23
+bdrv_find_conflicting_request(BdrvTrackedRequest *self)
24
+ QDict *options, Error **errp)
24
+{
25
+ BdrvTrackedRequest *req;
26
+
27
+ QLIST_FOREACH(req, &self->bs->tracked_requests, list) {
28
+ if (req == self || (!req->serialising && !self->serialising)) {
29
+ continue;
30
+ }
31
+ if (tracked_request_overlaps(req, self->overlap_offset,
32
+ self->overlap_bytes))
33
+ {
34
+ /*
35
+ * Hitting this means there was a reentrant request, for
36
+ * example, a block driver issuing nested requests. This must
37
+ * never happen since it means deadlock.
38
+ */
39
+ assert(qemu_coroutine_self() != req->co);
40
+
41
+ /*
42
+ * If the request is already (indirectly) waiting for us, or
43
+ * will wait for us as soon as it wakes up, then just go on
44
+ * (instead of producing a deadlock in the former case).
45
+ */
46
+ if (!req->waiting_for) {
47
+ return req;
48
+ }
49
+ }
50
+ }
51
+
52
+ return NULL;
53
+}
54
+
55
static bool coroutine_fn
56
bdrv_wait_serialising_requests_locked(BlockDriverState *bs,
57
BdrvTrackedRequest *self)
25
{
58
{
26
int ret;
59
BdrvTrackedRequest *req;
27
int matches;
60
- bool retry;
28
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
61
bool waited = false;
29
const char *p, *np;
62
30
int64_t sectors = 0;
63
- do {
31
int64_t flat_offset;
64
- retry = false;
32
+ char *desc_file_dir = NULL;
65
- QLIST_FOREACH(req, &bs->tracked_requests, list) {
33
char *extent_path;
66
- if (req == self || (!req->serialising && !self->serialising)) {
34
BdrvChild *extent_file;
67
- continue;
35
BDRVVmdkState *s = bs->opaque;
68
- }
36
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
69
- if (tracked_request_overlaps(req, self->overlap_offset,
37
continue;
70
- self->overlap_bytes))
38
}
71
- {
39
72
- /* Hitting this means there was a reentrant request, for
40
- if (!path_is_absolute(fname) && !path_has_protocol(fname) &&
73
- * example, a block driver issuing nested requests. This must
41
- !desc_file_path[0])
74
- * never happen since it means deadlock.
42
- {
75
- */
43
- bdrv_refresh_filename(bs->file->bs);
76
- assert(qemu_coroutine_self() != req->co);
44
- error_setg(errp, "Cannot use relative extent paths with VMDK "
77
-
45
- "descriptor file '%s'", bs->file->bs->filename);
78
- /* If the request is already (indirectly) waiting for us, or
46
- return -EINVAL;
79
- * will wait for us as soon as it wakes up, then just go on
80
- * (instead of producing a deadlock in the former case). */
81
- if (!req->waiting_for) {
82
- self->waiting_for = req;
83
- qemu_co_queue_wait(&req->wait_queue, &bs->reqs_lock);
84
- self->waiting_for = NULL;
85
- retry = true;
86
- waited = true;
87
- break;
88
- }
89
- }
47
- }
90
- }
48
+ if (path_is_absolute(fname)) {
91
- } while (retry);
49
+ extent_path = g_strdup(fname);
92
+ while ((req = bdrv_find_conflicting_request(self))) {
50
+ } else {
93
+ self->waiting_for = req;
51
+ if (!desc_file_dir) {
94
+ qemu_co_queue_wait(&req->wait_queue, &bs->reqs_lock);
52
+ desc_file_dir = bdrv_dirname(bs->file->bs, errp);
95
+ self->waiting_for = NULL;
53
+ if (!desc_file_dir) {
96
+ waited = true;
54
+ bdrv_refresh_filename(bs->file->bs);
97
+ }
55
+ error_prepend(errp, "Cannot use relative paths with VMDK "
56
+ "descriptor file '%s': ",
57
+ bs->file->bs->filename);
58
+ ret = -EINVAL;
59
+ goto out;
60
+ }
61
+ }
62
63
- extent_path = path_combine(desc_file_path, fname);
64
+ extent_path = g_strconcat(desc_file_dir, fname, NULL);
65
+ }
66
67
ret = snprintf(extent_opt_prefix, 32, "extents.%d", s->num_extents);
68
assert(ret < 32);
69
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
70
g_free(extent_path);
71
if (local_err) {
72
error_propagate(errp, local_err);
73
- return -EINVAL;
74
+ ret = -EINVAL;
75
+ goto out;
76
}
77
78
/* save to extents array */
79
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
80
0, 0, 0, 0, 0, &extent, errp);
81
if (ret < 0) {
82
bdrv_unref_child(bs, extent_file);
83
- return ret;
84
+ goto out;
85
}
86
extent->flat_start_offset = flat_offset << 9;
87
} else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
88
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
89
g_free(buf);
90
if (ret) {
91
bdrv_unref_child(bs, extent_file);
92
- return ret;
93
+ goto out;
94
}
95
extent = &s->extents[s->num_extents - 1];
96
} else if (!strcmp(type, "SESPARSE")) {
97
ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
98
if (ret) {
99
bdrv_unref_child(bs, extent_file);
100
- return ret;
101
+ goto out;
102
}
103
extent = &s->extents[s->num_extents - 1];
104
} else {
105
error_setg(errp, "Unsupported extent type '%s'", type);
106
bdrv_unref_child(bs, extent_file);
107
- return -ENOTSUP;
108
+ ret = -ENOTSUP;
109
+ goto out;
110
}
111
extent->type = g_strdup(type);
112
}
113
- return 0;
114
+
98
+
115
+ ret = 0;
99
return waited;
116
+ goto out;
117
118
invalid:
119
np = next_line(p);
120
@@ -XXX,XX +XXX,XX @@ invalid:
121
np--;
122
}
123
error_setg(errp, "Invalid extent line: %.*s", (int)(np - p), p);
124
- return -EINVAL;
125
+ ret = -EINVAL;
126
+
127
+out:
128
+ g_free(desc_file_dir);
129
+ return ret;
130
}
100
}
131
101
132
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
133
@@ -XXX,XX +XXX,XX @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
134
}
135
s->create_type = g_strdup(ct);
136
s->desc_offset = 0;
137
- ret = vmdk_parse_extents(buf, bs, bs->file->bs->exact_filename, options,
138
- errp);
139
+ ret = vmdk_parse_extents(buf, bs, options, errp);
140
exit:
141
return ret;
142
}
143
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
144
index XXXXXXX..XXXXXXX 100755
145
--- a/tests/qemu-iotests/059
146
+++ b/tests/qemu-iotests/059
147
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2
148
149
echo
150
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
151
+# Should work, because bdrv_dirname() works fine with blkdebug
152
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
153
-$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" 2>&1 \
154
- | _filter_testdir | _filter_imgfmt
155
+$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
156
+ -c info \
157
+ 2>&1 \
158
+ | _filter_testdir | _filter_imgfmt | _filter_img_info
159
_cleanup_test_img
160
161
echo
162
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
163
index XXXXXXX..XXXXXXX 100644
164
--- a/tests/qemu-iotests/059.out
165
+++ b/tests/qemu-iotests/059.out
166
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
167
168
=== Testing monolithicFlat with internally generated JSON file name ===
169
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
170
-qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}'
171
+format name: IMGFMT
172
+cluster size: 0 bytes
173
+vm state offset: 0 bytes
174
175
=== Testing version 3 ===
176
image: TEST_DIR/iotest-version3.IMGFMT
177
--
102
--
178
2.21.0
103
2.29.2
179
104
180
105
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
bs is linked in req, so no needs to pass it separately. Most of
4
tracked-requests API doesn't have bs argument. Actually, after this
5
patch only tracked_request_begin has it, but it's for purpose.
6
7
While being here, also add a comment about what "_locked" is.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-Id: <20201021145859.11201-5-vsementsov@virtuozzo.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
block/io.c | 10 +++++-----
15
1 file changed, 5 insertions(+), 5 deletions(-)
16
17
diff --git a/block/io.c b/block/io.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/io.c
20
+++ b/block/io.c
21
@@ -XXX,XX +XXX,XX @@ bdrv_find_conflicting_request(BdrvTrackedRequest *self)
22
return NULL;
23
}
24
25
+/* Called with self->bs->reqs_lock held */
26
static bool coroutine_fn
27
-bdrv_wait_serialising_requests_locked(BlockDriverState *bs,
28
- BdrvTrackedRequest *self)
29
+bdrv_wait_serialising_requests_locked(BdrvTrackedRequest *self)
30
{
31
BdrvTrackedRequest *req;
32
bool waited = false;
33
34
while ((req = bdrv_find_conflicting_request(self))) {
35
self->waiting_for = req;
36
- qemu_co_queue_wait(&req->wait_queue, &bs->reqs_lock);
37
+ qemu_co_queue_wait(&req->wait_queue, &self->bs->reqs_lock);
38
self->waiting_for = NULL;
39
waited = true;
40
}
41
@@ -XXX,XX +XXX,XX @@ bool bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
42
43
req->overlap_offset = MIN(req->overlap_offset, overlap_offset);
44
req->overlap_bytes = MAX(req->overlap_bytes, overlap_bytes);
45
- waited = bdrv_wait_serialising_requests_locked(bs, req);
46
+ waited = bdrv_wait_serialising_requests_locked(req);
47
qemu_co_mutex_unlock(&bs->reqs_lock);
48
return waited;
49
}
50
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self
51
}
52
53
qemu_co_mutex_lock(&bs->reqs_lock);
54
- waited = bdrv_wait_serialising_requests_locked(bs, self);
55
+ waited = bdrv_wait_serialising_requests_locked(self);
56
qemu_co_mutex_unlock(&bs->reqs_lock);
57
58
return waited;
59
--
60
2.29.2
61
62
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Fixes: a6b257a08e3d72219f03e461a52152672fec0612
3
We'll need a separate function, which will only "mark" request
4
("file-posix: Handle undetectable alignment")
4
serialising with specified align but not wait for conflicting
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
requests. So, it will be like old bdrv_mark_request_serialising(),
6
Message-id: 20190827101328.4062-1-stefanha@redhat.com
6
before merging bdrv_wait_serialising_requests_locked() into it.
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
8
To reduce the possible mess, let's do the following:
9
10
Public function that does both marking and waiting will be called
11
bdrv_make_request_serialising, and private function which will only
12
"mark" will be called tracked_request_set_serialising().
13
14
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
Message-Id: <20201021145859.11201-6-vsementsov@virtuozzo.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
18
---
10
block/file-posix.c | 2 +-
19
include/block/block_int.h | 3 ++-
11
1 file changed, 1 insertion(+), 1 deletion(-)
20
block/file-posix.c | 2 +-
21
block/io.c | 35 +++++++++++++++++++++++------------
22
3 files changed, 26 insertions(+), 14 deletions(-)
12
23
24
diff --git a/include/block/block_int.h b/include/block/block_int.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block_int.h
27
+++ b/include/block/block_int.h
28
@@ -XXX,XX +XXX,XX @@ extern unsigned int bdrv_drain_all_count;
29
void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
30
void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
31
32
-bool coroutine_fn bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align);
33
+bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
34
+ uint64_t align);
35
BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs);
36
37
int get_tmp_filename(char *filename, int size);
13
diff --git a/block/file-posix.c b/block/file-posix.c
38
diff --git a/block/file-posix.c b/block/file-posix.c
14
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
15
--- a/block/file-posix.c
40
--- a/block/file-posix.c
16
+++ b/block/file-posix.c
41
+++ b/block/file-posix.c
17
@@ -XXX,XX +XXX,XX @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
42
@@ -XXX,XX +XXX,XX @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
18
for (i = 0; i < ARRAY_SIZE(alignments); i++) {
43
19
align = alignments[i];
44
assert(bdrv_check_request(req->offset, req->bytes) == 0);
20
if (raw_is_io_aligned(fd, buf + align, max_align)) {
45
21
- /* Fallback to request_aligment. */
46
- bdrv_mark_request_serialising(req, bs->bl.request_alignment);
22
+ /* Fallback to request_alignment. */
47
+ bdrv_make_request_serialising(req, bs->bl.request_alignment);
23
s->buf_align = (align != 1) ? align : bs->bl.request_alignment;
48
}
24
break;
49
#endif
25
}
50
51
diff --git a/block/io.c b/block/io.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/block/io.c
54
+++ b/block/io.c
55
@@ -XXX,XX +XXX,XX @@ bdrv_wait_serialising_requests_locked(BdrvTrackedRequest *self)
56
return waited;
57
}
58
59
-bool bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
60
+/* Called with req->bs->reqs_lock held */
61
+static void tracked_request_set_serialising(BdrvTrackedRequest *req,
62
+ uint64_t align)
63
{
64
- BlockDriverState *bs = req->bs;
65
int64_t overlap_offset = req->offset & ~(align - 1);
66
uint64_t overlap_bytes = ROUND_UP(req->offset + req->bytes, align)
67
- overlap_offset;
68
- bool waited;
69
70
- qemu_co_mutex_lock(&bs->reqs_lock);
71
if (!req->serialising) {
72
qatomic_inc(&req->bs->serialising_in_flight);
73
req->serialising = true;
74
@@ -XXX,XX +XXX,XX @@ bool bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
75
76
req->overlap_offset = MIN(req->overlap_offset, overlap_offset);
77
req->overlap_bytes = MAX(req->overlap_bytes, overlap_bytes);
78
- waited = bdrv_wait_serialising_requests_locked(req);
79
- qemu_co_mutex_unlock(&bs->reqs_lock);
80
- return waited;
81
}
82
83
/**
84
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self
85
return waited;
86
}
87
88
+bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
89
+ uint64_t align)
90
+{
91
+ bool waited;
92
+
93
+ qemu_co_mutex_lock(&req->bs->reqs_lock);
94
+
95
+ tracked_request_set_serialising(req, align);
96
+ waited = bdrv_wait_serialising_requests_locked(req);
97
+
98
+ qemu_co_mutex_unlock(&req->bs->reqs_lock);
99
+
100
+ return waited;
101
+}
102
+
103
int bdrv_check_request(int64_t offset, int64_t bytes)
104
{
105
if (offset < 0 || bytes < 0) {
106
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
107
* with each other for the same cluster. For example, in copy-on-read
108
* it ensures that the CoR read and write operations are atomic and
109
* guest writes cannot interleave between them. */
110
- bdrv_mark_request_serialising(req, bdrv_get_cluster_size(bs));
111
+ bdrv_make_request_serialising(req, bdrv_get_cluster_size(bs));
112
} else {
113
bdrv_wait_serialising_requests(req);
114
}
115
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
116
assert(!(flags & ~BDRV_REQ_MASK));
117
118
if (flags & BDRV_REQ_SERIALISING) {
119
- bdrv_mark_request_serialising(req, bdrv_get_cluster_size(bs));
120
+ bdrv_make_request_serialising(req, bdrv_get_cluster_size(bs));
121
} else {
122
bdrv_wait_serialising_requests(req);
123
}
124
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
125
126
padding = bdrv_init_padding(bs, offset, bytes, &pad);
127
if (padding) {
128
- bdrv_mark_request_serialising(req, align);
129
+ bdrv_make_request_serialising(req, align);
130
131
bdrv_padding_rmw_read(child, req, &pad, true);
132
133
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
134
}
135
136
if (bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, &pad)) {
137
- bdrv_mark_request_serialising(&req, align);
138
+ bdrv_make_request_serialising(&req, align);
139
bdrv_padding_rmw_read(child, &req, &pad, false);
140
}
141
142
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
143
* new area, we need to make sure that no write requests are made to it
144
* concurrently or they might be overwritten by preallocation. */
145
if (new_bytes) {
146
- bdrv_mark_request_serialising(&req, 1);
147
+ bdrv_make_request_serialising(&req, 1);
148
}
149
if (bs->read_only) {
150
error_setg(errp, "Image is read-only");
26
--
151
--
27
2.21.0
152
2.29.2
28
153
29
154
diff view generated by jsdifflib
1
Compressed writes generally have to write full clusters, not just in
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
theory but also in practice when it comes to vmdk's streamOptimized
3
subformat. It currently is just silently broken for writes with
4
non-zero in-cluster offsets:
5
2
6
$ qemu-img create -f vmdk -o subformat=streamOptimized foo.vmdk 1M
3
Add flag to make serialising request no wait: if there are conflicting
7
$ qemu-io -c 'write 4k 4k' -c 'read 4k 4k' foo.vmdk
4
requests, just return error immediately. It's will be used in upcoming
8
wrote 4096/4096 bytes at offset 4096
5
preallocate filter.
9
4 KiB, 1 ops; 00.01 sec (443.724 KiB/sec and 110.9309 ops/sec)
10
read failed: Invalid argument
11
6
12
(The technical reason is that vmdk_write_extent() just writes the
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
incomplete compressed data actually to offset 4k. When reading the
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
data, vmdk_read_extent() looks at offset 0 and finds the compressed data
9
Message-Id: <20201021145859.11201-7-vsementsov@virtuozzo.com>
15
size to be 0, because that is what it reads from there. This yields an
16
error.)
17
18
For incomplete writes with zero in-cluster offsets, the error path when
19
reading the rest of the cluster is a bit different, but the result is
20
the same:
21
22
$ qemu-img create -f vmdk -o subformat=streamOptimized foo.vmdk 1M
23
$ qemu-io -c 'write 0k 4k' -c 'read 4k 4k' foo.vmdk
24
wrote 4096/4096 bytes at offset 0
25
4 KiB, 1 ops; 00.01 sec (362.641 KiB/sec and 90.6603 ops/sec)
26
read failed: Invalid argument
27
28
(Here, vmdk_read_extent() finds the data and then sees that the
29
uncompressed data is short.)
30
31
It is better to reject invalid writes than to make the user believe they
32
might have succeeded and then fail when trying to read it back.
33
34
Signed-off-by: Max Reitz <mreitz@redhat.com>
35
Reviewed-by: John Snow <jsnow@redhat.com>
36
Message-id: 20190815153638.4600-5-mreitz@redhat.com
37
Reviewed-by: John Snow <jsnow@redhat.com>
38
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
39
---
11
---
40
block/vmdk.c | 10 ++++++++++
12
include/block/block.h | 9 ++++++++-
41
1 file changed, 10 insertions(+)
13
block/io.c | 11 ++++++++++-
14
2 files changed, 18 insertions(+), 2 deletions(-)
42
15
43
diff --git a/block/vmdk.c b/block/vmdk.c
16
diff --git a/include/block/block.h b/include/block/block.h
44
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
45
--- a/block/vmdk.c
18
--- a/include/block/block.h
46
+++ b/block/vmdk.c
19
+++ b/include/block/block.h
47
@@ -XXX,XX +XXX,XX @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
20
@@ -XXX,XX +XXX,XX @@ typedef enum {
48
if (extent->compressed) {
21
* written to qiov parameter which may be NULL.
49
void *compressed_data;
22
*/
50
23
BDRV_REQ_PREFETCH = 0x200,
51
+ /* Only whole clusters */
24
+
52
+ if (offset_in_cluster ||
25
+ /*
53
+ n_bytes > (extent->cluster_sectors * SECTOR_SIZE) ||
26
+ * If we need to wait for other requests, just fail immediately. Used
54
+ (n_bytes < (extent->cluster_sectors * SECTOR_SIZE) &&
27
+ * only together with BDRV_REQ_SERIALISING.
55
+ offset + n_bytes != extent->end_sector * SECTOR_SIZE))
28
+ */
56
+ {
29
+ BDRV_REQ_NO_WAIT = 0x400,
57
+ ret = -EINVAL;
30
+
58
+ goto out;
31
/* Mask of valid flags */
32
- BDRV_REQ_MASK = 0x3ff,
33
+ BDRV_REQ_MASK = 0x7ff,
34
} BdrvRequestFlags;
35
36
typedef struct BlockSizes {
37
diff --git a/block/io.c b/block/io.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/block/io.c
40
+++ b/block/io.c
41
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
42
assert(!(bs->open_flags & BDRV_O_INACTIVE));
43
assert((bs->open_flags & BDRV_O_NO_IO) == 0);
44
assert(!(flags & ~BDRV_REQ_MASK));
45
+ assert(!((flags & BDRV_REQ_NO_WAIT) && !(flags & BDRV_REQ_SERIALISING)));
46
47
if (flags & BDRV_REQ_SERIALISING) {
48
- bdrv_make_request_serialising(req, bdrv_get_cluster_size(bs));
49
+ QEMU_LOCK_GUARD(&bs->reqs_lock);
50
+
51
+ tracked_request_set_serialising(req, bdrv_get_cluster_size(bs));
52
+
53
+ if ((flags & BDRV_REQ_NO_WAIT) && bdrv_find_conflicting_request(req)) {
54
+ return -EBUSY;
59
+ }
55
+ }
60
+
56
+
61
if (!extent->has_marker) {
57
+ bdrv_wait_serialising_requests_locked(req);
62
ret = -EINVAL;
58
} else {
63
goto out;
59
bdrv_wait_serialising_requests(req);
60
}
64
--
61
--
65
2.21.0
62
2.29.2
66
63
67
64
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Do generic processing even for drivers which define .bdrv_check_perm
4
handler. It's needed for further preallocate filter: it will need to do
5
additional action on bdrv_check_perm, but don't want to reimplement
6
generic logic.
7
8
The patch doesn't change existing behaviour: the only driver that
9
implements bdrv_check_perm is file-posix, but it never has any
10
children.
11
12
Also, bdrv_set_perm() don't stop processing if driver has
13
.bdrv_set_perm handler as well.
14
15
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
Message-Id: <20201021145859.11201-8-vsementsov@virtuozzo.com>
17
Reviewed-by: Max Reitz <mreitz@redhat.com>
18
Signed-off-by: Max Reitz <mreitz@redhat.com>
19
---
20
block.c | 7 +++++--
21
1 file changed, 5 insertions(+), 2 deletions(-)
22
23
diff --git a/block.c b/block.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block.c
26
+++ b/block.c
27
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
28
}
29
30
if (drv->bdrv_check_perm) {
31
- return drv->bdrv_check_perm(bs, cumulative_perms,
32
- cumulative_shared_perms, errp);
33
+ ret = drv->bdrv_check_perm(bs, cumulative_perms,
34
+ cumulative_shared_perms, errp);
35
+ if (ret < 0) {
36
+ return ret;
37
+ }
38
}
39
40
/* Drivers that never have children can omit .bdrv_child_perm() */
41
--
42
2.29.2
43
44
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
It's intended to be inserted between format and protocol nodes to
4
preallocate additional space (expanding protocol file) on writes
5
crossing EOF. It improves performance for file-systems with slow
6
allocation.
7
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Message-Id: <20201021145859.11201-9-vsementsov@virtuozzo.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
[mreitz: Two comment fixes, and bumped the version from 5.2 to 6.0]
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
docs/system/qemu-block-drivers.rst.inc | 26 ++
15
qapi/block-core.json | 20 +-
16
block/preallocate.c | 559 +++++++++++++++++++++++++
17
block/meson.build | 1 +
18
4 files changed, 605 insertions(+), 1 deletion(-)
19
create mode 100644 block/preallocate.c
20
21
diff --git a/docs/system/qemu-block-drivers.rst.inc b/docs/system/qemu-block-drivers.rst.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/docs/system/qemu-block-drivers.rst.inc
24
+++ b/docs/system/qemu-block-drivers.rst.inc
25
@@ -XXX,XX +XXX,XX @@ on host and see if there are locks held by the QEMU process on the image file.
26
More than one byte could be locked by the QEMU instance, each byte of which
27
reflects a particular permission that is acquired or protected by the running
28
block driver.
29
+
30
+Filter drivers
31
+~~~~~~~~~~~~~~
32
+
33
+QEMU supports several filter drivers, which don't store any data, but perform
34
+some additional tasks, hooking io requests.
35
+
36
+.. program:: filter-drivers
37
+.. option:: preallocate
38
+
39
+ The preallocate filter driver is intended to be inserted between format
40
+ and protocol nodes and preallocates some additional space
41
+ (expanding the protocol file) when writing past the file’s end. This can be
42
+ useful for file-systems with slow allocation.
43
+
44
+ Supported options:
45
+
46
+ .. program:: preallocate
47
+ .. option:: prealloc-align
48
+
49
+ On preallocation, align the file length to this value (in bytes), default 1M.
50
+
51
+ .. program:: preallocate
52
+ .. option:: prealloc-size
53
+
54
+ How much to preallocate (in bytes), default 128M.
55
diff --git a/qapi/block-core.json b/qapi/block-core.json
56
index XXXXXXX..XXXXXXX 100644
57
--- a/qapi/block-core.json
58
+++ b/qapi/block-core.json
59
@@ -XXX,XX +XXX,XX @@
60
'cloop', 'compress', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps',
61
'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi',
62
'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
63
- 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
64
+ 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
65
{ 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
66
'sheepdog',
67
'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
68
@@ -XXX,XX +XXX,XX @@
69
'data': { 'aes': 'QCryptoBlockOptionsQCow',
70
'luks': 'QCryptoBlockOptionsLUKS'} }
71
72
+##
73
+# @BlockdevOptionsPreallocate:
74
+#
75
+# Filter driver intended to be inserted between format and protocol node
76
+# and do preallocation in protocol node on write.
77
+#
78
+# @prealloc-align: on preallocation, align file length to this number,
79
+# default 1048576 (1M)
80
+#
81
+# @prealloc-size: how much to preallocate, default 134217728 (128M)
82
+#
83
+# Since: 6.0
84
+##
85
+{ 'struct': 'BlockdevOptionsPreallocate',
86
+ 'base': 'BlockdevOptionsGenericFormat',
87
+ 'data': { '*prealloc-align': 'int', '*prealloc-size': 'int' } }
88
+
89
##
90
# @BlockdevOptionsQcow2:
91
#
92
@@ -XXX,XX +XXX,XX @@
93
'null-co': 'BlockdevOptionsNull',
94
'nvme': 'BlockdevOptionsNVMe',
95
'parallels': 'BlockdevOptionsGenericFormat',
96
+ 'preallocate':'BlockdevOptionsPreallocate',
97
'qcow2': 'BlockdevOptionsQcow2',
98
'qcow': 'BlockdevOptionsQcow',
99
'qed': 'BlockdevOptionsGenericCOWFormat',
100
diff --git a/block/preallocate.c b/block/preallocate.c
101
new file mode 100644
102
index XXXXXXX..XXXXXXX
103
--- /dev/null
104
+++ b/block/preallocate.c
105
@@ -XXX,XX +XXX,XX @@
106
+/*
107
+ * preallocate filter driver
108
+ *
109
+ * The driver performs preallocate operation: it is injected above
110
+ * some node, and before each write over EOF it does additional preallocating
111
+ * write-zeroes request.
112
+ *
113
+ * Copyright (c) 2020 Virtuozzo International GmbH.
114
+ *
115
+ * Author:
116
+ * Sementsov-Ogievskiy Vladimir <vsementsov@virtuozzo.com>
117
+ *
118
+ * This program is free software; you can redistribute it and/or modify
119
+ * it under the terms of the GNU General Public License as published by
120
+ * the Free Software Foundation; either version 2 of the License, or
121
+ * (at your option) any later version.
122
+ *
123
+ * This program is distributed in the hope that it will be useful,
124
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
125
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
126
+ * GNU General Public License for more details.
127
+ *
128
+ * You should have received a copy of the GNU General Public License
129
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
130
+ */
131
+
132
+#include "qemu/osdep.h"
133
+
134
+#include "qapi/error.h"
135
+#include "qemu/module.h"
136
+#include "qemu/option.h"
137
+#include "qemu/units.h"
138
+#include "block/block_int.h"
139
+
140
+
141
+typedef struct PreallocateOpts {
142
+ int64_t prealloc_size;
143
+ int64_t prealloc_align;
144
+} PreallocateOpts;
145
+
146
+typedef struct BDRVPreallocateState {
147
+ PreallocateOpts opts;
148
+
149
+ /*
150
+ * Track real data end, to crop preallocation on close. If < 0 the status is
151
+ * unknown.
152
+ *
153
+ * @data_end is a maximum of file size on open (or when we get write/resize
154
+ * permissions) and all write request ends after it. So it's safe to
155
+ * truncate to data_end if it is valid.
156
+ */
157
+ int64_t data_end;
158
+
159
+ /*
160
+ * Start of trailing preallocated area which reads as zero. May be smaller
161
+ * than data_end, if user does over-EOF write zero operation. If < 0 the
162
+ * status is unknown.
163
+ *
164
+ * If both @zero_start and @file_end are valid, the region
165
+ * [@zero_start, @file_end) is known to be preallocated zeroes. If @file_end
166
+ * is not valid, @zero_start doesn't make much sense.
167
+ */
168
+ int64_t zero_start;
169
+
170
+ /*
171
+ * Real end of file. Actually the cache for bdrv_getlength(bs->file->bs),
172
+ * to avoid extra lseek() calls on each write operation. If < 0 the status
173
+ * is unknown.
174
+ */
175
+ int64_t file_end;
176
+
177
+ /*
178
+ * All three states @data_end, @zero_start and @file_end are guaranteed to
179
+ * be invalid (< 0) when we don't have both exclusive BLK_PERM_RESIZE and
180
+ * BLK_PERM_WRITE permissions on file child.
181
+ */
182
+} BDRVPreallocateState;
183
+
184
+#define PREALLOCATE_OPT_PREALLOC_ALIGN "prealloc-align"
185
+#define PREALLOCATE_OPT_PREALLOC_SIZE "prealloc-size"
186
+static QemuOptsList runtime_opts = {
187
+ .name = "preallocate",
188
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
189
+ .desc = {
190
+ {
191
+ .name = PREALLOCATE_OPT_PREALLOC_ALIGN,
192
+ .type = QEMU_OPT_SIZE,
193
+ .help = "on preallocation, align file length to this number, "
194
+ "default 1M",
195
+ },
196
+ {
197
+ .name = PREALLOCATE_OPT_PREALLOC_SIZE,
198
+ .type = QEMU_OPT_SIZE,
199
+ .help = "how much to preallocate, default 128M",
200
+ },
201
+ { /* end of list */ }
202
+ },
203
+};
204
+
205
+static bool preallocate_absorb_opts(PreallocateOpts *dest, QDict *options,
206
+ BlockDriverState *child_bs, Error **errp)
207
+{
208
+ QemuOpts *opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
209
+
210
+ if (!qemu_opts_absorb_qdict(opts, options, errp)) {
211
+ return false;
212
+ }
213
+
214
+ dest->prealloc_align =
215
+ qemu_opt_get_size(opts, PREALLOCATE_OPT_PREALLOC_ALIGN, 1 * MiB);
216
+ dest->prealloc_size =
217
+ qemu_opt_get_size(opts, PREALLOCATE_OPT_PREALLOC_SIZE, 128 * MiB);
218
+
219
+ qemu_opts_del(opts);
220
+
221
+ if (!QEMU_IS_ALIGNED(dest->prealloc_align, BDRV_SECTOR_SIZE)) {
222
+ error_setg(errp, "prealloc-align parameter of preallocate filter "
223
+ "is not aligned to %llu", BDRV_SECTOR_SIZE);
224
+ return false;
225
+ }
226
+
227
+ if (!QEMU_IS_ALIGNED(dest->prealloc_align,
228
+ child_bs->bl.request_alignment)) {
229
+ error_setg(errp, "prealloc-align parameter of preallocate filter "
230
+ "is not aligned to underlying node request alignment "
231
+ "(%" PRIi32 ")", child_bs->bl.request_alignment);
232
+ return false;
233
+ }
234
+
235
+ return true;
236
+}
237
+
238
+static int preallocate_open(BlockDriverState *bs, QDict *options, int flags,
239
+ Error **errp)
240
+{
241
+ BDRVPreallocateState *s = bs->opaque;
242
+
243
+ /*
244
+ * s->data_end and friends should be initialized on permission update.
245
+ * For this to work, mark them invalid.
246
+ */
247
+ s->file_end = s->zero_start = s->data_end = -EINVAL;
248
+
249
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
250
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
251
+ false, errp);
252
+ if (!bs->file) {
253
+ return -EINVAL;
254
+ }
255
+
256
+ if (!preallocate_absorb_opts(&s->opts, options, bs->file->bs, errp)) {
257
+ return -EINVAL;
258
+ }
259
+
260
+ bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
261
+ (BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
262
+
263
+ bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
264
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
265
+ bs->file->bs->supported_zero_flags);
266
+
267
+ return 0;
268
+}
269
+
270
+static void preallocate_close(BlockDriverState *bs)
271
+{
272
+ int ret;
273
+ BDRVPreallocateState *s = bs->opaque;
274
+
275
+ if (s->data_end < 0) {
276
+ return;
277
+ }
278
+
279
+ if (s->file_end < 0) {
280
+ s->file_end = bdrv_getlength(bs->file->bs);
281
+ if (s->file_end < 0) {
282
+ return;
283
+ }
284
+ }
285
+
286
+ if (s->data_end < s->file_end) {
287
+ ret = bdrv_truncate(bs->file, s->data_end, true, PREALLOC_MODE_OFF, 0,
288
+ NULL);
289
+ s->file_end = ret < 0 ? ret : s->data_end;
290
+ }
291
+}
292
+
293
+
294
+/*
295
+ * Handle reopen.
296
+ *
297
+ * We must implement reopen handlers, otherwise reopen just don't work. Handle
298
+ * new options and don't care about preallocation state, as it is handled in
299
+ * set/check permission handlers.
300
+ */
301
+
302
+static int preallocate_reopen_prepare(BDRVReopenState *reopen_state,
303
+ BlockReopenQueue *queue, Error **errp)
304
+{
305
+ PreallocateOpts *opts = g_new0(PreallocateOpts, 1);
306
+
307
+ if (!preallocate_absorb_opts(opts, reopen_state->options,
308
+ reopen_state->bs->file->bs, errp)) {
309
+ g_free(opts);
310
+ return -EINVAL;
311
+ }
312
+
313
+ reopen_state->opaque = opts;
314
+
315
+ return 0;
316
+}
317
+
318
+static void preallocate_reopen_commit(BDRVReopenState *state)
319
+{
320
+ BDRVPreallocateState *s = state->bs->opaque;
321
+
322
+ s->opts = *(PreallocateOpts *)state->opaque;
323
+
324
+ g_free(state->opaque);
325
+ state->opaque = NULL;
326
+}
327
+
328
+static void preallocate_reopen_abort(BDRVReopenState *state)
329
+{
330
+ g_free(state->opaque);
331
+ state->opaque = NULL;
332
+}
333
+
334
+static coroutine_fn int preallocate_co_preadv_part(
335
+ BlockDriverState *bs, uint64_t offset, uint64_t bytes,
336
+ QEMUIOVector *qiov, size_t qiov_offset, int flags)
337
+{
338
+ return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
339
+ flags);
340
+}
341
+
342
+static int coroutine_fn preallocate_co_pdiscard(BlockDriverState *bs,
343
+ int64_t offset, int bytes)
344
+{
345
+ return bdrv_co_pdiscard(bs->file, offset, bytes);
346
+}
347
+
348
+static bool can_write_resize(uint64_t perm)
349
+{
350
+ return (perm & BLK_PERM_WRITE) && (perm & BLK_PERM_RESIZE);
351
+}
352
+
353
+static bool has_prealloc_perms(BlockDriverState *bs)
354
+{
355
+ BDRVPreallocateState *s = bs->opaque;
356
+
357
+ if (can_write_resize(bs->file->perm)) {
358
+ assert(!(bs->file->shared_perm & BLK_PERM_WRITE));
359
+ assert(!(bs->file->shared_perm & BLK_PERM_RESIZE));
360
+ return true;
361
+ }
362
+
363
+ assert(s->data_end < 0);
364
+ assert(s->zero_start < 0);
365
+ assert(s->file_end < 0);
366
+ return false;
367
+}
368
+
369
+/*
370
+ * Call on each write. Returns true if @want_merge_zero is true and the region
371
+ * [offset, offset + bytes) is zeroed (as a result of this call or earlier
372
+ * preallocation).
373
+ *
374
+ * want_merge_zero is used to merge write-zero request with preallocation in
375
+ * one bdrv_co_pwrite_zeroes() call.
376
+ */
377
+static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
378
+ int64_t bytes, bool want_merge_zero)
379
+{
380
+ BDRVPreallocateState *s = bs->opaque;
381
+ int64_t end = offset + bytes;
382
+ int64_t prealloc_start, prealloc_end;
383
+ int ret;
384
+
385
+ if (!has_prealloc_perms(bs)) {
386
+ /* We don't have state neither should try to recover it */
387
+ return false;
388
+ }
389
+
390
+ if (s->data_end < 0) {
391
+ s->data_end = bdrv_getlength(bs->file->bs);
392
+ if (s->data_end < 0) {
393
+ return false;
394
+ }
395
+
396
+ if (s->file_end < 0) {
397
+ s->file_end = s->data_end;
398
+ }
399
+ }
400
+
401
+ if (end <= s->data_end) {
402
+ return false;
403
+ }
404
+
405
+ /* We have valid s->data_end, and request writes beyond it. */
406
+
407
+ s->data_end = end;
408
+ if (s->zero_start < 0 || !want_merge_zero) {
409
+ s->zero_start = end;
410
+ }
411
+
412
+ if (s->file_end < 0) {
413
+ s->file_end = bdrv_getlength(bs->file->bs);
414
+ if (s->file_end < 0) {
415
+ return false;
416
+ }
417
+ }
418
+
419
+ /* Now s->data_end, s->zero_start and s->file_end are valid. */
420
+
421
+ if (end <= s->file_end) {
422
+ /* No preallocation needed. */
423
+ return want_merge_zero && offset >= s->zero_start;
424
+ }
425
+
426
+ /* Now we want new preallocation, as request writes beyond s->file_end. */
427
+
428
+ prealloc_start = want_merge_zero ? MIN(offset, s->file_end) : s->file_end;
429
+ prealloc_end = QEMU_ALIGN_UP(end + s->opts.prealloc_size,
430
+ s->opts.prealloc_align);
431
+
432
+ ret = bdrv_co_pwrite_zeroes(
433
+ bs->file, prealloc_start, prealloc_end - prealloc_start,
434
+ BDRV_REQ_NO_FALLBACK | BDRV_REQ_SERIALISING | BDRV_REQ_NO_WAIT);
435
+ if (ret < 0) {
436
+ s->file_end = ret;
437
+ return false;
438
+ }
439
+
440
+ s->file_end = prealloc_end;
441
+ return want_merge_zero;
442
+}
443
+
444
+static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs,
445
+ int64_t offset, int bytes, BdrvRequestFlags flags)
446
+{
447
+ bool want_merge_zero =
448
+ !(flags & ~(BDRV_REQ_ZERO_WRITE | BDRV_REQ_NO_FALLBACK));
449
+ if (handle_write(bs, offset, bytes, want_merge_zero)) {
450
+ return 0;
451
+ }
452
+
453
+ return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
454
+}
455
+
456
+static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
457
+ uint64_t offset,
458
+ uint64_t bytes,
459
+ QEMUIOVector *qiov,
460
+ size_t qiov_offset,
461
+ int flags)
462
+{
463
+ handle_write(bs, offset, bytes, false);
464
+
465
+ return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
466
+ flags);
467
+}
468
+
469
+static int coroutine_fn
470
+preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
471
+ bool exact, PreallocMode prealloc,
472
+ BdrvRequestFlags flags, Error **errp)
473
+{
474
+ ERRP_GUARD();
475
+ BDRVPreallocateState *s = bs->opaque;
476
+ int ret;
477
+
478
+ if (s->data_end >= 0 && offset > s->data_end) {
479
+ if (s->file_end < 0) {
480
+ s->file_end = bdrv_getlength(bs->file->bs);
481
+ if (s->file_end < 0) {
482
+ error_setg(errp, "failed to get file length");
483
+ return s->file_end;
484
+ }
485
+ }
486
+
487
+ if (prealloc == PREALLOC_MODE_FALLOC) {
488
+ /*
489
+ * If offset <= s->file_end, the task is already done, just
490
+ * update s->data_end, to move part of "filter preallocation"
491
+ * to "preallocation requested by user".
492
+ * Otherwise just proceed to preallocate missing part.
493
+ */
494
+ if (offset <= s->file_end) {
495
+ s->data_end = offset;
496
+ return 0;
497
+ }
498
+ } else {
499
+ /*
500
+ * We have to drop our preallocation, to
501
+ * - avoid "Cannot use preallocation for shrinking files" in
502
+ * case of offset < file_end
503
+ * - give PREALLOC_MODE_OFF a chance to keep small disk
504
+ * usage
505
+ * - give PREALLOC_MODE_FULL a chance to actually write the
506
+ * whole region as user expects
507
+ */
508
+ if (s->file_end > s->data_end) {
509
+ ret = bdrv_co_truncate(bs->file, s->data_end, true,
510
+ PREALLOC_MODE_OFF, 0, errp);
511
+ if (ret < 0) {
512
+ s->file_end = ret;
513
+ error_prepend(errp, "preallocate-filter: failed to drop "
514
+ "write-zero preallocation: ");
515
+ return ret;
516
+ }
517
+ s->file_end = s->data_end;
518
+ }
519
+ }
520
+
521
+ s->data_end = offset;
522
+ }
523
+
524
+ ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
525
+ if (ret < 0) {
526
+ s->file_end = s->zero_start = s->data_end = ret;
527
+ return ret;
528
+ }
529
+
530
+ if (has_prealloc_perms(bs)) {
531
+ s->file_end = s->zero_start = s->data_end = offset;
532
+ }
533
+ return 0;
534
+}
535
+
536
+static int coroutine_fn preallocate_co_flush(BlockDriverState *bs)
537
+{
538
+ return bdrv_co_flush(bs->file->bs);
539
+}
540
+
541
+static int64_t preallocate_getlength(BlockDriverState *bs)
542
+{
543
+ int64_t ret;
544
+ BDRVPreallocateState *s = bs->opaque;
545
+
546
+ if (s->data_end >= 0) {
547
+ return s->data_end;
548
+ }
549
+
550
+ ret = bdrv_getlength(bs->file->bs);
551
+
552
+ if (has_prealloc_perms(bs)) {
553
+ s->file_end = s->zero_start = s->data_end = ret;
554
+ }
555
+
556
+ return ret;
557
+}
558
+
559
+static int preallocate_check_perm(BlockDriverState *bs,
560
+ uint64_t perm, uint64_t shared, Error **errp)
561
+{
562
+ BDRVPreallocateState *s = bs->opaque;
563
+
564
+ if (s->data_end >= 0 && !can_write_resize(perm)) {
565
+ /*
566
+ * Lose permissions.
567
+ * We should truncate in check_perm, as in set_perm bs->file->perm will
568
+ * be already changed, and we should not violate it.
569
+ */
570
+ if (s->file_end < 0) {
571
+ s->file_end = bdrv_getlength(bs->file->bs);
572
+ if (s->file_end < 0) {
573
+ error_setg(errp, "Failed to get file length");
574
+ return s->file_end;
575
+ }
576
+ }
577
+
578
+ if (s->data_end < s->file_end) {
579
+ int ret = bdrv_truncate(bs->file, s->data_end, true,
580
+ PREALLOC_MODE_OFF, 0, NULL);
581
+ if (ret < 0) {
582
+ error_setg(errp, "Failed to drop preallocation");
583
+ s->file_end = ret;
584
+ return ret;
585
+ }
586
+ s->file_end = s->data_end;
587
+ }
588
+ }
589
+
590
+ return 0;
591
+}
592
+
593
+static void preallocate_set_perm(BlockDriverState *bs,
594
+ uint64_t perm, uint64_t shared)
595
+{
596
+ BDRVPreallocateState *s = bs->opaque;
597
+
598
+ if (can_write_resize(perm)) {
599
+ if (s->data_end < 0) {
600
+ s->data_end = s->file_end = s->zero_start =
601
+ bdrv_getlength(bs->file->bs);
602
+ }
603
+ } else {
604
+ /*
605
+ * We drop our permissions, as well as allow shared
606
+ * permissions (see preallocate_child_perm), anyone will be able to
607
+ * change the child, so mark all states invalid. We'll regain control if
608
+ * get good permissions back.
609
+ */
610
+ s->data_end = s->file_end = s->zero_start = -EINVAL;
611
+ }
612
+}
613
+
614
+static void preallocate_child_perm(BlockDriverState *bs, BdrvChild *c,
615
+ BdrvChildRole role, BlockReopenQueue *reopen_queue,
616
+ uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared)
617
+{
618
+ bdrv_default_perms(bs, c, role, reopen_queue, perm, shared, nperm, nshared);
619
+
620
+ if (can_write_resize(perm)) {
621
+ /* This should come by default, but let's enforce: */
622
+ *nperm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
623
+
624
+ /*
625
+ * Don't share, to keep our states s->file_end, s->data_end and
626
+ * s->zero_start valid.
627
+ */
628
+ *nshared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
629
+ }
630
+}
631
+
632
+BlockDriver bdrv_preallocate_filter = {
633
+ .format_name = "preallocate",
634
+ .instance_size = sizeof(BDRVPreallocateState),
635
+
636
+ .bdrv_getlength = preallocate_getlength,
637
+ .bdrv_open = preallocate_open,
638
+ .bdrv_close = preallocate_close,
639
+
640
+ .bdrv_reopen_prepare = preallocate_reopen_prepare,
641
+ .bdrv_reopen_commit = preallocate_reopen_commit,
642
+ .bdrv_reopen_abort = preallocate_reopen_abort,
643
+
644
+ .bdrv_co_preadv_part = preallocate_co_preadv_part,
645
+ .bdrv_co_pwritev_part = preallocate_co_pwritev_part,
646
+ .bdrv_co_pwrite_zeroes = preallocate_co_pwrite_zeroes,
647
+ .bdrv_co_pdiscard = preallocate_co_pdiscard,
648
+ .bdrv_co_flush = preallocate_co_flush,
649
+ .bdrv_co_truncate = preallocate_co_truncate,
650
+
651
+ .bdrv_check_perm = preallocate_check_perm,
652
+ .bdrv_set_perm = preallocate_set_perm,
653
+ .bdrv_child_perm = preallocate_child_perm,
654
+
655
+ .has_variable_length = true,
656
+ .is_filter = true,
657
+};
658
+
659
+static void bdrv_preallocate_init(void)
660
+{
661
+ bdrv_register(&bdrv_preallocate_filter);
662
+}
663
+
664
+block_init(bdrv_preallocate_init);
665
diff --git a/block/meson.build b/block/meson.build
666
index XXXXXXX..XXXXXXX 100644
667
--- a/block/meson.build
668
+++ b/block/meson.build
669
@@ -XXX,XX +XXX,XX @@ block_ss.add(files(
670
'block-copy.c',
671
'commit.c',
672
'copy-on-read.c',
673
+ 'preallocate.c',
674
'create.c',
675
'crypto.c',
676
'dirty-bitmap.c',
677
--
678
2.29.2
679
680
diff view generated by jsdifflib
1
From: Denis Plotnikov <dplotnikov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
The patch allows to provide a pattern file for write
3
This will be used in further test.
4
command. There was no similar ability before.
5
4
6
Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-id: 20190820164616.4072-1-dplotnikov@virtuozzo.com
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-Id: <20201021145859.11201-10-vsementsov@virtuozzo.com>
9
[mreitz: Keep optstring in alphabetical order]
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
9
---
12
qemu-io-cmds.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++---
10
qemu-io-cmds.c | 46 ++++++++++++++++++++++++++++++++--------------
13
1 file changed, 93 insertions(+), 6 deletions(-)
11
1 file changed, 32 insertions(+), 14 deletions(-)
14
12
15
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
13
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/qemu-io-cmds.c
15
--- a/qemu-io-cmds.c
18
+++ b/qemu-io-cmds.c
16
+++ b/qemu-io-cmds.c
19
@@ -XXX,XX +XXX,XX @@ static void qemu_io_free(void *p)
17
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t flush_cmd = {
20
qemu_vfree(p);
18
.oneline = "flush all in-core file state to disk",
21
}
19
};
22
20
23
+/*
21
+static int truncate_f(BlockBackend *blk, int argc, char **argv);
24
+ * qemu_io_alloc_from_file()
22
+static const cmdinfo_t truncate_cmd = {
25
+ *
23
+ .name = "truncate",
26
+ * Allocates the buffer and populates it with the content of the given file
24
+ .altname = "t",
27
+ * up to @len bytes. If the file length is less than @len, then the buffer
25
+ .cfunc = truncate_f,
28
+ * is populated with the file content cyclically.
26
+ .perm = BLK_PERM_WRITE | BLK_PERM_RESIZE,
29
+ *
27
+ .argmin = 1,
30
+ * @blk - the block backend where the buffer content is going to be written to
28
+ .argmax = 3,
31
+ * @len - the buffer length
29
+ .args = "[-m prealloc_mode] off",
32
+ * @file_name - the file to read the content from
30
+ .oneline = "truncates the current file at the given offset",
33
+ *
31
+};
34
+ * Returns: the buffer pointer on success
35
+ * NULL on error
36
+ */
37
+static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
38
+ const char *file_name)
39
+{
40
+ char *buf, *buf_origin;
41
+ FILE *f = fopen(file_name, "r");
42
+ int pattern_len;
43
+
32
+
44
+ if (!f) {
33
static int truncate_f(BlockBackend *blk, int argc, char **argv)
45
+ perror(file_name);
34
{
46
+ return NULL;
35
Error *local_err = NULL;
47
+ }
36
int64_t offset;
48
+
37
- int ret;
49
+ if (qemuio_misalign) {
38
+ int c, ret;
50
+ len += MISALIGN_OFFSET;
39
+ PreallocMode prealloc = PREALLOC_MODE_OFF;
51
+ }
40
52
+
41
- offset = cvtnum(argv[1]);
53
+ buf_origin = buf = blk_blockalign(blk, len);
42
+ while ((c = getopt(argc, argv, "m:")) != -1) {
54
+
43
+ switch (c) {
55
+ if (qemuio_misalign) {
44
+ case 'm':
56
+ buf_origin += MISALIGN_OFFSET;
45
+ prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg,
57
+ buf += MISALIGN_OFFSET;
46
+ PREALLOC_MODE__MAX, NULL);
58
+ len -= MISALIGN_OFFSET;
47
+ if (prealloc == PREALLOC_MODE__MAX) {
59
+ }
48
+ error_report("Invalid preallocation mode '%s'", optarg);
60
+
49
+ return -EINVAL;
61
+ pattern_len = fread(buf_origin, 1, len, f);
50
+ }
62
+
51
+ break;
63
+ if (ferror(f)) {
52
+ default:
64
+ perror(file_name);
53
+ qemuio_command_usage(&truncate_cmd);
65
+ goto error;
54
+ return -EINVAL;
66
+ }
67
+
68
+ if (pattern_len == 0) {
69
+ fprintf(stderr, "%s: file is empty\n", file_name);
70
+ goto error;
71
+ }
72
+
73
+ fclose(f);
74
+
75
+ if (len > pattern_len) {
76
+ len -= pattern_len;
77
+ buf += pattern_len;
78
+
79
+ while (len > 0) {
80
+ size_t len_to_copy = MIN(pattern_len, len);
81
+
82
+ memcpy(buf, buf_origin, len_to_copy);
83
+
84
+ len -= len_to_copy;
85
+ buf += len_to_copy;
86
+ }
55
+ }
87
+ }
56
+ }
88
+
57
+
89
+ return buf_origin;
58
+ offset = cvtnum(argv[optind]);
90
+
59
if (offset < 0) {
91
+error:
60
print_cvtnum_err(offset, argv[1]);
92
+ qemu_io_free(buf_origin);
61
return offset;
93
+ return NULL;
62
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
94
+}
63
* exact=true. It is better to err on the "emit more errors" side
95
+
64
* than to be overly permissive.
96
static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
65
*/
66
- ret = blk_truncate(blk, offset, false, PREALLOC_MODE_OFF, 0, &local_err);
67
+ ret = blk_truncate(blk, offset, false, prealloc, 0, &local_err);
68
if (ret < 0) {
69
error_report_err(local_err);
70
return ret;
71
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
72
return 0;
73
}
74
75
-static const cmdinfo_t truncate_cmd = {
76
- .name = "truncate",
77
- .altname = "t",
78
- .cfunc = truncate_f,
79
- .perm = BLK_PERM_WRITE | BLK_PERM_RESIZE,
80
- .argmin = 1,
81
- .argmax = 1,
82
- .args = "off",
83
- .oneline = "truncates the current file at the given offset",
84
-};
85
-
86
static int length_f(BlockBackend *blk, int argc, char **argv)
97
{
87
{
98
uint64_t i;
88
int64_t size;
99
@@ -XXX,XX +XXX,XX @@ static void write_help(void)
100
" -n, -- with -z, don't allow slow fallback\n"
101
" -p, -- ignored for backwards compatibility\n"
102
" -P, -- use different pattern to fill file\n"
103
+" -s, -- use a pattern file to fill the write buffer\n"
104
" -C, -- report statistics in a machine parsable format\n"
105
" -q, -- quiet mode, do not show I/O statistics\n"
106
" -u, -- with -z, allow unmapping\n"
107
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t write_cmd = {
108
.perm = BLK_PERM_WRITE,
109
.argmin = 2,
110
.argmax = -1,
111
- .args = "[-bcCfnquz] [-P pattern] off len",
112
+ .args = "[-bcCfnquz] [-P pattern | -s source_file] off len",
113
.oneline = "writes a number of bytes at a specified offset",
114
.help = write_help,
115
};
116
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
117
{
118
struct timespec t1, t2;
119
bool Cflag = false, qflag = false, bflag = false;
120
- bool Pflag = false, zflag = false, cflag = false;
121
+ bool Pflag = false, zflag = false, cflag = false, sflag = false;
122
int flags = 0;
123
int c, cnt, ret;
124
char *buf = NULL;
125
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
126
/* Some compilers get confused and warn if this is not initialized. */
127
int64_t total = 0;
128
int pattern = 0xcd;
129
+ const char *file_name = NULL;
130
131
- while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) {
132
+ while ((c = getopt(argc, argv, "bcCfnpP:qs:uz")) != -1) {
133
switch (c) {
134
case 'b':
135
bflag = true;
136
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
137
case 'q':
138
qflag = true;
139
break;
140
+ case 's':
141
+ sflag = true;
142
+ file_name = optarg;
143
+ break;
144
case 'u':
145
flags |= BDRV_REQ_MAY_UNMAP;
146
break;
147
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
148
return -EINVAL;
149
}
150
151
- if (zflag && Pflag) {
152
- printf("-z and -P cannot be specified at the same time\n");
153
+ if (zflag + Pflag + sflag > 1) {
154
+ printf("Only one of -z, -P, and -s "
155
+ "can be specified at the same time\n");
156
return -EINVAL;
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
160
}
161
162
if (!zflag) {
163
- buf = qemu_io_alloc(blk, count, pattern);
164
+ if (sflag) {
165
+ buf = qemu_io_alloc_from_file(blk, count, file_name);
166
+ if (!buf) {
167
+ return -EINVAL;
168
+ }
169
+ } else {
170
+ buf = qemu_io_alloc(blk, count, pattern);
171
+ }
172
}
173
174
clock_gettime(CLOCK_MONOTONIC, &t1);
175
--
89
--
176
2.21.0
90
2.29.2
177
91
178
92
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Max Reitz <mreitz@redhat.com>
5
Message-Id: <20201021145859.11201-11-vsementsov@virtuozzo.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
tests/qemu-iotests/iotests.py | 7 ++++++-
9
1 file changed, 6 insertions(+), 1 deletion(-)
10
11
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qemu-iotests/iotests.py
14
+++ b/tests/qemu-iotests/iotests.py
15
@@ -XXX,XX +XXX,XX @@ def qemu_io_log(*args):
16
17
def qemu_io_silent(*args):
18
'''Run qemu-io and return the exit code, suppressing stdout'''
19
- args = qemu_io_args + list(args)
20
+ if '-f' in args or '--image-opts' in args:
21
+ default_args = qemu_io_args_no_fmt
22
+ else:
23
+ default_args = qemu_io_args
24
+
25
+ args = default_args + list(args)
26
exitcode = subprocess.call(args, stdout=open('/dev/null', 'w'))
27
if exitcode < 0:
28
sys.stderr.write('qemu-io received signal %i: %s\n' %
29
--
30
2.29.2
31
32
diff view generated by jsdifflib
1
From: Nir Soffer <nirsof@gmail.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Quoting cache mode is not needed, and most tests use unquoted values.
3
Add a parameter to skip test if some needed additional formats are not
4
Unify all test to use the same style.
4
supported (for example filter drivers).
5
5
6
Message-id: 20190827173432.7656-1-nsoffer@redhat.com
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
7
Message-Id: <20201021145859.11201-12-vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
---
10
tests/qemu-iotests/026 | 4 ++--
11
tests/qemu-iotests/iotests.py | 9 ++++++++-
11
tests/qemu-iotests/039 | 4 ++--
12
1 file changed, 8 insertions(+), 1 deletion(-)
12
tests/qemu-iotests/052 | 2 +-
13
tests/qemu-iotests/091 | 4 ++--
14
4 files changed, 7 insertions(+), 7 deletions(-)
15
13
16
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
14
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
17
index XXXXXXX..XXXXXXX 100755
15
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qemu-iotests/026
16
--- a/tests/qemu-iotests/iotests.py
19
+++ b/tests/qemu-iotests/026
17
+++ b/tests/qemu-iotests/iotests.py
20
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
18
@@ -XXX,XX +XXX,XX @@ def _verify_aio_mode(supported_aio_modes: Sequence[str] = ()) -> None:
21
# Currently only qcow2 supports rebasing
19
if supported_aio_modes and (aiomode not in supported_aio_modes):
22
_supported_fmt qcow2
20
notrun('not suitable for this aio mode: %s' % aiomode)
23
_supported_proto file
21
24
-_default_cache_mode "writethrough"
22
+def _verify_formats(required_formats: Sequence[str] = ()) -> None:
25
-_supported_cache_modes "writethrough" "none"
23
+ usf_list = list(set(required_formats) - set(supported_formats()))
26
+_default_cache_mode writethrough
24
+ if usf_list:
27
+_supported_cache_modes writethrough none
25
+ notrun(f'formats {usf_list} are not whitelisted')
28
# The refcount table tests expect a certain minimum width for refcount entries
26
+
29
# (so that the refcount table actually needs to grow); that minimum is 16 bits,
27
def supports_quorum():
30
# being the default refcount entry width.
28
return 'quorum' in qemu_img_pipe('--help')
31
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
29
32
index XXXXXXX..XXXXXXX 100755
30
@@ -XXX,XX +XXX,XX @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
33
--- a/tests/qemu-iotests/039
31
supported_aio_modes: Sequence[str] = (),
34
+++ b/tests/qemu-iotests/039
32
unsupported_fmts: Sequence[str] = (),
35
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
33
supported_protocols: Sequence[str] = (),
36
_supported_fmt qcow2
34
- unsupported_protocols: Sequence[str] = ()) -> bool:
37
_supported_proto file
35
+ unsupported_protocols: Sequence[str] = (),
38
_supported_os Linux
36
+ required_fmts: Sequence[str] = ()) -> bool:
39
-_default_cache_mode "writethrough"
37
"""
40
-_supported_cache_modes "writethrough"
38
Perform necessary setup for either script-style or unittest-style tests.
41
+_default_cache_mode writethrough
39
42
+_supported_cache_modes writethrough
40
@@ -XXX,XX +XXX,XX @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
43
41
_verify_platform(supported=supported_platforms)
44
size=128M
42
_verify_cache_mode(supported_cache_modes)
45
43
_verify_aio_mode(supported_aio_modes)
46
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
44
+ _verify_formats(required_fmts)
47
index XXXXXXX..XXXXXXX 100755
45
48
--- a/tests/qemu-iotests/052
46
return debug
49
+++ b/tests/qemu-iotests/052
50
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
51
_supported_proto file
52
53
# Don't do O_DIRECT on tmpfs
54
-_supported_cache_modes "writeback" "writethrough" "unsafe"
55
+_supported_cache_modes writeback writethrough unsafe
56
57
size=128M
58
_make_test_img $size
59
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
60
index XXXXXXX..XXXXXXX 100755
61
--- a/tests/qemu-iotests/091
62
+++ b/tests/qemu-iotests/091
63
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
64
_supported_fmt qcow2
65
_supported_proto file
66
_supported_os Linux
67
-_default_cache_mode "none"
68
-_supported_cache_modes "writethrough" "none" "writeback"
69
+_default_cache_mode none
70
+_supported_cache_modes writethrough none writeback
71
72
size=1G
73
47
74
--
48
--
75
2.21.0
49
2.29.2
76
50
77
51
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Message-Id: <20201021145859.11201-13-vsementsov@virtuozzo.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
tests/qemu-iotests/298 | 186 +++++++++++++++++++++++++++++++++++++
9
tests/qemu-iotests/298.out | 5 +
10
tests/qemu-iotests/group | 1 +
11
3 files changed, 192 insertions(+)
12
create mode 100644 tests/qemu-iotests/298
13
create mode 100644 tests/qemu-iotests/298.out
14
15
diff --git a/tests/qemu-iotests/298 b/tests/qemu-iotests/298
16
new file mode 100644
17
index XXXXXXX..XXXXXXX
18
--- /dev/null
19
+++ b/tests/qemu-iotests/298
20
@@ -XXX,XX +XXX,XX @@
21
+#!/usr/bin/env python3
22
+#
23
+# Test for preallocate filter
24
+#
25
+# Copyright (c) 2020 Virtuozzo International GmbH.
26
+#
27
+# This program is free software; you can redistribute it and/or modify
28
+# it under the terms of the GNU General Public License as published by
29
+# the Free Software Foundation; either version 2 of the License, or
30
+# (at your option) any later version.
31
+#
32
+# This program is distributed in the hope that it will be useful,
33
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
34
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35
+# GNU General Public License for more details.
36
+#
37
+# You should have received a copy of the GNU General Public License
38
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
39
+#
40
+
41
+import os
42
+import iotests
43
+
44
+MiB = 1024 * 1024
45
+disk = os.path.join(iotests.test_dir, 'disk')
46
+overlay = os.path.join(iotests.test_dir, 'overlay')
47
+refdisk = os.path.join(iotests.test_dir, 'refdisk')
48
+drive_opts = f'node-name=disk,driver={iotests.imgfmt},' \
49
+ f'file.node-name=filter,file.driver=preallocate,' \
50
+ f'file.file.node-name=file,file.file.filename={disk}'
51
+
52
+
53
+class TestPreallocateBase(iotests.QMPTestCase):
54
+ def setUp(self):
55
+ iotests.qemu_img_create('-f', iotests.imgfmt, disk, str(10 * MiB))
56
+
57
+ def tearDown(self):
58
+ try:
59
+ self.check_small()
60
+ check = iotests.qemu_img_check(disk)
61
+ self.assertFalse('leaks' in check)
62
+ self.assertFalse('corruptions' in check)
63
+ self.assertEqual(check['check-errors'], 0)
64
+ finally:
65
+ os.remove(disk)
66
+
67
+ def check_big(self):
68
+ self.assertTrue(os.path.getsize(disk) > 100 * MiB)
69
+
70
+ def check_small(self):
71
+ self.assertTrue(os.path.getsize(disk) < 10 * MiB)
72
+
73
+
74
+class TestQemuImg(TestPreallocateBase):
75
+ def test_qemu_img(self):
76
+ p = iotests.QemuIoInteractive('--image-opts', drive_opts)
77
+
78
+ p.cmd('write 0 1M')
79
+ p.cmd('flush')
80
+
81
+ self.check_big()
82
+
83
+ p.close()
84
+
85
+
86
+class TestPreallocateFilter(TestPreallocateBase):
87
+ def setUp(self):
88
+ super().setUp()
89
+ self.vm = iotests.VM().add_drive(path=None, opts=drive_opts)
90
+ self.vm.launch()
91
+
92
+ def tearDown(self):
93
+ self.vm.shutdown()
94
+ super().tearDown()
95
+
96
+ def test_prealloc(self):
97
+ self.vm.hmp_qemu_io('drive0', 'write 0 1M')
98
+ self.check_big()
99
+
100
+ def test_external_snapshot(self):
101
+ self.test_prealloc()
102
+
103
+ result = self.vm.qmp('blockdev-snapshot-sync', node_name='disk',
104
+ snapshot_file=overlay,
105
+ snapshot_node_name='overlay')
106
+ self.assert_qmp(result, 'return', {})
107
+
108
+ # on reopen to r-o base preallocation should be dropped
109
+ self.check_small()
110
+
111
+ self.vm.hmp_qemu_io('drive0', 'write 1M 1M')
112
+
113
+ result = self.vm.qmp('block-commit', device='overlay')
114
+ self.assert_qmp(result, 'return', {})
115
+ self.complete_and_wait()
116
+
117
+ # commit of new megabyte should trigger preallocation
118
+ self.check_big()
119
+
120
+ def test_reopen_opts(self):
121
+ result = self.vm.qmp('x-blockdev-reopen', **{
122
+ 'node-name': 'disk',
123
+ 'driver': iotests.imgfmt,
124
+ 'file': {
125
+ 'node-name': 'filter',
126
+ 'driver': 'preallocate',
127
+ 'prealloc-size': 20 * MiB,
128
+ 'prealloc-align': 5 * MiB,
129
+ 'file': {
130
+ 'node-name': 'file',
131
+ 'driver': 'file',
132
+ 'filename': disk
133
+ }
134
+ }
135
+ })
136
+ self.assert_qmp(result, 'return', {})
137
+
138
+ self.vm.hmp_qemu_io('drive0', 'write 0 1M')
139
+ self.assertTrue(os.path.getsize(disk) == 25 * MiB)
140
+
141
+
142
+class TestTruncate(iotests.QMPTestCase):
143
+ def setUp(self):
144
+ iotests.qemu_img_create('-f', iotests.imgfmt, disk, str(10 * MiB))
145
+ iotests.qemu_img_create('-f', iotests.imgfmt, refdisk, str(10 * MiB))
146
+
147
+ def tearDown(self):
148
+ os.remove(disk)
149
+ os.remove(refdisk)
150
+
151
+ def do_test(self, prealloc_mode, new_size):
152
+ ret = iotests.qemu_io_silent('--image-opts', '-c', 'write 0 10M', '-c',
153
+ f'truncate -m {prealloc_mode} {new_size}',
154
+ drive_opts)
155
+ self.assertEqual(ret, 0)
156
+
157
+ ret = iotests.qemu_io_silent('-f', iotests.imgfmt, '-c', 'write 0 10M',
158
+ '-c',
159
+ f'truncate -m {prealloc_mode} {new_size}',
160
+ refdisk)
161
+ self.assertEqual(ret, 0)
162
+
163
+ stat = os.stat(disk)
164
+ refstat = os.stat(refdisk)
165
+
166
+ # Probably we'll want preallocate filter to keep align to cluster when
167
+ # shrink preallocation, so, ignore small differece
168
+ self.assertLess(abs(stat.st_size - refstat.st_size), 64 * 1024)
169
+
170
+ # Preallocate filter may leak some internal clusters (for example, if
171
+ # guest write far over EOF, skipping some clusters - they will remain
172
+ # fallocated, preallocate filter don't care about such leaks, it drops
173
+ # only trailing preallocation.
174
+ self.assertLess(abs(stat.st_blocks - refstat.st_blocks) * 512,
175
+ 1024 * 1024)
176
+
177
+ def test_real_shrink(self):
178
+ self.do_test('off', '5M')
179
+
180
+ def test_truncate_inside_preallocated_area__falloc(self):
181
+ self.do_test('falloc', '50M')
182
+
183
+ def test_truncate_inside_preallocated_area__metadata(self):
184
+ self.do_test('metadata', '50M')
185
+
186
+ def test_truncate_inside_preallocated_area__full(self):
187
+ self.do_test('full', '50M')
188
+
189
+ def test_truncate_inside_preallocated_area__off(self):
190
+ self.do_test('off', '50M')
191
+
192
+ def test_truncate_over_preallocated_area__falloc(self):
193
+ self.do_test('falloc', '150M')
194
+
195
+ def test_truncate_over_preallocated_area__metadata(self):
196
+ self.do_test('metadata', '150M')
197
+
198
+ def test_truncate_over_preallocated_area__full(self):
199
+ self.do_test('full', '150M')
200
+
201
+ def test_truncate_over_preallocated_area__off(self):
202
+ self.do_test('off', '150M')
203
+
204
+
205
+if __name__ == '__main__':
206
+ iotests.main(supported_fmts=['qcow2'], required_fmts=['preallocate'])
207
diff --git a/tests/qemu-iotests/298.out b/tests/qemu-iotests/298.out
208
new file mode 100644
209
index XXXXXXX..XXXXXXX
210
--- /dev/null
211
+++ b/tests/qemu-iotests/298.out
212
@@ -XXX,XX +XXX,XX @@
213
+.............
214
+----------------------------------------------------------------------
215
+Ran 13 tests
216
+
217
+OK
218
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
219
index XXXXXXX..XXXXXXX 100644
220
--- a/tests/qemu-iotests/group
221
+++ b/tests/qemu-iotests/group
222
@@ -XXX,XX +XXX,XX @@
223
295 rw
224
296 rw
225
297 meta
226
+298
227
299 auto quick
228
300 migration
229
301 backing quick
230
--
231
2.29.2
232
233
diff view generated by jsdifflib
1
The error message for the test case where we have a quorum node for
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
which no directory name can be generated is different: For
3
twoGbMaxExtentSparse, it complains that it cannot open the extent file.
4
For other (sub)formats, it just notes that it cannot determine the
5
backing file path. Both are fine, but just disable twoGbMaxExtentSparse
6
for simplicity's sake.
7
2
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
4
Message-Id: <20201021145859.11201-14-vsementsov@virtuozzo.com>
10
Message-id: 20190815153638.4600-7-mreitz@redhat.com
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
7
---
14
tests/qemu-iotests/110 | 3 ++-
8
scripts/simplebench/simplebench.py | 12 ++++++------
15
1 file changed, 2 insertions(+), 1 deletion(-)
9
1 file changed, 6 insertions(+), 6 deletions(-)
16
10
17
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
11
diff --git a/scripts/simplebench/simplebench.py b/scripts/simplebench/simplebench.py
18
index XXXXXXX..XXXXXXX 100755
12
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/110
13
--- a/scripts/simplebench/simplebench.py
20
+++ b/tests/qemu-iotests/110
14
+++ b/scripts/simplebench/simplebench.py
21
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
15
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
22
# Any format supporting backing files
16
23
_supported_fmt qed qcow qcow2 vmdk
17
result = {'runs': runs}
24
_supported_proto file
18
25
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
19
- successed = [r for r in runs if ('seconds' in r)]
26
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
20
- if successed:
27
+ "subformat=twoGbMaxExtentSparse"
21
- avg = sum(r['seconds'] for r in successed) / len(successed)
28
22
+ succeeded = [r for r in runs if ('seconds' in r)]
29
TEST_IMG_REL=$(basename "$TEST_IMG")
23
+ if succeeded:
24
+ avg = sum(r['seconds'] for r in succeeded) / len(succeeded)
25
result['average'] = avg
26
- result['delta'] = max(abs(r['seconds'] - avg) for r in successed)
27
+ result['delta'] = max(abs(r['seconds'] - avg) for r in succeeded)
28
29
- if len(successed) < count:
30
- result['n-failed'] = count - len(successed)
31
+ if len(succeeded) < count:
32
+ result['n-failed'] = count - len(succeeded)
33
34
return result
30
35
31
--
36
--
32
2.21.0
37
2.29.2
33
38
34
39
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Support benchmarks returning not seconds but iops. We'll use it for
4
further new test.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20201021145859.11201-15-vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
scripts/simplebench/simplebench.py | 38 ++++++++++++++++++++++--------
12
1 file changed, 28 insertions(+), 10 deletions(-)
13
14
diff --git a/scripts/simplebench/simplebench.py b/scripts/simplebench/simplebench.py
15
index XXXXXXX..XXXXXXX 100644
16
--- a/scripts/simplebench/simplebench.py
17
+++ b/scripts/simplebench/simplebench.py
18
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
19
20
test_func -- benchmarking function with prototype
21
test_func(env, case), which takes test_env and test_case
22
- arguments and returns {'seconds': int} (which is benchmark
23
- result) on success and {'error': str} on error. Returned
24
- dict may contain any other additional fields.
25
+ arguments and on success returns dict with 'seconds' or
26
+ 'iops' (or both) fields, specifying the benchmark result.
27
+ If both 'iops' and 'seconds' provided, the 'iops' is
28
+ considered the main, and 'seconds' is just an additional
29
+ info. On failure test_func should return {'error': str}.
30
+ Returned dict may contain any other additional fields.
31
test_env -- test environment - opaque first argument for test_func
32
test_case -- test case - opaque second argument for test_func
33
count -- how many times to call test_func, to calculate average
34
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
35
36
Returns dict with the following fields:
37
'runs': list of test_func results
38
- 'average': average seconds per run (exists only if at least one run
39
- succeeded)
40
+ 'dimension': dimension of results, may be 'seconds' or 'iops'
41
+ 'average': average value (iops or seconds) per run (exists only if at
42
+ least one run succeeded)
43
'delta': maximum delta between test_func result and the average
44
(exists only if at least one run succeeded)
45
'n-failed': number of failed runs (exists only if at least one run
46
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
47
48
result = {'runs': runs}
49
50
- succeeded = [r for r in runs if ('seconds' in r)]
51
+ succeeded = [r for r in runs if ('seconds' in r or 'iops' in r)]
52
if succeeded:
53
- avg = sum(r['seconds'] for r in succeeded) / len(succeeded)
54
+ if 'iops' in succeeded[0]:
55
+ assert all('iops' in r for r in succeeded)
56
+ dim = 'iops'
57
+ else:
58
+ assert all('seconds' in r for r in succeeded)
59
+ assert all('iops' not in r for r in succeeded)
60
+ dim = 'seconds'
61
+ avg = sum(r[dim] for r in succeeded) / len(succeeded)
62
+ result['dimension'] = dim
63
result['average'] = avg
64
- result['delta'] = max(abs(r['seconds'] - avg) for r in succeeded)
65
+ result['delta'] = max(abs(r[dim] - avg) for r in succeeded)
66
67
if len(succeeded) < count:
68
result['n-failed'] = count - len(succeeded)
69
@@ -XXX,XX +XXX,XX @@ def ascii(results):
70
"""Return ASCII representation of bench() returned dict."""
71
from tabulate import tabulate
72
73
+ dim = None
74
tab = [[""] + [c['id'] for c in results['envs']]]
75
for case in results['cases']:
76
row = [case['id']]
77
for env in results['envs']:
78
- row.append(ascii_one(results['tab'][case['id']][env['id']]))
79
+ res = results['tab'][case['id']][env['id']]
80
+ if dim is None:
81
+ dim = res['dimension']
82
+ else:
83
+ assert dim == res['dimension']
84
+ row.append(ascii_one(res))
85
tab.append(row)
86
87
- return tabulate(tab)
88
+ return f'All results are in {dim}\n\n' + tabulate(tab)
89
--
90
2.29.2
91
92
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Standard deviation is more usual to see after +- than current maximum
4
of deviations.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20201021145859.11201-16-vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
scripts/simplebench/simplebench.py | 11 ++++++-----
12
1 file changed, 6 insertions(+), 5 deletions(-)
13
14
diff --git a/scripts/simplebench/simplebench.py b/scripts/simplebench/simplebench.py
15
index XXXXXXX..XXXXXXX 100644
16
--- a/scripts/simplebench/simplebench.py
17
+++ b/scripts/simplebench/simplebench.py
18
@@ -XXX,XX +XXX,XX @@
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
#
21
22
+import statistics
23
+
24
25
def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
26
"""Benchmark one test-case
27
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
28
'dimension': dimension of results, may be 'seconds' or 'iops'
29
'average': average value (iops or seconds) per run (exists only if at
30
least one run succeeded)
31
- 'delta': maximum delta between test_func result and the average
32
+ 'stdev': standard deviation of results
33
(exists only if at least one run succeeded)
34
'n-failed': number of failed runs (exists only if at least one run
35
failed)
36
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
37
assert all('seconds' in r for r in succeeded)
38
assert all('iops' not in r for r in succeeded)
39
dim = 'seconds'
40
- avg = sum(r[dim] for r in succeeded) / len(succeeded)
41
result['dimension'] = dim
42
- result['average'] = avg
43
- result['delta'] = max(abs(r[dim] - avg) for r in succeeded)
44
+ result['average'] = statistics.mean(r[dim] for r in succeeded)
45
+ result['stdev'] = statistics.stdev(r[dim] for r in succeeded)
46
47
if len(succeeded) < count:
48
result['n-failed'] = count - len(succeeded)
49
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
50
def ascii_one(result):
51
"""Return ASCII representation of bench_one() returned dict."""
52
if 'average' in result:
53
- s = '{:.2f} +- {:.2f}'.format(result['average'], result['delta'])
54
+ s = '{:.2f} +- {:.2f}'.format(result['average'], result['stdev'])
55
if 'n-failed' in result:
56
s += '\n({} failed)'.format(result['n-failed'])
57
return s
58
--
59
2.29.2
60
61
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Next patch will use utf8 plus-minus symbol, let's use more generic (and
4
more readable) name.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20201021145859.11201-17-vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
scripts/simplebench/bench-example.py | 2 +-
12
scripts/simplebench/bench_write_req.py | 2 +-
13
scripts/simplebench/simplebench.py | 10 +++++-----
14
3 files changed, 7 insertions(+), 7 deletions(-)
15
16
diff --git a/scripts/simplebench/bench-example.py b/scripts/simplebench/bench-example.py
17
index XXXXXXX..XXXXXXX 100644
18
--- a/scripts/simplebench/bench-example.py
19
+++ b/scripts/simplebench/bench-example.py
20
@@ -XXX,XX +XXX,XX @@ test_envs = [
21
]
22
23
result = simplebench.bench(bench_func, test_envs, test_cases, count=3)
24
-print(simplebench.ascii(result))
25
+print(simplebench.results_to_text(result))
26
diff --git a/scripts/simplebench/bench_write_req.py b/scripts/simplebench/bench_write_req.py
27
index XXXXXXX..XXXXXXX 100755
28
--- a/scripts/simplebench/bench_write_req.py
29
+++ b/scripts/simplebench/bench_write_req.py
30
@@ -XXX,XX +XXX,XX @@ if __name__ == '__main__':
31
32
result = simplebench.bench(bench_func, test_envs, test_cases, count=3,
33
initial_run=False)
34
- print(simplebench.ascii(result))
35
+ print(simplebench.results_to_text(result))
36
diff --git a/scripts/simplebench/simplebench.py b/scripts/simplebench/simplebench.py
37
index XXXXXXX..XXXXXXX 100644
38
--- a/scripts/simplebench/simplebench.py
39
+++ b/scripts/simplebench/simplebench.py
40
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
41
return result
42
43
44
-def ascii_one(result):
45
- """Return ASCII representation of bench_one() returned dict."""
46
+def result_to_text(result):
47
+ """Return text representation of bench_one() returned dict."""
48
if 'average' in result:
49
s = '{:.2f} +- {:.2f}'.format(result['average'], result['stdev'])
50
if 'n-failed' in result:
51
@@ -XXX,XX +XXX,XX @@ def bench(test_func, test_envs, test_cases, *args, **vargs):
52
return results
53
54
55
-def ascii(results):
56
- """Return ASCII representation of bench() returned dict."""
57
+def results_to_text(results):
58
+ """Return text representation of bench() returned dict."""
59
from tabulate import tabulate
60
61
dim = None
62
@@ -XXX,XX +XXX,XX @@ def ascii(results):
63
dim = res['dimension']
64
else:
65
assert dim == res['dimension']
66
- row.append(ascii_one(res))
67
+ row.append(result_to_text(res))
68
tab.append(row)
69
70
return f'All results are in {dim}\n\n' + tabulate(tab)
71
--
72
2.29.2
73
74
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Let's keep view part in separate: this way it's better to improve it in
4
the following commits.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20201021145859.11201-18-vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
scripts/simplebench/bench-example.py | 3 +-
12
scripts/simplebench/bench_write_req.py | 3 +-
13
scripts/simplebench/results_to_text.py | 48 ++++++++++++++++++++++++++
14
scripts/simplebench/simplebench.py | 31 -----------------
15
4 files changed, 52 insertions(+), 33 deletions(-)
16
create mode 100644 scripts/simplebench/results_to_text.py
17
18
diff --git a/scripts/simplebench/bench-example.py b/scripts/simplebench/bench-example.py
19
index XXXXXXX..XXXXXXX 100644
20
--- a/scripts/simplebench/bench-example.py
21
+++ b/scripts/simplebench/bench-example.py
22
@@ -XXX,XX +XXX,XX @@
23
#
24
25
import simplebench
26
+from results_to_text import results_to_text
27
from bench_block_job import bench_block_copy, drv_file, drv_nbd
28
29
30
@@ -XXX,XX +XXX,XX @@ test_envs = [
31
]
32
33
result = simplebench.bench(bench_func, test_envs, test_cases, count=3)
34
-print(simplebench.results_to_text(result))
35
+print(results_to_text(result))
36
diff --git a/scripts/simplebench/bench_write_req.py b/scripts/simplebench/bench_write_req.py
37
index XXXXXXX..XXXXXXX 100755
38
--- a/scripts/simplebench/bench_write_req.py
39
+++ b/scripts/simplebench/bench_write_req.py
40
@@ -XXX,XX +XXX,XX @@ import sys
41
import os
42
import subprocess
43
import simplebench
44
+from results_to_text import results_to_text
45
46
47
def bench_func(env, case):
48
@@ -XXX,XX +XXX,XX @@ if __name__ == '__main__':
49
50
result = simplebench.bench(bench_func, test_envs, test_cases, count=3,
51
initial_run=False)
52
- print(simplebench.results_to_text(result))
53
+ print(results_to_text(result))
54
diff --git a/scripts/simplebench/results_to_text.py b/scripts/simplebench/results_to_text.py
55
new file mode 100644
56
index XXXXXXX..XXXXXXX
57
--- /dev/null
58
+++ b/scripts/simplebench/results_to_text.py
59
@@ -XXX,XX +XXX,XX @@
60
+# Simple benchmarking framework
61
+#
62
+# Copyright (c) 2019 Virtuozzo International GmbH.
63
+#
64
+# This program is free software; you can redistribute it and/or modify
65
+# it under the terms of the GNU General Public License as published by
66
+# the Free Software Foundation; either version 2 of the License, or
67
+# (at your option) any later version.
68
+#
69
+# This program is distributed in the hope that it will be useful,
70
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
71
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72
+# GNU General Public License for more details.
73
+#
74
+# You should have received a copy of the GNU General Public License
75
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
76
+#
77
+
78
+
79
+def result_to_text(result):
80
+ """Return text representation of bench_one() returned dict."""
81
+ if 'average' in result:
82
+ s = '{:.2f} +- {:.2f}'.format(result['average'], result['stdev'])
83
+ if 'n-failed' in result:
84
+ s += '\n({} failed)'.format(result['n-failed'])
85
+ return s
86
+ else:
87
+ return 'FAILED'
88
+
89
+
90
+def results_to_text(results):
91
+ """Return text representation of bench() returned dict."""
92
+ from tabulate import tabulate
93
+
94
+ dim = None
95
+ tab = [[""] + [c['id'] for c in results['envs']]]
96
+ for case in results['cases']:
97
+ row = [case['id']]
98
+ for env in results['envs']:
99
+ res = results['tab'][case['id']][env['id']]
100
+ if dim is None:
101
+ dim = res['dimension']
102
+ else:
103
+ assert dim == res['dimension']
104
+ row.append(result_to_text(res))
105
+ tab.append(row)
106
+
107
+ return f'All results are in {dim}\n\n' + tabulate(tab)
108
diff --git a/scripts/simplebench/simplebench.py b/scripts/simplebench/simplebench.py
109
index XXXXXXX..XXXXXXX 100644
110
--- a/scripts/simplebench/simplebench.py
111
+++ b/scripts/simplebench/simplebench.py
112
@@ -XXX,XX +XXX,XX @@ def bench_one(test_func, test_env, test_case, count=5, initial_run=True):
113
return result
114
115
116
-def result_to_text(result):
117
- """Return text representation of bench_one() returned dict."""
118
- if 'average' in result:
119
- s = '{:.2f} +- {:.2f}'.format(result['average'], result['stdev'])
120
- if 'n-failed' in result:
121
- s += '\n({} failed)'.format(result['n-failed'])
122
- return s
123
- else:
124
- return 'FAILED'
125
-
126
-
127
def bench(test_func, test_envs, test_cases, *args, **vargs):
128
"""Fill benchmark table
129
130
@@ -XXX,XX +XXX,XX @@ def bench(test_func, test_envs, test_cases, *args, **vargs):
131
132
print('Done')
133
return results
134
-
135
-
136
-def results_to_text(results):
137
- """Return text representation of bench() returned dict."""
138
- from tabulate import tabulate
139
-
140
- dim = None
141
- tab = [[""] + [c['id'] for c in results['envs']]]
142
- for case in results['cases']:
143
- row = [case['id']]
144
- for env in results['envs']:
145
- res = results['tab'][case['id']][env['id']]
146
- if dim is None:
147
- dim = res['dimension']
148
- else:
149
- assert dim == res['dimension']
150
- row.append(result_to_text(res))
151
- tab.append(row)
152
-
153
- return f'All results are in {dim}\n\n' + tabulate(tab)
154
--
155
2.29.2
156
157
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Move to generic format for floats and percentage for error.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Message-Id: <20201021145859.11201-19-vsementsov@virtuozzo.com>
7
Acked-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
scripts/simplebench/results_to_text.py | 13 ++++++++++++-
11
1 file changed, 12 insertions(+), 1 deletion(-)
12
13
diff --git a/scripts/simplebench/results_to_text.py b/scripts/simplebench/results_to_text.py
14
index XXXXXXX..XXXXXXX 100644
15
--- a/scripts/simplebench/results_to_text.py
16
+++ b/scripts/simplebench/results_to_text.py
17
@@ -XXX,XX +XXX,XX @@
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#
20
21
+import math
22
+
23
+
24
+def format_value(x, stdev):
25
+ stdev_pr = stdev / x * 100
26
+ if stdev_pr < 1.5:
27
+ # don't care too much
28
+ return f'{x:.2g}'
29
+ else:
30
+ return f'{x:.2g} ± {math.ceil(stdev_pr)}%'
31
+
32
33
def result_to_text(result):
34
"""Return text representation of bench_one() returned dict."""
35
if 'average' in result:
36
- s = '{:.2f} +- {:.2f}'.format(result['average'], result['stdev'])
37
+ s = format_value(result['average'], result['stdev'])
38
if 'n-failed' in result:
39
s += '\n({} failed)'.format(result['n-failed'])
40
return s
41
--
42
2.29.2
43
44
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Performance improvements / degradations are usually discussed in
4
percentage. Let's make the script calculate it for us.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20201021145859.11201-20-vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
[mreitz: 'seconds' instead of 'secs']
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
scripts/simplebench/results_to_text.py | 67 +++++++++++++++++++++++---
13
1 file changed, 60 insertions(+), 7 deletions(-)
14
15
diff --git a/scripts/simplebench/results_to_text.py b/scripts/simplebench/results_to_text.py
16
index XXXXXXX..XXXXXXX 100644
17
--- a/scripts/simplebench/results_to_text.py
18
+++ b/scripts/simplebench/results_to_text.py
19
@@ -XXX,XX +XXX,XX @@
20
#
21
22
import math
23
+import tabulate
24
+
25
+# We want leading whitespace for difference row cells (see below)
26
+tabulate.PRESERVE_WHITESPACE = True
27
28
29
def format_value(x, stdev):
30
@@ -XXX,XX +XXX,XX @@ def result_to_text(result):
31
return 'FAILED'
32
33
34
-def results_to_text(results):
35
- """Return text representation of bench() returned dict."""
36
- from tabulate import tabulate
37
-
38
+def results_dimension(results):
39
dim = None
40
- tab = [[""] + [c['id'] for c in results['envs']]]
41
for case in results['cases']:
42
- row = [case['id']]
43
for env in results['envs']:
44
res = results['tab'][case['id']][env['id']]
45
if dim is None:
46
dim = res['dimension']
47
else:
48
assert dim == res['dimension']
49
+
50
+ assert dim in ('iops', 'seconds')
51
+
52
+ return dim
53
+
54
+
55
+def results_to_text(results):
56
+ """Return text representation of bench() returned dict."""
57
+ n_columns = len(results['envs'])
58
+ named_columns = n_columns > 2
59
+ dim = results_dimension(results)
60
+ tab = []
61
+
62
+ if named_columns:
63
+ # Environment columns are named A, B, ...
64
+ tab.append([''] + [chr(ord('A') + i) for i in range(n_columns)])
65
+
66
+ tab.append([''] + [c['id'] for c in results['envs']])
67
+
68
+ for case in results['cases']:
69
+ row = [case['id']]
70
+ case_results = results['tab'][case['id']]
71
+ for env in results['envs']:
72
+ res = case_results[env['id']]
73
row.append(result_to_text(res))
74
tab.append(row)
75
76
- return f'All results are in {dim}\n\n' + tabulate(tab)
77
+ # Add row of difference between columns. For each column starting from
78
+ # B we calculate difference with all previous columns.
79
+ row = ['', ''] # case name and first column
80
+ for i in range(1, n_columns):
81
+ cell = ''
82
+ env = results['envs'][i]
83
+ res = case_results[env['id']]
84
+
85
+ if 'average' not in res:
86
+ # Failed result
87
+ row.append(cell)
88
+ continue
89
+
90
+ for j in range(0, i):
91
+ env_j = results['envs'][j]
92
+ res_j = case_results[env_j['id']]
93
+ cell += ' '
94
+
95
+ if 'average' not in res_j:
96
+ # Failed result
97
+ cell += '--'
98
+ continue
99
+
100
+ col_j = tab[0][j + 1] if named_columns else ''
101
+ diff_pr = round((res['average'] - res_j['average']) /
102
+ res_j['average'] * 100)
103
+ cell += f' {col_j}{diff_pr:+}%'
104
+ row.append(cell)
105
+ tab.append(row)
106
+
107
+ return f'All results are in {dim}\n\n' + tabulate.tabulate(tab)
108
--
109
2.29.2
110
111
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
The sanitizers (especially the address sanitizer from Clang) are
3
Make results_to_text a tool to dump results saved in JSON file.
4
sometimes printing out warnings or false positives - this spoils
5
the output of the iotests, causing some of the tests to fail.
6
Thus let's skip the automatic iotests during "make check" when the
7
user configured QEMU with --enable-sanitizers.
8
4
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-id: 20190823084203.29734-1-thuth@redhat.com
6
Message-Id: <20201021145859.11201-21-vsementsov@virtuozzo.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
9
---
13
tests/check-block.sh | 5 +++++
10
scripts/simplebench/results_to_text.py | 14 ++++++++++++++
14
1 file changed, 5 insertions(+)
11
1 file changed, 14 insertions(+)
12
mode change 100644 => 100755 scripts/simplebench/results_to_text.py
15
13
16
diff --git a/tests/check-block.sh b/tests/check-block.sh
14
diff --git a/scripts/simplebench/results_to_text.py b/scripts/simplebench/results_to_text.py
17
index XXXXXXX..XXXXXXX 100755
15
old mode 100644
18
--- a/tests/check-block.sh
16
new mode 100755
19
+++ b/tests/check-block.sh
17
index XXXXXXX..XXXXXXX
20
@@ -XXX,XX +XXX,XX @@ if grep -q "TARGET_GPROF=y" *-softmmu/config-target.mak 2>/dev/null ; then
18
--- a/scripts/simplebench/results_to_text.py
21
exit 0
19
+++ b/scripts/simplebench/results_to_text.py
22
fi
20
@@ -XXX,XX +XXX,XX @@
23
21
+#!/usr/bin/env python3
24
+if grep -q "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ; then
22
+#
25
+ echo "Sanitizers are enabled ==> Not running the qemu-iotests."
23
# Simple benchmarking framework
26
+ exit 0
24
#
27
+fi
25
# Copyright (c) 2019 Virtuozzo International GmbH.
26
@@ -XXX,XX +XXX,XX @@ def results_to_text(results):
27
tab.append(row)
28
29
return f'All results are in {dim}\n\n' + tabulate.tabulate(tab)
28
+
30
+
29
if [ -z "$(find . -name 'qemu-system-*' -print)" ]; then
31
+
30
echo "No qemu-system binary available ==> Not running the qemu-iotests."
32
+if __name__ == '__main__':
31
exit 0
33
+ import sys
34
+ import json
35
+
36
+ if len(sys.argv) < 2:
37
+ print(f'USAGE: {sys.argv[0]} results.json')
38
+ exit(1)
39
+
40
+ with open(sys.argv[1]) as f:
41
+ print(results_to_text(json.load(f)))
32
--
42
--
33
2.21.0
43
2.29.2
34
44
35
45
diff view generated by jsdifflib
1
We had a test for a case where relative extent paths did not work, but
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
unfortunately we just fixed the underlying problem, so it works now.
3
This patch adds a new test case that still fails.
4
2
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Benchmark for new preallocate filter.
6
Reviewed-by: John Snow <jsnow@redhat.com>
4
7
Message-id: 20190815153638.4600-4-mreitz@redhat.com
5
Example usage:
8
Reviewed-by: John Snow <jsnow@redhat.com>
6
./bench_prealloc.py ../../build/qemu-img \
7
ssd-ext4:/path/to/mount/point \
8
ssd-xfs:/path2 hdd-ext4:/path3 hdd-xfs:/path4
9
10
The benchmark shows performance improvement (or degradation) when use
11
new preallocate filter with qcow2 image.
12
13
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Message-Id: <20201021145859.11201-22-vsementsov@virtuozzo.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
17
---
11
tests/qemu-iotests/059 | 27 +++++++++++++++++++++++++++
18
scripts/simplebench/bench_prealloc.py | 132 ++++++++++++++++++++++++++
12
tests/qemu-iotests/059.out | 4 ++++
19
1 file changed, 132 insertions(+)
13
2 files changed, 31 insertions(+)
20
create mode 100755 scripts/simplebench/bench_prealloc.py
14
21
15
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
22
diff --git a/scripts/simplebench/bench_prealloc.py b/scripts/simplebench/bench_prealloc.py
16
index XXXXXXX..XXXXXXX 100755
23
new file mode 100755
17
--- a/tests/qemu-iotests/059
24
index XXXXXXX..XXXXXXX
18
+++ b/tests/qemu-iotests/059
25
--- /dev/null
19
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2
26
+++ b/scripts/simplebench/bench_prealloc.py
20
27
@@ -XXX,XX +XXX,XX @@
21
echo
28
+#!/usr/bin/env python3
22
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
29
+#
23
+
30
+# Benchmark preallocate filter
24
+echo '--- blkdebug ---'
31
+#
25
# Should work, because bdrv_dirname() works fine with blkdebug
32
+# Copyright (c) 2020 Virtuozzo International GmbH.
26
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
33
+#
27
$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
34
+# This program is free software; you can redistribute it and/or modify
28
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TE
35
+# it under the terms of the GNU General Public License as published by
29
| _filter_testdir | _filter_imgfmt | _filter_img_info
36
+# the Free Software Foundation; either version 2 of the License, or
30
_cleanup_test_img
37
+# (at your option) any later version.
31
38
+#
32
+echo '--- quorum ---'
39
+# This program is distributed in the hope that it will be useful,
33
+# Should not work, because bdrv_dirname() does not work with quorum
40
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
34
+IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
41
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35
+cp "$TEST_IMG" "$TEST_IMG.orig"
42
+# GNU General Public License for more details.
36
+
43
+#
37
+filename="json:{
44
+# You should have received a copy of the GNU General Public License
38
+ \"driver\": \"$IMGFMT\",
45
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
39
+ \"file\": {
46
+#
40
+ \"driver\": \"quorum\",
41
+ \"children\": [ {
42
+ \"driver\": \"file\",
43
+ \"filename\": \"$TEST_IMG\"
44
+ }, {
45
+ \"driver\": \"file\",
46
+ \"filename\": \"$TEST_IMG.orig\"
47
+ } ],
48
+ \"vote-threshold\": 1
49
+ } }"
50
+
51
+filename=$(echo "$filename" | tr '\n' ' ' | sed -e 's/\s\+/ /g')
52
+$QEMU_IMG info "$filename" 2>&1 \
53
+ | sed -e "s/'json:[^']*'/\$QUORUM_FILE/g" \
54
+ | _filter_testdir | _filter_imgfmt | _filter_img_info
55
+
47
+
56
+
48
+
57
echo
49
+import sys
58
echo "=== Testing version 3 ==="
50
+import os
59
_use_sample_img iotest-version3.vmdk.bz2
51
+import subprocess
60
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
52
+import re
61
index XXXXXXX..XXXXXXX 100644
53
+import json
62
--- a/tests/qemu-iotests/059.out
54
+
63
+++ b/tests/qemu-iotests/059.out
55
+import simplebench
64
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
56
+from results_to_text import results_to_text
65
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
57
+
66
58
+
67
=== Testing monolithicFlat with internally generated JSON file name ===
59
+def qemu_img_bench(args):
68
+--- blkdebug ---
60
+ p = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
69
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
61
+ universal_newlines=True)
70
format name: IMGFMT
62
+
71
cluster size: 0 bytes
63
+ if p.returncode == 0:
72
vm state offset: 0 bytes
64
+ try:
73
+--- quorum ---
65
+ m = re.search(r'Run completed in (\d+.\d+) seconds.', p.stdout)
74
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
66
+ return {'seconds': float(m.group(1))}
75
+qemu-img: Could not open $QUORUM_FILE: Cannot use relative paths with VMDK descriptor file $QUORUM_FILE: Cannot generate a base directory for quorum nodes
67
+ except Exception:
76
68
+ return {'error': f'failed to parse qemu-img output: {p.stdout}'}
77
=== Testing version 3 ===
69
+ else:
78
image: TEST_DIR/iotest-version3.IMGFMT
70
+ return {'error': f'qemu-img failed: {p.returncode}: {p.stdout}'}
71
+
72
+
73
+def bench_func(env, case):
74
+ fname = f"{case['dir']}/prealloc-test.qcow2"
75
+ try:
76
+ os.remove(fname)
77
+ except OSError:
78
+ pass
79
+
80
+ subprocess.run([env['qemu-img-binary'], 'create', '-f', 'qcow2', fname,
81
+ '16G'], stdout=subprocess.DEVNULL,
82
+ stderr=subprocess.DEVNULL, check=True)
83
+
84
+ args = [env['qemu-img-binary'], 'bench', '-c', str(case['count']),
85
+ '-d', '64', '-s', case['block-size'], '-t', 'none', '-n', '-w']
86
+ if env['prealloc']:
87
+ args += ['--image-opts',
88
+ 'driver=qcow2,file.driver=preallocate,file.file.driver=file,'
89
+ f'file.file.filename={fname}']
90
+ else:
91
+ args += ['-f', 'qcow2', fname]
92
+
93
+ return qemu_img_bench(args)
94
+
95
+
96
+def auto_count_bench_func(env, case):
97
+ case['count'] = 100
98
+ while True:
99
+ res = bench_func(env, case)
100
+ if 'error' in res:
101
+ return res
102
+
103
+ if res['seconds'] >= 1:
104
+ break
105
+
106
+ case['count'] *= 10
107
+
108
+ if res['seconds'] < 5:
109
+ case['count'] = round(case['count'] * 5 / res['seconds'])
110
+ res = bench_func(env, case)
111
+ if 'error' in res:
112
+ return res
113
+
114
+ res['iops'] = case['count'] / res['seconds']
115
+ return res
116
+
117
+
118
+if __name__ == '__main__':
119
+ if len(sys.argv) < 2:
120
+ print(f'USAGE: {sys.argv[0]} <qemu-img binary> '
121
+ 'DISK_NAME:DIR_PATH ...')
122
+ exit(1)
123
+
124
+ qemu_img = sys.argv[1]
125
+
126
+ envs = [
127
+ {
128
+ 'id': 'no-prealloc',
129
+ 'qemu-img-binary': qemu_img,
130
+ 'prealloc': False
131
+ },
132
+ {
133
+ 'id': 'prealloc',
134
+ 'qemu-img-binary': qemu_img,
135
+ 'prealloc': True
136
+ }
137
+ ]
138
+
139
+ aligned_cases = []
140
+ unaligned_cases = []
141
+
142
+ for disk in sys.argv[2:]:
143
+ name, path = disk.split(':')
144
+ aligned_cases.append({
145
+ 'id': f'{name}, aligned sequential 16k',
146
+ 'block-size': '16k',
147
+ 'dir': path
148
+ })
149
+ unaligned_cases.append({
150
+ 'id': f'{name}, unaligned sequential 64k',
151
+ 'block-size': '16k',
152
+ 'dir': path
153
+ })
154
+
155
+ result = simplebench.bench(auto_count_bench_func, envs,
156
+ aligned_cases + unaligned_cases, count=5)
157
+ print(results_to_text(result))
158
+ with open('results.json', 'w') as f:
159
+ json.dump(result, f, indent=4)
79
--
160
--
80
2.21.0
161
2.29.2
81
162
82
163
diff view generated by jsdifflib
1
From: Nir Soffer <nirsof@gmail.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
When creating an image with preallocation "off" or "falloc", the first
3
The quorum driver does not implement bdrv_co_block_status() and
4
block of the image is typically not allocated. When using Gluster
4
because of that it always reports to contain data even if all its
5
storage backed by XFS filesystem, reading this block using direct I/O
5
children are known to be empty.
6
succeeds regardless of request length, fooling alignment detection.
6
7
7
One consequence of this is that if we for example create a quorum with
8
In this case we fallback to a safe value (4096) instead of the optimal
8
a size of 10GB and we mirror it to a new image the operation will
9
value (512), which may lead to unneeded data copying when aligning
9
write 10GB of actual zeroes to the destination image wasting a lot of
10
requests. Allocating the first block avoids the fallback.
10
time and disk space.
11
11
12
Since we allocate the first block even with preallocation=off, we no
12
Since a quorum has an arbitrary number of children of potentially
13
longer create images with zero disk size:
13
different formats there is no way to report all possible allocation
14
14
status flags in a way that makes sense, so this implementation only
15
$ ./qemu-img create -f raw test.raw 1g
15
reports when a given region is known to contain zeroes
16
Formatting 'test.raw', fmt=raw size=1073741824
16
(BDRV_BLOCK_ZERO) or not (BDRV_BLOCK_DATA).
17
17
18
$ ls -lhs test.raw
18
If all children agree that a region contains zeroes then we can return
19
4.0K -rw-r--r--. 1 nsoffer nsoffer 1.0G Aug 16 23:48 test.raw
19
BDRV_BLOCK_ZERO using the smallest size reported by the children
20
20
(because all agree that a region of at least that size contains
21
And converting the image requires additional cluster:
21
zeroes).
22
22
23
$ ./qemu-img measure -f raw -O qcow2 test.raw
23
If at least one child disagrees we have to return BDRV_BLOCK_DATA.
24
required size: 458752
24
In this case we use the largest of the sizes reported by the children
25
fully allocated size: 1074135040
25
that didn't return BDRV_BLOCK_ZERO (because we know that there won't
26
26
be an agreement for at least that size).
27
When using format like vmdk with multiple files per image, we allocate
27
28
one block per file:
28
Signed-off-by: Alberto Garcia <berto@igalia.com>
29
29
Tested-by: Tao Xu <tao3.xu@intel.com>
30
$ ./qemu-img create -f vmdk -o subformat=twoGbMaxExtentFlat test.vmdk 4g
31
Formatting 'test.vmdk', fmt=vmdk size=4294967296 compat6=off hwversion=undefined subformat=twoGbMaxExtentFlat
32
33
$ ls -lhs test*.vmdk
34
4.0K -rw-r--r--. 1 nsoffer nsoffer 2.0G Aug 27 03:23 test-f001.vmdk
35
4.0K -rw-r--r--. 1 nsoffer nsoffer 2.0G Aug 27 03:23 test-f002.vmdk
36
4.0K -rw-r--r--. 1 nsoffer nsoffer 353 Aug 27 03:23 test.vmdk
37
38
I did quick performance test for copying disks with qemu-img convert to
39
new raw target image to Gluster storage with sector size of 512 bytes:
40
41
for i in $(seq 10); do
42
rm -f dst.raw
43
sleep 10
44
time ./qemu-img convert -f raw -O raw -t none -T none src.raw dst.raw
45
done
46
47
Here is a table comparing the total time spent:
48
49
Type Before(s) After(s) Diff(%)
50
---------------------------------------
51
real 530.028 469.123 -11.4
52
user 17.204 10.768 -37.4
53
sys 17.881 7.011 -60.7
54
55
We can see very clear improvement in CPU usage.
56
57
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
58
Message-id: 20190827010528.8818-2-nsoffer@redhat.com
59
Reviewed-by: Max Reitz <mreitz@redhat.com>
30
Reviewed-by: Max Reitz <mreitz@redhat.com>
31
Message-Id: <db83149afcf0f793effc8878089d29af4c46ffe1.1605286097.git.berto@igalia.com>
60
Signed-off-by: Max Reitz <mreitz@redhat.com>
32
Signed-off-by: Max Reitz <mreitz@redhat.com>
61
---
33
---
62
block/file-posix.c | 51 +++++++++++++++++++
34
block/quorum.c | 52 +++++++++++++
63
tests/qemu-iotests/059.out | 2 +-
35
tests/qemu-iotests/312 | 148 +++++++++++++++++++++++++++++++++++++
64
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
36
tests/qemu-iotests/312.out | 67 +++++++++++++++++
65
tests/qemu-iotests/150.out.raw | 12 +++++
37
tests/qemu-iotests/group | 1 +
66
tests/qemu-iotests/175 | 19 ++++---
38
4 files changed, 268 insertions(+)
67
tests/qemu-iotests/175.out | 8 +--
39
create mode 100755 tests/qemu-iotests/312
68
tests/qemu-iotests/178.out.qcow2 | 4 +-
40
create mode 100644 tests/qemu-iotests/312.out
69
tests/qemu-iotests/221.out | 12 +++--
41
70
tests/qemu-iotests/253.out | 12 +++--
42
diff --git a/block/quorum.c b/block/quorum.c
71
9 files changed, 99 insertions(+), 21 deletions(-)
72
rename tests/qemu-iotests/{150.out => 150.out.qcow2} (100%)
73
create mode 100644 tests/qemu-iotests/150.out.raw
74
75
diff --git a/block/file-posix.c b/block/file-posix.c
76
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
77
--- a/block/file-posix.c
44
--- a/block/quorum.c
78
+++ b/block/file-posix.c
45
+++ b/block/quorum.c
79
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_discard(void *opaque)
46
@@ -XXX,XX +XXX,XX @@
80
return ret;
47
#include "qemu/module.h"
48
#include "qemu/option.h"
49
#include "block/block_int.h"
50
+#include "block/coroutines.h"
51
#include "block/qdict.h"
52
#include "qapi/error.h"
53
#include "qapi/qapi-events-block.h"
54
@@ -XXX,XX +XXX,XX @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
55
| DEFAULT_PERM_UNCHANGED;
81
}
56
}
82
57
83
+/*
58
+/*
84
+ * Help alignment probing by allocating the first block.
59
+ * Each one of the children can report different status flags even
85
+ *
60
+ * when they contain the same data, so what this function does is
86
+ * When reading with direct I/O from unallocated area on Gluster backed by XFS,
61
+ * return BDRV_BLOCK_ZERO if *all* children agree that a certain
87
+ * reading succeeds regardless of request length. In this case we fallback to
62
+ * region contains zeroes, and BDRV_BLOCK_DATA otherwise.
88
+ * safe alignment which is not optimal. Allocating the first block avoids this
89
+ * fallback.
90
+ *
91
+ * fd may be opened with O_DIRECT, but we don't know the buffer alignment or
92
+ * request alignment, so we use safe values.
93
+ *
94
+ * Returns: 0 on success, -errno on failure. Since this is an optimization,
95
+ * caller may ignore failures.
96
+ */
63
+ */
97
+static int allocate_first_block(int fd, size_t max_size)
64
+static int coroutine_fn quorum_co_block_status(BlockDriverState *bs,
65
+ bool want_zero,
66
+ int64_t offset, int64_t count,
67
+ int64_t *pnum, int64_t *map,
68
+ BlockDriverState **file)
98
+{
69
+{
99
+ size_t write_size = (max_size < MAX_BLOCKSIZE)
70
+ BDRVQuorumState *s = bs->opaque;
100
+ ? BDRV_SECTOR_SIZE
71
+ int i, ret;
101
+ : MAX_BLOCKSIZE;
72
+ int64_t pnum_zero = count;
102
+ size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize());
73
+ int64_t pnum_data = 0;
103
+ void *buf;
74
+
104
+ ssize_t n;
75
+ for (i = 0; i < s->num_children; i++) {
105
+ int ret;
76
+ int64_t bytes;
106
+
77
+ ret = bdrv_co_common_block_status_above(s->children[i]->bs, NULL, false,
107
+ buf = qemu_memalign(max_align, write_size);
78
+ want_zero, offset, count,
108
+ memset(buf, 0, write_size);
79
+ &bytes, NULL, NULL, NULL);
109
+
80
+ if (ret < 0) {
110
+ do {
81
+ quorum_report_bad(QUORUM_OP_TYPE_READ, offset, count,
111
+ n = pwrite(fd, buf, write_size, 0);
82
+ s->children[i]->bs->node_name, ret);
112
+ } while (n == -1 && errno == EINTR);
83
+ pnum_data = count;
113
+
84
+ break;
114
+ ret = (n == -1) ? -errno : 0;
85
+ }
115
+
86
+ /*
116
+ qemu_vfree(buf);
87
+ * Even if all children agree about whether there are zeroes
117
+ return ret;
88
+ * or not at @offset they might disagree on the size, so use
89
+ * the smallest when reporting BDRV_BLOCK_ZERO and the largest
90
+ * when reporting BDRV_BLOCK_DATA.
91
+ */
92
+ if (ret & BDRV_BLOCK_ZERO) {
93
+ pnum_zero = MIN(pnum_zero, bytes);
94
+ } else {
95
+ pnum_data = MAX(pnum_data, bytes);
96
+ }
97
+ }
98
+
99
+ if (pnum_data) {
100
+ *pnum = pnum_data;
101
+ return BDRV_BLOCK_DATA;
102
+ } else {
103
+ *pnum = pnum_zero;
104
+ return BDRV_BLOCK_ZERO;
105
+ }
118
+}
106
+}
119
+
107
+
120
static int handle_aiocb_truncate(void *opaque)
108
static const char *const quorum_strong_runtime_opts[] = {
121
{
109
QUORUM_OPT_VOTE_THRESHOLD,
122
RawPosixAIOData *aiocb = opaque;
110
QUORUM_OPT_BLKVERIFY,
123
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(void *opaque)
111
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_quorum = {
124
/* posix_fallocate() doesn't set errno. */
112
.bdrv_close = quorum_close,
125
error_setg_errno(errp, -result,
113
.bdrv_gather_child_options = quorum_gather_child_options,
126
"Could not preallocate new data");
114
.bdrv_dirname = quorum_dirname,
127
+ } else if (current_length == 0) {
115
+ .bdrv_co_block_status = quorum_co_block_status,
128
+ /*
116
129
+ * posix_fallocate() uses fallocate() if the filesystem
117
.bdrv_co_flush_to_disk = quorum_co_flush,
130
+ * supports it, or fallback to manually writing zeroes. If
118
131
+ * fallocate() was used, unaligned reads from the fallocated
119
diff --git a/tests/qemu-iotests/312 b/tests/qemu-iotests/312
132
+ * area in raw_probe_alignment() will succeed, hence we need to
120
new file mode 100755
133
+ * allocate the first block.
121
index XXXXXXX..XXXXXXX
134
+ *
122
--- /dev/null
135
+ * Optimize future alignment probing; ignore failures.
123
+++ b/tests/qemu-iotests/312
136
+ */
124
@@ -XXX,XX +XXX,XX @@
137
+ allocate_first_block(fd, offset);
125
+#!/usr/bin/env bash
138
}
126
+#
139
} else {
127
+# Test drive-mirror with quorum
140
result = 0;
128
+#
141
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(void *opaque)
129
+# The goal of this test is to check how the quorum driver reports
142
if (ftruncate(fd, offset) != 0) {
130
+# regions that are known to read as zeroes (BDRV_BLOCK_ZERO). The idea
143
result = -errno;
131
+# is that drive-mirror will try the efficient representation of zeroes
144
error_setg_errno(errp, -result, "Could not resize file");
132
+# in the destination image instead of writing actual zeroes.
145
+ } else if (current_length == 0 && offset > current_length) {
133
+#
146
+ /* Optimize future alignment probing; ignore failures. */
134
+# Copyright (C) 2020 Igalia, S.L.
147
+ allocate_first_block(fd, offset);
135
+# Author: Alberto Garcia <berto@igalia.com>
148
}
136
+#
149
return result;
137
+# This program is free software; you can redistribute it and/or modify
150
default:
138
+# it under the terms of the GNU General Public License as published by
151
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
139
+# the Free Software Foundation; either version 2 of the License, or
152
index XXXXXXX..XXXXXXX 100644
140
+# (at your option) any later version.
153
--- a/tests/qemu-iotests/059.out
141
+#
154
+++ b/tests/qemu-iotests/059.out
142
+# This program is distributed in the hope that it will be useful,
155
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMax
143
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
156
image: TEST_DIR/t.vmdk
144
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
157
file format: vmdk
145
+# GNU General Public License for more details.
158
virtual size: 0.977 TiB (1073741824000 bytes)
146
+#
159
-disk size: 16 KiB
147
+# You should have received a copy of the GNU General Public License
160
+disk size: 1.97 MiB
148
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
161
Format specific information:
149
+#
162
cid: XXXXXXXX
150
+
163
parent cid: XXXXXXXX
151
+# creator
164
diff --git a/tests/qemu-iotests/150.out b/tests/qemu-iotests/150.out.qcow2
152
+owner=berto@igalia.com
165
similarity index 100%
153
+
166
rename from tests/qemu-iotests/150.out
154
+seq=`basename $0`
167
rename to tests/qemu-iotests/150.out.qcow2
155
+echo "QA output created by $seq"
168
diff --git a/tests/qemu-iotests/150.out.raw b/tests/qemu-iotests/150.out.raw
156
+
157
+status=1    # failure is the default!
158
+
159
+_cleanup()
160
+{
161
+ _rm_test_img "$TEST_IMG.0"
162
+ _rm_test_img "$TEST_IMG.1"
163
+ _rm_test_img "$TEST_IMG.2"
164
+ _rm_test_img "$TEST_IMG.3"
165
+ _cleanup_qemu
166
+}
167
+trap "_cleanup; exit \$status" 0 1 2 3 15
168
+
169
+# get standard environment, filters and checks
170
+. ./common.rc
171
+. ./common.filter
172
+. ./common.qemu
173
+
174
+_supported_fmt qcow2
175
+_supported_proto file
176
+_supported_os Linux
177
+_unsupported_imgopts cluster_size data_file
178
+
179
+echo
180
+echo '### Create all images' # three source (quorum), one destination
181
+echo
182
+TEST_IMG="$TEST_IMG.0" _make_test_img -o cluster_size=64k 10M
183
+TEST_IMG="$TEST_IMG.1" _make_test_img -o cluster_size=64k 10M
184
+TEST_IMG="$TEST_IMG.2" _make_test_img -o cluster_size=64k 10M
185
+TEST_IMG="$TEST_IMG.3" _make_test_img -o cluster_size=64k 10M
186
+
187
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2"
188
+quorum="$quorum,file.children.0.file.filename=$TEST_IMG.0"
189
+quorum="$quorum,file.children.1.file.filename=$TEST_IMG.1"
190
+quorum="$quorum,file.children.2.file.filename=$TEST_IMG.2"
191
+quorum="$quorum,file.children.0.driver=$IMGFMT"
192
+quorum="$quorum,file.children.1.driver=$IMGFMT"
193
+quorum="$quorum,file.children.2.driver=$IMGFMT"
194
+
195
+echo
196
+echo '### Output of qemu-img map (empty quorum)'
197
+echo
198
+$QEMU_IMG map --image-opts $quorum | _filter_qemu_img_map
199
+
200
+# Now we write data to the quorum. All three images will read as
201
+# zeroes in all cases, but with different ways to represent them
202
+# (unallocated clusters, zero clusters, data clusters with zeroes)
203
+# that will have an effect on how the data will be mirrored and the
204
+# output of qemu-img map on the resulting image.
205
+echo
206
+echo '### Write data to the quorum'
207
+echo
208
+# Test 1: data regions surrounded by unallocated clusters.
209
+# Three data regions, the largest one (0x30000) will be picked, end result:
210
+# offset 0x10000, length 0x30000 -> data
211
+$QEMU_IO -c "write -P 0 $((0x10000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu_io
212
+$QEMU_IO -c "write -P 0 $((0x10000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io
213
+$QEMU_IO -c "write -P 0 $((0x10000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io
214
+
215
+# Test 2: zero regions surrounded by data clusters.
216
+# First we allocate the data clusters.
217
+$QEMU_IO -c "open -o $quorum" -c "write -P 0 $((0x100000)) $((0x40000))" | _filter_qemu_io
218
+
219
+# Three zero regions, the smallest one (0x10000) will be picked, end result:
220
+# offset 0x100000, length 0x10000 -> data
221
+# offset 0x110000, length 0x10000 -> zeroes
222
+# offset 0x120000, length 0x20000 -> data
223
+$QEMU_IO -c "write -z $((0x110000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu_io
224
+$QEMU_IO -c "write -z $((0x110000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io
225
+$QEMU_IO -c "write -z $((0x110000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io
226
+
227
+# Test 3: zero clusters surrounded by unallocated clusters.
228
+# Everything reads as zeroes, no effect on the end result.
229
+$QEMU_IO -c "write -z $((0x150000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu_io
230
+$QEMU_IO -c "write -z $((0x150000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io
231
+$QEMU_IO -c "write -z $((0x150000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io
232
+
233
+# Test 4: mix of data and zero clusters.
234
+# The zero region will be ignored in favor of the largest data region
235
+# (0x20000), end result:
236
+# offset 0x200000, length 0x20000 -> data
237
+$QEMU_IO -c "write -P 0 $((0x200000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu_io
238
+$QEMU_IO -c "write -z $((0x200000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io
239
+$QEMU_IO -c "write -P 0 $((0x200000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io
240
+
241
+echo
242
+echo '### Launch the drive-mirror job'
243
+echo
244
+qemu_comm_method="qmp" _launch_qemu -drive if=virtio,"$quorum"
245
+h=$QEMU_HANDLE
246
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return'
247
+
248
+_send_qemu_cmd $h \
249
+ "{'execute': 'drive-mirror',
250
+ 'arguments': {'device': 'virtio0',
251
+ 'format': '$IMGFMT',
252
+ 'target': '$TEST_IMG.3',
253
+ 'sync': 'full',
254
+ 'mode': 'existing' }}" \
255
+ "BLOCK_JOB_READY.*virtio0"
256
+
257
+_send_qemu_cmd $h \
258
+ "{ 'execute': 'block-job-complete',
259
+ 'arguments': { 'device': 'virtio0' } }" \
260
+ 'BLOCK_JOB_COMPLETED'
261
+
262
+_send_qemu_cmd $h "{ 'execute': 'quit' }" ''
263
+
264
+echo
265
+echo '### Output of qemu-img map (destination image)'
266
+echo
267
+$QEMU_IMG map "$TEST_IMG.3" | _filter_qemu_img_map
268
+
269
+# success, all done
270
+echo "*** done"
271
+rm -f $seq.full
272
+status=0
273
diff --git a/tests/qemu-iotests/312.out b/tests/qemu-iotests/312.out
169
new file mode 100644
274
new file mode 100644
170
index XXXXXXX..XXXXXXX
275
index XXXXXXX..XXXXXXX
171
--- /dev/null
276
--- /dev/null
172
+++ b/tests/qemu-iotests/150.out.raw
277
+++ b/tests/qemu-iotests/312.out
173
@@ -XXX,XX +XXX,XX @@
278
@@ -XXX,XX +XXX,XX @@
174
+QA output created by 150
279
+QA output created by 312
175
+
280
+
176
+=== Mapping sparse conversion ===
281
+### Create all images
282
+
283
+Formatting 'TEST_DIR/t.IMGFMT.0', fmt=IMGFMT size=10485760
284
+Formatting 'TEST_DIR/t.IMGFMT.1', fmt=IMGFMT size=10485760
285
+Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=10485760
286
+Formatting 'TEST_DIR/t.IMGFMT.3', fmt=IMGFMT size=10485760
287
+
288
+### Output of qemu-img map (empty quorum)
177
+
289
+
178
+Offset Length File
290
+Offset Length File
179
+0 0x1000 TEST_DIR/t.IMGFMT
291
+
180
+
292
+### Write data to the quorum
181
+=== Mapping non-sparse conversion ===
293
+
294
+wrote 65536/65536 bytes at offset 65536
295
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
296
+wrote 196608/196608 bytes at offset 65536
297
+192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
298
+wrote 131072/131072 bytes at offset 65536
299
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
300
+wrote 262144/262144 bytes at offset 1048576
301
+256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
302
+wrote 65536/65536 bytes at offset 1114112
303
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
304
+wrote 196608/196608 bytes at offset 1114112
305
+192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
306
+wrote 131072/131072 bytes at offset 1114112
307
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
308
+wrote 65536/65536 bytes at offset 1376256
309
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
310
+wrote 196608/196608 bytes at offset 1376256
311
+192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
312
+wrote 131072/131072 bytes at offset 1376256
313
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
314
+wrote 65536/65536 bytes at offset 2097152
315
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
316
+wrote 196608/196608 bytes at offset 2097152
317
+192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
318
+wrote 131072/131072 bytes at offset 2097152
319
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
320
+
321
+### Launch the drive-mirror job
322
+
323
+{ 'execute': 'qmp_capabilities' }
324
+{"return": {}}
325
+{'execute': 'drive-mirror', 'arguments': {'device': 'virtio0', 'format': 'IMGFMT', 'target': 'TEST_DIR/t.IMGFMT.3', 'sync': 'full', 'mode': 'existing' }}
326
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "virtio0"}}
327
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "virtio0"}}
328
+{"return": {}}
329
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "virtio0"}}
330
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 10485760, "offset": 10485760, "speed": 0, "type": "mirror"}}
331
+{ 'execute': 'block-job-complete', 'arguments': { 'device': 'virtio0' } }
332
+{"return": {}}
333
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "virtio0"}}
334
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "virtio0"}}
335
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "virtio0", "len": 10485760, "offset": 10485760, "speed": 0, "type": "mirror"}}
336
+{ 'execute': 'quit' }
337
+
338
+### Output of qemu-img map (destination image)
182
+
339
+
183
+Offset Length File
340
+Offset Length File
184
+0 0x100000 TEST_DIR/t.IMGFMT
341
+0x10000 0x30000 TEST_DIR/t.IMGFMT.3
342
+0x100000 0x10000 TEST_DIR/t.IMGFMT.3
343
+0x120000 0x20000 TEST_DIR/t.IMGFMT.3
344
+0x200000 0x20000 TEST_DIR/t.IMGFMT.3
185
+*** done
345
+*** done
186
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
346
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
187
index XXXXXXX..XXXXXXX 100755
188
--- a/tests/qemu-iotests/175
189
+++ b/tests/qemu-iotests/175
190
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
191
# the file size. This function hides the resulting difference in the
192
# stat -c '%b' output.
193
# Parameter 1: Number of blocks an empty file occupies
194
-# Parameter 2: Image size in bytes
195
+# Parameter 2: Minimal number of blocks in an image
196
+# Parameter 3: Image size in bytes
197
_filter_blocks()
198
{
199
extra_blocks=$1
200
- img_size=$2
201
+ min_blocks=$2
202
+ img_size=$3
203
204
- sed -e "s/blocks=$extra_blocks\\(\$\\|[^0-9]\\)/nothing allocated/" \
205
- -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/everything allocated/"
206
+ sed -e "s/blocks=$min_blocks\\(\$\\|[^0-9]\\)/min allocation/" \
207
+ -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/"
208
}
209
210
# get standard environment, filters and checks
211
@@ -XXX,XX +XXX,XX @@ size=$((1 * 1024 * 1024))
212
touch "$TEST_DIR/empty"
213
extra_blocks=$(stat -c '%b' "$TEST_DIR/empty")
214
215
+# We always write the first byte; check how many blocks this filesystem
216
+# allocates to match empty image alloation.
217
+printf "\0" > "$TEST_DIR/empty"
218
+min_blocks=$(stat -c '%b' "$TEST_DIR/empty")
219
+
220
echo
221
echo "== creating image with default preallocation =="
222
_make_test_img $size | _filter_imgfmt
223
-stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size
224
+stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
225
226
for mode in off full falloc; do
227
echo
228
echo "== creating image with preallocation $mode =="
229
IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt
230
- stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size
231
+ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
232
done
233
234
# success, all done
235
diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
236
index XXXXXXX..XXXXXXX 100644
347
index XXXXXXX..XXXXXXX 100644
237
--- a/tests/qemu-iotests/175.out
348
--- a/tests/qemu-iotests/group
238
+++ b/tests/qemu-iotests/175.out
349
+++ b/tests/qemu-iotests/group
239
@@ -XXX,XX +XXX,XX @@ QA output created by 175
350
@@ -XXX,XX +XXX,XX @@
240
351
307 rw quick export
241
== creating image with default preallocation ==
352
308 rw
242
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
353
309 rw auto quick
243
-size=1048576, nothing allocated
354
+312 rw auto quick
244
+size=1048576, min allocation
245
246
== creating image with preallocation off ==
247
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=off
248
-size=1048576, nothing allocated
249
+size=1048576, min allocation
250
251
== creating image with preallocation full ==
252
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=full
253
-size=1048576, everything allocated
254
+size=1048576, max allocation
255
256
== creating image with preallocation falloc ==
257
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc
258
-size=1048576, everything allocated
259
+size=1048576, max allocation
260
*** done
261
diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2
262
index XXXXXXX..XXXXXXX 100644
263
--- a/tests/qemu-iotests/178.out.qcow2
264
+++ b/tests/qemu-iotests/178.out.qcow2
265
@@ -XXX,XX +XXX,XX @@ converted image file size in bytes: 196608
266
== raw input image with data (human) ==
267
268
Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824
269
-required size: 393216
270
+required size: 458752
271
fully allocated size: 1074135040
272
wrote 512/512 bytes at offset 512
273
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
274
@@ -XXX,XX +XXX,XX @@ converted image file size in bytes: 196608
275
276
Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824
277
{
278
- "required": 393216,
279
+ "required": 458752,
280
"fully-allocated": 1074135040
281
}
282
wrote 512/512 bytes at offset 512
283
diff --git a/tests/qemu-iotests/221.out b/tests/qemu-iotests/221.out
284
index XXXXXXX..XXXXXXX 100644
285
--- a/tests/qemu-iotests/221.out
286
+++ b/tests/qemu-iotests/221.out
287
@@ -XXX,XX +XXX,XX @@ QA output created by 221
288
=== Check mapping of unaligned raw image ===
289
290
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65537
291
-[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
292
-[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
293
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
294
+{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
295
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
296
+{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
297
wrote 1/1 bytes at offset 65536
298
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
299
-[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
300
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
301
+{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
302
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
303
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
304
-[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
305
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
306
+{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
307
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
308
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
309
*** done
310
diff --git a/tests/qemu-iotests/253.out b/tests/qemu-iotests/253.out
311
index XXXXXXX..XXXXXXX 100644
312
--- a/tests/qemu-iotests/253.out
313
+++ b/tests/qemu-iotests/253.out
314
@@ -XXX,XX +XXX,XX @@ QA output created by 253
315
=== Check mapping of unaligned raw image ===
316
317
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575
318
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
319
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
320
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
321
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
322
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
323
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
324
wrote 65535/65535 bytes at offset 983040
325
63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
326
-[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
327
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
328
+{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
329
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
330
-[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
331
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
332
+{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
333
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
334
*** done
335
--
355
--
336
2.21.0
356
2.29.2
337
357
338
358
diff view generated by jsdifflib
1
From: Nir Soffer <nirsof@gmail.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
Using block_resize we can test allocate_first_block() with file
3
This simply calls bdrv_co_pwrite_zeroes() in all children.
4
descriptor opened with O_DIRECT, ensuring that it works for any size
5
larger than 4096 bytes.
6
4
7
Testing smaller sizes is tricky as the result depends on the filesystem
5
bs->supported_zero_flags is also set to the flags that are supported
8
used for testing. For example on NFS any size will work since O_DIRECT
6
by all children.
9
does not require any alignment.
10
7
11
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
9
Message-Id: <2f09c842781fe336b4c2e40036bba577b7430190.1605286097.git.berto@igalia.com>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
Message-id: 20190827010528.8818-3-nsoffer@redhat.com
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
12
---
16
tests/qemu-iotests/175 | 28 ++++++++++++++++++++++++++++
13
block/quorum.c | 36 ++++++++++++++++++++++++++++++++++--
17
tests/qemu-iotests/175.out | 8 ++++++++
14
tests/qemu-iotests/312 | 11 +++++++++++
18
2 files changed, 36 insertions(+)
15
tests/qemu-iotests/312.out | 8 ++++++++
16
3 files changed, 53 insertions(+), 2 deletions(-)
19
17
20
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
18
diff --git a/block/quorum.c b/block/quorum.c
21
index XXXXXXX..XXXXXXX 100755
19
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/qemu-iotests/175
20
--- a/block/quorum.c
23
+++ b/tests/qemu-iotests/175
21
+++ b/block/quorum.c
24
@@ -XXX,XX +XXX,XX @@ _filter_blocks()
22
@@ -XXX,XX +XXX,XX @@ static void write_quorum_entry(void *opaque)
25
-e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/"
23
QuorumChildRequest *sacb = &acb->qcrs[i];
24
25
sacb->bs = s->children[i]->bs;
26
- sacb->ret = bdrv_co_pwritev(s->children[i], acb->offset, acb->bytes,
27
- acb->qiov, acb->flags);
28
+ if (acb->flags & BDRV_REQ_ZERO_WRITE) {
29
+ sacb->ret = bdrv_co_pwrite_zeroes(s->children[i], acb->offset,
30
+ acb->bytes, acb->flags);
31
+ } else {
32
+ sacb->ret = bdrv_co_pwritev(s->children[i], acb->offset, acb->bytes,
33
+ acb->qiov, acb->flags);
34
+ }
35
if (sacb->ret == 0) {
36
acb->success_count++;
37
} else {
38
@@ -XXX,XX +XXX,XX @@ static int quorum_co_pwritev(BlockDriverState *bs, uint64_t offset,
39
return ret;
26
}
40
}
27
41
28
+# Resize image using block_resize.
42
+static int quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
29
+# Parameter 1: image path
43
+ int bytes, BdrvRequestFlags flags)
30
+# Parameter 2: new size
44
+
31
+_block_resize()
32
+{
45
+{
33
+ local path=$1
46
+ return quorum_co_pwritev(bs, offset, bytes, NULL,
34
+ local size=$2
47
+ flags | BDRV_REQ_ZERO_WRITE);
35
+
36
+ $QEMU -qmp stdio -nographic -nodefaults \
37
+ -blockdev file,node-name=file,filename=$path,cache.direct=on \
38
+ <<EOF
39
+{'execute': 'qmp_capabilities'}
40
+{'execute': 'block_resize', 'arguments': {'node-name': 'file', 'size': $size}}
41
+{'execute': 'quit'}
42
+EOF
43
+}
48
+}
44
+
49
+
45
# get standard environment, filters and checks
50
static int64_t quorum_getlength(BlockDriverState *bs)
46
. ./common.rc
51
{
47
. ./common.filter
52
BDRVQuorumState *s = bs->opaque;
48
@@ -XXX,XX +XXX,XX @@ _supported_fmt raw
53
@@ -XXX,XX +XXX,XX @@ static QemuOptsList quorum_runtime_opts = {
49
_supported_proto file
54
},
50
_supported_os Linux
55
};
51
56
52
+_default_cache_mode none
57
+static void quorum_refresh_flags(BlockDriverState *bs)
53
+_supported_cache_modes none directsync
58
+{
59
+ BDRVQuorumState *s = bs->opaque;
60
+ int i;
54
+
61
+
55
size=$((1 * 1024 * 1024))
62
+ bs->supported_zero_flags =
56
63
+ BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
57
touch "$TEST_DIR/empty"
58
@@ -XXX,XX +XXX,XX @@ for mode in off full falloc; do
59
stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
60
done
61
62
+for new_size in 4096 1048576; do
63
+ echo
64
+ echo "== resize empty image with block_resize =="
65
+ _make_test_img 0 | _filter_imgfmt
66
+ _block_resize $TEST_IMG $new_size >/dev/null
67
+ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $new_size
68
+done
69
+
64
+
70
# success, all done
65
+ for (i = 0; i < s->num_children; i++) {
71
echo "*** done"
66
+ bs->supported_zero_flags &= s->children[i]->bs->supported_zero_flags;
72
rm -f $seq.full
67
+ }
73
diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
68
+
69
+ bs->supported_zero_flags |= BDRV_REQ_WRITE_UNCHANGED;
70
+}
71
+
72
static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
73
Error **errp)
74
{
75
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
76
s->next_child_index = s->num_children;
77
78
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
79
+ quorum_refresh_flags(bs);
80
81
g_free(opened);
82
goto exit;
83
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
84
}
85
s->children = g_renew(BdrvChild *, s->children, s->num_children + 1);
86
s->children[s->num_children++] = child;
87
+ quorum_refresh_flags(bs);
88
89
out:
90
bdrv_drained_end(bs);
91
@@ -XXX,XX +XXX,XX @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
92
s->children = g_renew(BdrvChild *, s->children, --s->num_children);
93
bdrv_unref_child(bs, child);
94
95
+ quorum_refresh_flags(bs);
96
bdrv_drained_end(bs);
97
}
98
99
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_quorum = {
100
101
.bdrv_co_preadv = quorum_co_preadv,
102
.bdrv_co_pwritev = quorum_co_pwritev,
103
+ .bdrv_co_pwrite_zeroes = quorum_co_pwrite_zeroes,
104
105
.bdrv_add_child = quorum_add_child,
106
.bdrv_del_child = quorum_del_child,
107
diff --git a/tests/qemu-iotests/312 b/tests/qemu-iotests/312
108
index XXXXXXX..XXXXXXX 100755
109
--- a/tests/qemu-iotests/312
110
+++ b/tests/qemu-iotests/312
111
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "write -P 0 $((0x200000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu
112
$QEMU_IO -c "write -z $((0x200000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io
113
$QEMU_IO -c "write -P 0 $((0x200000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io
114
115
+# Test 5: write data to a region and then zeroize it, doing it
116
+# directly on the quorum device instead of the individual images.
117
+# This has no effect on the end result but proves that the quorum driver
118
+# supports 'write -z'.
119
+$QEMU_IO -c "open -o $quorum" -c "write -P 1 $((0x250000)) $((0x10000))" | _filter_qemu_io
120
+# Verify the data that we just wrote
121
+$QEMU_IO -c "open -o $quorum" -c "read -P 1 $((0x250000)) $((0x10000))" | _filter_qemu_io
122
+$QEMU_IO -c "open -o $quorum" -c "write -z $((0x250000)) $((0x10000))" | _filter_qemu_io
123
+# Now it should read back as zeroes
124
+$QEMU_IO -c "open -o $quorum" -c "read -P 0 $((0x250000)) $((0x10000))" | _filter_qemu_io
125
+
126
echo
127
echo '### Launch the drive-mirror job'
128
echo
129
diff --git a/tests/qemu-iotests/312.out b/tests/qemu-iotests/312.out
74
index XXXXXXX..XXXXXXX 100644
130
index XXXXXXX..XXXXXXX 100644
75
--- a/tests/qemu-iotests/175.out
131
--- a/tests/qemu-iotests/312.out
76
+++ b/tests/qemu-iotests/175.out
132
+++ b/tests/qemu-iotests/312.out
77
@@ -XXX,XX +XXX,XX @@ size=1048576, max allocation
133
@@ -XXX,XX +XXX,XX @@ wrote 196608/196608 bytes at offset 2097152
78
== creating image with preallocation falloc ==
134
192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
79
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc
135
wrote 131072/131072 bytes at offset 2097152
80
size=1048576, max allocation
136
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
81
+
137
+wrote 65536/65536 bytes at offset 2424832
82
+== resize empty image with block_resize ==
138
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
83
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
139
+read 65536/65536 bytes at offset 2424832
84
+size=4096, min allocation
140
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
85
+
141
+wrote 65536/65536 bytes at offset 2424832
86
+== resize empty image with block_resize ==
142
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
87
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
143
+read 65536/65536 bytes at offset 2424832
88
+size=1048576, min allocation
144
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
89
*** done
145
146
### Launch the drive-mirror job
147
90
--
148
--
91
2.21.0
149
2.29.2
92
150
93
151
diff view generated by jsdifflib
1
fe646693acc changed qemu-img create's output so that it no longer prints
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
single quotes around parameter values. The subformat and adapter_type
3
filters in _filter_img_create() have never been adapted to that change.
4
2
5
Fixes: fe646693acc13ac48b98435d14149ab04dc597bc
3
NVMe drive cannot be shrunk.
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
7
Reviewed-by: John Snow <jsnow@redhat.com>
5
Since commit c80d8b06cfa we can use the @exact parameter (set
8
Message-id: 20190815153638.4600-2-mreitz@redhat.com
6
to false) to return success if the block device is larger than
9
Reviewed-by: John Snow <jsnow@redhat.com>
7
the requested offset (even if we can not be shrunk).
8
9
Use this parameter to implement the NVMe truncate() coroutine,
10
similarly how it is done for the iscsi and file-posix drivers
11
(see commit 82325ae5f2f "Evaluate @exact in protocol drivers").
12
13
Reported-by: Xueqiang Wei <xuwei@redhat.com>
14
Suggested-by: Max Reitz <mreitz@redhat.com>
15
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Message-Id: <20201210125202.858656-1-philmd@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
18
---
12
tests/qemu-iotests/059.out | 16 ++++++++--------
19
block/nvme.c | 24 ++++++++++++++++++++++++
13
tests/qemu-iotests/common.filter | 4 ++--
20
1 file changed, 24 insertions(+)
14
2 files changed, 10 insertions(+), 10 deletions(-)
15
21
16
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
22
diff --git a/block/nvme.c b/block/nvme.c
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qemu-iotests/059.out
24
--- a/block/nvme.c
19
+++ b/tests/qemu-iotests/059.out
25
+++ b/block/nvme.c
20
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
26
@@ -XXX,XX +XXX,XX @@ out:
21
qemu-io: can't open device TEST_DIR/t.vmdk: L1 size too big
27
22
28
}
23
=== Testing monolithicFlat creation and opening ===
29
24
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
30
+static int coroutine_fn nvme_co_truncate(BlockDriverState *bs, int64_t offset,
25
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
31
+ bool exact, PreallocMode prealloc,
26
image: TEST_DIR/t.IMGFMT
32
+ BdrvRequestFlags flags, Error **errp)
27
file format: IMGFMT
33
+{
28
virtual size: 2 GiB (2147483648 bytes)
34
+ int64_t cur_length;
29
35
+
30
=== Testing monolithicFlat with zeroed_grain ===
36
+ if (prealloc != PREALLOC_MODE_OFF) {
31
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
37
+ error_setg(errp, "Unsupported preallocation mode '%s'",
32
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
38
+ PreallocMode_str(prealloc));
33
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
39
+ return -ENOTSUP;
34
40
+ }
35
=== Testing big twoGbMaxExtentFlat ===
41
+
36
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMaxExtentFlat
42
+ cur_length = nvme_getlength(bs);
37
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000
43
+ if (offset != cur_length && exact) {
38
image: TEST_DIR/t.vmdk
44
+ error_setg(errp, "Cannot resize NVMe devices");
39
file format: vmdk
45
+ return -ENOTSUP;
40
virtual size: 0.977 TiB (1073741824000 bytes)
46
+ } else if (offset > cur_length) {
41
@@ -XXX,XX +XXX,XX @@ Format specific information:
47
+ error_setg(errp, "Cannot grow NVMe devices");
42
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Invalid extent line: RW 12582912 VMFS "dummy.IMGFMT" 1
48
+ return -EINVAL;
43
49
+ }
44
=== Testing truncated sparse ===
50
+
45
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 subformat=monolithicSparse
51
+ return 0;
46
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400
52
+}
47
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': File truncated, expecting at least 13172736 bytes
53
48
54
static int nvme_reopen_prepare(BDRVReopenState *reopen_state,
49
=== Converting to streamOptimized from image with small cluster size===
55
BlockReopenQueue *queue, Error **errp)
50
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
56
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nvme = {
51
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
57
.bdrv_close = nvme_close,
52
58
.bdrv_getlength = nvme_getlength,
53
=== Testing monolithicFlat with internally generated JSON file name ===
59
.bdrv_probe_blocksizes = nvme_probe_blocksizes,
54
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 subformat=monolithicFlat
60
+ .bdrv_co_truncate = nvme_co_truncate,
55
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
61
56
qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}'
62
.bdrv_co_preadv = nvme_co_preadv,
57
63
.bdrv_co_pwritev = nvme_co_pwritev,
58
=== Testing version 3 ===
59
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 64931328
60
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
61
62
=== Testing 4TB monolithicFlat creation and IO ===
63
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat
64
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104
65
image: TEST_DIR/t.IMGFMT
66
file format: IMGFMT
67
virtual size: 4 TiB (4398046511104 bytes)
68
@@ -XXX,XX +XXX,XX @@ read 1024/1024 bytes at offset 966367641600
69
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
70
71
=== Testing qemu-img map on extents ===
72
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=monolithicSparse
73
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544
74
wrote 1024/1024 bytes at offset 65024
75
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
76
wrote 1024/1024 bytes at offset 2147483136
77
@@ -XXX,XX +XXX,XX @@ Offset Length Mapped to File
78
0 0x20000 0x3f0000 TEST_DIR/t.vmdk
79
0x7fff0000 0x20000 0x410000 TEST_DIR/t.vmdk
80
0x140000000 0x10000 0x430000 TEST_DIR/t.vmdk
81
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=twoGbMaxExtentSparse
82
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544
83
wrote 1024/1024 bytes at offset 65024
84
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
85
wrote 1024/1024 bytes at offset 2147483136
86
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
87
index XXXXXXX..XXXXXXX 100644
88
--- a/tests/qemu-iotests/common.filter
89
+++ b/tests/qemu-iotests/common.filter
90
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
91
-e "s# compat6=\\(on\\|off\\)##g" \
92
-e "s# static=\\(on\\|off\\)##g" \
93
-e "s# zeroed_grain=\\(on\\|off\\)##g" \
94
- -e "s# subformat='[^']*'##g" \
95
- -e "s# adapter_type='[^']*'##g" \
96
+ -e "s# subformat=[^ ]*##g" \
97
+ -e "s# adapter_type=[^ ]*##g" \
98
-e "s# hwversion=[^ ]*##g" \
99
-e "s# lazy_refcounts=\\(on\\|off\\)##g" \
100
-e "s# block_size=[0-9]\\+##g" \
101
--
64
--
102
2.21.0
65
2.29.2
103
66
104
67
diff view generated by jsdifflib
1
iotest 126 requires backing file support, which flat vmdks cannot offer.
1
The first parameter passed to _send_qemu_cmd is supposed to be the
2
Skip this test for such subformats.
2
$QEMU_HANDLE. 102 does not do so here, fix it.
3
4
As a result, the output changes: Now we see the prompt this command is
5
supposedly waiting for before the resize message - as it should be.
3
6
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Message-id: 20190815153638.4600-8-mreitz@redhat.com
8
Message-Id: <20201217153803.101231-2-mreitz@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
10
---
9
tests/qemu-iotests/126 | 2 ++
11
tests/qemu-iotests/102 | 2 +-
10
1 file changed, 2 insertions(+)
12
tests/qemu-iotests/102.out | 2 +-
13
2 files changed, 2 insertions(+), 2 deletions(-)
11
14
12
diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
15
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
13
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100755
14
--- a/tests/qemu-iotests/126
17
--- a/tests/qemu-iotests/102
15
+++ b/tests/qemu-iotests/126
18
+++ b/tests/qemu-iotests/102
16
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
19
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
17
20
qemu_comm_method=monitor _launch_qemu -drive if=none,file="$TEST_IMG",id=drv0
18
# Needs backing file support
21
19
_supported_fmt qcow qcow2 qed vmdk
22
# Wait for a prompt to appear (so we know qemu has opened the image)
20
+_unsupported_imgopts "subformat=monolithicFlat" \
23
-_send_qemu_cmd '' '(qemu)'
21
+ "subformat=twoGbMaxExtentFlat"
24
+_send_qemu_cmd $QEMU_HANDLE '' '(qemu)'
22
# This is the default protocol (and we want to test the difference between
25
23
# colons which separate a protocol prefix from the rest and colons which are
26
$QEMU_IMG resize --shrink --image-opts \
24
# just part of the filename, so we cannot test protocols which require a prefix)
27
"driver=raw,file.driver=file,file.filename=$TEST_IMG,file.locking=off" \
28
diff --git a/tests/qemu-iotests/102.out b/tests/qemu-iotests/102.out
29
index XXXXXXX..XXXXXXX 100644
30
--- a/tests/qemu-iotests/102.out
31
+++ b/tests/qemu-iotests/102.out
32
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
33
wrote 65536/65536 bytes at offset 0
34
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
35
QEMU X.Y.Z monitor - type 'help' for more information
36
-Image resized.
37
(qemu)
38
+Image resized.
39
(qemu) qemu-io drv0 map
40
64 KiB (0x10000) bytes allocated at offset 0 bytes (0x0)
41
*** done
25
--
42
--
26
2.21.0
43
2.29.2
27
44
28
45
diff view generated by jsdifflib
1
streamOptimized does not support writes that do not span exactly one
1
With bash 5.1, the output of the following script changes:
2
cluster. Furthermore, it cannot rewrite already allocated clusters.
2
3
As such, many iotests do not work with it. Disable them.
3
a=("double space")
4
a=${a[@]:0:1}
5
echo "$a"
6
7
from "double space" to "double space", i.e. all white space is
8
preserved as-is. This is probably what we actually want here (judging
9
from the "...to accommodate pathnames with spaces" comment), but before
10
5.1, we would have to quote the ${} slice to get the same behavior.
11
12
In any case, without quoting, the reference output of many iotests is
13
different between bash 5.1 and pre-5.1, which is not very good. The
14
output of 5.1 is what we want, so whatever we do to get pre-5.1 to the
15
same result, it means we have to fix the reference output of basically
16
all tests that invoke _send_qemu_cmd (except the ones that only use
17
single spaces in the commands they invoke).
18
19
Instead of quoting the ${} slice (cmd="${$@: 1:...}"), we can also just
20
not use array slicing and replace the whole thing with a simple "cmd=$1;
21
shift", which works because all callers quote the whole $cmd argument
22
anyway.
4
23
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
24
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Message-id: 20190815153638.4600-6-mreitz@redhat.com
25
Message-Id: <20201217153803.101231-3-mreitz@redhat.com>
7
Reviewed-by: John Snow <jsnow@redhat.com>
26
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
27
---
10
tests/qemu-iotests/002 | 1 +
28
tests/qemu-iotests/085.out | 167 ++++++++++++++++++++++++++++-----
11
tests/qemu-iotests/003 | 1 +
29
tests/qemu-iotests/094.out | 10 +-
12
tests/qemu-iotests/005 | 3 ++-
30
tests/qemu-iotests/095.out | 4 +-
13
tests/qemu-iotests/009 | 1 +
31
tests/qemu-iotests/109.out | 88 ++++++++++++-----
14
tests/qemu-iotests/010 | 1 +
32
tests/qemu-iotests/117.out | 13 ++-
15
tests/qemu-iotests/011 | 1 +
33
tests/qemu-iotests/127.out | 12 ++-
16
tests/qemu-iotests/017 | 3 ++-
34
tests/qemu-iotests/140.out | 10 +-
17
tests/qemu-iotests/018 | 3 ++-
35
tests/qemu-iotests/141.out | 128 +++++++++++++++++++------
18
tests/qemu-iotests/019 | 3 ++-
36
tests/qemu-iotests/143.out | 4 +-
19
tests/qemu-iotests/020 | 3 ++-
37
tests/qemu-iotests/144.out | 28 +++++-
20
tests/qemu-iotests/027 | 1 +
38
tests/qemu-iotests/153.out | 18 ++--
21
tests/qemu-iotests/032 | 1 +
39
tests/qemu-iotests/156.out | 39 ++++++--
22
tests/qemu-iotests/033 | 1 +
40
tests/qemu-iotests/161.out | 18 +++-
23
tests/qemu-iotests/034 | 3 ++-
41
tests/qemu-iotests/173.out | 25 ++++-
24
tests/qemu-iotests/037 | 3 ++-
42
tests/qemu-iotests/182.out | 42 +++++++--
25
tests/qemu-iotests/063 | 3 ++-
43
tests/qemu-iotests/183.out | 19 +++-
26
tests/qemu-iotests/072 | 1 +
44
tests/qemu-iotests/185.out | 45 +++++++--
27
tests/qemu-iotests/105 | 3 ++-
45
tests/qemu-iotests/191.out | 12 ++-
28
tests/qemu-iotests/197 | 1 +
46
tests/qemu-iotests/223.out | 92 ++++++++++++------
29
tests/qemu-iotests/215 | 1 +
47
tests/qemu-iotests/229.out | 13 ++-
30
tests/qemu-iotests/251 | 1 +
48
tests/qemu-iotests/249.out | 16 +++-
31
21 files changed, 30 insertions(+), 9 deletions(-)
49
tests/qemu-iotests/308.out | 103 +++++++++++++++++---
50
tests/qemu-iotests/312.out | 10 +-
51
tests/qemu-iotests/common.qemu | 11 +--
52
24 files changed, 728 insertions(+), 199 deletions(-)
32
53
33
diff --git a/tests/qemu-iotests/002 b/tests/qemu-iotests/002
54
diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out
34
index XXXXXXX..XXXXXXX 100755
55
index XXXXXXX..XXXXXXX 100644
35
--- a/tests/qemu-iotests/002
56
--- a/tests/qemu-iotests/085.out
36
+++ b/tests/qemu-iotests/002
57
+++ b/tests/qemu-iotests/085.out
37
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
58
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=134217728
38
59
39
_supported_fmt generic
60
=== Create a single snapshot on virtio0 ===
40
_supported_proto generic
61
41
+_unsupported_imgopts "subformat=streamOptimized"
62
-{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } }
42
63
+{ 'execute': 'blockdev-snapshot-sync',
43
64
+ 'arguments': { 'device': 'virtio0',
44
size=128M
65
+ 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT',
45
diff --git a/tests/qemu-iotests/003 b/tests/qemu-iotests/003
66
+ 'format': 'IMGFMT' } }
46
index XXXXXXX..XXXXXXX 100755
67
Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
47
--- a/tests/qemu-iotests/003
68
{"return": {}}
48
+++ b/tests/qemu-iotests/003
69
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
70
=== Invalid command - missing device and nodename ===
50
71
51
_supported_fmt generic
72
-{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } }
52
_supported_proto generic
73
+{ 'execute': 'blockdev-snapshot-sync',
53
+_unsupported_imgopts "subformat=streamOptimized"
74
+ 'arguments': { 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT',
54
75
+ 'format': 'IMGFMT' } }
55
size=128M
76
{"error": {"class": "GenericError", "desc": "Cannot find device= nor node_name="}}
56
offset=67M
77
57
diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005
78
=== Invalid command - missing snapshot-file ===
58
index XXXXXXX..XXXXXXX 100755
79
59
--- a/tests/qemu-iotests/005
80
-{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'format': 'IMGFMT' } }
60
+++ b/tests/qemu-iotests/005
81
+{ 'execute': 'blockdev-snapshot-sync',
61
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
82
+ 'arguments': { 'device': 'virtio0',
62
_supported_proto generic
83
+ 'format': 'IMGFMT' } }
63
_supported_os Linux
84
{"error": {"class": "GenericError", "desc": "Parameter 'snapshot-file' is missing"}}
64
_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
85
65
- "subformat=twoGbMaxExtentSparse"
86
66
+ "subformat=twoGbMaxExtentSparse" \
87
=== Create several transactional group snapshots ===
67
+ "subformat=streamOptimized"
88
68
89
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/2-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/2-snapshot-v1.IMGFMT' } } ] } }
69
# vpc is limited to 127GB, so we can't test it here
90
+{ 'execute': 'transaction', 'arguments':
70
if [ "$IMGFMT" = "vpc" ]; then
91
+ {'actions': [
71
diff --git a/tests/qemu-iotests/009 b/tests/qemu-iotests/009
92
+ { 'type': 'blockdev-snapshot-sync', 'data' :
72
index XXXXXXX..XXXXXXX 100755
93
+ { 'device': 'virtio0',
73
--- a/tests/qemu-iotests/009
94
+ 'snapshot-file': 'TEST_DIR/2-snapshot-v0.IMGFMT' } },
74
+++ b/tests/qemu-iotests/009
95
+ { 'type': 'blockdev-snapshot-sync', 'data' :
75
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
96
+ { 'device': 'virtio1',
76
97
+ 'snapshot-file': 'TEST_DIR/2-snapshot-v1.IMGFMT' } } ]
77
_supported_fmt generic
98
+ } }
78
_supported_proto generic
99
Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
79
+_unsupported_imgopts "subformat=streamOptimized"
100
Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
80
101
{"return": {}}
81
102
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/3-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/3-snapshot-v1.IMGFMT' } } ] } }
82
size=6G
103
+{ 'execute': 'transaction', 'arguments':
83
diff --git a/tests/qemu-iotests/010 b/tests/qemu-iotests/010
104
+ {'actions': [
84
index XXXXXXX..XXXXXXX 100755
105
+ { 'type': 'blockdev-snapshot-sync', 'data' :
85
--- a/tests/qemu-iotests/010
106
+ { 'device': 'virtio0',
86
+++ b/tests/qemu-iotests/010
107
+ 'snapshot-file': 'TEST_DIR/3-snapshot-v0.IMGFMT' } },
87
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
108
+ { 'type': 'blockdev-snapshot-sync', 'data' :
88
109
+ { 'device': 'virtio1',
89
_supported_fmt generic
110
+ 'snapshot-file': 'TEST_DIR/3-snapshot-v1.IMGFMT' } } ]
90
_supported_proto generic
111
+ } }
91
+_unsupported_imgopts "subformat=streamOptimized"
112
Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
92
113
Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
93
114
{"return": {}}
94
size=6G
115
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/4-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/4-snapshot-v1.IMGFMT' } } ] } }
95
diff --git a/tests/qemu-iotests/011 b/tests/qemu-iotests/011
116
+{ 'execute': 'transaction', 'arguments':
96
index XXXXXXX..XXXXXXX 100755
117
+ {'actions': [
97
--- a/tests/qemu-iotests/011
118
+ { 'type': 'blockdev-snapshot-sync', 'data' :
98
+++ b/tests/qemu-iotests/011
119
+ { 'device': 'virtio0',
99
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
120
+ 'snapshot-file': 'TEST_DIR/4-snapshot-v0.IMGFMT' } },
100
121
+ { 'type': 'blockdev-snapshot-sync', 'data' :
101
_supported_fmt generic
122
+ { 'device': 'virtio1',
102
_supported_proto generic
123
+ 'snapshot-file': 'TEST_DIR/4-snapshot-v1.IMGFMT' } } ]
103
+_unsupported_imgopts "subformat=streamOptimized"
124
+ } }
104
125
Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
105
126
Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
106
size=6G
127
{"return": {}}
107
diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017
128
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/5-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/5-snapshot-v1.IMGFMT' } } ] } }
108
index XXXXXXX..XXXXXXX 100755
129
+{ 'execute': 'transaction', 'arguments':
109
--- a/tests/qemu-iotests/017
130
+ {'actions': [
110
+++ b/tests/qemu-iotests/017
131
+ { 'type': 'blockdev-snapshot-sync', 'data' :
111
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
132
+ { 'device': 'virtio0',
112
_supported_fmt qcow qcow2 vmdk qed
133
+ 'snapshot-file': 'TEST_DIR/5-snapshot-v0.IMGFMT' } },
113
_supported_proto generic
134
+ { 'type': 'blockdev-snapshot-sync', 'data' :
114
_unsupported_proto vxhs
135
+ { 'device': 'virtio1',
115
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
136
+ 'snapshot-file': 'TEST_DIR/5-snapshot-v1.IMGFMT' } } ]
116
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
137
+ } }
117
+ "subformat=streamOptimized"
138
Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
118
139
Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
119
TEST_OFFSETS="0 4294967296"
140
{"return": {}}
120
141
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/6-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/6-snapshot-v1.IMGFMT' } } ] } }
121
diff --git a/tests/qemu-iotests/018 b/tests/qemu-iotests/018
142
+{ 'execute': 'transaction', 'arguments':
122
index XXXXXXX..XXXXXXX 100755
143
+ {'actions': [
123
--- a/tests/qemu-iotests/018
144
+ { 'type': 'blockdev-snapshot-sync', 'data' :
124
+++ b/tests/qemu-iotests/018
145
+ { 'device': 'virtio0',
125
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
146
+ 'snapshot-file': 'TEST_DIR/6-snapshot-v0.IMGFMT' } },
126
_supported_fmt qcow qcow2 vmdk qed
147
+ { 'type': 'blockdev-snapshot-sync', 'data' :
127
_supported_proto file
148
+ { 'device': 'virtio1',
128
_supported_os Linux
149
+ 'snapshot-file': 'TEST_DIR/6-snapshot-v1.IMGFMT' } } ]
129
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
150
+ } }
130
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
151
Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
131
+ "streamOptimized"
152
Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
132
153
{"return": {}}
133
TEST_OFFSETS="0 4294967296"
154
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/7-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/7-snapshot-v1.IMGFMT' } } ] } }
134
155
+{ 'execute': 'transaction', 'arguments':
135
diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019
156
+ {'actions': [
136
index XXXXXXX..XXXXXXX 100755
157
+ { 'type': 'blockdev-snapshot-sync', 'data' :
137
--- a/tests/qemu-iotests/019
158
+ { 'device': 'virtio0',
138
+++ b/tests/qemu-iotests/019
159
+ 'snapshot-file': 'TEST_DIR/7-snapshot-v0.IMGFMT' } },
139
@@ -XXX,XX +XXX,XX @@ _supported_proto file
160
+ { 'type': 'blockdev-snapshot-sync', 'data' :
140
_supported_os Linux
161
+ { 'device': 'virtio1',
141
_unsupported_imgopts "subformat=monolithicFlat" \
162
+ 'snapshot-file': 'TEST_DIR/7-snapshot-v1.IMGFMT' } } ]
142
"subformat=twoGbMaxExtentFlat" \
163
+ } }
143
- "subformat=twoGbMaxExtentSparse"
164
Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
144
+ "subformat=twoGbMaxExtentSparse" \
165
Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
145
+ "subformat=streamOptimized"
166
{"return": {}}
146
167
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/8-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/8-snapshot-v1.IMGFMT' } } ] } }
147
TEST_OFFSETS="0 4294967296"
168
+{ 'execute': 'transaction', 'arguments':
148
CLUSTER_SIZE=65536
169
+ {'actions': [
149
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
170
+ { 'type': 'blockdev-snapshot-sync', 'data' :
150
index XXXXXXX..XXXXXXX 100755
171
+ { 'device': 'virtio0',
151
--- a/tests/qemu-iotests/020
172
+ 'snapshot-file': 'TEST_DIR/8-snapshot-v0.IMGFMT' } },
152
+++ b/tests/qemu-iotests/020
173
+ { 'type': 'blockdev-snapshot-sync', 'data' :
153
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed
174
+ { 'device': 'virtio1',
154
_supported_proto file
175
+ 'snapshot-file': 'TEST_DIR/8-snapshot-v1.IMGFMT' } } ]
155
_unsupported_imgopts "subformat=monolithicFlat" \
176
+ } }
156
"subformat=twoGbMaxExtentFlat" \
177
Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
157
- "subformat=twoGbMaxExtentSparse"
178
Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
158
+ "subformat=twoGbMaxExtentSparse" \
179
{"return": {}}
159
+ "subformat=streamOptimized"
180
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/9-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/9-snapshot-v1.IMGFMT' } } ] } }
160
181
+{ 'execute': 'transaction', 'arguments':
161
TEST_OFFSETS="0 4294967296"
182
+ {'actions': [
162
183
+ { 'type': 'blockdev-snapshot-sync', 'data' :
163
diff --git a/tests/qemu-iotests/027 b/tests/qemu-iotests/027
184
+ { 'device': 'virtio0',
164
index XXXXXXX..XXXXXXX 100755
185
+ 'snapshot-file': 'TEST_DIR/9-snapshot-v0.IMGFMT' } },
165
--- a/tests/qemu-iotests/027
186
+ { 'type': 'blockdev-snapshot-sync', 'data' :
166
+++ b/tests/qemu-iotests/027
187
+ { 'device': 'virtio1',
167
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
188
+ 'snapshot-file': 'TEST_DIR/9-snapshot-v1.IMGFMT' } } ]
168
189
+ } }
169
_supported_fmt vmdk qcow qcow2 qed
190
Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
170
_supported_proto generic
191
Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
171
+_unsupported_imgopts "subformat=streamOptimized"
192
{"return": {}}
172
193
-{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/10-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/10-snapshot-v1.IMGFMT' } } ] } }
173
194
+{ 'execute': 'transaction', 'arguments':
174
size=128M
195
+ {'actions': [
175
diff --git a/tests/qemu-iotests/032 b/tests/qemu-iotests/032
196
+ { 'type': 'blockdev-snapshot-sync', 'data' :
176
index XXXXXXX..XXXXXXX 100755
197
+ { 'device': 'virtio0',
177
--- a/tests/qemu-iotests/032
198
+ 'snapshot-file': 'TEST_DIR/10-snapshot-v0.IMGFMT' } },
178
+++ b/tests/qemu-iotests/032
199
+ { 'type': 'blockdev-snapshot-sync', 'data' :
179
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
200
+ { 'device': 'virtio1',
180
# This works for any image format (though unlikely to segfault for raw)
201
+ 'snapshot-file': 'TEST_DIR/10-snapshot-v1.IMGFMT' } } ]
181
_supported_fmt generic
202
+ } }
182
_supported_proto generic
203
Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
183
+_unsupported_imgopts "subformat=streamOptimized"
204
Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
184
205
{"return": {}}
185
echo
206
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extende
186
echo === Prepare image ===
207
=== Create a couple of snapshots using blockdev-snapshot ===
187
diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
208
188
index XXXXXXX..XXXXXXX 100755
209
Formatting 'TEST_DIR/11-snapshot-v0.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/10-snapshot-v0.IMGFMT backing_fmt=IMGFMT
189
--- a/tests/qemu-iotests/033
210
-{ 'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'snap_11', 'backing': null, 'file': { 'driver': 'file', 'filename': 'TEST_DIR/11-snapshot-v0.IMGFMT', 'node-name': 'file_11' } } }
190
+++ b/tests/qemu-iotests/033
211
+{ 'execute': 'blockdev-add', 'arguments':
191
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
212
+ { 'driver': 'IMGFMT', 'node-name': 'snap_11', 'backing': null,
192
213
+ 'file':
193
_supported_fmt generic
214
+ { 'driver': 'file', 'filename': 'TEST_DIR/11-snapshot-v0.IMGFMT',
194
_supported_proto generic
215
+ 'node-name': 'file_11' } } }
195
+_unsupported_imgopts "subformat=streamOptimized"
216
{"return": {}}
196
217
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_11' } }
197
218
+{ 'execute': 'blockdev-snapshot',
198
size=128M
219
+ 'arguments': { 'node': 'virtio0',
199
diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034
220
+ 'overlay':'snap_11' } }
200
index XXXXXXX..XXXXXXX 100755
221
{"return": {}}
201
--- a/tests/qemu-iotests/034
222
Formatting 'TEST_DIR/12-snapshot-v0.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/11-snapshot-v0.IMGFMT backing_fmt=IMGFMT
202
+++ b/tests/qemu-iotests/034
223
-{ 'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'snap_12', 'backing': null, 'file': { 'driver': 'file', 'filename': 'TEST_DIR/12-snapshot-v0.IMGFMT', 'node-name': 'file_12' } } }
203
@@ -XXX,XX +XXX,XX @@ _supported_proto file
224
+{ 'execute': 'blockdev-add', 'arguments':
204
_supported_os Linux
225
+ { 'driver': 'IMGFMT', 'node-name': 'snap_12', 'backing': null,
205
_unsupported_imgopts "subformat=monolithicFlat" \
226
+ 'file':
206
"subformat=twoGbMaxExtentFlat" \
227
+ { 'driver': 'file', 'filename': 'TEST_DIR/12-snapshot-v0.IMGFMT',
207
- "subformat=twoGbMaxExtentSparse"
228
+ 'node-name': 'file_12' } } }
208
+ "subformat=twoGbMaxExtentSparse" \
229
{"return": {}}
209
+ "subformat=streamOptimized"
230
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_12' } }
210
231
+{ 'execute': 'blockdev-snapshot',
211
CLUSTER_SIZE=4k
232
+ 'arguments': { 'node': 'virtio0',
212
size=128M
233
+ 'overlay':'snap_12' } }
213
diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037
234
{"return": {}}
214
index XXXXXXX..XXXXXXX 100755
235
215
--- a/tests/qemu-iotests/037
236
=== Invalid command - cannot create a snapshot using a file BDS ===
216
+++ b/tests/qemu-iotests/037
237
217
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed
238
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node':'virtio0', 'overlay':'file_12' } }
218
_supported_proto file
239
+{ 'execute': 'blockdev-snapshot',
219
_unsupported_imgopts "subformat=monolithicFlat" \
240
+ 'arguments': { 'node':'virtio0',
220
"subformat=twoGbMaxExtentFlat" \
241
+ 'overlay':'file_12' }
221
- "subformat=twoGbMaxExtentSparse"
242
+ }
222
+ "subformat=twoGbMaxExtentSparse" \
243
{"error": {"class": "GenericError", "desc": "The overlay is already in use"}}
223
+ "subformat=streamOptimized"
244
224
245
=== Invalid command - snapshot node used as active layer ===
225
CLUSTER_SIZE=4k
246
226
size=128M
247
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_12' } }
227
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
248
+{ 'execute': 'blockdev-snapshot',
228
index XXXXXXX..XXXXXXX 100755
249
+ 'arguments': { 'node': 'virtio0',
229
--- a/tests/qemu-iotests/063
250
+ 'overlay':'snap_12' } }
230
+++ b/tests/qemu-iotests/063
251
{"error": {"class": "GenericError", "desc": "The overlay is already in use"}}
231
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed raw
252
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node':'virtio0', 'overlay':'virtio0' } }
232
_supported_proto file
253
+{ 'execute': 'blockdev-snapshot',
233
_unsupported_imgopts "subformat=monolithicFlat" \
254
+ 'arguments': { 'node':'virtio0',
234
"subformat=twoGbMaxExtentFlat" \
255
+ 'overlay':'virtio0' }
235
- "subformat=twoGbMaxExtentSparse"
256
+ }
236
+ "subformat=twoGbMaxExtentSparse" \
257
{"error": {"class": "GenericError", "desc": "The overlay is already in use"}}
237
+ "subformat=streamOptimized"
258
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node':'virtio0', 'overlay':'virtio1' } }
238
259
+{ 'execute': 'blockdev-snapshot',
239
_make_test_img 4M
260
+ 'arguments': { 'node':'virtio0',
240
261
+ 'overlay':'virtio1' }
241
diff --git a/tests/qemu-iotests/072 b/tests/qemu-iotests/072
262
+ }
242
index XXXXXXX..XXXXXXX 100755
263
{"error": {"class": "GenericError", "desc": "The overlay is already in use"}}
243
--- a/tests/qemu-iotests/072
264
244
+++ b/tests/qemu-iotests/072
265
=== Invalid command - snapshot node used as backing hd ===
245
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
266
246
267
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_11' } }
247
_supported_fmt vpc vmdk vhdx vdi qed qcow2 qcow
268
+{ 'execute': 'blockdev-snapshot',
248
_supported_proto file
269
+ 'arguments': { 'node': 'virtio0',
249
+_unsupported_imgopts "subformat=streamOptimized"
270
+ 'overlay':'snap_11' } }
250
271
{"error": {"class": "GenericError", "desc": "The overlay is already in use"}}
251
IMG_SIZE=64M
272
252
273
=== Invalid command - snapshot node has a backing image ===
253
diff --git a/tests/qemu-iotests/105 b/tests/qemu-iotests/105
274
254
index XXXXXXX..XXXXXXX 100755
275
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
255
--- a/tests/qemu-iotests/105
276
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
256
+++ b/tests/qemu-iotests/105
277
-{ 'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'snap_13', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'node-name': 'file_13' } } }
257
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
278
-{"return": {}}
258
_supported_fmt qcow2 vmdk vhdx qed
279
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_13' } }
259
_supported_proto generic
280
+{ 'execute': 'blockdev-add', 'arguments':
260
_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
281
+ { 'driver': 'IMGFMT', 'node-name': 'snap_13',
261
- "subformat=twoGbMaxExtentSparse"
282
+ 'file':
262
+ "subformat=twoGbMaxExtentSparse" \
283
+ { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT',
263
+ "subformat=streamOptimized"
284
+ 'node-name': 'file_13' } } }
264
285
+{"return": {}}
265
echo
286
+{ 'execute': 'blockdev-snapshot',
266
echo "creating large image"
287
+ 'arguments': { 'node': 'virtio0',
267
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
288
+ 'overlay':'snap_13' } }
268
index XXXXXXX..XXXXXXX 100755
289
{"error": {"class": "GenericError", "desc": "The overlay already has a backing image"}}
269
--- a/tests/qemu-iotests/197
290
270
+++ b/tests/qemu-iotests/197
291
=== Invalid command - The node does not exist ===
271
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
292
272
_supported_proto generic
293
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_14' } }
273
# LUKS support may be possible, but it complicates things.
294
+{ 'execute': 'blockdev-snapshot',
274
_unsupported_fmt luks
295
+ 'arguments': { 'node': 'virtio0',
275
+_unsupported_imgopts "subformat=streamOptimized"
296
+ 'overlay':'snap_14' } }
276
297
{"error": {"class": "GenericError", "desc": "Cannot find device=snap_14 nor node_name=snap_14"}}
277
echo
298
-{ 'execute': 'blockdev-snapshot', 'arguments': { 'node':'nodevice', 'overlay':'snap_13' } }
278
echo '=== Copy-on-read ==='
299
+{ 'execute': 'blockdev-snapshot',
279
diff --git a/tests/qemu-iotests/215 b/tests/qemu-iotests/215
300
+ 'arguments': { 'node':'nodevice',
280
index XXXXXXX..XXXXXXX 100755
301
+ 'overlay':'snap_13' }
281
--- a/tests/qemu-iotests/215
302
+ }
282
+++ b/tests/qemu-iotests/215
303
{"error": {"class": "GenericError", "desc": "Cannot find device=nodevice nor node_name=nodevice"}}
283
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
304
*** done
284
_supported_proto generic
305
diff --git a/tests/qemu-iotests/094.out b/tests/qemu-iotests/094.out
285
# LUKS support may be possible, but it complicates things.
306
index XXXXXXX..XXXXXXX 100644
286
_unsupported_fmt luks
307
--- a/tests/qemu-iotests/094.out
287
+_unsupported_imgopts "subformat=streamOptimized"
308
+++ b/tests/qemu-iotests/094.out
288
309
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
289
echo
310
Formatting 'TEST_DIR/source.IMGFMT', fmt=IMGFMT size=67108864
290
echo '=== Copy-on-read ==='
311
{'execute': 'qmp_capabilities'}
291
diff --git a/tests/qemu-iotests/251 b/tests/qemu-iotests/251
312
{"return": {}}
292
index XXXXXXX..XXXXXXX 100755
313
-{'execute': 'drive-mirror', 'arguments': {'device': 'src', 'target': 'nbd+unix:///?socket=SOCK_DIR/nbd', 'format': 'nbd', 'sync':'full', 'mode':'existing'}}
293
--- a/tests/qemu-iotests/251
314
+{'execute': 'drive-mirror',
294
+++ b/tests/qemu-iotests/251
315
+ 'arguments': {'device': 'src',
295
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
316
+ 'target': 'nbd+unix:///?socket=SOCK_DIR/nbd',
296
_supported_fmt generic
317
+ 'format': 'nbd',
297
_supported_proto file
318
+ 'sync':'full',
298
_supported_os Linux
319
+ 'mode':'existing'}}
299
+_unsupported_imgopts "subformat=streamOptimized"
320
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
300
321
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
301
if [ "$IMGOPTSSYNTAX" = "true" ]; then
322
{"return": {}}
302
# We use json:{} filenames here, so we cannot work with additional options.
323
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
324
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}}
325
-{'execute': 'block-job-complete', 'arguments': {'device': 'src'}}
326
+{'execute': 'block-job-complete',
327
+ 'arguments': {'device': 'src'}}
328
{"return": {}}
329
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}}
330
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "src"}}
331
diff --git a/tests/qemu-iotests/095.out b/tests/qemu-iotests/095.out
332
index XXXXXXX..XXXXXXX 100644
333
--- a/tests/qemu-iotests/095.out
334
+++ b/tests/qemu-iotests/095.out
335
@@ -XXX,XX +XXX,XX @@ virtual size: 5 MiB (5242880 bytes)
336
337
{ 'execute': 'qmp_capabilities' }
338
{"return": {}}
339
-{ 'execute': 'block-commit', 'arguments': { 'device': 'test', 'top': 'TEST_DIR/t.IMGFMT.snp1' } }
340
+{ 'execute': 'block-commit',
341
+ 'arguments': { 'device': 'test',
342
+ 'top': 'TEST_DIR/t.IMGFMT.snp1' } }
343
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "test"}}
344
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "test"}}
345
{"return": {}}
346
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
347
index XXXXXXX..XXXXXXX 100644
348
--- a/tests/qemu-iotests/109.out
349
+++ b/tests/qemu-iotests/109.out
350
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
351
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
352
{ 'execute': 'qmp_capabilities' }
353
{"return": {}}
354
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
355
+{'execute':'drive-mirror', 'arguments':{
356
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
357
+ 'mode': 'existing', 'sync': 'full'}}
358
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
359
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
360
Specify the 'raw' format explicitly to remove the restrictions.
361
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
362
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
363
{ 'execute': 'qmp_capabilities' }
364
{"return": {}}
365
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
366
+{'execute':'drive-mirror', 'arguments':{
367
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
368
+ 'mode': 'existing', 'sync': 'full'}}
369
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
370
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
371
{"return": {}}
372
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
373
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
374
{ 'execute': 'qmp_capabilities' }
375
{"return": {}}
376
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
377
+{'execute':'drive-mirror', 'arguments':{
378
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
379
+ 'mode': 'existing', 'sync': 'full'}}
380
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
381
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
382
Specify the 'raw' format explicitly to remove the restrictions.
383
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
384
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
385
{ 'execute': 'qmp_capabilities' }
386
{"return": {}}
387
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
388
+{'execute':'drive-mirror', 'arguments':{
389
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
390
+ 'mode': 'existing', 'sync': 'full'}}
391
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
392
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
393
{"return": {}}
394
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
395
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
396
{ 'execute': 'qmp_capabilities' }
397
{"return": {}}
398
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
399
+{'execute':'drive-mirror', 'arguments':{
400
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
401
+ 'mode': 'existing', 'sync': 'full'}}
402
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
403
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
404
Specify the 'raw' format explicitly to remove the restrictions.
405
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
406
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
407
{ 'execute': 'qmp_capabilities' }
408
{"return": {}}
409
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
410
+{'execute':'drive-mirror', 'arguments':{
411
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
412
+ 'mode': 'existing', 'sync': 'full'}}
413
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
414
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
415
{"return": {}}
416
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
417
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
418
{ 'execute': 'qmp_capabilities' }
419
{"return": {}}
420
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
421
+{'execute':'drive-mirror', 'arguments':{
422
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
423
+ 'mode': 'existing', 'sync': 'full'}}
424
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
425
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
426
Specify the 'raw' format explicitly to remove the restrictions.
427
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
428
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
429
{ 'execute': 'qmp_capabilities' }
430
{"return": {}}
431
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
432
+{'execute':'drive-mirror', 'arguments':{
433
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
434
+ 'mode': 'existing', 'sync': 'full'}}
435
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
436
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
437
{"return": {}}
438
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
439
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
440
{ 'execute': 'qmp_capabilities' }
441
{"return": {}}
442
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
443
+{'execute':'drive-mirror', 'arguments':{
444
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
445
+ 'mode': 'existing', 'sync': 'full'}}
446
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
447
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
448
Specify the 'raw' format explicitly to remove the restrictions.
449
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
450
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
451
{ 'execute': 'qmp_capabilities' }
452
{"return": {}}
453
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
454
+{'execute':'drive-mirror', 'arguments':{
455
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
456
+ 'mode': 'existing', 'sync': 'full'}}
457
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
458
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
459
{"return": {}}
460
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
461
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
462
{ 'execute': 'qmp_capabilities' }
463
{"return": {}}
464
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
465
+{'execute':'drive-mirror', 'arguments':{
466
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
467
+ 'mode': 'existing', 'sync': 'full'}}
468
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
469
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
470
Specify the 'raw' format explicitly to remove the restrictions.
471
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
472
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
473
{ 'execute': 'qmp_capabilities' }
474
{"return": {}}
475
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
476
+{'execute':'drive-mirror', 'arguments':{
477
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
478
+ 'mode': 'existing', 'sync': 'full'}}
479
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
480
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
481
{"return": {}}
482
@@ -XXX,XX +XXX,XX @@ Images are identical.
483
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
484
{ 'execute': 'qmp_capabilities' }
485
{"return": {}}
486
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
487
+{'execute':'drive-mirror', 'arguments':{
488
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
489
+ 'mode': 'existing', 'sync': 'full'}}
490
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
491
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
492
Specify the 'raw' format explicitly to remove the restrictions.
493
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
494
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
495
{ 'execute': 'qmp_capabilities' }
496
{"return": {}}
497
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
498
+{'execute':'drive-mirror', 'arguments':{
499
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
500
+ 'mode': 'existing', 'sync': 'full'}}
501
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
502
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
503
{"return": {}}
504
@@ -XXX,XX +XXX,XX @@ Images are identical.
505
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
506
{ 'execute': 'qmp_capabilities' }
507
{"return": {}}
508
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
509
+{'execute':'drive-mirror', 'arguments':{
510
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
511
+ 'mode': 'existing', 'sync': 'full'}}
512
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
513
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
514
Specify the 'raw' format explicitly to remove the restrictions.
515
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
516
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
517
{ 'execute': 'qmp_capabilities' }
518
{"return": {}}
519
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
520
+{'execute':'drive-mirror', 'arguments':{
521
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
522
+ 'mode': 'existing', 'sync': 'full'}}
523
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
524
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
525
{"return": {}}
526
@@ -XXX,XX +XXX,XX @@ Images are identical.
527
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
528
{ 'execute': 'qmp_capabilities' }
529
{"return": {}}
530
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
531
+{'execute':'drive-mirror', 'arguments':{
532
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
533
+ 'mode': 'existing', 'sync': 'full'}}
534
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
535
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
536
Specify the 'raw' format explicitly to remove the restrictions.
537
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
538
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
539
{ 'execute': 'qmp_capabilities' }
540
{"return": {}}
541
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
542
+{'execute':'drive-mirror', 'arguments':{
543
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
544
+ 'mode': 'existing', 'sync': 'full'}}
545
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
546
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
547
{"return": {}}
548
@@ -XXX,XX +XXX,XX @@ Images are identical.
549
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
550
{ 'execute': 'qmp_capabilities' }
551
{"return": {}}
552
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
553
+{'execute':'drive-mirror', 'arguments':{
554
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
555
+ 'mode': 'existing', 'sync': 'full'}}
556
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
557
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
558
Specify the 'raw' format explicitly to remove the restrictions.
559
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
560
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
561
{ 'execute': 'qmp_capabilities' }
562
{"return": {}}
563
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
564
+{'execute':'drive-mirror', 'arguments':{
565
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
566
+ 'mode': 'existing', 'sync': 'full'}}
567
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
568
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
569
{"return": {}}
570
@@ -XXX,XX +XXX,XX @@ Images are identical.
571
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
572
{ 'execute': 'qmp_capabilities' }
573
{"return": {}}
574
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
575
+{'execute':'drive-mirror', 'arguments':{
576
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT',
577
+ 'mode': 'existing', 'sync': 'full'}}
578
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
579
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
580
Specify the 'raw' format explicitly to remove the restrictions.
581
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
582
Images are identical.
583
{ 'execute': 'qmp_capabilities' }
584
{"return": {}}
585
-{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
586
+{'execute':'drive-mirror', 'arguments':{
587
+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT',
588
+ 'mode': 'existing', 'sync': 'full'}}
589
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}}
590
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}}
591
{"return": {}}
592
diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out
593
index XXXXXXX..XXXXXXX 100644
594
--- a/tests/qemu-iotests/117.out
595
+++ b/tests/qemu-iotests/117.out
596
@@ -XXX,XX +XXX,XX @@ QA output created by 117
597
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
598
{ 'execute': 'qmp_capabilities' }
599
{"return": {}}
600
-{ 'execute': 'blockdev-add', 'arguments': { 'node-name': 'protocol', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' } }
601
+{ 'execute': 'blockdev-add',
602
+ 'arguments': { 'node-name': 'protocol',
603
+ 'driver': 'file',
604
+ 'filename': 'TEST_DIR/t.IMGFMT' } }
605
{"return": {}}
606
-{ 'execute': 'blockdev-add', 'arguments': { 'node-name': 'format', 'driver': 'IMGFMT', 'file': 'protocol' } }
607
+{ 'execute': 'blockdev-add',
608
+ 'arguments': { 'node-name': 'format',
609
+ 'driver': 'IMGFMT',
610
+ 'file': 'protocol' } }
611
{"return": {}}
612
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io format "write -P 42 0 64k"' } }
613
+{ 'execute': 'human-monitor-command',
614
+ 'arguments': { 'command-line': 'qemu-io format "write -P 42 0 64k"' } }
615
wrote 65536/65536 bytes at offset 0
616
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
617
{"return": ""}
618
diff --git a/tests/qemu-iotests/127.out b/tests/qemu-iotests/127.out
619
index XXXXXXX..XXXXXXX 100644
620
--- a/tests/qemu-iotests/127.out
621
+++ b/tests/qemu-iotests/127.out
622
@@ -XXX,XX +XXX,XX @@ wrote 42/42 bytes at offset 0
623
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
624
{ 'execute': 'qmp_capabilities' }
625
{"return": {}}
626
-{ 'execute': 'drive-mirror', 'arguments': { 'job-id': 'mirror', 'device': 'source', 'target': 'TEST_DIR/t.IMGFMT.overlay1', 'mode': 'existing', 'sync': 'top' } }
627
+{ 'execute': 'drive-mirror',
628
+ 'arguments': {
629
+ 'job-id': 'mirror',
630
+ 'device': 'source',
631
+ 'target': 'TEST_DIR/t.IMGFMT.overlay1',
632
+ 'mode': 'existing',
633
+ 'sync': 'top'
634
+ } }
635
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "mirror"}}
636
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "mirror"}}
637
{"return": {}}
638
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}}
639
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
640
-{ 'execute': 'block-job-complete', 'arguments': { 'device': 'mirror' } }
641
+{ 'execute': 'block-job-complete',
642
+ 'arguments': { 'device': 'mirror' } }
643
{"return": {}}
644
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "mirror"}}
645
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "mirror"}}
646
diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
647
index XXXXXXX..XXXXXXX 100644
648
--- a/tests/qemu-iotests/140.out
649
+++ b/tests/qemu-iotests/140.out
650
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 0
651
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
652
{ 'execute': 'qmp_capabilities' }
653
{"return": {}}
654
-{ 'execute': 'nbd-server-start', 'arguments': { 'addr': { 'type': 'unix', 'data': { 'path': 'SOCK_DIR/nbd' }}}}
655
+{ 'execute': 'nbd-server-start',
656
+ 'arguments': { 'addr': { 'type': 'unix',
657
+ 'data': { 'path': 'SOCK_DIR/nbd' }}}}
658
{"return": {}}
659
-{ 'execute': 'nbd-server-add', 'arguments': { 'device': 'drv' }}
660
+{ 'execute': 'nbd-server-add',
661
+ 'arguments': { 'device': 'drv' }}
662
{"return": {}}
663
read 65536/65536 bytes at offset 0
664
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
665
-{ 'execute': 'eject', 'arguments': { 'device': 'drv' }}
666
+{ 'execute': 'eject',
667
+ 'arguments': { 'device': 'drv' }}
668
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "drv"}}
669
qemu-io: can't open device nbd+unix:///drv?socket=SOCK_DIR/nbd: Requested export not available
670
server reported: export 'drv' not present
671
diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
672
index XXXXXXX..XXXXXXX 100644
673
--- a/tests/qemu-iotests/141.out
674
+++ b/tests/qemu-iotests/141.out
675
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.
676
677
=== Testing drive-backup ===
678
679
-{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}}
680
-{"return": {}}
681
-{'execute': 'drive-backup', 'arguments': {'job-id': 'job0', 'device': 'drv0', 'target': 'TEST_DIR/o.IMGFMT', 'format': 'IMGFMT', 'sync': 'none'}}
682
+{'execute': 'blockdev-add',
683
+ 'arguments': {
684
+ 'node-name': 'drv0',
685
+ 'driver': 'IMGFMT',
686
+ 'file': {
687
+ 'driver': 'file',
688
+ 'filename': 'TEST_DIR/t.IMGFMT'
689
+ }}}
690
+{"return": {}}
691
+{'execute': 'drive-backup',
692
+'arguments': {'job-id': 'job0',
693
+'device': 'drv0',
694
+'target': 'TEST_DIR/o.IMGFMT',
695
+'format': 'IMGFMT',
696
+'sync': 'none'}}
697
Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
698
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
699
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
700
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "job0"}}
701
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
702
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
703
+{'execute': 'blockdev-del',
704
+ 'arguments': {'node-name': 'drv0'}}
705
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
706
-{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}}
707
+{'execute': 'block-job-cancel',
708
+ 'arguments': {'device': 'job0'}}
709
{"return": {}}
710
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
711
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}}
712
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
713
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
714
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
715
+{'execute': 'blockdev-del',
716
+ 'arguments': {'node-name': 'drv0'}}
717
{"return": {}}
718
719
=== Testing drive-mirror ===
720
721
-{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}}
722
-{"return": {}}
723
-{'execute': 'drive-mirror', 'arguments': {'job-id': 'job0', 'device': 'drv0', 'target': 'TEST_DIR/o.IMGFMT', 'format': 'IMGFMT', 'sync': 'none'}}
724
+{'execute': 'blockdev-add',
725
+ 'arguments': {
726
+ 'node-name': 'drv0',
727
+ 'driver': 'IMGFMT',
728
+ 'file': {
729
+ 'driver': 'file',
730
+ 'filename': 'TEST_DIR/t.IMGFMT'
731
+ }}}
732
+{"return": {}}
733
+{'execute': 'drive-mirror',
734
+'arguments': {'job-id': 'job0',
735
+'device': 'drv0',
736
+'target': 'TEST_DIR/o.IMGFMT',
737
+'format': 'IMGFMT',
738
+'sync': 'none'}}
739
Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
740
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
741
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
742
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
743
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
744
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
745
+{'execute': 'blockdev-del',
746
+ 'arguments': {'node-name': 'drv0'}}
747
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
748
-{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}}
749
+{'execute': 'block-job-cancel',
750
+ 'arguments': {'device': 'job0'}}
751
{"return": {}}
752
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
753
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
754
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
755
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
756
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
757
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
758
+{'execute': 'blockdev-del',
759
+ 'arguments': {'node-name': 'drv0'}}
760
{"return": {}}
761
762
=== Testing active block-commit ===
763
764
-{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}}
765
-{"return": {}}
766
-{'execute': 'block-commit', 'arguments': {'job-id': 'job0', 'device': 'drv0'}}
767
+{'execute': 'blockdev-add',
768
+ 'arguments': {
769
+ 'node-name': 'drv0',
770
+ 'driver': 'IMGFMT',
771
+ 'file': {
772
+ 'driver': 'file',
773
+ 'filename': 'TEST_DIR/t.IMGFMT'
774
+ }}}
775
+{"return": {}}
776
+{'execute': 'block-commit',
777
+'arguments': {'job-id': 'job0', 'device': 'drv0'}}
778
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
779
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
780
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
781
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
782
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
783
+{'execute': 'blockdev-del',
784
+ 'arguments': {'node-name': 'drv0'}}
785
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
786
-{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}}
787
+{'execute': 'block-job-cancel',
788
+ 'arguments': {'device': 'job0'}}
789
{"return": {}}
790
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
791
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
792
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
793
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
794
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
795
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
796
+{'execute': 'blockdev-del',
797
+ 'arguments': {'node-name': 'drv0'}}
798
{"return": {}}
799
800
=== Testing non-active block-commit ===
801
802
wrote 1048576/1048576 bytes at offset 0
803
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
804
-{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}}
805
-{"return": {}}
806
-{'execute': 'block-commit', 'arguments': {'job-id': 'job0', 'device': 'drv0', 'top': 'TEST_DIR/m.IMGFMT', 'speed': 1}}
807
+{'execute': 'blockdev-add',
808
+ 'arguments': {
809
+ 'node-name': 'drv0',
810
+ 'driver': 'IMGFMT',
811
+ 'file': {
812
+ 'driver': 'file',
813
+ 'filename': 'TEST_DIR/t.IMGFMT'
814
+ }}}
815
+{"return": {}}
816
+{'execute': 'block-commit',
817
+'arguments': {'job-id': 'job0',
818
+'device': 'drv0',
819
+'top': 'TEST_DIR/m.IMGFMT',
820
+'speed': 1}}
821
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
822
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
823
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
824
+{'execute': 'blockdev-del',
825
+ 'arguments': {'node-name': 'drv0'}}
826
{"error": {"class": "GenericError", "desc": "Node drv0 is in use"}}
827
-{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}}
828
+{'execute': 'block-job-cancel',
829
+ 'arguments': {'device': 'job0'}}
830
{"return": {}}
831
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
832
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}}
833
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
834
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
835
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
836
+{'execute': 'blockdev-del',
837
+ 'arguments': {'node-name': 'drv0'}}
838
{"return": {}}
839
840
=== Testing block-stream ===
841
842
wrote 1048576/1048576 bytes at offset 0
843
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
844
-{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}}
845
-{"return": {}}
846
-{'execute': 'block-stream', 'arguments': {'job-id': 'job0', 'device': 'drv0', 'speed': 1}}
847
+{'execute': 'blockdev-add',
848
+ 'arguments': {
849
+ 'node-name': 'drv0',
850
+ 'driver': 'IMGFMT',
851
+ 'file': {
852
+ 'driver': 'file',
853
+ 'filename': 'TEST_DIR/t.IMGFMT'
854
+ }}}
855
+{"return": {}}
856
+{'execute': 'block-stream',
857
+'arguments': {'job-id': 'job0',
858
+'device': 'drv0',
859
+'speed': 1}}
860
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
861
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
862
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
863
+{'execute': 'blockdev-del',
864
+ 'arguments': {'node-name': 'drv0'}}
865
{"error": {"class": "GenericError", "desc": "Node drv0 is in use"}}
866
-{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}}
867
+{'execute': 'block-job-cancel',
868
+ 'arguments': {'device': 'job0'}}
869
{"return": {}}
870
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
871
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}}
872
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
873
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
874
-{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}
875
+{'execute': 'blockdev-del',
876
+ 'arguments': {'node-name': 'drv0'}}
877
{"return": {}}
878
*** done
879
diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
880
index XXXXXXX..XXXXXXX 100644
881
--- a/tests/qemu-iotests/143.out
882
+++ b/tests/qemu-iotests/143.out
883
@@ -XXX,XX +XXX,XX @@
884
QA output created by 143
885
{ 'execute': 'qmp_capabilities' }
886
{"return": {}}
887
-{ 'execute': 'nbd-server-start', 'arguments': { 'addr': { 'type': 'unix', 'data': { 'path': 'SOCK_DIR/nbd' }}}}
888
+{ 'execute': 'nbd-server-start',
889
+ 'arguments': { 'addr': { 'type': 'unix',
890
+ 'data': { 'path': 'SOCK_DIR/nbd' }}}}
891
{"return": {}}
892
qemu-io: can't open device nbd+unix:///no_such_export?socket=SOCK_DIR/nbd: Requested export not available
893
server reported: export 'no_such_export' not present
894
diff --git a/tests/qemu-iotests/144.out b/tests/qemu-iotests/144.out
895
index XXXXXXX..XXXXXXX 100644
896
--- a/tests/qemu-iotests/144.out
897
+++ b/tests/qemu-iotests/144.out
898
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912
899
900
{ 'execute': 'qmp_capabilities' }
901
{"return": {}}
902
-{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp.IMGFMT', 'format': 'IMGFMT' } }
903
+{ 'execute': 'blockdev-snapshot-sync',
904
+ 'arguments': {
905
+ 'device': 'virtio0',
906
+ 'snapshot-file':'TEST_DIR/tmp.IMGFMT',
907
+ 'format': 'IMGFMT'
908
+ }
909
+ }
910
Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
911
{"return": {}}
912
913
=== Performing block-commit on active layer ===
914
915
-{ 'execute': 'block-commit', 'arguments': { 'device': 'virtio0' } }
916
+{ 'execute': 'block-commit',
917
+ 'arguments': {
918
+ 'device': 'virtio0'
919
+ }
920
+ }
921
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "virtio0"}}
922
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "virtio0"}}
923
{"return": {}}
924
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "virtio0"}}
925
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
926
-{ 'execute': 'block-job-complete', 'arguments': { 'device': 'virtio0' } }
927
+{ 'execute': 'block-job-complete',
928
+ 'arguments': {
929
+ 'device': 'virtio0'
930
+ }
931
+ }
932
{"return": {}}
933
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "virtio0"}}
934
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "virtio0"}}
935
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off co
936
937
=== Performing Live Snapshot 2 ===
938
939
-{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp2.IMGFMT', 'format': 'IMGFMT' } }
940
+{ 'execute': 'blockdev-snapshot-sync',
941
+ 'arguments': {
942
+ 'device': 'virtio0',
943
+ 'snapshot-file':'TEST_DIR/tmp2.IMGFMT',
944
+ 'format': 'IMGFMT'
945
+ }
946
+ }
947
Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
948
{"return": {}}
949
*** done
950
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
951
index XXXXXXX..XXXXXXX 100644
952
--- a/tests/qemu-iotests/153.out
953
+++ b/tests/qemu-iotests/153.out
954
@@ -XXX,XX +XXX,XX @@ _qemu_img_wrapper commit -b TEST_DIR/t.qcow2.b TEST_DIR/t.qcow2.c
955
{ 'execute': 'qmp_capabilities' }
956
{"return": {}}
957
Adding drive
958
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_add 0 if=none,id=d0,file=TEST_DIR/t.IMGFMT' } }
959
+{ 'execute': 'human-monitor-command',
960
+ 'arguments': { 'command-line': 'drive_add 0 if=none,id=d0,file=TEST_DIR/t.IMGFMT' } }
961
{"return": "OKrn"}
962
963
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
964
@@ -XXX,XX +XXX,XX @@ Creating overlay with qemu-img when the guest is running should be allowed
965
966
_qemu_img_wrapper create -f qcow2 -b TEST_DIR/t.qcow2 -F qcow2 TEST_DIR/t.qcow2.overlay
967
== Closing an image should unlock it ==
968
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_del d0' } }
969
+{ 'execute': 'human-monitor-command',
970
+ 'arguments': { 'command-line': 'drive_del d0' } }
971
{"return": ""}
972
973
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
974
Adding two and closing one
975
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_add 0 if=none,id=d0,file=TEST_DIR/t.IMGFMT,readonly=on' } }
976
+{ 'execute': 'human-monitor-command',
977
+ 'arguments': { 'command-line': 'drive_add 0 if=none,id=d0,file=TEST_DIR/t.IMGFMT,readonly=on' } }
978
{"return": "OKrn"}
979
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_add 0 if=none,id=d1,file=TEST_DIR/t.IMGFMT,readonly=on' } }
980
+{ 'execute': 'human-monitor-command',
981
+ 'arguments': { 'command-line': 'drive_add 0 if=none,id=d1,file=TEST_DIR/t.IMGFMT,readonly=on' } }
982
{"return": "OKrn"}
983
984
_qemu_img_wrapper info TEST_DIR/t.qcow2
985
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_del d0' } }
986
+{ 'execute': 'human-monitor-command',
987
+ 'arguments': { 'command-line': 'drive_del d0' } }
988
{"return": ""}
989
990
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
991
qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
992
Is another process using the image [TEST_DIR/t.qcow2]?
993
Closing the other
994
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_del d1' } }
995
+{ 'execute': 'human-monitor-command',
996
+ 'arguments': { 'command-line': 'drive_del d1' } }
997
{"return": ""}
998
999
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
1000
diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out
1001
index XXXXXXX..XXXXXXX 100644
1002
--- a/tests/qemu-iotests/156.out
1003
+++ b/tests/qemu-iotests/156.out
1004
@@ -XXX,XX +XXX,XX @@ wrote 196608/196608 bytes at offset 65536
1005
{ 'execute': 'qmp_capabilities' }
1006
{"return": {}}
1007
Formatting 'TEST_DIR/t.IMGFMT.overlay', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
1008
-{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'source', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'format': 'IMGFMT', 'mode': 'existing' } }
1009
+{ 'execute': 'blockdev-snapshot-sync',
1010
+ 'arguments': { 'device': 'source',
1011
+ 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay',
1012
+ 'format': 'IMGFMT',
1013
+ 'mode': 'existing' } }
1014
{"return": {}}
1015
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "write -P 3 128k 128k"' } }
1016
+{ 'execute': 'human-monitor-command',
1017
+ 'arguments': { 'command-line':
1018
+ 'qemu-io source "write -P 3 128k 128k"' } }
1019
wrote 131072/131072 bytes at offset 131072
1020
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1021
{"return": ""}
1022
Formatting 'TEST_DIR/t.IMGFMT.target.overlay', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.target backing_fmt=IMGFMT
1023
-{ 'execute': 'drive-mirror', 'arguments': { 'device': 'source', 'target': 'TEST_DIR/t.IMGFMT.target.overlay', 'mode': 'existing', 'sync': 'top' } }
1024
+{ 'execute': 'drive-mirror',
1025
+ 'arguments': { 'device': 'source',
1026
+ 'target': 'TEST_DIR/t.IMGFMT.target.overlay',
1027
+ 'mode': 'existing',
1028
+ 'sync': 'top' } }
1029
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "source"}}
1030
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "source"}}
1031
{"return": {}}
1032
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "source"}}
1033
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "source", "len": 131072, "offset": 131072, "speed": 0, "type": "mirror"}}
1034
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "write -P 4 192k 64k"' } }
1035
+{ 'execute': 'human-monitor-command',
1036
+ 'arguments': { 'command-line':
1037
+ 'qemu-io source "write -P 4 192k 64k"' } }
1038
wrote 65536/65536 bytes at offset 196608
1039
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1040
{"return": ""}
1041
-{ 'execute': 'block-job-complete', 'arguments': { 'device': 'source' } }
1042
+{ 'execute': 'block-job-complete',
1043
+ 'arguments': { 'device': 'source' } }
1044
{"return": {}}
1045
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "source"}}
1046
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "source"}}
1047
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 196608
1048
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "source"}}
1049
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "source"}}
1050
1051
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "read -P 1 0k 64k"' } }
1052
+{ 'execute': 'human-monitor-command',
1053
+ 'arguments': { 'command-line':
1054
+ 'qemu-io source "read -P 1 0k 64k"' } }
1055
read 65536/65536 bytes at offset 0
1056
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1057
{"return": ""}
1058
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "read -P 2 64k 64k"' } }
1059
+{ 'execute': 'human-monitor-command',
1060
+ 'arguments': { 'command-line':
1061
+ 'qemu-io source "read -P 2 64k 64k"' } }
1062
read 65536/65536 bytes at offset 65536
1063
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1064
{"return": ""}
1065
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "read -P 3 128k 64k"' } }
1066
+{ 'execute': 'human-monitor-command',
1067
+ 'arguments': { 'command-line':
1068
+ 'qemu-io source "read -P 3 128k 64k"' } }
1069
read 65536/65536 bytes at offset 131072
1070
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1071
{"return": ""}
1072
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "read -P 4 192k 64k"' } }
1073
+{ 'execute': 'human-monitor-command',
1074
+ 'arguments': { 'command-line':
1075
+ 'qemu-io source "read -P 4 192k 64k"' } }
1076
read 65536/65536 bytes at offset 196608
1077
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1078
{"return": ""}
1079
diff --git a/tests/qemu-iotests/161.out b/tests/qemu-iotests/161.out
1080
index XXXXXXX..XXXXXXX 100644
1081
--- a/tests/qemu-iotests/161.out
1082
+++ b/tests/qemu-iotests/161.out
1083
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
1084
1085
{ 'execute': 'qmp_capabilities' }
1086
{"return": {}}
1087
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
1088
+{ 'execute': 'human-monitor-command',
1089
+ 'arguments': { 'command-line':
1090
+ 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
1091
{"return": ""}
1092
1093
*** Stream and then change an option on the backing file
1094
1095
{ 'execute': 'qmp_capabilities' }
1096
{"return": {}}
1097
-{ 'execute': 'block-stream', 'arguments': { 'device': 'none0', 'base': 'TEST_DIR/t.IMGFMT.base' } }
1098
+{ 'execute': 'block-stream', 'arguments': { 'device': 'none0',
1099
+ 'base': 'TEST_DIR/t.IMGFMT.base' } }
1100
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
1101
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
1102
{"return": {}}
1103
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
1104
+{ 'execute': 'human-monitor-command',
1105
+ 'arguments': { 'command-line':
1106
+ 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
1107
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
1108
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
1109
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "stream"}}
1110
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.int', fmt=IMGFMT size=1048576 backing_file=TEST_DI
1111
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.int backing_fmt=IMGFMT
1112
{ 'execute': 'qmp_capabilities' }
1113
{"return": {}}
1114
-{ 'execute': 'block-commit', 'arguments': { 'device': 'none0', 'top': 'TEST_DIR/t.IMGFMT.int' } }
1115
+{ 'execute': 'block-commit', 'arguments': { 'device': 'none0',
1116
+ 'top': 'TEST_DIR/t.IMGFMT.int' } }
1117
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
1118
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
1119
{"return": {}}
1120
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
1121
+{ 'execute': 'human-monitor-command',
1122
+ 'arguments': { 'command-line':
1123
+ 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
1124
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
1125
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
1126
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
1127
diff --git a/tests/qemu-iotests/173.out b/tests/qemu-iotests/173.out
1128
index XXXXXXX..XXXXXXX 100644
1129
--- a/tests/qemu-iotests/173.out
1130
+++ b/tests/qemu-iotests/173.out
1131
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/image.snp1', fmt=IMGFMT size=104857600
1132
1133
{ 'execute': 'qmp_capabilities' }
1134
{"return": {}}
1135
-{ 'arguments': { 'device': 'disk2', 'format': 'IMGFMT', 'mode': 'existing', 'snapshot-file': 'TEST_DIR/image.snp1', 'snapshot-node-name': 'snp1' }, 'execute': 'blockdev-snapshot-sync' }
1136
+{ 'arguments': {
1137
+ 'device': 'disk2',
1138
+ 'format': 'IMGFMT',
1139
+ 'mode': 'existing',
1140
+ 'snapshot-file': 'TEST_DIR/image.snp1',
1141
+ 'snapshot-node-name': 'snp1'
1142
+ },
1143
+ 'execute': 'blockdev-snapshot-sync'
1144
+ }
1145
{"return": {}}
1146
-{ 'arguments': { 'backing-file': 'image.base', 'device': 'disk2', 'image-node-name': 'snp1' }, 'execute': 'change-backing-file' }
1147
+{ 'arguments': {
1148
+ 'backing-file': 'image.base',
1149
+ 'device': 'disk2',
1150
+ 'image-node-name': 'snp1'
1151
+ },
1152
+ 'execute': 'change-backing-file'
1153
+ }
1154
{"return": {}}
1155
-{ 'arguments': { 'base': 'TEST_DIR/image.base', 'device': 'disk2' }, 'execute': 'block-stream' }
1156
+{ 'arguments': {
1157
+ 'base': 'TEST_DIR/image.base',
1158
+ 'device': 'disk2'
1159
+ },
1160
+ 'execute': 'block-stream'
1161
+ }
1162
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk2"}}
1163
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk2"}}
1164
{"return": {}}
1165
diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out
1166
index XXXXXXX..XXXXXXX 100644
1167
--- a/tests/qemu-iotests/182.out
1168
+++ b/tests/qemu-iotests/182.out
1169
@@ -XXX,XX +XXX,XX @@ Is another process using the image [TEST_DIR/t.qcow2]?
1170
1171
{'execute': 'qmp_capabilities'}
1172
{"return": {}}
1173
-{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node0', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
1174
-{"return": {}}
1175
-{'execute': 'blockdev-snapshot-sync', 'arguments': { 'node-name': 'node0', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'snapshot-node-name': 'node1' } }
1176
+{'execute': 'blockdev-add',
1177
+ 'arguments': {
1178
+ 'node-name': 'node0',
1179
+ 'driver': 'file',
1180
+ 'filename': 'TEST_DIR/t.IMGFMT',
1181
+ 'locking': 'on'
1182
+ } }
1183
+{"return": {}}
1184
+{'execute': 'blockdev-snapshot-sync',
1185
+ 'arguments': {
1186
+ 'node-name': 'node0',
1187
+ 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay',
1188
+ 'snapshot-node-name': 'node1'
1189
+ } }
1190
Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file lazy_refcounts=off refcount_bits=16
1191
{"return": {}}
1192
-{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node1', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
1193
-{"return": {}}
1194
-{'execute': 'nbd-server-start', 'arguments': { 'addr': { 'type': 'unix', 'data': { 'path': 'SOCK_DIR/nbd.socket' } } } }
1195
-{"return": {}}
1196
-{'execute': 'nbd-server-add', 'arguments': { 'device': 'node1' } }
1197
+{'execute': 'blockdev-add',
1198
+ 'arguments': {
1199
+ 'node-name': 'node1',
1200
+ 'driver': 'file',
1201
+ 'filename': 'TEST_DIR/t.IMGFMT',
1202
+ 'locking': 'on'
1203
+ } }
1204
+{"return": {}}
1205
+{'execute': 'nbd-server-start',
1206
+ 'arguments': {
1207
+ 'addr': {
1208
+ 'type': 'unix',
1209
+ 'data': {
1210
+ 'path': 'SOCK_DIR/nbd.socket'
1211
+ } } } }
1212
+{"return": {}}
1213
+{'execute': 'nbd-server-add',
1214
+ 'arguments': {
1215
+ 'device': 'node1'
1216
+ } }
1217
{"return": {}}
1218
1219
=== Testing failure to loosen restrictions ===
1220
diff --git a/tests/qemu-iotests/183.out b/tests/qemu-iotests/183.out
1221
index XXXXXXX..XXXXXXX 100644
1222
--- a/tests/qemu-iotests/183.out
1223
+++ b/tests/qemu-iotests/183.out
1224
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.dest', fmt=IMGFMT size=67108864
1225
1226
=== Write something on the source ===
1227
1228
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write -P 0x55 0 64k"' } }
1229
+{ 'execute': 'human-monitor-command',
1230
+ 'arguments': { 'command-line':
1231
+ 'qemu-io disk "write -P 0x55 0 64k"' } }
1232
wrote 65536/65536 bytes at offset 0
1233
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1234
{"return": ""}
1235
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "read -P 0x55 0 64k"' } }
1236
+{ 'execute': 'human-monitor-command',
1237
+ 'arguments': { 'command-line':
1238
+ 'qemu-io disk "read -P 0x55 0 64k"' } }
1239
read 65536/65536 bytes at offset 0
1240
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1241
{"return": ""}
1242
1243
=== Do block migration to destination ===
1244
1245
-{ 'execute': 'migrate', 'arguments': { 'uri': 'unix:SOCK_DIR/migrate', 'blk': true } }
1246
+{ 'execute': 'migrate',
1247
+ 'arguments': { 'uri': 'unix:SOCK_DIR/migrate', 'blk': true } }
1248
{"return": {}}
1249
{ 'execute': 'query-status' }
1250
{"return": {"status": "postmigrate", "singlestep": false, "running": false}}
1251
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
1252
{ 'execute': 'query-status' }
1253
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESUME"}
1254
{"return": {"status": "running", "singlestep": false, "running": true}}
1255
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "read -P 0x55 0 64k"' } }
1256
+{ 'execute': 'human-monitor-command',
1257
+ 'arguments': { 'command-line':
1258
+ 'qemu-io disk "read -P 0x55 0 64k"' } }
1259
read 65536/65536 bytes at offset 0
1260
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1261
{"return": ""}
1262
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write -P 0x66 1M 64k"' } }
1263
+{ 'execute': 'human-monitor-command',
1264
+ 'arguments': { 'command-line':
1265
+ 'qemu-io disk "write -P 0x66 1M 64k"' } }
1266
wrote 65536/65536 bytes at offset 1048576
1267
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1268
{"return": ""}
1269
diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out
1270
index XXXXXXX..XXXXXXX 100644
1271
--- a/tests/qemu-iotests/185.out
1272
+++ b/tests/qemu-iotests/185.out
1273
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
1274
1275
=== Creating backing chain ===
1276
1277
-{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT.mid', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
1278
+{ 'execute': 'blockdev-snapshot-sync',
1279
+ 'arguments': { 'device': 'disk',
1280
+ 'snapshot-file': 'TEST_DIR/t.IMGFMT.mid',
1281
+ 'format': 'IMGFMT',
1282
+ 'mode': 'absolute-paths' } }
1283
Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1284
{"return": {}}
1285
-{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write 0 4M"' } }
1286
+{ 'execute': 'human-monitor-command',
1287
+ 'arguments': { 'command-line':
1288
+ 'qemu-io disk "write 0 4M"' } }
1289
wrote 4194304/4194304 bytes at offset 0
1290
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1291
{"return": ""}
1292
-{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
1293
+{ 'execute': 'blockdev-snapshot-sync',
1294
+ 'arguments': { 'device': 'disk',
1295
+ 'snapshot-file': 'TEST_DIR/t.IMGFMT',
1296
+ 'format': 'IMGFMT',
1297
+ 'mode': 'absolute-paths' } }
1298
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1299
{"return": {}}
1300
1301
=== Start commit job and exit qemu ===
1302
1303
-{ 'execute': 'block-commit', 'arguments': { 'device': 'disk', 'base':'TEST_DIR/t.IMGFMT.base', 'top': 'TEST_DIR/t.IMGFMT.mid', 'speed': 65536 } }
1304
+{ 'execute': 'block-commit',
1305
+ 'arguments': { 'device': 'disk',
1306
+ 'base':'TEST_DIR/t.IMGFMT.base',
1307
+ 'top': 'TEST_DIR/t.IMGFMT.mid',
1308
+ 'speed': 65536 } }
1309
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
1310
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
1311
{"return": {}}
1312
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off comp
1313
1314
{ 'execute': 'qmp_capabilities' }
1315
{"return": {}}
1316
-{ 'execute': 'block-commit', 'arguments': { 'device': 'disk', 'base':'TEST_DIR/t.IMGFMT.base', 'speed': 65536 } }
1317
+{ 'execute': 'block-commit',
1318
+ 'arguments': { 'device': 'disk',
1319
+ 'base':'TEST_DIR/t.IMGFMT.base',
1320
+ 'speed': 65536 } }
1321
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
1322
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
1323
{"return": {}}
1324
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off comp
1325
1326
{ 'execute': 'qmp_capabilities' }
1327
{"return": {}}
1328
-{ 'execute': 'drive-mirror', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
1329
+{ 'execute': 'drive-mirror',
1330
+ 'arguments': { 'device': 'disk',
1331
+ 'target': 'TEST_DIR/t.IMGFMT.copy',
1332
+ 'format': 'IMGFMT',
1333
+ 'sync': 'full',
1334
+ 'speed': 65536 } }
1335
Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
1336
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
1337
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
1338
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off
1339
1340
{ 'execute': 'qmp_capabilities' }
1341
{"return": {}}
1342
-{ 'execute': 'drive-backup', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
1343
+{ 'execute': 'drive-backup',
1344
+ 'arguments': { 'device': 'disk',
1345
+ 'target': 'TEST_DIR/t.IMGFMT.copy',
1346
+ 'format': 'IMGFMT',
1347
+ 'sync': 'full',
1348
+ 'speed': 65536 } }
1349
Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
1350
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
1351
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
1352
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off
1353
1354
{ 'execute': 'qmp_capabilities' }
1355
{"return": {}}
1356
-{ 'execute': 'block-stream', 'arguments': { 'device': 'disk', 'speed': 65536 } }
1357
+{ 'execute': 'block-stream',
1358
+ 'arguments': { 'device': 'disk',
1359
+ 'speed': 65536 } }
1360
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
1361
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
1362
{"return": {}}
1363
diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
1364
index XXXXXXX..XXXXXXX 100644
1365
--- a/tests/qemu-iotests/191.out
1366
+++ b/tests/qemu-iotests/191.out
1367
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 1048576
1368
1369
=== Perform commit job ===
1370
1371
-{ 'execute': 'block-commit', 'arguments': { 'job-id': 'commit0', 'device': 'top', 'base':'TEST_DIR/t.IMGFMT.base', 'top': 'TEST_DIR/t.IMGFMT.mid' } }
1372
+{ 'execute': 'block-commit',
1373
+ 'arguments': { 'job-id': 'commit0',
1374
+ 'device': 'top',
1375
+ 'base':'TEST_DIR/t.IMGFMT.base',
1376
+ 'top': 'TEST_DIR/t.IMGFMT.mid' } }
1377
{
1378
"timestamp": {
1379
"seconds": TIMESTAMP,
1380
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 1048576
1381
1382
=== Perform commit job ===
1383
1384
-{ 'execute': 'block-commit', 'arguments': { 'job-id': 'commit0', 'device': 'top', 'base':'TEST_DIR/t.IMGFMT.base', 'top': 'TEST_DIR/t.IMGFMT.mid' } }
1385
+{ 'execute': 'block-commit',
1386
+ 'arguments': { 'job-id': 'commit0',
1387
+ 'device': 'top',
1388
+ 'base':'TEST_DIR/t.IMGFMT.base',
1389
+ 'top': 'TEST_DIR/t.IMGFMT.mid' } }
1390
{
1391
"timestamp": {
1392
"seconds": TIMESTAMP,
1393
diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out
1394
index XXXXXXX..XXXXXXX 100644
1395
--- a/tests/qemu-iotests/223.out
1396
+++ b/tests/qemu-iotests/223.out
1397
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 2097152
1398
1399
{"execute":"qmp_capabilities"}
1400
{"return": {}}
1401
-{"execute":"blockdev-add", "arguments":{"driver":"IMGFMT", "node-name":"n", "file":{"driver":"file", "filename":"TEST_DIR/t.IMGFMT"}}}
1402
+{"execute":"blockdev-add",
1403
+ "arguments":{"driver":"IMGFMT", "node-name":"n",
1404
+ "file":{"driver":"file", "filename":"TEST_DIR/t.IMGFMT"}}}
1405
{"return": {}}
1406
-{"execute":"block-dirty-bitmap-disable", "arguments":{"node":"n", "name":"b"}}
1407
+{"execute":"block-dirty-bitmap-disable",
1408
+ "arguments":{"node":"n", "name":"b"}}
1409
{"return": {}}
1410
1411
=== Set up NBD with normal access ===
1412
1413
-{"execute":"nbd-server-add", "arguments":{"device":"n"}}
1414
+{"execute":"nbd-server-add",
1415
+ "arguments":{"device":"n"}}
1416
{"error": {"class": "GenericError", "desc": "NBD server not running"}}
1417
-{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"SOCK_DIR/nbd"}}}}
1418
+{"execute":"nbd-server-start",
1419
+ "arguments":{"addr":{"type":"unix",
1420
+ "data":{"path":"SOCK_DIR/nbd"}}}}
1421
{"return": {}}
1422
-{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"SOCK_DIR/nbd1"}}}}
1423
+{"execute":"nbd-server-start",
1424
+ "arguments":{"addr":{"type":"unix",
1425
+ "data":{"path":"SOCK_DIR/nbd1"}}}}
1426
{"error": {"class": "GenericError", "desc": "NBD server already running"}}
1427
exports available: 0
1428
-{"execute":"nbd-server-add", "arguments":{"device":"n", "bitmap":"b"}}
1429
+{"execute":"nbd-server-add",
1430
+ "arguments":{"device":"n", "bitmap":"b"}}
1431
{"return": {}}
1432
-{"execute":"nbd-server-add", "arguments":{"device":"nosuch"}}
1433
+{"execute":"nbd-server-add",
1434
+ "arguments":{"device":"nosuch"}}
1435
{"error": {"class": "GenericError", "desc": "Cannot find device=nosuch nor node_name=nosuch"}}
1436
-{"execute":"nbd-server-add", "arguments":{"device":"n"}}
1437
+{"execute":"nbd-server-add",
1438
+ "arguments":{"device":"n"}}
1439
{"error": {"class": "GenericError", "desc": "Block export id 'n' is already in use"}}
1440
-{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "bitmap":"b2"}}
1441
+{"execute":"nbd-server-add",
1442
+ "arguments":{"device":"n", "name":"n2",
1443
+ "bitmap":"b2"}}
1444
{"error": {"class": "GenericError", "desc": "Enabled bitmap 'b2' incompatible with readonly export"}}
1445
-{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "bitmap":"b3"}}
1446
+{"execute":"nbd-server-add",
1447
+ "arguments":{"device":"n", "name":"n2",
1448
+ "bitmap":"b3"}}
1449
{"error": {"class": "GenericError", "desc": "Bitmap 'b3' is not found"}}
1450
-{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "writable":true, "description":"some text", "bitmap":"b2"}}
1451
+{"execute":"nbd-server-add",
1452
+ "arguments":{"device":"n", "name":"n2", "writable":true,
1453
+ "description":"some text", "bitmap":"b2"}}
1454
{"return": {}}
1455
exports available: 2
1456
export: 'n'
1457
@@ -XXX,XX +XXX,XX @@ read 2097152/2097152 bytes at offset 2097152
1458
1459
=== End qemu NBD server ===
1460
1461
-{"execute":"nbd-server-remove", "arguments":{"name":"n"}}
1462
+{"execute":"nbd-server-remove",
1463
+ "arguments":{"name":"n"}}
1464
{"return": {}}
1465
-{"execute":"nbd-server-remove", "arguments":{"name":"n2"}}
1466
+{"execute":"nbd-server-remove",
1467
+ "arguments":{"name":"n2"}}
1468
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n"}}
1469
{"return": {}}
1470
-{"execute":"nbd-server-remove", "arguments":{"name":"n2"}}
1471
+{"execute":"nbd-server-remove",
1472
+ "arguments":{"name":"n2"}}
1473
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n2"}}
1474
{"error": {"class": "GenericError", "desc": "Export 'n2' is not found"}}
1475
{"execute":"nbd-server-stop"}
1476
@@ -XXX,XX +XXX,XX @@ read 2097152/2097152 bytes at offset 2097152
1477
1478
=== Set up NBD with iothread access ===
1479
1480
-{"execute":"x-blockdev-set-iothread", "arguments":{"node-name":"n", "iothread":"io0"}}
1481
+{"execute":"x-blockdev-set-iothread",
1482
+ "arguments":{"node-name":"n", "iothread":"io0"}}
1483
{"return": {}}
1484
-{"execute":"nbd-server-add", "arguments":{"device":"n"}}
1485
+{"execute":"nbd-server-add",
1486
+ "arguments":{"device":"n"}}
1487
{"error": {"class": "GenericError", "desc": "NBD server not running"}}
1488
-{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"SOCK_DIR/nbd"}}}}
1489
+{"execute":"nbd-server-start",
1490
+ "arguments":{"addr":{"type":"unix",
1491
+ "data":{"path":"SOCK_DIR/nbd"}}}}
1492
{"return": {}}
1493
-{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"SOCK_DIR/nbd1"}}}}
1494
+{"execute":"nbd-server-start",
1495
+ "arguments":{"addr":{"type":"unix",
1496
+ "data":{"path":"SOCK_DIR/nbd1"}}}}
1497
{"error": {"class": "GenericError", "desc": "NBD server already running"}}
1498
exports available: 0
1499
-{"execute":"nbd-server-add", "arguments":{"device":"n", "bitmap":"b"}}
1500
+{"execute":"nbd-server-add",
1501
+ "arguments":{"device":"n", "bitmap":"b"}}
1502
{"return": {}}
1503
-{"execute":"nbd-server-add", "arguments":{"device":"nosuch"}}
1504
+{"execute":"nbd-server-add",
1505
+ "arguments":{"device":"nosuch"}}
1506
{"error": {"class": "GenericError", "desc": "Cannot find device=nosuch nor node_name=nosuch"}}
1507
-{"execute":"nbd-server-add", "arguments":{"device":"n"}}
1508
+{"execute":"nbd-server-add",
1509
+ "arguments":{"device":"n"}}
1510
{"error": {"class": "GenericError", "desc": "Block export id 'n' is already in use"}}
1511
-{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "bitmap":"b2"}}
1512
+{"execute":"nbd-server-add",
1513
+ "arguments":{"device":"n", "name":"n2",
1514
+ "bitmap":"b2"}}
1515
{"error": {"class": "GenericError", "desc": "Enabled bitmap 'b2' incompatible with readonly export"}}
1516
-{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "bitmap":"b3"}}
1517
+{"execute":"nbd-server-add",
1518
+ "arguments":{"device":"n", "name":"n2",
1519
+ "bitmap":"b3"}}
1520
{"error": {"class": "GenericError", "desc": "Bitmap 'b3' is not found"}}
1521
-{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "writable":true, "description":"some text", "bitmap":"b2"}}
1522
+{"execute":"nbd-server-add",
1523
+ "arguments":{"device":"n", "name":"n2", "writable":true,
1524
+ "description":"some text", "bitmap":"b2"}}
1525
{"return": {}}
1526
exports available: 2
1527
export: 'n'
1528
@@ -XXX,XX +XXX,XX @@ read 2097152/2097152 bytes at offset 2097152
1529
1530
=== End qemu NBD server ===
1531
1532
-{"execute":"nbd-server-remove", "arguments":{"name":"n"}}
1533
+{"execute":"nbd-server-remove",
1534
+ "arguments":{"name":"n"}}
1535
{"return": {}}
1536
-{"execute":"nbd-server-remove", "arguments":{"name":"n2"}}
1537
+{"execute":"nbd-server-remove",
1538
+ "arguments":{"name":"n2"}}
1539
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n"}}
1540
{"return": {}}
1541
-{"execute":"nbd-server-remove", "arguments":{"name":"n2"}}
1542
+{"execute":"nbd-server-remove",
1543
+ "arguments":{"name":"n2"}}
1544
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n2"}}
1545
{"error": {"class": "GenericError", "desc": "Export 'n2' is not found"}}
1546
{"execute":"nbd-server-stop"}
1547
diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
1548
index XXXXXXX..XXXXXXX 100644
1549
--- a/tests/qemu-iotests/229.out
1550
+++ b/tests/qemu-iotests/229.out
1551
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 0
1552
1553
=== Starting drive-mirror, causing error & stop ===
1554
1555
-{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', 'format': 'IMGFMT', 'target': 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT.dest', 'sync': 'full', 'mode': 'existing', 'on-source-error': 'stop', 'on-target-error': 'stop' }}
1556
+{'execute': 'drive-mirror',
1557
+ 'arguments': {'device': 'testdisk',
1558
+ 'format': 'IMGFMT',
1559
+ 'target': 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT.dest',
1560
+ 'sync': 'full',
1561
+ 'mode': 'existing',
1562
+ 'on-source-error': 'stop',
1563
+ 'on-target-error': 'stop' }}
1564
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
1565
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
1566
{"return": {}}
1567
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 0
1568
1569
=== Force cancel job paused in error state ===
1570
1571
-{'execute': 'block-job-cancel', 'arguments': { 'device': 'testdisk', 'force': true}}
1572
+{'execute': 'block-job-cancel',
1573
+ 'arguments': { 'device': 'testdisk',
1574
+ 'force': true}}
1575
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
1576
{"return": {}}
1577
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
1578
diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
1579
index XXXXXXX..XXXXXXX 100644
1580
--- a/tests/qemu-iotests/249.out
1581
+++ b/tests/qemu-iotests/249.out
1582
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
1583
1584
=== Send a write command to a drive opened in read-only mode (1)
1585
1586
-{ 'execute': 'human-monitor-command', 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
1587
+{ 'execute': 'human-monitor-command',
1588
+ 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
1589
{"return": "Block node is read-onlyrn"}
1590
1591
=== Run block-commit on base using an invalid filter node name
1592
1593
-{ 'execute': 'block-commit', 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int', 'filter-node-name': '1234'}}
1594
+{ 'execute': 'block-commit',
1595
+ 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int',
1596
+ 'filter-node-name': '1234'}}
1597
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
1598
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
1599
{"error": {"class": "GenericError", "desc": "Invalid node name"}}
1600
1601
=== Send a write command to a drive opened in read-only mode (2)
1602
1603
-{ 'execute': 'human-monitor-command', 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
1604
+{ 'execute': 'human-monitor-command',
1605
+ 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
1606
{"return": "Block node is read-onlyrn"}
1607
1608
=== Run block-commit on base using the default filter node name
1609
1610
-{ 'execute': 'block-commit', 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}}
1611
+{ 'execute': 'block-commit',
1612
+ 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}}
1613
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
1614
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
1615
{"return": {}}
1616
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
1617
1618
=== Send a write command to a drive opened in read-only mode (3)
1619
1620
-{ 'execute': 'human-monitor-command', 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
1621
+{ 'execute': 'human-monitor-command',
1622
+ 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
1623
{"return": "Block node is read-onlyrn"}
1624
*** done
1625
diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out
1626
index XXXXXXX..XXXXXXX 100644
1627
--- a/tests/qemu-iotests/308.out
1628
+++ b/tests/qemu-iotests/308.out
1629
@@ -XXX,XX +XXX,XX @@ wrote 67108864/67108864 bytes at offset 0
1630
64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1631
{'execute': 'qmp_capabilities'}
1632
{"return": {}}
1633
-{'execute': 'blockdev-add', 'arguments': { 'driver': 'file', 'node-name': 'node-protocol', 'filename': 'TEST_DIR/t.IMGFMT' } }
1634
+{'execute': 'blockdev-add',
1635
+ 'arguments': {
1636
+ 'driver': 'file',
1637
+ 'node-name': 'node-protocol',
1638
+ 'filename': 'TEST_DIR/t.IMGFMT'
1639
+ } }
1640
{"return": {}}
1641
-{'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'node-format', 'file': 'node-protocol' } }
1642
+{'execute': 'blockdev-add',
1643
+ 'arguments': {
1644
+ 'driver': 'IMGFMT',
1645
+ 'node-name': 'node-format',
1646
+ 'file': 'node-protocol'
1647
+ } }
1648
{"return": {}}
1649
1650
=== Mountpoint not present ===
1651
-{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } }
1652
+{'execute': 'block-export-add',
1653
+ 'arguments': {
1654
+ 'type': 'fuse',
1655
+ 'id': 'export-err',
1656
+ 'node-name': 'node-format',
1657
+ 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse'
1658
+ } }
1659
{"error": {"class": "GenericError", "desc": "Failed to stat 'TEST_DIR/t.IMGFMT.fuse': No such file or directory"}}
1660
1661
=== Mountpoint is a directory ===
1662
-{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } }
1663
+{'execute': 'block-export-add',
1664
+ 'arguments': {
1665
+ 'type': 'fuse',
1666
+ 'id': 'export-err',
1667
+ 'node-name': 'node-format',
1668
+ 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse'
1669
+ } }
1670
{"error": {"class": "GenericError", "desc": "'TEST_DIR/t.IMGFMT.fuse' is not a regular file"}}
1671
1672
=== Mountpoint is a regular file ===
1673
-{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } }
1674
+{'execute': 'block-export-add',
1675
+ 'arguments': {
1676
+ 'type': 'fuse',
1677
+ 'id': 'export-mp',
1678
+ 'node-name': 'node-format',
1679
+ 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse'
1680
+ } }
1681
{"return": {}}
1682
Images are identical.
1683
1684
=== Mount over existing file ===
1685
-{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-img', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT' } }
1686
+{'execute': 'block-export-add',
1687
+ 'arguments': {
1688
+ 'type': 'fuse',
1689
+ 'id': 'export-img',
1690
+ 'node-name': 'node-format',
1691
+ 'mountpoint': 'TEST_DIR/t.IMGFMT'
1692
+ } }
1693
{"return": {}}
1694
Images are identical.
1695
1696
=== Double export ===
1697
-{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } }
1698
+{'execute': 'block-export-add',
1699
+ 'arguments': {
1700
+ 'type': 'fuse',
1701
+ 'id': 'export-err',
1702
+ 'node-name': 'node-format',
1703
+ 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse'
1704
+ } }
1705
{"error": {"class": "GenericError", "desc": "There already is a FUSE export on 'TEST_DIR/t.IMGFMT.fuse'"}}
1706
1707
=== Remove export ===
1708
virtual size: 64 MiB (67108864 bytes)
1709
-{'execute': 'block-export-del', 'arguments': { 'id': 'export-mp' } }
1710
+{'execute': 'block-export-del',
1711
+ 'arguments': {
1712
+ 'id': 'export-mp'
1713
+ } }
1714
{"return": {}}
1715
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}}
1716
virtual size: 0 B (0 bytes)
1717
1718
=== Writable export ===
1719
-{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true } }
1720
+{'execute': 'block-export-add',
1721
+ 'arguments': {
1722
+ 'type': 'fuse',
1723
+ 'id': 'export-mp',
1724
+ 'node-name': 'node-format',
1725
+ 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true
1726
+ } }
1727
{"return": {}}
1728
write failed: Permission denied
1729
wrote 65536/65536 bytes at offset 1048576
1730
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 1048576
1731
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1732
1733
=== Resizing exports ===
1734
-{'execute': 'block-export-del', 'arguments': { 'id': 'export-mp' } }
1735
+{'execute': 'block-export-del',
1736
+ 'arguments': {
1737
+ 'id': 'export-mp'
1738
+ } }
1739
{"return": {}}
1740
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}}
1741
-{'execute': 'block-export-del', 'arguments': { 'id': 'export-img' } }
1742
+{'execute': 'block-export-del',
1743
+ 'arguments': {
1744
+ 'id': 'export-img'
1745
+ } }
1746
{"return": {}}
1747
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-img"}}
1748
-{'execute': 'blockdev-del', 'arguments': { 'node-name': 'node-format' } }
1749
+{'execute': 'blockdev-del',
1750
+ 'arguments': {
1751
+ 'node-name': 'node-format'
1752
+ } }
1753
{"return": {}}
1754
-{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-protocol', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true } }
1755
+{'execute': 'block-export-add',
1756
+ 'arguments': {
1757
+ 'type': 'fuse',
1758
+ 'id': 'export-mp',
1759
+ 'node-name': 'node-protocol',
1760
+ 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true
1761
+ } }
1762
{"return": {}}
1763
1764
--- Try growing non-growable export ---
1765
@@ -XXX,XX +XXX,XX @@ OK: Post-truncate image size is as expected
1766
OK: Disk usage grew with fallocate
1767
1768
--- Try growing growable export ---
1769
-{'execute': 'block-export-del', 'arguments': { 'id': 'export-mp' } }
1770
+{'execute': 'block-export-del',
1771
+ 'arguments': {
1772
+ 'id': 'export-mp'
1773
+ } }
1774
{"return": {}}
1775
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}}
1776
-{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-protocol', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true, 'growable': true } }
1777
+{'execute': 'block-export-add',
1778
+ 'arguments': {
1779
+ 'type': 'fuse',
1780
+ 'id': 'export-mp',
1781
+ 'node-name': 'node-protocol',
1782
+ 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true, 'growable': true
1783
+ } }
1784
{"return": {}}
1785
65536+0 records in
1786
65536+0 records out
1787
diff --git a/tests/qemu-iotests/312.out b/tests/qemu-iotests/312.out
1788
index XXXXXXX..XXXXXXX 100644
1789
--- a/tests/qemu-iotests/312.out
1790
+++ b/tests/qemu-iotests/312.out
1791
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 2424832
1792
1793
{ 'execute': 'qmp_capabilities' }
1794
{"return": {}}
1795
-{'execute': 'drive-mirror', 'arguments': {'device': 'virtio0', 'format': 'IMGFMT', 'target': 'TEST_DIR/t.IMGFMT.3', 'sync': 'full', 'mode': 'existing' }}
1796
+{'execute': 'drive-mirror',
1797
+ 'arguments': {'device': 'virtio0',
1798
+ 'format': 'IMGFMT',
1799
+ 'target': 'TEST_DIR/t.IMGFMT.3',
1800
+ 'sync': 'full',
1801
+ 'mode': 'existing' }}
1802
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "virtio0"}}
1803
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "virtio0"}}
1804
{"return": {}}
1805
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "virtio0"}}
1806
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 10485760, "offset": 10485760, "speed": 0, "type": "mirror"}}
1807
-{ 'execute': 'block-job-complete', 'arguments': { 'device': 'virtio0' } }
1808
+{ 'execute': 'block-job-complete',
1809
+ 'arguments': { 'device': 'virtio0' } }
1810
{"return": {}}
1811
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "virtio0"}}
1812
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "virtio0"}}
1813
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
1814
index XXXXXXX..XXXXXXX 100644
1815
--- a/tests/qemu-iotests/common.qemu
1816
+++ b/tests/qemu-iotests/common.qemu
1817
@@ -XXX,XX +XXX,XX @@ _send_qemu_cmd()
1818
count=${qemu_cmd_repeat}
1819
use_error="no"
1820
fi
1821
- # This array element extraction is done to accommodate pathnames with spaces
1822
- if [ -z "${success_or_failure}" ]; then
1823
- cmd=${@: 1:${#@}-1}
1824
- shift $(($# - 1))
1825
- else
1826
- cmd=${@: 1:${#@}-2}
1827
- shift $(($# - 2))
1828
- fi
1829
+
1830
+ cmd=$1
1831
+ shift
1832
1833
# Display QMP being sent, but not HMP (since HMP already echoes its
1834
# input back to output); decide based on leading '{'
303
--
1835
--
304
2.21.0
1836
2.29.2
305
1837
306
1838
diff view generated by jsdifflib