1
The following changes since commit 23919ddfd56135cad3cb468a8f54d5a595f024f4:
1
The following changes since commit eb6490f544388dd24c0d054a96dd304bc7284450:
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/pmaydell/tags/pull-target-arm-20200703' into staging (2020-07-04 16:08:41 +0100)
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-07-06
8
8
9
for you to fetch changes up to bb043c056cffcc2f3ce88bfdaf2e76e455c09e2c:
9
for you to fetch changes up to 365fed5111b06d31c1632af63c7528dfe49d62a2:
10
10
11
iotests: Unify cache mode quoting (2019-08-27 19:48:44 +0200)
11
qed: Simplify backing reads (2020-07-06 10:34:14 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Block patches for 5.1:
15
- qemu-io now accepts a file to read a write pattern from
15
- LUKS keyslot amendment
16
- Ensure that raw files have their first block allocated so we can probe
16
(+ patches to make the iotests pass on non-Linux systems, and to keep
17
the O_DIRECT alignment if necessary
17
the tests passing for qcow v1, and to skip LUKS tests (including
18
- Various fixes
18
qcow2 LUKS) when the built qemu does not support it)
19
- Refactoring in the block layer: Drop the basically unnecessary
20
unallocated_blocks_are_zero field from BlockDriverInfo
21
- Fix qcow2 preallocation when the image size is not a multiple of the
22
cluster size
23
- Fix in block-copy code
19
24
20
----------------------------------------------------------------
25
----------------------------------------------------------------
21
Denis Plotnikov (1):
26
Alberto Garcia (1):
22
qemu-io: add pattern file for write command
27
qcow2: Fix preallocation on images with unaligned sizes
23
28
24
Max Reitz (7):
29
Eric Blake (1):
25
iotests: Fix _filter_img_create()
30
qed: Simplify backing reads
26
vmdk: Use bdrv_dirname() for relative extent paths
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
31
33
Nir Soffer (3):
32
Max Reitz (5):
34
block: posix: Always allocate the first block
33
iotests: Make _filter_img_create more active
35
iotests: Test allocate_first_block() with O_DIRECT
34
iotests/common.rc: Add _require_working_luks
36
iotests: Unify cache mode quoting
35
iotests.py: Add qemu_img_pipe_and_status()
36
iotests.py: Add (verify|has)_working_luks()
37
iotests: Check whether luks works
37
38
38
Stefan Hajnoczi (1):
39
Maxim Levitsky (14):
39
file-posix: fix request_alignment typo
40
iotests: filter few more luks specific create options
41
qcrypto/core: add generic infrastructure for crypto options amendment
42
qcrypto/luks: implement encryption key management
43
block/amend: add 'force' option
44
block/amend: separate amend and create options for qemu-img
45
block/amend: refactor qcow2 amend options
46
block/crypto: rename two functions
47
block/crypto: implement the encryption key management
48
block/qcow2: extend qemu-img amend interface with crypto options
49
iotests: qemu-img tests for luks key management
50
block/core: add generic infrastructure for x-blockdev-amend qmp
51
command
52
block/crypto: implement blockdev-amend
53
block/qcow2: implement blockdev-amend
54
iotests: add tests for blockdev-amend
40
55
41
Thomas Huth (2):
56
Vladimir Sementsov-Ogievskiy (10):
42
iotests: Check for enabled drivers before testing them
57
block/block-copy: block_copy_dirty_clusters: fix failure check
43
tests/check-block: Skip iotests when sanitizers are enabled
58
qemu-img: convert: don't use unallocated_blocks_are_zero
59
block: inline bdrv_unallocated_blocks_are_zero()
60
block/vdi: return ZERO block-status when appropriate
61
block/vpc: return ZERO block-status when appropriate
62
block/crypto: drop unallocated_blocks_are_zero
63
block/iscsi: drop unallocated_blocks_are_zero
64
block/file-posix: drop unallocated_blocks_are_zero
65
block/vhdx: drop unallocated_blocks_are_zero
66
block: drop unallocated_blocks_are_zero
44
67
45
Vladimir Sementsov-Ogievskiy (1):
68
docs/tools/qemu-img.rst | 5 +-
46
block: fix permission update in bdrv_replace_node
69
qapi/block-core.json | 68 +++++
47
70
qapi/crypto.json | 73 +++++-
48
block.c | 5 +-
71
qapi/job.json | 4 +-
49
block/file-posix.c | 53 +++++++++-
72
block/crypto.h | 37 +++
50
block/vmdk.c | 64 ++++++++----
73
block/qed.h | 1 -
51
qemu-io-cmds.c | 99 +++++++++++++++++--
74
crypto/blockpriv.h | 8 +
52
tests/check-block.sh | 5 +
75
include/block/block.h | 7 +-
53
tests/qemu-iotests/002 | 1 +
76
include/block/block_int.h | 36 ++-
54
tests/qemu-iotests/003 | 1 +
77
include/crypto/block.h | 22 ++
55
tests/qemu-iotests/005 | 3 +-
78
block.c | 19 +-
56
tests/qemu-iotests/009 | 1 +
79
block/amend.c | 113 +++++++++
57
tests/qemu-iotests/010 | 1 +
80
block/block-copy.c | 4 +-
58
tests/qemu-iotests/011 | 1 +
81
block/crypto.c | 207 +++++++++++++--
59
tests/qemu-iotests/017 | 3 +-
82
block/file-posix.c | 3 -
60
tests/qemu-iotests/018 | 3 +-
83
block/io.c | 8 +-
61
tests/qemu-iotests/019 | 3 +-
84
block/iscsi.c | 1 -
62
tests/qemu-iotests/020 | 3 +-
85
block/qcow2.c | 350 +++++++++++++++-----------
63
tests/qemu-iotests/026 | 4 +-
86
block/qed.c | 65 +----
64
tests/qemu-iotests/027 | 1 +
87
block/vdi.c | 3 +-
65
tests/qemu-iotests/032 | 1 +
88
block/vhdx.c | 3 -
66
tests/qemu-iotests/033 | 1 +
89
block/vpc.c | 3 +-
67
tests/qemu-iotests/034 | 3 +-
90
crypto/block-luks.c | 416 ++++++++++++++++++++++++++++++-
68
tests/qemu-iotests/037 | 3 +-
91
crypto/block.c | 29 +++
69
tests/qemu-iotests/039 | 4 +-
92
qemu-img.c | 48 ++--
70
tests/qemu-iotests/052 | 2 +-
93
block/Makefile.objs | 2 +-
71
tests/qemu-iotests/059 | 34 ++++++-
94
qemu-img-cmds.hx | 4 +-
72
tests/qemu-iotests/059.out | 26 +++--
95
tests/qemu-iotests/049.out | 102 ++++----
73
tests/qemu-iotests/063 | 3 +-
96
tests/qemu-iotests/061.out | 12 +-
74
tests/qemu-iotests/071 | 1 +
97
tests/qemu-iotests/082.out | 185 ++++----------
75
tests/qemu-iotests/072 | 1 +
98
tests/qemu-iotests/085.out | 38 +--
76
tests/qemu-iotests/081 | 4 +-
99
tests/qemu-iotests/087 | 1 +
77
tests/qemu-iotests/091 | 4 +-
100
tests/qemu-iotests/087.out | 6 +-
78
tests/qemu-iotests/099 | 1 +
101
tests/qemu-iotests/112.out | 2 +-
79
tests/qemu-iotests/105 | 3 +-
102
tests/qemu-iotests/125 | 24 ++
80
tests/qemu-iotests/110 | 3 +-
103
tests/qemu-iotests/125.out | 9 +
81
tests/qemu-iotests/120 | 1 +
104
tests/qemu-iotests/134.out | 2 +-
82
tests/qemu-iotests/126 | 2 +
105
tests/qemu-iotests/141 | 2 +-
83
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
106
tests/qemu-iotests/144.out | 4 +-
84
tests/qemu-iotests/150.out.raw | 12 +++
107
tests/qemu-iotests/146 | 60 +++--
85
tests/qemu-iotests/162 | 4 +-
108
tests/qemu-iotests/146.out | 405 ++++++++++++++++++++++++++++--
86
tests/qemu-iotests/175 | 47 +++++++--
109
tests/qemu-iotests/153 | 9 +-
87
tests/qemu-iotests/175.out | 16 ++-
110
tests/qemu-iotests/158.out | 4 +-
88
tests/qemu-iotests/178.out.qcow2 | 4 +-
111
tests/qemu-iotests/178 | 1 +
89
tests/qemu-iotests/184 | 1 +
112
tests/qemu-iotests/182.out | 2 +-
90
tests/qemu-iotests/186 | 1 +
113
tests/qemu-iotests/185.out | 8 +-
91
tests/qemu-iotests/197 | 1 +
114
tests/qemu-iotests/188 | 1 +
92
tests/qemu-iotests/215 | 1 +
115
tests/qemu-iotests/188.out | 2 +-
93
tests/qemu-iotests/221.out | 12 ++-
116
tests/qemu-iotests/189 | 1 +
94
tests/qemu-iotests/251 | 1 +
117
tests/qemu-iotests/189.out | 4 +-
95
tests/qemu-iotests/253.out | 12 ++-
118
tests/qemu-iotests/198 | 1 +
96
tests/qemu-iotests/common.filter | 4 +-
119
tests/qemu-iotests/198.out | 4 +-
97
tests/qemu-iotests/common.rc | 14 +++
120
tests/qemu-iotests/206 | 1 +
98
50 files changed, 391 insertions(+), 87 deletions(-)
121
tests/qemu-iotests/255.out | 8 +-
99
rename tests/qemu-iotests/{150.out => 150.out.qcow2} (100%)
122
tests/qemu-iotests/263 | 1 +
100
create mode 100644 tests/qemu-iotests/150.out.raw
123
tests/qemu-iotests/263.out | 4 +-
124
tests/qemu-iotests/274.out | 46 ++--
125
tests/qemu-iotests/280.out | 2 +-
126
tests/qemu-iotests/284 | 1 +
127
tests/qemu-iotests/284.out | 6 +-
128
tests/qemu-iotests/293 | 208 ++++++++++++++++
129
tests/qemu-iotests/293.out | 99 ++++++++
130
tests/qemu-iotests/294 | 90 +++++++
131
tests/qemu-iotests/294.out | 30 +++
132
tests/qemu-iotests/295 | 280 +++++++++++++++++++++
133
tests/qemu-iotests/295.out | 40 +++
134
tests/qemu-iotests/296 | 234 +++++++++++++++++
135
tests/qemu-iotests/296.out | 33 +++
136
tests/qemu-iotests/common.filter | 106 ++++++--
137
tests/qemu-iotests/common.rc | 30 +++
138
tests/qemu-iotests/group | 4 +
139
tests/qemu-iotests/iotests.py | 84 +++++--
140
72 files changed, 3103 insertions(+), 632 deletions(-)
141
create mode 100644 block/amend.c
142
create mode 100755 tests/qemu-iotests/293
143
create mode 100644 tests/qemu-iotests/293.out
144
create mode 100755 tests/qemu-iotests/294
145
create mode 100644 tests/qemu-iotests/294.out
146
create mode 100755 tests/qemu-iotests/295
147
create mode 100644 tests/qemu-iotests/295.out
148
create mode 100755 tests/qemu-iotests/296
149
create mode 100644 tests/qemu-iotests/296.out
101
150
102
--
151
--
103
2.21.0
152
2.26.2
104
153
105
154
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
ret may be > 0 on success path at this point. Fix assertion, which may
4
crash currently.
5
6
Fixes: 4ce5dd3e9b5ee0fac18625860eb3727399ee965e
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20200526181347.489557-1-vsementsov@virtuozzo.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
block/block-copy.c | 4 +++-
12
1 file changed, 3 insertions(+), 1 deletion(-)
13
14
diff --git a/block/block-copy.c b/block/block-copy.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/block-copy.c
17
+++ b/block/block-copy.c
18
@@ -XXX,XX +XXX,XX @@ out:
19
* block_copy_task_run. If it fails, it means some task already failed
20
* for real reason, let's return first failure.
21
* Still, assert that we don't rewrite failure by success.
22
+ *
23
+ * Note: ret may be positive here because of block-status result.
24
*/
25
- assert(ret == 0 || aio_task_pool_status(aio) < 0);
26
+ assert(ret >= 0 || aio_task_pool_status(aio) < 0);
27
ret = aio_task_pool_status(aio);
28
29
aio_task_pool_free(aio);
30
--
31
2.26.2
32
33
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
When resizing an image with qcow2_co_truncate() using the falloc or
4
descriptor opened with O_DIRECT, ensuring that it works for any size
4
full preallocation modes the code assumes that both the old and new
5
larger than 4096 bytes.
5
sizes are cluster-aligned.
6
6
7
Testing smaller sizes is tricky as the result depends on the filesystem
7
There are two problems with this:
8
used for testing. For example on NFS any size will work since O_DIRECT
9
does not require any alignment.
10
8
11
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
9
1) The calculation of how many clusters are involved does not always
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
get the right result.
13
Message-id: 20190827010528.8818-3-nsoffer@redhat.com
11
12
Example: creating a 60KB image and resizing it (with
13
preallocation=full) to 80KB won't allocate the second cluster.
14
15
2) No copy-on-write is performed, so in the previous example if
16
there is a backing file then the first 60KB of the first cluster
17
won't be filled with data from the backing file.
18
19
This patch fixes both issues.
20
21
Signed-off-by: Alberto Garcia <berto@igalia.com>
22
Message-Id: <20200617140036.20311-1-berto@igalia.com>
23
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
24
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
25
---
16
tests/qemu-iotests/175 | 28 ++++++++++++++++++++++++++++
26
block/qcow2.c | 17 ++++++++++++++---
17
tests/qemu-iotests/175.out | 8 ++++++++
27
tests/qemu-iotests/125 | 24 ++++++++++++++++++++++++
18
2 files changed, 36 insertions(+)
28
tests/qemu-iotests/125.out | 9 +++++++++
29
3 files changed, 47 insertions(+), 3 deletions(-)
19
30
20
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
31
diff --git a/block/qcow2.c b/block/qcow2.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block/qcow2.c
34
+++ b/block/qcow2.c
35
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
36
old_file_size = ROUND_UP(old_file_size, s->cluster_size);
37
}
38
39
- nb_new_data_clusters = DIV_ROUND_UP(offset - old_length,
40
- s->cluster_size);
41
+ nb_new_data_clusters = (ROUND_UP(offset, s->cluster_size) -
42
+ start_of_cluster(s, old_length)) >> s->cluster_bits;
43
44
/* This is an overestimation; we will not actually allocate space for
45
* these in the file but just make sure the new refcount structures are
46
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
47
int64_t nb_clusters = MIN(
48
nb_new_data_clusters,
49
s->l2_slice_size - offset_to_l2_slice_index(s, guest_offset));
50
- QCowL2Meta allocation = {
51
+ unsigned cow_start_length = offset_into_cluster(s, guest_offset);
52
+ QCowL2Meta allocation;
53
+ guest_offset = start_of_cluster(s, guest_offset);
54
+ allocation = (QCowL2Meta) {
55
.offset = guest_offset,
56
.alloc_offset = host_offset,
57
.nb_clusters = nb_clusters,
58
+ .cow_start = {
59
+ .offset = 0,
60
+ .nb_bytes = cow_start_length,
61
+ },
62
+ .cow_end = {
63
+ .offset = nb_clusters << s->cluster_bits,
64
+ .nb_bytes = 0,
65
+ },
66
};
67
qemu_co_queue_init(&allocation.dependent_requests);
68
69
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
21
index XXXXXXX..XXXXXXX 100755
70
index XXXXXXX..XXXXXXX 100755
22
--- a/tests/qemu-iotests/175
71
--- a/tests/qemu-iotests/125
23
+++ b/tests/qemu-iotests/175
72
+++ b/tests/qemu-iotests/125
24
@@ -XXX,XX +XXX,XX @@ _filter_blocks()
73
@@ -XXX,XX +XXX,XX @@ for GROWTH_SIZE in 16 48 80; do
25
-e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/"
26
}
27
28
+# Resize image using block_resize.
29
+# Parameter 1: image path
30
+# Parameter 2: new size
31
+_block_resize()
32
+{
33
+ local path=$1
34
+ local size=$2
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
+}
44
+
45
# get standard environment, filters and checks
46
. ./common.rc
47
. ./common.filter
48
@@ -XXX,XX +XXX,XX @@ _supported_fmt raw
49
_supported_proto file
50
_supported_os Linux
51
52
+_default_cache_mode none
53
+_supported_cache_modes none directsync
54
+
55
size=$((1 * 1024 * 1024))
56
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
74
done
61
75
done
62
+for new_size in 4096 1048576; do
76
77
+# Test image resizing using preallocation and unaligned offsets
78
+$QEMU_IMG create -f raw "$TEST_IMG.base" 128k | _filter_img_create
79
+$QEMU_IO -c 'write -q -P 1 0 128k' -f raw "$TEST_IMG.base"
80
+for orig_size in 31k 33k; do
81
+ echo "--- Resizing image from $orig_size to 96k ---"
82
+ _make_test_img -F raw -b "$TEST_IMG.base" -o cluster_size=64k "$orig_size"
83
+ $QEMU_IMG resize -f "$IMGFMT" --preallocation=full "$TEST_IMG" 96k
84
+ # The first part of the image should contain data from the backing file
85
+ $QEMU_IO -c "read -q -P 1 0 ${orig_size}" "$TEST_IMG"
86
+ # The resized part of the image should contain zeroes
87
+ $QEMU_IO -c "read -q -P 0 ${orig_size} 63k" "$TEST_IMG"
88
+ # If the image does not have an external data file we can also verify its
89
+ # actual size. The resized image should have 7 clusters:
90
+ # header, L1 table, L2 table, refcount table, refcount block, 2 data clusters
91
+ if ! _get_data_file "$TEST_IMG" > /dev/null; then
92
+ expected_file_length=$((65536 * 7))
93
+ file_length=$(stat -c '%s' "$TEST_IMG_FILE")
94
+ if [ "$file_length" != "$expected_file_length" ]; then
95
+ echo "ERROR: file length $file_length (expected $expected_file_length)"
96
+ fi
97
+ fi
63
+ echo
98
+ 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
99
+done
69
+
100
+
70
# success, all done
101
# success, all done
71
echo "*** done"
102
echo '*** done'
72
rm -f $seq.full
103
rm -f $seq.full
73
diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
104
diff --git a/tests/qemu-iotests/125.out b/tests/qemu-iotests/125.out
74
index XXXXXXX..XXXXXXX 100644
105
index XXXXXXX..XXXXXXX 100644
75
--- a/tests/qemu-iotests/175.out
106
--- a/tests/qemu-iotests/125.out
76
+++ b/tests/qemu-iotests/175.out
107
+++ b/tests/qemu-iotests/125.out
77
@@ -XXX,XX +XXX,XX @@ size=1048576, max allocation
108
@@ -XXX,XX +XXX,XX @@ wrote 2048000/2048000 bytes at offset 0
78
== creating image with preallocation falloc ==
109
wrote 81920/81920 bytes at offset 2048000
79
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc
110
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
80
size=1048576, max allocation
111
112
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=raw size=131072
113
+--- Resizing image from 31k to 96k ---
114
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=31744 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
115
+Image resized.
81
+
116
+
82
+== resize empty image with block_resize ==
117
+--- Resizing image from 33k to 96k ---
83
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
118
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33792 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
84
+size=4096, min allocation
119
+Image resized.
85
+
120
+
86
+== resize empty image with block_resize ==
121
*** done
87
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
88
+size=1048576, min allocation
89
*** done
90
--
122
--
91
2.21.0
123
2.26.2
92
124
93
125
diff view generated by jsdifflib
New patch
1
1
Right now, _filter_img_create just filters out everything that looks
2
format-dependent, and applies some filename filters. That means that we
3
have to add another filter line every time some format gets a new
4
creation option. This can be avoided by instead discarding everything
5
and just keeping what we know is format-independent (format, size,
6
backing file, encryption information[1], preallocation) or just
7
interesting to have in the reference output (external data file path).
8
9
Furthermore, we probably want to sort these options. Format drivers are
10
not required to define them in any specific order, so the output is
11
effectively random (although this has never bothered us until now). We
12
need a specific order for our reference outputs, though. Unfortunately,
13
just using a plain "sort" would change a lot of existing reference
14
outputs, so we have to pre-filter the option keys to keep our existing
15
order (fmt, size, backing*, data, encryption info, preallocation).
16
17
Finally, this makes it difficult for _filter_img_create to automagically
18
work for QMP output. Thus, this patch adds a separate
19
_filter_img_create_for_qmp function that echos every line verbatim that
20
does not start with "Formatting", and pipes those "Formatting" lines to
21
_filter_img_create.
22
23
[1] Actually, the only thing that is really important is whether
24
encryption is enabled or not. A patch by Maxim thus removes all
25
other "encrypt.*" options from the output:
26
https://lists.nongnu.org/archive/html/qemu-block/2020-06/msg00339.html
27
But that patch needs to come later so we can get away with changing
28
as few reference outputs in this patch here as possible.
29
30
Signed-off-by: Max Reitz <mreitz@redhat.com>
31
Message-Id: <20200625125548.870061-2-mreitz@redhat.com>
32
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
33
---
34
tests/qemu-iotests/112.out | 2 +-
35
tests/qemu-iotests/141 | 2 +-
36
tests/qemu-iotests/153 | 9 ++-
37
tests/qemu-iotests/common.filter | 109 ++++++++++++++++++++++++-------
38
4 files changed, 91 insertions(+), 31 deletions(-)
39
40
diff --git a/tests/qemu-iotests/112.out b/tests/qemu-iotests/112.out
41
index XXXXXXX..XXXXXXX 100644
42
--- a/tests/qemu-iotests/112.out
43
+++ b/tests/qemu-iotests/112.out
44
@@ -XXX,XX +XXX,XX @@ QA output created by 112
45
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
46
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
47
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
48
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 refcount_bits=-1
49
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
50
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
51
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
52
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
53
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
54
index XXXXXXX..XXXXXXX 100755
55
--- a/tests/qemu-iotests/141
56
+++ b/tests/qemu-iotests/141
57
@@ -XXX,XX +XXX,XX @@ test_blockjob()
58
_send_qemu_cmd $QEMU_HANDLE \
59
"$1" \
60
"$2" \
61
- | _filter_img_create | _filter_qmp_empty_return
62
+ | _filter_img_create_in_qmp | _filter_qmp_empty_return
63
64
# We want this to return an error because the block job is still running
65
_send_qemu_cmd $QEMU_HANDLE \
66
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
67
index XXXXXXX..XXXXXXX 100755
68
--- a/tests/qemu-iotests/153
69
+++ b/tests/qemu-iotests/153
70
@@ -XXX,XX +XXX,XX @@ done
71
72
echo
73
echo "== Creating ${TEST_IMG}.[abc] ==" | _filter_testdir
74
-(
75
- $QEMU_IMG create -f qcow2 "${TEST_IMG}.a" -b "${TEST_IMG}"
76
- $QEMU_IMG create -f qcow2 "${TEST_IMG}.b" -b "${TEST_IMG}"
77
- $QEMU_IMG create -f qcow2 "${TEST_IMG}.c" -b "${TEST_IMG}.b"
78
-) | _filter_img_create
79
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.a" -b "${TEST_IMG}" | _filter_img_create
80
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.b" -b "${TEST_IMG}" | _filter_img_create
81
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.c" -b "${TEST_IMG}.b" \
82
+ | _filter_img_create
83
84
echo
85
echo "== Two devices sharing the same file in backing chain =="
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_actual_image_size()
91
# replace driver-specific options in the "Formatting..." line
92
_filter_img_create()
93
{
94
- data_file_filter=()
95
- if data_file=$(_get_data_file "$TEST_IMG"); then
96
- data_file_filter=(-e "s# data_file=$data_file##")
97
+ # Split the line into the pre-options part ($filename_part, which
98
+ # precedes ", fmt=") and the options part ($options, which starts
99
+ # with "fmt=")
100
+ # (And just echo everything before the first "^Formatting")
101
+ readarray formatting_line < <($SED -e 's/, fmt=/\n/')
102
+
103
+ filename_part=''
104
+ options=''
105
+ lines=${#formatting_line[@]}
106
+ for ((i = 0; i < $lines; i++)); do
107
+ line=${formatting_line[i]}
108
+ unset formatting_line[i]
109
+
110
+ filename_part="$filename_part$line"
111
+
112
+ if echo "$line" | grep -q '^Formatting'; then
113
+ next_i=$((i + 1))
114
+ if [ -n "${formatting_line[next_i]}" ]; then
115
+ options="fmt=${formatting_line[@]}"
116
+ fi
117
+ break
118
+ fi
119
+ done
120
+
121
+ # Set grep_data_file to '\|data_file' to keep it; make it empty
122
+ # to drop it.
123
+ # We want to drop it if it is part of the global $IMGOPTS, and we
124
+ # want to keep it otherwise (if the test specifically wants to
125
+ # test data files).
126
+ grep_data_file=(-e data_file)
127
+ if _get_data_file "$TEST_IMG" > /dev/null; then
128
+ grep_data_file=()
129
fi
130
131
- $SED "${data_file_filter[@]}" \
132
+ filename_filters=(
133
-e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
134
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
135
-e "s#$TEST_DIR#TEST_DIR#g" \
136
-e "s#$SOCK_DIR#SOCK_DIR#g" \
137
-e "s#$IMGFMT#IMGFMT#g" \
138
-e 's#nbd:127.0.0.1:[0-9]\\+#TEST_DIR/t.IMGFMT#g' \
139
- -e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g' \
140
- -e "s# encryption=off##g" \
141
- -e "s# cluster_size=[0-9]\\+##g" \
142
- -e "s# table_size=[0-9]\\+##g" \
143
- -e "s# compat=[^ ]*##g" \
144
- -e "s# compat6=\\(on\\|off\\)##g" \
145
- -e "s# static=\\(on\\|off\\)##g" \
146
- -e "s# zeroed_grain=\\(on\\|off\\)##g" \
147
- -e "s# subformat=[^ ]*##g" \
148
- -e "s# adapter_type=[^ ]*##g" \
149
- -e "s# hwversion=[^ ]*##g" \
150
- -e "s# lazy_refcounts=\\(on\\|off\\)##g" \
151
- -e "s# block_size=[0-9]\\+##g" \
152
- -e "s# block_state_zero=\\(on\\|off\\)##g" \
153
- -e "s# log_size=[0-9]\\+##g" \
154
- -e "s# refcount_bits=[0-9]\\+##g" \
155
- -e "s# key-secret=[a-zA-Z0-9]\\+##g" \
156
- -e "s# iter-time=[0-9]\\+##g" \
157
- -e "s# force_size=\\(on\\|off\\)##g" \
158
- -e "s# compression_type=[a-zA-Z0-9]\\+##g"
159
+ -e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g'
160
+ )
161
+
162
+ filename_part=$(echo "$filename_part" | $SED "${filename_filters[@]}")
163
+
164
+ # Break the option line before each option (preserving pre-existing
165
+ # line breaks by replacing them by \0 and restoring them at the end),
166
+ # then filter out the options we want to keep and sort them according
167
+ # to some order that all block drivers used at the time of writing
168
+ # this function.
169
+ options=$(
170
+ echo "$options" \
171
+ | tr '\n' '\0' \
172
+ | $SED -e 's/ \([a-z0-9_.-]*\)=/\n\1=/g' \
173
+ | grep -a -e '^fmt' -e '^size' -e '^backing' -e '^preallocation' \
174
+ -e '^encrypt' "${grep_data_file[@]}" \
175
+ | $SED "${filename_filters[@]}" \
176
+ -e 's/^\(fmt\)/0-\1/' \
177
+ -e 's/^\(size\)/1-\1/' \
178
+ -e 's/^\(backing\)/2-\1/' \
179
+ -e 's/^\(data_file\)/3-\1/' \
180
+ -e 's/^\(encryption\)/4-\1/' \
181
+ -e 's/^\(encrypt\.format\)/5-\1/' \
182
+ -e 's/^\(encrypt\.key-secret\)/6-\1/' \
183
+ -e 's/^\(encrypt\.iter-time\)/7-\1/' \
184
+ -e 's/^\(preallocation\)/8-\1/' \
185
+ | sort \
186
+ | $SED -e 's/^[0-9]-//' \
187
+ | tr '\n\0' ' \n' \
188
+ | $SED -e 's/^ *$//' -e 's/ *$//'
189
+ )
190
+
191
+ if [ -n "$options" ]; then
192
+ echo "$filename_part, $options"
193
+ elif [ -n "$filename_part" ]; then
194
+ echo "$filename_part"
195
+ fi
196
+}
197
+
198
+# Filter the "Formatting..." line in QMP output (leaving the QMP output
199
+# untouched)
200
+# (In contrast to _filter_img_create(), this function does not support
201
+# multi-line Formatting output)
202
+_filter_img_create_in_qmp()
203
+{
204
+ while read -r line; do
205
+ if echo "$line" | grep -q '^Formatting'; then
206
+ echo "$line" | _filter_img_create
207
+ else
208
+ echo "$line"
209
+ fi
210
+ done
211
}
212
213
_filter_img_create_size()
214
--
215
2.26.2
216
217
diff view generated by jsdifflib
New patch
1
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
3
This allows more tests to be able to have same output on both qcow2 luks encrypted images
4
and raw luks images
5
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
9
Message-Id: <20200625125548.870061-3-mreitz@redhat.com>
10
---
11
tests/qemu-iotests/087.out | 6 +++---
12
tests/qemu-iotests/134.out | 2 +-
13
tests/qemu-iotests/158.out | 4 ++--
14
tests/qemu-iotests/188.out | 2 +-
15
tests/qemu-iotests/189.out | 4 ++--
16
tests/qemu-iotests/198.out | 4 ++--
17
tests/qemu-iotests/263.out | 4 ++--
18
tests/qemu-iotests/284.out | 6 +++---
19
tests/qemu-iotests/common.filter | 5 +----
20
9 files changed, 17 insertions(+), 20 deletions(-)
21
22
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
23
index XXXXXXX..XXXXXXX 100644
24
--- a/tests/qemu-iotests/087.out
25
+++ b/tests/qemu-iotests/087.out
26
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
27
28
=== Encrypted image QCow ===
29
30
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0
31
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
32
Testing:
33
QMP_VERSION
34
{"return": {}}
35
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
36
37
=== Encrypted image LUKS ===
38
39
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encrypt.format=luks encrypt.key-secret=sec0
40
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
41
Testing:
42
QMP_VERSION
43
{"return": {}}
44
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
45
46
=== Missing driver ===
47
48
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0
49
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
50
Testing: -S
51
QMP_VERSION
52
{"return": {}}
53
diff --git a/tests/qemu-iotests/134.out b/tests/qemu-iotests/134.out
54
index XXXXXXX..XXXXXXX 100644
55
--- a/tests/qemu-iotests/134.out
56
+++ b/tests/qemu-iotests/134.out
57
@@ -XXX,XX +XXX,XX @@
58
QA output created by 134
59
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0
60
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
61
62
== reading whole image ==
63
read 134217728/134217728 bytes at offset 0
64
diff --git a/tests/qemu-iotests/158.out b/tests/qemu-iotests/158.out
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tests/qemu-iotests/158.out
67
+++ b/tests/qemu-iotests/158.out
68
@@ -XXX,XX +XXX,XX @@
69
QA output created by 158
70
== create base ==
71
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0
72
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 encryption=on
73
74
== writing whole image ==
75
wrote 134217728/134217728 bytes at offset 0
76
@@ -XXX,XX +XXX,XX @@ wrote 134217728/134217728 bytes at offset 0
77
read 134217728/134217728 bytes at offset 0
78
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
79
== create overlay ==
80
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base encryption=on encrypt.key-secret=sec0
81
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base encryption=on
82
83
== writing part of a cluster ==
84
wrote 1024/1024 bytes at offset 0
85
diff --git a/tests/qemu-iotests/188.out b/tests/qemu-iotests/188.out
86
index XXXXXXX..XXXXXXX 100644
87
--- a/tests/qemu-iotests/188.out
88
+++ b/tests/qemu-iotests/188.out
89
@@ -XXX,XX +XXX,XX @@
90
QA output created by 188
91
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
92
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216
93
94
== reading whole image ==
95
read 16777216/16777216 bytes at offset 0
96
diff --git a/tests/qemu-iotests/189.out b/tests/qemu-iotests/189.out
97
index XXXXXXX..XXXXXXX 100644
98
--- a/tests/qemu-iotests/189.out
99
+++ b/tests/qemu-iotests/189.out
100
@@ -XXX,XX +XXX,XX @@
101
QA output created by 189
102
== create base ==
103
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
104
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216
105
106
== writing whole image ==
107
wrote 16777216/16777216 bytes at offset 0
108
@@ -XXX,XX +XXX,XX @@ wrote 16777216/16777216 bytes at offset 0
109
read 16777216/16777216 bytes at offset 0
110
16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
111
== create overlay ==
112
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 backing_file=TEST_DIR/t.IMGFMT.base encrypt.format=luks encrypt.key-secret=sec1 encrypt.iter-time=10
113
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 backing_file=TEST_DIR/t.IMGFMT.base
114
115
== writing part of a cluster ==
116
wrote 1024/1024 bytes at offset 0
117
diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out
118
index XXXXXXX..XXXXXXX 100644
119
--- a/tests/qemu-iotests/198.out
120
+++ b/tests/qemu-iotests/198.out
121
@@ -XXX,XX +XXX,XX @@
122
QA output created by 198
123
== create base ==
124
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
125
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216
126
127
== writing whole image base ==
128
wrote 16777216/16777216 bytes at offset 0
129
16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
130
== create overlay ==
131
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 backing_file=TEST_DIR/t.IMGFMT.base encrypt.format=luks encrypt.key-secret=sec1 encrypt.iter-time=10
132
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 backing_file=TEST_DIR/t.IMGFMT.base
133
134
== writing whole image layer ==
135
wrote 16777216/16777216 bytes at offset 0
136
diff --git a/tests/qemu-iotests/263.out b/tests/qemu-iotests/263.out
137
index XXXXXXX..XXXXXXX 100644
138
--- a/tests/qemu-iotests/263.out
139
+++ b/tests/qemu-iotests/263.out
140
@@ -XXX,XX +XXX,XX @@ QA output created by 263
141
142
testing LUKS qcow2 encryption
143
144
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
145
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
146
== reading the whole image ==
147
read 1048576/1048576 bytes at offset 0
148
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
149
@@ -XXX,XX +XXX,XX @@ read 982528/982528 bytes at offset 66048
150
151
testing legacy AES qcow2 encryption
152
153
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=aes encrypt.key-secret=sec0
154
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
155
== reading the whole image ==
156
read 1048576/1048576 bytes at offset 0
157
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
158
diff --git a/tests/qemu-iotests/284.out b/tests/qemu-iotests/284.out
159
index XXXXXXX..XXXXXXX 100644
160
--- a/tests/qemu-iotests/284.out
161
+++ b/tests/qemu-iotests/284.out
162
@@ -XXX,XX +XXX,XX @@ QA output created by 284
163
164
testing LUKS qcow2 encryption
165
166
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
167
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
168
169
== cluster size 512
170
== checking image refcounts ==
171
@@ -XXX,XX +XXX,XX @@ wrote 1/1 bytes at offset 512
172
173
== rechecking image refcounts ==
174
No errors were found on the image.
175
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
176
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
177
178
== cluster size 2048
179
== checking image refcounts ==
180
@@ -XXX,XX +XXX,XX @@ wrote 1/1 bytes at offset 2048
181
182
== rechecking image refcounts ==
183
No errors were found on the image.
184
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
185
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
186
187
== cluster size 32768
188
== checking image refcounts ==
189
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
190
index XXXXXXX..XXXXXXX 100644
191
--- a/tests/qemu-iotests/common.filter
192
+++ b/tests/qemu-iotests/common.filter
193
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
194
| tr '\n' '\0' \
195
| $SED -e 's/ \([a-z0-9_.-]*\)=/\n\1=/g' \
196
| grep -a -e '^fmt' -e '^size' -e '^backing' -e '^preallocation' \
197
- -e '^encrypt' "${grep_data_file[@]}" \
198
+ -e '^encryption' "${grep_data_file[@]}" \
199
| $SED "${filename_filters[@]}" \
200
-e 's/^\(fmt\)/0-\1/' \
201
-e 's/^\(size\)/1-\1/' \
202
-e 's/^\(backing\)/2-\1/' \
203
-e 's/^\(data_file\)/3-\1/' \
204
-e 's/^\(encryption\)/4-\1/' \
205
- -e 's/^\(encrypt\.format\)/5-\1/' \
206
- -e 's/^\(encrypt\.key-secret\)/6-\1/' \
207
- -e 's/^\(encrypt\.iter-time\)/7-\1/' \
208
-e 's/^\(preallocation\)/8-\1/' \
209
| sort \
210
| $SED -e 's/^[0-9]-//' \
211
--
212
2.26.2
213
214
diff view generated by jsdifflib
New patch
1
That the luks driver is present is little indication on whether it is
2
actually working. Without the crypto libraries linked in, it does not
3
work. So add this function, which tries to create a luks image to see
4
whether that actually works.
1
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-Id: <20200625125548.870061-4-mreitz@redhat.com>
8
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
9
---
10
tests/qemu-iotests/common.rc | 27 +++++++++++++++++++++++++++
11
1 file changed, 27 insertions(+)
12
13
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qemu-iotests/common.rc
16
+++ b/tests/qemu-iotests/common.rc
17
@@ -XXX,XX +XXX,XX @@ _unsupported_imgopts()
18
done
19
}
20
21
+# Caution: Overwrites $TEST_DIR/t.luks
22
+_require_working_luks()
23
+{
24
+ file="$TEST_DIR/t.luks"
25
+
26
+ output=$(
27
+ $QEMU_IMG create -f luks \
28
+ --object secret,id=sec0,data=hunter0 \
29
+ -o key-secret=sec0 \
30
+ -o iter-time=10 \
31
+ "$file" \
32
+ 1M \
33
+ 2>&1
34
+ )
35
+ status=$?
36
+
37
+ IMGFMT='luks' _rm_test_img "$file"
38
+
39
+ if [ $status != 0 ]; then
40
+ reason=$(echo "$output" | grep "$file:" | $SED -e "s#.*$file: *##")
41
+ if [ -z "$reason" ]; then
42
+ reason="Failed to create a LUKS image"
43
+ fi
44
+ _notrun "$reason"
45
+ fi
46
+}
47
+
48
# this test requires that a specified command (executable) exists
49
#
50
_require_command()
51
--
52
2.26.2
53
54
diff view generated by jsdifflib
1
iotest 126 requires backing file support, which flat vmdks cannot offer.
1
This function will be used by the next patch, which intends to check
2
Skip this test for such subformats.
2
both the exit code and qemu-img's output.
3
3
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Message-id: 20190815153638.4600-8-mreitz@redhat.com
5
Message-Id: <20200625125548.870061-5-mreitz@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
6
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
7
[mreitz: Rebased on 49438972b8c2e]
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
9
---
9
tests/qemu-iotests/126 | 2 ++
10
tests/qemu-iotests/iotests.py | 40 +++++++++++++++++------------------
10
1 file changed, 2 insertions(+)
11
1 file changed, 20 insertions(+), 20 deletions(-)
11
12
12
diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
13
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
13
index XXXXXXX..XXXXXXX 100755
14
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/126
15
--- a/tests/qemu-iotests/iotests.py
15
+++ b/tests/qemu-iotests/126
16
+++ b/tests/qemu-iotests/iotests.py
16
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
17
@@ -XXX,XX +XXX,XX @@ import struct
17
18
import subprocess
18
# Needs backing file support
19
import sys
19
_supported_fmt qcow qcow2 qed vmdk
20
from typing import (Any, Callable, Dict, Iterable,
20
+_unsupported_imgopts "subformat=monolithicFlat" \
21
- List, Optional, Sequence, TypeVar)
21
+ "subformat=twoGbMaxExtentFlat"
22
+ List, Optional, Sequence, Tuple, TypeVar)
22
# This is the default protocol (and we want to test the difference between
23
import unittest
23
# colons which separate a protocol prefix from the rest and colons which are
24
24
# just part of the filename, so we cannot test protocols which require a prefix)
25
# pylint: disable=import-error, wrong-import-position
26
@@ -XXX,XX +XXX,XX @@ luks_default_secret_object = 'secret,id=keysec0,data=' + \
27
luks_default_key_secret_opt = 'key-secret=keysec0'
28
29
30
-def qemu_img(*args):
31
- '''Run qemu-img and return the exit code'''
32
- devnull = open('/dev/null', 'r+')
33
- exitcode = subprocess.call(qemu_img_args + list(args),
34
- stdin=devnull, stdout=devnull)
35
- if exitcode < 0:
36
+def qemu_img_pipe_and_status(*args: str) -> Tuple[str, int]:
37
+ """
38
+ Run qemu-img and return both its output and its exit code
39
+ """
40
+ subp = subprocess.Popen(qemu_img_args + list(args),
41
+ stdout=subprocess.PIPE,
42
+ stderr=subprocess.STDOUT,
43
+ universal_newlines=True)
44
+ output = subp.communicate()[0]
45
+ if subp.returncode < 0:
46
sys.stderr.write('qemu-img received signal %i: %s\n'
47
- % (-exitcode, ' '.join(qemu_img_args + list(args))))
48
- return exitcode
49
+ % (-subp.returncode,
50
+ ' '.join(qemu_img_args + list(args))))
51
+ return (output, subp.returncode)
52
+
53
+def qemu_img(*args: str) -> int:
54
+ '''Run qemu-img and return the exit code'''
55
+ return qemu_img_pipe_and_status(*args)[1]
56
57
def ordered_qmp(qmsg, conv_keys=True):
58
# Dictionaries are not ordered prior to 3.6, therefore:
59
@@ -XXX,XX +XXX,XX @@ def qemu_img_verbose(*args):
60
% (-exitcode, ' '.join(qemu_img_args + list(args))))
61
return exitcode
62
63
-def qemu_img_pipe(*args):
64
+def qemu_img_pipe(*args: str) -> str:
65
'''Run qemu-img and return its output'''
66
- subp = subprocess.Popen(qemu_img_args + list(args),
67
- stdout=subprocess.PIPE,
68
- stderr=subprocess.STDOUT,
69
- universal_newlines=True)
70
- output = subp.communicate()[0]
71
- if subp.returncode < 0:
72
- sys.stderr.write('qemu-img received signal %i: %s\n'
73
- % (-subp.returncode,
74
- ' '.join(qemu_img_args + list(args))))
75
- return output
76
+ return qemu_img_pipe_and_status(*args)[0]
77
78
def qemu_img_log(*args):
79
result = qemu_img_pipe(*args)
25
--
80
--
26
2.21.0
81
2.26.2
27
82
28
83
diff view generated by jsdifflib
New patch
1
Similar to _require_working_luks for bash tests, these functions can be
2
used to check whether our luks driver can actually create images.
1
3
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Message-Id: <20200625125548.870061-6-mreitz@redhat.com>
6
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
7
---
8
tests/qemu-iotests/iotests.py | 39 +++++++++++++++++++++++++++++++++++
9
1 file changed, 39 insertions(+)
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 verify_quorum():
16
if not supports_quorum():
17
notrun('quorum support missing')
18
19
+def has_working_luks() -> Tuple[bool, str]:
20
+ """
21
+ Check whether our LUKS driver can actually create images
22
+ (this extends to LUKS encryption for qcow2).
23
+
24
+ If not, return the reason why.
25
+ """
26
+
27
+ img_file = f'{test_dir}/luks-test.luks'
28
+ (output, status) = \
29
+ qemu_img_pipe_and_status('create', '-f', 'luks',
30
+ '--object', luks_default_secret_object,
31
+ '-o', luks_default_key_secret_opt,
32
+ '-o', 'iter-time=10',
33
+ img_file, '1G')
34
+ try:
35
+ os.remove(img_file)
36
+ except OSError:
37
+ pass
38
+
39
+ if status != 0:
40
+ reason = output
41
+ for line in output.splitlines():
42
+ if img_file + ':' in line:
43
+ reason = line.split(img_file + ':', 1)[1].strip()
44
+ break
45
+
46
+ return (False, reason)
47
+ else:
48
+ return (True, '')
49
+
50
+def verify_working_luks():
51
+ """
52
+ Skip test suite if LUKS does not work
53
+ """
54
+ (working, reason) = has_working_luks()
55
+ if not working:
56
+ notrun(reason)
57
+
58
def qemu_pipe(*args):
59
"""
60
Run qemu with an option to print something and exit (e.g. a help option).
61
--
62
2.26.2
63
64
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
Whenever running an iotest for the luks format, we should check whether
2
luks actually really works.
2
3
3
It is possible to enable only a subset of the block drivers with the
4
Tests that try to create luks-encrypted qcow2 images should do the same.
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
5
13
This patch mainly targets the test in the "auto" group which should
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
never fail in such a case, but also improves some of the other tests
7
Message-Id: <20200625125548.870061-7-mreitz@redhat.com>
15
along the way. Note that we also assume that the "qcow2" and "file"
8
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
16
drivers are always available - otherwise it does not make sense to
9
---
17
run "make check-block" at all (which only tests with qcow2 by default).
10
tests/qemu-iotests/087 | 1 +
11
tests/qemu-iotests/178 | 1 +
12
tests/qemu-iotests/188 | 1 +
13
tests/qemu-iotests/189 | 1 +
14
tests/qemu-iotests/198 | 1 +
15
tests/qemu-iotests/206 | 1 +
16
tests/qemu-iotests/263 | 1 +
17
tests/qemu-iotests/284 | 1 +
18
tests/qemu-iotests/common.rc | 3 +++
19
tests/qemu-iotests/iotests.py | 5 +++++
20
10 files changed, 16 insertions(+)
18
21
19
Signed-off-by: Thomas Huth <thuth@redhat.com>
22
diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087
20
Message-id: 20190823133552.11680-1-thuth@redhat.com
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
---
23
tests/qemu-iotests/071 | 1 +
24
tests/qemu-iotests/081 | 4 +---
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
33
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
34
index XXXXXXX..XXXXXXX 100755
23
index XXXXXXX..XXXXXXX 100755
35
--- a/tests/qemu-iotests/071
24
--- a/tests/qemu-iotests/087
36
+++ b/tests/qemu-iotests/071
25
+++ b/tests/qemu-iotests/087
37
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
26
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
38
39
_supported_fmt qcow2
27
_supported_fmt qcow2
40
_supported_proto file
28
_supported_proto file
41
+_require_drivers blkdebug blkverify
29
_supported_os Linux
30
+_require_working_luks
42
31
43
do_run_qemu()
32
do_run_qemu()
44
{
33
{
45
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
34
diff --git a/tests/qemu-iotests/178 b/tests/qemu-iotests/178
46
index XXXXXXX..XXXXXXX 100755
35
index XXXXXXX..XXXXXXX 100755
47
--- a/tests/qemu-iotests/081
36
--- a/tests/qemu-iotests/178
48
+++ b/tests/qemu-iotests/081
37
+++ b/tests/qemu-iotests/178
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
38
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
50
_supported_fmt raw
39
_supported_fmt raw qcow2
51
_supported_proto file
40
_supported_proto file
52
_supported_os Linux
41
_supported_os Linux
53
+_require_drivers quorum
42
+_require_working_luks
54
43
55
do_run_qemu()
44
echo "== Input validation =="
56
{
45
echo
57
@@ -XXX,XX +XXX,XX @@ run_qemu()
46
diff --git a/tests/qemu-iotests/188 b/tests/qemu-iotests/188
58
| _filter_qemu_io | _filter_generated_node_ids
59
}
60
61
-test_quorum=$($QEMU_IMG --help|grep quorum)
62
-[ "$test_quorum" = "" ] && _supported_fmt quorum
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
47
index XXXXXXX..XXXXXXX 100755
69
--- a/tests/qemu-iotests/099
48
--- a/tests/qemu-iotests/188
70
+++ b/tests/qemu-iotests/099
49
+++ b/tests/qemu-iotests/188
71
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
50
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
72
_supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc
51
_supported_fmt qcow2
73
_supported_proto file
52
_supported_proto generic
74
_supported_os Linux
53
_supported_os Linux
75
+_require_drivers blkdebug blkverify
54
+_require_working_luks
76
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
55
77
"subformat=twoGbMaxExtentSparse"
56
78
57
size=16M
79
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
58
diff --git a/tests/qemu-iotests/189 b/tests/qemu-iotests/189
80
index XXXXXXX..XXXXXXX 100755
59
index XXXXXXX..XXXXXXX 100755
81
--- a/tests/qemu-iotests/120
60
--- a/tests/qemu-iotests/189
82
+++ b/tests/qemu-iotests/120
61
+++ b/tests/qemu-iotests/189
83
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
62
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
84
_supported_fmt generic
63
_supported_fmt qcow2
85
_supported_proto file
64
_supported_proto generic
86
_unsupported_fmt luks
65
_supported_os Linux
87
+_require_drivers raw
66
+_require_working_luks
88
67
89
_make_test_img 64M
68
90
69
size=16M
91
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
70
diff --git a/tests/qemu-iotests/198 b/tests/qemu-iotests/198
92
index XXXXXXX..XXXXXXX 100755
71
index XXXXXXX..XXXXXXX 100755
93
--- a/tests/qemu-iotests/162
72
--- a/tests/qemu-iotests/198
94
+++ b/tests/qemu-iotests/162
73
+++ b/tests/qemu-iotests/198
95
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
74
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
96
. ./common.filter
75
_supported_fmt qcow2
97
76
_supported_proto generic
98
_supported_fmt generic
77
_supported_os Linux
99
-
78
+_require_working_luks
100
-test_ssh=$($QEMU_IMG --help | grep '^Supported formats:.* ssh\( \|$\)')
79
101
-[ "$test_ssh" = "" ] && _notrun "ssh support required"
80
102
+_require_drivers ssh
81
size=16M
103
82
diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206
104
echo
105
echo '=== NBD ==='
106
diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184
107
index XXXXXXX..XXXXXXX 100755
83
index XXXXXXX..XXXXXXX 100755
108
--- a/tests/qemu-iotests/184
84
--- a/tests/qemu-iotests/206
109
+++ b/tests/qemu-iotests/184
85
+++ b/tests/qemu-iotests/206
110
@@ -XXX,XX +XXX,XX @@ trap "exit \$status" 0 1 2 3 15
86
@@ -XXX,XX +XXX,XX @@ import iotests
111
. ./common.filter
87
from iotests import imgfmt
112
88
89
iotests.script_initialize(supported_fmts=['qcow2'])
90
+iotests.verify_working_luks()
91
92
with iotests.FilePath('t.qcow2') as disk_path, \
93
iotests.FilePath('t.qcow2.base') as backing_path, \
94
diff --git a/tests/qemu-iotests/263 b/tests/qemu-iotests/263
95
index XXXXXXX..XXXXXXX 100755
96
--- a/tests/qemu-iotests/263
97
+++ b/tests/qemu-iotests/263
98
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
99
_supported_fmt qcow2
100
_supported_proto generic
113
_supported_os Linux
101
_supported_os Linux
114
+_require_drivers throttle
102
+_require_working_luks
115
103
116
do_run_qemu()
104
117
{
105
size=1M
118
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
106
diff --git a/tests/qemu-iotests/284 b/tests/qemu-iotests/284
119
index XXXXXXX..XXXXXXX 100755
107
index XXXXXXX..XXXXXXX 100755
120
--- a/tests/qemu-iotests/186
108
--- a/tests/qemu-iotests/284
121
+++ b/tests/qemu-iotests/186
109
+++ b/tests/qemu-iotests/284
122
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
110
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
123
124
_supported_fmt qcow2
111
_supported_fmt qcow2
125
_supported_proto file
112
_supported_proto generic
126
+_require_drivers null-co
113
_supported_os Linux
127
114
+_require_working_luks
128
if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
115
129
_notrun "Requires a PC machine"
116
117
size=1M
130
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
118
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
131
index XXXXXXX..XXXXXXX 100644
119
index XXXXXXX..XXXXXXX 100644
132
--- a/tests/qemu-iotests/common.rc
120
--- a/tests/qemu-iotests/common.rc
133
+++ b/tests/qemu-iotests/common.rc
121
+++ b/tests/qemu-iotests/common.rc
134
@@ -XXX,XX +XXX,XX @@ _require_command()
122
@@ -XXX,XX +XXX,XX @@ _supported_fmt()
135
[ -x "$c" ] || _notrun "$1 utility required, skipped this test"
123
# setting IMGFMT_GENERIC to false.
136
}
124
for f; do
137
125
if [ "$f" = "$IMGFMT" -o "$f" = "generic" -a "$IMGFMT_GENERIC" = "true" ]; then
138
+# Check that a set of drivers has been whitelisted in the QEMU binary
126
+ if [ "$IMGFMT" = "luks" ]; then
139
+#
127
+ _require_working_luks
140
+_require_drivers()
128
+ fi
141
+{
129
return
142
+ available=$($QEMU -drive format=help | \
130
fi
143
+ sed -e '/Supported formats:/!d' -e 's/Supported formats://')
131
done
144
+ for driver
132
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
145
+ do
133
index XXXXXXX..XXXXXXX 100644
146
+ if ! echo "$available" | grep -q " $driver\( \|$\)"; then
134
--- a/tests/qemu-iotests/iotests.py
147
+ _notrun "$driver not available"
135
+++ b/tests/qemu-iotests/iotests.py
148
+ fi
136
@@ -XXX,XX +XXX,XX @@ def _verify_image_format(supported_fmts: Sequence[str] = (),
149
+ done
137
# similar to
150
+}
138
# _supported_fmt generic
139
# for bash tests
140
+ if imgfmt == 'luks':
141
+ verify_working_luks()
142
return
143
144
not_sup = supported_fmts and (imgfmt not in supported_fmts)
145
if not_sup or (imgfmt in unsupported_fmts):
146
notrun('not suitable for this image format: %s' % imgfmt)
147
148
+ if imgfmt == 'luks':
149
+ verify_working_luks()
151
+
150
+
152
# make sure this script returns success
151
def _verify_protocol(supported: Sequence[str] = (),
153
true
152
unsupported: Sequence[str] = ()) -> None:
153
assert not (supported and unsupported)
154
--
154
--
155
2.21.0
155
2.26.2
156
156
157
157
diff view generated by jsdifflib
1
From: Denis Plotnikov <dplotnikov@virtuozzo.com>
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
2
3
The patch allows to provide a pattern file for write
3
This will be used first to implement luks keyslot management.
4
command. There was no similar ability before.
5
4
6
Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
5
block_crypto_amend_opts_init will be used to convert
7
Message-id: 20190820164616.4072-1-dplotnikov@virtuozzo.com
6
qemu-img cmdline to QCryptoBlockAmendOptions
8
Reviewed-by: Eric Blake <eblake@redhat.com>
7
9
[mreitz: Keep optstring in alphabetical order]
8
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
10
Message-Id: <20200608094030.670121-2-mlevitsk@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
---
12
qemu-io-cmds.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++---
13
qapi/crypto.json | 16 ++++++++++++++++
13
1 file changed, 93 insertions(+), 6 deletions(-)
14
block/crypto.h | 3 +++
15
crypto/blockpriv.h | 8 ++++++++
16
include/crypto/block.h | 22 ++++++++++++++++++++++
17
block/crypto.c | 17 +++++++++++++++++
18
crypto/block.c | 29 +++++++++++++++++++++++++++++
19
6 files changed, 95 insertions(+)
14
20
15
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
21
diff --git a/qapi/crypto.json b/qapi/crypto.json
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/qemu-io-cmds.c
23
--- a/qapi/crypto.json
18
+++ b/qemu-io-cmds.c
24
+++ b/qapi/crypto.json
19
@@ -XXX,XX +XXX,XX @@ static void qemu_io_free(void *p)
25
@@ -XXX,XX +XXX,XX @@
20
qemu_vfree(p);
26
'base': 'QCryptoBlockInfoBase',
27
'discriminator': 'format',
28
'data': { 'luks': 'QCryptoBlockInfoLUKS' } }
29
+
30
+
31
+
32
+##
33
+# @QCryptoBlockAmendOptions:
34
+#
35
+# The options that are available for all encryption formats
36
+# when amending encryption settings
37
+#
38
+# Since: 5.1
39
+##
40
+{ 'union': 'QCryptoBlockAmendOptions',
41
+ 'base': 'QCryptoBlockOptionsBase',
42
+ 'discriminator': 'format',
43
+ 'data': {
44
+ } }
45
diff --git a/block/crypto.h b/block/crypto.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/crypto.h
48
+++ b/block/crypto.h
49
@@ -XXX,XX +XXX,XX @@
50
QCryptoBlockCreateOptions *
51
block_crypto_create_opts_init(QDict *opts, Error **errp);
52
53
+QCryptoBlockAmendOptions *
54
+block_crypto_amend_opts_init(QDict *opts, Error **errp);
55
+
56
QCryptoBlockOpenOptions *
57
block_crypto_open_opts_init(QDict *opts, Error **errp);
58
59
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
60
index XXXXXXX..XXXXXXX 100644
61
--- a/crypto/blockpriv.h
62
+++ b/crypto/blockpriv.h
63
@@ -XXX,XX +XXX,XX @@ struct QCryptoBlockDriver {
64
void *opaque,
65
Error **errp);
66
67
+ int (*amend)(QCryptoBlock *block,
68
+ QCryptoBlockReadFunc readfunc,
69
+ QCryptoBlockWriteFunc writefunc,
70
+ void *opaque,
71
+ QCryptoBlockAmendOptions *options,
72
+ bool force,
73
+ Error **errp);
74
+
75
int (*get_info)(QCryptoBlock *block,
76
QCryptoBlockInfo *info,
77
Error **errp);
78
diff --git a/include/crypto/block.h b/include/crypto/block.h
79
index XXXXXXX..XXXXXXX 100644
80
--- a/include/crypto/block.h
81
+++ b/include/crypto/block.h
82
@@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
83
void *opaque,
84
Error **errp);
85
86
+/**
87
+ * qcrypto_block_amend_options:
88
+ * @block: the block encryption object
89
+ *
90
+ * @readfunc: callback for reading data from the volume header
91
+ * @writefunc: callback for writing data to the volume header
92
+ * @opaque: data to pass to @readfunc and @writefunc
93
+ * @options: the new/amended encryption options
94
+ * @force: hint for the driver to allow unsafe operation
95
+ * @errp: error pointer
96
+ *
97
+ * Changes the crypto options of the encryption format
98
+ *
99
+ */
100
+int qcrypto_block_amend_options(QCryptoBlock *block,
101
+ QCryptoBlockReadFunc readfunc,
102
+ QCryptoBlockWriteFunc writefunc,
103
+ void *opaque,
104
+ QCryptoBlockAmendOptions *options,
105
+ bool force,
106
+ Error **errp);
107
+
108
109
/**
110
* qcrypto_block_calculate_payload_offset:
111
diff --git a/block/crypto.c b/block/crypto.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/block/crypto.c
114
+++ b/block/crypto.c
115
@@ -XXX,XX +XXX,XX @@ block_crypto_create_opts_init(QDict *opts, Error **errp)
116
return ret;
21
}
117
}
22
118
23
+/*
119
+QCryptoBlockAmendOptions *
24
+ * qemu_io_alloc_from_file()
120
+block_crypto_amend_opts_init(QDict *opts, Error **errp)
25
+ *
26
+ * Allocates the buffer and populates it with the content of the given file
27
+ * up to @len bytes. If the file length is less than @len, then the buffer
28
+ * is populated with the file content cyclically.
29
+ *
30
+ * @blk - the block backend where the buffer content is going to be written to
31
+ * @len - the buffer length
32
+ * @file_name - the file to read the content from
33
+ *
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
+{
121
+{
40
+ char *buf, *buf_origin;
122
+ Visitor *v;
41
+ FILE *f = fopen(file_name, "r");
123
+ QCryptoBlockAmendOptions *ret;
42
+ int pattern_len;
43
+
124
+
44
+ if (!f) {
125
+ v = qobject_input_visitor_new_flat_confused(opts, errp);
45
+ perror(file_name);
126
+ if (!v) {
46
+ return NULL;
127
+ return NULL;
47
+ }
128
+ }
48
+
129
+
49
+ if (qemuio_misalign) {
130
+ visit_type_QCryptoBlockAmendOptions(v, NULL, &ret, errp);
50
+ len += MISALIGN_OFFSET;
131
+
132
+ visit_free(v);
133
+ return ret;
134
+}
135
+
136
137
static int block_crypto_open_generic(QCryptoBlockFormat format,
138
QemuOptsList *opts_spec,
139
diff --git a/crypto/block.c b/crypto/block.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/crypto/block.c
142
+++ b/crypto/block.c
143
@@ -XXX,XX +XXX,XX @@ qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts,
144
return crypto != NULL;
145
}
146
147
+int qcrypto_block_amend_options(QCryptoBlock *block,
148
+ QCryptoBlockReadFunc readfunc,
149
+ QCryptoBlockWriteFunc writefunc,
150
+ void *opaque,
151
+ QCryptoBlockAmendOptions *options,
152
+ bool force,
153
+ Error **errp)
154
+{
155
+ if (options->format != block->format) {
156
+ error_setg(errp,
157
+ "Cannot amend encryption format");
158
+ return -1;
51
+ }
159
+ }
52
+
160
+
53
+ buf_origin = buf = blk_blockalign(blk, len);
161
+ if (!block->driver->amend) {
54
+
162
+ error_setg(errp,
55
+ if (qemuio_misalign) {
163
+ "Crypto format %s doesn't support format options amendment",
56
+ buf_origin += MISALIGN_OFFSET;
164
+ QCryptoBlockFormat_str(block->format));
57
+ buf += MISALIGN_OFFSET;
165
+ return -1;
58
+ len -= MISALIGN_OFFSET;
59
+ }
166
+ }
60
+
167
+
61
+ pattern_len = fread(buf_origin, 1, len, f);
168
+ return block->driver->amend(block,
62
+
169
+ readfunc,
63
+ if (ferror(f)) {
170
+ writefunc,
64
+ perror(file_name);
171
+ opaque,
65
+ goto error;
172
+ options,
66
+ }
173
+ force,
67
+
174
+ errp);
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
+ }
87
+ }
88
+
89
+ return buf_origin;
90
+
91
+error:
92
+ qemu_io_free(buf_origin);
93
+ return NULL;
94
+}
175
+}
95
+
176
96
static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
177
QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
97
{
178
Error **errp)
98
uint64_t i;
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
--
179
--
176
2.21.0
180
2.26.2
177
181
178
182
diff view generated by jsdifflib
1
From: Nir Soffer <nirsof@gmail.com>
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
2
3
When creating an image with preallocation "off" or "falloc", the first
3
Next few patches will expose that functionality to the user.
4
block of the image is typically not allocated. When using Gluster
5
storage backed by XFS filesystem, reading this block using direct I/O
6
succeeds regardless of request length, fooling alignment detection.
7
4
8
In this case we fallback to a safe value (4096) instead of the optimal
5
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
9
value (512), which may lead to unneeded data copying when aligning
6
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
10
requests. Allocating the first block avoids the fallback.
7
Message-Id: <20200608094030.670121-3-mlevitsk@redhat.com>
11
12
Since we allocate the first block even with preallocation=off, we no
13
longer create images with zero disk size:
14
15
$ ./qemu-img create -f raw test.raw 1g
16
Formatting 'test.raw', fmt=raw size=1073741824
17
18
$ ls -lhs test.raw
19
4.0K -rw-r--r--. 1 nsoffer nsoffer 1.0G Aug 16 23:48 test.raw
20
21
And converting the image requires additional cluster:
22
23
$ ./qemu-img measure -f raw -O qcow2 test.raw
24
required size: 458752
25
fully allocated size: 1074135040
26
27
When using format like vmdk with multiple files per image, we allocate
28
one block per file:
29
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>
60
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
61
---
9
---
62
block/file-posix.c | 51 +++++++++++++++++++
10
qapi/crypto.json | 59 ++++++-
63
tests/qemu-iotests/059.out | 2 +-
11
crypto/block-luks.c | 416 +++++++++++++++++++++++++++++++++++++++++++-
64
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
12
2 files changed, 469 insertions(+), 6 deletions(-)
65
tests/qemu-iotests/150.out.raw | 12 +++++
66
tests/qemu-iotests/175 | 19 ++++---
67
tests/qemu-iotests/175.out | 8 +--
68
tests/qemu-iotests/178.out.qcow2 | 4 +-
69
tests/qemu-iotests/221.out | 12 +++--
70
tests/qemu-iotests/253.out | 12 +++--
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
13
75
diff --git a/block/file-posix.c b/block/file-posix.c
14
diff --git a/qapi/crypto.json b/qapi/crypto.json
76
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
77
--- a/block/file-posix.c
16
--- a/qapi/crypto.json
78
+++ b/block/file-posix.c
17
+++ b/qapi/crypto.json
79
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_discard(void *opaque)
18
@@ -XXX,XX +XXX,XX @@
80
return ret;
19
'uuid': 'str',
20
'slots': [ 'QCryptoBlockInfoLUKSSlot' ] }}
21
22
-
23
##
24
# @QCryptoBlockInfo:
25
#
26
@@ -XXX,XX +XXX,XX @@
27
'discriminator': 'format',
28
'data': { 'luks': 'QCryptoBlockInfoLUKS' } }
29
30
+##
31
+# @QCryptoBlockLUKSKeyslotState:
32
+#
33
+# Defines state of keyslots that are affected by the update
34
+#
35
+# @active: The slots contain the given password and marked as active
36
+# @inactive: The slots are erased (contain garbage) and marked as inactive
37
+#
38
+# Since: 5.1
39
+##
40
+{ 'enum': 'QCryptoBlockLUKSKeyslotState',
41
+ 'data': [ 'active', 'inactive' ] }
42
+
43
44
+##
45
+# @QCryptoBlockAmendOptionsLUKS:
46
+#
47
+# This struct defines the update parameters that activate/de-activate set
48
+# of keyslots
49
+#
50
+# @state: the desired state of the keyslots
51
+#
52
+# @new-secret: The ID of a QCryptoSecret object providing the password to be
53
+# written into added active keyslots
54
+#
55
+# @old-secret: Optional (for deactivation only)
56
+# If given will deactive all keyslots that
57
+# match password located in QCryptoSecret with this ID
58
+#
59
+# @iter-time: Optional (for activation only)
60
+# Number of milliseconds to spend in
61
+# PBKDF passphrase processing for the newly activated keyslot.
62
+# Currently defaults to 2000.
63
+#
64
+# @keyslot: Optional. ID of the keyslot to activate/deactivate.
65
+# For keyslot activation, keyslot should not be active already
66
+# (this is unsafe to update an active keyslot),
67
+# but possible if 'force' parameter is given.
68
+# If keyslot is not given, first free keyslot will be written.
69
+#
70
+# For keyslot deactivation, this parameter specifies the exact
71
+# keyslot to deactivate
72
+#
73
+# @secret: Optional. The ID of a QCryptoSecret object providing the
74
+# password to use to retrive current master key.
75
+# Defaults to the same secret that was used to open the image
76
+#
77
+#
78
+# Since 5.1
79
+##
80
+{ 'struct': 'QCryptoBlockAmendOptionsLUKS',
81
+ 'data': { 'state': 'QCryptoBlockLUKSKeyslotState',
82
+ '*new-secret': 'str',
83
+ '*old-secret': 'str',
84
+ '*keyslot': 'int',
85
+ '*iter-time': 'int',
86
+ '*secret': 'str' } }
87
88
##
89
# @QCryptoBlockAmendOptions:
90
@@ -XXX,XX +XXX,XX @@
91
'base': 'QCryptoBlockOptionsBase',
92
'discriminator': 'format',
93
'data': {
94
- } }
95
+ 'luks': 'QCryptoBlockAmendOptionsLUKS' } }
96
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/crypto/block-luks.c
99
+++ b/crypto/block-luks.c
100
@@ -XXX,XX +XXX,XX @@
101
#include "qemu/uuid.h"
102
103
#include "qemu/coroutine.h"
104
+#include "qemu/bitmap.h"
105
106
/*
107
* Reference for the LUKS format implemented here is
108
@@ -XXX,XX +XXX,XX @@ typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot;
109
110
#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL
111
112
+#define QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS 2000
113
+#define QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS 40
114
+
115
static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = {
116
'L', 'U', 'K', 'S', 0xBA, 0xBE
117
};
118
@@ -XXX,XX +XXX,XX @@ struct QCryptoBlockLUKS {
119
120
/* Hash algorithm used in pbkdf2 function */
121
QCryptoHashAlgorithm hash_alg;
122
+
123
+ /* Name of the secret that was used to open the image */
124
+ char *secret;
125
};
126
127
128
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_store_key(QCryptoBlock *block,
129
Error **errp)
130
{
131
QCryptoBlockLUKS *luks = block->opaque;
132
- QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx];
133
+ QCryptoBlockLUKSKeySlot *slot;
134
g_autofree uint8_t *splitkey = NULL;
135
size_t splitkeylen;
136
g_autofree uint8_t *slotkey = NULL;
137
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_store_key(QCryptoBlock *block,
138
uint64_t iters;
139
int ret = -1;
140
141
+ assert(slot_idx < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
142
+ slot = &luks->header.key_slots[slot_idx];
143
if (qcrypto_random_bytes(slot->salt,
144
QCRYPTO_BLOCK_LUKS_SALT_LEN,
145
errp) < 0) {
146
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_load_key(QCryptoBlock *block,
147
Error **errp)
148
{
149
QCryptoBlockLUKS *luks = block->opaque;
150
- const QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx];
151
+ const QCryptoBlockLUKSKeySlot *slot;
152
g_autofree uint8_t *splitkey = NULL;
153
size_t splitkeylen;
154
g_autofree uint8_t *possiblekey = NULL;
155
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_load_key(QCryptoBlock *block,
156
g_autoptr(QCryptoIVGen) ivgen = NULL;
157
size_t niv;
158
159
+ assert(slot_idx < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
160
+ slot = &luks->header.key_slots[slot_idx];
161
if (slot->active != QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED) {
162
return 0;
163
}
164
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_find_key(QCryptoBlock *block,
165
return -1;
81
}
166
}
82
167
83
+/*
168
+/*
84
+ * Help alignment probing by allocating the first block.
169
+ * Returns true if a slot i is marked as active
85
+ *
170
+ * (contains encrypted copy of the master key)
86
+ * When reading with direct I/O from unallocated area on Gluster backed by XFS,
87
+ * reading succeeds regardless of request length. In this case we fallback to
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
+ */
171
+ */
97
+static int allocate_first_block(int fd, size_t max_size)
172
+static bool
173
+qcrypto_block_luks_slot_active(const QCryptoBlockLUKS *luks,
174
+ unsigned int slot_idx)
98
+{
175
+{
99
+ size_t write_size = (max_size < MAX_BLOCKSIZE)
176
+ uint32_t val;
100
+ ? BDRV_SECTOR_SIZE
177
+
101
+ : MAX_BLOCKSIZE;
178
+ assert(slot_idx < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
102
+ size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize());
179
+ val = luks->header.key_slots[slot_idx].active;
103
+ void *buf;
180
+ return val == QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED;
104
+ ssize_t n;
181
+}
105
+ int ret;
182
+
106
+
183
+/*
107
+ buf = qemu_memalign(max_align, write_size);
184
+ * Returns the number of slots that are marked as active
108
+ memset(buf, 0, write_size);
185
+ * (slots that contain encrypted copy of the master key)
109
+
186
+ */
110
+ do {
187
+static unsigned int
111
+ n = pwrite(fd, buf, write_size, 0);
188
+qcrypto_block_luks_count_active_slots(const QCryptoBlockLUKS *luks)
112
+ } while (n == -1 && errno == EINTR);
189
+{
113
+
190
+ size_t i = 0;
114
+ ret = (n == -1) ? -errno : 0;
191
+ unsigned int ret = 0;
115
+
192
+
116
+ qemu_vfree(buf);
193
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
194
+ if (qcrypto_block_luks_slot_active(luks, i)) {
195
+ ret++;
196
+ }
197
+ }
117
+ return ret;
198
+ return ret;
118
+}
199
+}
119
+
200
+
120
static int handle_aiocb_truncate(void *opaque)
201
+/*
202
+ * Finds first key slot which is not active
203
+ * Returns the key slot index, or -1 if it doesn't exist
204
+ */
205
+static int
206
+qcrypto_block_luks_find_free_keyslot(const QCryptoBlockLUKS *luks)
207
+{
208
+ size_t i;
209
+
210
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
211
+ if (!qcrypto_block_luks_slot_active(luks, i)) {
212
+ return i;
213
+ }
214
+ }
215
+ return -1;
216
+}
217
+
218
+/*
219
+ * Erases an keyslot given its index
220
+ * Returns:
221
+ * 0 if the keyslot was erased successfully
222
+ * -1 if a error occurred while erasing the keyslot
223
+ *
224
+ */
225
+static int
226
+qcrypto_block_luks_erase_key(QCryptoBlock *block,
227
+ unsigned int slot_idx,
228
+ QCryptoBlockWriteFunc writefunc,
229
+ void *opaque,
230
+ Error **errp)
231
+{
232
+ QCryptoBlockLUKS *luks = block->opaque;
233
+ QCryptoBlockLUKSKeySlot *slot;
234
+ g_autofree uint8_t *garbagesplitkey = NULL;
235
+ size_t splitkeylen;
236
+ size_t i;
237
+ Error *local_err = NULL;
238
+ int ret;
239
+
240
+ assert(slot_idx < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
241
+ slot = &luks->header.key_slots[slot_idx];
242
+
243
+ splitkeylen = luks->header.master_key_len * slot->stripes;
244
+ assert(splitkeylen > 0);
245
+
246
+ garbagesplitkey = g_new0(uint8_t, splitkeylen);
247
+
248
+ /* Reset the key slot header */
249
+ memset(slot->salt, 0, QCRYPTO_BLOCK_LUKS_SALT_LEN);
250
+ slot->iterations = 0;
251
+ slot->active = QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED;
252
+
253
+ ret = qcrypto_block_luks_store_header(block, writefunc,
254
+ opaque, &local_err);
255
+
256
+ if (ret < 0) {
257
+ error_propagate(errp, local_err);
258
+ }
259
+ /*
260
+ * Now try to erase the key material, even if the header
261
+ * update failed
262
+ */
263
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS; i++) {
264
+ if (qcrypto_random_bytes(garbagesplitkey,
265
+ splitkeylen, &local_err) < 0) {
266
+ /*
267
+ * If we failed to get the random data, still write
268
+ * at least zeros to the key slot at least once
269
+ */
270
+ error_propagate(errp, local_err);
271
+
272
+ if (i > 0) {
273
+ return -1;
274
+ }
275
+ }
276
+ if (writefunc(block,
277
+ slot->key_offset_sector * QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
278
+ garbagesplitkey,
279
+ splitkeylen,
280
+ opaque,
281
+ &local_err) != splitkeylen) {
282
+ error_propagate(errp, local_err);
283
+ return -1;
284
+ }
285
+ }
286
+ return ret;
287
+}
288
289
static int
290
qcrypto_block_luks_open(QCryptoBlock *block,
291
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_open(QCryptoBlock *block,
292
293
luks = g_new0(QCryptoBlockLUKS, 1);
294
block->opaque = luks;
295
+ luks->secret = g_strdup(options->u.luks.key_secret);
296
297
if (qcrypto_block_luks_load_header(block, readfunc, opaque, errp) < 0) {
298
goto fail;
299
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_open(QCryptoBlock *block,
300
fail:
301
qcrypto_block_free_cipher(block);
302
qcrypto_ivgen_free(block->ivgen);
303
+ g_free(luks->secret);
304
g_free(luks);
305
return -1;
306
}
307
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block,
308
309
memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts));
310
if (!luks_opts.has_iter_time) {
311
- luks_opts.iter_time = 2000;
312
+ luks_opts.iter_time = QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS;
313
}
314
if (!luks_opts.has_cipher_alg) {
315
luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256;
316
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block,
317
optprefix ? optprefix : "");
318
goto error;
319
}
320
+ luks->secret = g_strdup(options->u.luks.key_secret);
321
+
322
password = qcrypto_secret_lookup_as_utf8(luks_opts.key_secret, errp);
323
if (!password) {
324
goto error;
325
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block,
326
qcrypto_block_free_cipher(block);
327
qcrypto_ivgen_free(block->ivgen);
328
329
+ g_free(luks->secret);
330
g_free(luks);
331
return -1;
332
}
333
334
+static int
335
+qcrypto_block_luks_amend_add_keyslot(QCryptoBlock *block,
336
+ QCryptoBlockReadFunc readfunc,
337
+ QCryptoBlockWriteFunc writefunc,
338
+ void *opaque,
339
+ QCryptoBlockAmendOptionsLUKS *opts_luks,
340
+ bool force,
341
+ Error **errp)
342
+{
343
+ QCryptoBlockLUKS *luks = block->opaque;
344
+ uint64_t iter_time = opts_luks->has_iter_time ?
345
+ opts_luks->iter_time :
346
+ QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS;
347
+ int keyslot;
348
+ g_autofree char *old_password = NULL;
349
+ g_autofree char *new_password = NULL;
350
+ g_autofree uint8_t *master_key = NULL;
351
+
352
+ char *secret = opts_luks->has_secret ? opts_luks->secret : luks->secret;
353
+
354
+ if (!opts_luks->has_new_secret) {
355
+ error_setg(errp, "'new-secret' is required to activate a keyslot");
356
+ return -1;
357
+ }
358
+ if (opts_luks->has_old_secret) {
359
+ error_setg(errp,
360
+ "'old-secret' must not be given when activating keyslots");
361
+ return -1;
362
+ }
363
+
364
+ if (opts_luks->has_keyslot) {
365
+ keyslot = opts_luks->keyslot;
366
+ if (keyslot < 0 || keyslot >= QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS) {
367
+ error_setg(errp,
368
+ "Invalid keyslot %u specified, must be between 0 and %u",
369
+ keyslot, QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS - 1);
370
+ return -1;
371
+ }
372
+ } else {
373
+ keyslot = qcrypto_block_luks_find_free_keyslot(luks);
374
+ if (keyslot == -1) {
375
+ error_setg(errp,
376
+ "Can't add a keyslot - all keyslots are in use");
377
+ return -1;
378
+ }
379
+ }
380
+
381
+ if (!force && qcrypto_block_luks_slot_active(luks, keyslot)) {
382
+ error_setg(errp,
383
+ "Refusing to overwrite active keyslot %i - "
384
+ "please erase it first",
385
+ keyslot);
386
+ return -1;
387
+ }
388
+
389
+ /* Locate the password that will be used to retrieve the master key */
390
+ old_password = qcrypto_secret_lookup_as_utf8(secret, errp);
391
+ if (!old_password) {
392
+ return -1;
393
+ }
394
+
395
+ /* Retrieve the master key */
396
+ master_key = g_new0(uint8_t, luks->header.master_key_len);
397
+
398
+ if (qcrypto_block_luks_find_key(block, old_password, master_key,
399
+ readfunc, opaque, errp) < 0) {
400
+ error_append_hint(errp, "Failed to retrieve the master key");
401
+ return -1;
402
+ }
403
+
404
+ /* Locate the new password*/
405
+ new_password = qcrypto_secret_lookup_as_utf8(opts_luks->new_secret, errp);
406
+ if (!new_password) {
407
+ return -1;
408
+ }
409
+
410
+ /* Now set the new keyslots */
411
+ if (qcrypto_block_luks_store_key(block, keyslot, new_password, master_key,
412
+ iter_time, writefunc, opaque, errp)) {
413
+ error_append_hint(errp, "Failed to write to keyslot %i", keyslot);
414
+ return -1;
415
+ }
416
+ return 0;
417
+}
418
+
419
+static int
420
+qcrypto_block_luks_amend_erase_keyslots(QCryptoBlock *block,
421
+ QCryptoBlockReadFunc readfunc,
422
+ QCryptoBlockWriteFunc writefunc,
423
+ void *opaque,
424
+ QCryptoBlockAmendOptionsLUKS *opts_luks,
425
+ bool force,
426
+ Error **errp)
427
+{
428
+ QCryptoBlockLUKS *luks = block->opaque;
429
+ g_autofree uint8_t *tmpkey = NULL;
430
+ g_autofree char *old_password = NULL;
431
+
432
+ if (opts_luks->has_new_secret) {
433
+ error_setg(errp,
434
+ "'new-secret' must not be given when erasing keyslots");
435
+ return -1;
436
+ }
437
+ if (opts_luks->has_iter_time) {
438
+ error_setg(errp,
439
+ "'iter-time' must not be given when erasing keyslots");
440
+ return -1;
441
+ }
442
+ if (opts_luks->has_secret) {
443
+ error_setg(errp,
444
+ "'secret' must not be given when erasing keyslots");
445
+ return -1;
446
+ }
447
+
448
+ /* Load the old password if given */
449
+ if (opts_luks->has_old_secret) {
450
+ old_password = qcrypto_secret_lookup_as_utf8(opts_luks->old_secret,
451
+ errp);
452
+ if (!old_password) {
453
+ return -1;
454
+ }
455
+
456
+ /*
457
+ * Allocate a temporary key buffer that we will need when
458
+ * checking if slot matches the given old password
459
+ */
460
+ tmpkey = g_new0(uint8_t, luks->header.master_key_len);
461
+ }
462
+
463
+ /* Erase an explicitly given keyslot */
464
+ if (opts_luks->has_keyslot) {
465
+ int keyslot = opts_luks->keyslot;
466
+
467
+ if (keyslot < 0 || keyslot >= QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS) {
468
+ error_setg(errp,
469
+ "Invalid keyslot %i specified, must be between 0 and %i",
470
+ keyslot, QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS - 1);
471
+ return -1;
472
+ }
473
+
474
+ if (opts_luks->has_old_secret) {
475
+ int rv = qcrypto_block_luks_load_key(block,
476
+ keyslot,
477
+ old_password,
478
+ tmpkey,
479
+ readfunc,
480
+ opaque,
481
+ errp);
482
+ if (rv == -1) {
483
+ return -1;
484
+ } else if (rv == 0) {
485
+ error_setg(errp,
486
+ "Given keyslot %i doesn't contain the given "
487
+ "old password for erase operation",
488
+ keyslot);
489
+ return -1;
490
+ }
491
+ }
492
+
493
+ if (!force && !qcrypto_block_luks_slot_active(luks, keyslot)) {
494
+ error_setg(errp,
495
+ "Given keyslot %i is already erased (inactive) ",
496
+ keyslot);
497
+ return -1;
498
+ }
499
+
500
+ if (!force && qcrypto_block_luks_count_active_slots(luks) == 1) {
501
+ error_setg(errp,
502
+ "Attempt to erase the only active keyslot %i "
503
+ "which will erase all the data in the image "
504
+ "irreversibly - refusing operation",
505
+ keyslot);
506
+ return -1;
507
+ }
508
+
509
+ if (qcrypto_block_luks_erase_key(block, keyslot,
510
+ writefunc, opaque, errp)) {
511
+ error_append_hint(errp, "Failed to erase keyslot %i", keyslot);
512
+ return -1;
513
+ }
514
+
515
+ /* Erase all keyslots that match the given old password */
516
+ } else if (opts_luks->has_old_secret) {
517
+
518
+ unsigned long slots_to_erase_bitmap = 0;
519
+ size_t i;
520
+ int slot_count;
521
+
522
+ assert(QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS <=
523
+ sizeof(slots_to_erase_bitmap) * 8);
524
+
525
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
526
+ int rv = qcrypto_block_luks_load_key(block,
527
+ i,
528
+ old_password,
529
+ tmpkey,
530
+ readfunc,
531
+ opaque,
532
+ errp);
533
+ if (rv == -1) {
534
+ return -1;
535
+ } else if (rv == 1) {
536
+ bitmap_set(&slots_to_erase_bitmap, i, 1);
537
+ }
538
+ }
539
+
540
+ slot_count = bitmap_count_one(&slots_to_erase_bitmap,
541
+ QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
542
+ if (slot_count == 0) {
543
+ error_setg(errp,
544
+ "No keyslots match given (old) password for erase operation");
545
+ return -1;
546
+ }
547
+
548
+ if (!force &&
549
+ slot_count == qcrypto_block_luks_count_active_slots(luks)) {
550
+ error_setg(errp,
551
+ "All the active keyslots match the (old) password that "
552
+ "was given and erasing them will erase all the data in "
553
+ "the image irreversibly - refusing operation");
554
+ return -1;
555
+ }
556
+
557
+ /* Now apply the update */
558
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
559
+ if (!test_bit(i, &slots_to_erase_bitmap)) {
560
+ continue;
561
+ }
562
+ if (qcrypto_block_luks_erase_key(block, i, writefunc,
563
+ opaque, errp)) {
564
+ error_append_hint(errp, "Failed to erase keyslot %zu", i);
565
+ return -1;
566
+ }
567
+ }
568
+ } else {
569
+ error_setg(errp,
570
+ "To erase keyslot(s), either explicit keyslot index "
571
+ "or the password currently contained in them must be given");
572
+ return -1;
573
+ }
574
+ return 0;
575
+}
576
+
577
+static int
578
+qcrypto_block_luks_amend_options(QCryptoBlock *block,
579
+ QCryptoBlockReadFunc readfunc,
580
+ QCryptoBlockWriteFunc writefunc,
581
+ void *opaque,
582
+ QCryptoBlockAmendOptions *options,
583
+ bool force,
584
+ Error **errp)
585
+{
586
+ QCryptoBlockAmendOptionsLUKS *opts_luks = &options->u.luks;
587
+
588
+ switch (opts_luks->state) {
589
+ case Q_CRYPTO_BLOCKLUKS_KEYSLOT_STATE_ACTIVE:
590
+ return qcrypto_block_luks_amend_add_keyslot(block, readfunc,
591
+ writefunc, opaque,
592
+ opts_luks, force, errp);
593
+ case Q_CRYPTO_BLOCKLUKS_KEYSLOT_STATE_INACTIVE:
594
+ return qcrypto_block_luks_amend_erase_keyslots(block, readfunc,
595
+ writefunc, opaque,
596
+ opts_luks, force, errp);
597
+ default:
598
+ g_assert_not_reached();
599
+ }
600
+}
601
602
static int qcrypto_block_luks_get_info(QCryptoBlock *block,
603
QCryptoBlockInfo *info,
604
@@ -XXX,XX +XXX,XX @@ static int qcrypto_block_luks_get_info(QCryptoBlock *block,
605
606
static void qcrypto_block_luks_cleanup(QCryptoBlock *block)
121
{
607
{
122
RawPosixAIOData *aiocb = opaque;
608
- g_free(block->opaque);
123
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(void *opaque)
609
+ QCryptoBlockLUKS *luks = block->opaque;
124
/* posix_fallocate() doesn't set errno. */
610
+ if (luks) {
125
error_setg_errno(errp, -result,
611
+ g_free(luks->secret);
126
"Could not preallocate new data");
612
+ g_free(luks);
127
+ } else if (current_length == 0) {
613
+ }
128
+ /*
129
+ * posix_fallocate() uses fallocate() if the filesystem
130
+ * supports it, or fallback to manually writing zeroes. If
131
+ * fallocate() was used, unaligned reads from the fallocated
132
+ * area in raw_probe_alignment() will succeed, hence we need to
133
+ * allocate the first block.
134
+ *
135
+ * Optimize future alignment probing; ignore failures.
136
+ */
137
+ allocate_first_block(fd, offset);
138
}
139
} else {
140
result = 0;
141
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(void *opaque)
142
if (ftruncate(fd, offset) != 0) {
143
result = -errno;
144
error_setg_errno(errp, -result, "Could not resize file");
145
+ } else if (current_length == 0 && offset > current_length) {
146
+ /* Optimize future alignment probing; ignore failures. */
147
+ allocate_first_block(fd, offset);
148
}
149
return result;
150
default:
151
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
152
index XXXXXXX..XXXXXXX 100644
153
--- a/tests/qemu-iotests/059.out
154
+++ b/tests/qemu-iotests/059.out
155
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMax
156
image: TEST_DIR/t.vmdk
157
file format: vmdk
158
virtual size: 0.977 TiB (1073741824000 bytes)
159
-disk size: 16 KiB
160
+disk size: 1.97 MiB
161
Format specific information:
162
cid: XXXXXXXX
163
parent cid: XXXXXXXX
164
diff --git a/tests/qemu-iotests/150.out b/tests/qemu-iotests/150.out.qcow2
165
similarity index 100%
166
rename from tests/qemu-iotests/150.out
167
rename to tests/qemu-iotests/150.out.qcow2
168
diff --git a/tests/qemu-iotests/150.out.raw b/tests/qemu-iotests/150.out.raw
169
new file mode 100644
170
index XXXXXXX..XXXXXXX
171
--- /dev/null
172
+++ b/tests/qemu-iotests/150.out.raw
173
@@ -XXX,XX +XXX,XX @@
174
+QA output created by 150
175
+
176
+=== Mapping sparse conversion ===
177
+
178
+Offset Length File
179
+0 0x1000 TEST_DIR/t.IMGFMT
180
+
181
+=== Mapping non-sparse conversion ===
182
+
183
+Offset Length File
184
+0 0x100000 TEST_DIR/t.IMGFMT
185
+*** done
186
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
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
}
614
}
209
615
210
# get standard environment, filters and checks
616
211
@@ -XXX,XX +XXX,XX @@ size=$((1 * 1024 * 1024))
617
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_encrypt(QCryptoBlock *block,
212
touch "$TEST_DIR/empty"
618
const QCryptoBlockDriver qcrypto_block_driver_luks = {
213
extra_blocks=$(stat -c '%b' "$TEST_DIR/empty")
619
.open = qcrypto_block_luks_open,
214
620
.create = qcrypto_block_luks_create,
215
+# We always write the first byte; check how many blocks this filesystem
621
+ .amend = qcrypto_block_luks_amend_options,
216
+# allocates to match empty image alloation.
622
.get_info = qcrypto_block_luks_get_info,
217
+printf "\0" > "$TEST_DIR/empty"
623
.cleanup = qcrypto_block_luks_cleanup,
218
+min_blocks=$(stat -c '%b' "$TEST_DIR/empty")
624
.decrypt = qcrypto_block_luks_decrypt,
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
237
--- a/tests/qemu-iotests/175.out
238
+++ b/tests/qemu-iotests/175.out
239
@@ -XXX,XX +XXX,XX @@ QA output created by 175
240
241
== creating image with default preallocation ==
242
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
243
-size=1048576, nothing allocated
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
--
625
--
336
2.21.0
626
2.26.2
337
627
338
628
diff view generated by jsdifflib
New patch
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
2
3
'force' option will be used for some unsafe amend operations.
4
5
This includes things like erasing last keyslot in luks based formats
6
(which destroys the data, unless the master key is backed up
7
by external means), but that _might_ be desired result.
8
9
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
10
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20200608094030.670121-4-mlevitsk@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
docs/tools/qemu-img.rst | 5 ++++-
16
include/block/block.h | 1 +
17
include/block/block_int.h | 1 +
18
block.c | 4 +++-
19
block/qcow2.c | 1 +
20
qemu-img.c | 8 +++++++-
21
qemu-img-cmds.hx | 4 ++--
22
7 files changed, 19 insertions(+), 5 deletions(-)
23
24
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
25
index XXXXXXX..XXXXXXX 100644
26
--- a/docs/tools/qemu-img.rst
27
+++ b/docs/tools/qemu-img.rst
28
@@ -XXX,XX +XXX,XX @@ Command description:
29
30
.. program:: qemu-img-commands
31
32
-.. option:: amend [--object OBJECTDEF] [--image-opts] [-p] [-q] [-f FMT] [-t CACHE] -o OPTIONS FILENAME
33
+.. option:: amend [--object OBJECTDEF] [--image-opts] [-p] [-q] [-f FMT] [-t CACHE] [--force] -o OPTIONS FILENAME
34
35
Amends the image format specific *OPTIONS* for the image file
36
*FILENAME*. Not all file formats support this operation.
37
38
+ --force allows some unsafe operations. Currently for -f luks, it allows to
39
+ erase the last encryption key, and to overwrite an active encryption key.
40
+
41
.. option:: bench [-c COUNT] [-d DEPTH] [-f FMT] [--flush-interval=FLUSH_INTERVAL] [-i AIO] [-n] [--no-drain] [-o OFFSET] [--pattern=PATTERN] [-q] [-s BUFFER_SIZE] [-S STEP_SIZE] [-t CACHE] [-w] [-U] FILENAME
42
43
Run a simple sequential I/O benchmark on the specified image. If ``-w`` is
44
diff --git a/include/block/block.h b/include/block/block.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/block/block.h
47
+++ b/include/block/block.h
48
@@ -XXX,XX +XXX,XX @@ typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset,
49
int64_t total_work_size, void *opaque);
50
int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
51
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
52
+ bool force,
53
Error **errp);
54
55
/* check if a named node can be replaced when doing drive-mirror */
56
diff --git a/include/block/block_int.h b/include/block/block_int.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/block/block_int.h
59
+++ b/include/block/block_int.h
60
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
61
int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
62
BlockDriverAmendStatusCB *status_cb,
63
void *cb_opaque,
64
+ bool force,
65
Error **errp);
66
67
void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
68
diff --git a/block.c b/block.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/block.c
71
+++ b/block.c
72
@@ -XXX,XX +XXX,XX @@ void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
73
74
int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts,
75
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
76
+ bool force,
77
Error **errp)
78
{
79
if (!bs->drv) {
80
@@ -XXX,XX +XXX,XX @@ int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts,
81
bs->drv->format_name);
82
return -ENOTSUP;
83
}
84
- return bs->drv->bdrv_amend_options(bs, opts, status_cb, cb_opaque, errp);
85
+ return bs->drv->bdrv_amend_options(bs, opts, status_cb,
86
+ cb_opaque, force, errp);
87
}
88
89
/*
90
diff --git a/block/qcow2.c b/block/qcow2.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/block/qcow2.c
93
+++ b/block/qcow2.c
94
@@ -XXX,XX +XXX,XX @@ static void qcow2_amend_helper_cb(BlockDriverState *bs,
95
static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
96
BlockDriverAmendStatusCB *status_cb,
97
void *cb_opaque,
98
+ bool force,
99
Error **errp)
100
{
101
BDRVQcow2State *s = bs->opaque;
102
diff --git a/qemu-img.c b/qemu-img.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/qemu-img.c
105
+++ b/qemu-img.c
106
@@ -XXX,XX +XXX,XX @@ enum {
107
OPTION_DISABLE = 273,
108
OPTION_MERGE = 274,
109
OPTION_BITMAPS = 275,
110
+ OPTION_FORCE = 276,
111
};
112
113
typedef enum OutputFormat {
114
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
115
BlockBackend *blk = NULL;
116
BlockDriverState *bs = NULL;
117
bool image_opts = false;
118
+ bool force = false;
119
120
cache = BDRV_DEFAULT_CACHE;
121
for (;;) {
122
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
123
{"help", no_argument, 0, 'h'},
124
{"object", required_argument, 0, OPTION_OBJECT},
125
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
126
+ {"force", no_argument, 0, OPTION_FORCE},
127
{0, 0, 0, 0}
128
};
129
c = getopt_long(argc, argv, ":ho:f:t:pq",
130
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
131
case OPTION_IMAGE_OPTS:
132
image_opts = true;
133
break;
134
+ case OPTION_FORCE:
135
+ force = true;
136
+ break;
137
}
138
}
139
140
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
141
142
/* In case the driver does not call amend_status_cb() */
143
qemu_progress_print(0.f, 0);
144
- ret = bdrv_amend_options(bs, opts, &amend_status_cb, NULL, &err);
145
+ ret = bdrv_amend_options(bs, opts, &amend_status_cb, NULL, force, &err);
146
qemu_progress_print(100.f, 0);
147
if (ret < 0) {
148
error_report_err(err);
149
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
150
index XXXXXXX..XXXXXXX 100644
151
--- a/qemu-img-cmds.hx
152
+++ b/qemu-img-cmds.hx
153
@@ -XXX,XX +XXX,XX @@ HXCOMM When amending the rST sections, please remember to copy the usage
154
HXCOMM over to the per-command sections in docs/tools/qemu-img.rst.
155
156
DEF("amend", img_amend,
157
- "amend [--object objectdef] [--image-opts] [-p] [-q] [-f fmt] [-t cache] -o options filename")
158
+ "amend [--object objectdef] [--image-opts] [-p] [-q] [-f fmt] [-t cache] [--force] -o options filename")
159
SRST
160
-.. option:: amend [--object OBJECTDEF] [--image-opts] [-p] [-q] [-f FMT] [-t CACHE] -o OPTIONS FILENAME
161
+.. option:: amend [--object OBJECTDEF] [--image-opts] [-p] [-q] [-f FMT] [-t CACHE] [--force] -o OPTIONS FILENAME
162
ERST
163
164
DEF("bench", img_bench,
165
--
166
2.26.2
167
168
diff view generated by jsdifflib
New patch
1
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
3
Some options are only useful for creation
4
(or hard to be amended, like cluster size for qcow2), while some other
5
options are only useful for amend, like upcoming keyslot management
6
options for luks
7
8
Since currently only qcow2 supports amend, move all its options
9
to a common macro and then include it in each action option list.
10
11
In future it might be useful to remove some options which are
12
not supported anyway from amend list, which currently
13
cause an error message if amended.
14
15
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
16
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
17
Reviewed-by: Max Reitz <mreitz@redhat.com>
18
Message-Id: <20200608094030.670121-5-mlevitsk@redhat.com>
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
20
---
21
include/block/block_int.h | 4 +
22
block/qcow2.c | 173 +++++++++++++++++++++-----------------
23
qemu-img.c | 18 ++--
24
3 files changed, 107 insertions(+), 88 deletions(-)
25
26
diff --git a/include/block/block_int.h b/include/block/block_int.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/block/block_int.h
29
+++ b/include/block/block_int.h
30
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
31
32
/* List of options for creating images, terminated by name == NULL */
33
QemuOptsList *create_opts;
34
+
35
+ /* List of options for image amend */
36
+ QemuOptsList *amend_opts;
37
+
38
/*
39
* If this driver supports reopening images this contains a
40
* NULL-terminated list of the runtime options that can be
41
diff --git a/block/qcow2.c b/block/qcow2.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block/qcow2.c
44
+++ b/block/qcow2.c
45
@@ -XXX,XX +XXX,XX @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
46
s->signaled_corruption = true;
47
}
48
49
+#define QCOW_COMMON_OPTIONS \
50
+ { \
51
+ .name = BLOCK_OPT_SIZE, \
52
+ .type = QEMU_OPT_SIZE, \
53
+ .help = "Virtual disk size" \
54
+ }, \
55
+ { \
56
+ .name = BLOCK_OPT_COMPAT_LEVEL, \
57
+ .type = QEMU_OPT_STRING, \
58
+ .help = "Compatibility level (v2 [0.10] or v3 [1.1])" \
59
+ }, \
60
+ { \
61
+ .name = BLOCK_OPT_BACKING_FILE, \
62
+ .type = QEMU_OPT_STRING, \
63
+ .help = "File name of a base image" \
64
+ }, \
65
+ { \
66
+ .name = BLOCK_OPT_BACKING_FMT, \
67
+ .type = QEMU_OPT_STRING, \
68
+ .help = "Image format of the base image" \
69
+ }, \
70
+ { \
71
+ .name = BLOCK_OPT_DATA_FILE, \
72
+ .type = QEMU_OPT_STRING, \
73
+ .help = "File name of an external data file" \
74
+ }, \
75
+ { \
76
+ .name = BLOCK_OPT_DATA_FILE_RAW, \
77
+ .type = QEMU_OPT_BOOL, \
78
+ .help = "The external data file must stay valid " \
79
+ "as a raw image" \
80
+ }, \
81
+ { \
82
+ .name = BLOCK_OPT_ENCRYPT, \
83
+ .type = QEMU_OPT_BOOL, \
84
+ .help = "Encrypt the image with format 'aes'. (Deprecated " \
85
+ "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", \
86
+ }, \
87
+ { \
88
+ .name = BLOCK_OPT_ENCRYPT_FORMAT, \
89
+ .type = QEMU_OPT_STRING, \
90
+ .help = "Encrypt the image, format choices: 'aes', 'luks'", \
91
+ }, \
92
+ BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", \
93
+ "ID of secret providing qcow AES key or LUKS passphrase"), \
94
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."), \
95
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."), \
96
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."), \
97
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."), \
98
+ BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."), \
99
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."), \
100
+ { \
101
+ .name = BLOCK_OPT_CLUSTER_SIZE, \
102
+ .type = QEMU_OPT_SIZE, \
103
+ .help = "qcow2 cluster size", \
104
+ .def_value_str = stringify(DEFAULT_CLUSTER_SIZE) \
105
+ }, \
106
+ { \
107
+ .name = BLOCK_OPT_PREALLOC, \
108
+ .type = QEMU_OPT_STRING, \
109
+ .help = "Preallocation mode (allowed values: off, " \
110
+ "metadata, falloc, full)" \
111
+ }, \
112
+ { \
113
+ .name = BLOCK_OPT_LAZY_REFCOUNTS, \
114
+ .type = QEMU_OPT_BOOL, \
115
+ .help = "Postpone refcount updates", \
116
+ .def_value_str = "off" \
117
+ }, \
118
+ { \
119
+ .name = BLOCK_OPT_REFCOUNT_BITS, \
120
+ .type = QEMU_OPT_NUMBER, \
121
+ .help = "Width of a reference count entry in bits", \
122
+ .def_value_str = "16" \
123
+ }, \
124
+ { \
125
+ .name = BLOCK_OPT_COMPRESSION_TYPE, \
126
+ .type = QEMU_OPT_STRING, \
127
+ .help = "Compression method used for image cluster " \
128
+ "compression", \
129
+ .def_value_str = "zlib" \
130
+ }
131
+
132
static QemuOptsList qcow2_create_opts = {
133
.name = "qcow2-create-opts",
134
.head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
135
.desc = {
136
- {
137
- .name = BLOCK_OPT_SIZE,
138
- .type = QEMU_OPT_SIZE,
139
- .help = "Virtual disk size"
140
- },
141
- {
142
- .name = BLOCK_OPT_COMPAT_LEVEL,
143
- .type = QEMU_OPT_STRING,
144
- .help = "Compatibility level (v2 [0.10] or v3 [1.1])"
145
- },
146
- {
147
- .name = BLOCK_OPT_BACKING_FILE,
148
- .type = QEMU_OPT_STRING,
149
- .help = "File name of a base image"
150
- },
151
- {
152
- .name = BLOCK_OPT_BACKING_FMT,
153
- .type = QEMU_OPT_STRING,
154
- .help = "Image format of the base image"
155
- },
156
- {
157
- .name = BLOCK_OPT_DATA_FILE,
158
- .type = QEMU_OPT_STRING,
159
- .help = "File name of an external data file"
160
- },
161
- {
162
- .name = BLOCK_OPT_DATA_FILE_RAW,
163
- .type = QEMU_OPT_BOOL,
164
- .help = "The external data file must stay valid as a raw image"
165
- },
166
- {
167
- .name = BLOCK_OPT_ENCRYPT,
168
- .type = QEMU_OPT_BOOL,
169
- .help = "Encrypt the image with format 'aes'. (Deprecated "
170
- "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)",
171
- },
172
- {
173
- .name = BLOCK_OPT_ENCRYPT_FORMAT,
174
- .type = QEMU_OPT_STRING,
175
- .help = "Encrypt the image, format choices: 'aes', 'luks'",
176
- },
177
- BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.",
178
- "ID of secret providing qcow AES key or LUKS passphrase"),
179
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."),
180
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."),
181
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."),
182
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."),
183
- BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."),
184
- BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."),
185
- {
186
- .name = BLOCK_OPT_CLUSTER_SIZE,
187
- .type = QEMU_OPT_SIZE,
188
- .help = "qcow2 cluster size",
189
- .def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
190
- },
191
- {
192
- .name = BLOCK_OPT_PREALLOC,
193
- .type = QEMU_OPT_STRING,
194
- .help = "Preallocation mode (allowed values: off, metadata, "
195
- "falloc, full)"
196
- },
197
- {
198
- .name = BLOCK_OPT_LAZY_REFCOUNTS,
199
- .type = QEMU_OPT_BOOL,
200
- .help = "Postpone refcount updates",
201
- .def_value_str = "off"
202
- },
203
- {
204
- .name = BLOCK_OPT_REFCOUNT_BITS,
205
- .type = QEMU_OPT_NUMBER,
206
- .help = "Width of a reference count entry in bits",
207
- .def_value_str = "16"
208
- },
209
- {
210
- .name = BLOCK_OPT_COMPRESSION_TYPE,
211
- .type = QEMU_OPT_STRING,
212
- .help = "Compression method used for image cluster compression",
213
- .def_value_str = "zlib"
214
- },
215
+ QCOW_COMMON_OPTIONS,
216
+ { /* end of list */ }
217
+ }
218
+};
219
+
220
+static QemuOptsList qcow2_amend_opts = {
221
+ .name = "qcow2-amend-opts",
222
+ .head = QTAILQ_HEAD_INITIALIZER(qcow2_amend_opts.head),
223
+ .desc = {
224
+ QCOW_COMMON_OPTIONS,
225
{ /* end of list */ }
226
}
227
};
228
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
229
.bdrv_inactivate = qcow2_inactivate,
230
231
.create_opts = &qcow2_create_opts,
232
+ .amend_opts = &qcow2_amend_opts,
233
.strong_runtime_opts = qcow2_strong_runtime_opts,
234
.mutable_opts = mutable_opts,
235
.bdrv_co_check = qcow2_co_check,
236
diff --git a/qemu-img.c b/qemu-img.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/qemu-img.c
239
+++ b/qemu-img.c
240
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
241
return 1;
242
}
243
244
- /* Every driver supporting amendment must have create_opts */
245
- assert(drv->create_opts);
246
+ /* Every driver supporting amendment must have amend_opts */
247
+ assert(drv->amend_opts);
248
249
printf("Creation options for '%s':\n", format);
250
- qemu_opts_print_help(drv->create_opts, false);
251
+ qemu_opts_print_help(drv->amend_opts, false);
252
printf("\nNote that not all of these options may be amendable.\n");
253
return 0;
254
}
255
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
256
Error *err = NULL;
257
int c, ret = 0;
258
char *options = NULL;
259
- QemuOptsList *create_opts = NULL;
260
+ QemuOptsList *amend_opts = NULL;
261
QemuOpts *opts = NULL;
262
const char *fmt = NULL, *filename, *cache;
263
int flags;
264
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
265
goto out;
266
}
267
268
- /* Every driver supporting amendment must have create_opts */
269
- assert(bs->drv->create_opts);
270
+ /* Every driver supporting amendment must have amend_opts */
271
+ assert(bs->drv->amend_opts);
272
273
- create_opts = qemu_opts_append(create_opts, bs->drv->create_opts);
274
- opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
275
+ amend_opts = qemu_opts_append(amend_opts, bs->drv->amend_opts);
276
+ opts = qemu_opts_create(amend_opts, NULL, 0, &error_abort);
277
qemu_opts_do_parse(opts, options, NULL, &err);
278
if (err) {
279
error_report_err(err);
280
@@ -XXX,XX +XXX,XX @@ out:
281
out_no_progress:
282
blk_unref(blk);
283
qemu_opts_del(opts);
284
- qemu_opts_free(create_opts);
285
+ qemu_opts_free(amend_opts);
286
g_free(options);
287
288
if (ret) {
289
--
290
2.26.2
291
292
diff view generated by jsdifflib
1
fe646693acc changed qemu-img create's output so that it no longer prints
1
From: Maxim Levitsky <mlevitsk@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
Some qcow2 create options can't be used for amend.
4
Remove them from the qcow2 create options and add generic logic to detect
5
such options in qemu-img
6
7
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
8
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
9
[mreitz: Dropped some iotests reference output hunks that became
10
unnecessary thanks to
11
"iotests: Make _filter_img_create more active"]
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: John Snow <jsnow@redhat.com>
13
Message-Id: <20200625125548.870061-12-mreitz@redhat.com>
8
Message-id: 20190815153638.4600-2-mreitz@redhat.com
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
14
---
12
tests/qemu-iotests/059.out | 16 ++++++++--------
15
block/qcow2.c | 138 +++++++++-----------------------
13
tests/qemu-iotests/common.filter | 4 ++--
16
qemu-img.c | 18 ++++-
14
2 files changed, 10 insertions(+), 10 deletions(-)
17
tests/qemu-iotests/049.out | 102 ++++++++++++------------
18
tests/qemu-iotests/061.out | 12 ++-
19
tests/qemu-iotests/082.out | 158 ++++---------------------------------
20
tests/qemu-iotests/085.out | 38 ++++-----
21
tests/qemu-iotests/144.out | 4 +-
22
tests/qemu-iotests/182.out | 2 +-
23
tests/qemu-iotests/185.out | 8 +-
24
tests/qemu-iotests/255.out | 8 +-
25
tests/qemu-iotests/274.out | 46 +++++------
26
tests/qemu-iotests/280.out | 2 +-
27
12 files changed, 183 insertions(+), 353 deletions(-)
15
28
16
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
29
diff --git a/block/qcow2.c b/block/qcow2.c
17
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qemu-iotests/059.out
31
--- a/block/qcow2.c
19
+++ b/tests/qemu-iotests/059.out
32
+++ b/block/qcow2.c
20
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
33
@@ -XXX,XX +XXX,XX @@ static int qcow2_change_backing_file(BlockDriverState *bs,
21
qemu-io: can't open device TEST_DIR/t.vmdk: L1 size too big
34
return qcow2_update_header(bs);
22
35
}
23
=== Testing monolithicFlat creation and opening ===
36
24
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
37
-static int qcow2_crypt_method_from_format(const char *encryptfmt)
25
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
38
-{
39
- if (g_str_equal(encryptfmt, "luks")) {
40
- return QCOW_CRYPT_LUKS;
41
- } else if (g_str_equal(encryptfmt, "aes")) {
42
- return QCOW_CRYPT_AES;
43
- } else {
44
- return -EINVAL;
45
- }
46
-}
47
-
48
static int qcow2_set_up_encryption(BlockDriverState *bs,
49
QCryptoBlockCreateOptions *cryptoopts,
50
Error **errp)
51
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
52
bool lazy_refcounts = s->use_lazy_refcounts;
53
bool data_file_raw = data_file_is_raw(bs);
54
const char *compat = NULL;
55
- uint64_t cluster_size = s->cluster_size;
56
- bool encrypt;
57
- int encformat;
58
int refcount_bits = s->refcount_bits;
59
int ret;
60
QemuOptDesc *desc = opts->list->desc;
61
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
62
error_setg(errp, "Unknown compatibility level %s", compat);
63
return -EINVAL;
64
}
65
- } else if (!strcmp(desc->name, BLOCK_OPT_PREALLOC)) {
66
- error_setg(errp, "Cannot change preallocation mode");
67
- return -ENOTSUP;
68
} else if (!strcmp(desc->name, BLOCK_OPT_SIZE)) {
69
new_size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
70
} else if (!strcmp(desc->name, BLOCK_OPT_BACKING_FILE)) {
71
backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
72
} else if (!strcmp(desc->name, BLOCK_OPT_BACKING_FMT)) {
73
backing_format = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
74
- } else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT)) {
75
- encrypt = qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT,
76
- !!s->crypto);
77
-
78
- if (encrypt != !!s->crypto) {
79
- error_setg(errp,
80
- "Changing the encryption flag is not supported");
81
- return -ENOTSUP;
82
- }
83
- } else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT_FORMAT)) {
84
- encformat = qcow2_crypt_method_from_format(
85
- qemu_opt_get(opts, BLOCK_OPT_ENCRYPT_FORMAT));
86
-
87
- if (encformat != s->crypt_method_header) {
88
- error_setg(errp,
89
- "Changing the encryption format is not supported");
90
- return -ENOTSUP;
91
- }
92
- } else if (g_str_has_prefix(desc->name, "encrypt.")) {
93
- error_setg(errp,
94
- "Changing the encryption parameters is not supported");
95
- return -ENOTSUP;
96
- } else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) {
97
- cluster_size = qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE,
98
- cluster_size);
99
- if (cluster_size != s->cluster_size) {
100
- error_setg(errp, "Changing the cluster size is not supported");
101
- return -ENOTSUP;
102
- }
103
} else if (!strcmp(desc->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
104
lazy_refcounts = qemu_opt_get_bool(opts, BLOCK_OPT_LAZY_REFCOUNTS,
105
lazy_refcounts);
106
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
107
"images");
108
return -EINVAL;
109
}
110
- } else if (!strcmp(desc->name, BLOCK_OPT_COMPRESSION_TYPE)) {
111
- const char *ct_name =
112
- qemu_opt_get(opts, BLOCK_OPT_COMPRESSION_TYPE);
113
- int compression_type =
114
- qapi_enum_parse(&Qcow2CompressionType_lookup, ct_name, -1,
115
- NULL);
116
- if (compression_type == -1) {
117
- error_setg(errp, "Unknown compression type: %s", ct_name);
118
- return -ENOTSUP;
119
- }
120
-
121
- if (compression_type != s->compression_type) {
122
- error_setg(errp, "Changing the compression type "
123
- "is not supported");
124
- return -ENOTSUP;
125
- }
126
} else {
127
/* if this point is reached, this probably means a new option was
128
* added without having it covered here */
129
@@ -XXX,XX +XXX,XX @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
130
.help = "The external data file must stay valid " \
131
"as a raw image" \
132
}, \
133
- { \
134
- .name = BLOCK_OPT_ENCRYPT, \
135
- .type = QEMU_OPT_BOOL, \
136
- .help = "Encrypt the image with format 'aes'. (Deprecated " \
137
- "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", \
138
- }, \
139
- { \
140
- .name = BLOCK_OPT_ENCRYPT_FORMAT, \
141
- .type = QEMU_OPT_STRING, \
142
- .help = "Encrypt the image, format choices: 'aes', 'luks'", \
143
- }, \
144
- BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", \
145
- "ID of secret providing qcow AES key or LUKS passphrase"), \
146
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."), \
147
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."), \
148
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."), \
149
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."), \
150
- BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."), \
151
- BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."), \
152
- { \
153
- .name = BLOCK_OPT_CLUSTER_SIZE, \
154
- .type = QEMU_OPT_SIZE, \
155
- .help = "qcow2 cluster size", \
156
- .def_value_str = stringify(DEFAULT_CLUSTER_SIZE) \
157
- }, \
158
- { \
159
- .name = BLOCK_OPT_PREALLOC, \
160
- .type = QEMU_OPT_STRING, \
161
- .help = "Preallocation mode (allowed values: off, " \
162
- "metadata, falloc, full)" \
163
- }, \
164
{ \
165
.name = BLOCK_OPT_LAZY_REFCOUNTS, \
166
.type = QEMU_OPT_BOOL, \
167
@@ -XXX,XX +XXX,XX @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
168
.type = QEMU_OPT_NUMBER, \
169
.help = "Width of a reference count entry in bits", \
170
.def_value_str = "16" \
171
- }, \
172
- { \
173
- .name = BLOCK_OPT_COMPRESSION_TYPE, \
174
- .type = QEMU_OPT_STRING, \
175
- .help = "Compression method used for image cluster " \
176
- "compression", \
177
- .def_value_str = "zlib" \
178
}
179
180
static QemuOptsList qcow2_create_opts = {
181
.name = "qcow2-create-opts",
182
.head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
183
.desc = {
184
+ { \
185
+ .name = BLOCK_OPT_ENCRYPT, \
186
+ .type = QEMU_OPT_BOOL, \
187
+ .help = "Encrypt the image with format 'aes'. (Deprecated " \
188
+ "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", \
189
+ }, \
190
+ { \
191
+ .name = BLOCK_OPT_ENCRYPT_FORMAT, \
192
+ .type = QEMU_OPT_STRING, \
193
+ .help = "Encrypt the image, format choices: 'aes', 'luks'", \
194
+ }, \
195
+ BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", \
196
+ "ID of secret providing qcow AES key or LUKS passphrase"), \
197
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."), \
198
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."), \
199
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."), \
200
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."), \
201
+ BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."), \
202
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."), \
203
+ { \
204
+ .name = BLOCK_OPT_CLUSTER_SIZE, \
205
+ .type = QEMU_OPT_SIZE, \
206
+ .help = "qcow2 cluster size", \
207
+ .def_value_str = stringify(DEFAULT_CLUSTER_SIZE) \
208
+ }, \
209
+ { \
210
+ .name = BLOCK_OPT_PREALLOC, \
211
+ .type = QEMU_OPT_STRING, \
212
+ .help = "Preallocation mode (allowed values: off, " \
213
+ "metadata, falloc, full)" \
214
+ }, \
215
+ { \
216
+ .name = BLOCK_OPT_COMPRESSION_TYPE, \
217
+ .type = QEMU_OPT_STRING, \
218
+ .help = "Compression method used for image cluster " \
219
+ "compression", \
220
+ .def_value_str = "zlib" \
221
+ },
222
QCOW_COMMON_OPTIONS,
223
{ /* end of list */ }
224
}
225
diff --git a/qemu-img.c b/qemu-img.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/qemu-img.c
228
+++ b/qemu-img.c
229
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
230
/* Every driver supporting amendment must have amend_opts */
231
assert(drv->amend_opts);
232
233
- printf("Creation options for '%s':\n", format);
234
+ printf("Amend options for '%s':\n", format);
235
qemu_opts_print_help(drv->amend_opts, false);
236
- printf("\nNote that not all of these options may be amendable.\n");
237
return 0;
238
}
239
240
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
241
amend_opts = qemu_opts_append(amend_opts, bs->drv->amend_opts);
242
opts = qemu_opts_create(amend_opts, NULL, 0, &error_abort);
243
qemu_opts_do_parse(opts, options, NULL, &err);
244
+
245
if (err) {
246
+ /* Try to parse options using the create options */
247
+ Error *err1 = NULL;
248
+ amend_opts = qemu_opts_append(amend_opts, bs->drv->create_opts);
249
+ qemu_opts_del(opts);
250
+ opts = qemu_opts_create(amend_opts, NULL, 0, &error_abort);
251
+ qemu_opts_do_parse(opts, options, NULL, &err1);
252
+
253
+ if (!err1) {
254
+ error_append_hint(&err,
255
+ "This option is only supported for image creation\n");
256
+ } else {
257
+ error_free(err1);
258
+ }
259
+
260
error_report_err(err);
261
ret = -1;
262
goto out;
263
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
264
index XXXXXXX..XXXXXXX 100644
265
--- a/tests/qemu-iotests/049.out
266
+++ b/tests/qemu-iotests/049.out
267
@@ -XXX,XX +XXX,XX @@ QA output created by 049
268
== 1. Traditional size parameter ==
269
270
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024
271
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
272
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
273
274
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b
275
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
276
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
277
278
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k
279
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
280
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
281
282
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K
283
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
284
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
285
286
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M
287
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
288
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16
289
290
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G
291
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
292
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16
293
294
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T
295
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
296
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16
297
298
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0
299
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
300
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
301
302
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b
303
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
304
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
305
306
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k
307
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
308
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
309
310
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K
311
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
312
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
313
314
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M
315
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
316
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16
317
318
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G
319
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
320
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16
321
322
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T
323
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
324
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16
325
326
== 2. Specifying size via -o ==
327
328
qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2
329
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
330
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
331
332
qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2
333
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
334
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
335
336
qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2
337
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
338
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
339
340
qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2
341
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
342
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
343
344
qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2
345
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
346
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16
347
348
qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2
349
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
350
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16
351
352
qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2
353
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
354
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16
355
356
qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2
357
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
358
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
359
360
qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2
361
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
362
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
363
364
qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2
365
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
366
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
367
368
qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2
369
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
370
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
371
372
qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2
373
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
374
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16
375
376
qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2
377
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
378
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16
379
380
qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2
381
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
382
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16
383
384
== 3. Invalid sizes ==
385
386
@@ -XXX,XX +XXX,XX @@ qemu-img: TEST_DIR/t.qcow2: The image size must be specified only once
387
== Check correct interpretation of suffixes for cluster size ==
388
389
qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M
390
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
391
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
392
393
qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M
394
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
395
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
396
397
qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M
398
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
399
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
400
401
qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M
402
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
403
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
404
405
qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M
406
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1048576 lazy_refcounts=off refcount_bits=16 compression_type=zlib
407
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1048576 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
408
409
qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M
410
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
411
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
412
413
qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M
414
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
415
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
416
417
qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M
418
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 compression_type=zlib
419
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
420
421
qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M
422
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 compression_type=zlib
423
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
424
425
qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M
426
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=524288 lazy_refcounts=off refcount_bits=16 compression_type=zlib
427
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=524288 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
428
429
== Check compat level option ==
430
431
qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M
432
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
433
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16
434
435
qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M
436
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
437
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16
438
439
qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M
440
qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42'
441
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
442
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16
443
444
qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M
445
qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar'
446
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
447
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16
448
449
== Check preallocation option ==
450
451
qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M
452
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=off lazy_refcounts=off refcount_bits=16 compression_type=zlib
453
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
454
455
qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M
456
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16 compression_type=zlib
457
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=metadata compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
458
459
qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
460
qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234'
461
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=1234 lazy_refcounts=off refcount_bits=16 compression_type=zlib
462
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
463
464
== Check encryption option ==
465
466
qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M
467
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
468
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=off cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
469
470
qemu-img create -f qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 TEST_DIR/t.qcow2 64M
471
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
472
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=on encrypt.key-secret=sec0 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
473
474
== Check lazy_refcounts option (only with v3) ==
475
476
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M
477
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
478
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16
479
480
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M
481
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib
482
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=on refcount_bits=16
483
484
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M
485
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
486
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16
487
488
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M
489
qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater)
490
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib
491
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=on refcount_bits=16
492
493
*** done
494
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
495
index XXXXXXX..XXXXXXX 100644
496
--- a/tests/qemu-iotests/061.out
497
+++ b/tests/qemu-iotests/061.out
498
@@ -XXX,XX +XXX,XX @@ qemu-img: Lazy refcounts only supported with compatibility level 1.1 and above (
499
qemu-img: Lazy refcounts only supported with compatibility level 1.1 and above (use compat=1.1 or greater)
500
qemu-img: Unknown compatibility level 0.42
501
qemu-img: Invalid parameter 'foo'
502
-qemu-img: Changing the cluster size is not supported
503
-qemu-img: Changing the encryption flag is not supported
504
-qemu-img: Cannot change preallocation mode
505
+qemu-img: Invalid parameter 'cluster_size'
506
+This option is only supported for image creation
507
+qemu-img: Invalid parameter 'encryption'
508
+This option is only supported for image creation
509
+qemu-img: Invalid parameter 'preallocation'
510
+This option is only supported for image creation
511
512
=== Testing correct handling of unset value ===
513
514
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
515
Should work:
516
Should not work:
517
-qemu-img: Changing the cluster size is not supported
518
+qemu-img: Invalid parameter 'cluster_size'
519
+This option is only supported for image creation
520
521
=== Testing zero expansion on inactive clusters ===
522
523
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
524
index XXXXXXX..XXXXXXX 100644
525
--- a/tests/qemu-iotests/082.out
526
+++ b/tests/qemu-iotests/082.out
527
@@ -XXX,XX +XXX,XX @@ QA output created by 082
528
=== create: Options specified more than once ===
529
530
Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M
531
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
532
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
26
image: TEST_DIR/t.IMGFMT
533
image: TEST_DIR/t.IMGFMT
27
file format: IMGFMT
534
file format: IMGFMT
28
virtual size: 2 GiB (2147483648 bytes)
535
virtual size: 128 MiB (134217728 bytes)
29
536
cluster_size: 65536
30
=== Testing monolithicFlat with zeroed_grain ===
537
31
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
538
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
32
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
539
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on refcount_bits=16 compression_type=zlib
33
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
540
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=4096 compression_type=zlib size=134217728 lazy_refcounts=on refcount_bits=16
34
35
=== Testing big twoGbMaxExtentFlat ===
36
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMaxExtentFlat
37
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000
38
image: TEST_DIR/t.vmdk
39
file format: vmdk
40
virtual size: 0.977 TiB (1073741824000 bytes)
41
@@ -XXX,XX +XXX,XX @@ Format specific information:
42
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Invalid extent line: RW 12582912 VMFS "dummy.IMGFMT" 1
43
44
=== Testing truncated sparse ===
45
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 subformat=monolithicSparse
46
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400
47
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': File truncated, expecting at least 13172736 bytes
48
49
=== Converting to streamOptimized from image with small cluster size===
50
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
51
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
52
53
=== Testing monolithicFlat with internally generated JSON file name ===
54
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 subformat=monolithicFlat
55
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
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"}'
57
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
541
image: TEST_DIR/t.IMGFMT
66
file format: IMGFMT
542
file format: IMGFMT
67
virtual size: 4 TiB (4398046511104 bytes)
543
virtual size: 128 MiB (134217728 bytes)
68
@@ -XXX,XX +XXX,XX @@ read 1024/1024 bytes at offset 966367641600
544
@@ -XXX,XX +XXX,XX @@ Format specific information:
69
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
545
corrupt: false
70
546
71
=== Testing qemu-img map on extents ===
547
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M
72
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=monolithicSparse
548
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on refcount_bits=16 compression_type=zlib
73
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544
549
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=8192 compression_type=zlib size=134217728 lazy_refcounts=on refcount_bits=16
74
wrote 1024/1024 bytes at offset 65024
550
image: TEST_DIR/t.IMGFMT
75
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
551
file format: IMGFMT
76
wrote 1024/1024 bytes at offset 2147483136
552
virtual size: 128 MiB (134217728 bytes)
77
@@ -XXX,XX +XXX,XX @@ Offset Length Mapped to File
553
@@ -XXX,XX +XXX,XX @@ Format specific information:
78
0 0x20000 0x3f0000 TEST_DIR/t.vmdk
554
corrupt: false
79
0x7fff0000 0x20000 0x410000 TEST_DIR/t.vmdk
555
80
0x140000000 0x10000 0x430000 TEST_DIR/t.vmdk
556
Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M
81
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=twoGbMaxExtentSparse
557
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off refcount_bits=16 compression_type=zlib
82
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544
558
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=8192 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
83
wrote 1024/1024 bytes at offset 65024
559
image: TEST_DIR/t.IMGFMT
84
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
560
file format: IMGFMT
85
wrote 1024/1024 bytes at offset 2147483136
561
virtual size: 128 MiB (134217728 bytes)
86
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
562
@@ -XXX,XX +XXX,XX @@ Supported options:
563
size=<size> - Virtual disk size
564
565
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
566
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
567
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2,,help lazy_refcounts=off refcount_bits=16
568
569
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M
570
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
571
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2,,? lazy_refcounts=off refcount_bits=16
572
573
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M
574
qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2,
575
@@ -XXX,XX +XXX,XX @@ qemu-img: Format driver 'bochs' does not support image creation
576
=== convert: Options specified more than once ===
577
578
Testing: create -f qcow2 TEST_DIR/t.qcow2 128M
579
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
580
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
581
582
Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
583
image: TEST_DIR/t.IMGFMT.base
584
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
585
=== amend: help for -o ===
586
587
Testing: amend -f qcow2 -o help TEST_DIR/t.qcow2
588
-Creation options for 'qcow2':
589
+Amend options for 'qcow2':
590
backing_file=<str> - File name of a base image
591
backing_fmt=<str> - Image format of the base image
592
- cluster_size=<size> - qcow2 cluster size
593
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
594
- compression_type=<str> - Compression method used for image cluster compression
595
data_file=<str> - File name of an external data file
596
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
597
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
598
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
599
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
600
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
601
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
602
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
603
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
604
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
605
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
606
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
607
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
608
refcount_bits=<num> - Width of a reference count entry in bits
609
size=<size> - Virtual disk size
610
611
-Note that not all of these options may be amendable.
612
-
613
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
614
-Creation options for 'qcow2':
615
+Amend options for 'qcow2':
616
backing_file=<str> - File name of a base image
617
backing_fmt=<str> - Image format of the base image
618
- cluster_size=<size> - qcow2 cluster size
619
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
620
- compression_type=<str> - Compression method used for image cluster compression
621
data_file=<str> - File name of an external data file
622
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
623
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
624
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
625
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
626
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
627
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
628
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
629
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
630
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
631
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
632
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
633
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
634
refcount_bits=<num> - Width of a reference count entry in bits
635
size=<size> - Virtual disk size
636
637
-Note that not all of these options may be amendable.
638
-
639
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
640
-Creation options for 'qcow2':
641
+Amend options for 'qcow2':
642
backing_file=<str> - File name of a base image
643
backing_fmt=<str> - Image format of the base image
644
- cluster_size=<size> - qcow2 cluster size
645
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
646
- compression_type=<str> - Compression method used for image cluster compression
647
data_file=<str> - File name of an external data file
648
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
649
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
650
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
651
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
652
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
653
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
654
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
655
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
656
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
657
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
658
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
659
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
660
refcount_bits=<num> - Width of a reference count entry in bits
661
size=<size> - Virtual disk size
662
663
-Note that not all of these options may be amendable.
664
-
665
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
666
-Creation options for 'qcow2':
667
+Amend options for 'qcow2':
668
backing_file=<str> - File name of a base image
669
backing_fmt=<str> - Image format of the base image
670
- cluster_size=<size> - qcow2 cluster size
671
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
672
- compression_type=<str> - Compression method used for image cluster compression
673
data_file=<str> - File name of an external data file
674
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
675
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
676
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
677
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
678
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
679
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
680
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
681
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
682
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
683
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
684
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
685
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
686
refcount_bits=<num> - Width of a reference count entry in bits
687
size=<size> - Virtual disk size
688
689
-Note that not all of these options may be amendable.
690
-
691
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
692
-Creation options for 'qcow2':
693
+Amend options for 'qcow2':
694
backing_file=<str> - File name of a base image
695
backing_fmt=<str> - Image format of the base image
696
- cluster_size=<size> - qcow2 cluster size
697
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
698
- compression_type=<str> - Compression method used for image cluster compression
699
data_file=<str> - File name of an external data file
700
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
701
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
702
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
703
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
704
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
705
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
706
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
707
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
708
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
709
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
710
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
711
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
712
refcount_bits=<num> - Width of a reference count entry in bits
713
size=<size> - Virtual disk size
714
715
-Note that not all of these options may be amendable.
716
-
717
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
718
-Creation options for 'qcow2':
719
+Amend options for 'qcow2':
720
backing_file=<str> - File name of a base image
721
backing_fmt=<str> - Image format of the base image
722
- cluster_size=<size> - qcow2 cluster size
723
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
724
- compression_type=<str> - Compression method used for image cluster compression
725
data_file=<str> - File name of an external data file
726
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
727
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
728
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
729
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
730
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
731
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
732
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
733
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
734
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
735
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
736
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
737
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
738
refcount_bits=<num> - Width of a reference count entry in bits
739
size=<size> - Virtual disk size
740
741
-Note that not all of these options may be amendable.
742
-
743
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
744
-Creation options for 'qcow2':
745
+Amend options for 'qcow2':
746
backing_file=<str> - File name of a base image
747
backing_fmt=<str> - Image format of the base image
748
- cluster_size=<size> - qcow2 cluster size
749
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
750
- compression_type=<str> - Compression method used for image cluster compression
751
data_file=<str> - File name of an external data file
752
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
753
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
754
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
755
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
756
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
757
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
758
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
759
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
760
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
761
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
762
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
763
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
764
refcount_bits=<num> - Width of a reference count entry in bits
765
size=<size> - Virtual disk size
766
767
-Note that not all of these options may be amendable.
768
-
769
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
770
-Creation options for 'qcow2':
771
+Amend options for 'qcow2':
772
backing_file=<str> - File name of a base image
773
backing_fmt=<str> - Image format of the base image
774
- cluster_size=<size> - qcow2 cluster size
775
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
776
- compression_type=<str> - Compression method used for image cluster compression
777
data_file=<str> - File name of an external data file
778
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
779
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
780
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
781
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
782
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
783
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
784
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
785
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
786
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
787
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
788
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
789
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
790
refcount_bits=<num> - Width of a reference count entry in bits
791
size=<size> - Virtual disk size
792
793
-Note that not all of these options may be amendable.
794
-
795
Testing: amend -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2
796
797
Testing: rebase -u -b -f qcow2 TEST_DIR/t.qcow2
798
@@ -XXX,XX +XXX,XX @@ Testing: amend -f qcow2 -o backing_file=TEST_DIR/t.qcow2 -o ,, -o help TEST_DIR/
799
qemu-img: Invalid option list: ,,
800
801
Testing: amend -f qcow2 -o help
802
-Creation options for 'qcow2':
803
+Amend options for 'qcow2':
804
backing_file=<str> - File name of a base image
805
backing_fmt=<str> - Image format of the base image
806
- cluster_size=<size> - qcow2 cluster size
807
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
808
- compression_type=<str> - Compression method used for image cluster compression
809
data_file=<str> - File name of an external data file
810
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
811
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
812
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
813
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
814
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
815
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
816
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
817
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
818
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
819
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
820
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
821
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
822
refcount_bits=<num> - Width of a reference count entry in bits
823
size=<size> - Virtual disk size
824
825
-Note that not all of these options may be amendable.
826
-
827
Testing: amend -o help
828
qemu-img: Expecting one image file name
829
830
diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out
87
index XXXXXXX..XXXXXXX 100644
831
index XXXXXXX..XXXXXXX 100644
88
--- a/tests/qemu-iotests/common.filter
832
--- a/tests/qemu-iotests/085.out
89
+++ b/tests/qemu-iotests/common.filter
833
+++ b/tests/qemu-iotests/085.out
90
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
834
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=134217728
91
-e "s# compat6=\\(on\\|off\\)##g" \
835
=== Create a single snapshot on virtio0 ===
92
-e "s# static=\\(on\\|off\\)##g" \
836
93
-e "s# zeroed_grain=\\(on\\|off\\)##g" \
837
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } }
94
- -e "s# subformat='[^']*'##g" \
838
-Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
95
- -e "s# adapter_type='[^']*'##g" \
839
+Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
96
+ -e "s# subformat=[^ ]*##g" \
840
{"return": {}}
97
+ -e "s# adapter_type=[^ ]*##g" \
841
98
-e "s# hwversion=[^ ]*##g" \
842
=== Invalid command - missing device and nodename ===
99
-e "s# lazy_refcounts=\\(on\\|off\\)##g" \
843
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file
100
-e "s# block_size=[0-9]\\+##g" \
844
=== Create several transactional group snapshots ===
845
846
{ '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' } } ] } }
847
-Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
848
-Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
849
+Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
850
+Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
851
{"return": {}}
852
{ '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' } } ] } }
853
-Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
854
-Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
855
+Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
856
+Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
857
{"return": {}}
858
{ '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' } } ] } }
859
-Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
860
-Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
861
+Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
862
+Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
863
{"return": {}}
864
{ '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' } } ] } }
865
-Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
866
-Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
867
+Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
868
+Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
869
{"return": {}}
870
{ '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' } } ] } }
871
-Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
872
-Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
873
+Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
874
+Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
875
{"return": {}}
876
{ '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' } } ] } }
877
-Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
878
-Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
879
+Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
880
+Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
881
{"return": {}}
882
{ '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' } } ] } }
883
-Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
884
-Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
885
+Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
886
+Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
887
{"return": {}}
888
{ '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' } } ] } }
889
-Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
890
-Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
891
+Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
892
+Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
893
{"return": {}}
894
{ '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' } } ] } }
895
-Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
896
-Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
897
+Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
898
+Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
899
{"return": {}}
900
901
=== Create a couple of snapshots using blockdev-snapshot ===
902
diff --git a/tests/qemu-iotests/144.out b/tests/qemu-iotests/144.out
903
index XXXXXXX..XXXXXXX 100644
904
--- a/tests/qemu-iotests/144.out
905
+++ b/tests/qemu-iotests/144.out
906
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912
907
{ 'execute': 'qmp_capabilities' }
908
{"return": {}}
909
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp.IMGFMT', 'format': 'IMGFMT' } }
910
-Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
911
+Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
912
{"return": {}}
913
914
=== Performing block-commit on active layer ===
915
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/
916
=== Performing Live Snapshot 2 ===
917
918
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp2.IMGFMT', 'format': 'IMGFMT' } }
919
-Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
920
+Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
921
{"return": {}}
922
*** done
923
diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out
924
index XXXXXXX..XXXXXXX 100644
925
--- a/tests/qemu-iotests/182.out
926
+++ b/tests/qemu-iotests/182.out
927
@@ -XXX,XX +XXX,XX @@ Is another process using the image [TEST_DIR/t.qcow2]?
928
{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node0', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
929
{"return": {}}
930
{'execute': 'blockdev-snapshot-sync', 'arguments': { 'node-name': 'node0', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'snapshot-node-name': 'node1' } }
931
-Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
932
+Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 cluster_size=65536 compression_type=zlib size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file lazy_refcounts=off refcount_bits=16
933
{"return": {}}
934
{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node1', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
935
{"return": {}}
936
diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out
937
index XXXXXXX..XXXXXXX 100644
938
--- a/tests/qemu-iotests/185.out
939
+++ b/tests/qemu-iotests/185.out
940
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
941
=== Creating backing chain ===
942
943
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT.mid', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
944
-Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
945
+Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
946
{"return": {}}
947
{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write 0 4M"' } }
948
wrote 4194304/4194304 bytes at offset 0
949
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
950
{"return": ""}
951
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
952
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
953
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
954
{"return": {}}
955
956
=== Start commit job and exit qemu ===
957
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.q
958
{ 'execute': 'qmp_capabilities' }
959
{"return": {}}
960
{ 'execute': 'drive-mirror', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
961
-Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
962
+Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
963
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
964
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
965
{"return": {}}
966
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 l
967
{ 'execute': 'qmp_capabilities' }
968
{"return": {}}
969
{ 'execute': 'drive-backup', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
970
-Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
971
+Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
972
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
973
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
974
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}}
975
diff --git a/tests/qemu-iotests/255.out b/tests/qemu-iotests/255.out
976
index XXXXXXX..XXXXXXX 100644
977
--- a/tests/qemu-iotests/255.out
978
+++ b/tests/qemu-iotests/255.out
979
@@ -XXX,XX +XXX,XX @@ Finishing a commit job with background reads
980
981
=== Create backing chain and start VM ===
982
983
-Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
984
+Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
985
986
-Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
987
+Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
988
989
=== Start background read requests ===
990
991
@@ -XXX,XX +XXX,XX @@ Closing the VM while a job is being cancelled
992
993
=== Create images and start VM ===
994
995
-Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
996
+Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
997
998
-Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
999
+Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
1000
1001
wrote 1048576/1048576 bytes at offset 0
1002
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1003
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
1004
index XXXXXXX..XXXXXXX 100644
1005
--- a/tests/qemu-iotests/274.out
1006
+++ b/tests/qemu-iotests/274.out
1007
@@ -XXX,XX +XXX,XX @@
1008
== Commit tests ==
1009
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1010
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
1011
1012
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1013
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1014
1015
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1016
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid lazy_refcounts=off refcount_bits=16
1017
1018
wrote 2097152/2097152 bytes at offset 0
1019
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1020
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
1021
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1022
1023
=== Testing HMP commit (top -> mid) ===
1024
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1025
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
1026
1027
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1028
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1029
1030
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1031
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid lazy_refcounts=off refcount_bits=16
1032
1033
wrote 2097152/2097152 bytes at offset 0
1034
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1035
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
1036
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1037
1038
=== Testing QMP active commit (top -> mid) ===
1039
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1040
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
1041
1042
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1043
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1044
1045
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1046
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid lazy_refcounts=off refcount_bits=16
1047
1048
wrote 2097152/2097152 bytes at offset 0
1049
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1050
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
1051
1052
== Resize tests ==
1053
=== preallocation=off ===
1054
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1055
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=6442450944 lazy_refcounts=off refcount_bits=16
1056
1057
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1058
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1059
1060
wrote 65536/65536 bytes at offset 5368709120
1061
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1062
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 5368709120
1063
{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
1064
1065
=== preallocation=metadata ===
1066
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1067
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=34359738368 lazy_refcounts=off refcount_bits=16
1068
1069
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1070
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=32212254720 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1071
1072
wrote 65536/65536 bytes at offset 33285996544
1073
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1074
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 33285996544
1075
{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
1076
1077
=== preallocation=falloc ===
1078
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1079
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=10485760 lazy_refcounts=off refcount_bits=16
1080
1081
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1082
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=5242880 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1083
1084
wrote 65536/65536 bytes at offset 9437184
1085
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1086
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
1087
{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
1088
1089
=== preallocation=full ===
1090
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1091
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=16777216 lazy_refcounts=off refcount_bits=16
1092
1093
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1094
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=8388608 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1095
1096
wrote 65536/65536 bytes at offset 11534336
1097
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1098
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
1099
{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
1100
1101
=== preallocation=off ===
1102
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1103
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=393216 lazy_refcounts=off refcount_bits=16
1104
1105
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1106
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=259072 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1107
1108
wrote 65536/65536 bytes at offset 259072
1109
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1110
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 259072
1111
{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
1112
1113
=== preallocation=off ===
1114
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1115
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=409600 lazy_refcounts=off refcount_bits=16
1116
1117
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1118
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1119
1120
wrote 65536/65536 bytes at offset 344064
1121
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1122
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 344064
1123
{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
1124
1125
=== preallocation=off ===
1126
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1127
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=524288 lazy_refcounts=off refcount_bits=16
1128
1129
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1130
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1131
1132
wrote 65536/65536 bytes at offset 446464
1133
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1134
diff --git a/tests/qemu-iotests/280.out b/tests/qemu-iotests/280.out
1135
index XXXXXXX..XXXXXXX 100644
1136
--- a/tests/qemu-iotests/280.out
1137
+++ b/tests/qemu-iotests/280.out
1138
@@ -XXX,XX +XXX,XX @@
1139
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1140
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
1141
1142
=== Launch VM ===
1143
Enabling migration QMP events on VM...
101
--
1144
--
102
2.21.0
1145
2.26.2
103
1146
104
1147
diff view generated by jsdifflib
New patch
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
2
3
rename the write_func to create_write_func, and init_func to create_init_func.
4
This is preparation for other write_func that will be used to update the encryption keys.
5
6
No functional changes
7
8
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
10
Message-Id: <20200608094030.670121-7-mlevitsk@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
block/crypto.c | 25 ++++++++++++-------------
14
1 file changed, 12 insertions(+), 13 deletions(-)
15
16
diff --git a/block/crypto.c b/block/crypto.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/crypto.c
19
+++ b/block/crypto.c
20
@@ -XXX,XX +XXX,XX @@ struct BlockCryptoCreateData {
21
};
22
23
24
-static ssize_t block_crypto_write_func(QCryptoBlock *block,
25
- size_t offset,
26
- const uint8_t *buf,
27
- size_t buflen,
28
- void *opaque,
29
- Error **errp)
30
+static ssize_t block_crypto_create_write_func(QCryptoBlock *block,
31
+ size_t offset,
32
+ const uint8_t *buf,
33
+ size_t buflen,
34
+ void *opaque,
35
+ Error **errp)
36
{
37
struct BlockCryptoCreateData *data = opaque;
38
ssize_t ret;
39
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_write_func(QCryptoBlock *block,
40
return ret;
41
}
42
43
-
44
-static ssize_t block_crypto_init_func(QCryptoBlock *block,
45
- size_t headerlen,
46
- void *opaque,
47
- Error **errp)
48
+static ssize_t block_crypto_create_init_func(QCryptoBlock *block,
49
+ size_t headerlen,
50
+ void *opaque,
51
+ Error **errp)
52
{
53
struct BlockCryptoCreateData *data = opaque;
54
Error *local_error = NULL;
55
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
56
};
57
58
crypto = qcrypto_block_create(opts, NULL,
59
- block_crypto_init_func,
60
- block_crypto_write_func,
61
+ block_crypto_create_init_func,
62
+ block_crypto_create_write_func,
63
&data,
64
errp);
65
66
--
67
2.26.2
68
69
diff view generated by jsdifflib
New patch
1
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
3
This implements the encryption key management using the generic code in
4
qcrypto layer and exposes it to the user via qemu-img
5
6
This code adds another 'write_func' because the initialization
7
write_func works directly on the underlying file, and amend
8
works on instance of luks device.
9
10
This commit also adds a 'hack/workaround' I and Kevin Wolf (thanks)
11
made to make the driver both support write sharing (to avoid breaking the users),
12
and be safe against concurrent metadata update (the keyslots)
13
14
Eventually the write sharing for luks driver will be deprecated
15
and removed together with this hack.
16
17
The hack is that we ask (as a format driver) for BLK_PERM_CONSISTENT_READ
18
and then when we want to update the keys, we unshare that permission.
19
So if someone else has the image open, even readonly, encryption
20
key update will fail gracefully.
21
22
Also thanks to Daniel Berrange for the idea of
23
unsharing read, rather that write permission which allows
24
to avoid cases when the other user had opened the image read-only.
25
26
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
27
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
28
Reviewed-by: Max Reitz <mreitz@redhat.com>
29
Message-Id: <20200608094030.670121-8-mlevitsk@redhat.com>
30
Signed-off-by: Max Reitz <mreitz@redhat.com>
31
---
32
block/crypto.h | 34 +++++++++++++
33
block/crypto.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++--
34
2 files changed, 161 insertions(+), 3 deletions(-)
35
36
diff --git a/block/crypto.h b/block/crypto.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/block/crypto.h
39
+++ b/block/crypto.h
40
@@ -XXX,XX +XXX,XX @@
41
#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg"
42
#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
43
#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
44
+#define BLOCK_CRYPTO_OPT_LUKS_KEYSLOT "keyslot"
45
+#define BLOCK_CRYPTO_OPT_LUKS_STATE "state"
46
+#define BLOCK_CRYPTO_OPT_LUKS_OLD_SECRET "old-secret"
47
+#define BLOCK_CRYPTO_OPT_LUKS_NEW_SECRET "new-secret"
48
+
49
50
#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix) \
51
BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, \
52
@@ -XXX,XX +XXX,XX @@
53
.help = "Time to spend in PBKDF in milliseconds", \
54
}
55
56
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_STATE(prefix) \
57
+ { \
58
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_STATE, \
59
+ .type = QEMU_OPT_STRING, \
60
+ .help = "Select new state of affected keyslots (active/inactive)",\
61
+ }
62
+
63
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(prefix) \
64
+ { \
65
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_KEYSLOT, \
66
+ .type = QEMU_OPT_NUMBER, \
67
+ .help = "Select a single keyslot to modify explicitly",\
68
+ }
69
+
70
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET(prefix) \
71
+ { \
72
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_OLD_SECRET, \
73
+ .type = QEMU_OPT_STRING, \
74
+ .help = "Select all keyslots that match this password", \
75
+ }
76
+
77
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET(prefix) \
78
+ { \
79
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_NEW_SECRET, \
80
+ .type = QEMU_OPT_STRING, \
81
+ .help = "New secret to set in the matching keyslots. " \
82
+ "Empty string to erase", \
83
+ }
84
+
85
QCryptoBlockCreateOptions *
86
block_crypto_create_opts_init(QDict *opts, Error **errp);
87
88
diff --git a/block/crypto.c b/block/crypto.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/block/crypto.c
91
+++ b/block/crypto.c
92
@@ -XXX,XX +XXX,XX @@ typedef struct BlockCrypto BlockCrypto;
93
94
struct BlockCrypto {
95
QCryptoBlock *block;
96
+ bool updating_keys;
97
};
98
99
100
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_read_func(QCryptoBlock *block,
101
return ret;
102
}
103
104
+static ssize_t block_crypto_write_func(QCryptoBlock *block,
105
+ size_t offset,
106
+ const uint8_t *buf,
107
+ size_t buflen,
108
+ void *opaque,
109
+ Error **errp)
110
+{
111
+ BlockDriverState *bs = opaque;
112
+ ssize_t ret;
113
+
114
+ ret = bdrv_pwrite(bs->file, offset, buf, buflen);
115
+ if (ret < 0) {
116
+ error_setg_errno(errp, -ret, "Could not write encryption header");
117
+ return ret;
118
+ }
119
+ return ret;
120
+}
121
+
122
123
struct BlockCryptoCreateData {
124
BlockBackend *blk;
125
@@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_create_opts_luks = {
126
};
127
128
129
+static QemuOptsList block_crypto_amend_opts_luks = {
130
+ .name = "crypto",
131
+ .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
132
+ .desc = {
133
+ BLOCK_CRYPTO_OPT_DEF_LUKS_STATE(""),
134
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(""),
135
+ BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET(""),
136
+ BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET(""),
137
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
138
+ { /* end of list */ }
139
+ },
140
+};
141
+
142
QCryptoBlockOpenOptions *
143
block_crypto_open_opts_init(QDict *opts, Error **errp)
144
{
145
@@ -XXX,XX +XXX,XX @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
146
return spec_info;
147
}
148
149
+static int
150
+block_crypto_amend_options_luks(BlockDriverState *bs,
151
+ QemuOpts *opts,
152
+ BlockDriverAmendStatusCB *status_cb,
153
+ void *cb_opaque,
154
+ bool force,
155
+ Error **errp)
156
+{
157
+ BlockCrypto *crypto = bs->opaque;
158
+ QDict *cryptoopts = NULL;
159
+ QCryptoBlockAmendOptions *amend_options = NULL;
160
+ int ret;
161
+
162
+ assert(crypto);
163
+ assert(crypto->block);
164
+ crypto->updating_keys = true;
165
+
166
+ ret = bdrv_child_refresh_perms(bs, bs->file, errp);
167
+ if (ret < 0) {
168
+ goto cleanup;
169
+ }
170
+
171
+ cryptoopts = qemu_opts_to_qdict(opts, NULL);
172
+ qdict_put_str(cryptoopts, "format", "luks");
173
+ amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
174
+ if (!amend_options) {
175
+ ret = -EINVAL;
176
+ goto cleanup;
177
+ }
178
+
179
+ ret = qcrypto_block_amend_options(crypto->block,
180
+ block_crypto_read_func,
181
+ block_crypto_write_func,
182
+ bs,
183
+ amend_options,
184
+ force,
185
+ errp);
186
+cleanup:
187
+ crypto->updating_keys = false;
188
+ bdrv_child_refresh_perms(bs, bs->file, errp);
189
+ qapi_free_QCryptoBlockAmendOptions(amend_options);
190
+ qobject_unref(cryptoopts);
191
+ return ret;
192
+}
193
+
194
+
195
+static void
196
+block_crypto_child_perms(BlockDriverState *bs, BdrvChild *c,
197
+ const BdrvChildRole role,
198
+ BlockReopenQueue *reopen_queue,
199
+ uint64_t perm, uint64_t shared,
200
+ uint64_t *nperm, uint64_t *nshared)
201
+{
202
+
203
+ BlockCrypto *crypto = bs->opaque;
204
+
205
+ bdrv_default_perms(bs, c, role, reopen_queue, perm, shared, nperm, nshared);
206
+
207
+ /*
208
+ * For backward compatibility, manually share the write
209
+ * and resize permission
210
+ */
211
+ *nshared |= (BLK_PERM_WRITE | BLK_PERM_RESIZE);
212
+ /*
213
+ * Since we are not fully a format driver, don't always request
214
+ * the read/resize permission but only when explicitly
215
+ * requested
216
+ */
217
+ *nperm &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
218
+ *nperm |= perm & (BLK_PERM_WRITE | BLK_PERM_RESIZE);
219
+
220
+ /*
221
+ * This driver doesn't modify LUKS metadata except
222
+ * when updating the encryption slots.
223
+ * Thus unlike a proper format driver we don't ask for
224
+ * shared write/read permission. However we need it
225
+ * when we are updating the keys, to ensure that only we
226
+ * have access to the device.
227
+ *
228
+ * Encryption update will set the crypto->updating_keys
229
+ * during that period and refresh permissions
230
+ *
231
+ */
232
+ if (crypto->updating_keys) {
233
+ /* need exclusive write access for header update */
234
+ *nperm |= BLK_PERM_WRITE;
235
+ /* unshare read and write permission */
236
+ *nshared &= ~(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE);
237
+ }
238
+}
239
+
240
+
241
static const char *const block_crypto_strong_runtime_opts[] = {
242
BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
243
244
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
245
.bdrv_probe = block_crypto_probe_luks,
246
.bdrv_open = block_crypto_open_luks,
247
.bdrv_close = block_crypto_close,
248
- /* This driver doesn't modify LUKS metadata except when creating image.
249
- * Allow share-rw=on as a special case. */
250
- .bdrv_child_perm = bdrv_default_perms,
251
+ .bdrv_child_perm = block_crypto_child_perms,
252
.bdrv_co_create = block_crypto_co_create_luks,
253
.bdrv_co_create_opts = block_crypto_co_create_opts_luks,
254
.bdrv_co_truncate = block_crypto_co_truncate,
255
.create_opts = &block_crypto_create_opts_luks,
256
+ .amend_opts = &block_crypto_amend_opts_luks,
257
258
.bdrv_reopen_prepare = block_crypto_reopen_prepare,
259
.bdrv_refresh_limits = block_crypto_refresh_limits,
260
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
261
.bdrv_measure = block_crypto_measure,
262
.bdrv_get_info = block_crypto_get_info_luks,
263
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
264
+ .bdrv_amend_options = block_crypto_amend_options_luks,
265
266
.is_format = true,
267
268
--
269
2.26.2
270
271
diff view generated by jsdifflib
New patch
1
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
3
Now that we have all the infrastructure in place,
4
wire it in the qcow2 driver and expose this to the user.
5
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
7
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-Id: <20200608094030.670121-9-mlevitsk@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
block/qcow2.c | 71 +++++++++++++++++++++++++++++++++-----
13
tests/qemu-iotests/082.out | 45 ++++++++++++++++++++++++
14
2 files changed, 107 insertions(+), 9 deletions(-)
15
16
diff --git a/block/qcow2.c b/block/qcow2.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2.c
19
+++ b/block/qcow2.c
20
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,
21
return ret;
22
}
23
24
+static QDict*
25
+qcow2_extract_crypto_opts(QemuOpts *opts, const char *fmt, Error **errp)
26
+{
27
+ QDict *cryptoopts_qdict;
28
+ QDict *opts_qdict;
29
+
30
+ /* Extract "encrypt." options into a qdict */
31
+ opts_qdict = qemu_opts_to_qdict(opts, NULL);
32
+ qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, "encrypt.");
33
+ qobject_unref(opts_qdict);
34
+ qdict_put_str(cryptoopts_qdict, "format", fmt);
35
+ return cryptoopts_qdict;
36
+}
37
38
/*
39
* read qcow2 extension and fill bs
40
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
41
42
if (has_luks) {
43
g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
44
- QDict *opts_qdict;
45
- QDict *cryptoopts;
46
+ QDict *cryptoopts = qcow2_extract_crypto_opts(opts, "luks", errp);
47
size_t headerlen;
48
49
- opts_qdict = qemu_opts_to_qdict(opts, NULL);
50
- qdict_extract_subqdict(opts_qdict, &cryptoopts, "encrypt.");
51
- qobject_unref(opts_qdict);
52
-
53
- qdict_put_str(cryptoopts, "format", "luks");
54
-
55
create_opts = block_crypto_create_opts_init(cryptoopts, errp);
56
qobject_unref(cryptoopts);
57
if (!create_opts) {
58
@@ -XXX,XX +XXX,XX @@ typedef enum Qcow2AmendOperation {
59
QCOW2_NO_OPERATION = 0,
60
61
QCOW2_UPGRADING,
62
+ QCOW2_UPDATING_ENCRYPTION,
63
QCOW2_CHANGING_REFCOUNT_ORDER,
64
QCOW2_DOWNGRADING,
65
} Qcow2AmendOperation;
66
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
67
int ret;
68
QemuOptDesc *desc = opts->list->desc;
69
Qcow2AmendHelperCBInfo helper_cb_info;
70
+ bool encryption_update = false;
71
72
while (desc && desc->name) {
73
if (!qemu_opt_find(opts, desc->name)) {
74
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
75
backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
76
} else if (!strcmp(desc->name, BLOCK_OPT_BACKING_FMT)) {
77
backing_format = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
78
+ } else if (g_str_has_prefix(desc->name, "encrypt.")) {
79
+ if (!s->crypto) {
80
+ error_setg(errp,
81
+ "Can't amend encryption options - encryption not present");
82
+ return -EINVAL;
83
+ }
84
+ if (s->crypt_method_header != QCOW_CRYPT_LUKS) {
85
+ error_setg(errp,
86
+ "Only LUKS encryption options can be amended");
87
+ return -ENOTSUP;
88
+ }
89
+ encryption_update = true;
90
} else if (!strcmp(desc->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
91
lazy_refcounts = qemu_opt_get_bool(opts, BLOCK_OPT_LAZY_REFCOUNTS,
92
lazy_refcounts);
93
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
94
.original_status_cb = status_cb,
95
.original_cb_opaque = cb_opaque,
96
.total_operations = (new_version != old_version)
97
- + (s->refcount_bits != refcount_bits)
98
+ + (s->refcount_bits != refcount_bits) +
99
+ (encryption_update == true)
100
};
101
102
/* Upgrade first (some features may require compat=1.1) */
103
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
104
}
105
}
106
107
+ if (encryption_update) {
108
+ QDict *amend_opts_dict;
109
+ QCryptoBlockAmendOptions *amend_opts;
110
+
111
+ helper_cb_info.current_operation = QCOW2_UPDATING_ENCRYPTION;
112
+ amend_opts_dict = qcow2_extract_crypto_opts(opts, "luks", errp);
113
+ if (!amend_opts_dict) {
114
+ return -EINVAL;
115
+ }
116
+ amend_opts = block_crypto_amend_opts_init(amend_opts_dict, errp);
117
+ qobject_unref(amend_opts_dict);
118
+ if (!amend_opts) {
119
+ return -EINVAL;
120
+ }
121
+ ret = qcrypto_block_amend_options(s->crypto,
122
+ qcow2_crypto_hdr_read_func,
123
+ qcow2_crypto_hdr_write_func,
124
+ bs,
125
+ amend_opts,
126
+ force,
127
+ errp);
128
+ qapi_free_QCryptoBlockAmendOptions(amend_opts);
129
+ if (ret < 0) {
130
+ return ret;
131
+ }
132
+ }
133
+
134
if (s->refcount_bits != refcount_bits) {
135
int refcount_order = ctz32(refcount_bits);
136
137
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_amend_opts = {
138
.name = "qcow2-amend-opts",
139
.head = QTAILQ_HEAD_INITIALIZER(qcow2_amend_opts.head),
140
.desc = {
141
+ BLOCK_CRYPTO_OPT_DEF_LUKS_STATE("encrypt."),
142
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT("encrypt."),
143
+ BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET("encrypt."),
144
+ BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET("encrypt."),
145
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."),
146
QCOW_COMMON_OPTIONS,
147
{ /* end of list */ }
148
}
149
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
150
index XXXXXXX..XXXXXXX 100644
151
--- a/tests/qemu-iotests/082.out
152
+++ b/tests/qemu-iotests/082.out
153
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
154
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
155
data_file=<str> - File name of an external data file
156
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
157
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
158
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
159
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
160
+ encrypt.old-secret=<str> - Select all keyslots that match this password
161
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
162
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
163
refcount_bits=<num> - Width of a reference count entry in bits
164
size=<size> - Virtual disk size
165
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
166
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
167
data_file=<str> - File name of an external data file
168
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
169
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
170
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
171
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
172
+ encrypt.old-secret=<str> - Select all keyslots that match this password
173
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
174
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
175
refcount_bits=<num> - Width of a reference count entry in bits
176
size=<size> - Virtual disk size
177
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
178
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
179
data_file=<str> - File name of an external data file
180
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
181
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
182
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
183
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
184
+ encrypt.old-secret=<str> - Select all keyslots that match this password
185
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
186
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
187
refcount_bits=<num> - Width of a reference count entry in bits
188
size=<size> - Virtual disk size
189
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
190
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
191
data_file=<str> - File name of an external data file
192
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
193
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
194
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
195
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
196
+ encrypt.old-secret=<str> - Select all keyslots that match this password
197
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
198
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
199
refcount_bits=<num> - Width of a reference count entry in bits
200
size=<size> - Virtual disk size
201
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
202
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
203
data_file=<str> - File name of an external data file
204
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
205
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
206
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
207
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
208
+ encrypt.old-secret=<str> - Select all keyslots that match this password
209
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
210
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
211
refcount_bits=<num> - Width of a reference count entry in bits
212
size=<size> - Virtual disk size
213
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
214
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
215
data_file=<str> - File name of an external data file
216
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
217
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
218
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
219
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
220
+ encrypt.old-secret=<str> - Select all keyslots that match this password
221
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
222
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
223
refcount_bits=<num> - Width of a reference count entry in bits
224
size=<size> - Virtual disk size
225
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
226
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
227
data_file=<str> - File name of an external data file
228
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
229
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
230
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
231
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
232
+ encrypt.old-secret=<str> - Select all keyslots that match this password
233
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
234
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
235
refcount_bits=<num> - Width of a reference count entry in bits
236
size=<size> - Virtual disk size
237
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
238
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
239
data_file=<str> - File name of an external data file
240
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
241
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
242
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
243
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
244
+ encrypt.old-secret=<str> - Select all keyslots that match this password
245
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
246
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
247
refcount_bits=<num> - Width of a reference count entry in bits
248
size=<size> - Virtual disk size
249
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
250
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
251
data_file=<str> - File name of an external data file
252
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
253
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
254
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
255
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
256
+ encrypt.old-secret=<str> - Select all keyslots that match this password
257
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
258
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
259
refcount_bits=<num> - Width of a reference count entry in bits
260
size=<size> - Virtual disk size
261
--
262
2.26.2
263
264
diff view generated by jsdifflib
New patch
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
2
3
This commit adds two tests, which test the new amend interface
4
of both luks raw images and qcow2 luks encrypted images.
5
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
7
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
8
[mreitz: Let 293 verify that LUKS works; drop $(seq) usage from 293;
9
drop 293 and 294 from the auto group]
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Message-Id: <20200625125548.870061-16-mreitz@redhat.com>
12
---
13
tests/qemu-iotests/293 | 208 +++++++++++++++++++++++++++++++++++++
14
tests/qemu-iotests/293.out | 99 ++++++++++++++++++
15
tests/qemu-iotests/294 | 90 ++++++++++++++++
16
tests/qemu-iotests/294.out | 30 ++++++
17
tests/qemu-iotests/group | 2 +
18
5 files changed, 429 insertions(+)
19
create mode 100755 tests/qemu-iotests/293
20
create mode 100644 tests/qemu-iotests/293.out
21
create mode 100755 tests/qemu-iotests/294
22
create mode 100644 tests/qemu-iotests/294.out
23
24
diff --git a/tests/qemu-iotests/293 b/tests/qemu-iotests/293
25
new file mode 100755
26
index XXXXXXX..XXXXXXX
27
--- /dev/null
28
+++ b/tests/qemu-iotests/293
29
@@ -XXX,XX +XXX,XX @@
30
+#!/usr/bin/env bash
31
+#
32
+# Test encryption key management with luks
33
+# Based on 134
34
+#
35
+# Copyright (C) 2019 Red Hat, Inc.
36
+#
37
+# This program is free software; you can redistribute it and/or modify
38
+# it under the terms of the GNU General Public License as published by
39
+# the Free Software Foundation; either version 2 of the License, or
40
+# (at your option) any later version.
41
+#
42
+# This program is distributed in the hope that it will be useful,
43
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
44
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45
+# GNU General Public License for more details.
46
+#
47
+# You should have received a copy of the GNU General Public License
48
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
49
+#
50
+
51
+# creator
52
+owner=mlevitsk@redhat.com
53
+
54
+seq=`basename $0`
55
+echo "QA output created by $seq"
56
+
57
+status=1    # failure is the default!
58
+
59
+_cleanup()
60
+{
61
+    _cleanup_test_img
62
+}
63
+trap "_cleanup; exit \$status" 0 1 2 3 15
64
+
65
+# get standard environment, filters and checks
66
+. ./common.rc
67
+. ./common.filter
68
+
69
+_supported_fmt qcow2 luks
70
+_supported_proto file #TODO
71
+_require_working_luks
72
+
73
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
74
+
75
+if [ "$IMGFMT" = "qcow2" ] ; then
76
+    PR="encrypt."
77
+    EXTRA_IMG_ARGS="-o encrypt.format=luks"
78
+fi
79
+
80
+
81
+# secrets: you are supposed to see the password as *******, see :-)
82
+S0="--object secret,id=sec0,data=hunter0"
83
+S1="--object secret,id=sec1,data=hunter1"
84
+S2="--object secret,id=sec2,data=hunter2"
85
+S3="--object secret,id=sec3,data=hunter3"
86
+S4="--object secret,id=sec4,data=hunter4"
87
+SECRETS="$S0 $S1 $S2 $S3 $S4"
88
+
89
+# image with given secret
90
+IMGS0="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec0"
91
+IMGS1="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec1"
92
+IMGS2="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec2"
93
+IMGS3="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec3"
94
+IMGS4="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec4"
95
+
96
+
97
+echo "== creating a test image =="
98
+_make_test_img $S0 $EXTRA_IMG_ARGS -o ${PR}key-secret=sec0,${PR}iter-time=10 32M
99
+
100
+echo
101
+echo "== test that key 0 opens the image =="
102
+$QEMU_IO $S0 -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
103
+
104
+echo
105
+echo "== adding a password to slot 4 =="
106
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec4,${PR}iter-time=10,${PR}keyslot=4
107
+echo "== adding a password to slot 1 =="
108
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}iter-time=10
109
+echo "== adding a password to slot 3 =="
110
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10,${PR}keyslot=3
111
+
112
+echo "== adding a password to slot 2 =="
113
+$QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec2,${PR}iter-time=10
114
+
115
+
116
+echo "== erase slot 4 =="
117
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=4 | _filter_img_create
118
+
119
+
120
+echo
121
+echo "== all secrets should work =="
122
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
123
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
124
+done
125
+
126
+echo
127
+echo "== erase slot 0 and try it =="
128
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec0 | _filter_img_create
129
+$QEMU_IO $SECRETS -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
130
+
131
+echo
132
+echo "== erase slot 2 and try it =="
133
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=2 | _filter_img_create
134
+$QEMU_IO $SECRETS -c "read 0 4096" $IMGS2 | _filter_qemu_io | _filter_testdir
135
+
136
+
137
+# at this point slots 1 and 3 should be active
138
+
139
+echo
140
+echo "== filling 4 slots with secret 2 =="
141
+for ((i = 0; i < 4; i++)); do
142
+    $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec2,${PR}iter-time=10
143
+done
144
+
145
+echo
146
+echo "== adding secret 0 =="
147
+    $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec0,${PR}iter-time=10
148
+
149
+echo
150
+echo "== adding secret 3 (last slot) =="
151
+    $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10
152
+
153
+echo
154
+echo "== trying to add another slot (should fail) =="
155
+$QEMU_IMG amend $SECRETS $IMGS2 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10
156
+
157
+echo
158
+echo "== all secrets should work again =="
159
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
160
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
161
+done
162
+
163
+
164
+echo
165
+
166
+echo "== erase all keys of secret 2=="
167
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec2
168
+
169
+echo "== erase all keys of secret 1=="
170
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec1
171
+
172
+echo "== erase all keys of secret 0=="
173
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=inactive,${PR}old-secret=sec0
174
+
175
+echo "== erasing secret3 will fail now since it is the only secret (in 3 slots) =="
176
+$QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=inactive,${PR}old-secret=sec3
177
+
178
+echo
179
+echo "== only secret3 should work now =="
180
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
181
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
182
+done
183
+
184
+echo
185
+echo "== add secret0 =="
186
+$QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec0,${PR}iter-time=10
187
+
188
+echo "== erase secret3 =="
189
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=inactive,${PR}old-secret=sec3
190
+
191
+echo
192
+echo "== only secret0 should work now =="
193
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
194
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
195
+done
196
+
197
+echo
198
+echo "== replace secret0 with secret1 (should fail) =="
199
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}keyslot=0
200
+
201
+echo
202
+echo "== replace secret0 with secret1 with force (should work) =="
203
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}iter-time=10,${PR}keyslot=0 --force
204
+
205
+echo
206
+echo "== only secret1 should work now =="
207
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
208
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
209
+done
210
+
211
+
212
+echo
213
+echo "== erase last secret (should fail) =="
214
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=0
215
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec1
216
+
217
+
218
+echo "== erase non existing secrets (should fail) =="
219
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec5 --force
220
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec0 --force
221
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=1 --force
222
+
223
+echo
224
+echo "== erase last secret with force by slot (should work) =="
225
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=0 --force
226
+
227
+echo
228
+echo "== we have no secrets now, data is lost forever =="
229
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
230
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
231
+done
232
+
233
+# success, all done
234
+echo "*** done"
235
+rm -f $seq.full
236
+status=0
237
+
238
diff --git a/tests/qemu-iotests/293.out b/tests/qemu-iotests/293.out
239
new file mode 100644
240
index XXXXXXX..XXXXXXX
241
--- /dev/null
242
+++ b/tests/qemu-iotests/293.out
243
@@ -XXX,XX +XXX,XX @@
244
+QA output created by 293
245
+== creating a test image ==
246
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432
247
+
248
+== test that key 0 opens the image ==
249
+read 4096/4096 bytes at offset 0
250
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
251
+
252
+== adding a password to slot 4 ==
253
+== adding a password to slot 1 ==
254
+== adding a password to slot 3 ==
255
+== adding a password to slot 2 ==
256
+== erase slot 4 ==
257
+
258
+== all secrets should work ==
259
+read 4096/4096 bytes at offset 0
260
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
261
+read 4096/4096 bytes at offset 0
262
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
263
+read 4096/4096 bytes at offset 0
264
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
265
+read 4096/4096 bytes at offset 0
266
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
267
+
268
+== erase slot 0 and try it ==
269
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
270
+
271
+== erase slot 2 and try it ==
272
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
273
+
274
+== filling 4 slots with secret 2 ==
275
+
276
+== adding secret 0 ==
277
+
278
+== adding secret 3 (last slot) ==
279
+
280
+== trying to add another slot (should fail) ==
281
+qemu-img: Can't add a keyslot - all keyslots are in use
282
+
283
+== all secrets should work again ==
284
+read 4096/4096 bytes at offset 0
285
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
286
+read 4096/4096 bytes at offset 0
287
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
288
+read 4096/4096 bytes at offset 0
289
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
290
+read 4096/4096 bytes at offset 0
291
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
292
+
293
+== erase all keys of secret 2==
294
+== erase all keys of secret 1==
295
+== erase all keys of secret 0==
296
+== erasing secret3 will fail now since it is the only secret (in 3 slots) ==
297
+qemu-img: All the active keyslots match the (old) password that was given and erasing them will erase all the data in the image irreversibly - refusing operation
298
+
299
+== only secret3 should work now ==
300
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
301
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
302
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
303
+read 4096/4096 bytes at offset 0
304
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
305
+
306
+== add secret0 ==
307
+== erase secret3 ==
308
+
309
+== only secret0 should work now ==
310
+read 4096/4096 bytes at offset 0
311
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
312
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
313
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
314
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
315
+
316
+== replace secret0 with secret1 (should fail) ==
317
+qemu-img: Refusing to overwrite active keyslot 0 - please erase it first
318
+
319
+== replace secret0 with secret1 with force (should work) ==
320
+
321
+== only secret1 should work now ==
322
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
323
+read 4096/4096 bytes at offset 0
324
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
325
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
326
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
327
+
328
+== erase last secret (should fail) ==
329
+qemu-img: Attempt to erase the only active keyslot 0 which will erase all the data in the image irreversibly - refusing operation
330
+qemu-img: All the active keyslots match the (old) password that was given and erasing them will erase all the data in the image irreversibly - refusing operation
331
+== erase non existing secrets (should fail) ==
332
+qemu-img: No secret with id 'sec5'
333
+qemu-img: No keyslots match given (old) password for erase operation
334
+
335
+== erase last secret with force by slot (should work) ==
336
+
337
+== we have no secrets now, data is lost forever ==
338
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
339
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
340
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
341
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
342
+*** done
343
diff --git a/tests/qemu-iotests/294 b/tests/qemu-iotests/294
344
new file mode 100755
345
index XXXXXXX..XXXXXXX
346
--- /dev/null
347
+++ b/tests/qemu-iotests/294
348
@@ -XXX,XX +XXX,XX @@
349
+#
350
+# Copyright (C) 2019 Red Hat, Inc.
351
+#
352
+# This program is free software; you can redistribute it and/or modify
353
+# it under the terms of the GNU General Public License as published by
354
+# the Free Software Foundation; either version 2 of the License, or
355
+# (at your option) any later version.
356
+#
357
+# This program is distributed in the hope that it will be useful,
358
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
359
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
360
+# GNU General Public License for more details.
361
+#
362
+# You should have received a copy of the GNU General Public License
363
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
364
+#
365
+
366
+# creator
367
+owner=mlevitsk@redhat.com
368
+
369
+seq=`basename $0`
370
+echo "QA output created by $seq"
371
+
372
+status=1    # failure is the default!
373
+
374
+_cleanup()
375
+{
376
+    _cleanup_test_img
377
+}
378
+trap "_cleanup; exit \$status" 0 1 2 3 15
379
+
380
+# get standard environment, filters and checks
381
+. ./common.rc
382
+. ./common.filter
383
+
384
+_supported_fmt luks
385
+_supported_proto file #TODO
386
+
387
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
388
+
389
+# you are supposed to see the password as *******, see :-)
390
+S0="--object secret,id=sec0,data=hunter0"
391
+S1="--object secret,id=sec1,data=hunter1"
392
+SECRETS="$S0 $S1"
393
+
394
+
395
+IMGS0="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,key-secret=sec0"
396
+IMGS1="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,key-secret=sec1"
397
+
398
+echo "== creating a test image =="
399
+_make_test_img $S0 -o "key-secret=sec0,iter-time=10" 32M
400
+
401
+echo
402
+echo "== test that key 0 opens the image =="
403
+$QEMU_IO $S0 -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
404
+
405
+echo
406
+echo "== adding a password to slot 1 =="
407
+$QEMU_IMG amend $SECRETS $IMGS0 -o state=active,new-secret=sec1,keyslot=1,iter-time=10
408
+
409
+echo
410
+echo "== 'backup' the image header =="
411
+dd if=$TEST_IMG_FILE of=${TEST_IMG_FILE}.bk bs=4K skip=0 count=1
412
+
413
+echo
414
+echo "== erase slot 0 =="
415
+$QEMU_IMG amend $SECRETS $IMGS1 -o state=inactive,keyslot=0 | _filter_img_create
416
+
417
+echo
418
+echo "== test that key 0 doesn't open the image =="
419
+$QEMU_IO $S0 -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
420
+
421
+echo
422
+echo "== 'restore' the image header =="
423
+dd if=${TEST_IMG_FILE}.bk of=${TEST_IMG_FILE} bs=4K skip=0 count=1 conv=notrunc
424
+
425
+echo
426
+echo "== test that key 0 still doesn't open the image (key material is erased) =="
427
+$QEMU_IO $SECRETS -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
428
+
429
+echo
430
+echo "== test that key 1 still works =="
431
+$QEMU_IO $SECRETS -c "read 0 4096" $IMGS1 | _filter_qemu_io | _filter_testdir
432
+
433
+echo "*** done"
434
+rm -f $seq.full
435
+status=0
436
+
437
+
438
+exit 0
439
diff --git a/tests/qemu-iotests/294.out b/tests/qemu-iotests/294.out
440
new file mode 100644
441
index XXXXXXX..XXXXXXX
442
--- /dev/null
443
+++ b/tests/qemu-iotests/294.out
444
@@ -XXX,XX +XXX,XX @@
445
+QA output created by 294
446
+== creating a test image ==
447
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432
448
+
449
+== test that key 0 opens the image ==
450
+read 4096/4096 bytes at offset 0
451
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
452
+
453
+== adding a password to slot 1 ==
454
+
455
+== 'backup' the image header ==
456
+1+0 records in
457
+1+0 records out
458
+
459
+== erase slot 0 ==
460
+
461
+== test that key 0 doesn't open the image ==
462
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
463
+
464
+== 'restore' the image header ==
465
+1+0 records in
466
+1+0 records out
467
+
468
+== test that key 0 still doesn't open the image (key material is erased) ==
469
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
470
+
471
+== test that key 1 still works ==
472
+read 4096/4096 bytes at offset 0
473
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
474
+*** done
475
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
476
index XXXXXXX..XXXXXXX 100644
477
--- a/tests/qemu-iotests/group
478
+++ b/tests/qemu-iotests/group
479
@@ -XXX,XX +XXX,XX @@
480
290 rw auto quick
481
291 rw quick
482
292 rw auto quick
483
+293 rw
484
+294 rw quick
485
297 meta
486
--
487
2.26.2
488
489
diff view generated by jsdifflib
New patch
1
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
3
blockdev-amend will be used similiar to blockdev-create
4
to allow on the fly changes of the structure of the format based block devices.
5
6
Current plan is to first support encryption keyslot management for luks
7
based formats (raw and embedded in qcow2)
8
9
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
10
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
11
Message-Id: <20200608094030.670121-12-mlevitsk@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
qapi/block-core.json | 42 ++++++++++++++
15
qapi/job.json | 4 +-
16
include/block/block_int.h | 21 +++++--
17
block/amend.c | 113 ++++++++++++++++++++++++++++++++++++++
18
block/Makefile.objs | 2 +-
19
5 files changed, 174 insertions(+), 8 deletions(-)
20
create mode 100644 block/amend.c
21
22
diff --git a/qapi/block-core.json b/qapi/block-core.json
23
index XXXXXXX..XXXXXXX 100644
24
--- a/qapi/block-core.json
25
+++ b/qapi/block-core.json
26
@@ -XXX,XX +XXX,XX @@
27
'data': { 'job-id': 'str',
28
'options': 'BlockdevCreateOptions' } }
29
30
+##
31
+# @BlockdevAmendOptions:
32
+#
33
+# Options for amending an image format
34
+#
35
+# @driver: Block driver of the node to amend.
36
+#
37
+# Since: 5.1
38
+##
39
+{ 'union': 'BlockdevAmendOptions',
40
+ 'base': {
41
+ 'driver': 'BlockdevDriver' },
42
+ 'discriminator': 'driver',
43
+ 'data': {
44
+ } }
45
+
46
+##
47
+# @x-blockdev-amend:
48
+#
49
+# Starts a job to amend format specific options of an existing open block device
50
+# The job is automatically finalized, but a manual job-dismiss is required.
51
+#
52
+# @job-id: Identifier for the newly created job.
53
+#
54
+# @node-name: Name of the block node to work on
55
+#
56
+# @options: Options (driver specific)
57
+#
58
+# @force: Allow unsafe operations, format specific
59
+# For luks that allows erase of the last active keyslot
60
+# (permanent loss of data),
61
+# and replacement of an active keyslot
62
+# (possible loss of data if IO error happens)
63
+#
64
+# Since: 5.1
65
+##
66
+{ 'command': 'x-blockdev-amend',
67
+ 'data': { 'job-id': 'str',
68
+ 'node-name': 'str',
69
+ 'options': 'BlockdevAmendOptions',
70
+ '*force': 'bool' } }
71
+
72
##
73
# @BlockErrorAction:
74
#
75
diff --git a/qapi/job.json b/qapi/job.json
76
index XXXXXXX..XXXXXXX 100644
77
--- a/qapi/job.json
78
+++ b/qapi/job.json
79
@@ -XXX,XX +XXX,XX @@
80
#
81
# @create: image creation job type, see "blockdev-create" (since 3.0)
82
#
83
+# @amend: image options amend job type, see "x-blockdev-amend" (since 5.1)
84
+#
85
# Since: 1.7
86
##
87
{ 'enum': 'JobType',
88
- 'data': ['commit', 'stream', 'mirror', 'backup', 'create'] }
89
+ 'data': ['commit', 'stream', 'mirror', 'backup', 'create', 'amend'] }
90
91
##
92
# @JobStatus:
93
diff --git a/include/block/block_int.h b/include/block/block_int.h
94
index XXXXXXX..XXXXXXX 100644
95
--- a/include/block/block_int.h
96
+++ b/include/block/block_int.h
97
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
98
int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags,
99
Error **errp);
100
void (*bdrv_close)(BlockDriverState *bs);
101
+
102
+
103
int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts,
104
Error **errp);
105
int coroutine_fn (*bdrv_co_create_opts)(BlockDriver *drv,
106
const char *filename,
107
QemuOpts *opts,
108
Error **errp);
109
+
110
+ int coroutine_fn (*bdrv_co_amend)(BlockDriverState *bs,
111
+ BlockdevAmendOptions *opts,
112
+ bool force,
113
+ Error **errp);
114
+
115
+ int (*bdrv_amend_options)(BlockDriverState *bs,
116
+ QemuOpts *opts,
117
+ BlockDriverAmendStatusCB *status_cb,
118
+ void *cb_opaque,
119
+ bool force,
120
+ Error **errp);
121
+
122
int (*bdrv_make_empty)(BlockDriverState *bs);
123
124
/*
125
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
126
BdrvCheckResult *result,
127
BdrvCheckMode fix);
128
129
- int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
130
- BlockDriverAmendStatusCB *status_cb,
131
- void *cb_opaque,
132
- bool force,
133
- Error **errp);
134
-
135
void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
136
137
/* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
138
diff --git a/block/amend.c b/block/amend.c
139
new file mode 100644
140
index XXXXXXX..XXXXXXX
141
--- /dev/null
142
+++ b/block/amend.c
143
@@ -XXX,XX +XXX,XX @@
144
+/*
145
+ * Block layer code related to image options amend
146
+ *
147
+ * Copyright (c) 2018 Kevin Wolf <kwolf@redhat.com>
148
+ * Copyright (c) 2020 Red Hat. Inc
149
+ *
150
+ * Heavily based on create.c
151
+ *
152
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
153
+ * of this software and associated documentation files (the "Software"), to deal
154
+ * in the Software without restriction, including without limitation the rights
155
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
156
+ * copies of the Software, and to permit persons to whom the Software is
157
+ * furnished to do so, subject to the following conditions:
158
+ *
159
+ * The above copyright notice and this permission notice shall be included in
160
+ * all copies or substantial portions of the Software.
161
+ *
162
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
163
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
165
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
166
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
167
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
168
+ * THE SOFTWARE.
169
+ */
170
+
171
+#include "qemu/osdep.h"
172
+#include "block/block_int.h"
173
+#include "qemu/job.h"
174
+#include "qemu/main-loop.h"
175
+#include "qapi/qapi-commands-block-core.h"
176
+#include "qapi/qapi-visit-block-core.h"
177
+#include "qapi/clone-visitor.h"
178
+#include "qapi/error.h"
179
+
180
+typedef struct BlockdevAmendJob {
181
+ Job common;
182
+ BlockdevAmendOptions *opts;
183
+ BlockDriverState *bs;
184
+ bool force;
185
+} BlockdevAmendJob;
186
+
187
+static int coroutine_fn blockdev_amend_run(Job *job, Error **errp)
188
+{
189
+ BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
190
+ int ret;
191
+
192
+ job_progress_set_remaining(&s->common, 1);
193
+ ret = s->bs->drv->bdrv_co_amend(s->bs, s->opts, s->force, errp);
194
+ job_progress_update(&s->common, 1);
195
+ qapi_free_BlockdevAmendOptions(s->opts);
196
+ return ret;
197
+}
198
+
199
+static const JobDriver blockdev_amend_job_driver = {
200
+ .instance_size = sizeof(BlockdevAmendJob),
201
+ .job_type = JOB_TYPE_AMEND,
202
+ .run = blockdev_amend_run,
203
+};
204
+
205
+void qmp_x_blockdev_amend(const char *job_id,
206
+ const char *node_name,
207
+ BlockdevAmendOptions *options,
208
+ bool has_force,
209
+ bool force,
210
+ Error **errp)
211
+{
212
+ BlockdevAmendJob *s;
213
+ const char *fmt = BlockdevDriver_str(options->driver);
214
+ BlockDriver *drv = bdrv_find_format(fmt);
215
+ BlockDriverState *bs = bdrv_find_node(node_name);
216
+
217
+
218
+ if (!drv) {
219
+ error_setg(errp, "Block driver '%s' not found or not supported", fmt);
220
+ return;
221
+ }
222
+
223
+ /*
224
+ * If the driver is in the schema, we know that it exists. But it may not
225
+ * be whitelisted.
226
+ */
227
+ if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
228
+ error_setg(errp, "Driver is not whitelisted");
229
+ return;
230
+ }
231
+
232
+ if (bs->drv != drv) {
233
+ error_setg(errp,
234
+ "x-blockdev-amend doesn't support changing the block driver");
235
+ return;
236
+ }
237
+
238
+ /* Error out if the driver doesn't support .bdrv_co_amend */
239
+ if (!drv->bdrv_co_amend) {
240
+ error_setg(errp, "Driver does not support x-blockdev-amend");
241
+ return;
242
+ }
243
+
244
+ /* Create the block job */
245
+ s = job_create(job_id, &blockdev_amend_job_driver, NULL,
246
+ bdrv_get_aio_context(bs), JOB_DEFAULT | JOB_MANUAL_DISMISS,
247
+ NULL, NULL, errp);
248
+ if (!s) {
249
+ return;
250
+ }
251
+
252
+ s->bs = bs,
253
+ s->opts = QAPI_CLONE(BlockdevAmendOptions, options),
254
+ s->force = has_force ? force : false;
255
+ job_start(&s->common);
256
+}
257
diff --git a/block/Makefile.objs b/block/Makefile.objs
258
index XXXXXXX..XXXXXXX 100644
259
--- a/block/Makefile.objs
260
+++ b/block/Makefile.objs
261
@@ -XXX,XX +XXX,XX @@ block-obj-$(CONFIG_WIN32) += file-win32.o win32-aio.o
262
block-obj-$(CONFIG_POSIX) += file-posix.o
263
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
264
block-obj-$(CONFIG_LINUX_IO_URING) += io_uring.o
265
-block-obj-y += null.o mirror.o commit.o io.o create.o
266
+block-obj-y += null.o mirror.o commit.o io.o create.o amend.o
267
block-obj-y += throttle-groups.o
268
block-obj-$(CONFIG_LINUX) += nvme.o
269
270
--
271
2.26.2
272
273
diff view generated by jsdifflib
1
This makes iotest 033 pass with e.g. subformat=monolithicFlat. It also
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
turns a former error in 059 into success.
3
2
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
5
Message-id: 20190815153638.4600-3-mreitz@redhat.com
4
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Message-Id: <20200608094030.670121-13-mlevitsk@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
8
---
9
block/vmdk.c | 54 ++++++++++++++++++++++++--------------
9
qapi/block-core.json | 14 ++++++++-
10
tests/qemu-iotests/059 | 7 +++--
10
block/crypto.c | 72 ++++++++++++++++++++++++++++++++------------
11
tests/qemu-iotests/059.out | 4 ++-
11
2 files changed, 66 insertions(+), 20 deletions(-)
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/qapi/block-core.json b/qapi/block-core.json
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/block/vmdk.c
15
--- a/qapi/block-core.json
17
+++ b/block/vmdk.c
16
+++ b/qapi/block-core.json
18
@@ -XXX,XX +XXX,XX @@ static const char *next_line(const char *s)
17
@@ -XXX,XX +XXX,XX @@
18
'data': { 'job-id': 'str',
19
'options': 'BlockdevCreateOptions' } }
20
21
+##
22
+# @BlockdevAmendOptionsLUKS:
23
+#
24
+# Driver specific image amend options for LUKS.
25
+#
26
+# Since: 5.1
27
+##
28
+{ 'struct': 'BlockdevAmendOptionsLUKS',
29
+ 'base': 'QCryptoBlockAmendOptionsLUKS',
30
+ 'data': { }
31
+}
32
+
33
##
34
# @BlockdevAmendOptions:
35
#
36
@@ -XXX,XX +XXX,XX @@
37
'driver': 'BlockdevDriver' },
38
'discriminator': 'driver',
39
'data': {
40
- } }
41
+ 'luks': 'BlockdevAmendOptionsLUKS' } }
42
43
##
44
# @x-blockdev-amend:
45
diff --git a/block/crypto.c b/block/crypto.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/crypto.c
48
+++ b/block/crypto.c
49
@@ -XXX,XX +XXX,XX @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
19
}
50
}
20
51
21
static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
52
static int
22
- const char *desc_file_path, QDict *options,
53
-block_crypto_amend_options_luks(BlockDriverState *bs,
23
- Error **errp)
54
- QemuOpts *opts,
24
+ QDict *options, Error **errp)
55
- BlockDriverAmendStatusCB *status_cb,
56
- void *cb_opaque,
57
- bool force,
58
- Error **errp)
59
+block_crypto_amend_options_generic_luks(BlockDriverState *bs,
60
+ QCryptoBlockAmendOptions *amend_options,
61
+ bool force,
62
+ Error **errp)
25
{
63
{
64
BlockCrypto *crypto = bs->opaque;
65
- QDict *cryptoopts = NULL;
66
- QCryptoBlockAmendOptions *amend_options = NULL;
26
int ret;
67
int ret;
27
int matches;
68
28
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
69
assert(crypto);
29
const char *p, *np;
70
assert(crypto->block);
30
int64_t sectors = 0;
71
- crypto->updating_keys = true;
31
int64_t flat_offset;
72
32
+ char *desc_file_dir = NULL;
73
+ /* apply for exclusive read/write permissions to the underlying file*/
33
char *extent_path;
74
+ crypto->updating_keys = true;
34
BdrvChild *extent_file;
75
ret = bdrv_child_refresh_perms(bs, bs->file, errp);
35
BDRVVmdkState *s = bs->opaque;
76
- if (ret < 0) {
36
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
77
- goto cleanup;
37
continue;
78
- }
38
}
79
-
39
80
- cryptoopts = qemu_opts_to_qdict(opts, NULL);
40
- if (!path_is_absolute(fname) && !path_has_protocol(fname) &&
81
- qdict_put_str(cryptoopts, "format", "luks");
41
- !desc_file_path[0])
82
- amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
42
- {
83
- if (!amend_options) {
43
- bdrv_refresh_filename(bs->file->bs);
84
- ret = -EINVAL;
44
- error_setg(errp, "Cannot use relative extent paths with VMDK "
85
+ if (ret) {
45
- "descriptor file '%s'", bs->file->bs->filename);
86
goto cleanup;
46
- return -EINVAL;
47
- }
48
+ if (path_is_absolute(fname)) {
49
+ extent_path = g_strdup(fname);
50
+ } else {
51
+ if (!desc_file_dir) {
52
+ desc_file_dir = bdrv_dirname(bs->file->bs, errp);
53
+ if (!desc_file_dir) {
54
+ bdrv_refresh_filename(bs->file->bs);
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
}
87
}
113
- return 0;
88
89
@@ -XXX,XX +XXX,XX @@ block_crypto_amend_options_luks(BlockDriverState *bs,
90
force,
91
errp);
92
cleanup:
93
+ /* release exclusive read/write permissions to the underlying file*/
94
crypto->updating_keys = false;
95
bdrv_child_refresh_perms(bs, bs->file, errp);
96
- qapi_free_QCryptoBlockAmendOptions(amend_options);
97
+ return ret;
98
+}
114
+
99
+
115
+ ret = 0;
100
+static int
116
+ goto out;
101
+block_crypto_amend_options_luks(BlockDriverState *bs,
117
102
+ QemuOpts *opts,
118
invalid:
103
+ BlockDriverAmendStatusCB *status_cb,
119
np = next_line(p);
104
+ void *cb_opaque,
120
@@ -XXX,XX +XXX,XX @@ invalid:
105
+ bool force,
121
np--;
106
+ Error **errp)
122
}
107
+{
123
error_setg(errp, "Invalid extent line: %.*s", (int)(np - p), p);
108
+ BlockCrypto *crypto = bs->opaque;
124
- return -EINVAL;
109
+ QDict *cryptoopts = NULL;
125
+ ret = -EINVAL;
110
+ QCryptoBlockAmendOptions *amend_options = NULL;
111
+ int ret = -EINVAL;
126
+
112
+
127
+out:
113
+ assert(crypto);
128
+ g_free(desc_file_dir);
114
+ assert(crypto->block);
129
+ return ret;
115
+
130
}
116
+ cryptoopts = qemu_opts_to_qdict(opts, NULL);
131
117
+ qdict_put_str(cryptoopts, "format", "luks");
132
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
118
+ amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
133
@@ -XXX,XX +XXX,XX @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
119
qobject_unref(cryptoopts);
134
}
120
+ if (!amend_options) {
135
s->create_type = g_strdup(ct);
121
+ goto cleanup;
136
s->desc_offset = 0;
122
+ }
137
- ret = vmdk_parse_extents(buf, bs, bs->file->bs->exact_filename, options,
123
+ ret = block_crypto_amend_options_generic_luks(bs, amend_options,
138
- errp);
124
+ force, errp);
139
+ ret = vmdk_parse_extents(buf, bs, options, errp);
125
+cleanup:
140
exit:
126
+ qapi_free_QCryptoBlockAmendOptions(amend_options);
141
return ret;
127
return ret;
142
}
128
}
143
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
129
144
index XXXXXXX..XXXXXXX 100755
130
+static int
145
--- a/tests/qemu-iotests/059
131
+coroutine_fn block_crypto_co_amend_luks(BlockDriverState *bs,
146
+++ b/tests/qemu-iotests/059
132
+ BlockdevAmendOptions *opts,
147
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2
133
+ bool force,
148
134
+ Error **errp)
149
echo
135
+{
150
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
136
+ QCryptoBlockAmendOptions amend_opts;
151
+# Should work, because bdrv_dirname() works fine with blkdebug
137
+
152
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
138
+ amend_opts = (QCryptoBlockAmendOptions) {
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 \
139
+ .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
154
- | _filter_testdir | _filter_imgfmt
140
+ .u.luks = *qapi_BlockdevAmendOptionsLUKS_base(&opts->u.luks),
155
+$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
141
+ };
156
+ -c info \
142
+ return block_crypto_amend_options_generic_luks(bs, &amend_opts,
157
+ 2>&1 \
143
+ force, errp);
158
+ | _filter_testdir | _filter_imgfmt | _filter_img_info
144
+}
159
_cleanup_test_img
145
160
146
static void
161
echo
147
block_crypto_child_perms(BlockDriverState *bs, BdrvChild *c,
162
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
148
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
163
index XXXXXXX..XXXXXXX 100644
149
.bdrv_get_info = block_crypto_get_info_luks,
164
--- a/tests/qemu-iotests/059.out
150
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
165
+++ b/tests/qemu-iotests/059.out
151
.bdrv_amend_options = block_crypto_amend_options_luks,
166
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
152
+ .bdrv_co_amend = block_crypto_co_amend_luks,
167
153
168
=== Testing monolithicFlat with internally generated JSON file name ===
154
.is_format = true,
169
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
155
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
--
156
--
178
2.21.0
157
2.26.2
179
158
180
159
diff view generated by jsdifflib
1
Compressed writes generally have to write full clusters, not just in
1
From: Maxim Levitsky <mlevitsk@redhat.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
Currently the implementation only supports amending the encryption
7
$ qemu-io -c 'write 4k 4k' -c 'read 4k 4k' foo.vmdk
4
options, unlike the qemu-img version
8
wrote 4096/4096 bytes at offset 4096
9
4 KiB, 1 ops; 00.01 sec (443.724 KiB/sec and 110.9309 ops/sec)
10
read failed: Invalid argument
11
5
12
(The technical reason is that vmdk_write_extent() just writes the
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
13
incomplete compressed data actually to offset 4k. When reading the
7
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
14
data, vmdk_read_extent() looks at offset 0 and finds the compressed data
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
15
size to be 0, because that is what it reads from there. This yields an
9
Message-Id: <20200608094030.670121-14-mlevitsk@redhat.com>
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
qapi/block-core.json | 16 +++++++++++++++-
41
1 file changed, 10 insertions(+)
13
block/qcow2.c | 39 +++++++++++++++++++++++++++++++++++++++
14
2 files changed, 54 insertions(+), 1 deletion(-)
42
15
43
diff --git a/block/vmdk.c b/block/vmdk.c
16
diff --git a/qapi/block-core.json b/qapi/block-core.json
44
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
45
--- a/block/vmdk.c
18
--- a/qapi/block-core.json
46
+++ b/block/vmdk.c
19
+++ b/qapi/block-core.json
47
@@ -XXX,XX +XXX,XX @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
20
@@ -XXX,XX +XXX,XX @@
48
if (extent->compressed) {
21
'data': { }
49
void *compressed_data;
22
}
50
23
51
+ /* Only whole clusters */
24
+##
52
+ if (offset_in_cluster ||
25
+# @BlockdevAmendOptionsQcow2:
53
+ n_bytes > (extent->cluster_sectors * SECTOR_SIZE) ||
26
+#
54
+ (n_bytes < (extent->cluster_sectors * SECTOR_SIZE) &&
27
+# Driver specific image amend options for qcow2.
55
+ offset + n_bytes != extent->end_sector * SECTOR_SIZE))
28
+# For now, only encryption options can be amended
56
+ {
29
+#
57
+ ret = -EINVAL;
30
+# @encrypt Encryption options to be amended
58
+ goto out;
31
+#
32
+# Since: 5.1
33
+##
34
+{ 'struct': 'BlockdevAmendOptionsQcow2',
35
+ 'data': { '*encrypt': 'QCryptoBlockAmendOptions' } }
36
+
37
##
38
# @BlockdevAmendOptions:
39
#
40
@@ -XXX,XX +XXX,XX @@
41
'driver': 'BlockdevDriver' },
42
'discriminator': 'driver',
43
'data': {
44
- 'luks': 'BlockdevAmendOptionsLUKS' } }
45
+ 'luks': 'BlockdevAmendOptionsLUKS',
46
+ 'qcow2': 'BlockdevAmendOptionsQcow2' } }
47
48
##
49
# @x-blockdev-amend:
50
diff --git a/block/qcow2.c b/block/qcow2.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/qcow2.c
53
+++ b/block/qcow2.c
54
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
55
return 0;
56
}
57
58
+static int coroutine_fn qcow2_co_amend(BlockDriverState *bs,
59
+ BlockdevAmendOptions *opts,
60
+ bool force,
61
+ Error **errp)
62
+{
63
+ BlockdevAmendOptionsQcow2 *qopts = &opts->u.qcow2;
64
+ BDRVQcow2State *s = bs->opaque;
65
+ int ret = 0;
66
+
67
+ if (qopts->has_encrypt) {
68
+ if (!s->crypto) {
69
+ error_setg(errp, "image is not encrypted, can't amend");
70
+ return -EOPNOTSUPP;
59
+ }
71
+ }
60
+
72
+
61
if (!extent->has_marker) {
73
+ if (qopts->encrypt->format != Q_CRYPTO_BLOCK_FORMAT_LUKS) {
62
ret = -EINVAL;
74
+ error_setg(errp,
63
goto out;
75
+ "Amend can't be used to change the qcow2 encryption format");
76
+ return -EOPNOTSUPP;
77
+ }
78
+
79
+ if (s->crypt_method_header != QCOW_CRYPT_LUKS) {
80
+ error_setg(errp,
81
+ "Only LUKS encryption options can be amended for qcow2 with blockdev-amend");
82
+ return -EOPNOTSUPP;
83
+ }
84
+
85
+ ret = qcrypto_block_amend_options(s->crypto,
86
+ qcow2_crypto_hdr_read_func,
87
+ qcow2_crypto_hdr_write_func,
88
+ bs,
89
+ qopts->encrypt,
90
+ force,
91
+ errp);
92
+ }
93
+ return ret;
94
+}
95
+
96
/*
97
* If offset or size are negative, respectively, they will not be included in
98
* the BLOCK_IMAGE_CORRUPTED event emitted.
99
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
100
.mutable_opts = mutable_opts,
101
.bdrv_co_check = qcow2_co_check,
102
.bdrv_amend_options = qcow2_amend_options,
103
+ .bdrv_co_amend = qcow2_co_amend,
104
105
.bdrv_detach_aio_context = qcow2_detach_aio_context,
106
.bdrv_attach_aio_context = qcow2_attach_aio_context,
64
--
107
--
65
2.21.0
108
2.26.2
66
109
67
110
diff view generated by jsdifflib
New patch
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
2
3
This commit adds two tests that cover the
4
new blockdev-amend functionality of luks and qcow2 driver
5
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
7
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
8
[mreitz: Let 295 verify that LUKS works; drop 295 and 296 from the auto
9
group]
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Message-Id: <20200625125548.870061-20-mreitz@redhat.com>
12
---
13
tests/qemu-iotests/295 | 280 +++++++++++++++++++++++++++++++++++++
14
tests/qemu-iotests/295.out | 40 ++++++
15
tests/qemu-iotests/296 | 234 +++++++++++++++++++++++++++++++
16
tests/qemu-iotests/296.out | 33 +++++
17
tests/qemu-iotests/group | 2 +
18
5 files changed, 589 insertions(+)
19
create mode 100755 tests/qemu-iotests/295
20
create mode 100644 tests/qemu-iotests/295.out
21
create mode 100755 tests/qemu-iotests/296
22
create mode 100644 tests/qemu-iotests/296.out
23
24
diff --git a/tests/qemu-iotests/295 b/tests/qemu-iotests/295
25
new file mode 100755
26
index XXXXXXX..XXXXXXX
27
--- /dev/null
28
+++ b/tests/qemu-iotests/295
29
@@ -XXX,XX +XXX,XX @@
30
+#!/usr/bin/env python3
31
+#
32
+# Test case QMP's encrypted key management
33
+#
34
+# Copyright (C) 2019 Red Hat, Inc.
35
+#
36
+# This program is free software; you can redistribute it and/or modify
37
+# it under the terms of the GNU General Public License as published by
38
+# the Free Software Foundation; either version 2 of the License, or
39
+# (at your option) any later version.
40
+#
41
+# This program is distributed in the hope that it will be useful,
42
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
43
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44
+# GNU General Public License for more details.
45
+#
46
+# You should have received a copy of the GNU General Public License
47
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
48
+#
49
+
50
+import iotests
51
+import os
52
+import time
53
+import json
54
+
55
+test_img = os.path.join(iotests.test_dir, 'test.img')
56
+
57
+class Secret:
58
+ def __init__(self, index):
59
+ self._id = "keysec" + str(index)
60
+ # you are not supposed to see the password...
61
+ self._secret = "hunter" + str(index)
62
+
63
+ def id(self):
64
+ return self._id
65
+
66
+ def secret(self):
67
+ return self._secret
68
+
69
+ def to_cmdline_object(self):
70
+ return [ "secret,id=" + self._id + ",data=" + self._secret]
71
+
72
+ def to_qmp_object(self):
73
+ return { "qom_type" : "secret", "id": self.id(),
74
+ "props": { "data": self.secret() } }
75
+
76
+################################################################################
77
+class EncryptionSetupTestCase(iotests.QMPTestCase):
78
+
79
+ # test case startup
80
+ def setUp(self):
81
+ # start the VM
82
+ self.vm = iotests.VM()
83
+ self.vm.launch()
84
+
85
+ # create the secrets and load 'em into the VM
86
+ self.secrets = [ Secret(i) for i in range(0, 6) ]
87
+ for secret in self.secrets:
88
+ result = self.vm.qmp("object-add", **secret.to_qmp_object())
89
+ self.assert_qmp(result, 'return', {})
90
+
91
+ if iotests.imgfmt == "qcow2":
92
+ self.pfx = "encrypt."
93
+ self.img_opts = [ '-o', "encrypt.format=luks" ]
94
+ else:
95
+ self.pfx = ""
96
+ self.img_opts = []
97
+
98
+ # test case shutdown
99
+ def tearDown(self):
100
+ # stop the VM
101
+ self.vm.shutdown()
102
+
103
+ ###########################################################################
104
+ # create the encrypted block device
105
+ def createImg(self, file, secret):
106
+
107
+ iotests.qemu_img(
108
+ 'create',
109
+ '--object', *secret.to_cmdline_object(),
110
+ '-f', iotests.imgfmt,
111
+ '-o', self.pfx + 'key-secret=' + secret.id(),
112
+ '-o', self.pfx + 'iter-time=10',
113
+ *self.img_opts,
114
+ file,
115
+ '1M')
116
+
117
+ ###########################################################################
118
+ # open an encrypted block device
119
+ def openImageQmp(self, id, file, secret, read_only = False):
120
+
121
+ encrypt_options = {
122
+ 'key-secret' : secret.id()
123
+ }
124
+
125
+ if iotests.imgfmt == "qcow2":
126
+ encrypt_options = {
127
+ 'encrypt': {
128
+ 'format':'luks',
129
+ **encrypt_options
130
+ }
131
+ }
132
+
133
+ result = self.vm.qmp('blockdev-add', **
134
+ {
135
+ 'driver': iotests.imgfmt,
136
+ 'node-name': id,
137
+ 'read-only': read_only,
138
+
139
+ **encrypt_options,
140
+
141
+ 'file': {
142
+ 'driver': 'file',
143
+ 'filename': test_img,
144
+ }
145
+ }
146
+ )
147
+ self.assert_qmp(result, 'return', {})
148
+
149
+ # close the encrypted block device
150
+ def closeImageQmp(self, id):
151
+ result = self.vm.qmp('blockdev-del', **{ 'node-name': id })
152
+ self.assert_qmp(result, 'return', {})
153
+
154
+ ###########################################################################
155
+ # add a key to an encrypted block device
156
+ def addKeyQmp(self, id, new_secret, secret = None,
157
+ slot = None, force = False):
158
+
159
+ crypt_options = {
160
+ 'state' : 'active',
161
+ 'new-secret' : new_secret.id(),
162
+ 'iter-time' : 10
163
+ }
164
+
165
+ if slot != None:
166
+ crypt_options['keyslot'] = slot
167
+
168
+
169
+ if secret != None:
170
+ crypt_options['secret'] = secret.id()
171
+
172
+ if iotests.imgfmt == "qcow2":
173
+ crypt_options['format'] = 'luks'
174
+ crypt_options = {
175
+ 'encrypt': crypt_options
176
+ }
177
+
178
+ args = {
179
+ 'node-name': id,
180
+ 'job-id' : 'job_add_key',
181
+ 'options' : {
182
+ 'driver' : iotests.imgfmt,
183
+ **crypt_options
184
+ },
185
+ }
186
+
187
+ if force == True:
188
+ args['force'] = True
189
+
190
+ #TODO: check what jobs return
191
+ result = self.vm.qmp('x-blockdev-amend', **args)
192
+ assert result['return'] == {}
193
+ self.vm.run_job('job_add_key')
194
+
195
+ # erase a key from an encrypted block device
196
+ def eraseKeyQmp(self, id, old_secret = None, slot = None, force = False):
197
+
198
+ crypt_options = {
199
+ 'state' : 'inactive',
200
+ }
201
+
202
+ if slot != None:
203
+ crypt_options['keyslot'] = slot
204
+ if old_secret != None:
205
+ crypt_options['old-secret'] = old_secret.id()
206
+
207
+ if iotests.imgfmt == "qcow2":
208
+ crypt_options['format'] = 'luks'
209
+ crypt_options = {
210
+ 'encrypt': crypt_options
211
+ }
212
+
213
+ args = {
214
+ 'node-name': id,
215
+ 'job-id' : 'job_erase_key',
216
+ 'options' : {
217
+ 'driver' : iotests.imgfmt,
218
+ **crypt_options
219
+ },
220
+ }
221
+
222
+ if force == True:
223
+ args['force'] = True
224
+
225
+ result = self.vm.qmp('x-blockdev-amend', **args)
226
+ assert result['return'] == {}
227
+ self.vm.run_job('job_erase_key')
228
+
229
+ ###########################################################################
230
+ # create image, and change its key
231
+ def testChangeKey(self):
232
+
233
+ # create the image with secret0 and open it
234
+ self.createImg(test_img, self.secrets[0]);
235
+ self.openImageQmp("testdev", test_img, self.secrets[0])
236
+
237
+ # add key to slot 1
238
+ self.addKeyQmp("testdev", new_secret = self.secrets[1])
239
+
240
+ # add key to slot 5
241
+ self.addKeyQmp("testdev", new_secret = self.secrets[2], slot=5)
242
+
243
+ # erase key from slot 0
244
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[0])
245
+
246
+ #reopen the image with secret1
247
+ self.closeImageQmp("testdev")
248
+ self.openImageQmp("testdev", test_img, self.secrets[1])
249
+
250
+ # close and erase the image for good
251
+ self.closeImageQmp("testdev")
252
+ os.remove(test_img)
253
+
254
+ # test that if we erase the old password,
255
+ # we can still change the encryption keys using 'old-secret'
256
+ def testOldPassword(self):
257
+
258
+ # create the image with secret0 and open it
259
+ self.createImg(test_img, self.secrets[0]);
260
+ self.openImageQmp("testdev", test_img, self.secrets[0])
261
+
262
+ # add key to slot 1
263
+ self.addKeyQmp("testdev", new_secret = self.secrets[1])
264
+
265
+ # erase key from slot 0
266
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[0])
267
+
268
+ # this will fail as the old password is no longer valid
269
+ self.addKeyQmp("testdev", new_secret = self.secrets[2])
270
+
271
+ # this will work
272
+ self.addKeyQmp("testdev", new_secret = self.secrets[2], secret = self.secrets[1])
273
+
274
+ # close and erase the image for good
275
+ self.closeImageQmp("testdev")
276
+ os.remove(test_img)
277
+
278
+ def testUseForceLuke(self):
279
+
280
+ self.createImg(test_img, self.secrets[0]);
281
+ self.openImageQmp("testdev", test_img, self.secrets[0])
282
+
283
+ # Add bunch of secrets
284
+ self.addKeyQmp("testdev", new_secret = self.secrets[1], slot=4)
285
+ self.addKeyQmp("testdev", new_secret = self.secrets[4], slot=2)
286
+
287
+ # overwrite an active secret
288
+ self.addKeyQmp("testdev", new_secret = self.secrets[5], slot=2)
289
+ self.addKeyQmp("testdev", new_secret = self.secrets[5], slot=2, force=True)
290
+
291
+ self.addKeyQmp("testdev", new_secret = self.secrets[0])
292
+
293
+ # Now erase all the secrets
294
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[5])
295
+ self.eraseKeyQmp("testdev", slot=4)
296
+
297
+ # erase last keyslot
298
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[0])
299
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[0], force=True)
300
+
301
+ self.closeImageQmp("testdev")
302
+ os.remove(test_img)
303
+
304
+
305
+if __name__ == '__main__':
306
+ iotests.verify_working_luks()
307
+ # Encrypted formats support
308
+ iotests.activate_logging()
309
+ iotests.main(supported_fmts = ['qcow2', 'luks'])
310
diff --git a/tests/qemu-iotests/295.out b/tests/qemu-iotests/295.out
311
new file mode 100644
312
index XXXXXXX..XXXXXXX
313
--- /dev/null
314
+++ b/tests/qemu-iotests/295.out
315
@@ -XXX,XX +XXX,XX @@
316
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
317
+{"return": {}}
318
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
319
+{"return": {}}
320
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
321
+{"return": {}}
322
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
323
+{"return": {}}
324
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
325
+{"return": {}}
326
+Job failed: Invalid password, cannot unlock any keyslot
327
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
328
+{"return": {}}
329
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
330
+{"return": {}}
331
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
332
+{"return": {}}
333
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
334
+{"return": {}}
335
+Job failed: Refusing to overwrite active keyslot 2 - please erase it first
336
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
337
+{"return": {}}
338
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
339
+{"return": {}}
340
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
341
+{"return": {}}
342
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
343
+{"return": {}}
344
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
345
+{"return": {}}
346
+Job failed: All the active keyslots match the (old) password that was given and erasing them will erase all the data in the image irreversibly - refusing operation
347
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
348
+{"return": {}}
349
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
350
+{"return": {}}
351
+...
352
+----------------------------------------------------------------------
353
+Ran 3 tests
354
+
355
+OK
356
diff --git a/tests/qemu-iotests/296 b/tests/qemu-iotests/296
357
new file mode 100755
358
index XXXXXXX..XXXXXXX
359
--- /dev/null
360
+++ b/tests/qemu-iotests/296
361
@@ -XXX,XX +XXX,XX @@
362
+#!/usr/bin/env python3
363
+#
364
+# Test case for encryption key management versus image sharing
365
+#
366
+# Copyright (C) 2019 Red Hat, Inc.
367
+#
368
+# This program is free software; you can redistribute it and/or modify
369
+# it under the terms of the GNU General Public License as published by
370
+# the Free Software Foundation; either version 2 of the License, or
371
+# (at your option) any later version.
372
+#
373
+# This program is distributed in the hope that it will be useful,
374
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
375
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
376
+# GNU General Public License for more details.
377
+#
378
+# You should have received a copy of the GNU General Public License
379
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
380
+#
381
+
382
+import iotests
383
+import os
384
+import time
385
+import json
386
+
387
+test_img = os.path.join(iotests.test_dir, 'test.img')
388
+
389
+class Secret:
390
+ def __init__(self, index):
391
+ self._id = "keysec" + str(index)
392
+ # you are not supposed to see the password...
393
+ self._secret = "hunter" + str(index)
394
+
395
+ def id(self):
396
+ return self._id
397
+
398
+ def secret(self):
399
+ return self._secret
400
+
401
+ def to_cmdline_object(self):
402
+ return [ "secret,id=" + self._id + ",data=" + self._secret]
403
+
404
+ def to_qmp_object(self):
405
+ return { "qom_type" : "secret", "id": self.id(),
406
+ "props": { "data": self.secret() } }
407
+
408
+################################################################################
409
+
410
+class EncryptionSetupTestCase(iotests.QMPTestCase):
411
+
412
+ # test case startup
413
+ def setUp(self):
414
+
415
+ # start the VMs
416
+ self.vm1 = iotests.VM(path_suffix = 'VM1')
417
+ self.vm2 = iotests.VM(path_suffix = 'VM2')
418
+ self.vm1.launch()
419
+ self.vm2.launch()
420
+
421
+ # create the secrets and load 'em into the VMs
422
+ self.secrets = [ Secret(i) for i in range(0, 4) ]
423
+ for secret in self.secrets:
424
+ result = self.vm1.qmp("object-add", **secret.to_qmp_object())
425
+ self.assert_qmp(result, 'return', {})
426
+ result = self.vm2.qmp("object-add", **secret.to_qmp_object())
427
+ self.assert_qmp(result, 'return', {})
428
+
429
+ # test case shutdown
430
+ def tearDown(self):
431
+ # stop the VM
432
+ self.vm1.shutdown()
433
+ self.vm2.shutdown()
434
+
435
+ ###########################################################################
436
+ # create the encrypted block device using qemu-img
437
+ def createImg(self, file, secret):
438
+
439
+ output = iotests.qemu_img_pipe(
440
+ 'create',
441
+ '--object', *secret.to_cmdline_object(),
442
+ '-f', iotests.imgfmt,
443
+ '-o', 'key-secret=' + secret.id(),
444
+ '-o', 'iter-time=10',
445
+ file,
446
+ '1M')
447
+
448
+ iotests.log(output, filters=[iotests.filter_test_dir])
449
+
450
+ # attempts to add a key using qemu-img
451
+ def addKey(self, file, secret, new_secret):
452
+
453
+ image_options = {
454
+ 'key-secret' : secret.id(),
455
+ 'driver' : iotests.imgfmt,
456
+ 'file' : {
457
+ 'driver':'file',
458
+ 'filename': file,
459
+ }
460
+ }
461
+
462
+ output = iotests.qemu_img_pipe(
463
+ 'amend',
464
+ '--object', *secret.to_cmdline_object(),
465
+ '--object', *new_secret.to_cmdline_object(),
466
+
467
+ '-o', 'state=active',
468
+ '-o', 'new-secret=' + new_secret.id(),
469
+ '-o', 'iter-time=10',
470
+
471
+ "json:" + json.dumps(image_options)
472
+ )
473
+
474
+ iotests.log(output, filters=[iotests.filter_test_dir])
475
+
476
+ ###########################################################################
477
+ # open an encrypted block device
478
+ def openImageQmp(self, vm, id, file, secret,
479
+ readOnly = False, reOpen = False):
480
+
481
+ command = 'x-blockdev-reopen' if reOpen else 'blockdev-add'
482
+
483
+ result = vm.qmp(command, **
484
+ {
485
+ 'driver': iotests.imgfmt,
486
+ 'node-name': id,
487
+ 'read-only': readOnly,
488
+ 'key-secret' : secret.id(),
489
+ 'file': {
490
+ 'driver': 'file',
491
+ 'filename': test_img,
492
+ }
493
+ }
494
+ )
495
+ self.assert_qmp(result, 'return', {})
496
+
497
+ # close the encrypted block device
498
+ def closeImageQmp(self, vm, id):
499
+ result = vm.qmp('blockdev-del', **{ 'node-name': id })
500
+ self.assert_qmp(result, 'return', {})
501
+
502
+ ###########################################################################
503
+
504
+ # add a key to an encrypted block device
505
+ def addKeyQmp(self, vm, id, new_secret):
506
+
507
+ args = {
508
+ 'node-name': id,
509
+ 'job-id' : 'job0',
510
+ 'options' : {
511
+ 'state' : 'active',
512
+ 'driver' : iotests.imgfmt,
513
+ 'new-secret': new_secret.id(),
514
+ 'iter-time' : 10
515
+ },
516
+ }
517
+
518
+ result = vm.qmp('x-blockdev-amend', **args)
519
+ assert result['return'] == {}
520
+ vm.run_job('job0')
521
+
522
+ # test that when the image opened by two qemu processes,
523
+ # neither of them can update the image
524
+ def test1(self):
525
+ self.createImg(test_img, self.secrets[0]);
526
+
527
+ # VM1 opens the image and adds a key
528
+ self.openImageQmp(self.vm1, "testdev", test_img, self.secrets[0])
529
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[1])
530
+
531
+
532
+ # VM2 opens the image
533
+ self.openImageQmp(self.vm2, "testdev", test_img, self.secrets[0])
534
+
535
+
536
+ # neither VMs now should be able to add a key
537
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[2])
538
+ self.addKeyQmp(self.vm2, "testdev", new_secret = self.secrets[2])
539
+
540
+
541
+ # VM 1 closes the image
542
+ self.closeImageQmp(self.vm1, "testdev")
543
+
544
+
545
+ # now VM2 can add the key
546
+ self.addKeyQmp(self.vm2, "testdev", new_secret = self.secrets[2])
547
+
548
+
549
+ # qemu-img should also not be able to add a key
550
+ self.addKey(test_img, self.secrets[0], self.secrets[2])
551
+
552
+ # cleanup
553
+ self.closeImageQmp(self.vm2, "testdev")
554
+ os.remove(test_img)
555
+
556
+
557
+ def test2(self):
558
+ self.createImg(test_img, self.secrets[0]);
559
+
560
+ # VM1 opens the image readonly
561
+ self.openImageQmp(self.vm1, "testdev", test_img, self.secrets[0],
562
+ readOnly = True)
563
+
564
+ # VM2 opens the image
565
+ self.openImageQmp(self.vm2, "testdev", test_img, self.secrets[0])
566
+
567
+ # VM1 can't add a key since image is readonly
568
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[2])
569
+
570
+ # VM2 can't add a key since VM is has the image opened
571
+ self.addKeyQmp(self.vm2, "testdev", new_secret = self.secrets[2])
572
+
573
+
574
+ #VM1 reopens the image read-write
575
+ self.openImageQmp(self.vm1, "testdev", test_img, self.secrets[0],
576
+ reOpen = True, readOnly = False)
577
+
578
+ # VM1 still can't add the key
579
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[2])
580
+
581
+ # VM2 gets away
582
+ self.closeImageQmp(self.vm2, "testdev")
583
+
584
+ # VM1 now can add the key
585
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[2])
586
+
587
+ self.closeImageQmp(self.vm1, "testdev")
588
+ os.remove(test_img)
589
+
590
+
591
+if __name__ == '__main__':
592
+ # support only raw luks since luks encrypted qcow2 is a proper
593
+ # format driver which doesn't allow any sharing
594
+ iotests.activate_logging()
595
+ iotests.main(supported_fmts = ['luks'])
596
diff --git a/tests/qemu-iotests/296.out b/tests/qemu-iotests/296.out
597
new file mode 100644
598
index XXXXXXX..XXXXXXX
599
--- /dev/null
600
+++ b/tests/qemu-iotests/296.out
601
@@ -XXX,XX +XXX,XX @@
602
+Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
603
+
604
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
605
+{"return": {}}
606
+Job failed: Failed to get shared "consistent read" lock
607
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
608
+{"return": {}}
609
+Job failed: Failed to get shared "consistent read" lock
610
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
611
+{"return": {}}
612
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
613
+{"return": {}}
614
+qemu-img: Failed to get shared "consistent read" lock
615
+Is another process using the image [TEST_DIR/test.img]?
616
+
617
+Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
618
+
619
+Job failed: Block node is read-only
620
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
621
+{"return": {}}
622
+Job failed: Failed to get shared "consistent read" lock
623
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
624
+{"return": {}}
625
+Job failed: Failed to get shared "consistent read" lock
626
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
627
+{"return": {}}
628
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
629
+{"return": {}}
630
+..
631
+----------------------------------------------------------------------
632
+Ran 2 tests
633
+
634
+OK
635
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
636
index XXXXXXX..XXXXXXX 100644
637
--- a/tests/qemu-iotests/group
638
+++ b/tests/qemu-iotests/group
639
@@ -XXX,XX +XXX,XX @@
640
292 rw auto quick
641
293 rw
642
294 rw quick
643
+295 rw
644
+296 rw
645
297 meta
646
--
647
2.26.2
648
649
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
qemu-img convert wants to distinguish ZERO which comes from short
4
backing files. unallocated_blocks_are_zero field of bdi is unrelated:
5
space after EOF is always considered to be zero anyway. So, just make
6
post_backing_zero true in case of short backing file.
7
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-Id: <20200528094405.145708-2-vsementsov@virtuozzo.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
qemu-img.c | 4 +---
14
1 file changed, 1 insertion(+), 3 deletions(-)
15
16
diff --git a/qemu-img.c b/qemu-img.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/qemu-img.c
19
+++ b/qemu-img.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct ImgConvertState {
21
BlockBackend *target;
22
bool has_zero_init;
23
bool compressed;
24
- bool unallocated_blocks_are_zero;
25
bool target_is_new;
26
bool target_has_backing;
27
int64_t target_backing_sectors; /* negative if unknown */
28
@@ -XXX,XX +XXX,XX @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
29
30
if (s->target_backing_sectors >= 0) {
31
if (sector_num >= s->target_backing_sectors) {
32
- post_backing_zero = s->unallocated_blocks_are_zero;
33
+ post_backing_zero = true;
34
} else if (sector_num + n > s->target_backing_sectors) {
35
/* Split requests around target_backing_sectors (because
36
* starting from there, zeros are handled differently) */
37
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
38
} else {
39
s.compressed = s.compressed || bdi.needs_compressed_writes;
40
s.cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE;
41
- s.unallocated_blocks_are_zero = bdi.unallocated_blocks_are_zero;
42
}
43
44
ret = convert_do_copy(&s);
45
--
46
2.26.2
47
48
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
The function has only one user: bdrv_co_block_status(). Inline it to
4
permission updates.
4
simplify reviewing of the following patches, which will finally drop
5
Also, no needs to consider previously calculated permissions, as at
5
unallocated_blocks_are_zero field too.
6
this point we already bind all new parents and bdrv_get_cumulative_perm
7
result is enough. So fix the bug by just set permissions by
8
bdrv_get_cumulative_perm result.
9
10
Bug was introduced in long ago 234ac1a9025, in 2.9.
11
6
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Message-id: 20190824100740.61635-1-vsementsov@virtuozzo.com
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Message-Id: <20200528094405.145708-3-vsementsov@virtuozzo.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
11
---
16
block.c | 5 ++---
12
include/block/block.h | 1 -
17
1 file changed, 2 insertions(+), 3 deletions(-)
13
block.c | 15 ---------------
14
block/io.c | 11 ++++++++---
15
3 files changed, 8 insertions(+), 19 deletions(-)
18
16
17
diff --git a/include/block/block.h b/include/block/block.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block.h
20
+++ b/include/block/block.h
21
@@ -XXX,XX +XXX,XX @@ int bdrv_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
22
int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
23
int bdrv_has_zero_init_1(BlockDriverState *bs);
24
int bdrv_has_zero_init(BlockDriverState *bs);
25
-bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
26
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
27
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
28
int64_t bytes, int64_t *pnum, int64_t *map,
19
diff --git a/block.c b/block.c
29
diff --git a/block.c b/block.c
20
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
21
--- a/block.c
31
--- a/block.c
22
+++ b/block.c
32
+++ b/block.c
23
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
33
@@ -XXX,XX +XXX,XX @@ int bdrv_has_zero_init(BlockDriverState *bs)
34
return 0;
35
}
36
37
-bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs)
38
-{
39
- BlockDriverInfo bdi;
40
-
41
- if (bs->backing) {
42
- return false;
43
- }
44
-
45
- if (bdrv_get_info(bs, &bdi) == 0) {
46
- return bdi.unallocated_blocks_are_zero;
47
- }
48
-
49
- return false;
50
-}
51
-
52
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs)
24
{
53
{
25
BdrvChild *c, *next;
54
if (!(bs->open_flags & BDRV_O_UNMAP)) {
26
GSList *list = NULL, *p;
55
diff --git a/block/io.c b/block/io.c
27
- uint64_t old_perm, old_shared;
56
index XXXXXXX..XXXXXXX 100644
28
uint64_t perm = 0, shared = BLK_PERM_ALL;
57
--- a/block/io.c
29
int ret;
58
+++ b/block/io.c
30
59
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
31
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
60
if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {
32
bdrv_unref(from);
61
ret |= BDRV_BLOCK_ALLOCATED;
62
} else if (want_zero) {
63
- if (bdrv_unallocated_blocks_are_zero(bs)) {
64
- ret |= BDRV_BLOCK_ZERO;
65
- } else if (bs->backing) {
66
+ if (bs->backing) {
67
BlockDriverState *bs2 = bs->backing->bs;
68
int64_t size2 = bdrv_getlength(bs2);
69
70
if (size2 >= 0 && offset >= size2) {
71
ret |= BDRV_BLOCK_ZERO;
72
}
73
+ } else {
74
+ BlockDriverInfo bdi;
75
+ int ret2 = bdrv_get_info(bs, &bdi);
76
+
77
+ if (ret2 == 0 && bdi.unallocated_blocks_are_zero) {
78
+ ret |= BDRV_BLOCK_ZERO;
79
+ }
80
}
33
}
81
}
34
82
35
- bdrv_get_cumulative_perm(to, &old_perm, &old_shared);
36
- bdrv_set_perm(to, old_perm | perm, old_shared | shared);
37
+ bdrv_get_cumulative_perm(to, &perm, &shared);
38
+ bdrv_set_perm(to, perm, shared);
39
40
out:
41
g_slist_free(list);
42
--
83
--
43
2.21.0
84
2.26.2
44
85
45
86
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
In case of !VDI_IS_ALLOCATED[], we do zero out the corresponding chunk
4
of qiov. So, this should be reported as ZERO.
5
6
Note that this changes visible output of "qemu-img map --output=json"
7
and "qemu-io -c map" commands. For qemu-img map, the change is obvious:
8
we just mark as zero what is really zero. For qemu-io it's less
9
obvious: what was unallocated now is allocated.
10
11
There is an inconsistency in understanding of unallocated regions in
12
Qemu: backing-supporting format-drivers return 0 block-status to report
13
go-to-backing logic for this area. Some protocol-drivers (iscsi) return
14
0 to report fs-unallocated-non-zero status (i.e., don't occupy space on
15
disk, read result is undefined).
16
17
BDRV_BLOCK_ALLOCATED is defined as something more close to
18
go-to-backing logic. Still it is calculated as ZERO | DATA, so 0 from
19
iscsi is treated as unallocated. It doesn't influence backing-chain
20
behavior, as iscsi can't have backing file. But it does influence
21
"qemu-io -c map".
22
23
We should solve this inconsistency at some future point. Now, let's
24
just make backing-not-supporting format drivers (vdi at this patch and
25
vpc with the following) to behave more like backing-supporting drivers
26
and not report 0 block-status. More over, returning ZERO status is
27
absolutely valid thing, and again, corresponds to how the other
28
format-drivers (backing-supporting) work.
29
30
After block-status update, it never reports 0, so setting
31
unallocated_blocks_are_zero doesn't make sense (as the only user of it
32
is bdrv_co_block_status and it checks unallocated_blocks_are_zero only
33
for unallocated areas). Drop it.
34
35
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
36
Reviewed-by: Eric Blake <eblake@redhat.com>
37
Message-Id: <20200528094405.145708-4-vsementsov@virtuozzo.com>
38
Signed-off-by: Max Reitz <mreitz@redhat.com>
39
---
40
block/vdi.c | 3 +--
41
1 file changed, 1 insertion(+), 2 deletions(-)
42
43
diff --git a/block/vdi.c b/block/vdi.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/block/vdi.c
46
+++ b/block/vdi.c
47
@@ -XXX,XX +XXX,XX @@ static int vdi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
48
logout("\n");
49
bdi->cluster_size = s->block_size;
50
bdi->vm_state_offset = 0;
51
- bdi->unallocated_blocks_are_zero = true;
52
return 0;
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_block_status(BlockDriverState *bs,
56
*pnum = MIN(s->block_size - index_in_block, bytes);
57
result = VDI_IS_ALLOCATED(bmap_entry);
58
if (!result) {
59
- return 0;
60
+ return BDRV_BLOCK_ZERO;
61
}
62
63
*map = s->header.offset_data + (uint64_t)bmap_entry * s->block_size +
64
--
65
2.26.2
66
67
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
In case when get_image_offset() returns -1, we do zero out the
4
corresponding chunk of qiov. So, this should be reported as ZERO.
5
6
Note that this changes visible output of "qemu-img map --output=json"
7
and "qemu-io -c map" commands. For qemu-img map, the change is obvious:
8
we just mark as zero what is really zero. For qemu-io it's less
9
obvious: what was unallocated now is allocated.
10
11
There is an inconsistency in understanding of unallocated regions in
12
Qemu: backing-supporting format-drivers return 0 block-status to report
13
go-to-backing logic for this area. Some protocol-drivers (iscsi) return
14
0 to report fs-unallocated-non-zero status (i.e., don't occupy space on
15
disk, read result is undefined).
16
17
BDRV_BLOCK_ALLOCATED is defined as something more close to
18
go-to-backing logic. Still it is calculated as ZERO | DATA, so 0 from
19
iscsi is treated as unallocated. It doesn't influence backing-chain
20
behavior, as iscsi can't have backing file. But it does influence
21
"qemu-io -c map".
22
23
We should solve this inconsistency at some future point. Now, let's
24
just make backing-not-supporting format drivers (vdi in the previous
25
patch and vpc now) to behave more like backing-supporting drivers
26
and not report 0 block-status. More over, returning ZERO status is
27
absolutely valid thing, and again, corresponds to how the other
28
format-drivers (backing-supporting) work.
29
30
After block-status update, it never reports 0, so setting
31
unallocated_blocks_are_zero doesn't make sense (as the only user of it
32
is bdrv_co_block_status and it checks unallocated_blocks_are_zero only
33
for unallocated areas). Drop it.
34
35
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
36
Reviewed-by: Eric Blake <eblake@redhat.com>
37
Message-Id: <20200528094405.145708-5-vsementsov@virtuozzo.com>
38
[mreitz: qemu-io -c map as used by iotest 146 now reports everything as
39
allocated; in order to make the test do something useful, we
40
use qemu-img map --output=json now]
41
Signed-off-by: Max Reitz <mreitz@redhat.com>
42
---
43
block/vpc.c | 3 +-
44
tests/qemu-iotests/146 | 60 ++++--
45
tests/qemu-iotests/146.out | 405 +++++++++++++++++++++++++++++++++++--
46
3 files changed, 436 insertions(+), 32 deletions(-)
47
48
diff --git a/block/vpc.c b/block/vpc.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/block/vpc.c
51
+++ b/block/vpc.c
52
@@ -XXX,XX +XXX,XX @@ static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
53
bdi->cluster_size = s->block_size;
54
}
55
56
- bdi->unallocated_blocks_are_zero = true;
57
return 0;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vpc_co_block_status(BlockDriverState *bs,
61
image_offset = get_image_offset(bs, offset, false, NULL);
62
allocated = (image_offset != -1);
63
*pnum = 0;
64
- ret = 0;
65
+ ret = BDRV_BLOCK_ZERO;
66
67
do {
68
/* All sectors in a block are contiguous (without using the bitmap) */
69
diff --git a/tests/qemu-iotests/146 b/tests/qemu-iotests/146
70
index XXXXXXX..XXXXXXX 100755
71
--- a/tests/qemu-iotests/146
72
+++ b/tests/qemu-iotests/146
73
@@ -XXX,XX +XXX,XX @@ echo === Testing VPC Autodetect ===
74
echo
75
_use_sample_img virtualpc-dynamic.vhd.bz2
76
77
-${QEMU_IO} -c "open -o driver=vpc ${TEST_IMG}" -c 'map'
78
+$QEMU_IMG map --output=json --image-opts \
79
+ "driver=vpc,file.filename=$TEST_IMG" \
80
+ | _filter_qemu_img_map
81
82
echo
83
echo === Testing VPC with current_size force ===
84
echo
85
86
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=current_size ${TEST_IMG}" -c 'map'
87
+$QEMU_IMG map --output=json --image-opts \
88
+ "driver=vpc,force_size_calc=current_size,file.filename=$TEST_IMG" \
89
+ | _filter_qemu_img_map
90
91
echo
92
echo === Testing VPC with chs force ===
93
echo
94
95
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=chs ${TEST_IMG}" -c 'map'
96
+$QEMU_IMG map --output=json --image-opts \
97
+ "driver=vpc,force_size_calc=chs,file.filename=$TEST_IMG" \
98
+ | _filter_qemu_img_map
99
100
_cleanup_test_img
101
102
@@ -XXX,XX +XXX,XX @@ echo === Testing Hyper-V Autodetect ===
103
echo
104
_use_sample_img hyperv2012r2-dynamic.vhd.bz2
105
106
-${QEMU_IO} -c "open -o driver=vpc ${TEST_IMG}" -c 'map'
107
+$QEMU_IMG map --output=json --image-opts \
108
+ "driver=vpc,file.filename=$TEST_IMG" \
109
+ | _filter_qemu_img_map
110
111
echo
112
echo === Testing Hyper-V with current_size force ===
113
echo
114
115
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=current_size ${TEST_IMG}" -c 'map'
116
+$QEMU_IMG map --output=json --image-opts \
117
+ "driver=vpc,force_size_calc=current_size,file.filename=$TEST_IMG" \
118
+ | _filter_qemu_img_map
119
120
echo
121
echo === Testing Hyper-V with chs force ===
122
echo
123
124
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=chs ${TEST_IMG}" -c 'map'
125
+$QEMU_IMG map --output=json --image-opts \
126
+ "driver=vpc,force_size_calc=chs,file.filename=$TEST_IMG" \
127
+ | _filter_qemu_img_map
128
129
_cleanup_test_img
130
131
@@ -XXX,XX +XXX,XX @@ echo === Testing d2v Autodetect ===
132
echo
133
_use_sample_img d2v-zerofilled.vhd.bz2
134
135
-${QEMU_IO} -c "open -o driver=vpc ${TEST_IMG}" -c 'map'
136
+$QEMU_IMG map --output=json --image-opts \
137
+ "driver=vpc,file.filename=$TEST_IMG" \
138
+ | _filter_qemu_img_map
139
140
echo
141
echo === Testing d2v with current_size force ===
142
echo
143
144
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=current_size ${TEST_IMG}" -c 'map'
145
+$QEMU_IMG map --output=json --image-opts \
146
+ "driver=vpc,force_size_calc=current_size,file.filename=$TEST_IMG" \
147
+ | _filter_qemu_img_map
148
149
echo
150
echo === Testing d2v with chs force ===
151
echo
152
153
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=chs ${TEST_IMG}" -c 'map'
154
+$QEMU_IMG map --output=json --image-opts \
155
+ "driver=vpc,force_size_calc=chs,file.filename=$TEST_IMG" \
156
+ | _filter_qemu_img_map
157
158
_cleanup_test_img
159
160
@@ -XXX,XX +XXX,XX @@ echo
161
echo === Read created image, default opts ====
162
echo
163
164
-${QEMU_IO} -c "open -o driver=vpc ${TEST_IMG}" -c 'map'
165
+$QEMU_IMG map --output=json --image-opts \
166
+ "driver=vpc,file.filename=$TEST_IMG" \
167
+ | _filter_qemu_img_map
168
169
echo
170
echo === Read created image, force_size_calc=chs ====
171
echo
172
173
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=chs ${TEST_IMG}" -c 'map'
174
+$QEMU_IMG map --output=json --image-opts \
175
+ "driver=vpc,force_size_calc=chs,file.filename=$TEST_IMG" \
176
+ | _filter_qemu_img_map
177
178
echo
179
echo === Read created image, force_size_calc=current_size ====
180
echo
181
182
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=current_size ${TEST_IMG}" -c 'map'
183
+$QEMU_IMG map --output=json --image-opts \
184
+ "driver=vpc,force_size_calc=current_size,file.filename=$TEST_IMG" \
185
+ | _filter_qemu_img_map
186
187
echo
188
echo === Testing Image create, force_size ===
189
@@ -XXX,XX +XXX,XX @@ echo
190
echo === Read created image, default opts ====
191
echo
192
193
-${QEMU_IO} -c "open -o driver=vpc ${TEST_IMG}" -c 'map'
194
+$QEMU_IMG map --output=json --image-opts \
195
+ "driver=vpc,file.filename=$TEST_IMG" \
196
+ | _filter_qemu_img_map
197
198
echo
199
echo === Read created image, force_size_calc=chs ====
200
echo
201
202
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=chs ${TEST_IMG}" -c 'map'
203
+$QEMU_IMG map --output=json --image-opts \
204
+ "driver=vpc,force_size_calc=chs,file.filename=$TEST_IMG" \
205
+ | _filter_qemu_img_map
206
207
echo
208
echo === Read created image, force_size_calc=current_size ====
209
echo
210
211
-${QEMU_IO} -c "open -o driver=vpc,force_size_calc=current_size ${TEST_IMG}" -c 'map'
212
+$QEMU_IMG map --output=json --image-opts \
213
+ "driver=vpc,force_size_calc=current_size,file.filename=$TEST_IMG" \
214
+ | _filter_qemu_img_map
215
216
echo "*** done"
217
rm -f $seq.full
218
diff --git a/tests/qemu-iotests/146.out b/tests/qemu-iotests/146.out
219
index XXXXXXX..XXXXXXX 100644
220
--- a/tests/qemu-iotests/146.out
221
+++ b/tests/qemu-iotests/146.out
222
@@ -XXX,XX +XXX,XX @@ QA output created by 146
223
224
=== Testing VPC Autodetect ===
225
226
-126.998 GiB (0x1fbfe04000) bytes not allocated at offset 0 bytes (0x0)
227
+[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false }]
228
229
=== Testing VPC with current_size force ===
230
231
-127 GiB (0x1fc0000000) bytes not allocated at offset 0 bytes (0x0)
232
+[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false }]
233
234
=== Testing VPC with chs force ===
235
236
-126.998 GiB (0x1fbfe04000) bytes not allocated at offset 0 bytes (0x0)
237
+[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false }]
238
239
=== Testing Hyper-V Autodetect ===
240
241
-127 GiB (0x1fc0000000) bytes not allocated at offset 0 bytes (0x0)
242
+[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false }]
243
244
=== Testing Hyper-V with current_size force ===
245
246
-127 GiB (0x1fc0000000) bytes not allocated at offset 0 bytes (0x0)
247
+[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false }]
248
249
=== Testing Hyper-V with chs force ===
250
251
-126.998 GiB (0x1fbfe04000) bytes not allocated at offset 0 bytes (0x0)
252
+[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false }]
253
254
=== Testing d2v Autodetect ===
255
256
-251.250 MiB (0xfb40000) bytes allocated at offset 0 bytes (0x0)
257
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
258
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
259
+{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
260
+{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
261
+{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
262
+{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
263
+{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
264
+{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
265
+{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
266
+{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
267
+{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
268
+{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
269
+{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
270
+{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
271
+{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
272
+{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
273
+{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
274
+{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
275
+{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
276
+{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
277
+{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
278
+{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
279
+{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
280
+{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
281
+{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
282
+{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
283
+{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
284
+{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
285
+{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
286
+{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
287
+{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
288
+{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
289
+{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
290
+{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
291
+{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
292
+{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
293
+{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
294
+{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
295
+{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
296
+{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
297
+{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
298
+{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
299
+{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
300
+{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
301
+{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
302
+{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
303
+{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
304
+{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
305
+{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
306
+{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
307
+{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
308
+{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
309
+{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
310
+{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
311
+{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
312
+{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
313
+{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
314
+{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
315
+{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
316
+{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
317
+{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
318
+{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
319
+{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
320
+{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
321
+{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
322
+{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
323
+{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
324
+{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
325
+{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
326
+{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
327
+{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
328
+{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
329
+{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
330
+{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
331
+{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
332
+{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
333
+{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
334
+{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
335
+{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
336
+{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
337
+{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
338
+{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
339
+{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
340
+{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
341
+{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
342
+{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
343
+{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
344
+{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
345
+{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
346
+{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
347
+{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
348
+{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
349
+{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
350
+{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
351
+{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
352
+{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
353
+{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
354
+{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
355
+{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
356
+{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
357
+{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
358
+{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
359
+{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
360
+{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
361
+{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
362
+{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
363
+{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
364
+{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
365
+{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
366
+{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
367
+{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
368
+{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
369
+{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
370
+{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
371
+{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
372
+{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
373
+{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
374
+{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
375
+{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
376
+{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
377
+{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
378
+{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
379
+{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
380
+{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
381
+{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
382
+{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET }]
383
384
=== Testing d2v with current_size force ===
385
386
-251.250 MiB (0xfb40000) bytes allocated at offset 0 bytes (0x0)
387
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
388
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
389
+{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
390
+{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
391
+{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
392
+{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
393
+{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
394
+{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
395
+{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
396
+{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
397
+{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
398
+{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
399
+{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
400
+{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
401
+{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
402
+{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
403
+{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
404
+{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
405
+{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
406
+{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
407
+{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
408
+{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
409
+{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
410
+{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
411
+{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
412
+{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
413
+{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
414
+{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
415
+{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
416
+{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
417
+{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
418
+{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
419
+{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
420
+{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
421
+{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
422
+{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
423
+{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
424
+{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
425
+{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
426
+{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
427
+{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
428
+{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
429
+{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
430
+{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
431
+{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
432
+{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
433
+{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
434
+{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
435
+{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
436
+{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
437
+{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
438
+{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
439
+{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
440
+{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
441
+{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
442
+{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
443
+{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
444
+{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
445
+{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
446
+{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
447
+{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
448
+{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
449
+{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
450
+{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
451
+{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
452
+{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
453
+{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
454
+{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
455
+{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
456
+{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
457
+{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
458
+{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
459
+{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
460
+{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
461
+{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
462
+{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
463
+{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
464
+{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
465
+{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
466
+{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
467
+{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
468
+{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
469
+{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
470
+{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
471
+{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
472
+{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
473
+{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
474
+{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
475
+{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
476
+{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
477
+{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
478
+{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
479
+{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
480
+{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
481
+{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
482
+{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
483
+{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
484
+{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
485
+{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
486
+{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
487
+{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
488
+{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
489
+{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
490
+{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
491
+{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
492
+{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
493
+{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
494
+{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
495
+{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
496
+{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
497
+{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
498
+{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
499
+{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
500
+{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
501
+{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
502
+{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
503
+{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
504
+{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
505
+{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
506
+{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
507
+{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
508
+{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
509
+{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
510
+{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
511
+{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
512
+{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET }]
513
514
=== Testing d2v with chs force ===
515
516
-251.250 MiB (0xfb40000) bytes allocated at offset 0 bytes (0x0)
517
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
518
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
519
+{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
520
+{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
521
+{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
522
+{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
523
+{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
524
+{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
525
+{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
526
+{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
527
+{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
528
+{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
529
+{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
530
+{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
531
+{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
532
+{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
533
+{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
534
+{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
535
+{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
536
+{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
537
+{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
538
+{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
539
+{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
540
+{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
541
+{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
542
+{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
543
+{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
544
+{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
545
+{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
546
+{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
547
+{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
548
+{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
549
+{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
550
+{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
551
+{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
552
+{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
553
+{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
554
+{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
555
+{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
556
+{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
557
+{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
558
+{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
559
+{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
560
+{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
561
+{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
562
+{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
563
+{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
564
+{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
565
+{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
566
+{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
567
+{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
568
+{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
569
+{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
570
+{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
571
+{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
572
+{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
573
+{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
574
+{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
575
+{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
576
+{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
577
+{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
578
+{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
579
+{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
580
+{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
581
+{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
582
+{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
583
+{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
584
+{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
585
+{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
586
+{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
587
+{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
588
+{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
589
+{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
590
+{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
591
+{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
592
+{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
593
+{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
594
+{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
595
+{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
596
+{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
597
+{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
598
+{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
599
+{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
600
+{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
601
+{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
602
+{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
603
+{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
604
+{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
605
+{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
606
+{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
607
+{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
608
+{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
609
+{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
610
+{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
611
+{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
612
+{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
613
+{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
614
+{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
615
+{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
616
+{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
617
+{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
618
+{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
619
+{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
620
+{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
621
+{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
622
+{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
623
+{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
624
+{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
625
+{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
626
+{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
627
+{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
628
+{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
629
+{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
630
+{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
631
+{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
632
+{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
633
+{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
634
+{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
635
+{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
636
+{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
637
+{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
638
+{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
639
+{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
640
+{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
641
+{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
642
+{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET }]
643
644
=== Testing Image create, default ===
645
646
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/IMGFMT-create-test.IMGFMT', fmt=IMGFMT size=4294967296
647
648
=== Read created image, default opts ====
649
650
-4 GiB (0x10007a000) bytes not allocated at offset 0 bytes (0x0)
651
+[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false }]
652
653
=== Read created image, force_size_calc=chs ====
654
655
-4 GiB (0x10007a000) bytes not allocated at offset 0 bytes (0x0)
656
+[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false }]
657
658
=== Read created image, force_size_calc=current_size ====
659
660
-4 GiB (0x10007a000) bytes not allocated at offset 0 bytes (0x0)
661
+[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false }]
662
663
=== Testing Image create, force_size ===
664
665
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/IMGFMT-create-test.IMGFMT', fmt=IMGFMT size=4294967296
666
667
=== Read created image, default opts ====
668
669
-4 GiB (0x100000000) bytes not allocated at offset 0 bytes (0x0)
670
+[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false }]
671
672
=== Read created image, force_size_calc=chs ====
673
674
-4 GiB (0x100000000) bytes not allocated at offset 0 bytes (0x0)
675
+[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false }]
676
677
=== Read created image, force_size_calc=current_size ====
678
679
-4 GiB (0x100000000) bytes not allocated at offset 0 bytes (0x0)
680
+[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false }]
681
*** done
682
--
683
2.26.2
684
685
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
It's false by default, no needs to set it. We are going to drop this
4
sometimes printing out warnings or false positives - this spoils
4
variable at all, so drop it now here, it doesn't hurt.
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
5
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-id: 20190823084203.29734-1-thuth@redhat.com
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Message-Id: <20200528094405.145708-6-vsementsov@virtuozzo.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
10
---
13
tests/check-block.sh | 5 +++++
11
block/crypto.c | 1 -
14
1 file changed, 5 insertions(+)
12
1 file changed, 1 deletion(-)
15
13
16
diff --git a/tests/check-block.sh b/tests/check-block.sh
14
diff --git a/block/crypto.c b/block/crypto.c
17
index XXXXXXX..XXXXXXX 100755
15
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/check-block.sh
16
--- a/block/crypto.c
19
+++ b/tests/check-block.sh
17
+++ b/block/crypto.c
20
@@ -XXX,XX +XXX,XX @@ if grep -q "TARGET_GPROF=y" *-softmmu/config-target.mak 2>/dev/null ; then
18
@@ -XXX,XX +XXX,XX @@ static int block_crypto_get_info_luks(BlockDriverState *bs,
21
exit 0
19
return ret;
22
fi
20
}
23
21
24
+if grep -q "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ; then
22
- bdi->unallocated_blocks_are_zero = false;
25
+ echo "Sanitizers are enabled ==> Not running the qemu-iotests."
23
bdi->cluster_size = subbdi.cluster_size;
26
+ exit 0
24
27
+fi
25
return 0;
28
+
29
if [ -z "$(find . -name 'qemu-system-*' -print)" ]; then
30
echo "No qemu-system binary available ==> Not running the qemu-iotests."
31
exit 0
32
--
26
--
33
2.21.0
27
2.26.2
34
28
35
29
diff view generated by jsdifflib
1
streamOptimized does not support writes that do not span exactly one
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
cluster. Furthermore, it cannot rewrite already allocated clusters.
3
As such, many iotests do not work with it. Disable them.
4
2
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
We set bdi->unallocated_blocks_are_zero = iscsilun->lbprz, but
6
Message-id: 20190815153638.4600-6-mreitz@redhat.com
4
iscsi_co_block_status doesn't return 0 in case of iscsilun->lbprz, it
7
Reviewed-by: John Snow <jsnow@redhat.com>
5
returns ZERO when appropriate. So actually unallocated_blocks_are_zero
6
is useless (it doesn't affect the only user of the field:
7
bdrv_co_block_status()). Drop it now.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Message-Id: <20200528094405.145708-7-vsementsov@virtuozzo.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
13
---
10
tests/qemu-iotests/002 | 1 +
14
block/iscsi.c | 1 -
11
tests/qemu-iotests/003 | 1 +
15
1 file changed, 1 deletion(-)
12
tests/qemu-iotests/005 | 3 ++-
13
tests/qemu-iotests/009 | 1 +
14
tests/qemu-iotests/010 | 1 +
15
tests/qemu-iotests/011 | 1 +
16
tests/qemu-iotests/017 | 3 ++-
17
tests/qemu-iotests/018 | 3 ++-
18
tests/qemu-iotests/019 | 3 ++-
19
tests/qemu-iotests/020 | 3 ++-
20
tests/qemu-iotests/027 | 1 +
21
tests/qemu-iotests/032 | 1 +
22
tests/qemu-iotests/033 | 1 +
23
tests/qemu-iotests/034 | 3 ++-
24
tests/qemu-iotests/037 | 3 ++-
25
tests/qemu-iotests/063 | 3 ++-
26
tests/qemu-iotests/072 | 1 +
27
tests/qemu-iotests/105 | 3 ++-
28
tests/qemu-iotests/197 | 1 +
29
tests/qemu-iotests/215 | 1 +
30
tests/qemu-iotests/251 | 1 +
31
21 files changed, 30 insertions(+), 9 deletions(-)
32
16
33
diff --git a/tests/qemu-iotests/002 b/tests/qemu-iotests/002
17
diff --git a/block/iscsi.c b/block/iscsi.c
34
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100644
35
--- a/tests/qemu-iotests/002
19
--- a/block/iscsi.c
36
+++ b/tests/qemu-iotests/002
20
+++ b/block/iscsi.c
37
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
21
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
38
22
static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
39
_supported_fmt generic
23
{
40
_supported_proto generic
24
IscsiLun *iscsilun = bs->opaque;
41
+_unsupported_imgopts "subformat=streamOptimized"
25
- bdi->unallocated_blocks_are_zero = iscsilun->lbprz;
42
26
bdi->cluster_size = iscsilun->cluster_size;
43
27
return 0;
44
size=128M
28
}
45
diff --git a/tests/qemu-iotests/003 b/tests/qemu-iotests/003
46
index XXXXXXX..XXXXXXX 100755
47
--- a/tests/qemu-iotests/003
48
+++ b/tests/qemu-iotests/003
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
50
51
_supported_fmt generic
52
_supported_proto generic
53
+_unsupported_imgopts "subformat=streamOptimized"
54
55
size=128M
56
offset=67M
57
diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005
58
index XXXXXXX..XXXXXXX 100755
59
--- a/tests/qemu-iotests/005
60
+++ b/tests/qemu-iotests/005
61
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
62
_supported_proto generic
63
_supported_os Linux
64
_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
65
- "subformat=twoGbMaxExtentSparse"
66
+ "subformat=twoGbMaxExtentSparse" \
67
+ "subformat=streamOptimized"
68
69
# vpc is limited to 127GB, so we can't test it here
70
if [ "$IMGFMT" = "vpc" ]; then
71
diff --git a/tests/qemu-iotests/009 b/tests/qemu-iotests/009
72
index XXXXXXX..XXXXXXX 100755
73
--- a/tests/qemu-iotests/009
74
+++ b/tests/qemu-iotests/009
75
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
76
77
_supported_fmt generic
78
_supported_proto generic
79
+_unsupported_imgopts "subformat=streamOptimized"
80
81
82
size=6G
83
diff --git a/tests/qemu-iotests/010 b/tests/qemu-iotests/010
84
index XXXXXXX..XXXXXXX 100755
85
--- a/tests/qemu-iotests/010
86
+++ b/tests/qemu-iotests/010
87
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
88
89
_supported_fmt generic
90
_supported_proto generic
91
+_unsupported_imgopts "subformat=streamOptimized"
92
93
94
size=6G
95
diff --git a/tests/qemu-iotests/011 b/tests/qemu-iotests/011
96
index XXXXXXX..XXXXXXX 100755
97
--- a/tests/qemu-iotests/011
98
+++ b/tests/qemu-iotests/011
99
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
100
101
_supported_fmt generic
102
_supported_proto generic
103
+_unsupported_imgopts "subformat=streamOptimized"
104
105
106
size=6G
107
diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017
108
index XXXXXXX..XXXXXXX 100755
109
--- a/tests/qemu-iotests/017
110
+++ b/tests/qemu-iotests/017
111
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
112
_supported_fmt qcow qcow2 vmdk qed
113
_supported_proto generic
114
_unsupported_proto vxhs
115
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
116
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
117
+ "subformat=streamOptimized"
118
119
TEST_OFFSETS="0 4294967296"
120
121
diff --git a/tests/qemu-iotests/018 b/tests/qemu-iotests/018
122
index XXXXXXX..XXXXXXX 100755
123
--- a/tests/qemu-iotests/018
124
+++ b/tests/qemu-iotests/018
125
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
126
_supported_fmt qcow qcow2 vmdk qed
127
_supported_proto file
128
_supported_os Linux
129
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
130
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
131
+ "streamOptimized"
132
133
TEST_OFFSETS="0 4294967296"
134
135
diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019
136
index XXXXXXX..XXXXXXX 100755
137
--- a/tests/qemu-iotests/019
138
+++ b/tests/qemu-iotests/019
139
@@ -XXX,XX +XXX,XX @@ _supported_proto file
140
_supported_os Linux
141
_unsupported_imgopts "subformat=monolithicFlat" \
142
"subformat=twoGbMaxExtentFlat" \
143
- "subformat=twoGbMaxExtentSparse"
144
+ "subformat=twoGbMaxExtentSparse" \
145
+ "subformat=streamOptimized"
146
147
TEST_OFFSETS="0 4294967296"
148
CLUSTER_SIZE=65536
149
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
150
index XXXXXXX..XXXXXXX 100755
151
--- a/tests/qemu-iotests/020
152
+++ b/tests/qemu-iotests/020
153
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed
154
_supported_proto file
155
_unsupported_imgopts "subformat=monolithicFlat" \
156
"subformat=twoGbMaxExtentFlat" \
157
- "subformat=twoGbMaxExtentSparse"
158
+ "subformat=twoGbMaxExtentSparse" \
159
+ "subformat=streamOptimized"
160
161
TEST_OFFSETS="0 4294967296"
162
163
diff --git a/tests/qemu-iotests/027 b/tests/qemu-iotests/027
164
index XXXXXXX..XXXXXXX 100755
165
--- a/tests/qemu-iotests/027
166
+++ b/tests/qemu-iotests/027
167
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
168
169
_supported_fmt vmdk qcow qcow2 qed
170
_supported_proto generic
171
+_unsupported_imgopts "subformat=streamOptimized"
172
173
174
size=128M
175
diff --git a/tests/qemu-iotests/032 b/tests/qemu-iotests/032
176
index XXXXXXX..XXXXXXX 100755
177
--- a/tests/qemu-iotests/032
178
+++ b/tests/qemu-iotests/032
179
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
180
# This works for any image format (though unlikely to segfault for raw)
181
_supported_fmt generic
182
_supported_proto generic
183
+_unsupported_imgopts "subformat=streamOptimized"
184
185
echo
186
echo === Prepare image ===
187
diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
188
index XXXXXXX..XXXXXXX 100755
189
--- a/tests/qemu-iotests/033
190
+++ b/tests/qemu-iotests/033
191
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
192
193
_supported_fmt generic
194
_supported_proto generic
195
+_unsupported_imgopts "subformat=streamOptimized"
196
197
198
size=128M
199
diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034
200
index XXXXXXX..XXXXXXX 100755
201
--- a/tests/qemu-iotests/034
202
+++ b/tests/qemu-iotests/034
203
@@ -XXX,XX +XXX,XX @@ _supported_proto file
204
_supported_os Linux
205
_unsupported_imgopts "subformat=monolithicFlat" \
206
"subformat=twoGbMaxExtentFlat" \
207
- "subformat=twoGbMaxExtentSparse"
208
+ "subformat=twoGbMaxExtentSparse" \
209
+ "subformat=streamOptimized"
210
211
CLUSTER_SIZE=4k
212
size=128M
213
diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037
214
index XXXXXXX..XXXXXXX 100755
215
--- a/tests/qemu-iotests/037
216
+++ b/tests/qemu-iotests/037
217
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed
218
_supported_proto file
219
_unsupported_imgopts "subformat=monolithicFlat" \
220
"subformat=twoGbMaxExtentFlat" \
221
- "subformat=twoGbMaxExtentSparse"
222
+ "subformat=twoGbMaxExtentSparse" \
223
+ "subformat=streamOptimized"
224
225
CLUSTER_SIZE=4k
226
size=128M
227
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
228
index XXXXXXX..XXXXXXX 100755
229
--- a/tests/qemu-iotests/063
230
+++ b/tests/qemu-iotests/063
231
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed raw
232
_supported_proto file
233
_unsupported_imgopts "subformat=monolithicFlat" \
234
"subformat=twoGbMaxExtentFlat" \
235
- "subformat=twoGbMaxExtentSparse"
236
+ "subformat=twoGbMaxExtentSparse" \
237
+ "subformat=streamOptimized"
238
239
_make_test_img 4M
240
241
diff --git a/tests/qemu-iotests/072 b/tests/qemu-iotests/072
242
index XXXXXXX..XXXXXXX 100755
243
--- a/tests/qemu-iotests/072
244
+++ b/tests/qemu-iotests/072
245
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
246
247
_supported_fmt vpc vmdk vhdx vdi qed qcow2 qcow
248
_supported_proto file
249
+_unsupported_imgopts "subformat=streamOptimized"
250
251
IMG_SIZE=64M
252
253
diff --git a/tests/qemu-iotests/105 b/tests/qemu-iotests/105
254
index XXXXXXX..XXXXXXX 100755
255
--- a/tests/qemu-iotests/105
256
+++ b/tests/qemu-iotests/105
257
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
258
_supported_fmt qcow2 vmdk vhdx qed
259
_supported_proto generic
260
_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
261
- "subformat=twoGbMaxExtentSparse"
262
+ "subformat=twoGbMaxExtentSparse" \
263
+ "subformat=streamOptimized"
264
265
echo
266
echo "creating large image"
267
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
268
index XXXXXXX..XXXXXXX 100755
269
--- a/tests/qemu-iotests/197
270
+++ b/tests/qemu-iotests/197
271
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
272
_supported_proto generic
273
# LUKS support may be possible, but it complicates things.
274
_unsupported_fmt luks
275
+_unsupported_imgopts "subformat=streamOptimized"
276
277
echo
278
echo '=== Copy-on-read ==='
279
diff --git a/tests/qemu-iotests/215 b/tests/qemu-iotests/215
280
index XXXXXXX..XXXXXXX 100755
281
--- a/tests/qemu-iotests/215
282
+++ b/tests/qemu-iotests/215
283
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
284
_supported_proto generic
285
# LUKS support may be possible, but it complicates things.
286
_unsupported_fmt luks
287
+_unsupported_imgopts "subformat=streamOptimized"
288
289
echo
290
echo '=== Copy-on-read ==='
291
diff --git a/tests/qemu-iotests/251 b/tests/qemu-iotests/251
292
index XXXXXXX..XXXXXXX 100755
293
--- a/tests/qemu-iotests/251
294
+++ b/tests/qemu-iotests/251
295
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
296
_supported_fmt generic
297
_supported_proto file
298
_supported_os Linux
299
+_unsupported_imgopts "subformat=streamOptimized"
300
301
if [ "$IMGOPTSSYNTAX" = "true" ]; then
302
# We use json:{} filenames here, so we cannot work with additional options.
303
--
29
--
304
2.21.0
30
2.26.2
305
31
306
32
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
raw_co_block_status() in block/file-posix.c never returns 0, so
4
("file-posix: Handle undetectable alignment")
4
unallocated_blocks_are_zero is useless (it doesn't affect the only user
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
of the field: bdrv_co_block_status()). Drop it.
6
Message-id: 20190827101328.4062-1-stefanha@redhat.com
6
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Message-Id: <20200528094405.145708-8-vsementsov@virtuozzo.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
11
---
10
block/file-posix.c | 2 +-
12
block/file-posix.c | 3 ---
11
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 3 deletions(-)
12
14
13
diff --git a/block/file-posix.c b/block/file-posix.c
15
diff --git a/block/file-posix.c b/block/file-posix.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/block/file-posix.c
17
--- a/block/file-posix.c
16
+++ b/block/file-posix.c
18
+++ b/block/file-posix.c
17
@@ -XXX,XX +XXX,XX @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_pwrite_zeroes(
18
for (i = 0; i < ARRAY_SIZE(alignments); i++) {
20
19
align = alignments[i];
21
static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
20
if (raw_is_io_aligned(fd, buf + align, max_align)) {
22
{
21
- /* Fallback to request_aligment. */
23
- BDRVRawState *s = bs->opaque;
22
+ /* Fallback to request_alignment. */
24
-
23
s->buf_align = (align != 1) ? align : bs->bl.request_alignment;
25
- bdi->unallocated_blocks_are_zero = s->discard_zeroes;
24
break;
26
return 0;
25
}
27
}
28
26
--
29
--
27
2.21.0
30
2.26.2
28
31
29
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
vhdx doesn't have .bdrv_co_block_status handler, so DATA|ALLOCATED is
4
Unify all test to use the same style.
4
always assumed for it in bdrv_co_block_status().
5
unallocated_blocks_are_zero is useless (it doesn't affect the only user
6
of the field: bdrv_co_block_status()), drop it.
5
7
6
Message-id: 20190827173432.7656-1-nsoffer@redhat.com
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-Id: <20200528094405.145708-9-vsementsov@virtuozzo.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
12
---
10
tests/qemu-iotests/026 | 4 ++--
13
block/vhdx.c | 3 ---
11
tests/qemu-iotests/039 | 4 ++--
14
1 file changed, 3 deletions(-)
12
tests/qemu-iotests/052 | 2 +-
13
tests/qemu-iotests/091 | 4 ++--
14
4 files changed, 7 insertions(+), 7 deletions(-)
15
15
16
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
16
diff --git a/block/vhdx.c b/block/vhdx.c
17
index XXXXXXX..XXXXXXX 100755
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qemu-iotests/026
18
--- a/block/vhdx.c
19
+++ b/tests/qemu-iotests/026
19
+++ b/block/vhdx.c
20
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
20
@@ -XXX,XX +XXX,XX @@ static int vhdx_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
21
# Currently only qcow2 supports rebasing
21
22
_supported_fmt qcow2
22
bdi->cluster_size = s->block_size;
23
_supported_proto file
23
24
-_default_cache_mode "writethrough"
24
- bdi->unallocated_blocks_are_zero =
25
-_supported_cache_modes "writethrough" "none"
25
- (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) == 0;
26
+_default_cache_mode writethrough
26
-
27
+_supported_cache_modes writethrough none
27
return 0;
28
# The refcount table tests expect a certain minimum width for refcount entries
28
}
29
# (so that the refcount table actually needs to grow); that minimum is 16 bits,
30
# being the default refcount entry width.
31
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
32
index XXXXXXX..XXXXXXX 100755
33
--- a/tests/qemu-iotests/039
34
+++ b/tests/qemu-iotests/039
35
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
36
_supported_fmt qcow2
37
_supported_proto file
38
_supported_os Linux
39
-_default_cache_mode "writethrough"
40
-_supported_cache_modes "writethrough"
41
+_default_cache_mode writethrough
42
+_supported_cache_modes writethrough
43
44
size=128M
45
46
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
47
index XXXXXXX..XXXXXXX 100755
48
--- a/tests/qemu-iotests/052
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
29
74
--
30
--
75
2.21.0
31
2.26.2
76
32
77
33
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
Currently this field only set by qed and qcow2. But in fact, all
9
Reviewed-by: John Snow <jsnow@redhat.com>
4
backing-supporting formats (parallels, qcow, qcow2, qed, vmdk) share
10
Message-id: 20190815153638.4600-7-mreitz@redhat.com
5
these semantics: on unallocated blocks, if there is no backing file they
11
Reviewed-by: John Snow <jsnow@redhat.com>
6
just memset the buffer with zeroes.
7
8
So, document this behavior for .supports_backing and drop
9
.unallocated_blocks_are_zero
10
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Message-Id: <20200528094405.145708-10-vsementsov@virtuozzo.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
15
---
14
tests/qemu-iotests/110 | 3 ++-
16
include/block/block.h | 5 -----
15
1 file changed, 2 insertions(+), 1 deletion(-)
17
include/block/block_int.h | 12 +++++++++++-
18
block/io.c | 9 ++-------
19
block/qcow2.c | 1 -
20
block/qed.c | 1 -
21
5 files changed, 13 insertions(+), 15 deletions(-)
16
22
17
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
23
diff --git a/include/block/block.h b/include/block/block.h
18
index XXXXXXX..XXXXXXX 100755
24
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/110
25
--- a/include/block/block.h
20
+++ b/tests/qemu-iotests/110
26
+++ b/include/block/block.h
21
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
27
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDriverInfo {
22
# Any format supporting backing files
28
/* offset at which the VM state can be saved (0 if not possible) */
23
_supported_fmt qed qcow qcow2 vmdk
29
int64_t vm_state_offset;
24
_supported_proto file
30
bool is_dirty;
25
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
31
- /*
26
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
32
- * True if unallocated blocks read back as zeroes. This is equivalent
27
+ "subformat=twoGbMaxExtentSparse"
33
- * to the LBPRZ flag in the SCSI logical block provisioning page.
28
34
- */
29
TEST_IMG_REL=$(basename "$TEST_IMG")
35
- bool unallocated_blocks_are_zero;
36
/*
37
* True if this block driver only supports compressed writes
38
*/
39
diff --git a/include/block/block_int.h b/include/block/block_int.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/block/block_int.h
42
+++ b/include/block/block_int.h
43
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
44
*/
45
bool bdrv_needs_filename;
46
47
- /* Set if a driver can support backing files */
48
+ /*
49
+ * Set if a driver can support backing files. This also implies the
50
+ * following semantics:
51
+ *
52
+ * - Return status 0 of .bdrv_co_block_status means that corresponding
53
+ * blocks are not allocated in this layer of backing-chain
54
+ * - For such (unallocated) blocks, read will:
55
+ * - fill buffer with zeros if there is no backing file
56
+ * - read from the backing file otherwise, where the block layer
57
+ * takes care of reading zeros beyond EOF if backing file is short
58
+ */
59
bool supports_backing;
60
61
/* For handling image reopen for split or non-split files */
62
diff --git a/block/io.c b/block/io.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/block/io.c
65
+++ b/block/io.c
66
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
67
68
if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {
69
ret |= BDRV_BLOCK_ALLOCATED;
70
- } else if (want_zero) {
71
+ } else if (want_zero && bs->drv->supports_backing) {
72
if (bs->backing) {
73
BlockDriverState *bs2 = bs->backing->bs;
74
int64_t size2 = bdrv_getlength(bs2);
75
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
76
ret |= BDRV_BLOCK_ZERO;
77
}
78
} else {
79
- BlockDriverInfo bdi;
80
- int ret2 = bdrv_get_info(bs, &bdi);
81
-
82
- if (ret2 == 0 && bdi.unallocated_blocks_are_zero) {
83
- ret |= BDRV_BLOCK_ZERO;
84
- }
85
+ ret |= BDRV_BLOCK_ZERO;
86
}
87
}
88
89
diff --git a/block/qcow2.c b/block/qcow2.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/block/qcow2.c
92
+++ b/block/qcow2.c
93
@@ -XXX,XX +XXX,XX @@ err:
94
static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
95
{
96
BDRVQcow2State *s = bs->opaque;
97
- bdi->unallocated_blocks_are_zero = true;
98
bdi->cluster_size = s->cluster_size;
99
bdi->vm_state_offset = qcow2_vm_state_offset(s);
100
return 0;
101
diff --git a/block/qed.c b/block/qed.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/block/qed.c
104
+++ b/block/qed.c
105
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
106
memset(bdi, 0, sizeof(*bdi));
107
bdi->cluster_size = s->header.cluster_size;
108
bdi->is_dirty = s->header.features & QED_F_NEED_CHECK;
109
- bdi->unallocated_blocks_are_zero = true;
110
return 0;
111
}
30
112
31
--
113
--
32
2.21.0
114
2.26.2
33
115
34
116
diff view generated by jsdifflib
1
We had a test for a case where relative extent paths did not work, but
1
From: Eric Blake <eblake@redhat.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
The other four drivers that support backing files (qcow, qcow2,
6
Reviewed-by: John Snow <jsnow@redhat.com>
4
parallels, vmdk) all rely on the block layer to populate zeroes when
7
Message-id: 20190815153638.4600-4-mreitz@redhat.com
5
reading beyond EOF of a short backing file. We can simplify the qed
8
Reviewed-by: John Snow <jsnow@redhat.com>
6
code by doing likewise.
7
8
Signed-off-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-Id: <20200528094405.145708-11-vsementsov@virtuozzo.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
12
---
11
tests/qemu-iotests/059 | 27 +++++++++++++++++++++++++++
13
block/qed.h | 1 -
12
tests/qemu-iotests/059.out | 4 ++++
14
block/qed.c | 64 +++++------------------------------------------------
13
2 files changed, 31 insertions(+)
15
2 files changed, 6 insertions(+), 59 deletions(-)
14
16
15
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
17
diff --git a/block/qed.h b/block/qed.h
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/059
18
+++ b/tests/qemu-iotests/059
19
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2
20
21
echo
22
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
23
+
24
+echo '--- blkdebug ---'
25
# Should work, because bdrv_dirname() works fine with blkdebug
26
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
27
$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
28
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TE
29
| _filter_testdir | _filter_imgfmt | _filter_img_info
30
_cleanup_test_img
31
32
+echo '--- quorum ---'
33
+# Should not work, because bdrv_dirname() does not work with quorum
34
+IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
35
+cp "$TEST_IMG" "$TEST_IMG.orig"
36
+
37
+filename="json:{
38
+ \"driver\": \"$IMGFMT\",
39
+ \"file\": {
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
+
56
+
57
echo
58
echo "=== Testing version 3 ==="
59
_use_sample_img iotest-version3.vmdk.bz2
60
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
61
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
62
--- a/tests/qemu-iotests/059.out
19
--- a/block/qed.h
63
+++ b/tests/qemu-iotests/059.out
20
+++ b/block/qed.h
64
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
21
@@ -XXX,XX +XXX,XX @@ typedef struct QEDAIOCB {
65
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
22
66
23
/* Current cluster scatter-gather list */
67
=== Testing monolithicFlat with internally generated JSON file name ===
24
QEMUIOVector cur_qiov;
68
+--- blkdebug ---
25
- QEMUIOVector *backing_qiov;
69
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
26
uint64_t cur_pos; /* position on block device, in bytes */
70
format name: IMGFMT
27
uint64_t cur_cluster; /* cluster offset in image file */
71
cluster size: 0 bytes
28
unsigned int cur_nclusters; /* number of clusters being accessed */
72
vm state offset: 0 bytes
29
diff --git a/block/qed.c b/block/qed.c
73
+--- quorum ---
30
index XXXXXXX..XXXXXXX 100644
74
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
31
--- a/block/qed.c
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
32
+++ b/block/qed.c
76
33
@@ -XXX,XX +XXX,XX @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
77
=== Testing version 3 ===
34
* @s: QED state
78
image: TEST_DIR/iotest-version3.IMGFMT
35
* @pos: Byte position in device
36
* @qiov: Destination I/O vector
37
- * @backing_qiov: Possibly shortened copy of qiov, to be allocated here
38
- * @cb: Completion function
39
- * @opaque: User data for completion function
40
*
41
* This function reads qiov->size bytes starting at pos from the backing file.
42
* If there is no backing file then zeroes are read.
43
*/
44
static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
45
- QEMUIOVector *qiov,
46
- QEMUIOVector **backing_qiov)
47
+ QEMUIOVector *qiov)
48
{
49
- uint64_t backing_length = 0;
50
- size_t size;
51
- int ret;
52
-
53
- /* If there is a backing file, get its length. Treat the absence of a
54
- * backing file like a zero length backing file.
55
- */
56
if (s->bs->backing) {
57
- int64_t l = bdrv_getlength(s->bs->backing->bs);
58
- if (l < 0) {
59
- return l;
60
- }
61
- backing_length = l;
62
- }
63
-
64
- /* Zero all sectors if reading beyond the end of the backing file */
65
- if (pos >= backing_length ||
66
- pos + qiov->size > backing_length) {
67
- qemu_iovec_memset(qiov, 0, 0, qiov->size);
68
- }
69
-
70
- /* Complete now if there are no backing file sectors to read */
71
- if (pos >= backing_length) {
72
- return 0;
73
- }
74
-
75
- /* If the read straddles the end of the backing file, shorten it */
76
- size = MIN((uint64_t)backing_length - pos, qiov->size);
77
-
78
- assert(*backing_qiov == NULL);
79
- *backing_qiov = g_new(QEMUIOVector, 1);
80
- qemu_iovec_init(*backing_qiov, qiov->niov);
81
- qemu_iovec_concat(*backing_qiov, qiov, 0, size);
82
-
83
- BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
84
- ret = bdrv_co_preadv(s->bs->backing, pos, size, *backing_qiov, 0);
85
- if (ret < 0) {
86
- return ret;
87
+ BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
88
+ return bdrv_co_preadv(s->bs->backing, pos, qiov->size, qiov, 0);
89
}
90
+ qemu_iovec_memset(qiov, 0, 0, qiov->size);
91
return 0;
92
}
93
94
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
95
uint64_t offset)
96
{
97
QEMUIOVector qiov;
98
- QEMUIOVector *backing_qiov = NULL;
99
int ret;
100
101
/* Skip copy entirely if there is no work to do */
102
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
103
104
qemu_iovec_init_buf(&qiov, qemu_blockalign(s->bs, len), len);
105
106
- ret = qed_read_backing_file(s, pos, &qiov, &backing_qiov);
107
-
108
- if (backing_qiov) {
109
- qemu_iovec_destroy(backing_qiov);
110
- g_free(backing_qiov);
111
- backing_qiov = NULL;
112
- }
113
+ ret = qed_read_backing_file(s, pos, &qiov);
114
115
if (ret) {
116
goto out;
117
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
118
qemu_iovec_memset(&acb->cur_qiov, 0, 0, acb->cur_qiov.size);
119
r = 0;
120
} else if (ret != QED_CLUSTER_FOUND) {
121
- r = qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov,
122
- &acb->backing_qiov);
123
+ r = qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov);
124
} else {
125
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
126
r = bdrv_co_preadv(bs->file, offset, acb->cur_qiov.size,
127
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
128
while (1) {
129
trace_qed_aio_next_io(s, acb, 0, acb->cur_pos + acb->cur_qiov.size);
130
131
- if (acb->backing_qiov) {
132
- qemu_iovec_destroy(acb->backing_qiov);
133
- g_free(acb->backing_qiov);
134
- acb->backing_qiov = NULL;
135
- }
136
-
137
acb->qiov_offset += acb->cur_qiov.size;
138
acb->cur_pos += acb->cur_qiov.size;
139
qemu_iovec_reset(&acb->cur_qiov);
79
--
140
--
80
2.21.0
141
2.26.2
81
142
82
143
diff view generated by jsdifflib