1
The following changes since commit c4e0780ed1ffd056f205348d387a61b4136a45df:
1
The following changes since commit cdfaa2720f4a09e5254868bd1f6e33f3e9eae76f:
2
2
3
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-4.0-pull-request' into staging (2019-03-07 18:40:43 +0000)
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2019-06-17-v2' into staging (2019-06-18 10:47:00 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to e88153ea9a40009a8ae7648282c0eac1b7f5494f:
9
for you to fetch changes up to 128b05f7e00765d883164631b974a27af5b4b613:
10
10
11
qcow2 spec: Describe string header extensions (2019-03-08 12:26:46 +0100)
11
block/null: Expose read-zeroes option in QAPI schema (2019-06-18 16:41:10 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- qcow2: Support for external data files
16
- block: Remove bs->job
17
- qcow2: Default to 4KB for the qcow2 cache entry size
17
- block: Ignore loosening perm restrictions failures
18
- Apply block driver whitelist for -drive format=help
18
- block/null: Expose read-zeroes option in QAPI schema
19
- Several qemu-iotests improvements
19
- iotests: Hide timestamps for skipped tests
20
20
21
----------------------------------------------------------------
21
----------------------------------------------------------------
22
Alberto Garcia (1):
22
Kevin Wolf (1):
23
qcow2: Default to 4KB for the qcow2 cache entry size
23
block/null: Expose read-zeroes option in QAPI schema
24
24
25
Andrey Shinkevich (4):
25
Max Reitz (9):
26
iotests: open notrun files in text mode
26
iotests: Hide timestamps for skipped tests
27
block: iterate_format with account of whitelisting
27
file-posix: Update open_flags in raw_set_perm()
28
iotests: ask QEMU for supported formats
28
block: Add bdrv_child_refresh_perms()
29
iotests: check whitelisted formats
29
block/mirror: Fix child permissions
30
block/commit: Drop bdrv_child_try_set_perm()
31
block: Fix order in bdrv_replace_child()
32
block: Add *tighten_restrictions to *check*_perm()
33
block: Ignore loosening perm restrictions failures
34
iotests: Test failure to loosen restrictions
30
35
31
Kevin Wolf (21):
36
Vladimir Sementsov-Ogievskiy (4):
32
qemu-iotests: Test qcow2 preallocation modes
37
block/replication: drop usage of bs->job
33
qcow2: Simplify preallocation code
38
block/block-backend: blk_iostatus_reset: drop usage of bs->job
34
qcow2: Extend spec for external data files
39
blockdev: blockdev_mark_auto_del: drop usage of bs->job
35
qcow2: Basic definitions for external data files
40
block: drop bs->job
36
qcow2: Pass bs to qcow2_get_cluster_type()
37
qcow2: Prepare qcow2_get_cluster_type() for external data file
38
qcow2: Prepare count_contiguous_clusters() for external data file
39
qcow2: Don't assume 0 is an invalid cluster offset
40
qcow2: Return 0/-errno in qcow2_alloc_compressed_cluster_offset()
41
qcow2: Prepare qcow2_co_block_status() for data file
42
qcow2: External file I/O
43
qcow2: Return error for snapshot operation with data file
44
qcow2: Support external data file in qemu-img check
45
qcow2: Add basic data-file infrastructure
46
qcow2: Creating images with external data file
47
qcow2: Store data file name in the image
48
qcow2: Implement data-file-raw create option
49
qemu-iotests: Preallocation with external data file
50
qemu-iotests: General tests for qcow2 with external data file
51
qemu-iotests: amend with external data file
52
qcow2 spec: Describe string header extensions
53
41
54
Philippe Mathieu-Daudé (6):
42
qapi/block-core.json | 4 +-
55
tests/multiboot: Improve portability by searching bash in the $PATH
43
include/block/block_int.h | 30 ++++++---
56
tests/bios-tables: Improve portability by searching bash in the $PATH
44
include/block/blockjob.h | 9 +++
57
qemu-iotests: Improve portability by searching bash in the $PATH
45
block.c | 155 +++++++++++++++++++++++++++++++++++++--------
58
qemu-iotests: Ensure GNU sed is used
46
block/block-backend.c | 4 --
59
ahci-test: Add dependency to qemu-img tool
47
block/commit.c | 2 -
60
qemu-iotests: Add dependency to qemu-nbd tool
48
block/file-posix.c | 4 ++
49
block/mirror.c | 70 ++++++++++++--------
50
block/replication.c | 21 +++---
51
blockdev.c | 19 +++---
52
blockjob.c | 22 ++++---
53
monitor/qmp-cmds.c | 5 ++
54
tests/test-blockjob.c | 5 +-
55
block/trace-events | 2 +-
56
tests/qemu-iotests/182 | 21 ++++++
57
tests/qemu-iotests/182.out | 6 ++
58
tests/qemu-iotests/check | 1 +
59
17 files changed, 283 insertions(+), 97 deletions(-)
61
60
62
Stefan Hajnoczi (1):
63
iotests: use iotests.VM in 238
64
65
qapi/block-core.json | 26 ++-
66
docs/interop/qcow2.txt | 54 +++++-
67
docs/qcow2-cache.txt | 17 +-
68
block/qcow2.h | 66 +++++--
69
include/block/block.h | 2 +-
70
include/block/block_int.h | 2 +
71
block.c | 23 ++-
72
block/qcow2-bitmap.c | 7 +-
73
block/qcow2-cache.c | 6 +-
74
block/qcow2-cluster.c | 182 +++++++++++-------
75
block/qcow2-refcount.c | 88 ++++++---
76
block/qcow2-snapshot.c | 22 ++-
77
block/qcow2.c | 326 +++++++++++++++++++++++++++-----
78
blockdev.c | 4 +-
79
qemu-img.c | 2 +-
80
tests/Makefile.include | 4 +-
81
tests/data/acpi/rebuild-expected-aml.sh | 2 +-
82
tests/multiboot/run_test.sh | 2 +-
83
tests/qemu-iotests/001 | 2 +-
84
tests/qemu-iotests/002 | 2 +-
85
tests/qemu-iotests/003 | 2 +-
86
tests/qemu-iotests/004 | 2 +-
87
tests/qemu-iotests/005 | 2 +-
88
tests/qemu-iotests/007 | 2 +-
89
tests/qemu-iotests/008 | 2 +-
90
tests/qemu-iotests/009 | 2 +-
91
tests/qemu-iotests/010 | 2 +-
92
tests/qemu-iotests/011 | 2 +-
93
tests/qemu-iotests/012 | 2 +-
94
tests/qemu-iotests/013 | 2 +-
95
tests/qemu-iotests/014 | 2 +-
96
tests/qemu-iotests/015 | 2 +-
97
tests/qemu-iotests/017 | 2 +-
98
tests/qemu-iotests/018 | 2 +-
99
tests/qemu-iotests/019 | 2 +-
100
tests/qemu-iotests/020 | 2 +-
101
tests/qemu-iotests/021 | 2 +-
102
tests/qemu-iotests/022 | 2 +-
103
tests/qemu-iotests/023 | 2 +-
104
tests/qemu-iotests/024 | 2 +-
105
tests/qemu-iotests/025 | 2 +-
106
tests/qemu-iotests/026 | 2 +-
107
tests/qemu-iotests/027 | 2 +-
108
tests/qemu-iotests/028 | 2 +-
109
tests/qemu-iotests/029 | 2 +-
110
tests/qemu-iotests/031 | 2 +-
111
tests/qemu-iotests/031.out | 8 +-
112
tests/qemu-iotests/032 | 2 +-
113
tests/qemu-iotests/033 | 2 +-
114
tests/qemu-iotests/034 | 2 +-
115
tests/qemu-iotests/035 | 2 +-
116
tests/qemu-iotests/036 | 2 +-
117
tests/qemu-iotests/036.out | 4 +-
118
tests/qemu-iotests/037 | 2 +-
119
tests/qemu-iotests/038 | 2 +-
120
tests/qemu-iotests/039 | 2 +-
121
tests/qemu-iotests/042 | 2 +-
122
tests/qemu-iotests/043 | 2 +-
123
tests/qemu-iotests/046 | 2 +-
124
tests/qemu-iotests/047 | 2 +-
125
tests/qemu-iotests/048 | 2 +-
126
tests/qemu-iotests/049 | 2 +-
127
tests/qemu-iotests/050 | 2 +-
128
tests/qemu-iotests/051 | 2 +-
129
tests/qemu-iotests/052 | 2 +-
130
tests/qemu-iotests/053 | 2 +-
131
tests/qemu-iotests/054 | 2 +-
132
tests/qemu-iotests/058 | 2 +-
133
tests/qemu-iotests/059 | 2 +-
134
tests/qemu-iotests/060 | 2 +-
135
tests/qemu-iotests/061 | 47 ++++-
136
tests/qemu-iotests/061.out | 103 +++++++++-
137
tests/qemu-iotests/062 | 2 +-
138
tests/qemu-iotests/063 | 2 +-
139
tests/qemu-iotests/064 | 2 +-
140
tests/qemu-iotests/066 | 2 +-
141
tests/qemu-iotests/067 | 2 +-
142
tests/qemu-iotests/068 | 2 +-
143
tests/qemu-iotests/069 | 2 +-
144
tests/qemu-iotests/070 | 2 +-
145
tests/qemu-iotests/071 | 2 +-
146
tests/qemu-iotests/072 | 2 +-
147
tests/qemu-iotests/073 | 2 +-
148
tests/qemu-iotests/074 | 2 +-
149
tests/qemu-iotests/075 | 2 +-
150
tests/qemu-iotests/076 | 2 +-
151
tests/qemu-iotests/077 | 2 +-
152
tests/qemu-iotests/078 | 2 +-
153
tests/qemu-iotests/079 | 2 +-
154
tests/qemu-iotests/080 | 2 +-
155
tests/qemu-iotests/081 | 2 +-
156
tests/qemu-iotests/082 | 2 +-
157
tests/qemu-iotests/082.out | 54 ++++++
158
tests/qemu-iotests/083 | 2 +-
159
tests/qemu-iotests/084 | 2 +-
160
tests/qemu-iotests/085 | 2 +-
161
tests/qemu-iotests/086 | 2 +-
162
tests/qemu-iotests/087 | 2 +-
163
tests/qemu-iotests/088 | 2 +-
164
tests/qemu-iotests/089 | 2 +-
165
tests/qemu-iotests/090 | 2 +-
166
tests/qemu-iotests/091 | 2 +-
167
tests/qemu-iotests/092 | 2 +-
168
tests/qemu-iotests/094 | 2 +-
169
tests/qemu-iotests/095 | 2 +-
170
tests/qemu-iotests/097 | 2 +-
171
tests/qemu-iotests/098 | 2 +-
172
tests/qemu-iotests/099 | 2 +-
173
tests/qemu-iotests/101 | 2 +-
174
tests/qemu-iotests/102 | 2 +-
175
tests/qemu-iotests/103 | 2 +-
176
tests/qemu-iotests/104 | 2 +-
177
tests/qemu-iotests/105 | 2 +-
178
tests/qemu-iotests/106 | 2 +-
179
tests/qemu-iotests/107 | 2 +-
180
tests/qemu-iotests/108 | 2 +-
181
tests/qemu-iotests/109 | 2 +-
182
tests/qemu-iotests/110 | 2 +-
183
tests/qemu-iotests/111 | 2 +-
184
tests/qemu-iotests/112 | 2 +-
185
tests/qemu-iotests/113 | 2 +-
186
tests/qemu-iotests/114 | 2 +-
187
tests/qemu-iotests/115 | 2 +-
188
tests/qemu-iotests/116 | 2 +-
189
tests/qemu-iotests/117 | 2 +-
190
tests/qemu-iotests/119 | 2 +-
191
tests/qemu-iotests/120 | 2 +-
192
tests/qemu-iotests/121 | 2 +-
193
tests/qemu-iotests/122 | 2 +-
194
tests/qemu-iotests/123 | 2 +-
195
tests/qemu-iotests/125 | 2 +-
196
tests/qemu-iotests/126 | 2 +-
197
tests/qemu-iotests/127 | 2 +-
198
tests/qemu-iotests/128 | 2 +-
199
tests/qemu-iotests/130 | 2 +-
200
tests/qemu-iotests/131 | 2 +-
201
tests/qemu-iotests/133 | 2 +-
202
tests/qemu-iotests/134 | 2 +-
203
tests/qemu-iotests/135 | 2 +-
204
tests/qemu-iotests/137 | 2 +-
205
tests/qemu-iotests/138 | 2 +-
206
tests/qemu-iotests/139 | 3 +
207
tests/qemu-iotests/140 | 2 +-
208
tests/qemu-iotests/141 | 2 +-
209
tests/qemu-iotests/142 | 2 +-
210
tests/qemu-iotests/143 | 2 +-
211
tests/qemu-iotests/144 | 2 +-
212
tests/qemu-iotests/145 | 2 +-
213
tests/qemu-iotests/146 | 2 +-
214
tests/qemu-iotests/150 | 2 +-
215
tests/qemu-iotests/153 | 2 +-
216
tests/qemu-iotests/154 | 2 +-
217
tests/qemu-iotests/156 | 2 +-
218
tests/qemu-iotests/157 | 2 +-
219
tests/qemu-iotests/158 | 2 +-
220
tests/qemu-iotests/159 | 2 +-
221
tests/qemu-iotests/160 | 2 +-
222
tests/qemu-iotests/161 | 2 +-
223
tests/qemu-iotests/162 | 2 +-
224
tests/qemu-iotests/170 | 2 +-
225
tests/qemu-iotests/171 | 2 +-
226
tests/qemu-iotests/172 | 2 +-
227
tests/qemu-iotests/173 | 2 +-
228
tests/qemu-iotests/174 | 2 +-
229
tests/qemu-iotests/175 | 2 +-
230
tests/qemu-iotests/176 | 2 +-
231
tests/qemu-iotests/177 | 2 +-
232
tests/qemu-iotests/178 | 2 +-
233
tests/qemu-iotests/179 | 2 +-
234
tests/qemu-iotests/181 | 2 +-
235
tests/qemu-iotests/182 | 2 +-
236
tests/qemu-iotests/183 | 2 +-
237
tests/qemu-iotests/184 | 2 +-
238
tests/qemu-iotests/185 | 2 +-
239
tests/qemu-iotests/186 | 2 +-
240
tests/qemu-iotests/187 | 2 +-
241
tests/qemu-iotests/188 | 2 +-
242
tests/qemu-iotests/189 | 2 +-
243
tests/qemu-iotests/190 | 2 +-
244
tests/qemu-iotests/191 | 2 +-
245
tests/qemu-iotests/192 | 2 +-
246
tests/qemu-iotests/195 | 2 +-
247
tests/qemu-iotests/197 | 2 +-
248
tests/qemu-iotests/198 | 2 +-
249
tests/qemu-iotests/200 | 2 +-
250
tests/qemu-iotests/201 | 2 +-
251
tests/qemu-iotests/204 | 2 +-
252
tests/qemu-iotests/214 | 2 +-
253
tests/qemu-iotests/215 | 2 +-
254
tests/qemu-iotests/217 | 2 +-
255
tests/qemu-iotests/220 | 2 +-
256
tests/qemu-iotests/220.out | 2 +-
257
tests/qemu-iotests/221 | 2 +-
258
tests/qemu-iotests/223 | 2 +-
259
tests/qemu-iotests/225 | 2 +-
260
tests/qemu-iotests/226 | 2 +-
261
tests/qemu-iotests/227 | 2 +-
262
tests/qemu-iotests/229 | 2 +-
263
tests/qemu-iotests/231 | 2 +-
264
tests/qemu-iotests/232 | 2 +-
265
tests/qemu-iotests/233 | 2 +-
266
tests/qemu-iotests/238 | 7 +-
267
tests/qemu-iotests/243 | 85 +++++++++
268
tests/qemu-iotests/243.out | 58 ++++++
269
tests/qemu-iotests/244 | 200 ++++++++++++++++++++
270
tests/qemu-iotests/244.out | 125 ++++++++++++
271
tests/qemu-iotests/check | 15 +-
272
tests/qemu-iotests/common.config | 2 +-
273
tests/qemu-iotests/common.filter | 38 ++--
274
tests/qemu-iotests/common.nbd | 2 +-
275
tests/qemu-iotests/common.pattern | 2 +-
276
tests/qemu-iotests/common.qemu | 2 +-
277
tests/qemu-iotests/common.rc | 15 +-
278
tests/qemu-iotests/common.tls | 2 +-
279
tests/qemu-iotests/group | 2 +
280
tests/qemu-iotests/iotests.py | 45 ++++-
281
216 files changed, 1585 insertions(+), 423 deletions(-)
282
create mode 100755 tests/qemu-iotests/243
283
create mode 100644 tests/qemu-iotests/243.out
284
create mode 100755 tests/qemu-iotests/244
285
create mode 100644 tests/qemu-iotests/244.out
286
diff view generated by jsdifflib
Deleted patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
1
3
Test 238 does not require the kvm accelerator. Using the qtest
4
accelerator allows the test to run in both non-kvm and non-tcg
5
environments.
6
7
iotests.VM implicitly uses the qtest accelerator and is really the class
8
that this test should be using. Switch to that instead of
9
qemu.QEMUMachine.
10
11
Suggested-by: Thomas Huth <thuth@redhat.com>
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
tests/qemu-iotests/238 | 7 +------
16
1 file changed, 1 insertion(+), 6 deletions(-)
17
18
diff --git a/tests/qemu-iotests/238 b/tests/qemu-iotests/238
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/238
21
+++ b/tests/qemu-iotests/238
22
@@ -XXX,XX +XXX,XX @@ import os
23
import iotests
24
from iotests import log
25
26
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
27
-
28
-from qemu import QEMUMachine
29
-
30
if iotests.qemu_default_machine == 's390-ccw-virtio':
31
virtio_scsi_device = 'virtio-scsi-ccw'
32
else:
33
virtio_scsi_device = 'virtio-scsi-pci'
34
35
-vm = QEMUMachine(iotests.qemu_prog)
36
-vm.add_args('-machine', 'accel=kvm')
37
+vm = iotests.VM()
38
vm.launch()
39
40
log(vm.qmp('blockdev-add', node_name='hd0', driver='null-co'))
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Alberto Garcia <berto@igalia.com>
2
1
3
QEMU 2.12 (commit 1221fe6f636754ab5f2c1c87caa77633e9123622) introduced
4
a new setting called l2-cache-entry-size that allows making entries on
5
the qcow2 L2 cache smaller than the cluster size.
6
7
I have been performing several tests with different cluster and entry
8
sizes and all of them show that reducing the entry size (aka L2 slice)
9
consistently improves I/O performance, notably during random I/O (all
10
tests done with sequential I/O show similar results). This is to be
11
expected because loading and evicting an L2 slice is more expensive
12
the larger the slice is.
13
14
Here are some numbers on fully populated 40GB qcow2 images. The
15
rightmost column represents the maximum L2 cache size in both cases.
16
17
Cluster size = 64 KB
18
|-------------+--------------+--------------+--------------|
19
| | 1MB L2 cache | 3MB L2 cache | 5MB L2 cache |
20
|-------------+--------------+--------------+--------------|
21
| 4KB slices | 6545 IOPS | 12045 IOPS | 55680 IOPS |
22
| 16KB slices | 5177 IOPS | 9798 IOPS | 56278 IOPS |
23
| 64KB slices | 2718 IOPS | 5326 IOPS | 57355 IOPS |
24
|-------------+--------------+--------------+--------------|
25
26
Cluster size = 256 KB
27
|--------------+----------------+--------------+-----------------|
28
| | 512KB L2 cache | 1MB L2 cache | 1280KB L2 cache |
29
|--------------+----------------+--------------+-----------------|
30
| 4KB slices | 8539 IOPS | 21071 IOPS | 55417 IOPS |
31
| 64KB slices | 3598 IOPS | 9772 IOPS | 57687 IOPS |
32
| 256KB slices | 1415 IOPS | 4120 IOPS | 58001 IOPS |
33
|--------------+----------------+--------------+-----------------|
34
35
As can be seen in the numbers, the only exception to the rule is when
36
the cache is large enough to hold all L2 tables. This is also to be
37
expected because in this case no cache entry is ever evicted so
38
reducing its size doesn't bring any benefit.
39
40
This patch sets the default L2 cache entry size to 4KB except when the
41
cache is large enough for the whole disk.
42
43
Signed-off-by: Alberto Garcia <berto@igalia.com>
44
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
45
---
46
docs/qcow2-cache.txt | 17 +++++++++++------
47
block/qcow2.c | 12 ++++++++++++
48
2 files changed, 23 insertions(+), 6 deletions(-)
49
50
diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt
51
index XXXXXXX..XXXXXXX 100644
52
--- a/docs/qcow2-cache.txt
53
+++ b/docs/qcow2-cache.txt
54
@@ -XXX,XX +XXX,XX @@ refcount cache is as small as possible unless overridden by the user.
55
56
Using smaller cache entries
57
---------------------------
58
-The qcow2 L2 cache stores complete tables by default. This means that
59
-if QEMU needs an entry from an L2 table then the whole table is read
60
-from disk and is kept in the cache. If the cache is full then a
61
-complete table needs to be evicted first.
62
+The qcow2 L2 cache can store complete tables. This means that if QEMU
63
+needs an entry from an L2 table then the whole table is read from disk
64
+and is kept in the cache. If the cache is full then a complete table
65
+needs to be evicted first.
66
67
This can be inefficient with large cluster sizes since it results in
68
more disk I/O and wastes more cache memory.
69
@@ -XXX,XX +XXX,XX @@ it smaller than the cluster size. This can be configured using the
70
71
-drive file=hd.qcow2,l2-cache-size=2097152,l2-cache-entry-size=4096
72
73
+Since QEMU 4.0 the value of l2-cache-entry-size defaults to 4KB (or
74
+the cluster size if it's smaller).
75
+
76
Some things to take into account:
77
78
- The L2 cache entry size has the same restrictions as the cluster
79
@@ -XXX,XX +XXX,XX @@ Some things to take into account:
80
81
- Try different entry sizes to see which one gives faster performance
82
in your case. The block size of the host filesystem is generally a
83
- good default (usually 4096 bytes in the case of ext4).
84
+ good default (usually 4096 bytes in the case of ext4, hence the
85
+ default).
86
87
- Only the L2 cache can be configured this way. The refcount cache
88
always uses the cluster size as the entry size.
89
@@ -XXX,XX +XXX,XX @@ Some things to take into account:
90
(as explained in the "Choosing the right cache sizes" and "How to
91
configure the cache sizes" sections in this document) then none of
92
this is necessary and you can omit the "l2-cache-entry-size"
93
- parameter altogether.
94
+ parameter altogether. In this case QEMU makes the entry size
95
+ equal to the cluster size by default.
96
97
98
Reducing the memory usage
99
diff --git a/block/qcow2.c b/block/qcow2.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/qcow2.c
102
+++ b/block/qcow2.c
103
@@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
104
BDRVQcow2State *s = bs->opaque;
105
uint64_t combined_cache_size, l2_cache_max_setting;
106
bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set;
107
+ bool l2_cache_entry_size_set;
108
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
109
uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
110
uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
111
@@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
112
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
113
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
114
refcount_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE);
115
+ l2_cache_entry_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_ENTRY_SIZE);
116
117
combined_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_CACHE_SIZE, 0);
118
l2_cache_max_setting = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE,
119
@@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
120
}
121
}
122
}
123
+
124
+ /*
125
+ * If the L2 cache is not enough to cover the whole disk then
126
+ * default to 4KB entries. Smaller entries reduce the cost of
127
+ * loads and evictions and increase I/O performance.
128
+ */
129
+ if (*l2_cache_size < max_l2_cache && !l2_cache_entry_size_set) {
130
+ *l2_cache_entry_size = MIN(s->cluster_size, 4096);
131
+ }
132
+
133
/* l2_cache_size and refcount_cache_size are ensured to have at least
134
* their minimum values in qcow2_update_options_prepare() */
135
136
--
137
2.20.1
138
139
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Supported formats listed by 'qemu' may differ from those listed by
3
Currently, the "thistime" variable is not reinitialized on every loop
4
'qemu-img' due to whitelists. Some test cases require specific formats
4
iteration. This leads to tests that do not yield a run time (because
5
that may be used with qemu. They can be inquired directly by running
5
they failed or were skipped) printing the run time of the previous test
6
'qemu -drive format=help'. The response takes whitelists into account.
6
that did. Fix that by reinitializing "thistime" for every test.
7
The method supported_formats() serves for that. The method decorator
8
skip_if_unsupported() checks if all requested formats are whitelisted.
9
If not, the test case will be skipped. That has been implemented in
10
the 'check' file in the way similar to the 'test notrun' mechanism.
11
7
12
Suggested-by: Roman Kagan <rkagan@virtuozzo.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Suggested-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
12
---
18
tests/qemu-iotests/check | 13 ++++++++++-
13
tests/qemu-iotests/check | 1 +
19
tests/qemu-iotests/iotests.py | 43 +++++++++++++++++++++++++++++++++++
14
1 file changed, 1 insertion(+)
20
2 files changed, 55 insertions(+), 1 deletion(-)
21
15
22
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
16
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
23
index XXXXXXX..XXXXXXX 100755
17
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/check
18
--- a/tests/qemu-iotests/check
25
+++ b/tests/qemu-iotests/check
19
+++ b/tests/qemu-iotests/check
26
@@ -XXX,XX +XXX,XX @@ try=0
27
n_bad=0
28
bad=""
29
notrun=""
30
+casenotrun=""
31
interrupt=true
32
33
# by default don't output timestamps
34
@@ -XXX,XX +XXX,XX @@ END { if (NR > 0) {
35
echo "Not run:$notrun"
36
echo "Not run:$notrun" >>check.log
37
fi
38
+ if [ ! -z "$casenotrun" ]
39
+ then
40
+ echo "Some cases not run in:$casenotrun"
41
+ echo "Some cases not run in:$casenotrun" >>check.log
42
+ fi
43
if [ ! -z "$n_bad" -a $n_bad != 0 ]
44
then
45
echo "Failures:$bad"
46
@@ -XXX,XX +XXX,XX @@ do
20
@@ -XXX,XX +XXX,XX @@ do
47
printf " " # prettier output with timestamps.
21
printdiff=false # show diff to reference output?
48
fi
22
status="" # test result summary
49
rm -f core $seq.notrun
23
results="" # test result details
50
+ rm -f $seq.casenotrun
24
+ thistime="" # time the test took
51
25
52
start=$(_wallclock)
26
if [ -n "$TESTS_REMAINING_LOG" ] ; then
53
$timestamp && printf %s " [$(date "+%T")]"
27
sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
54
@@ -XXX,XX +XXX,XX @@ do
55
fi
56
fi
57
fi
58
-
59
+ if [ -f $seq.casenotrun ]
60
+ then
61
+ cat $seq.casenotrun
62
+ casenotrun="$casenotrun $seq"
63
+ fi
64
fi
65
66
# come here for each test, except when $showme is true
67
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
68
index XXXXXXX..XXXXXXX 100644
69
--- a/tests/qemu-iotests/iotests.py
70
+++ b/tests/qemu-iotests/iotests.py
71
@@ -XXX,XX +XXX,XX @@ def notrun(reason):
72
print('%s not run: %s' % (seq, reason))
73
sys.exit(0)
74
75
+def case_notrun(reason):
76
+ '''Skip this test case'''
77
+ # Each test in qemu-iotests has a number ("seq")
78
+ seq = os.path.basename(sys.argv[0])
79
+
80
+ open('%s/%s.casenotrun' % (output_dir, seq), 'a').write(
81
+ ' [case not run] ' + reason + '\n')
82
+
83
def verify_image_format(supported_fmts=[], unsupported_fmts=[]):
84
assert not (supported_fmts and unsupported_fmts)
85
86
@@ -XXX,XX +XXX,XX @@ def verify_quorum():
87
if not supports_quorum():
88
notrun('quorum support missing')
89
90
+def qemu_pipe(*args):
91
+ '''Run qemu with an option to print something and exit (e.g. a help option),
92
+ and return its output'''
93
+ args = [qemu_prog] + qemu_opts + list(args)
94
+ subp = subprocess.Popen(args, stdout=subprocess.PIPE,
95
+ stderr=subprocess.STDOUT,
96
+ universal_newlines=True)
97
+ exitcode = subp.wait()
98
+ if exitcode < 0:
99
+ sys.stderr.write('qemu received signal %i: %s\n' % (-exitcode,
100
+ ' '.join(args)))
101
+ return subp.communicate()[0]
102
+
103
+def supported_formats(read_only=False):
104
+ '''Set 'read_only' to True to check ro-whitelist
105
+ Otherwise, rw-whitelist is checked'''
106
+ format_message = qemu_pipe("-drive", "format=help")
107
+ line = 1 if read_only else 0
108
+ return format_message.splitlines()[line].split(":")[1].split()
109
+
110
+def skip_if_unsupported(required_formats=[], read_only=False):
111
+ '''Skip Test Decorator
112
+ Runs the test if all the required formats are whitelisted'''
113
+ def skip_test_decorator(func):
114
+ def func_wrapper(*args, **kwargs):
115
+ usf_list = list(set(required_formats) -
116
+ set(supported_formats(read_only)))
117
+ if usf_list:
118
+ case_notrun('{}: formats {} are not whitelisted'.format(
119
+ args[0], usf_list))
120
+ else:
121
+ return func(*args, **kwargs)
122
+ return func_wrapper
123
+ return skip_test_decorator
124
+
125
def main(supported_fmts=[], supported_oses=['linux'], supported_cache_modes=[],
126
unsupported_fmts=[]):
127
'''Run tests'''
128
--
28
--
129
2.20.1
29
2.20.1
130
30
131
31
diff view generated by jsdifflib
1
Provide an option to force QEMU to always keep the external data file
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
consistent as a standalone read-only raw image.
2
3
3
We are going to remove bs->job pointer. Drop it's usage in replication
4
At the moment, this means making sure that write_zeroes requests are
4
code. Additionally we have to return job pointer from some mirror APIs.
5
forwarded to the data file instead of just updating the metadata, and
5
6
checking that no backing file is used.
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
8
---
10
qapi/block-core.json | 9 ++++++
9
include/block/block_int.h | 12 ++++++------
11
block/qcow2.h | 9 +++++-
10
block/mirror.c | 38 ++++++++++++++++++++++----------------
12
include/block/block_int.h | 1 +
11
block/replication.c | 21 ++++++++++++---------
13
block/qcow2-cluster.c | 10 +++++++
12
3 files changed, 40 insertions(+), 31 deletions(-)
14
block/qcow2.c | 56 ++++++++++++++++++++++++++++++++++++--
13
15
tests/qemu-iotests/082.out | 27 ++++++++++++++++++
16
6 files changed, 109 insertions(+), 3 deletions(-)
17
18
diff --git a/qapi/block-core.json b/qapi/block-core.json
19
index XXXXXXX..XXXXXXX 100644
20
--- a/qapi/block-core.json
21
+++ b/qapi/block-core.json
22
@@ -XXX,XX +XXX,XX @@
23
# @data-file: the filename of the external data file that is stored in the
24
# image and used as a default for opening the image (since: 4.0)
25
#
26
+# @data-file-raw: True if the external data file must stay valid as a
27
+# standalone (read-only) raw image without looking at qcow2
28
+# metadata (since: 4.0)
29
+#
30
# @lazy-refcounts: on or off; only valid for compat >= 1.1
31
#
32
# @corrupt: true if the image has been marked corrupt; only valid for
33
@@ -XXX,XX +XXX,XX @@
34
'data': {
35
'compat': 'str',
36
'*data-file': 'str',
37
+ '*data-file-raw': 'bool',
38
'*lazy-refcounts': 'bool',
39
'*corrupt': 'bool',
40
'refcount-bits': 'int',
41
@@ -XXX,XX +XXX,XX @@
42
# @data-file Node to use as an external data file in which all guest
43
# data is stored so that only metadata remains in the qcow2
44
# file (since: 4.0)
45
+# @data-file-raw True if the external data file must stay valid as a
46
+# standalone (read-only) raw image without looking at qcow2
47
+# metadata (default: false; since: 4.0)
48
# @size Size of the virtual disk in bytes
49
# @version Compatibility level (default: v3)
50
# @backing-file File name of the backing file if a backing file
51
@@ -XXX,XX +XXX,XX @@
52
{ 'struct': 'BlockdevCreateOptionsQcow2',
53
'data': { 'file': 'BlockdevRef',
54
'*data-file': 'BlockdevRef',
55
+ '*data-file-raw': 'bool',
56
'size': 'size',
57
'*version': 'BlockdevQcow2Version',
58
'*backing-file': 'str',
59
diff --git a/block/qcow2.h b/block/qcow2.h
60
index XXXXXXX..XXXXXXX 100644
61
--- a/block/qcow2.h
62
+++ b/block/qcow2.h
63
@@ -XXX,XX +XXX,XX @@ enum {
64
QCOW2_AUTOCLEAR_BITMAPS = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR,
65
QCOW2_AUTOCLEAR_DATA_FILE_RAW = 1 << QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR,
66
67
- QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS,
68
+ QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS
69
+ | QCOW2_AUTOCLEAR_DATA_FILE_RAW,
70
};
71
72
enum qcow2_discard_type {
73
@@ -XXX,XX +XXX,XX @@ static inline bool has_data_file(BlockDriverState *bs)
74
return (s->data_file != bs->file);
75
}
76
77
+static inline bool data_file_is_raw(BlockDriverState *bs)
78
+{
79
+ BDRVQcow2State *s = bs->opaque;
80
+ return !!(s->autoclear_features & QCOW2_AUTOCLEAR_DATA_FILE_RAW);
81
+}
82
+
83
static inline int64_t start_of_cluster(BDRVQcow2State *s, int64_t offset)
84
{
85
return offset & ~(s->cluster_size - 1);
86
diff --git a/include/block/block_int.h b/include/block/block_int.h
14
diff --git a/include/block/block_int.h b/include/block/block_int.h
87
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
88
--- a/include/block/block_int.h
16
--- a/include/block/block_int.h
89
+++ b/include/block/block_int.h
17
+++ b/include/block/block_int.h
90
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
91
#define BLOCK_OPT_OBJECT_SIZE "object_size"
19
* @errp: Error object.
92
#define BLOCK_OPT_REFCOUNT_BITS "refcount_bits"
20
*
93
#define BLOCK_OPT_DATA_FILE "data_file"
21
*/
94
+#define BLOCK_OPT_DATA_FILE_RAW "data_file_raw"
22
-void commit_active_start(const char *job_id, BlockDriverState *bs,
95
23
- BlockDriverState *base, int creation_flags,
96
#define BLOCK_PROBE_BUF_SIZE 512
24
- int64_t speed, BlockdevOnError on_error,
97
25
- const char *filter_node_name,
98
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
26
- BlockCompletionFunc *cb, void *opaque,
27
- bool auto_complete, Error **errp);
28
+BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
29
+ BlockDriverState *base, int creation_flags,
30
+ int64_t speed, BlockdevOnError on_error,
31
+ const char *filter_node_name,
32
+ BlockCompletionFunc *cb, void *opaque,
33
+ bool auto_complete, Error **errp);
34
/*
35
* mirror_start:
36
* @job_id: The id of the newly-created job, or %NULL to use the
37
diff --git a/block/mirror.c b/block/mirror.c
99
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
100
--- a/block/qcow2-cluster.c
39
--- a/block/mirror.c
101
+++ b/block/qcow2-cluster.c
40
+++ b/block/mirror.c
102
@@ -XXX,XX +XXX,XX @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
41
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_mirror_top = {
103
int64_t cleared;
42
.bdrv_child_perm = bdrv_mirror_top_child_perm,
43
};
44
45
-static void mirror_start_job(const char *job_id, BlockDriverState *bs,
46
+static BlockJob *mirror_start_job(
47
+ const char *job_id, BlockDriverState *bs,
48
int creation_flags, BlockDriverState *target,
49
const char *replaces, int64_t speed,
50
uint32_t granularity, int64_t buf_size,
51
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
52
53
if (buf_size < 0) {
54
error_setg(errp, "Invalid parameter 'buf-size'");
55
- return;
56
+ return NULL;
57
}
58
59
if (buf_size == 0) {
60
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
61
62
if (bs == target) {
63
error_setg(errp, "Can't mirror node into itself");
64
- return;
65
+ return NULL;
66
}
67
68
/* In the case of active commit, add dummy driver to provide consistent
69
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
70
mirror_top_bs = bdrv_new_open_driver(&bdrv_mirror_top, filter_node_name,
71
BDRV_O_RDWR, errp);
72
if (mirror_top_bs == NULL) {
73
- return;
74
+ return NULL;
75
}
76
if (!filter_node_name) {
77
mirror_top_bs->implicit = true;
78
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
79
if (local_err) {
80
bdrv_unref(mirror_top_bs);
81
error_propagate(errp, local_err);
82
- return;
83
+ return NULL;
84
}
85
86
/* Make sure that the source is not resized while the job is running */
87
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
88
89
trace_mirror_start(bs, s, opaque);
90
job_start(&s->common.job);
91
- return;
92
+
93
+ return &s->common;
94
95
fail:
96
if (s) {
97
@@ -XXX,XX +XXX,XX @@ fail:
98
bdrv_replace_node(mirror_top_bs, backing_bs(mirror_top_bs), &error_abort);
99
100
bdrv_unref(mirror_top_bs);
101
+
102
+ return NULL;
103
}
104
105
void mirror_start(const char *job_id, BlockDriverState *bs,
106
@@ -XXX,XX +XXX,XX @@ void mirror_start(const char *job_id, BlockDriverState *bs,
107
filter_node_name, true, copy_mode, errp);
108
}
109
110
-void commit_active_start(const char *job_id, BlockDriverState *bs,
111
- BlockDriverState *base, int creation_flags,
112
- int64_t speed, BlockdevOnError on_error,
113
- const char *filter_node_name,
114
- BlockCompletionFunc *cb, void *opaque,
115
- bool auto_complete, Error **errp)
116
+BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
117
+ BlockDriverState *base, int creation_flags,
118
+ int64_t speed, BlockdevOnError on_error,
119
+ const char *filter_node_name,
120
+ BlockCompletionFunc *cb, void *opaque,
121
+ bool auto_complete, Error **errp)
122
{
123
bool base_read_only;
124
Error *local_err = NULL;
125
+ BlockJob *ret;
126
127
base_read_only = bdrv_is_read_only(base);
128
129
if (base_read_only) {
130
if (bdrv_reopen_set_read_only(base, false, errp) < 0) {
131
- return;
132
+ return NULL;
133
}
134
}
135
136
- mirror_start_job(job_id, bs, creation_flags, base, NULL, speed, 0, 0,
137
+ ret = mirror_start_job(
138
+ job_id, bs, creation_flags, base, NULL, speed, 0, 0,
139
MIRROR_LEAVE_BACKING_CHAIN,
140
on_error, on_error, true, cb, opaque,
141
&commit_active_job_driver, false, base, auto_complete,
142
@@ -XXX,XX +XXX,XX @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
143
goto error_restore_flags;
144
}
145
146
- return;
147
+ return ret;
148
149
error_restore_flags:
150
/* ignore error and errp for bdrv_reopen, because we want to propagate
151
@@ -XXX,XX +XXX,XX @@ error_restore_flags:
152
if (base_read_only) {
153
bdrv_reopen_set_read_only(base, true, NULL);
154
}
155
- return;
156
+ return NULL;
157
}
158
diff --git a/block/replication.c b/block/replication.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/block/replication.c
161
+++ b/block/replication.c
162
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVReplicationState {
163
ReplicationMode mode;
164
ReplicationStage stage;
165
BdrvChild *active_disk;
166
+ BlockJob *commit_job;
167
BdrvChild *hidden_disk;
168
BdrvChild *secondary_disk;
169
+ BlockJob *backup_job;
170
char *top_id;
171
ReplicationState *rs;
172
Error *blocker;
173
@@ -XXX,XX +XXX,XX @@ static void replication_close(BlockDriverState *bs)
174
replication_stop(s->rs, false, NULL);
175
}
176
if (s->stage == BLOCK_REPLICATION_FAILOVER) {
177
- job_cancel_sync(&s->active_disk->bs->job->job);
178
+ job_cancel_sync(&s->commit_job->job);
179
}
180
181
if (s->mode == REPLICATION_MODE_SECONDARY) {
182
@@ -XXX,XX +XXX,XX @@ static void secondary_do_checkpoint(BDRVReplicationState *s, Error **errp)
183
Error *local_err = NULL;
104
int ret;
184
int ret;
105
185
106
+ /* If we have to stay in sync with an external data file, zero out
186
- if (!s->secondary_disk->bs->job) {
107
+ * s->data_file first. */
187
+ if (!s->backup_job) {
108
+ if (data_file_is_raw(bs)) {
188
error_setg(errp, "Backup job was cancelled unexpectedly");
109
+ assert(has_data_file(bs));
189
return;
110
+ ret = bdrv_co_pwrite_zeroes(s->data_file, offset, bytes, flags);
190
}
111
+ if (ret < 0) {
191
112
+ return ret;
192
- backup_do_checkpoint(s->secondary_disk->bs->job, &local_err);
113
+ }
193
+ backup_do_checkpoint(s->backup_job, &local_err);
114
+ }
194
if (local_err) {
115
+
195
error_propagate(errp, local_err);
116
/* Caller must pass aligned values, except at image end */
196
return;
117
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
197
@@ -XXX,XX +XXX,XX @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
118
assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) ||
198
int64_t active_length, hidden_length, disk_length;
119
diff --git a/block/qcow2.c b/block/qcow2.c
199
AioContext *aio_context;
120
index XXXXXXX..XXXXXXX 100644
200
Error *local_err = NULL;
121
--- a/block/qcow2.c
201
- BlockJob *job;
122
+++ b/block/qcow2.c
202
123
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
203
aio_context = bdrv_get_aio_context(bs);
124
"external data file");
204
aio_context_acquire(aio_context);
125
ret = -EINVAL;
205
@@ -XXX,XX +XXX,XX @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
126
goto fail;
206
bdrv_op_block_all(top_bs, s->blocker);
127
- } else {
207
bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);
128
- s->data_file = bs->file;
208
129
+ }
209
- job = backup_job_create(NULL, s->secondary_disk->bs, s->hidden_disk->bs,
130
+
210
+ s->backup_job = backup_job_create(
131
+ s->data_file = bs->file;
211
+ NULL, s->secondary_disk->bs, s->hidden_disk->bs,
132
+
212
0, MIRROR_SYNC_MODE_NONE, NULL, false,
133
+ if (data_file_is_raw(bs)) {
213
BLOCKDEV_ON_ERROR_REPORT,
134
+ error_setg(errp, "data-file-raw requires a data file");
214
BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
135
+ ret = -EINVAL;
215
@@ -XXX,XX +XXX,XX @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
136
+ goto fail;
216
aio_context_release(aio_context);
137
}
217
return;
138
}
218
}
139
219
- job_start(&job->job);
140
@@ -XXX,XX +XXX,XX @@ static int qcow2_change_backing_file(BlockDriverState *bs,
220
+ job_start(&s->backup_job->job);
141
{
221
break;
142
BDRVQcow2State *s = bs->opaque;
222
default:
143
223
aio_context_release(aio_context);
144
+ /* Adding a backing file means that the external data file alone won't be
224
@@ -XXX,XX +XXX,XX @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
145
+ * enough to make sense of the content */
225
* before the BDS is closed, because we will access hidden
146
+ if (backing_file && data_file_is_raw(bs)) {
226
* disk, secondary disk in backup_job_completed().
147
+ return -EINVAL;
227
*/
148
+ }
228
- if (s->secondary_disk->bs->job) {
149
+
229
- job_cancel_sync(&s->secondary_disk->bs->job->job);
150
if (backing_file && strlen(backing_file) > 1023) {
230
+ if (s->backup_job) {
151
return -EINVAL;
231
+ job_cancel_sync(&s->backup_job->job);
152
}
232
}
153
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
233
154
}
234
if (!failover) {
155
refcount_order = ctz32(qcow2_opts->refcount_bits);
235
@@ -XXX,XX +XXX,XX @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
156
236
}
157
+ if (qcow2_opts->data_file_raw && !qcow2_opts->data_file) {
237
158
+ error_setg(errp, "data-file-raw requires data-file");
238
s->stage = BLOCK_REPLICATION_FAILOVER;
159
+ ret = -EINVAL;
239
- commit_active_start(NULL, s->active_disk->bs, s->secondary_disk->bs,
160
+ goto out;
240
+ s->commit_job = commit_active_start(
161
+ }
241
+ NULL, s->active_disk->bs, s->secondary_disk->bs,
162
+ if (qcow2_opts->data_file_raw && qcow2_opts->has_backing_file) {
242
JOB_INTERNAL, 0, BLOCKDEV_ON_ERROR_REPORT,
163
+ error_setg(errp, "Backing file and data-file-raw cannot be used at "
243
NULL, replication_done, bs, true, errp);
164
+ "the same time");
244
break;
165
+ ret = -EINVAL;
166
+ goto out;
167
+ }
168
+
169
if (qcow2_opts->data_file) {
170
if (version < 3) {
171
error_setg(errp, "External data files are only supported with "
172
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
173
header->incompatible_features |=
174
cpu_to_be64(QCOW2_INCOMPAT_DATA_FILE);
175
}
176
+ if (qcow2_opts->data_file_raw) {
177
+ header->autoclear_features |=
178
+ cpu_to_be64(QCOW2_AUTOCLEAR_DATA_FILE_RAW);
179
+ }
180
181
ret = blk_pwrite(blk, 0, header, cluster_size, 0);
182
g_free(header);
183
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_create_opts(const char *filename, QemuOpts *opt
184
{ BLOCK_OPT_REFCOUNT_BITS, "refcount-bits" },
185
{ BLOCK_OPT_ENCRYPT, BLOCK_OPT_ENCRYPT_FORMAT },
186
{ BLOCK_OPT_COMPAT_LEVEL, "version" },
187
+ { BLOCK_OPT_DATA_FILE_RAW, "data-file-raw" },
188
{ NULL, NULL },
189
};
190
191
@@ -XXX,XX +XXX,XX @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs,
192
.bitmaps = bitmaps,
193
.has_data_file = !!s->image_data_file,
194
.data_file = g_strdup(s->image_data_file),
195
+ .has_data_file_raw = has_data_file(bs),
196
+ .data_file_raw = data_file_is_raw(bs),
197
};
198
} else {
199
/* if this assertion fails, this probably means a new version was
200
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
201
uint64_t new_size = 0;
202
const char *backing_file = NULL, *backing_format = NULL, *data_file = NULL;
203
bool lazy_refcounts = s->use_lazy_refcounts;
204
+ bool data_file_raw = data_file_is_raw(bs);
205
const char *compat = NULL;
206
uint64_t cluster_size = s->cluster_size;
207
bool encrypt;
208
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
209
"use an external data file");
210
return -EINVAL;
211
}
212
+ } else if (!strcmp(desc->name, BLOCK_OPT_DATA_FILE_RAW)) {
213
+ data_file_raw = qemu_opt_get_bool(opts, BLOCK_OPT_DATA_FILE_RAW,
214
+ data_file_raw);
215
+ if (data_file_raw && !data_file_is_raw(bs)) {
216
+ error_setg(errp, "data-file-raw cannot be set on existing "
217
+ "images");
218
+ return -EINVAL;
219
+ }
220
} else {
221
/* if this point is reached, this probably means a new option was
222
* added without having it covered here */
223
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
224
}
225
}
226
227
+ /* data-file-raw blocks backing files, so clear it first if requested */
228
+ if (data_file_raw) {
229
+ s->autoclear_features |= QCOW2_AUTOCLEAR_DATA_FILE_RAW;
230
+ } else {
231
+ s->autoclear_features &= ~QCOW2_AUTOCLEAR_DATA_FILE_RAW;
232
+ }
233
+
234
if (data_file) {
235
g_free(s->image_data_file);
236
s->image_data_file = *data_file ? g_strdup(data_file) : NULL;
237
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = {
238
.type = QEMU_OPT_STRING,
239
.help = "File name of an external data file"
240
},
241
+ {
242
+ .name = BLOCK_OPT_DATA_FILE_RAW,
243
+ .type = QEMU_OPT_BOOL,
244
+ .help = "The external data file must stay valid as a raw image"
245
+ },
246
{
247
.name = BLOCK_OPT_ENCRYPT,
248
.type = QEMU_OPT_BOOL,
249
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
250
index XXXXXXX..XXXXXXX 100644
251
--- a/tests/qemu-iotests/082.out
252
+++ b/tests/qemu-iotests/082.out
253
@@ -XXX,XX +XXX,XX @@ Supported options:
254
cluster_size=<size> - qcow2 cluster size
255
compat=<str> - Compatibility level (0.10 or 1.1)
256
data_file=<str> - File name of an external data file
257
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
258
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
259
encrypt.cipher-mode=<str> - Name of encryption cipher mode
260
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
261
@@ -XXX,XX +XXX,XX @@ Supported options:
262
cluster_size=<size> - qcow2 cluster size
263
compat=<str> - Compatibility level (0.10 or 1.1)
264
data_file=<str> - File name of an external data file
265
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
266
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
267
encrypt.cipher-mode=<str> - Name of encryption cipher mode
268
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
269
@@ -XXX,XX +XXX,XX @@ Supported options:
270
cluster_size=<size> - qcow2 cluster size
271
compat=<str> - Compatibility level (0.10 or 1.1)
272
data_file=<str> - File name of an external data file
273
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
274
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
275
encrypt.cipher-mode=<str> - Name of encryption cipher mode
276
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
277
@@ -XXX,XX +XXX,XX @@ Supported options:
278
cluster_size=<size> - qcow2 cluster size
279
compat=<str> - Compatibility level (0.10 or 1.1)
280
data_file=<str> - File name of an external data file
281
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
282
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
283
encrypt.cipher-mode=<str> - Name of encryption cipher mode
284
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
285
@@ -XXX,XX +XXX,XX @@ Supported options:
286
cluster_size=<size> - qcow2 cluster size
287
compat=<str> - Compatibility level (0.10 or 1.1)
288
data_file=<str> - File name of an external data file
289
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
290
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
291
encrypt.cipher-mode=<str> - Name of encryption cipher mode
292
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
293
@@ -XXX,XX +XXX,XX @@ Supported options:
294
cluster_size=<size> - qcow2 cluster size
295
compat=<str> - Compatibility level (0.10 or 1.1)
296
data_file=<str> - File name of an external data file
297
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
298
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
299
encrypt.cipher-mode=<str> - Name of encryption cipher mode
300
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
301
@@ -XXX,XX +XXX,XX @@ Supported options:
302
cluster_size=<size> - qcow2 cluster size
303
compat=<str> - Compatibility level (0.10 or 1.1)
304
data_file=<str> - File name of an external data file
305
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
306
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
307
encrypt.cipher-mode=<str> - Name of encryption cipher mode
308
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
309
@@ -XXX,XX +XXX,XX @@ Supported options:
310
cluster_size=<size> - qcow2 cluster size
311
compat=<str> - Compatibility level (0.10 or 1.1)
312
data_file=<str> - File name of an external data file
313
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
314
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
315
encrypt.cipher-mode=<str> - Name of encryption cipher mode
316
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
317
@@ -XXX,XX +XXX,XX @@ Supported options:
318
cluster_size=<size> - qcow2 cluster size
319
compat=<str> - Compatibility level (0.10 or 1.1)
320
data_file=<str> - File name of an external data file
321
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
322
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
323
encrypt.cipher-mode=<str> - Name of encryption cipher mode
324
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
325
@@ -XXX,XX +XXX,XX @@ Supported options:
326
cluster_size=<size> - qcow2 cluster size
327
compat=<str> - Compatibility level (0.10 or 1.1)
328
data_file=<str> - File name of an external data file
329
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
330
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
331
encrypt.cipher-mode=<str> - Name of encryption cipher mode
332
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
333
@@ -XXX,XX +XXX,XX @@ Supported options:
334
cluster_size=<size> - qcow2 cluster size
335
compat=<str> - Compatibility level (0.10 or 1.1)
336
data_file=<str> - File name of an external data file
337
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
338
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
339
encrypt.cipher-mode=<str> - Name of encryption cipher mode
340
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
341
@@ -XXX,XX +XXX,XX @@ Supported options:
342
cluster_size=<size> - qcow2 cluster size
343
compat=<str> - Compatibility level (0.10 or 1.1)
344
data_file=<str> - File name of an external data file
345
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
346
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
347
encrypt.cipher-mode=<str> - Name of encryption cipher mode
348
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
349
@@ -XXX,XX +XXX,XX @@ Supported options:
350
cluster_size=<size> - qcow2 cluster size
351
compat=<str> - Compatibility level (0.10 or 1.1)
352
data_file=<str> - File name of an external data file
353
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
354
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
355
encrypt.cipher-mode=<str> - Name of encryption cipher mode
356
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
357
@@ -XXX,XX +XXX,XX @@ Supported options:
358
cluster_size=<size> - qcow2 cluster size
359
compat=<str> - Compatibility level (0.10 or 1.1)
360
data_file=<str> - File name of an external data file
361
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
362
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
363
encrypt.cipher-mode=<str> - Name of encryption cipher mode
364
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
365
@@ -XXX,XX +XXX,XX @@ Supported options:
366
cluster_size=<size> - qcow2 cluster size
367
compat=<str> - Compatibility level (0.10 or 1.1)
368
data_file=<str> - File name of an external data file
369
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
370
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
371
encrypt.cipher-mode=<str> - Name of encryption cipher mode
372
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
373
@@ -XXX,XX +XXX,XX @@ Supported options:
374
cluster_size=<size> - qcow2 cluster size
375
compat=<str> - Compatibility level (0.10 or 1.1)
376
data_file=<str> - File name of an external data file
377
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
378
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
379
encrypt.cipher-mode=<str> - Name of encryption cipher mode
380
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
381
@@ -XXX,XX +XXX,XX @@ Supported options:
382
cluster_size=<size> - qcow2 cluster size
383
compat=<str> - Compatibility level (0.10 or 1.1)
384
data_file=<str> - File name of an external data file
385
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
386
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
387
encrypt.cipher-mode=<str> - Name of encryption cipher mode
388
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
389
@@ -XXX,XX +XXX,XX @@ Supported options:
390
cluster_size=<size> - qcow2 cluster size
391
compat=<str> - Compatibility level (0.10 or 1.1)
392
data_file=<str> - File name of an external data file
393
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
394
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
395
encrypt.cipher-mode=<str> - Name of encryption cipher mode
396
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
397
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
398
cluster_size=<size> - qcow2 cluster size
399
compat=<str> - Compatibility level (0.10 or 1.1)
400
data_file=<str> - File name of an external data file
401
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
402
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
403
encrypt.cipher-mode=<str> - Name of encryption cipher mode
404
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
405
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
406
cluster_size=<size> - qcow2 cluster size
407
compat=<str> - Compatibility level (0.10 or 1.1)
408
data_file=<str> - File name of an external data file
409
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
410
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
411
encrypt.cipher-mode=<str> - Name of encryption cipher mode
412
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
413
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
414
cluster_size=<size> - qcow2 cluster size
415
compat=<str> - Compatibility level (0.10 or 1.1)
416
data_file=<str> - File name of an external data file
417
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
418
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
419
encrypt.cipher-mode=<str> - Name of encryption cipher mode
420
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
421
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
422
cluster_size=<size> - qcow2 cluster size
423
compat=<str> - Compatibility level (0.10 or 1.1)
424
data_file=<str> - File name of an external data file
425
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
426
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
427
encrypt.cipher-mode=<str> - Name of encryption cipher mode
428
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
429
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
430
cluster_size=<size> - qcow2 cluster size
431
compat=<str> - Compatibility level (0.10 or 1.1)
432
data_file=<str> - File name of an external data file
433
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
434
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
435
encrypt.cipher-mode=<str> - Name of encryption cipher mode
436
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
437
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
438
cluster_size=<size> - qcow2 cluster size
439
compat=<str> - Compatibility level (0.10 or 1.1)
440
data_file=<str> - File name of an external data file
441
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
442
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
443
encrypt.cipher-mode=<str> - Name of encryption cipher mode
444
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
445
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
446
cluster_size=<size> - qcow2 cluster size
447
compat=<str> - Compatibility level (0.10 or 1.1)
448
data_file=<str> - File name of an external data file
449
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
450
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
451
encrypt.cipher-mode=<str> - Name of encryption cipher mode
452
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
453
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
454
cluster_size=<size> - qcow2 cluster size
455
compat=<str> - Compatibility level (0.10 or 1.1)
456
data_file=<str> - File name of an external data file
457
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
458
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
459
encrypt.cipher-mode=<str> - Name of encryption cipher mode
460
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
461
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
462
cluster_size=<size> - qcow2 cluster size
463
compat=<str> - Compatibility level (0.10 or 1.1)
464
data_file=<str> - File name of an external data file
465
+ data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
466
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
467
encrypt.cipher-mode=<str> - Name of encryption cipher mode
468
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
469
--
245
--
470
2.20.1
246
2.20.1
471
247
472
248
diff view generated by jsdifflib
1
Rather than requiring that the external data file node is passed
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
explicitly when creating the qcow2 node, store the filename in the
3
designated header extension during .bdrv_create and read it from there
4
as a default during .bdrv_open.
5
2
3
We are going to remove bs->job pointer. Drop it's usage in
4
blk_iostatus_reset.
5
6
blk_iostatus_reset() has only two callers:
7
8
1. blk_attach_dev(). This doesn't have anything to do with jobs and
9
attaching a new guest device won't solve any problem the job
10
encountered, so no reason to reset the iostatus for the job.
11
12
2. qmp_cont(). This resets the iostatus for everything. We can just
13
call block_job_iostatus_reset() for all block jobs instead of going
14
through BlockBackend.
15
16
Suggested-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
19
---
8
qapi/block-core.json | 8 +++-
20
block/block-backend.c | 4 ----
9
block/qcow2.h | 1 +
21
monitor/qmp-cmds.c | 5 +++++
10
block/qcow2.c | 94 +++++++++++++++++++++++++++++++++++++-
22
2 files changed, 5 insertions(+), 4 deletions(-)
11
tests/qemu-iotests/082.out | 27 +++++++++++
12
4 files changed, 128 insertions(+), 2 deletions(-)
13
23
14
diff --git a/qapi/block-core.json b/qapi/block-core.json
24
diff --git a/block/block-backend.c b/block/block-backend.c
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/qapi/block-core.json
26
--- a/block/block-backend.c
17
+++ b/qapi/block-core.json
27
+++ b/block/block-backend.c
18
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ void blk_iostatus_disable(BlockBackend *blk)
19
#
29
void blk_iostatus_reset(BlockBackend *blk)
20
# @compat: compatibility level
30
{
21
#
31
if (blk_iostatus_is_enabled(blk)) {
22
+# @data-file: the filename of the external data file that is stored in the
32
- BlockDriverState *bs = blk_bs(blk);
23
+# image and used as a default for opening the image (since: 4.0)
33
blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
24
+#
34
- if (bs && bs->job) {
25
# @lazy-refcounts: on or off; only valid for compat >= 1.1
35
- block_job_iostatus_reset(bs->job);
26
#
36
- }
27
# @corrupt: true if the image has been marked corrupt; only valid for
37
}
28
@@ -XXX,XX +XXX,XX @@
38
}
29
{ 'struct': 'ImageInfoSpecificQCow2',
39
30
'data': {
40
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
31
'compat': 'str',
32
+ '*data-file': 'str',
33
'*lazy-refcounts': 'bool',
34
'*corrupt': 'bool',
35
'refcount-bits': 'int',
36
@@ -XXX,XX +XXX,XX @@
37
#
38
# @data-file: reference to or definition of the external data file.
39
# This may only be specified for images that require an
40
-# external data file. (since 4.0)
41
+# external data file. If it is not specified for such
42
+# an image, the data file name is loaded from the image
43
+# file. (since 4.0)
44
#
45
# Since: 2.9
46
##
47
diff --git a/block/qcow2.h b/block/qcow2.h
48
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
49
--- a/block/qcow2.h
42
--- a/monitor/qmp-cmds.c
50
+++ b/block/qcow2.h
43
+++ b/monitor/qmp-cmds.c
51
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State {
44
@@ -XXX,XX +XXX,XX @@ void qmp_x_exit_preconfig(Error **errp)
52
* override) */
45
void qmp_cont(Error **errp)
53
char *image_backing_file;
46
{
54
char *image_backing_format;
47
BlockBackend *blk;
55
+ char *image_data_file;
48
+ BlockJob *job;
56
49
Error *local_err = NULL;
57
CoQueue compress_wait_queue;
50
58
int nb_compress_threads;
51
/* if there is a dump in background, we should wait until the dump
59
diff --git a/block/qcow2.c b/block/qcow2.c
52
@@ -XXX,XX +XXX,XX @@ void qmp_cont(Error **errp)
60
index XXXXXXX..XXXXXXX 100644
53
blk_iostatus_reset(blk);
61
--- a/block/qcow2.c
62
+++ b/block/qcow2.c
63
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
64
#endif
65
break;
66
67
+ case QCOW2_EXT_MAGIC_DATA_FILE:
68
+ {
69
+ s->image_data_file = g_malloc0(ext.len + 1);
70
+ ret = bdrv_pread(bs->file, offset, s->image_data_file, ext.len);
71
+ if (ret < 0) {
72
+ error_setg_errno(errp, -ret,
73
+ "ERROR: Could not read data file name");
74
+ return ret;
75
+ }
76
+#ifdef DEBUG_EXT
77
+ printf("Qcow2: Got external data file %s\n", s->image_data_file);
78
+#endif
79
+ break;
80
+ }
81
+
82
default:
83
/* unknown magic - save it in case we need to rewrite the header */
84
/* If you add a new feature, make sure to also update the fast
85
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
86
}
54
}
87
55
88
if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
56
+ for (job = block_job_next(NULL); job; job = block_job_next(job)) {
89
+ if (!s->data_file && s->image_data_file) {
57
+ block_job_iostatus_reset(job);
90
+ s->data_file = bdrv_open_child(s->image_data_file, options,
91
+ "data-file", bs, &child_file,
92
+ false, errp);
93
+ if (!s->data_file) {
94
+ ret = -EINVAL;
95
+ goto fail;
96
+ }
97
+ }
98
if (!s->data_file) {
99
error_setg(errp, "'data-file' is required for this image");
100
ret = -EINVAL;
101
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
102
return ret;
103
104
fail:
105
+ g_free(s->image_data_file);
106
if (has_data_file(bs)) {
107
bdrv_unref_child(bs, s->data_file);
108
}
109
@@ -XXX,XX +XXX,XX @@ static void qcow2_close(BlockDriverState *bs)
110
g_free(s->unknown_header_fields);
111
cleanup_unknown_header_ext(bs);
112
113
+ g_free(s->image_data_file);
114
g_free(s->image_backing_file);
115
g_free(s->image_backing_format);
116
117
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
118
buflen -= ret;
119
}
120
121
+ /* External data file header extension */
122
+ if (has_data_file(bs) && s->image_data_file) {
123
+ ret = header_ext_add(buf, QCOW2_EXT_MAGIC_DATA_FILE,
124
+ s->image_data_file, strlen(s->image_data_file),
125
+ buflen);
126
+ if (ret < 0) {
127
+ goto fail;
128
+ }
129
+
130
+ buf += ret;
131
+ buflen -= ret;
132
+ }
58
+ }
133
+
59
+
134
/* Full disk encryption header pointer extension */
60
/* Continuing after completed migration. Images have been inactivated to
135
if (s->crypto_header.offset != 0) {
61
* allow the destination to take control. Need to get control back now.
136
s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset);
62
*
137
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
138
abort();
139
}
140
141
+ /* Set the external data file if necessary */
142
+ if (data_bs) {
143
+ BDRVQcow2State *s = blk_bs(blk)->opaque;
144
+ s->image_data_file = g_strdup(data_bs->filename);
145
+ }
146
+
147
/* Create a full header (including things like feature table) */
148
ret = qcow2_update_header(blk_bs(blk));
149
if (ret < 0) {
150
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_create_opts(const char *filename, QemuOpts *opt
151
QDict *qdict;
152
Visitor *v;
153
BlockDriverState *bs = NULL;
154
+ BlockDriverState *data_bs = NULL;
155
Error *local_err = NULL;
156
const char *val;
157
int ret;
158
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_create_opts(const char *filename, QemuOpts *opt
159
goto finish;
160
}
161
162
+ /* Create and open an external data file (protocol layer) */
163
+ val = qdict_get_try_str(qdict, BLOCK_OPT_DATA_FILE);
164
+ if (val) {
165
+ ret = bdrv_create_file(val, opts, errp);
166
+ if (ret < 0) {
167
+ goto finish;
168
+ }
169
+
170
+ data_bs = bdrv_open(val, NULL, NULL,
171
+ BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
172
+ errp);
173
+ if (data_bs == NULL) {
174
+ ret = -EIO;
175
+ goto finish;
176
+ }
177
+
178
+ qdict_del(qdict, BLOCK_OPT_DATA_FILE);
179
+ qdict_put_str(qdict, "data-file", data_bs->node_name);
180
+ }
181
+
182
/* Set 'driver' and 'node' options */
183
qdict_put_str(qdict, "driver", "qcow2");
184
qdict_put_str(qdict, "file", bs->node_name);
185
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_create_opts(const char *filename, QemuOpts *opt
186
finish:
187
qobject_unref(qdict);
188
bdrv_unref(bs);
189
+ bdrv_unref(data_bs);
190
qapi_free_BlockdevCreateOptions(create_options);
191
return ret;
192
}
193
@@ -XXX,XX +XXX,XX @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs,
194
.refcount_bits = s->refcount_bits,
195
.has_bitmaps = !!bitmaps,
196
.bitmaps = bitmaps,
197
+ .has_data_file = !!s->image_data_file,
198
+ .data_file = g_strdup(s->image_data_file),
199
};
200
} else {
201
/* if this assertion fails, this probably means a new version was
202
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
203
BDRVQcow2State *s = bs->opaque;
204
int old_version = s->qcow_version, new_version = old_version;
205
uint64_t new_size = 0;
206
- const char *backing_file = NULL, *backing_format = NULL;
207
+ const char *backing_file = NULL, *backing_format = NULL, *data_file = NULL;
208
bool lazy_refcounts = s->use_lazy_refcounts;
209
const char *compat = NULL;
210
uint64_t cluster_size = s->cluster_size;
211
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
212
"may not exceed 64 bits");
213
return -EINVAL;
214
}
215
+ } else if (!strcmp(desc->name, BLOCK_OPT_DATA_FILE)) {
216
+ data_file = qemu_opt_get(opts, BLOCK_OPT_DATA_FILE);
217
+ if (data_file && !has_data_file(bs)) {
218
+ error_setg(errp, "data-file can only be set for images that "
219
+ "use an external data file");
220
+ return -EINVAL;
221
+ }
222
} else {
223
/* if this point is reached, this probably means a new option was
224
* added without having it covered here */
225
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
226
}
227
}
228
229
+ if (data_file) {
230
+ g_free(s->image_data_file);
231
+ s->image_data_file = *data_file ? g_strdup(data_file) : NULL;
232
+ }
233
+
234
+ ret = qcow2_update_header(bs);
235
+ if (ret < 0) {
236
+ error_setg_errno(errp, -ret, "Failed to update the image header");
237
+ return ret;
238
+ }
239
+
240
if (backing_file || backing_format) {
241
ret = qcow2_change_backing_file(bs,
242
backing_file ?: s->image_backing_file,
243
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = {
244
.type = QEMU_OPT_STRING,
245
.help = "Image format of the base image"
246
},
247
+ {
248
+ .name = BLOCK_OPT_DATA_FILE,
249
+ .type = QEMU_OPT_STRING,
250
+ .help = "File name of an external data file"
251
+ },
252
{
253
.name = BLOCK_OPT_ENCRYPT,
254
.type = QEMU_OPT_BOOL,
255
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
256
index XXXXXXX..XXXXXXX 100644
257
--- a/tests/qemu-iotests/082.out
258
+++ b/tests/qemu-iotests/082.out
259
@@ -XXX,XX +XXX,XX @@ Supported options:
260
backing_fmt=<str> - Image format of the base image
261
cluster_size=<size> - qcow2 cluster size
262
compat=<str> - Compatibility level (0.10 or 1.1)
263
+ data_file=<str> - File name of an external data file
264
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
265
encrypt.cipher-mode=<str> - Name of encryption cipher mode
266
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
267
@@ -XXX,XX +XXX,XX @@ Supported options:
268
backing_fmt=<str> - Image format of the base image
269
cluster_size=<size> - qcow2 cluster size
270
compat=<str> - Compatibility level (0.10 or 1.1)
271
+ data_file=<str> - File name of an external data file
272
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
273
encrypt.cipher-mode=<str> - Name of encryption cipher mode
274
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
275
@@ -XXX,XX +XXX,XX @@ Supported options:
276
backing_fmt=<str> - Image format of the base image
277
cluster_size=<size> - qcow2 cluster size
278
compat=<str> - Compatibility level (0.10 or 1.1)
279
+ data_file=<str> - File name of an external data file
280
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
281
encrypt.cipher-mode=<str> - Name of encryption cipher mode
282
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
283
@@ -XXX,XX +XXX,XX @@ Supported options:
284
backing_fmt=<str> - Image format of the base image
285
cluster_size=<size> - qcow2 cluster size
286
compat=<str> - Compatibility level (0.10 or 1.1)
287
+ data_file=<str> - File name of an external data file
288
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
289
encrypt.cipher-mode=<str> - Name of encryption cipher mode
290
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
291
@@ -XXX,XX +XXX,XX @@ Supported options:
292
backing_fmt=<str> - Image format of the base image
293
cluster_size=<size> - qcow2 cluster size
294
compat=<str> - Compatibility level (0.10 or 1.1)
295
+ data_file=<str> - File name of an external data file
296
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
297
encrypt.cipher-mode=<str> - Name of encryption cipher mode
298
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
299
@@ -XXX,XX +XXX,XX @@ Supported options:
300
backing_fmt=<str> - Image format of the base image
301
cluster_size=<size> - qcow2 cluster size
302
compat=<str> - Compatibility level (0.10 or 1.1)
303
+ data_file=<str> - File name of an external data file
304
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
305
encrypt.cipher-mode=<str> - Name of encryption cipher mode
306
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
307
@@ -XXX,XX +XXX,XX @@ Supported options:
308
backing_fmt=<str> - Image format of the base image
309
cluster_size=<size> - qcow2 cluster size
310
compat=<str> - Compatibility level (0.10 or 1.1)
311
+ data_file=<str> - File name of an external data file
312
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
313
encrypt.cipher-mode=<str> - Name of encryption cipher mode
314
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
315
@@ -XXX,XX +XXX,XX @@ Supported options:
316
backing_fmt=<str> - Image format of the base image
317
cluster_size=<size> - qcow2 cluster size
318
compat=<str> - Compatibility level (0.10 or 1.1)
319
+ data_file=<str> - File name of an external data file
320
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
321
encrypt.cipher-mode=<str> - Name of encryption cipher mode
322
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
323
@@ -XXX,XX +XXX,XX @@ Supported options:
324
backing_fmt=<str> - Image format of the base image
325
cluster_size=<size> - qcow2 cluster size
326
compat=<str> - Compatibility level (0.10 or 1.1)
327
+ data_file=<str> - File name of an external data file
328
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
329
encrypt.cipher-mode=<str> - Name of encryption cipher mode
330
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
331
@@ -XXX,XX +XXX,XX @@ Supported options:
332
backing_fmt=<str> - Image format of the base image
333
cluster_size=<size> - qcow2 cluster size
334
compat=<str> - Compatibility level (0.10 or 1.1)
335
+ data_file=<str> - File name of an external data file
336
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
337
encrypt.cipher-mode=<str> - Name of encryption cipher mode
338
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
339
@@ -XXX,XX +XXX,XX @@ Supported options:
340
backing_fmt=<str> - Image format of the base image
341
cluster_size=<size> - qcow2 cluster size
342
compat=<str> - Compatibility level (0.10 or 1.1)
343
+ data_file=<str> - File name of an external data file
344
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
345
encrypt.cipher-mode=<str> - Name of encryption cipher mode
346
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
347
@@ -XXX,XX +XXX,XX @@ Supported options:
348
backing_fmt=<str> - Image format of the base image
349
cluster_size=<size> - qcow2 cluster size
350
compat=<str> - Compatibility level (0.10 or 1.1)
351
+ data_file=<str> - File name of an external data file
352
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
353
encrypt.cipher-mode=<str> - Name of encryption cipher mode
354
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
355
@@ -XXX,XX +XXX,XX @@ Supported options:
356
backing_fmt=<str> - Image format of the base image
357
cluster_size=<size> - qcow2 cluster size
358
compat=<str> - Compatibility level (0.10 or 1.1)
359
+ data_file=<str> - File name of an external data file
360
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
361
encrypt.cipher-mode=<str> - Name of encryption cipher mode
362
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
363
@@ -XXX,XX +XXX,XX @@ Supported options:
364
backing_fmt=<str> - Image format of the base image
365
cluster_size=<size> - qcow2 cluster size
366
compat=<str> - Compatibility level (0.10 or 1.1)
367
+ data_file=<str> - File name of an external data file
368
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
369
encrypt.cipher-mode=<str> - Name of encryption cipher mode
370
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
371
@@ -XXX,XX +XXX,XX @@ Supported options:
372
backing_fmt=<str> - Image format of the base image
373
cluster_size=<size> - qcow2 cluster size
374
compat=<str> - Compatibility level (0.10 or 1.1)
375
+ data_file=<str> - File name of an external data file
376
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
377
encrypt.cipher-mode=<str> - Name of encryption cipher mode
378
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
379
@@ -XXX,XX +XXX,XX @@ Supported options:
380
backing_fmt=<str> - Image format of the base image
381
cluster_size=<size> - qcow2 cluster size
382
compat=<str> - Compatibility level (0.10 or 1.1)
383
+ data_file=<str> - File name of an external data file
384
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
385
encrypt.cipher-mode=<str> - Name of encryption cipher mode
386
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
387
@@ -XXX,XX +XXX,XX @@ Supported options:
388
backing_fmt=<str> - Image format of the base image
389
cluster_size=<size> - qcow2 cluster size
390
compat=<str> - Compatibility level (0.10 or 1.1)
391
+ data_file=<str> - File name of an external data file
392
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
393
encrypt.cipher-mode=<str> - Name of encryption cipher mode
394
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
395
@@ -XXX,XX +XXX,XX @@ Supported options:
396
backing_fmt=<str> - Image format of the base image
397
cluster_size=<size> - qcow2 cluster size
398
compat=<str> - Compatibility level (0.10 or 1.1)
399
+ data_file=<str> - File name of an external data file
400
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
401
encrypt.cipher-mode=<str> - Name of encryption cipher mode
402
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
403
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
404
backing_fmt=<str> - Image format of the base image
405
cluster_size=<size> - qcow2 cluster size
406
compat=<str> - Compatibility level (0.10 or 1.1)
407
+ data_file=<str> - File name of an external data file
408
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
409
encrypt.cipher-mode=<str> - Name of encryption cipher mode
410
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
411
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
412
backing_fmt=<str> - Image format of the base image
413
cluster_size=<size> - qcow2 cluster size
414
compat=<str> - Compatibility level (0.10 or 1.1)
415
+ data_file=<str> - File name of an external data file
416
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
417
encrypt.cipher-mode=<str> - Name of encryption cipher mode
418
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
419
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
420
backing_fmt=<str> - Image format of the base image
421
cluster_size=<size> - qcow2 cluster size
422
compat=<str> - Compatibility level (0.10 or 1.1)
423
+ data_file=<str> - File name of an external data file
424
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
425
encrypt.cipher-mode=<str> - Name of encryption cipher mode
426
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
427
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
428
backing_fmt=<str> - Image format of the base image
429
cluster_size=<size> - qcow2 cluster size
430
compat=<str> - Compatibility level (0.10 or 1.1)
431
+ data_file=<str> - File name of an external data file
432
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
433
encrypt.cipher-mode=<str> - Name of encryption cipher mode
434
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
435
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
436
backing_fmt=<str> - Image format of the base image
437
cluster_size=<size> - qcow2 cluster size
438
compat=<str> - Compatibility level (0.10 or 1.1)
439
+ data_file=<str> - File name of an external data file
440
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
441
encrypt.cipher-mode=<str> - Name of encryption cipher mode
442
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
443
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
444
backing_fmt=<str> - Image format of the base image
445
cluster_size=<size> - qcow2 cluster size
446
compat=<str> - Compatibility level (0.10 or 1.1)
447
+ data_file=<str> - File name of an external data file
448
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
449
encrypt.cipher-mode=<str> - Name of encryption cipher mode
450
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
451
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
452
backing_fmt=<str> - Image format of the base image
453
cluster_size=<size> - qcow2 cluster size
454
compat=<str> - Compatibility level (0.10 or 1.1)
455
+ data_file=<str> - File name of an external data file
456
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
457
encrypt.cipher-mode=<str> - Name of encryption cipher mode
458
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
459
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
460
backing_fmt=<str> - Image format of the base image
461
cluster_size=<size> - qcow2 cluster size
462
compat=<str> - Compatibility level (0.10 or 1.1)
463
+ data_file=<str> - File name of an external data file
464
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
465
encrypt.cipher-mode=<str> - Name of encryption cipher mode
466
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
467
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
468
backing_fmt=<str> - Image format of the base image
469
cluster_size=<size> - qcow2 cluster size
470
compat=<str> - Compatibility level (0.10 or 1.1)
471
+ data_file=<str> - File name of an external data file
472
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
473
encrypt.cipher-mode=<str> - Name of encryption cipher mode
474
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
475
--
63
--
476
2.20.1
64
2.20.1
477
65
478
66
diff view generated by jsdifflib
1
qcow2_alloc_compressed_cluster_offset() used to return the cluster
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
offset for success and 0 for error. This doesn't only conflict with 0 as
3
a valid host offset, but also loses the error code.
4
2
5
Similar to the change made to qcow2_alloc_cluster_offset() for
3
We are going to remove bs->job pointer. Drop it's usage in
6
uncompressed clusters in commit 148da7ea9d6, make the function return
4
blockdev_mark_auto_del: instead of looking at bs->job let's check all
7
0/-errno and return the allocated cluster offset in a by-reference
5
jobs for references to bs.
8
parameter.
9
6
7
Suggested-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
10
---
12
block/qcow2.h | 7 ++++---
11
include/block/blockjob.h | 9 +++++++++
13
block/qcow2-cluster.c | 28 +++++++++++++---------------
12
blockdev.c | 17 ++++++++---------
14
block/qcow2.c | 19 ++++++++-----------
13
blockjob.c | 14 ++++++++++++++
15
tests/qemu-iotests/220.out | 2 +-
14
3 files changed, 31 insertions(+), 9 deletions(-)
16
4 files changed, 26 insertions(+), 30 deletions(-)
17
15
18
diff --git a/block/qcow2.h b/block/qcow2.h
16
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2.h
18
--- a/include/block/blockjob.h
21
+++ b/block/qcow2.h
19
+++ b/include/block/blockjob.h
22
@@ -XXX,XX +XXX,XX @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
20
@@ -XXX,XX +XXX,XX @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
23
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
21
*/
24
unsigned int *bytes, uint64_t *host_offset,
22
void block_job_remove_all_bdrv(BlockJob *job);
25
QCowL2Meta **m);
23
26
-uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
24
+/**
27
- uint64_t offset,
25
+ * block_job_has_bdrv:
28
- int compressed_size);
26
+ * @job: The block job
29
+int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
27
+ *
30
+ uint64_t offset,
28
+ * Searches for @bs in the list of nodes that are involved in the
31
+ int compressed_size,
29
+ * job.
32
+ uint64_t *host_offset);
30
+ */
33
31
+bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs);
34
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
32
+
35
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
33
/**
36
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
34
* block_job_set_speed:
35
* @job: The job to set the speed for.
36
diff --git a/blockdev.c b/blockdev.c
37
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
38
--- a/block/qcow2-cluster.c
38
--- a/blockdev.c
39
+++ b/block/qcow2-cluster.c
39
+++ b/blockdev.c
40
@@ -XXX,XX +XXX,XX @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
40
@@ -XXX,XX +XXX,XX @@ void override_max_devs(BlockInterfaceType type, int max_devs)
41
/*
41
void blockdev_mark_auto_del(BlockBackend *blk)
42
* alloc_compressed_cluster_offset
43
*
44
- * For a given offset of the disk image, return cluster offset in
45
- * qcow2 file.
46
- *
47
- * If the offset is not found, allocate a new compressed cluster.
48
- *
49
- * Return the cluster offset if successful,
50
- * Return 0, otherwise.
51
+ * For a given offset on the virtual disk, allocate a new compressed cluster
52
+ * and put the host offset of the cluster into *host_offset. If a cluster is
53
+ * already allocated at the offset, return an error.
54
*
55
+ * Return 0 on success and -errno in error cases
56
*/
57
-
58
-uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
59
- uint64_t offset,
60
- int compressed_size)
61
+int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
62
+ uint64_t offset,
63
+ int compressed_size,
64
+ uint64_t *host_offset)
65
{
42
{
66
BDRVQcow2State *s = bs->opaque;
43
DriveInfo *dinfo = blk_legacy_dinfo(blk);
67
int l2_index, ret;
44
- BlockDriverState *bs = blk_bs(blk);
68
@@ -XXX,XX +XXX,XX @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
45
- AioContext *aio_context;
69
46
+ BlockJob *job;
70
ret = get_cluster_table(bs, offset, &l2_slice, &l2_index);
47
71
if (ret < 0) {
48
if (!dinfo) {
72
- return 0;
49
return;
73
+ return ret;
74
}
50
}
75
51
76
/* Compression can't overwrite anything. Fail if the cluster was already
52
- if (bs) {
77
@@ -XXX,XX +XXX,XX @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
53
- aio_context = bdrv_get_aio_context(bs);
78
cluster_offset = be64_to_cpu(l2_slice[l2_index]);
54
- aio_context_acquire(aio_context);
79
if (cluster_offset & L2E_OFFSET_MASK) {
55
+ for (job = block_job_next(NULL); job; job = block_job_next(job)) {
80
qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
56
+ if (block_job_has_bdrv(job, blk_bs(blk))) {
81
- return 0;
57
+ AioContext *aio_context = job->job.aio_context;
82
+ return -EIO;
58
+ aio_context_acquire(aio_context);
59
60
- if (bs->job) {
61
- job_cancel(&bs->job->job, false);
62
- }
63
+ job_cancel(&job->job, false);
64
65
- aio_context_release(aio_context);
66
+ aio_context_release(aio_context);
67
+ }
83
}
68
}
84
69
85
cluster_offset = qcow2_alloc_bytes(bs, compressed_size);
70
dinfo->auto_del = 1;
86
if (cluster_offset < 0) {
71
diff --git a/blockjob.c b/blockjob.c
87
qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
72
index XXXXXXX..XXXXXXX 100644
88
- return 0;
73
--- a/blockjob.c
89
+ return cluster_offset;
74
+++ b/blockjob.c
90
}
75
@@ -XXX,XX +XXX,XX @@ void block_job_remove_all_bdrv(BlockJob *job)
91
76
job->nodes = NULL;
92
nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
93
@@ -XXX,XX +XXX,XX @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
94
l2_slice[l2_index] = cpu_to_be64(cluster_offset);
95
qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
96
97
- return cluster_offset;
98
+ *host_offset = cluster_offset & s->cluster_offset_mask;
99
+ return 0;
100
}
77
}
101
78
102
static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
79
+bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
103
diff --git a/block/qcow2.c b/block/qcow2.c
80
+{
104
index XXXXXXX..XXXXXXX 100644
81
+ GSList *el;
105
--- a/block/qcow2.c
82
+
106
+++ b/block/qcow2.c
83
+ for (el = job->nodes; el; el = el->next) {
107
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
84
+ BdrvChild *c = el->data;
108
int ret;
85
+ if (c->bs == bs) {
109
size_t out_len;
86
+ return true;
110
uint8_t *buf, *out_buf;
87
+ }
111
- int64_t cluster_offset;
88
+ }
112
+ uint64_t cluster_offset;
89
+
113
90
+ return false;
114
if (bytes == 0) {
91
+}
115
/* align end of file to a sector boundary to ease reading with
92
+
116
sector based I/Os */
93
int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
117
- cluster_offset = bdrv_getlength(bs->file->bs);
94
uint64_t perm, uint64_t shared_perm, Error **errp)
118
- if (cluster_offset < 0) {
95
{
119
- return cluster_offset;
120
+ int64_t len = bdrv_getlength(bs->file->bs);
121
+ if (len < 0) {
122
+ return len;
123
}
124
- return bdrv_co_truncate(bs->file, cluster_offset, PREALLOC_MODE_OFF,
125
- NULL);
126
+ return bdrv_co_truncate(bs->file, len, PREALLOC_MODE_OFF, NULL);
127
}
128
129
if (offset_into_cluster(s, offset)) {
130
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
131
}
132
133
qemu_co_mutex_lock(&s->lock);
134
- cluster_offset =
135
- qcow2_alloc_compressed_cluster_offset(bs, offset, out_len);
136
- if (!cluster_offset) {
137
+ ret = qcow2_alloc_compressed_cluster_offset(bs, offset, out_len,
138
+ &cluster_offset);
139
+ if (ret < 0) {
140
qemu_co_mutex_unlock(&s->lock);
141
- ret = -EIO;
142
goto fail;
143
}
144
- cluster_offset &= s->cluster_offset_mask;
145
146
ret = qcow2_pre_write_overlap_check(bs, 0, cluster_offset, out_len);
147
qemu_co_mutex_unlock(&s->lock);
148
diff --git a/tests/qemu-iotests/220.out b/tests/qemu-iotests/220.out
149
index XXXXXXX..XXXXXXX 100644
150
--- a/tests/qemu-iotests/220.out
151
+++ b/tests/qemu-iotests/220.out
152
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 37748736
153
No errors were found on the image.
154
image size 39845888
155
== Trying to write compressed cluster ==
156
-write failed: Input/output error
157
+write failed: File too large
158
image size 562949957615616
159
== Writing normal cluster ==
160
wrote 2097152/2097152 bytes at offset 0
161
--
96
--
162
2.20.1
97
2.20.1
163
98
164
99
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
bdrv_iterate_format (which is currently only used for printing out the
3
Drop remaining users of bs->job:
4
formats supported by the block layer) doesn't take format whitelisting
4
1. assertions actually duplicated by assert(!bs->refcnt)
5
into account.
5
2. trace-point seems not enough reason to change stream_start to return
6
BlockJob pointer
7
3. Restricting creation of two jobs based on same bs is bad idea, as
8
3.1 Some jobs creates filters to be their main node, so, this check
9
don't actually prevent creating second job on same real node (which
10
will create another filter node) (but I hope it is restricted by
11
other mechanisms)
12
3.2 Even without bs->job we have two systems of permissions:
13
op-blockers and BLK_PERM
14
3.3 We may want to run several jobs on one node one day
6
15
7
This creates a problem for tests: they enumerate supported formats to
16
And finally, drop bs->job pointer itself. Hurrah!
8
decide which tests to enable, but then discover that QEMU doesn't let
9
them actually use some of those formats.
10
17
11
To avoid that, exclude formats that are not whitelisted from
18
Suggested-by: Kevin Wolf <kwolf@redhat.com>
12
enumeration, if whitelisting is in use. Since we have separate
19
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
whitelists for r/w and r/o, take this a parameter to
14
bdrv_iterate_format, and print two lists of supported formats (r/w and
15
r/o) in main qemu.
16
17
Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
18
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
---
21
include/block/block.h | 2 +-
22
include/block/block_int.h | 3 ---
22
block.c | 23 +++++++++++++++++++----
23
block.c | 2 --
23
blockdev.c | 4 +++-
24
blockdev.c | 2 +-
24
qemu-img.c | 2 +-
25
blockjob.c | 8 --------
25
4 files changed, 24 insertions(+), 7 deletions(-)
26
tests/test-blockjob.c | 5 +++--
27
block/trace-events | 2 +-
28
6 files changed, 5 insertions(+), 17 deletions(-)
26
29
27
diff --git a/include/block/block.h b/include/block/block.h
30
diff --git a/include/block/block_int.h b/include/block/block_int.h
28
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
29
--- a/include/block/block.h
32
--- a/include/block/block_int.h
30
+++ b/include/block/block.h
33
+++ b/include/block/block_int.h
31
@@ -XXX,XX +XXX,XX @@ void bdrv_next_cleanup(BdrvNextIterator *it);
34
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
32
BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
35
/* operation blockers */
33
bool bdrv_is_encrypted(BlockDriverState *bs);
36
QLIST_HEAD(, BdrvOpBlocker) op_blockers[BLOCK_OP_TYPE_MAX];
34
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
37
35
- void *opaque);
38
- /* long-running background operation */
36
+ void *opaque, bool read_only);
39
- BlockJob *job;
37
const char *bdrv_get_node_name(const BlockDriverState *bs);
40
-
38
const char *bdrv_get_device_name(const BlockDriverState *bs);
41
/* The node that this node inherited default options from (and a reopen on
39
const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
42
* which can affect this node by changing these defaults). This is always a
43
* parent node of this node. */
40
diff --git a/block.c b/block.c
44
diff --git a/block.c b/block.c
41
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
42
--- a/block.c
46
--- a/block.c
43
+++ b/block.c
47
+++ b/block.c
44
@@ -XXX,XX +XXX,XX @@ BlockDriver *bdrv_find_format(const char *format_name)
48
@@ -XXX,XX +XXX,XX @@ static void bdrv_close(BlockDriverState *bs)
45
return bdrv_do_find_format(format_name);
49
BdrvAioNotifier *ban, *ban_next;
46
}
50
BdrvChild *child, *next;
47
51
48
-int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
52
- assert(!bs->job);
49
+static int bdrv_format_is_whitelisted(const char *format_name, bool read_only)
53
assert(!bs->refcnt);
54
55
bdrv_drained_begin(bs); /* complete I/O */
56
@@ -XXX,XX +XXX,XX @@ out:
57
58
static void bdrv_delete(BlockDriverState *bs)
50
{
59
{
51
static const char *whitelist_rw[] = {
60
- assert(!bs->job);
52
CONFIG_BDRV_RW_WHITELIST
61
assert(bdrv_op_blocker_is_empty(bs));
53
@@ -XXX,XX +XXX,XX @@ int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
62
assert(!bs->refcnt);
54
}
63
55
56
for (p = whitelist_rw; *p; p++) {
57
- if (!strcmp(drv->format_name, *p)) {
58
+ if (!strcmp(format_name, *p)) {
59
return 1;
60
}
61
}
62
if (read_only) {
63
for (p = whitelist_ro; *p; p++) {
64
- if (!strcmp(drv->format_name, *p)) {
65
+ if (!strcmp(format_name, *p)) {
66
return 1;
67
}
68
}
69
@@ -XXX,XX +XXX,XX @@ int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
70
return 0;
71
}
72
73
+int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
74
+{
75
+ return bdrv_format_is_whitelisted(drv->format_name, read_only);
76
+}
77
+
78
bool bdrv_uses_whitelist(void)
79
{
80
return use_bdrv_whitelist;
81
@@ -XXX,XX +XXX,XX @@ static int qsort_strcmp(const void *a, const void *b)
82
}
83
84
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
85
- void *opaque)
86
+ void *opaque, bool read_only)
87
{
88
BlockDriver *drv;
89
int count = 0;
90
@@ -XXX,XX +XXX,XX @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
91
if (drv->format_name) {
92
bool found = false;
93
int i = count;
94
+
95
+ if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, read_only)) {
96
+ continue;
97
+ }
98
+
99
while (formats && i && !found) {
100
found = !strcmp(formats[--i], drv->format_name);
101
}
102
@@ -XXX,XX +XXX,XX @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
103
bool found = false;
104
int j = count;
105
106
+ if (use_bdrv_whitelist &&
107
+ !bdrv_format_is_whitelisted(format_name, read_only)) {
108
+ continue;
109
+ }
110
+
111
while (formats && j && !found) {
112
found = !strcmp(formats[--j], format_name);
113
}
114
diff --git a/blockdev.c b/blockdev.c
64
diff --git a/blockdev.c b/blockdev.c
115
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
116
--- a/blockdev.c
66
--- a/blockdev.c
117
+++ b/blockdev.c
67
+++ b/blockdev.c
118
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
68
@@ -XXX,XX +XXX,XX @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
119
if ((buf = qemu_opt_get(opts, "format")) != NULL) {
69
goto out;
120
if (is_help_option(buf)) {
70
}
121
error_printf("Supported formats:");
71
122
- bdrv_iterate_format(bdrv_format_print, NULL);
72
- trace_qmp_block_stream(bs, bs->job);
123
+ bdrv_iterate_format(bdrv_format_print, NULL, false);
73
+ trace_qmp_block_stream(bs);
124
+ error_printf("\nSupported formats (read-only):");
74
125
+ bdrv_iterate_format(bdrv_format_print, NULL, true);
75
out:
126
error_printf("\n");
76
aio_context_release(aio_context);
127
goto early_err;
77
diff --git a/blockjob.c b/blockjob.c
128
}
129
diff --git a/qemu-img.c b/qemu-img.c
130
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
131
--- a/qemu-img.c
79
--- a/blockjob.c
132
+++ b/qemu-img.c
80
+++ b/blockjob.c
133
@@ -XXX,XX +XXX,XX @@ static void QEMU_NORETURN help(void)
81
@@ -XXX,XX +XXX,XX @@ BlockJob *block_job_get(const char *id)
134
" 'skip=N' skip N bs-sized blocks at the start of input\n";
82
void block_job_free(Job *job)
135
83
{
136
printf("%s\nSupported formats:", help_msg);
84
BlockJob *bjob = container_of(job, BlockJob, job);
137
- bdrv_iterate_format(format_print, NULL);
85
- BlockDriverState *bs = blk_bs(bjob->blk);
138
+ bdrv_iterate_format(format_print, NULL, false);
86
139
printf("\n\n" QEMU_HELP_BOTTOM "\n");
87
- bs->job = NULL;
140
exit(EXIT_SUCCESS);
88
block_job_remove_all_bdrv(bjob);
141
}
89
blk_unref(bjob->blk);
90
error_free(bjob->blocker);
91
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
92
BlockJob *job;
93
int ret;
94
95
- if (bs->job) {
96
- error_setg(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
97
- return NULL;
98
- }
99
-
100
if (job_id == NULL && !(flags & JOB_INTERNAL)) {
101
job_id = bdrv_get_device_name(bs);
102
}
103
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
104
error_setg(&job->blocker, "block device is in use by block job: %s",
105
job_type_str(&job->job));
106
block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
107
- bs->job = job;
108
109
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
110
111
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/tests/test-blockjob.c
114
+++ b/tests/test-blockjob.c
115
@@ -XXX,XX +XXX,XX @@ static void test_job_ids(void)
116
/* This one is valid */
117
job[0] = do_test_id(blk[0], "id0", true);
118
119
- /* We cannot have two jobs in the same BDS */
120
- do_test_id(blk[0], "id1", false);
121
+ /* We can have two jobs in the same BDS */
122
+ job[1] = do_test_id(blk[0], "id1", true);
123
+ job_early_fail(&job[1]->job);
124
125
/* Duplicate job IDs are not allowed */
126
job[1] = do_test_id(blk[1], "id0", false);
127
diff --git a/block/trace-events b/block/trace-events
128
index XXXXXXX..XXXXXXX 100644
129
--- a/block/trace-events
130
+++ b/block/trace-events
131
@@ -XXX,XX +XXX,XX @@ qmp_block_job_resume(void *job) "job %p"
132
qmp_block_job_complete(void *job) "job %p"
133
qmp_block_job_finalize(void *job) "job %p"
134
qmp_block_job_dismiss(void *job) "job %p"
135
-qmp_block_stream(void *bs, void *job) "bs %p job %p"
136
+qmp_block_stream(void *bs) "bs %p"
137
138
# file-posix.c
139
# file-win32.c
142
--
140
--
143
2.20.1
141
2.20.1
144
142
145
143
diff view generated by jsdifflib
1
Image creation already involves a bdrv_co_truncate() call, which allows
1
From: Max Reitz <mreitz@redhat.com>
2
to specify a preallocation mode. Just pass the right mode there and
3
remove the code that is made redundant by this.
4
2
3
raw_check_perm() + raw_set_perm() can change the flags associated with
4
the current FD. If so, we have to update BDRVRawState.open_flags
5
accordingly. Otherwise, we may keep reopening the FD even though the
6
current one already has the correct flags.
7
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
11
---
7
block/qcow2.c | 28 +---------------------------
12
block/file-posix.c | 4 ++++
8
1 file changed, 1 insertion(+), 27 deletions(-)
13
1 file changed, 4 insertions(+)
9
14
10
diff --git a/block/qcow2.c b/block/qcow2.c
15
diff --git a/block/file-posix.c b/block/file-posix.c
11
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
12
--- a/block/qcow2.c
17
--- a/block/file-posix.c
13
+++ b/block/qcow2.c
18
+++ b/block/file-posix.c
14
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
15
goto out;
20
uint64_t locked_shared_perm;
16
}
21
17
22
int perm_change_fd;
18
- if (qcow2_opts->preallocation == PREALLOC_MODE_FULL ||
23
+ int perm_change_flags;
19
- qcow2_opts->preallocation == PREALLOC_MODE_FALLOC)
24
BDRVReopenState *reopen_state;
20
- {
25
21
- int64_t prealloc_size =
26
#ifdef CONFIG_XFS
22
- qcow2_calc_prealloc_size(qcow2_opts->size, cluster_size,
27
@@ -XXX,XX +XXX,XX @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
23
- refcount_order);
28
assert(s->reopen_state->shared_perm == shared);
24
-
29
rs = s->reopen_state->opaque;
25
- ret = blk_truncate(blk, prealloc_size, qcow2_opts->preallocation, errp);
30
s->perm_change_fd = rs->fd;
26
- if (ret < 0) {
31
+ s->perm_change_flags = rs->open_flags;
27
- goto out;
32
} else {
28
- }
33
/* We may need a new fd if auto-read-only switches the mode */
29
- }
34
ret = raw_reconfigure_getfd(bs, bs->open_flags, &open_flags, perm,
30
-
35
@@ -XXX,XX +XXX,XX @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
31
/* Write the header */
36
return ret;
32
QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header));
37
} else if (ret != s->fd) {
33
header = g_malloc0(cluster_size);
38
s->perm_change_fd = ret;
34
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
39
+ s->perm_change_flags = open_flags;
35
}
36
37
/* Okay, now that we have a valid image, let's give it the right size */
38
- ret = blk_truncate(blk, qcow2_opts->size, PREALLOC_MODE_OFF, errp);
39
+ ret = blk_truncate(blk, qcow2_opts->size, qcow2_opts->preallocation, errp);
40
if (ret < 0) {
41
error_prepend(errp, "Could not resize image: ");
42
goto out;
43
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
44
}
40
}
45
}
41
}
46
42
47
- /* And if we're supposed to preallocate metadata, do that now */
43
@@ -XXX,XX +XXX,XX @@ static void raw_set_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared)
48
- if (qcow2_opts->preallocation != PREALLOC_MODE_OFF) {
44
if (s->perm_change_fd && s->fd != s->perm_change_fd) {
49
- BDRVQcow2State *s = blk_bs(blk)->opaque;
45
qemu_close(s->fd);
50
- qemu_co_mutex_lock(&s->lock);
46
s->fd = s->perm_change_fd;
51
- ret = preallocate_co(blk_bs(blk), 0, qcow2_opts->size);
47
+ s->open_flags = s->perm_change_flags;
52
- qemu_co_mutex_unlock(&s->lock);
48
}
53
-
49
s->perm_change_fd = 0;
54
- if (ret < 0) {
55
- error_setg_errno(errp, -ret, "Could not preallocate metadata");
56
- goto out;
57
- }
58
- }
59
-
60
blk_unref(blk);
61
blk = NULL;
62
50
63
--
51
--
64
2.20.1
52
2.20.1
65
53
66
54
diff view generated by jsdifflib
1
This adds a .bdrv_create option to use an external data file.
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
If a block node uses bdrv_child_try_set_perm() to change the permission
4
it takes on its child, the result may be very short-lived. If anything
5
makes the block layer recalculate the permissions internally, it will
6
invoke the node driver's .bdrv_child_perm() implementation. The
7
permission/shared permissions masks that returns will then override the
8
values previously passed to bdrv_child_try_set_perm().
9
10
If drivers want a child edge to have specific values for the
11
permissions/shared permissions mask, it must return them in
12
.bdrv_child_perm(). Consequentially, there is no need for them to pass
13
the same values to bdrv_child_try_set_perm() then: It is better to have
14
a function that invokes .bdrv_child_perm() and calls
15
bdrv_child_try_set_perm() with the result. This patch adds such a
16
function under the name of bdrv_child_refresh_perms().
17
18
Signed-off-by: Max Reitz <mreitz@redhat.com>
19
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
---
21
---
5
qapi/block-core.json | 4 ++++
22
include/block/block_int.h | 15 +++++++++++++++
6
include/block/block_int.h | 1 +
23
block.c | 12 ++++++++++++
7
block/qcow2.c | 26 ++++++++++++++++++++++++++
24
2 files changed, 27 insertions(+)
8
3 files changed, 31 insertions(+)
9
25
10
diff --git a/qapi/block-core.json b/qapi/block-core.json
11
index XXXXXXX..XXXXXXX 100644
12
--- a/qapi/block-core.json
13
+++ b/qapi/block-core.json
14
@@ -XXX,XX +XXX,XX @@
15
# Driver specific image creation options for qcow2.
16
#
17
# @file Node to create the image format on
18
+# @data-file Node to use as an external data file in which all guest
19
+# data is stored so that only metadata remains in the qcow2
20
+# file (since: 4.0)
21
# @size Size of the virtual disk in bytes
22
# @version Compatibility level (default: v3)
23
# @backing-file File name of the backing file if a backing file
24
@@ -XXX,XX +XXX,XX @@
25
##
26
{ 'struct': 'BlockdevCreateOptionsQcow2',
27
'data': { 'file': 'BlockdevRef',
28
+ '*data-file': 'BlockdevRef',
29
'size': 'size',
30
'*version': 'BlockdevQcow2Version',
31
'*backing-file': 'str',
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
26
diff --git a/include/block/block_int.h b/include/block/block_int.h
33
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block_int.h
28
--- a/include/block/block_int.h
35
+++ b/include/block/block_int.h
29
+++ b/include/block/block_int.h
36
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
37
#define BLOCK_OPT_NOCOW "nocow"
31
void *opaque, Error **errp);
38
#define BLOCK_OPT_OBJECT_SIZE "object_size"
32
void bdrv_root_unref_child(BdrvChild *child);
39
#define BLOCK_OPT_REFCOUNT_BITS "refcount_bits"
33
40
+#define BLOCK_OPT_DATA_FILE "data_file"
34
+/**
41
35
+ * Sets a BdrvChild's permissions. Avoid if the parent is a BDS; use
42
#define BLOCK_PROBE_BUF_SIZE 512
36
+ * bdrv_child_refresh_perms() instead and make the parent's
43
37
+ * .bdrv_child_perm() implementation return the correct values.
44
diff --git a/block/qcow2.c b/block/qcow2.c
38
+ */
39
int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
40
Error **errp);
41
42
+/**
43
+ * Calls bs->drv->bdrv_child_perm() and updates the child's permission
44
+ * masks with the result.
45
+ * Drivers should invoke this function whenever an event occurs that
46
+ * makes their .bdrv_child_perm() implementation return different
47
+ * values than before, but which will not result in the block layer
48
+ * automatically refreshing the permissions.
49
+ */
50
+int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
51
+
52
/* Default implementation for BlockDriver.bdrv_child_perm() that can be used by
53
* block filters: Forward CONSISTENT_READ, WRITE, WRITE_UNCHANGED and RESIZE to
54
* all children */
55
diff --git a/block.c b/block.c
45
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
46
--- a/block/qcow2.c
57
--- a/block.c
47
+++ b/block/qcow2.c
58
+++ b/block.c
48
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
59
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
49
*/
60
return 0;
50
BlockBackend *blk = NULL;
51
BlockDriverState *bs = NULL;
52
+ BlockDriverState *data_bs = NULL;
53
QCowHeader *header;
54
size_t cluster_size;
55
int version;
56
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
57
}
58
refcount_order = ctz32(qcow2_opts->refcount_bits);
59
60
+ if (qcow2_opts->data_file) {
61
+ if (version < 3) {
62
+ error_setg(errp, "External data files are only supported with "
63
+ "compatibility level 1.1 and above (use version=v3 or "
64
+ "greater)");
65
+ ret = -EINVAL;
66
+ goto out;
67
+ }
68
+ data_bs = bdrv_open_blockdev_ref(qcow2_opts->data_file, errp);
69
+ if (bs == NULL) {
70
+ ret = -EIO;
71
+ goto out;
72
+ }
73
+ }
74
75
/* Create BlockBackend to write to the image */
76
blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
77
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
78
header->compatible_features |=
79
cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS);
80
}
81
+ if (data_bs) {
82
+ header->incompatible_features |=
83
+ cpu_to_be64(QCOW2_INCOMPAT_DATA_FILE);
84
+ }
85
86
ret = blk_pwrite(blk, 0, header, cluster_size, 0);
87
g_free(header);
88
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
89
options = qdict_new();
90
qdict_put_str(options, "driver", "qcow2");
91
qdict_put_str(options, "file", bs->node_name);
92
+ if (data_bs) {
93
+ qdict_put_str(options, "data-file", data_bs->node_name);
94
+ }
95
blk = blk_new_open(NULL, NULL, options,
96
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH,
97
&local_err);
98
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
99
options = qdict_new();
100
qdict_put_str(options, "driver", "qcow2");
101
qdict_put_str(options, "file", bs->node_name);
102
+ if (data_bs) {
103
+ qdict_put_str(options, "data-file", data_bs->node_name);
104
+ }
105
blk = blk_new_open(NULL, NULL, options,
106
BDRV_O_RDWR | BDRV_O_NO_BACKING | BDRV_O_NO_IO,
107
&local_err);
108
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
109
out:
110
blk_unref(blk);
111
bdrv_unref(bs);
112
+ bdrv_unref(data_bs);
113
return ret;
114
}
61
}
115
62
63
+int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp)
64
+{
65
+ uint64_t parent_perms, parent_shared;
66
+ uint64_t perms, shared;
67
+
68
+ bdrv_get_cumulative_perm(bs, &parent_perms, &parent_shared);
69
+ bdrv_child_perm(bs, c->bs, c, c->role, NULL, parent_perms, parent_shared,
70
+ &perms, &shared);
71
+
72
+ return bdrv_child_try_set_perm(c, perms, shared, errp);
73
+}
74
+
75
void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
76
const BdrvChildRole *role,
77
BlockReopenQueue *reopen_queue,
116
--
78
--
117
2.20.1
79
2.20.1
118
80
119
81
diff view generated by jsdifflib
1
This changes the qcow2 implementation to direct all guest data I/O to
1
From: Max Reitz <mreitz@redhat.com>
2
s->data_file rather than bs->file, while metadata I/O still uses
3
bs->file. At the moment, this is still always the same, but soon we'll
4
add options to set s->data_file to an external data file.
5
2
3
We cannot use bdrv_child_try_set_perm() to give up all restrictions on
4
the child edge, and still have bdrv_mirror_top_child_perm() request
5
BLK_PERM_WRITE. Fix this by making bdrv_mirror_top_child_perm() return
6
0/BLK_PERM_ALL when we want to give up all permissions, and replacing
7
bdrv_child_try_set_perm() by bdrv_child_refresh_perms().
8
9
The bdrv_child_try_set_perm() before removing the node with
10
bdrv_replace_node() is then unnecessary. No permissions have changed
11
since the previous invocation of bdrv_child_try_set_perm().
12
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
16
---
8
block/qcow2.h | 2 +-
17
block/mirror.c | 32 +++++++++++++++++++++++---------
9
block/qcow2-bitmap.c | 7 +++---
18
1 file changed, 23 insertions(+), 9 deletions(-)
10
block/qcow2-cache.c | 6 ++---
11
block/qcow2-cluster.c | 46 +++++++++++++++++++++++++++++++------
12
block/qcow2-refcount.c | 39 +++++++++++++++++++++++--------
13
block/qcow2-snapshot.c | 7 +++---
14
block/qcow2.c | 52 +++++++++++++++++++++++++++++++++---------
15
7 files changed, 122 insertions(+), 37 deletions(-)
16
19
17
diff --git a/block/qcow2.h b/block/qcow2.h
20
diff --git a/block/mirror.c b/block/mirror.c
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.h
22
--- a/block/mirror.c
20
+++ b/block/qcow2.h
23
+++ b/block/mirror.c
21
@@ -XXX,XX +XXX,XX @@ void qcow2_process_discards(BlockDriverState *bs, int ret);
24
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorBlockJob {
22
int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
25
23
int64_t size);
26
typedef struct MirrorBDSOpaque {
24
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
27
MirrorBlockJob *job;
25
- int64_t size);
28
+ bool stop;
26
+ int64_t size, bool data_file);
29
} MirrorBDSOpaque;
27
int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
30
28
void **refcount_table,
31
struct MirrorOp {
29
int64_t *refcount_table_size,
32
@@ -XXX,XX +XXX,XX @@ static int mirror_exit_common(Job *job)
30
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
33
31
index XXXXXXX..XXXXXXX 100644
34
/* We don't access the source any more. Dropping any WRITE/RESIZE is
32
--- a/block/qcow2-bitmap.c
35
* required before it could become a backing file of target_bs. */
33
+++ b/block/qcow2-bitmap.c
36
- bdrv_child_try_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL,
34
@@ -XXX,XX +XXX,XX @@ static int bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list,
37
- &error_abort);
35
* directory in-place (actually, turn-off the extension), which is checked
38
+ bs_opaque->stop = true;
36
* in qcow2_check_metadata_overlap() */
39
+ bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
37
ret = qcow2_pre_write_overlap_check(
40
+ &error_abort);
38
- bs, in_place ? QCOW2_OL_BITMAP_DIRECTORY : 0, dir_offset, dir_size);
41
if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) {
39
+ bs, in_place ? QCOW2_OL_BITMAP_DIRECTORY : 0, dir_offset, dir_size,
42
BlockDriverState *backing = s->is_none_mode ? src : s->base;
40
+ false);
43
if (backing_bs(target_bs) != backing) {
41
if (ret < 0) {
44
@@ -XXX,XX +XXX,XX @@ static int mirror_exit_common(Job *job)
42
goto fail;
45
g_free(s->replaces);
43
}
46
bdrv_unref(target_bs);
44
@@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
47
45
memset(buf + write_size, 0, s->cluster_size - write_size);
48
- /* Remove the mirror filter driver from the graph. Before this, get rid of
46
}
49
+ /*
47
50
+ * Remove the mirror filter driver from the graph. Before this, get rid of
48
- ret = qcow2_pre_write_overlap_check(bs, 0, off, s->cluster_size);
51
* the blockers on the intermediate nodes so that the resulting state is
49
+ ret = qcow2_pre_write_overlap_check(bs, 0, off, s->cluster_size, false);
52
- * valid. Also give up permissions on mirror_top_bs->backing, which might
50
if (ret < 0) {
53
- * block the removal. */
51
error_setg_errno(errp, -ret, "Qcow2 overlap check failed");
54
+ * valid.
52
goto fail;
55
+ */
53
@@ -XXX,XX +XXX,XX @@ static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp)
56
block_job_remove_all_bdrv(bjob);
54
}
57
- bdrv_child_try_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL,
55
58
- &error_abort);
56
ret = qcow2_pre_write_overlap_check(bs, 0, tb_offset,
59
bdrv_replace_node(mirror_top_bs, backing_bs(mirror_top_bs), &error_abort);
57
- tb_size * sizeof(tb[0]));
60
58
+ tb_size * sizeof(tb[0]), false);
61
/* We just changed the BDS the job BB refers to (with either or both of the
59
if (ret < 0) {
62
@@ -XXX,XX +XXX,XX @@ static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c,
60
error_setg_errno(errp, -ret, "Qcow2 overlap check failed");
63
uint64_t perm, uint64_t shared,
61
goto fail;
64
uint64_t *nperm, uint64_t *nshared)
62
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/block/qcow2-cache.c
65
+++ b/block/qcow2-cache.c
66
@@ -XXX,XX +XXX,XX @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
67
68
if (c == s->refcount_block_cache) {
69
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_REFCOUNT_BLOCK,
70
- c->entries[i].offset, c->table_size);
71
+ c->entries[i].offset, c->table_size, false);
72
} else if (c == s->l2_table_cache) {
73
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,
74
- c->entries[i].offset, c->table_size);
75
+ c->entries[i].offset, c->table_size, false);
76
} else {
77
ret = qcow2_pre_write_overlap_check(bs, 0,
78
- c->entries[i].offset, c->table_size);
79
+ c->entries[i].offset, c->table_size, false);
80
}
81
82
if (ret < 0) {
83
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/block/qcow2-cluster.c
86
+++ b/block/qcow2-cluster.c
87
@@ -XXX,XX +XXX,XX @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
88
/* the L1 position has not yet been updated, so these clusters must
89
* indeed be completely free */
90
ret = qcow2_pre_write_overlap_check(bs, 0, new_l1_table_offset,
91
- new_l1_size2);
92
+ new_l1_size2, false);
93
if (ret < 0) {
94
goto fail;
95
}
96
@@ -XXX,XX +XXX,XX @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
97
}
98
99
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1,
100
- s->l1_table_offset + 8 * l1_start_index, sizeof(buf));
101
+ s->l1_table_offset + 8 * l1_start_index, sizeof(buf), false);
102
if (ret < 0) {
103
return ret;
104
}
105
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn do_perform_cow_write(BlockDriverState *bs,
106
unsigned offset_in_cluster,
107
QEMUIOVector *qiov)
108
{
65
{
109
+ BDRVQcow2State *s = bs->opaque;
66
+ MirrorBDSOpaque *s = bs->opaque;
110
int ret;
111
112
if (qiov->size == 0) {
113
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn do_perform_cow_write(BlockDriverState *bs,
114
}
115
116
ret = qcow2_pre_write_overlap_check(bs, 0,
117
- cluster_offset + offset_in_cluster, qiov->size);
118
+ cluster_offset + offset_in_cluster, qiov->size, true);
119
if (ret < 0) {
120
return ret;
121
}
122
123
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
124
- ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
125
+ ret = bdrv_co_pwritev(s->data_file, cluster_offset + offset_in_cluster,
126
qiov->size, qiov, 0);
127
if (ret < 0) {
128
return ret;
129
@@ -XXX,XX +XXX,XX @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
130
}
131
switch (type) {
132
case QCOW2_CLUSTER_COMPRESSED:
133
+ if (has_data_file(bs)) {
134
+ qcow2_signal_corruption(bs, true, -1, -1, "Compressed cluster "
135
+ "entry found in image with external data "
136
+ "file (L2 offset: %#" PRIx64 ", L2 index: "
137
+ "%#x)", l2_offset, l2_index);
138
+ ret = -EIO;
139
+ goto fail;
140
+ }
141
/* Compressed clusters can only be processed one by one */
142
c = 1;
143
*cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK;
144
@@ -XXX,XX +XXX,XX @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
145
ret = -EIO;
146
goto fail;
147
}
148
+ if (has_data_file(bs) && *cluster_offset != offset - offset_in_cluster)
149
+ {
150
+ qcow2_signal_corruption(bs, true, -1, -1,
151
+ "External data file host cluster offset %#"
152
+ PRIx64 " does not match guest cluster "
153
+ "offset: %#" PRIx64
154
+ ", L2 index: %#x)", *cluster_offset,
155
+ offset - offset_in_cluster, l2_index);
156
+ ret = -EIO;
157
+ goto fail;
158
+ }
159
break;
160
default:
161
abort();
162
@@ -XXX,XX +XXX,XX @@ int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
163
int64_t cluster_offset;
164
int nb_csectors;
165
166
+ if (has_data_file(bs)) {
167
+ return 0;
168
+ }
169
+
67
+
170
ret = get_cluster_table(bs, offset, &l2_slice, &l2_index);
68
+ if (s->stop) {
171
if (ret < 0) {
69
+ /*
172
return ret;
70
+ * If the job is to be stopped, we do not need to forward
173
@@ -XXX,XX +XXX,XX @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
71
+ * anything to the real image.
174
trace_qcow2_do_alloc_clusters_offset(qemu_coroutine_self(), guest_offset,
72
+ */
175
*host_offset, *nb_clusters);
73
+ *nperm = 0;
176
74
+ *nshared = BLK_PERM_ALL;
177
+ if (has_data_file(bs)) {
178
+ assert(*host_offset == INV_OFFSET ||
179
+ *host_offset == start_of_cluster(s, guest_offset));
180
+ *host_offset = start_of_cluster(s, guest_offset);
181
+ return 0;
182
+ }
183
+
184
/* Allocate new clusters */
185
trace_qcow2_cluster_alloc_phys(qemu_coroutine_self());
186
if (*host_offset == INV_OFFSET) {
187
@@ -XXX,XX +XXX,XX @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
188
}
189
190
ret = qcow2_pre_write_overlap_check(bs, 0, offset,
191
- s->cluster_size);
192
+ s->cluster_size, true);
193
if (ret < 0) {
194
if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
195
qcow2_free_clusters(bs, offset, s->cluster_size,
196
@@ -XXX,XX +XXX,XX @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
197
goto fail;
198
}
199
200
- ret = bdrv_pwrite_zeroes(bs->file, offset, s->cluster_size, 0);
201
+ ret = bdrv_pwrite_zeroes(s->data_file, offset,
202
+ s->cluster_size, 0);
203
if (ret < 0) {
204
if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
205
qcow2_free_clusters(bs, offset, s->cluster_size,
206
@@ -XXX,XX +XXX,XX @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
207
if (l2_dirty) {
208
ret = qcow2_pre_write_overlap_check(
209
bs, QCOW2_OL_INACTIVE_L2 | QCOW2_OL_ACTIVE_L2,
210
- slice_offset, slice_size2);
211
+ slice_offset, slice_size2, false);
212
if (ret < 0) {
213
goto fail;
214
}
215
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/block/qcow2-refcount.c
218
+++ b/block/qcow2-refcount.c
219
@@ -XXX,XX +XXX,XX @@ void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry,
220
int nb_clusters, enum qcow2_discard_type type)
221
{
222
BDRVQcow2State *s = bs->opaque;
223
+ QCow2ClusterType ctype = qcow2_get_cluster_type(bs, l2_entry);
224
225
- switch (qcow2_get_cluster_type(bs, l2_entry)) {
226
+ if (has_data_file(bs)) {
227
+ if (s->discard_passthrough[type] &&
228
+ (ctype == QCOW2_CLUSTER_NORMAL ||
229
+ ctype == QCOW2_CLUSTER_ZERO_ALLOC))
230
+ {
231
+ bdrv_pdiscard(s->data_file, l2_entry & L2E_OFFSET_MASK,
232
+ nb_clusters << s->cluster_bits);
233
+ }
234
+ return;
75
+ return;
235
+ }
76
+ }
236
+
77
+
237
+ switch (ctype) {
78
/* Must be able to forward guest writes to the real image */
238
case QCOW2_CLUSTER_COMPRESSED:
79
*nperm = 0;
239
{
80
if (perm & BLK_PERM_WRITE) {
240
int nb_csectors;
81
@@ -XXX,XX +XXX,XX @@ fail:
241
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
82
job_early_fail(&s->common.job);
242
l2_table[i] = cpu_to_be64(l2_entry);
243
ret = qcow2_pre_write_overlap_check(bs,
244
QCOW2_OL_ACTIVE_L2 | QCOW2_OL_INACTIVE_L2,
245
- l2e_offset, sizeof(uint64_t));
246
+ l2e_offset, sizeof(uint64_t), false);
247
if (ret < 0) {
248
fprintf(stderr, "ERROR: Overlap check failed\n");
249
res->check_errors++;
250
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
251
252
if (l2_dirty) {
253
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,
254
- l2_offset, s->cluster_size);
255
+ l2_offset, s->cluster_size,
256
+ false);
257
if (ret < 0) {
258
fprintf(stderr, "ERROR: Could not write L2 table; metadata "
259
"overlap check failed: %s\n", strerror(-ret));
260
@@ -XXX,XX +XXX,XX @@ write_refblocks:
261
}
262
263
ret = qcow2_pre_write_overlap_check(bs, 0, refblock_offset,
264
- s->cluster_size);
265
+ s->cluster_size, false);
266
if (ret < 0) {
267
fprintf(stderr, "ERROR writing refblock: %s\n", strerror(-ret));
268
goto fail;
269
@@ -XXX,XX +XXX,XX @@ write_refblocks:
270
}
83
}
271
84
272
ret = qcow2_pre_write_overlap_check(bs, 0, reftable_offset,
85
- bdrv_child_try_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL,
273
- reftable_size * sizeof(uint64_t));
86
- &error_abort);
274
+ reftable_size * sizeof(uint64_t),
87
+ bs_opaque->stop = true;
275
+ false);
88
+ bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
276
if (ret < 0) {
89
+ &error_abort);
277
fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret));
90
bdrv_replace_node(mirror_top_bs, backing_bs(mirror_top_bs), &error_abort);
278
goto fail;
91
279
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR != ARRAY_SIZE(metadata_ol_names));
92
bdrv_unref(mirror_top_bs);
280
* overlaps; or a negative value (-errno) on error.
281
*/
282
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
283
- int64_t size)
284
+ int64_t size, bool data_file)
285
{
286
- int ret = qcow2_check_metadata_overlap(bs, ign, offset, size);
287
+ int ret;
288
+
289
+ if (data_file && has_data_file(bs)) {
290
+ return 0;
291
+ }
292
293
+ ret = qcow2_check_metadata_overlap(bs, ign, offset, size);
294
if (ret < 0) {
295
return ret;
296
} else if (ret > 0) {
297
@@ -XXX,XX +XXX,XX @@ static int flush_refblock(BlockDriverState *bs, uint64_t **reftable,
298
if (reftable_index < *reftable_size && (*reftable)[reftable_index]) {
299
offset = (*reftable)[reftable_index];
300
301
- ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size);
302
+ ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size,
303
+ false);
304
if (ret < 0) {
305
error_setg_errno(errp, -ret, "Overlap check failed");
306
return ret;
307
@@ -XXX,XX +XXX,XX @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
308
309
/* Write the new reftable */
310
ret = qcow2_pre_write_overlap_check(bs, 0, new_reftable_offset,
311
- new_reftable_size * sizeof(uint64_t));
312
+ new_reftable_size * sizeof(uint64_t),
313
+ false);
314
if (ret < 0) {
315
error_setg_errno(errp, -ret, "Overlap check failed");
316
goto done;
317
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
318
index XXXXXXX..XXXXXXX 100644
319
--- a/block/qcow2-snapshot.c
320
+++ b/block/qcow2-snapshot.c
321
@@ -XXX,XX +XXX,XX @@ static int qcow2_write_snapshots(BlockDriverState *bs)
322
323
/* The snapshot list position has not yet been updated, so these clusters
324
* must indeed be completely free */
325
- ret = qcow2_pre_write_overlap_check(bs, 0, offset, snapshots_size);
326
+ ret = qcow2_pre_write_overlap_check(bs, 0, offset, snapshots_size, false);
327
if (ret < 0) {
328
goto fail;
329
}
330
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
331
}
332
333
ret = qcow2_pre_write_overlap_check(bs, 0, sn->l1_table_offset,
334
- s->l1_size * sizeof(uint64_t));
335
+ s->l1_size * sizeof(uint64_t), false);
336
if (ret < 0) {
337
goto fail;
338
}
339
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
340
}
341
342
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1,
343
- s->l1_table_offset, cur_l1_bytes);
344
+ s->l1_table_offset, cur_l1_bytes,
345
+ false);
346
if (ret < 0) {
347
goto fail;
348
}
349
diff --git a/block/qcow2.c b/block/qcow2.c
350
index XXXXXXX..XXXXXXX 100644
351
--- a/block/qcow2.c
352
+++ b/block/qcow2.c
353
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen,
354
/* Zero fill remaining space in cluster so it has predictable
355
* content in case of future spec changes */
356
clusterlen = size_to_clusters(s, headerlen) * s->cluster_size;
357
- assert(qcow2_pre_write_overlap_check(bs, 0, ret, clusterlen) == 0);
358
+ assert(qcow2_pre_write_overlap_check(bs, 0, ret, clusterlen, false) == 0);
359
ret = bdrv_pwrite_zeroes(bs->file,
360
ret + headerlen,
361
clusterlen - headerlen, 0);
362
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
363
*/
364
if (!cluster_data) {
365
cluster_data =
366
- qemu_try_blockalign(bs->file->bs,
367
+ qemu_try_blockalign(s->data_file->bs,
368
QCOW_MAX_CRYPT_CLUSTERS
369
* s->cluster_size);
370
if (cluster_data == NULL) {
371
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
372
373
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
374
qemu_co_mutex_unlock(&s->lock);
375
- ret = bdrv_co_preadv(bs->file,
376
+ ret = bdrv_co_preadv(s->data_file,
377
cluster_offset + offset_in_cluster,
378
cur_bytes, &hd_qiov, 0);
379
qemu_co_mutex_lock(&s->lock);
380
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
381
}
382
383
ret = qcow2_pre_write_overlap_check(bs, 0,
384
- cluster_offset + offset_in_cluster, cur_bytes);
385
+ cluster_offset + offset_in_cluster, cur_bytes, true);
386
if (ret < 0) {
387
goto fail;
388
}
389
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
390
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
391
trace_qcow2_writev_data(qemu_coroutine_self(),
392
cluster_offset + offset_in_cluster);
393
- ret = bdrv_co_pwritev(bs->file,
394
+ ret = bdrv_co_pwritev(s->data_file,
395
cluster_offset + offset_in_cluster,
396
cur_bytes, &hd_qiov, 0);
397
qemu_co_mutex_lock(&s->lock);
398
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_from(BlockDriverState *bs,
399
goto out;
400
401
case QCOW2_CLUSTER_NORMAL:
402
- child = bs->file;
403
+ child = s->data_file;
404
copy_offset += offset_into_cluster(s, src_offset);
405
if ((copy_offset & 511) != 0) {
406
ret = -EIO;
407
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_to(BlockDriverState *bs,
408
assert((cluster_offset & 511) == 0);
409
410
ret = qcow2_pre_write_overlap_check(bs, 0,
411
- cluster_offset + offset_in_cluster, cur_bytes);
412
+ cluster_offset + offset_in_cluster, cur_bytes, true);
413
if (ret < 0) {
414
goto fail;
415
}
416
417
qemu_co_mutex_unlock(&s->lock);
418
ret = bdrv_co_copy_range_to(src, src_offset,
419
- bs->file,
420
+ s->data_file,
421
cluster_offset + offset_in_cluster,
422
cur_bytes, read_flags, write_flags);
423
qemu_co_mutex_lock(&s->lock);
424
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
425
int64_t old_file_size, new_file_size;
426
uint64_t nb_new_data_clusters, nb_new_l2_tables;
427
428
+ /* With a data file, preallocation means just allocating the metadata
429
+ * and forwarding the truncate request to the data file */
430
+ if (has_data_file(bs)) {
431
+ ret = preallocate_co(bs, old_length, offset);
432
+ if (ret < 0) {
433
+ error_setg_errno(errp, -ret, "Preallocation failed");
434
+ goto fail;
435
+ }
436
+ break;
437
+ }
438
+
439
old_file_size = bdrv_getlength(bs->file->bs);
440
if (old_file_size < 0) {
441
error_setg_errno(errp, -old_file_size,
442
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
443
444
bs->total_sectors = offset / BDRV_SECTOR_SIZE;
445
446
+ if (has_data_file(bs)) {
447
+ if (prealloc == PREALLOC_MODE_METADATA) {
448
+ prealloc = PREALLOC_MODE_OFF;
449
+ }
450
+ ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
451
+ if (ret < 0) {
452
+ goto fail;
453
+ }
454
+ }
455
+
456
/* write updated header.size */
457
offset = cpu_to_be64(offset);
458
ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
459
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
460
uint8_t *buf, *out_buf;
461
uint64_t cluster_offset;
462
463
+ if (has_data_file(bs)) {
464
+ return -ENOTSUP;
465
+ }
466
+
467
if (bytes == 0) {
468
/* align end of file to a sector boundary to ease reading with
469
sector based I/Os */
470
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
471
goto fail;
472
}
473
474
- ret = qcow2_pre_write_overlap_check(bs, 0, cluster_offset, out_len);
475
+ ret = qcow2_pre_write_overlap_check(bs, 0, cluster_offset, out_len, true);
476
qemu_co_mutex_unlock(&s->lock);
477
if (ret < 0) {
478
goto fail;
479
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
480
481
qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
482
483
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
484
- ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0);
485
+ BLKDBG_EVENT(s->data_file, BLKDBG_WRITE_COMPRESSED);
486
+ ret = bdrv_co_pwritev(s->data_file, cluster_offset, out_len, &hd_qiov, 0);
487
if (ret < 0) {
488
goto fail;
489
}
490
@@ -XXX,XX +XXX,XX @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version,
491
return -ENOTSUP;
492
}
493
494
+ if (has_data_file(bs)) {
495
+ error_setg(errp, "Cannot downgrade an image with a data file");
496
+ return -ENOTSUP;
497
+ }
498
+
499
/* clear incompatible features */
500
if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) {
501
ret = qcow2_mark_clean(bs);
502
--
93
--
503
2.20.1
94
2.20.1
504
95
505
96
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Replace the binary mode with the default text one when *.notrun
3
commit_top_bs never requests or unshares any permissions. There is no
4
files are opened for skipped tests. That change is made for the
4
reason to make this so explicit here.
5
compatibility with Python 3 which returns error otherwise.
6
5
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
9
---
11
tests/qemu-iotests/iotests.py | 2 +-
10
block/commit.c | 2 --
12
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 2 deletions(-)
13
12
14
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
13
diff --git a/block/commit.c b/block/commit.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qemu-iotests/iotests.py
15
--- a/block/commit.c
17
+++ b/tests/qemu-iotests/iotests.py
16
+++ b/block/commit.c
18
@@ -XXX,XX +XXX,XX @@ def notrun(reason):
17
@@ -XXX,XX +XXX,XX @@ static void commit_abort(Job *job)
19
# Each test in qemu-iotests has a number ("seq")
18
* XXX Can (or should) we somehow keep 'consistent read' blocked even
20
seq = os.path.basename(sys.argv[0])
19
* after the failed/cancelled commit job is gone? If we already wrote
21
20
* something to base, the intermediate images aren't valid any more. */
22
- open('%s/%s.notrun' % (output_dir, seq), 'wb').write(reason + '\n')
21
- bdrv_child_try_set_perm(s->commit_top_bs->backing, 0, BLK_PERM_ALL,
23
+ open('%s/%s.notrun' % (output_dir, seq), 'w').write(reason + '\n')
22
- &error_abort);
24
print('%s not run: %s' % (seq, reason))
23
bdrv_replace_node(s->commit_top_bs, backing_bs(s->commit_top_bs),
25
sys.exit(0)
24
&error_abort);
26
25
27
--
26
--
28
2.20.1
27
2.20.1
29
28
30
29
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
2
1
3
Some test cases require specific formats. The method decorator
4
skip_if_unsupported() checks if requested formats are whitelisted.
5
The test #139 was selected for a sample output, after running
6
$ ./check -qcow2 131-140
7
8
137 3s ...
9
138 0s ...
10
139 2s ...
11
[case not run] testBlkDebug (__main__.TestBlockdevDel): formats ['blkdebug'] are not whitelisted
12
[case not run] testBlkVerify (__main__.TestBlockdevDel): formats ['blkverify'] are not whitelisted
13
[case not run] testQuorum (__main__.TestBlockdevDel): formats ['quorum'] are not whitelisted
14
140 0s ...
15
Not run: 131 135 136
16
Some cases not run in: 139
17
Passed all 7 tests
18
19
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
---
22
tests/qemu-iotests/139 | 3 +++
23
1 file changed, 3 insertions(+)
24
25
diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139
26
index XXXXXXX..XXXXXXX 100755
27
--- a/tests/qemu-iotests/139
28
+++ b/tests/qemu-iotests/139
29
@@ -XXX,XX +XXX,XX @@ class TestBlockdevDel(iotests.QMPTestCase):
30
# FIXME mirror0 disappears, drive-mirror doesn't take a reference
31
#self.delBlockDriverState('mirror0')
32
33
+ @iotests.skip_if_unsupported(['blkdebug'])
34
def testBlkDebug(self):
35
self.addBlkDebug('debug0', 'node0')
36
# 'node0' is used by the blkdebug node
37
@@ -XXX,XX +XXX,XX @@ class TestBlockdevDel(iotests.QMPTestCase):
38
self.delBlockDriverState('debug0')
39
self.checkBlockDriverState('node0', False)
40
41
+ @iotests.skip_if_unsupported(['blkverify'])
42
def testBlkVerify(self):
43
self.addBlkVerify('verify0', 'node0', 'node1')
44
# We cannot remove the children of a blkverify device
45
@@ -XXX,XX +XXX,XX @@ class TestBlockdevDel(iotests.QMPTestCase):
46
self.checkBlockDriverState('node0', False)
47
self.checkBlockDriverState('node1', False)
48
49
+ @iotests.skip_if_unsupported(['quorum'])
50
def testQuorum(self):
51
if not iotests.supports_quorum():
52
return
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Bash is not always installed as /bin/bash. In particular on OpenBSD,
4
the package installs it in /usr/local/bin.
5
Use the 'env' shebang to search bash in the $PATH.
6
7
Reviewed-by: Kamil Rytarowski <n54@gmx.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
tests/multiboot/run_test.sh | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/multiboot/run_test.sh
18
+++ b/tests/multiboot/run_test.sh
19
@@ -XXX,XX +XXX,XX @@
20
-#!/bin/bash
21
+#!/usr/bin/env bash
22
23
# Copyright (c) 2013 Kevin Wolf <kwolf@redhat.com>
24
#
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Bash is not always installed as /bin/bash. In particular on OpenBSD,
4
the package installs it in /usr/local/bin.
5
Use the 'env' shebang to search bash in the $PATH.
6
7
Reviewed-by: Kamil Rytarowski <n54@gmx.com>
8
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Acked-by: Thomas Huth <thuth@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
tests/data/acpi/rebuild-expected-aml.sh | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/tests/data/acpi/rebuild-expected-aml.sh b/tests/data/acpi/rebuild-expected-aml.sh
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/data/acpi/rebuild-expected-aml.sh
20
+++ b/tests/data/acpi/rebuild-expected-aml.sh
21
@@ -XXX,XX +XXX,XX @@
22
-#! /bin/bash
23
+#!/usr/bin/env bash
24
25
#
26
# Rebuild expected AML files for acpi unit-test
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Bash is not always installed as /bin/bash. In particular on OpenBSD,
4
the package installs it in /usr/local/bin.
5
Use the 'env' shebang to search bash in the $PATH.
6
7
Patch created mechanically by running:
8
9
$ git grep -lE '#! ?/bin/bash' -- tests/qemu-iotests \
10
| while read f; do \
11
sed -i 's|^#!.\?/bin/bash$|#!/usr/bin/env bash|' $f; \
12
done
13
14
Reviewed-by: Eric Blake <eblake@redhat.com>
15
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
tests/qemu-iotests/001 | 2 +-
19
tests/qemu-iotests/002 | 2 +-
20
tests/qemu-iotests/003 | 2 +-
21
tests/qemu-iotests/004 | 2 +-
22
tests/qemu-iotests/005 | 2 +-
23
tests/qemu-iotests/007 | 2 +-
24
tests/qemu-iotests/008 | 2 +-
25
tests/qemu-iotests/009 | 2 +-
26
tests/qemu-iotests/010 | 2 +-
27
tests/qemu-iotests/011 | 2 +-
28
tests/qemu-iotests/012 | 2 +-
29
tests/qemu-iotests/013 | 2 +-
30
tests/qemu-iotests/014 | 2 +-
31
tests/qemu-iotests/015 | 2 +-
32
tests/qemu-iotests/017 | 2 +-
33
tests/qemu-iotests/018 | 2 +-
34
tests/qemu-iotests/019 | 2 +-
35
tests/qemu-iotests/020 | 2 +-
36
tests/qemu-iotests/021 | 2 +-
37
tests/qemu-iotests/022 | 2 +-
38
tests/qemu-iotests/023 | 2 +-
39
tests/qemu-iotests/024 | 2 +-
40
tests/qemu-iotests/025 | 2 +-
41
tests/qemu-iotests/026 | 2 +-
42
tests/qemu-iotests/027 | 2 +-
43
tests/qemu-iotests/028 | 2 +-
44
tests/qemu-iotests/029 | 2 +-
45
tests/qemu-iotests/031 | 2 +-
46
tests/qemu-iotests/032 | 2 +-
47
tests/qemu-iotests/033 | 2 +-
48
tests/qemu-iotests/034 | 2 +-
49
tests/qemu-iotests/035 | 2 +-
50
tests/qemu-iotests/036 | 2 +-
51
tests/qemu-iotests/037 | 2 +-
52
tests/qemu-iotests/038 | 2 +-
53
tests/qemu-iotests/039 | 2 +-
54
tests/qemu-iotests/042 | 2 +-
55
tests/qemu-iotests/043 | 2 +-
56
tests/qemu-iotests/046 | 2 +-
57
tests/qemu-iotests/047 | 2 +-
58
tests/qemu-iotests/048 | 2 +-
59
tests/qemu-iotests/049 | 2 +-
60
tests/qemu-iotests/050 | 2 +-
61
tests/qemu-iotests/051 | 2 +-
62
tests/qemu-iotests/052 | 2 +-
63
tests/qemu-iotests/053 | 2 +-
64
tests/qemu-iotests/054 | 2 +-
65
tests/qemu-iotests/058 | 2 +-
66
tests/qemu-iotests/059 | 2 +-
67
tests/qemu-iotests/060 | 2 +-
68
tests/qemu-iotests/061 | 2 +-
69
tests/qemu-iotests/062 | 2 +-
70
tests/qemu-iotests/063 | 2 +-
71
tests/qemu-iotests/064 | 2 +-
72
tests/qemu-iotests/066 | 2 +-
73
tests/qemu-iotests/067 | 2 +-
74
tests/qemu-iotests/068 | 2 +-
75
tests/qemu-iotests/069 | 2 +-
76
tests/qemu-iotests/070 | 2 +-
77
tests/qemu-iotests/071 | 2 +-
78
tests/qemu-iotests/072 | 2 +-
79
tests/qemu-iotests/073 | 2 +-
80
tests/qemu-iotests/074 | 2 +-
81
tests/qemu-iotests/075 | 2 +-
82
tests/qemu-iotests/076 | 2 +-
83
tests/qemu-iotests/077 | 2 +-
84
tests/qemu-iotests/078 | 2 +-
85
tests/qemu-iotests/079 | 2 +-
86
tests/qemu-iotests/080 | 2 +-
87
tests/qemu-iotests/081 | 2 +-
88
tests/qemu-iotests/082 | 2 +-
89
tests/qemu-iotests/083 | 2 +-
90
tests/qemu-iotests/084 | 2 +-
91
tests/qemu-iotests/085 | 2 +-
92
tests/qemu-iotests/086 | 2 +-
93
tests/qemu-iotests/087 | 2 +-
94
tests/qemu-iotests/088 | 2 +-
95
tests/qemu-iotests/089 | 2 +-
96
tests/qemu-iotests/090 | 2 +-
97
tests/qemu-iotests/091 | 2 +-
98
tests/qemu-iotests/092 | 2 +-
99
tests/qemu-iotests/094 | 2 +-
100
tests/qemu-iotests/095 | 2 +-
101
tests/qemu-iotests/097 | 2 +-
102
tests/qemu-iotests/098 | 2 +-
103
tests/qemu-iotests/099 | 2 +-
104
tests/qemu-iotests/101 | 2 +-
105
tests/qemu-iotests/102 | 2 +-
106
tests/qemu-iotests/103 | 2 +-
107
tests/qemu-iotests/104 | 2 +-
108
tests/qemu-iotests/105 | 2 +-
109
tests/qemu-iotests/106 | 2 +-
110
tests/qemu-iotests/107 | 2 +-
111
tests/qemu-iotests/108 | 2 +-
112
tests/qemu-iotests/109 | 2 +-
113
tests/qemu-iotests/110 | 2 +-
114
tests/qemu-iotests/111 | 2 +-
115
tests/qemu-iotests/112 | 2 +-
116
tests/qemu-iotests/113 | 2 +-
117
tests/qemu-iotests/114 | 2 +-
118
tests/qemu-iotests/115 | 2 +-
119
tests/qemu-iotests/116 | 2 +-
120
tests/qemu-iotests/117 | 2 +-
121
tests/qemu-iotests/119 | 2 +-
122
tests/qemu-iotests/120 | 2 +-
123
tests/qemu-iotests/121 | 2 +-
124
tests/qemu-iotests/122 | 2 +-
125
tests/qemu-iotests/123 | 2 +-
126
tests/qemu-iotests/125 | 2 +-
127
tests/qemu-iotests/126 | 2 +-
128
tests/qemu-iotests/127 | 2 +-
129
tests/qemu-iotests/128 | 2 +-
130
tests/qemu-iotests/130 | 2 +-
131
tests/qemu-iotests/131 | 2 +-
132
tests/qemu-iotests/133 | 2 +-
133
tests/qemu-iotests/134 | 2 +-
134
tests/qemu-iotests/135 | 2 +-
135
tests/qemu-iotests/137 | 2 +-
136
tests/qemu-iotests/138 | 2 +-
137
tests/qemu-iotests/140 | 2 +-
138
tests/qemu-iotests/141 | 2 +-
139
tests/qemu-iotests/142 | 2 +-
140
tests/qemu-iotests/143 | 2 +-
141
tests/qemu-iotests/144 | 2 +-
142
tests/qemu-iotests/145 | 2 +-
143
tests/qemu-iotests/146 | 2 +-
144
tests/qemu-iotests/150 | 2 +-
145
tests/qemu-iotests/153 | 2 +-
146
tests/qemu-iotests/154 | 2 +-
147
tests/qemu-iotests/156 | 2 +-
148
tests/qemu-iotests/157 | 2 +-
149
tests/qemu-iotests/158 | 2 +-
150
tests/qemu-iotests/159 | 2 +-
151
tests/qemu-iotests/160 | 2 +-
152
tests/qemu-iotests/161 | 2 +-
153
tests/qemu-iotests/162 | 2 +-
154
tests/qemu-iotests/170 | 2 +-
155
tests/qemu-iotests/171 | 2 +-
156
tests/qemu-iotests/172 | 2 +-
157
tests/qemu-iotests/173 | 2 +-
158
tests/qemu-iotests/174 | 2 +-
159
tests/qemu-iotests/175 | 2 +-
160
tests/qemu-iotests/176 | 2 +-
161
tests/qemu-iotests/177 | 2 +-
162
tests/qemu-iotests/178 | 2 +-
163
tests/qemu-iotests/179 | 2 +-
164
tests/qemu-iotests/181 | 2 +-
165
tests/qemu-iotests/182 | 2 +-
166
tests/qemu-iotests/183 | 2 +-
167
tests/qemu-iotests/184 | 2 +-
168
tests/qemu-iotests/185 | 2 +-
169
tests/qemu-iotests/186 | 2 +-
170
tests/qemu-iotests/187 | 2 +-
171
tests/qemu-iotests/188 | 2 +-
172
tests/qemu-iotests/189 | 2 +-
173
tests/qemu-iotests/190 | 2 +-
174
tests/qemu-iotests/191 | 2 +-
175
tests/qemu-iotests/192 | 2 +-
176
tests/qemu-iotests/195 | 2 +-
177
tests/qemu-iotests/197 | 2 +-
178
tests/qemu-iotests/198 | 2 +-
179
tests/qemu-iotests/200 | 2 +-
180
tests/qemu-iotests/201 | 2 +-
181
tests/qemu-iotests/204 | 2 +-
182
tests/qemu-iotests/214 | 2 +-
183
tests/qemu-iotests/215 | 2 +-
184
tests/qemu-iotests/217 | 2 +-
185
tests/qemu-iotests/220 | 2 +-
186
tests/qemu-iotests/221 | 2 +-
187
tests/qemu-iotests/223 | 2 +-
188
tests/qemu-iotests/225 | 2 +-
189
tests/qemu-iotests/226 | 2 +-
190
tests/qemu-iotests/227 | 2 +-
191
tests/qemu-iotests/229 | 2 +-
192
tests/qemu-iotests/231 | 2 +-
193
tests/qemu-iotests/232 | 2 +-
194
tests/qemu-iotests/233 | 2 +-
195
tests/qemu-iotests/check | 2 +-
196
tests/qemu-iotests/common.config | 2 +-
197
tests/qemu-iotests/common.filter | 2 +-
198
tests/qemu-iotests/common.nbd | 2 +-
199
tests/qemu-iotests/common.pattern | 2 +-
200
tests/qemu-iotests/common.qemu | 2 +-
201
tests/qemu-iotests/common.rc | 2 +-
202
tests/qemu-iotests/common.tls | 2 +-
203
185 files changed, 185 insertions(+), 185 deletions(-)
204
205
diff --git a/tests/qemu-iotests/001 b/tests/qemu-iotests/001
206
index XXXXXXX..XXXXXXX 100755
207
--- a/tests/qemu-iotests/001
208
+++ b/tests/qemu-iotests/001
209
@@ -XXX,XX +XXX,XX @@
210
-#!/bin/bash
211
+#!/usr/bin/env bash
212
#
213
# Test simple read/write using plain bdrv_read/bdrv_write
214
#
215
diff --git a/tests/qemu-iotests/002 b/tests/qemu-iotests/002
216
index XXXXXXX..XXXXXXX 100755
217
--- a/tests/qemu-iotests/002
218
+++ b/tests/qemu-iotests/002
219
@@ -XXX,XX +XXX,XX @@
220
-#!/bin/bash
221
+#!/usr/bin/env bash
222
#
223
# Test simple read/write using plain bdrv_pread/bdrv_pwrite
224
#
225
diff --git a/tests/qemu-iotests/003 b/tests/qemu-iotests/003
226
index XXXXXXX..XXXXXXX 100755
227
--- a/tests/qemu-iotests/003
228
+++ b/tests/qemu-iotests/003
229
@@ -XXX,XX +XXX,XX @@
230
-#!/bin/bash
231
+#!/usr/bin/env bash
232
#
233
# Test simple read/write using bdrv_aio_readv/bdrv_aio_writev
234
#
235
diff --git a/tests/qemu-iotests/004 b/tests/qemu-iotests/004
236
index XXXXXXX..XXXXXXX 100755
237
--- a/tests/qemu-iotests/004
238
+++ b/tests/qemu-iotests/004
239
@@ -XXX,XX +XXX,XX @@
240
-#!/bin/bash
241
+#!/usr/bin/env bash
242
#
243
# Make sure we can't read and write outside of the image size.
244
#
245
diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005
246
index XXXXXXX..XXXXXXX 100755
247
--- a/tests/qemu-iotests/005
248
+++ b/tests/qemu-iotests/005
249
@@ -XXX,XX +XXX,XX @@
250
-#!/bin/bash
251
+#!/usr/bin/env bash
252
#
253
# Make sure qemu-img can create 5TB images
254
#
255
diff --git a/tests/qemu-iotests/007 b/tests/qemu-iotests/007
256
index XXXXXXX..XXXXXXX 100755
257
--- a/tests/qemu-iotests/007
258
+++ b/tests/qemu-iotests/007
259
@@ -XXX,XX +XXX,XX @@
260
-#!/bin/bash
261
+#!/usr/bin/env bash
262
#
263
# Check for one possible case of qcow2 refcount corruption.
264
#
265
diff --git a/tests/qemu-iotests/008 b/tests/qemu-iotests/008
266
index XXXXXXX..XXXXXXX 100755
267
--- a/tests/qemu-iotests/008
268
+++ b/tests/qemu-iotests/008
269
@@ -XXX,XX +XXX,XX @@
270
-#!/bin/bash
271
+#!/usr/bin/env bash
272
#
273
# Test simple asynchronous read/write operations.
274
#
275
diff --git a/tests/qemu-iotests/009 b/tests/qemu-iotests/009
276
index XXXXXXX..XXXXXXX 100755
277
--- a/tests/qemu-iotests/009
278
+++ b/tests/qemu-iotests/009
279
@@ -XXX,XX +XXX,XX @@
280
-#!/bin/bash
281
+#!/usr/bin/env bash
282
#
283
# Nolan I qcow2 corruption - incorrectly reports free clusters
284
#
285
diff --git a/tests/qemu-iotests/010 b/tests/qemu-iotests/010
286
index XXXXXXX..XXXXXXX 100755
287
--- a/tests/qemu-iotests/010
288
+++ b/tests/qemu-iotests/010
289
@@ -XXX,XX +XXX,XX @@
290
-#!/bin/bash
291
+#!/usr/bin/env bash
292
#
293
# Nolan II qcow2 corruption - wrong used cluster
294
#
295
diff --git a/tests/qemu-iotests/011 b/tests/qemu-iotests/011
296
index XXXXXXX..XXXXXXX 100755
297
--- a/tests/qemu-iotests/011
298
+++ b/tests/qemu-iotests/011
299
@@ -XXX,XX +XXX,XX @@
300
-#!/bin/bash
301
+#!/usr/bin/env bash
302
#
303
# Test for AIO allocation on the same cluster
304
#
305
diff --git a/tests/qemu-iotests/012 b/tests/qemu-iotests/012
306
index XXXXXXX..XXXXXXX 100755
307
--- a/tests/qemu-iotests/012
308
+++ b/tests/qemu-iotests/012
309
@@ -XXX,XX +XXX,XX @@
310
-#!/bin/bash
311
+#!/usr/bin/env bash
312
#
313
# Make sure we can open read-only images
314
#
315
diff --git a/tests/qemu-iotests/013 b/tests/qemu-iotests/013
316
index XXXXXXX..XXXXXXX 100755
317
--- a/tests/qemu-iotests/013
318
+++ b/tests/qemu-iotests/013
319
@@ -XXX,XX +XXX,XX @@
320
-#!/bin/bash
321
+#!/usr/bin/env bash
322
#
323
# qcow2 pattern test, empty and compressed image - 4k cluster patterns
324
#
325
diff --git a/tests/qemu-iotests/014 b/tests/qemu-iotests/014
326
index XXXXXXX..XXXXXXX 100755
327
--- a/tests/qemu-iotests/014
328
+++ b/tests/qemu-iotests/014
329
@@ -XXX,XX +XXX,XX @@
330
-#!/bin/bash
331
+#!/usr/bin/env bash
332
#
333
# qcow2 pattern test, complex patterns including compression and snapshots
334
# Using patterns for 4k cluster size.
335
diff --git a/tests/qemu-iotests/015 b/tests/qemu-iotests/015
336
index XXXXXXX..XXXXXXX 100755
337
--- a/tests/qemu-iotests/015
338
+++ b/tests/qemu-iotests/015
339
@@ -XXX,XX +XXX,XX @@
340
-#!/bin/bash
341
+#!/usr/bin/env bash
342
#
343
# Combined test to grow the refcount table and test snapshots.
344
#
345
diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017
346
index XXXXXXX..XXXXXXX 100755
347
--- a/tests/qemu-iotests/017
348
+++ b/tests/qemu-iotests/017
349
@@ -XXX,XX +XXX,XX @@
350
-#!/bin/bash
351
+#!/usr/bin/env bash
352
#
353
# Simple backing file reads
354
#
355
diff --git a/tests/qemu-iotests/018 b/tests/qemu-iotests/018
356
index XXXXXXX..XXXXXXX 100755
357
--- a/tests/qemu-iotests/018
358
+++ b/tests/qemu-iotests/018
359
@@ -XXX,XX +XXX,XX @@
360
-#!/bin/bash
361
+#!/usr/bin/env bash
362
#
363
# Merge backing file into test image when converting the image
364
#
365
diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019
366
index XXXXXXX..XXXXXXX 100755
367
--- a/tests/qemu-iotests/019
368
+++ b/tests/qemu-iotests/019
369
@@ -XXX,XX +XXX,XX @@
370
-#!/bin/bash
371
+#!/usr/bin/env bash
372
#
373
# When using a backing file for the output image in qemu-img convert,
374
# the backing file clusters must not copied. The data must still be
375
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
376
index XXXXXXX..XXXXXXX 100755
377
--- a/tests/qemu-iotests/020
378
+++ b/tests/qemu-iotests/020
379
@@ -XXX,XX +XXX,XX @@
380
-#!/bin/bash
381
+#!/usr/bin/env bash
382
#
383
# Commit changes to backing file
384
#
385
diff --git a/tests/qemu-iotests/021 b/tests/qemu-iotests/021
386
index XXXXXXX..XXXXXXX 100755
387
--- a/tests/qemu-iotests/021
388
+++ b/tests/qemu-iotests/021
389
@@ -XXX,XX +XXX,XX @@
390
-#!/bin/bash
391
+#!/usr/bin/env bash
392
#
393
# Test handling of invalid patterns arguments to qemu-io
394
#
395
diff --git a/tests/qemu-iotests/022 b/tests/qemu-iotests/022
396
index XXXXXXX..XXXXXXX 100755
397
--- a/tests/qemu-iotests/022
398
+++ b/tests/qemu-iotests/022
399
@@ -XXX,XX +XXX,XX @@
400
-#!/bin/bash
401
+#!/usr/bin/env bash
402
#
403
# Test bdrv_load/save_vmstate using the usual patterns
404
#
405
diff --git a/tests/qemu-iotests/023 b/tests/qemu-iotests/023
406
index XXXXXXX..XXXXXXX 100755
407
--- a/tests/qemu-iotests/023
408
+++ b/tests/qemu-iotests/023
409
@@ -XXX,XX +XXX,XX @@
410
-#!/bin/bash
411
+#!/usr/bin/env bash
412
#
413
# qcow2 pattern test with various cluster sizes
414
#
415
diff --git a/tests/qemu-iotests/024 b/tests/qemu-iotests/024
416
index XXXXXXX..XXXXXXX 100755
417
--- a/tests/qemu-iotests/024
418
+++ b/tests/qemu-iotests/024
419
@@ -XXX,XX +XXX,XX @@
420
-#!/bin/bash
421
+#!/usr/bin/env bash
422
#
423
# Rebasing COW images
424
#
425
diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025
426
index XXXXXXX..XXXXXXX 100755
427
--- a/tests/qemu-iotests/025
428
+++ b/tests/qemu-iotests/025
429
@@ -XXX,XX +XXX,XX @@
430
-#!/bin/bash
431
+#!/usr/bin/env bash
432
#
433
# Resizing images
434
#
435
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
436
index XXXXXXX..XXXXXXX 100755
437
--- a/tests/qemu-iotests/026
438
+++ b/tests/qemu-iotests/026
439
@@ -XXX,XX +XXX,XX @@
440
-#!/bin/bash
441
+#!/usr/bin/env bash
442
#
443
# qcow2 error path testing
444
#
445
diff --git a/tests/qemu-iotests/027 b/tests/qemu-iotests/027
446
index XXXXXXX..XXXXXXX 100755
447
--- a/tests/qemu-iotests/027
448
+++ b/tests/qemu-iotests/027
449
@@ -XXX,XX +XXX,XX @@
450
-#!/bin/bash
451
+#!/usr/bin/env bash
452
#
453
# Test that sub-cluster allocating writes zero the rest of the cluster
454
#
455
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
456
index XXXXXXX..XXXXXXX 100755
457
--- a/tests/qemu-iotests/028
458
+++ b/tests/qemu-iotests/028
459
@@ -XXX,XX +XXX,XX @@
460
-#!/bin/bash
461
+#!/usr/bin/env bash
462
#
463
# Test that backing files can be smaller than the image
464
#
465
diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029
466
index XXXXXXX..XXXXXXX 100755
467
--- a/tests/qemu-iotests/029
468
+++ b/tests/qemu-iotests/029
469
@@ -XXX,XX +XXX,XX @@
470
-#!/bin/bash
471
+#!/usr/bin/env bash
472
#
473
# qcow2 internal snapshots/VM state tests
474
#
475
diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
476
index XXXXXXX..XXXXXXX 100755
477
--- a/tests/qemu-iotests/031
478
+++ b/tests/qemu-iotests/031
479
@@ -XXX,XX +XXX,XX @@
480
-#!/bin/bash
481
+#!/usr/bin/env bash
482
#
483
# Test that all qcow2 header extensions survive a header rewrite
484
#
485
diff --git a/tests/qemu-iotests/032 b/tests/qemu-iotests/032
486
index XXXXXXX..XXXXXXX 100755
487
--- a/tests/qemu-iotests/032
488
+++ b/tests/qemu-iotests/032
489
@@ -XXX,XX +XXX,XX @@
490
-#!/bin/bash
491
+#!/usr/bin/env bash
492
#
493
# Test that AIO requests are drained before an image is closed. This used
494
# to segfault because the request coroutine kept running even after the
495
diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
496
index XXXXXXX..XXXXXXX 100755
497
--- a/tests/qemu-iotests/033
498
+++ b/tests/qemu-iotests/033
499
@@ -XXX,XX +XXX,XX @@
500
-#!/bin/bash
501
+#!/usr/bin/env bash
502
#
503
# Test aligned and misaligned write zeroes operations.
504
#
505
diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034
506
index XXXXXXX..XXXXXXX 100755
507
--- a/tests/qemu-iotests/034
508
+++ b/tests/qemu-iotests/034
509
@@ -XXX,XX +XXX,XX @@
510
-#!/bin/bash
511
+#!/usr/bin/env bash
512
#
513
# Test bdrv_pwrite_zeroes with backing files (see also 154)
514
#
515
diff --git a/tests/qemu-iotests/035 b/tests/qemu-iotests/035
516
index XXXXXXX..XXXXXXX 100755
517
--- a/tests/qemu-iotests/035
518
+++ b/tests/qemu-iotests/035
519
@@ -XXX,XX +XXX,XX @@
520
-#!/bin/bash
521
+#!/usr/bin/env bash
522
#
523
# Let a few AIO requests run in parallel and have them access different L2
524
# tables so that the cache has a chance to get used up.
525
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
526
index XXXXXXX..XXXXXXX 100755
527
--- a/tests/qemu-iotests/036
528
+++ b/tests/qemu-iotests/036
529
@@ -XXX,XX +XXX,XX @@
530
-#!/bin/bash
531
+#!/usr/bin/env bash
532
#
533
# Test qcow2 feature bits
534
#
535
diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037
536
index XXXXXXX..XXXXXXX 100755
537
--- a/tests/qemu-iotests/037
538
+++ b/tests/qemu-iotests/037
539
@@ -XXX,XX +XXX,XX @@
540
-#!/bin/bash
541
+#!/usr/bin/env bash
542
#
543
# Test COW from backing files
544
#
545
diff --git a/tests/qemu-iotests/038 b/tests/qemu-iotests/038
546
index XXXXXXX..XXXXXXX 100755
547
--- a/tests/qemu-iotests/038
548
+++ b/tests/qemu-iotests/038
549
@@ -XXX,XX +XXX,XX @@
550
-#!/bin/bash
551
+#!/usr/bin/env bash
552
#
553
# Test COW from backing files with AIO
554
#
555
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
556
index XXXXXXX..XXXXXXX 100755
557
--- a/tests/qemu-iotests/039
558
+++ b/tests/qemu-iotests/039
559
@@ -XXX,XX +XXX,XX @@
560
-#!/bin/bash
561
+#!/usr/bin/env bash
562
#
563
# Test qcow2 lazy refcounts
564
#
565
diff --git a/tests/qemu-iotests/042 b/tests/qemu-iotests/042
566
index XXXXXXX..XXXXXXX 100755
567
--- a/tests/qemu-iotests/042
568
+++ b/tests/qemu-iotests/042
569
@@ -XXX,XX +XXX,XX @@
570
-#!/bin/bash
571
+#!/usr/bin/env bash
572
#
573
# Test qemu-img operation on zero size images
574
#
575
diff --git a/tests/qemu-iotests/043 b/tests/qemu-iotests/043
576
index XXXXXXX..XXXXXXX 100755
577
--- a/tests/qemu-iotests/043
578
+++ b/tests/qemu-iotests/043
579
@@ -XXX,XX +XXX,XX @@
580
-#!/bin/bash
581
+#!/usr/bin/env bash
582
#
583
# Test that qemu-img info --backing-chain detects infinite loops
584
#
585
diff --git a/tests/qemu-iotests/046 b/tests/qemu-iotests/046
586
index XXXXXXX..XXXXXXX 100755
587
--- a/tests/qemu-iotests/046
588
+++ b/tests/qemu-iotests/046
589
@@ -XXX,XX +XXX,XX @@
590
-#!/bin/bash
591
+#!/usr/bin/env bash
592
#
593
# Test concurrent cluster allocations
594
#
595
diff --git a/tests/qemu-iotests/047 b/tests/qemu-iotests/047
596
index XXXXXXX..XXXXXXX 100755
597
--- a/tests/qemu-iotests/047
598
+++ b/tests/qemu-iotests/047
599
@@ -XXX,XX +XXX,XX @@
600
-#!/bin/bash
601
+#!/usr/bin/env bash
602
#
603
# Regression test for commit b7ab0fea (which was a corruption fix,
604
# despite the commit message claiming otherwise)
605
diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048
606
index XXXXXXX..XXXXXXX 100755
607
--- a/tests/qemu-iotests/048
608
+++ b/tests/qemu-iotests/048
609
@@ -XXX,XX +XXX,XX @@
610
-#!/bin/bash
611
+#!/usr/bin/env bash
612
##
613
## qemu-img compare test
614
##
615
diff --git a/tests/qemu-iotests/049 b/tests/qemu-iotests/049
616
index XXXXXXX..XXXXXXX 100755
617
--- a/tests/qemu-iotests/049
618
+++ b/tests/qemu-iotests/049
619
@@ -XXX,XX +XXX,XX @@
620
-#!/bin/bash
621
+#!/usr/bin/env bash
622
#
623
# Check qemu-img option parsing
624
#
625
diff --git a/tests/qemu-iotests/050 b/tests/qemu-iotests/050
626
index XXXXXXX..XXXXXXX 100755
627
--- a/tests/qemu-iotests/050
628
+++ b/tests/qemu-iotests/050
629
@@ -XXX,XX +XXX,XX @@
630
-#!/bin/bash
631
+#!/usr/bin/env bash
632
#
633
# Test qemu-img rebase with zero clusters
634
#
635
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
636
index XXXXXXX..XXXXXXX 100755
637
--- a/tests/qemu-iotests/051
638
+++ b/tests/qemu-iotests/051
639
@@ -XXX,XX +XXX,XX @@
640
-#!/bin/bash
641
+#!/usr/bin/env bash
642
#
643
# Test command line configuration of block devices and driver-specific options
644
#
645
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
646
index XXXXXXX..XXXXXXX 100755
647
--- a/tests/qemu-iotests/052
648
+++ b/tests/qemu-iotests/052
649
@@ -XXX,XX +XXX,XX @@
650
-#!/bin/bash
651
+#!/usr/bin/env bash
652
#
653
# Test bdrv_read/bdrv_write using BDRV_O_SNAPSHOT
654
#
655
diff --git a/tests/qemu-iotests/053 b/tests/qemu-iotests/053
656
index XXXXXXX..XXXXXXX 100755
657
--- a/tests/qemu-iotests/053
658
+++ b/tests/qemu-iotests/053
659
@@ -XXX,XX +XXX,XX @@
660
-#!/bin/bash
661
+#!/usr/bin/env bash
662
#
663
# Test qemu-img convert when image length is not a multiple of cluster size
664
#
665
diff --git a/tests/qemu-iotests/054 b/tests/qemu-iotests/054
666
index XXXXXXX..XXXXXXX 100755
667
--- a/tests/qemu-iotests/054
668
+++ b/tests/qemu-iotests/054
669
@@ -XXX,XX +XXX,XX @@
670
-#!/bin/bash
671
+#!/usr/bin/env bash
672
#
673
# Test huge qcow2 images
674
#
675
diff --git a/tests/qemu-iotests/058 b/tests/qemu-iotests/058
676
index XXXXXXX..XXXXXXX 100755
677
--- a/tests/qemu-iotests/058
678
+++ b/tests/qemu-iotests/058
679
@@ -XXX,XX +XXX,XX @@
680
-#!/bin/bash
681
+#!/usr/bin/env bash
682
#
683
# Test export internal snapshot by qemu-nbd, convert it by qemu-img.
684
#
685
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
686
index XXXXXXX..XXXXXXX 100755
687
--- a/tests/qemu-iotests/059
688
+++ b/tests/qemu-iotests/059
689
@@ -XXX,XX +XXX,XX @@
690
-#!/bin/bash
691
+#!/usr/bin/env bash
692
#
693
# Test case for vmdk
694
#
695
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
696
index XXXXXXX..XXXXXXX 100755
697
--- a/tests/qemu-iotests/060
698
+++ b/tests/qemu-iotests/060
699
@@ -XXX,XX +XXX,XX @@
700
-#!/bin/bash
701
+#!/usr/bin/env bash
702
#
703
# Test case for image corruption (overlapping data structures) in qcow2
704
#
705
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
706
index XXXXXXX..XXXXXXX 100755
707
--- a/tests/qemu-iotests/061
708
+++ b/tests/qemu-iotests/061
709
@@ -XXX,XX +XXX,XX @@
710
-#!/bin/bash
711
+#!/usr/bin/env bash
712
#
713
# Test case for image option amendment in qcow2.
714
#
715
diff --git a/tests/qemu-iotests/062 b/tests/qemu-iotests/062
716
index XXXXXXX..XXXXXXX 100755
717
--- a/tests/qemu-iotests/062
718
+++ b/tests/qemu-iotests/062
719
@@ -XXX,XX +XXX,XX @@
720
-#!/bin/bash
721
+#!/usr/bin/env bash
722
#
723
# Test case for snapshotting images with unallocated zero clusters in
724
# qcow2
725
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
726
index XXXXXXX..XXXXXXX 100755
727
--- a/tests/qemu-iotests/063
728
+++ b/tests/qemu-iotests/063
729
@@ -XXX,XX +XXX,XX @@
730
-#!/bin/bash
731
+#!/usr/bin/env bash
732
#
733
# test of qemu-img convert -n - convert without creation
734
#
735
diff --git a/tests/qemu-iotests/064 b/tests/qemu-iotests/064
736
index XXXXXXX..XXXXXXX 100755
737
--- a/tests/qemu-iotests/064
738
+++ b/tests/qemu-iotests/064
739
@@ -XXX,XX +XXX,XX @@
740
-#!/bin/bash
741
+#!/usr/bin/env bash
742
#
743
# Test VHDX read/write from a sample image created with Hyper-V
744
#
745
diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066
746
index XXXXXXX..XXXXXXX 100755
747
--- a/tests/qemu-iotests/066
748
+++ b/tests/qemu-iotests/066
749
@@ -XXX,XX +XXX,XX @@
750
-#!/bin/bash
751
+#!/usr/bin/env bash
752
#
753
# Test case for preallocated zero clusters in qcow2
754
#
755
diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067
756
index XXXXXXX..XXXXXXX 100755
757
--- a/tests/qemu-iotests/067
758
+++ b/tests/qemu-iotests/067
759
@@ -XXX,XX +XXX,XX @@
760
-#!/bin/bash
761
+#!/usr/bin/env bash
762
#
763
# Test automatic deletion of BDSes created by -drive/drive_add
764
#
765
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
766
index XXXXXXX..XXXXXXX 100755
767
--- a/tests/qemu-iotests/068
768
+++ b/tests/qemu-iotests/068
769
@@ -XXX,XX +XXX,XX @@
770
-#!/bin/bash
771
+#!/usr/bin/env bash
772
#
773
# Test case for loading a saved VM state from a qcow2 image
774
#
775
diff --git a/tests/qemu-iotests/069 b/tests/qemu-iotests/069
776
index XXXXXXX..XXXXXXX 100755
777
--- a/tests/qemu-iotests/069
778
+++ b/tests/qemu-iotests/069
779
@@ -XXX,XX +XXX,XX @@
780
-#!/bin/bash
781
+#!/usr/bin/env bash
782
#
783
# Test case for deleting a backing file
784
#
785
diff --git a/tests/qemu-iotests/070 b/tests/qemu-iotests/070
786
index XXXXXXX..XXXXXXX 100755
787
--- a/tests/qemu-iotests/070
788
+++ b/tests/qemu-iotests/070
789
@@ -XXX,XX +XXX,XX @@
790
-#!/bin/bash
791
+#!/usr/bin/env bash
792
#
793
# Test VHDX log replay from an image with a journal that needs to be
794
# replayed
795
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
796
index XXXXXXX..XXXXXXX 100755
797
--- a/tests/qemu-iotests/071
798
+++ b/tests/qemu-iotests/071
799
@@ -XXX,XX +XXX,XX @@
800
-#!/bin/bash
801
+#!/usr/bin/env bash
802
#
803
# Test case for the QMP blkdebug and blkverify interfaces
804
#
805
diff --git a/tests/qemu-iotests/072 b/tests/qemu-iotests/072
806
index XXXXXXX..XXXXXXX 100755
807
--- a/tests/qemu-iotests/072
808
+++ b/tests/qemu-iotests/072
809
@@ -XXX,XX +XXX,XX @@
810
-#!/bin/bash
811
+#!/usr/bin/env bash
812
#
813
# Test case for nested image formats
814
#
815
diff --git a/tests/qemu-iotests/073 b/tests/qemu-iotests/073
816
index XXXXXXX..XXXXXXX 100755
817
--- a/tests/qemu-iotests/073
818
+++ b/tests/qemu-iotests/073
819
@@ -XXX,XX +XXX,XX @@
820
-#!/bin/bash
821
+#!/usr/bin/env bash
822
#
823
# Test count_contiguous_clusters in qcow2
824
#
825
diff --git a/tests/qemu-iotests/074 b/tests/qemu-iotests/074
826
index XXXXXXX..XXXXXXX 100755
827
--- a/tests/qemu-iotests/074
828
+++ b/tests/qemu-iotests/074
829
@@ -XXX,XX +XXX,XX @@
830
-#!/bin/bash
831
+#!/usr/bin/env bash
832
##
833
## qemu-img compare test (qcow2 only ones)
834
##
835
diff --git a/tests/qemu-iotests/075 b/tests/qemu-iotests/075
836
index XXXXXXX..XXXXXXX 100755
837
--- a/tests/qemu-iotests/075
838
+++ b/tests/qemu-iotests/075
839
@@ -XXX,XX +XXX,XX @@
840
-#!/bin/bash
841
+#!/usr/bin/env bash
842
#
843
# cloop format input validation tests
844
#
845
diff --git a/tests/qemu-iotests/076 b/tests/qemu-iotests/076
846
index XXXXXXX..XXXXXXX 100755
847
--- a/tests/qemu-iotests/076
848
+++ b/tests/qemu-iotests/076
849
@@ -XXX,XX +XXX,XX @@
850
-#!/bin/bash
851
+#!/usr/bin/env bash
852
#
853
# parallels format input validation tests
854
#
855
diff --git a/tests/qemu-iotests/077 b/tests/qemu-iotests/077
856
index XXXXXXX..XXXXXXX 100755
857
--- a/tests/qemu-iotests/077
858
+++ b/tests/qemu-iotests/077
859
@@ -XXX,XX +XXX,XX @@
860
-#!/bin/bash
861
+#!/usr/bin/env bash
862
#
863
# Test concurrent pread/pwrite
864
#
865
diff --git a/tests/qemu-iotests/078 b/tests/qemu-iotests/078
866
index XXXXXXX..XXXXXXX 100755
867
--- a/tests/qemu-iotests/078
868
+++ b/tests/qemu-iotests/078
869
@@ -XXX,XX +XXX,XX @@
870
-#!/bin/bash
871
+#!/usr/bin/env bash
872
#
873
# bochs format input validation tests
874
#
875
diff --git a/tests/qemu-iotests/079 b/tests/qemu-iotests/079
876
index XXXXXXX..XXXXXXX 100755
877
--- a/tests/qemu-iotests/079
878
+++ b/tests/qemu-iotests/079
879
@@ -XXX,XX +XXX,XX @@
880
-#!/bin/bash
881
+#!/usr/bin/env bash
882
#
883
# Test qcow2 preallocation with different cluster_sizes
884
#
885
diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080
886
index XXXXXXX..XXXXXXX 100755
887
--- a/tests/qemu-iotests/080
888
+++ b/tests/qemu-iotests/080
889
@@ -XXX,XX +XXX,XX @@
890
-#!/bin/bash
891
+#!/usr/bin/env bash
892
#
893
# qcow2 format input validation tests
894
#
895
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
896
index XXXXXXX..XXXXXXX 100755
897
--- a/tests/qemu-iotests/081
898
+++ b/tests/qemu-iotests/081
899
@@ -XXX,XX +XXX,XX @@
900
-#!/bin/bash
901
+#!/usr/bin/env bash
902
#
903
# Test Quorum block driver
904
#
905
diff --git a/tests/qemu-iotests/082 b/tests/qemu-iotests/082
906
index XXXXXXX..XXXXXXX 100755
907
--- a/tests/qemu-iotests/082
908
+++ b/tests/qemu-iotests/082
909
@@ -XXX,XX +XXX,XX @@
910
-#!/bin/bash
911
+#!/usr/bin/env bash
912
#
913
# Test qemu-img command line parsing
914
#
915
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
916
index XXXXXXX..XXXXXXX 100755
917
--- a/tests/qemu-iotests/083
918
+++ b/tests/qemu-iotests/083
919
@@ -XXX,XX +XXX,XX @@
920
-#!/bin/bash
921
+#!/usr/bin/env bash
922
#
923
# Test NBD client unexpected disconnect
924
#
925
diff --git a/tests/qemu-iotests/084 b/tests/qemu-iotests/084
926
index XXXXXXX..XXXXXXX 100755
927
--- a/tests/qemu-iotests/084
928
+++ b/tests/qemu-iotests/084
929
@@ -XXX,XX +XXX,XX @@
930
-#!/bin/bash
931
+#!/usr/bin/env bash
932
#
933
# Test case for VDI header corruption; image too large, and too many blocks.
934
# Also simple test for creating dynamic and static VDI images.
935
diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085
936
index XXXXXXX..XXXXXXX 100755
937
--- a/tests/qemu-iotests/085
938
+++ b/tests/qemu-iotests/085
939
@@ -XXX,XX +XXX,XX @@
940
-#!/bin/bash
941
+#!/usr/bin/env bash
942
#
943
# Live snapshot tests
944
#
945
diff --git a/tests/qemu-iotests/086 b/tests/qemu-iotests/086
946
index XXXXXXX..XXXXXXX 100755
947
--- a/tests/qemu-iotests/086
948
+++ b/tests/qemu-iotests/086
949
@@ -XXX,XX +XXX,XX @@
950
-#!/bin/bash
951
+#!/usr/bin/env bash
952
#
953
# Test qemu-img progress output
954
#
955
diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087
956
index XXXXXXX..XXXXXXX 100755
957
--- a/tests/qemu-iotests/087
958
+++ b/tests/qemu-iotests/087
959
@@ -XXX,XX +XXX,XX @@
960
-#!/bin/bash
961
+#!/usr/bin/env bash
962
#
963
# Test unsupported blockdev-add cases
964
#
965
diff --git a/tests/qemu-iotests/088 b/tests/qemu-iotests/088
966
index XXXXXXX..XXXXXXX 100755
967
--- a/tests/qemu-iotests/088
968
+++ b/tests/qemu-iotests/088
969
@@ -XXX,XX +XXX,XX @@
970
-#!/bin/bash
971
+#!/usr/bin/env bash
972
#
973
# vpc (VHD) format input validation tests
974
#
975
diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089
976
index XXXXXXX..XXXXXXX 100755
977
--- a/tests/qemu-iotests/089
978
+++ b/tests/qemu-iotests/089
979
@@ -XXX,XX +XXX,XX @@
980
-#!/bin/bash
981
+#!/usr/bin/env bash
982
#
983
# Test case for support of JSON filenames
984
#
985
diff --git a/tests/qemu-iotests/090 b/tests/qemu-iotests/090
986
index XXXXXXX..XXXXXXX 100755
987
--- a/tests/qemu-iotests/090
988
+++ b/tests/qemu-iotests/090
989
@@ -XXX,XX +XXX,XX @@
990
-#!/bin/bash
991
+#!/usr/bin/env bash
992
#
993
# Test for discarding compressed clusters on qcow2 images
994
#
995
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
996
index XXXXXXX..XXXXXXX 100755
997
--- a/tests/qemu-iotests/091
998
+++ b/tests/qemu-iotests/091
999
@@ -XXX,XX +XXX,XX @@
1000
-#!/bin/bash
1001
+#!/usr/bin/env bash
1002
#
1003
# Live migration test
1004
#
1005
diff --git a/tests/qemu-iotests/092 b/tests/qemu-iotests/092
1006
index XXXXXXX..XXXXXXX 100755
1007
--- a/tests/qemu-iotests/092
1008
+++ b/tests/qemu-iotests/092
1009
@@ -XXX,XX +XXX,XX @@
1010
-#!/bin/bash
1011
+#!/usr/bin/env bash
1012
#
1013
# qcow1 format input validation tests
1014
#
1015
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
1016
index XXXXXXX..XXXXXXX 100755
1017
--- a/tests/qemu-iotests/094
1018
+++ b/tests/qemu-iotests/094
1019
@@ -XXX,XX +XXX,XX @@
1020
-#!/bin/bash
1021
+#!/usr/bin/env bash
1022
#
1023
# Test case for drive-mirror to NBD
1024
#
1025
diff --git a/tests/qemu-iotests/095 b/tests/qemu-iotests/095
1026
index XXXXXXX..XXXXXXX 100755
1027
--- a/tests/qemu-iotests/095
1028
+++ b/tests/qemu-iotests/095
1029
@@ -XXX,XX +XXX,XX @@
1030
-#!/bin/bash
1031
+#!/usr/bin/env bash
1032
#
1033
# Test for commit of larger active layer
1034
#
1035
diff --git a/tests/qemu-iotests/097 b/tests/qemu-iotests/097
1036
index XXXXXXX..XXXXXXX 100755
1037
--- a/tests/qemu-iotests/097
1038
+++ b/tests/qemu-iotests/097
1039
@@ -XXX,XX +XXX,XX @@
1040
-#!/bin/bash
1041
+#!/usr/bin/env bash
1042
#
1043
# Commit changes into backing chains and empty the top image if the
1044
# backing image is not explicitly specified
1045
diff --git a/tests/qemu-iotests/098 b/tests/qemu-iotests/098
1046
index XXXXXXX..XXXXXXX 100755
1047
--- a/tests/qemu-iotests/098
1048
+++ b/tests/qemu-iotests/098
1049
@@ -XXX,XX +XXX,XX @@
1050
-#!/bin/bash
1051
+#!/usr/bin/env bash
1052
#
1053
# Test qcow2's bdrv_make_empty for images without internal snapshots
1054
#
1055
diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099
1056
index XXXXXXX..XXXXXXX 100755
1057
--- a/tests/qemu-iotests/099
1058
+++ b/tests/qemu-iotests/099
1059
@@ -XXX,XX +XXX,XX @@
1060
-#!/bin/bash
1061
+#!/usr/bin/env bash
1062
#
1063
# Test valid filenames for blkdebug and blkverify representatively for
1064
# other protocols (such as NBD) when queried
1065
diff --git a/tests/qemu-iotests/101 b/tests/qemu-iotests/101
1066
index XXXXXXX..XXXXXXX 100755
1067
--- a/tests/qemu-iotests/101
1068
+++ b/tests/qemu-iotests/101
1069
@@ -XXX,XX +XXX,XX @@
1070
-#!/bin/bash
1071
+#!/usr/bin/env bash
1072
#
1073
# Test short file I/O
1074
#
1075
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
1076
index XXXXXXX..XXXXXXX 100755
1077
--- a/tests/qemu-iotests/102
1078
+++ b/tests/qemu-iotests/102
1079
@@ -XXX,XX +XXX,XX @@
1080
-#!/bin/bash
1081
+#!/usr/bin/env bash
1082
#
1083
# Test case for qemu-io -c map and qemu-img map
1084
#
1085
diff --git a/tests/qemu-iotests/103 b/tests/qemu-iotests/103
1086
index XXXXXXX..XXXXXXX 100755
1087
--- a/tests/qemu-iotests/103
1088
+++ b/tests/qemu-iotests/103
1089
@@ -XXX,XX +XXX,XX @@
1090
-#!/bin/bash
1091
+#!/usr/bin/env bash
1092
#
1093
# Test case for qcow2 metadata cache size specification
1094
#
1095
diff --git a/tests/qemu-iotests/104 b/tests/qemu-iotests/104
1096
index XXXXXXX..XXXXXXX 100755
1097
--- a/tests/qemu-iotests/104
1098
+++ b/tests/qemu-iotests/104
1099
@@ -XXX,XX +XXX,XX @@
1100
-#!/bin/bash
1101
+#!/usr/bin/env bash
1102
#
1103
# Test image creation with aligned and unaligned sizes
1104
#
1105
diff --git a/tests/qemu-iotests/105 b/tests/qemu-iotests/105
1106
index XXXXXXX..XXXXXXX 100755
1107
--- a/tests/qemu-iotests/105
1108
+++ b/tests/qemu-iotests/105
1109
@@ -XXX,XX +XXX,XX @@
1110
-#!/bin/bash
1111
+#!/usr/bin/env bash
1112
#
1113
# Create, read, write big image
1114
#
1115
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
1116
index XXXXXXX..XXXXXXX 100755
1117
--- a/tests/qemu-iotests/106
1118
+++ b/tests/qemu-iotests/106
1119
@@ -XXX,XX +XXX,XX @@
1120
-#!/bin/bash
1121
+#!/usr/bin/env bash
1122
#
1123
# Test preallocated resize of raw images
1124
#
1125
diff --git a/tests/qemu-iotests/107 b/tests/qemu-iotests/107
1126
index XXXXXXX..XXXXXXX 100755
1127
--- a/tests/qemu-iotests/107
1128
+++ b/tests/qemu-iotests/107
1129
@@ -XXX,XX +XXX,XX @@
1130
-#!/bin/bash
1131
+#!/usr/bin/env bash
1132
#
1133
# Tests updates of the qcow2 L1 table
1134
#
1135
diff --git a/tests/qemu-iotests/108 b/tests/qemu-iotests/108
1136
index XXXXXXX..XXXXXXX 100755
1137
--- a/tests/qemu-iotests/108
1138
+++ b/tests/qemu-iotests/108
1139
@@ -XXX,XX +XXX,XX @@
1140
-#!/bin/bash
1141
+#!/usr/bin/env bash
1142
#
1143
# Test case for repairing qcow2 images which cannot be repaired using
1144
# the on-disk refcount structures
1145
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
1146
index XXXXXXX..XXXXXXX 100755
1147
--- a/tests/qemu-iotests/109
1148
+++ b/tests/qemu-iotests/109
1149
@@ -XXX,XX +XXX,XX @@
1150
-#!/bin/bash
1151
+#!/usr/bin/env bash
1152
#
1153
# Test writing image headers of other formats into raw images
1154
#
1155
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
1156
index XXXXXXX..XXXXXXX 100755
1157
--- a/tests/qemu-iotests/110
1158
+++ b/tests/qemu-iotests/110
1159
@@ -XXX,XX +XXX,XX @@
1160
-#!/bin/bash
1161
+#!/usr/bin/env bash
1162
#
1163
# Test case for relative backing file names in complex BDS trees
1164
#
1165
diff --git a/tests/qemu-iotests/111 b/tests/qemu-iotests/111
1166
index XXXXXXX..XXXXXXX 100755
1167
--- a/tests/qemu-iotests/111
1168
+++ b/tests/qemu-iotests/111
1169
@@ -XXX,XX +XXX,XX @@
1170
-#!/bin/bash
1171
+#!/usr/bin/env bash
1172
#
1173
# Test case for non-existing backing file when creating a qcow2 image
1174
# and not specifying the size
1175
diff --git a/tests/qemu-iotests/112 b/tests/qemu-iotests/112
1176
index XXXXXXX..XXXXXXX 100755
1177
--- a/tests/qemu-iotests/112
1178
+++ b/tests/qemu-iotests/112
1179
@@ -XXX,XX +XXX,XX @@
1180
-#!/bin/bash
1181
+#!/usr/bin/env bash
1182
#
1183
# Test cases for different refcount_bits values
1184
#
1185
diff --git a/tests/qemu-iotests/113 b/tests/qemu-iotests/113
1186
index XXXXXXX..XXXXXXX 100755
1187
--- a/tests/qemu-iotests/113
1188
+++ b/tests/qemu-iotests/113
1189
@@ -XXX,XX +XXX,XX @@
1190
-#!/bin/bash
1191
+#!/usr/bin/env bash
1192
#
1193
# Test case for accessing creation options on image formats and
1194
# protocols not supporting image creation
1195
diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114
1196
index XXXXXXX..XXXXXXX 100755
1197
--- a/tests/qemu-iotests/114
1198
+++ b/tests/qemu-iotests/114
1199
@@ -XXX,XX +XXX,XX @@
1200
-#!/bin/bash
1201
+#!/usr/bin/env bash
1202
#
1203
# Test invalid backing file format in qcow2 images
1204
#
1205
diff --git a/tests/qemu-iotests/115 b/tests/qemu-iotests/115
1206
index XXXXXXX..XXXXXXX 100755
1207
--- a/tests/qemu-iotests/115
1208
+++ b/tests/qemu-iotests/115
1209
@@ -XXX,XX +XXX,XX @@
1210
-#!/bin/bash
1211
+#!/usr/bin/env bash
1212
#
1213
# Test case for non-self-referential qcow2 refcount blocks
1214
#
1215
diff --git a/tests/qemu-iotests/116 b/tests/qemu-iotests/116
1216
index XXXXXXX..XXXXXXX 100755
1217
--- a/tests/qemu-iotests/116
1218
+++ b/tests/qemu-iotests/116
1219
@@ -XXX,XX +XXX,XX @@
1220
-#!/bin/bash
1221
+#!/usr/bin/env bash
1222
#
1223
# Test error code paths for invalid QED images
1224
#
1225
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
1226
index XXXXXXX..XXXXXXX 100755
1227
--- a/tests/qemu-iotests/117
1228
+++ b/tests/qemu-iotests/117
1229
@@ -XXX,XX +XXX,XX @@
1230
-#!/bin/bash
1231
+#!/usr/bin/env bash
1232
#
1233
# Test case for shared BDS between backend trees
1234
#
1235
diff --git a/tests/qemu-iotests/119 b/tests/qemu-iotests/119
1236
index XXXXXXX..XXXXXXX 100755
1237
--- a/tests/qemu-iotests/119
1238
+++ b/tests/qemu-iotests/119
1239
@@ -XXX,XX +XXX,XX @@
1240
-#!/bin/bash
1241
+#!/usr/bin/env bash
1242
#
1243
# NBD test case for overriding BDRV_O_PROTOCOL by explicitly specifying
1244
# a driver
1245
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
1246
index XXXXXXX..XXXXXXX 100755
1247
--- a/tests/qemu-iotests/120
1248
+++ b/tests/qemu-iotests/120
1249
@@ -XXX,XX +XXX,XX @@
1250
-#!/bin/bash
1251
+#!/usr/bin/env bash
1252
#
1253
# Non-NBD test cases for overriding BDRV_O_PROTOCOL by explicitly
1254
# specifying a driver
1255
diff --git a/tests/qemu-iotests/121 b/tests/qemu-iotests/121
1256
index XXXXXXX..XXXXXXX 100755
1257
--- a/tests/qemu-iotests/121
1258
+++ b/tests/qemu-iotests/121
1259
@@ -XXX,XX +XXX,XX @@
1260
-#!/bin/bash
1261
+#!/usr/bin/env bash
1262
#
1263
# Test cases for qcow2 refcount table growth
1264
#
1265
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
1266
index XXXXXXX..XXXXXXX 100755
1267
--- a/tests/qemu-iotests/122
1268
+++ b/tests/qemu-iotests/122
1269
@@ -XXX,XX +XXX,XX @@
1270
-#!/bin/bash
1271
+#!/usr/bin/env bash
1272
#
1273
# Test some qemu-img convert cases
1274
#
1275
diff --git a/tests/qemu-iotests/123 b/tests/qemu-iotests/123
1276
index XXXXXXX..XXXXXXX 100755
1277
--- a/tests/qemu-iotests/123
1278
+++ b/tests/qemu-iotests/123
1279
@@ -XXX,XX +XXX,XX @@
1280
-#!/bin/bash
1281
+#!/usr/bin/env bash
1282
#
1283
# Test case for qemu-img convert to NBD
1284
#
1285
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
1286
index XXXXXXX..XXXXXXX 100755
1287
--- a/tests/qemu-iotests/125
1288
+++ b/tests/qemu-iotests/125
1289
@@ -XXX,XX +XXX,XX @@
1290
-#!/bin/bash
1291
+#!/usr/bin/env bash
1292
#
1293
# Test preallocated growth of qcow2 images
1294
#
1295
diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
1296
index XXXXXXX..XXXXXXX 100755
1297
--- a/tests/qemu-iotests/126
1298
+++ b/tests/qemu-iotests/126
1299
@@ -XXX,XX +XXX,XX @@
1300
-#!/bin/bash
1301
+#!/usr/bin/env bash
1302
#
1303
# Tests handling of colons in filenames (which may be confused with protocol
1304
# prefixes)
1305
diff --git a/tests/qemu-iotests/127 b/tests/qemu-iotests/127
1306
index XXXXXXX..XXXXXXX 100755
1307
--- a/tests/qemu-iotests/127
1308
+++ b/tests/qemu-iotests/127
1309
@@ -XXX,XX +XXX,XX @@
1310
-#!/bin/bash
1311
+#!/usr/bin/env bash
1312
#
1313
# Test case for mirroring with dataplane
1314
#
1315
diff --git a/tests/qemu-iotests/128 b/tests/qemu-iotests/128
1316
index XXXXXXX..XXXXXXX 100755
1317
--- a/tests/qemu-iotests/128
1318
+++ b/tests/qemu-iotests/128
1319
@@ -XXX,XX +XXX,XX @@
1320
-#!/bin/bash
1321
+#!/usr/bin/env bash
1322
#
1323
# Test that opening O_DIRECT succeeds when image file I/O produces EIO
1324
#
1325
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
1326
index XXXXXXX..XXXXXXX 100755
1327
--- a/tests/qemu-iotests/130
1328
+++ b/tests/qemu-iotests/130
1329
@@ -XXX,XX +XXX,XX @@
1330
-#!/bin/bash
1331
+#!/usr/bin/env bash
1332
#
1333
# Test that temporary backing file overrides (on the command line or in
1334
# blockdev-add) don't replace the original path stored in the image during
1335
diff --git a/tests/qemu-iotests/131 b/tests/qemu-iotests/131
1336
index XXXXXXX..XXXXXXX 100755
1337
--- a/tests/qemu-iotests/131
1338
+++ b/tests/qemu-iotests/131
1339
@@ -XXX,XX +XXX,XX @@
1340
-#!/bin/bash
1341
+#!/usr/bin/env bash
1342
#
1343
# parallels format validation tests (created by QEMU)
1344
#
1345
diff --git a/tests/qemu-iotests/133 b/tests/qemu-iotests/133
1346
index XXXXXXX..XXXXXXX 100755
1347
--- a/tests/qemu-iotests/133
1348
+++ b/tests/qemu-iotests/133
1349
@@ -XXX,XX +XXX,XX @@
1350
-#!/bin/bash
1351
+#!/usr/bin/env bash
1352
#
1353
# Test for reopen
1354
#
1355
diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134
1356
index XXXXXXX..XXXXXXX 100755
1357
--- a/tests/qemu-iotests/134
1358
+++ b/tests/qemu-iotests/134
1359
@@ -XXX,XX +XXX,XX @@
1360
-#!/bin/bash
1361
+#!/usr/bin/env bash
1362
#
1363
# Test encrypted read/write using plain bdrv_read/bdrv_write
1364
#
1365
diff --git a/tests/qemu-iotests/135 b/tests/qemu-iotests/135
1366
index XXXXXXX..XXXXXXX 100755
1367
--- a/tests/qemu-iotests/135
1368
+++ b/tests/qemu-iotests/135
1369
@@ -XXX,XX +XXX,XX @@
1370
-#!/bin/bash
1371
+#!/usr/bin/env bash
1372
#
1373
# Test VPC open of image with large Max Table Entries value.
1374
#
1375
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
1376
index XXXXXXX..XXXXXXX 100755
1377
--- a/tests/qemu-iotests/137
1378
+++ b/tests/qemu-iotests/137
1379
@@ -XXX,XX +XXX,XX @@
1380
-#!/bin/bash
1381
+#!/usr/bin/env bash
1382
#
1383
# Test qcow2 reopen
1384
#
1385
diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138
1386
index XXXXXXX..XXXXXXX 100755
1387
--- a/tests/qemu-iotests/138
1388
+++ b/tests/qemu-iotests/138
1389
@@ -XXX,XX +XXX,XX @@
1390
-#!/bin/bash
1391
+#!/usr/bin/env bash
1392
#
1393
# General test case for qcow2's image check
1394
#
1395
diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140
1396
index XXXXXXX..XXXXXXX 100755
1397
--- a/tests/qemu-iotests/140
1398
+++ b/tests/qemu-iotests/140
1399
@@ -XXX,XX +XXX,XX @@
1400
-#!/bin/bash
1401
+#!/usr/bin/env bash
1402
#
1403
# Test case for ejecting a BlockBackend with an NBD server attached to it
1404
#
1405
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
1406
index XXXXXXX..XXXXXXX 100755
1407
--- a/tests/qemu-iotests/141
1408
+++ b/tests/qemu-iotests/141
1409
@@ -XXX,XX +XXX,XX @@
1410
-#!/bin/bash
1411
+#!/usr/bin/env bash
1412
#
1413
# Test case for ejecting BDSs with block jobs still running on them
1414
#
1415
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
1416
index XXXXXXX..XXXXXXX 100755
1417
--- a/tests/qemu-iotests/142
1418
+++ b/tests/qemu-iotests/142
1419
@@ -XXX,XX +XXX,XX @@
1420
-#!/bin/bash
1421
+#!/usr/bin/env bash
1422
#
1423
# Test for configuring cache modes of arbitrary nodes (requires O_DIRECT)
1424
#
1425
diff --git a/tests/qemu-iotests/143 b/tests/qemu-iotests/143
1426
index XXXXXXX..XXXXXXX 100755
1427
--- a/tests/qemu-iotests/143
1428
+++ b/tests/qemu-iotests/143
1429
@@ -XXX,XX +XXX,XX @@
1430
-#!/bin/bash
1431
+#!/usr/bin/env bash
1432
#
1433
# Test case for connecting to a non-existing NBD export name
1434
#
1435
diff --git a/tests/qemu-iotests/144 b/tests/qemu-iotests/144
1436
index XXXXXXX..XXXXXXX 100755
1437
--- a/tests/qemu-iotests/144
1438
+++ b/tests/qemu-iotests/144
1439
@@ -XXX,XX +XXX,XX @@
1440
-#!/bin/bash
1441
+#!/usr/bin/env bash
1442
# Check live snapshot, followed by active commit, and another snapshot.
1443
#
1444
# This test is to catch the error case of BZ #1300209:
1445
diff --git a/tests/qemu-iotests/145 b/tests/qemu-iotests/145
1446
index XXXXXXX..XXXXXXX 100755
1447
--- a/tests/qemu-iotests/145
1448
+++ b/tests/qemu-iotests/145
1449
@@ -XXX,XX +XXX,XX @@
1450
-#!/bin/bash
1451
+#!/usr/bin/env bash
1452
#
1453
# Test the combination of -incoming and snapshot=on
1454
#
1455
diff --git a/tests/qemu-iotests/146 b/tests/qemu-iotests/146
1456
index XXXXXXX..XXXXXXX 100755
1457
--- a/tests/qemu-iotests/146
1458
+++ b/tests/qemu-iotests/146
1459
@@ -XXX,XX +XXX,XX @@
1460
-#!/bin/bash
1461
+#!/usr/bin/env bash
1462
#
1463
# Test VHD image format creator detection and override
1464
#
1465
diff --git a/tests/qemu-iotests/150 b/tests/qemu-iotests/150
1466
index XXXXXXX..XXXXXXX 100755
1467
--- a/tests/qemu-iotests/150
1468
+++ b/tests/qemu-iotests/150
1469
@@ -XXX,XX +XXX,XX @@
1470
-#!/bin/bash
1471
+#!/usr/bin/env bash
1472
#
1473
# Test that qemu-img convert -S 0 fully allocates the target image
1474
#
1475
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
1476
index XXXXXXX..XXXXXXX 100755
1477
--- a/tests/qemu-iotests/153
1478
+++ b/tests/qemu-iotests/153
1479
@@ -XXX,XX +XXX,XX @@
1480
-#!/bin/bash
1481
+#!/usr/bin/env bash
1482
#
1483
# Test image locking
1484
#
1485
diff --git a/tests/qemu-iotests/154 b/tests/qemu-iotests/154
1486
index XXXXXXX..XXXXXXX 100755
1487
--- a/tests/qemu-iotests/154
1488
+++ b/tests/qemu-iotests/154
1489
@@ -XXX,XX +XXX,XX @@
1490
-#!/bin/bash
1491
+#!/usr/bin/env bash
1492
#
1493
# qcow2 specific bdrv_pwrite_zeroes tests with backing files (complements 034)
1494
#
1495
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
1496
index XXXXXXX..XXXXXXX 100755
1497
--- a/tests/qemu-iotests/156
1498
+++ b/tests/qemu-iotests/156
1499
@@ -XXX,XX +XXX,XX @@
1500
-#!/bin/bash
1501
+#!/usr/bin/env bash
1502
#
1503
# Tests oVirt-like storage migration:
1504
# - Create snapshot
1505
diff --git a/tests/qemu-iotests/157 b/tests/qemu-iotests/157
1506
index XXXXXXX..XXXXXXX 100755
1507
--- a/tests/qemu-iotests/157
1508
+++ b/tests/qemu-iotests/157
1509
@@ -XXX,XX +XXX,XX @@
1510
-#!/bin/bash
1511
+#!/usr/bin/env bash
1512
#
1513
# Test command line configuration of block devices with qdev
1514
#
1515
diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158
1516
index XXXXXXX..XXXXXXX 100755
1517
--- a/tests/qemu-iotests/158
1518
+++ b/tests/qemu-iotests/158
1519
@@ -XXX,XX +XXX,XX @@
1520
-#!/bin/bash
1521
+#!/usr/bin/env bash
1522
#
1523
# Test encrypted read/write using backing files
1524
#
1525
diff --git a/tests/qemu-iotests/159 b/tests/qemu-iotests/159
1526
index XXXXXXX..XXXXXXX 100755
1527
--- a/tests/qemu-iotests/159
1528
+++ b/tests/qemu-iotests/159
1529
@@ -XXX,XX +XXX,XX @@
1530
-#! /bin/bash
1531
+#!/usr/bin/env bash
1532
#
1533
# qemu-img dd test with different block sizes
1534
#
1535
diff --git a/tests/qemu-iotests/160 b/tests/qemu-iotests/160
1536
index XXXXXXX..XXXXXXX 100755
1537
--- a/tests/qemu-iotests/160
1538
+++ b/tests/qemu-iotests/160
1539
@@ -XXX,XX +XXX,XX @@
1540
-#! /bin/bash
1541
+#!/usr/bin/env bash
1542
#
1543
# qemu-img dd test for the skip option
1544
#
1545
diff --git a/tests/qemu-iotests/161 b/tests/qemu-iotests/161
1546
index XXXXXXX..XXXXXXX 100755
1547
--- a/tests/qemu-iotests/161
1548
+++ b/tests/qemu-iotests/161
1549
@@ -XXX,XX +XXX,XX @@
1550
-#!/bin/bash
1551
+#!/usr/bin/env bash
1552
#
1553
# Test reopening a backing image after block-stream and block-commit
1554
#
1555
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
1556
index XXXXXXX..XXXXXXX 100755
1557
--- a/tests/qemu-iotests/162
1558
+++ b/tests/qemu-iotests/162
1559
@@ -XXX,XX +XXX,XX @@
1560
-#!/bin/bash
1561
+#!/usr/bin/env bash
1562
#
1563
# Test case for specifying runtime options of the wrong type to some
1564
# block drivers
1565
diff --git a/tests/qemu-iotests/170 b/tests/qemu-iotests/170
1566
index XXXXXXX..XXXXXXX 100755
1567
--- a/tests/qemu-iotests/170
1568
+++ b/tests/qemu-iotests/170
1569
@@ -XXX,XX +XXX,XX @@
1570
-#! /bin/bash
1571
+#!/usr/bin/env bash
1572
#
1573
# qemu-img dd test
1574
#
1575
diff --git a/tests/qemu-iotests/171 b/tests/qemu-iotests/171
1576
index XXXXXXX..XXXXXXX 100755
1577
--- a/tests/qemu-iotests/171
1578
+++ b/tests/qemu-iotests/171
1579
@@ -XXX,XX +XXX,XX @@
1580
-#!/bin/bash
1581
+#!/usr/bin/env bash
1582
#
1583
# Test 'offset' and 'size' options of the raw driver. Make sure we can't
1584
# (or can) read and write outside of the image size.
1585
diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
1586
index XXXXXXX..XXXXXXX 100755
1587
--- a/tests/qemu-iotests/172
1588
+++ b/tests/qemu-iotests/172
1589
@@ -XXX,XX +XXX,XX @@
1590
-#!/bin/bash
1591
+#!/usr/bin/env bash
1592
#
1593
# Test floppy configuration
1594
#
1595
diff --git a/tests/qemu-iotests/173 b/tests/qemu-iotests/173
1596
index XXXXXXX..XXXXXXX 100755
1597
--- a/tests/qemu-iotests/173
1598
+++ b/tests/qemu-iotests/173
1599
@@ -XXX,XX +XXX,XX @@
1600
-#!/bin/bash
1601
+#!/usr/bin/env bash
1602
#
1603
# Test QAPI commands looking up protocol based images with relative
1604
# filename backing strings
1605
diff --git a/tests/qemu-iotests/174 b/tests/qemu-iotests/174
1606
index XXXXXXX..XXXXXXX 100755
1607
--- a/tests/qemu-iotests/174
1608
+++ b/tests/qemu-iotests/174
1609
@@ -XXX,XX +XXX,XX @@
1610
-#!/bin/bash
1611
+#!/usr/bin/env bash
1612
#
1613
# Test that qemu-io fail with non-zero exit code
1614
#
1615
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
1616
index XXXXXXX..XXXXXXX 100755
1617
--- a/tests/qemu-iotests/175
1618
+++ b/tests/qemu-iotests/175
1619
@@ -XXX,XX +XXX,XX @@
1620
-#!/bin/bash
1621
+#!/usr/bin/env bash
1622
#
1623
# Test creating raw image preallocation mode
1624
#
1625
diff --git a/tests/qemu-iotests/176 b/tests/qemu-iotests/176
1626
index XXXXXXX..XXXXXXX 100755
1627
--- a/tests/qemu-iotests/176
1628
+++ b/tests/qemu-iotests/176
1629
@@ -XXX,XX +XXX,XX @@
1630
-#!/bin/bash
1631
+#!/usr/bin/env bash
1632
#
1633
# Commit changes into backing chains and empty the top image if the
1634
# backing image is not explicitly specified.
1635
diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177
1636
index XXXXXXX..XXXXXXX 100755
1637
--- a/tests/qemu-iotests/177
1638
+++ b/tests/qemu-iotests/177
1639
@@ -XXX,XX +XXX,XX @@
1640
-#!/bin/bash
1641
+#!/usr/bin/env bash
1642
#
1643
# Test corner cases with unusual block geometries
1644
#
1645
diff --git a/tests/qemu-iotests/178 b/tests/qemu-iotests/178
1646
index XXXXXXX..XXXXXXX 100755
1647
--- a/tests/qemu-iotests/178
1648
+++ b/tests/qemu-iotests/178
1649
@@ -XXX,XX +XXX,XX @@
1650
-#!/bin/bash
1651
+#!/usr/bin/env bash
1652
#
1653
# qemu-img measure sub-command tests
1654
#
1655
diff --git a/tests/qemu-iotests/179 b/tests/qemu-iotests/179
1656
index XXXXXXX..XXXXXXX 100755
1657
--- a/tests/qemu-iotests/179
1658
+++ b/tests/qemu-iotests/179
1659
@@ -XXX,XX +XXX,XX @@
1660
-#!/bin/bash
1661
+#!/usr/bin/env bash
1662
#
1663
# Test case for write zeroes with unmap
1664
#
1665
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
1666
index XXXXXXX..XXXXXXX 100755
1667
--- a/tests/qemu-iotests/181
1668
+++ b/tests/qemu-iotests/181
1669
@@ -XXX,XX +XXX,XX @@
1670
-#!/bin/bash
1671
+#!/usr/bin/env bash
1672
#
1673
# Test postcopy live migration with shared storage
1674
#
1675
diff --git a/tests/qemu-iotests/182 b/tests/qemu-iotests/182
1676
index XXXXXXX..XXXXXXX 100755
1677
--- a/tests/qemu-iotests/182
1678
+++ b/tests/qemu-iotests/182
1679
@@ -XXX,XX +XXX,XX @@
1680
-#!/bin/bash
1681
+#!/usr/bin/env bash
1682
#
1683
# Test image locking for POSIX locks
1684
#
1685
diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
1686
index XXXXXXX..XXXXXXX 100755
1687
--- a/tests/qemu-iotests/183
1688
+++ b/tests/qemu-iotests/183
1689
@@ -XXX,XX +XXX,XX @@
1690
-#!/bin/bash
1691
+#!/usr/bin/env bash
1692
#
1693
# Test old-style block migration (migrate -b)
1694
#
1695
diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184
1696
index XXXXXXX..XXXXXXX 100755
1697
--- a/tests/qemu-iotests/184
1698
+++ b/tests/qemu-iotests/184
1699
@@ -XXX,XX +XXX,XX @@
1700
-#!/bin/bash
1701
+#!/usr/bin/env bash
1702
#
1703
# Test I/O throttle block filter driver interface
1704
#
1705
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
1706
index XXXXXXX..XXXXXXX 100755
1707
--- a/tests/qemu-iotests/185
1708
+++ b/tests/qemu-iotests/185
1709
@@ -XXX,XX +XXX,XX @@
1710
-#!/bin/bash
1711
+#!/usr/bin/env bash
1712
#
1713
# Test exiting qemu while jobs are still running
1714
#
1715
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
1716
index XXXXXXX..XXXXXXX 100755
1717
--- a/tests/qemu-iotests/186
1718
+++ b/tests/qemu-iotests/186
1719
@@ -XXX,XX +XXX,XX @@
1720
-#!/bin/bash
1721
+#!/usr/bin/env bash
1722
#
1723
# Test 'info block' with all kinds of configurations
1724
#
1725
diff --git a/tests/qemu-iotests/187 b/tests/qemu-iotests/187
1726
index XXXXXXX..XXXXXXX 100755
1727
--- a/tests/qemu-iotests/187
1728
+++ b/tests/qemu-iotests/187
1729
@@ -XXX,XX +XXX,XX @@
1730
-#!/bin/bash
1731
+#!/usr/bin/env bash
1732
#
1733
# Test switching between read-only and read-write
1734
#
1735
diff --git a/tests/qemu-iotests/188 b/tests/qemu-iotests/188
1736
index XXXXXXX..XXXXXXX 100755
1737
--- a/tests/qemu-iotests/188
1738
+++ b/tests/qemu-iotests/188
1739
@@ -XXX,XX +XXX,XX @@
1740
-#!/bin/bash
1741
+#!/usr/bin/env bash
1742
#
1743
# Test encrypted read/write using plain bdrv_read/bdrv_write
1744
#
1745
diff --git a/tests/qemu-iotests/189 b/tests/qemu-iotests/189
1746
index XXXXXXX..XXXXXXX 100755
1747
--- a/tests/qemu-iotests/189
1748
+++ b/tests/qemu-iotests/189
1749
@@ -XXX,XX +XXX,XX @@
1750
-#!/bin/bash
1751
+#!/usr/bin/env bash
1752
#
1753
# Test encrypted read/write using backing files
1754
#
1755
diff --git a/tests/qemu-iotests/190 b/tests/qemu-iotests/190
1756
index XXXXXXX..XXXXXXX 100755
1757
--- a/tests/qemu-iotests/190
1758
+++ b/tests/qemu-iotests/190
1759
@@ -XXX,XX +XXX,XX @@
1760
-#!/bin/bash
1761
+#!/usr/bin/env bash
1762
#
1763
# qemu-img measure sub-command tests on huge qcow2 files
1764
#
1765
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
1766
index XXXXXXX..XXXXXXX 100755
1767
--- a/tests/qemu-iotests/191
1768
+++ b/tests/qemu-iotests/191
1769
@@ -XXX,XX +XXX,XX @@
1770
-#!/bin/bash
1771
+#!/usr/bin/env bash
1772
#
1773
# Test commit block job where top has two parents
1774
#
1775
diff --git a/tests/qemu-iotests/192 b/tests/qemu-iotests/192
1776
index XXXXXXX..XXXXXXX 100755
1777
--- a/tests/qemu-iotests/192
1778
+++ b/tests/qemu-iotests/192
1779
@@ -XXX,XX +XXX,XX @@
1780
-#!/bin/bash
1781
+#!/usr/bin/env bash
1782
#
1783
# Test NBD export with -incoming (non-shared storage migration use case from
1784
# libvirt)
1785
diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195
1786
index XXXXXXX..XXXXXXX 100755
1787
--- a/tests/qemu-iotests/195
1788
+++ b/tests/qemu-iotests/195
1789
@@ -XXX,XX +XXX,XX @@
1790
-#!/bin/bash
1791
+#!/usr/bin/env bash
1792
#
1793
# Test change-backing-file command
1794
#
1795
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
1796
index XXXXXXX..XXXXXXX 100755
1797
--- a/tests/qemu-iotests/197
1798
+++ b/tests/qemu-iotests/197
1799
@@ -XXX,XX +XXX,XX @@
1800
-#!/bin/bash
1801
+#!/usr/bin/env bash
1802
#
1803
# Test case for copy-on-read into qcow2
1804
#
1805
diff --git a/tests/qemu-iotests/198 b/tests/qemu-iotests/198
1806
index XXXXXXX..XXXXXXX 100755
1807
--- a/tests/qemu-iotests/198
1808
+++ b/tests/qemu-iotests/198
1809
@@ -XXX,XX +XXX,XX @@
1810
-#!/bin/bash
1811
+#!/usr/bin/env bash
1812
#
1813
# Test commit of encrypted qcow2 files
1814
#
1815
diff --git a/tests/qemu-iotests/200 b/tests/qemu-iotests/200
1816
index XXXXXXX..XXXXXXX 100755
1817
--- a/tests/qemu-iotests/200
1818
+++ b/tests/qemu-iotests/200
1819
@@ -XXX,XX +XXX,XX @@
1820
-#!/bin/bash
1821
+#!/usr/bin/env bash
1822
#
1823
# Block job co-routine race condition test.
1824
#
1825
diff --git a/tests/qemu-iotests/201 b/tests/qemu-iotests/201
1826
index XXXXXXX..XXXXXXX 100755
1827
--- a/tests/qemu-iotests/201
1828
+++ b/tests/qemu-iotests/201
1829
@@ -XXX,XX +XXX,XX @@
1830
-#!/bin/bash
1831
+#!/usr/bin/env bash
1832
#
1833
# Test savevm and loadvm after live migration with postcopy flag
1834
#
1835
diff --git a/tests/qemu-iotests/204 b/tests/qemu-iotests/204
1836
index XXXXXXX..XXXXXXX 100755
1837
--- a/tests/qemu-iotests/204
1838
+++ b/tests/qemu-iotests/204
1839
@@ -XXX,XX +XXX,XX @@
1840
-#!/bin/bash
1841
+#!/usr/bin/env bash
1842
#
1843
# Test corner cases with unusual block geometries
1844
#
1845
diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214
1846
index XXXXXXX..XXXXXXX 100755
1847
--- a/tests/qemu-iotests/214
1848
+++ b/tests/qemu-iotests/214
1849
@@ -XXX,XX +XXX,XX @@
1850
-#!/bin/bash
1851
+#!/usr/bin/env bash
1852
#
1853
# Test qcow2 image compression
1854
#
1855
diff --git a/tests/qemu-iotests/215 b/tests/qemu-iotests/215
1856
index XXXXXXX..XXXXXXX 100755
1857
--- a/tests/qemu-iotests/215
1858
+++ b/tests/qemu-iotests/215
1859
@@ -XXX,XX +XXX,XX @@
1860
-#!/bin/bash
1861
+#!/usr/bin/env bash
1862
#
1863
# Test case for copy-on-read into qcow2, using the COR filter driver
1864
#
1865
diff --git a/tests/qemu-iotests/217 b/tests/qemu-iotests/217
1866
index XXXXXXX..XXXXXXX 100755
1867
--- a/tests/qemu-iotests/217
1868
+++ b/tests/qemu-iotests/217
1869
@@ -XXX,XX +XXX,XX @@
1870
-#!/bin/bash
1871
+#!/usr/bin/env bash
1872
#
1873
# I/O errors when working with internal qcow2 snapshots, and repairing
1874
# the result
1875
diff --git a/tests/qemu-iotests/220 b/tests/qemu-iotests/220
1876
index XXXXXXX..XXXXXXX 100755
1877
--- a/tests/qemu-iotests/220
1878
+++ b/tests/qemu-iotests/220
1879
@@ -XXX,XX +XXX,XX @@
1880
-#!/bin/bash
1881
+#!/usr/bin/env bash
1882
#
1883
# max limits on compression in huge qcow2 files
1884
#
1885
diff --git a/tests/qemu-iotests/221 b/tests/qemu-iotests/221
1886
index XXXXXXX..XXXXXXX 100755
1887
--- a/tests/qemu-iotests/221
1888
+++ b/tests/qemu-iotests/221
1889
@@ -XXX,XX +XXX,XX @@
1890
-#!/bin/bash
1891
+#!/usr/bin/env bash
1892
#
1893
# Test qemu-img vs. unaligned images
1894
#
1895
diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223
1896
index XXXXXXX..XXXXXXX 100755
1897
--- a/tests/qemu-iotests/223
1898
+++ b/tests/qemu-iotests/223
1899
@@ -XXX,XX +XXX,XX @@
1900
-#!/bin/bash
1901
+#!/usr/bin/env bash
1902
#
1903
# Test reading dirty bitmap over NBD
1904
#
1905
diff --git a/tests/qemu-iotests/225 b/tests/qemu-iotests/225
1906
index XXXXXXX..XXXXXXX 100755
1907
--- a/tests/qemu-iotests/225
1908
+++ b/tests/qemu-iotests/225
1909
@@ -XXX,XX +XXX,XX @@
1910
-#!/bin/bash
1911
+#!/usr/bin/env bash
1912
#
1913
# Test vmdk backing file correlation
1914
#
1915
diff --git a/tests/qemu-iotests/226 b/tests/qemu-iotests/226
1916
index XXXXXXX..XXXXXXX 100755
1917
--- a/tests/qemu-iotests/226
1918
+++ b/tests/qemu-iotests/226
1919
@@ -XXX,XX +XXX,XX @@
1920
-#!/bin/bash
1921
+#!/usr/bin/env bash
1922
#
1923
# This test covers expected filetypes for the file, host_cdrom and
1924
# host_device drivers.
1925
diff --git a/tests/qemu-iotests/227 b/tests/qemu-iotests/227
1926
index XXXXXXX..XXXXXXX 100755
1927
--- a/tests/qemu-iotests/227
1928
+++ b/tests/qemu-iotests/227
1929
@@ -XXX,XX +XXX,XX @@
1930
-#!/bin/bash
1931
+#!/usr/bin/env bash
1932
#
1933
# Test query-blockstats with different ways to create a BB
1934
#
1935
diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
1936
index XXXXXXX..XXXXXXX 100755
1937
--- a/tests/qemu-iotests/229
1938
+++ b/tests/qemu-iotests/229
1939
@@ -XXX,XX +XXX,XX @@
1940
-#!/bin/bash
1941
+#!/usr/bin/env bash
1942
#
1943
# Test for force canceling a running blockjob that is paused in
1944
# an error state.
1945
diff --git a/tests/qemu-iotests/231 b/tests/qemu-iotests/231
1946
index XXXXXXX..XXXXXXX 100755
1947
--- a/tests/qemu-iotests/231
1948
+++ b/tests/qemu-iotests/231
1949
@@ -XXX,XX +XXX,XX @@
1950
-#!/bin/bash
1951
+#!/usr/bin/env bash
1952
#
1953
# Test legacy and modern option parsing for rbd/ceph. This will not
1954
# actually connect to a ceph server, but rather looks for the appropriate
1955
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
1956
index XXXXXXX..XXXXXXX 100755
1957
--- a/tests/qemu-iotests/232
1958
+++ b/tests/qemu-iotests/232
1959
@@ -XXX,XX +XXX,XX @@
1960
-#!/bin/bash
1961
+#!/usr/bin/env bash
1962
#
1963
# Test for auto-read-only
1964
#
1965
diff --git a/tests/qemu-iotests/233 b/tests/qemu-iotests/233
1966
index XXXXXXX..XXXXXXX 100755
1967
--- a/tests/qemu-iotests/233
1968
+++ b/tests/qemu-iotests/233
1969
@@ -XXX,XX +XXX,XX @@
1970
-#!/bin/bash
1971
+#!/usr/bin/env bash
1972
#
1973
# Test NBD TLS certificate / authorization integration
1974
#
1975
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
1976
index XXXXXXX..XXXXXXX 100755
1977
--- a/tests/qemu-iotests/check
1978
+++ b/tests/qemu-iotests/check
1979
@@ -XXX,XX +XXX,XX @@
1980
-#!/bin/bash
1981
+#!/usr/bin/env bash
1982
#
1983
# Copyright (C) 2009 Red Hat, Inc.
1984
# Copyright (c) 2000-2002,2006 Silicon Graphics, Inc. All Rights Reserved.
1985
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
1986
index XXXXXXX..XXXXXXX 100644
1987
--- a/tests/qemu-iotests/common.config
1988
+++ b/tests/qemu-iotests/common.config
1989
@@ -XXX,XX +XXX,XX @@
1990
-#!/bin/bash
1991
+#!/usr/bin/env bash
1992
#
1993
# Copyright (C) 2009 Red Hat, Inc.
1994
# Copyright (c) 2000-2003,2006 Silicon Graphics, Inc. All Rights Reserved.
1995
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
1996
index XXXXXXX..XXXXXXX 100644
1997
--- a/tests/qemu-iotests/common.filter
1998
+++ b/tests/qemu-iotests/common.filter
1999
@@ -XXX,XX +XXX,XX @@
2000
-#!/bin/bash
2001
+#!/usr/bin/env bash
2002
#
2003
# Copyright (C) 2009 Red Hat, Inc.
2004
# Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
2005
diff --git a/tests/qemu-iotests/common.nbd b/tests/qemu-iotests/common.nbd
2006
index XXXXXXX..XXXXXXX 100644
2007
--- a/tests/qemu-iotests/common.nbd
2008
+++ b/tests/qemu-iotests/common.nbd
2009
@@ -XXX,XX +XXX,XX @@
2010
-#!/bin/bash
2011
+#!/usr/bin/env bash
2012
# -*- shell-script-mode -*-
2013
#
2014
# Helpers for NBD server related config
2015
diff --git a/tests/qemu-iotests/common.pattern b/tests/qemu-iotests/common.pattern
2016
index XXXXXXX..XXXXXXX 100644
2017
--- a/tests/qemu-iotests/common.pattern
2018
+++ b/tests/qemu-iotests/common.pattern
2019
@@ -XXX,XX +XXX,XX @@
2020
-#!/bin/bash
2021
+#!/usr/bin/env bash
2022
#
2023
# Copyright (C) 2009 Red Hat, Inc.
2024
#
2025
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
2026
index XXXXXXX..XXXXXXX 100644
2027
--- a/tests/qemu-iotests/common.qemu
2028
+++ b/tests/qemu-iotests/common.qemu
2029
@@ -XXX,XX +XXX,XX @@
2030
-#!/bin/bash
2031
+#!/usr/bin/env bash
2032
#
2033
# This allows for launching of multiple QEMU instances, with independent
2034
# communication possible to each instance.
2035
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
2036
index XXXXXXX..XXXXXXX 100644
2037
--- a/tests/qemu-iotests/common.rc
2038
+++ b/tests/qemu-iotests/common.rc
2039
@@ -XXX,XX +XXX,XX @@
2040
-#!/bin/bash
2041
+#!/usr/bin/env bash
2042
#
2043
# Copyright (C) 2009 Red Hat, Inc.
2044
# Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
2045
diff --git a/tests/qemu-iotests/common.tls b/tests/qemu-iotests/common.tls
2046
index XXXXXXX..XXXXXXX 100644
2047
--- a/tests/qemu-iotests/common.tls
2048
+++ b/tests/qemu-iotests/common.tls
2049
@@ -XXX,XX +XXX,XX @@
2050
-#!/bin/bash
2051
+#!/usr/bin/env bash
2052
#
2053
# Helpers for TLS related config
2054
#
2055
--
2056
2.20.1
2057
2058
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Various sed regexp from common.filter use sed GNU extensions.
4
Instead of spending time to write these regex to be POSIX compliant,
5
verify the GNU sed is available and use it.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
tests/qemu-iotests/common.filter | 36 ++++++++++++++++----------------
11
tests/qemu-iotests/common.rc | 13 ++++++++++++
12
2 files changed, 31 insertions(+), 18 deletions(-)
13
14
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qemu-iotests/common.filter
17
+++ b/tests/qemu-iotests/common.filter
18
@@ -XXX,XX +XXX,XX @@
19
#
20
_filter_date()
21
{
22
- sed \
23
+ $SED \
24
-e 's/[A-Z][a-z][a-z] [A-z][a-z][a-z] *[0-9][0-9]* [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]$/DATE/'
25
}
26
27
_filter_generated_node_ids()
28
{
29
- sed -re 's/\#block[0-9]{3,}/NODE_NAME/'
30
+ $SED -re 's/\#block[0-9]{3,}/NODE_NAME/'
31
}
32
33
_filter_qom_path()
34
{
35
- sed -e 's#\(Attached to: *\) /.*#\1 PATH#'
36
+ $SED -e 's#\(Attached to: *\) /.*#\1 PATH#'
37
}
38
39
# replace occurrences of the actual TEST_DIR value with TEST_DIR
40
_filter_testdir()
41
{
42
- sed -e "s#$TEST_DIR/#TEST_DIR/#g"
43
+ $SED -e "s#$TEST_DIR/#TEST_DIR/#g"
44
}
45
46
# replace occurrences of the actual IMGFMT value with IMGFMT
47
_filter_imgfmt()
48
{
49
- sed -e "s#$IMGFMT#IMGFMT#g"
50
+ $SED -e "s#$IMGFMT#IMGFMT#g"
51
}
52
53
# Replace error message when the format is not supported and delete
54
# the output lines after the first one
55
_filter_qemu_img_check()
56
{
57
- sed -e '/allocated.*fragmented.*compressed clusters/d' \
58
+ $SED -e '/allocated.*fragmented.*compressed clusters/d' \
59
-e 's/qemu-img: This image format does not support checks/No errors were found on the image./' \
60
-e '/Image end offset: [0-9]\+/d'
61
}
62
@@ -XXX,XX +XXX,XX @@ _filter_qemu_img_check()
63
# Removes \r from messages
64
_filter_win32()
65
{
66
- sed -e 's/\r//g'
67
+ $SED -e 's/\r//g'
68
}
69
70
# sanitize qemu-io output
71
_filter_qemu_io()
72
{
73
- _filter_win32 | sed -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/" \
74
+ _filter_win32 | $SED -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/" \
75
-e "s/: line [0-9][0-9]*: *[0-9][0-9]*\( Aborted\| Killed\)/:\1/" \
76
-e "s/qemu-io> //g"
77
}
78
@@ -XXX,XX +XXX,XX @@ _filter_qemu_io()
79
# replace occurrences of QEMU_PROG with "qemu"
80
_filter_qemu()
81
{
82
- sed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \
83
+ $SED -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \
84
-e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#' \
85
-e $'s#\r##' # QEMU monitor uses \r\n line endings
86
}
87
@@ -XXX,XX +XXX,XX @@ _filter_qemu()
88
_filter_qmp()
89
{
90
_filter_win32 | \
91
- sed -e 's#\("\(micro\)\?seconds": \)[0-9]\+#\1 TIMESTAMP#g' \
92
+ $SED -e 's#\("\(micro\)\?seconds": \)[0-9]\+#\1 TIMESTAMP#g' \
93
-e 's#^{"QMP":.*}$#QMP_VERSION#' \
94
-e '/^ "QMP": {\s*$/, /^ }\s*$/ c\' \
95
-e ' QMP_VERSION'
96
@@ -XXX,XX +XXX,XX @@ _filter_qmp()
97
# readline makes HMP command strings so long that git complains
98
_filter_hmp()
99
{
100
- sed -e $'s/^\\((qemu) \\)\\?.*\e\\[D/\\1/g' \
101
+ $SED -e $'s/^\\((qemu) \\)\\?.*\e\\[D/\\1/g' \
102
-e $'s/\e\\[K//g'
103
}
104
105
# replace block job offset
106
_filter_block_job_offset()
107
{
108
- sed -e 's/, "offset": [0-9]\+,/, "offset": OFFSET,/'
109
+ $SED -e 's/, "offset": [0-9]\+,/, "offset": OFFSET,/'
110
}
111
112
# replace block job len
113
_filter_block_job_len()
114
{
115
- sed -e 's/, "len": [0-9]\+,/, "len": LEN,/g'
116
+ $SED -e 's/, "len": [0-9]\+,/, "len": LEN,/g'
117
}
118
119
# replace actual image size (depends on the host filesystem)
120
_filter_actual_image_size()
121
{
122
- sed -s 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g'
123
+ $SED -s 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g'
124
}
125
126
# replace driver-specific options in the "Formatting..." line
127
_filter_img_create()
128
{
129
- sed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
130
+ $SED -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
131
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
132
-e "s#$TEST_DIR#TEST_DIR#g" \
133
-e "s#$IMGFMT#IMGFMT#g" \
134
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
135
136
discard=0
137
regex_json_spec_start='^ *"format-specific": \{'
138
- sed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
139
+ $SED -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
140
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
141
-e "s#$TEST_DIR#TEST_DIR#g" \
142
-e "s#$IMGFMT#IMGFMT#g" \
143
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
144
# human and json output
145
_filter_qemu_img_map()
146
{
147
- sed -e 's/\([0-9a-fx]* *[0-9a-fx]* *\)[0-9a-fx]* */\1/g' \
148
+ $SED -e 's/\([0-9a-fx]* *[0-9a-fx]* *\)[0-9a-fx]* */\1/g' \
149
-e 's/"offset": [0-9]\+/"offset": OFFSET/g' \
150
-e 's/Mapped to *//' | _filter_testdir | _filter_imgfmt
151
}
152
@@ -XXX,XX +XXX,XX @@ _filter_nbd()
153
# receive callbacks sometimes, making them unreliable.
154
#
155
# Filter out the TCP port number since this changes between runs.
156
- sed -e '/nbd\/.*\.c:/d' \
157
+ $SED -e '/nbd\/.*\.c:/d' \
158
-e 's#127\.0\.0\.1:[0-9]*#127.0.0.1:PORT#g' \
159
-e "s#?socket=$TEST_DIR#?socket=TEST_DIR#g" \
160
-e 's#\(foo\|PORT/\?\|.sock\): Failed to .*$#\1#'
161
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
162
index XXXXXXX..XXXXXXX 100644
163
--- a/tests/qemu-iotests/common.rc
164
+++ b/tests/qemu-iotests/common.rc
165
@@ -XXX,XX +XXX,XX @@
166
# along with this program. If not, see <http://www.gnu.org/licenses/>.
167
#
168
169
+SED=
170
+for sed in sed gsed; do
171
+ ($sed --version | grep 'GNU sed') > /dev/null 2>&1
172
+ if [ "$?" -eq 0 ]; then
173
+ SED=$sed
174
+ break
175
+ fi
176
+done
177
+if [ -z "$SED" ]; then
178
+ echo "$0: GNU sed not found"
179
+ exit 1
180
+fi
181
+
182
dd()
183
{
184
if [ "$HOSTOS" == "Linux" ]
185
--
186
2.20.1
187
188
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Eric Blake <eblake@redhat.com>
3
---
4
tests/qemu-iotests/243 | 63 ++++++++++++++++++++++++++++++++++++++
5
tests/qemu-iotests/243.out | 26 ++++++++++++++++
6
tests/qemu-iotests/group | 1 +
7
3 files changed, 90 insertions(+)
8
create mode 100755 tests/qemu-iotests/243
9
create mode 100644 tests/qemu-iotests/243.out
10
1
11
diff --git a/tests/qemu-iotests/243 b/tests/qemu-iotests/243
12
new file mode 100755
13
index XXXXXXX..XXXXXXX
14
--- /dev/null
15
+++ b/tests/qemu-iotests/243
16
@@ -XXX,XX +XXX,XX @@
17
+#!/bin/bash
18
+#
19
+# Test qcow2 preallocation
20
+#
21
+# Copyright (C) 2019 Red Hat, Inc.
22
+#
23
+# This program is free software; you can redistribute it and/or modify
24
+# it under the terms of the GNU General Public License as published by
25
+# the Free Software Foundation; either version 2 of the License, or
26
+# (at your option) any later version.
27
+#
28
+# This program is distributed in the hope that it will be useful,
29
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
30
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31
+# GNU General Public License for more details.
32
+#
33
+# You should have received a copy of the GNU General Public License
34
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
35
+#
36
+
37
+# creator
38
+owner=kwolf@redhat.com
39
+
40
+seq=$(basename $0)
41
+echo "QA output created by $seq"
42
+
43
+status=1    # failure is the default!
44
+
45
+_cleanup()
46
+{
47
+ _cleanup_test_img
48
+}
49
+trap "_cleanup; exit \$status" 0 1 2 3 15
50
+
51
+# get standard environment, filters and checks
52
+. ./common.rc
53
+. ./common.filter
54
+
55
+_supported_fmt qcow2
56
+_supported_proto file
57
+_supported_os Linux
58
+
59
+for mode in off metadata falloc full; do
60
+
61
+ echo
62
+ echo "=== preallocation=$mode ==="
63
+ echo
64
+
65
+ IMGOPTS="preallocation=$mode" _make_test_img 64M
66
+
67
+ printf "File size: "
68
+ du -b $TEST_IMG | cut -f1
69
+
70
+ # Can't use precise numbers here because they differ between filesystems
71
+ printf "Disk usage: "
72
+ [ $(du -B1 $TEST_IMG | cut -f1) -lt 1048576 ] && echo "low" || echo "high"
73
+
74
+done
75
+
76
+# success, all done
77
+echo "*** done"
78
+rm -f $seq.full
79
+status=0
80
diff --git a/tests/qemu-iotests/243.out b/tests/qemu-iotests/243.out
81
new file mode 100644
82
index XXXXXXX..XXXXXXX
83
--- /dev/null
84
+++ b/tests/qemu-iotests/243.out
85
@@ -XXX,XX +XXX,XX @@
86
+QA output created by 243
87
+
88
+=== preallocation=off ===
89
+
90
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 preallocation=off
91
+File size: 196616
92
+Disk usage: low
93
+
94
+=== preallocation=metadata ===
95
+
96
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 preallocation=metadata
97
+File size: 67436544
98
+Disk usage: low
99
+
100
+=== preallocation=falloc ===
101
+
102
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 preallocation=falloc
103
+File size: 67436544
104
+Disk usage: high
105
+
106
+=== preallocation=full ===
107
+
108
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 preallocation=full
109
+File size: 67436544
110
+Disk usage: high
111
+*** done
112
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
113
index XXXXXXX..XXXXXXX 100644
114
--- a/tests/qemu-iotests/group
115
+++ b/tests/qemu-iotests/group
116
@@ -XXX,XX +XXX,XX @@
117
239 rw auto quick
118
240 auto quick
119
242 rw auto quick
120
+243 rw auto quick
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
This adds external data file to the qcow2 spec as a new incompatible
2
feature.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
6
docs/interop/qcow2.txt | 42 ++++++++++++++++++++++++++++++++++++++----
7
1 file changed, 38 insertions(+), 4 deletions(-)
8
9
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
10
index XXXXXXX..XXXXXXX 100644
11
--- a/docs/interop/qcow2.txt
12
+++ b/docs/interop/qcow2.txt
13
@@ -XXX,XX +XXX,XX @@ in the description of a field.
14
be written to (unless for regaining
15
consistency).
16
17
- Bits 2-63: Reserved (set to 0)
18
+ Bit 2: External data file bit. If this bit is set, an
19
+ external data file is used. Guest clusters are
20
+ then stored in the external data file. For such
21
+ images, clusters in the external data file are
22
+ not refcounted. The offset field in the
23
+ Standard Cluster Descriptor must match the
24
+ guest offset and neither compressed clusters
25
+ nor internal snapshots are supported.
26
+
27
+ An External Data File Name header extension may
28
+ be present if this bit is set.
29
+
30
+ Bits 3-63: Reserved (set to 0)
31
32
80 - 87: compatible_features
33
Bitmask of compatible features. An implementation can
34
@@ -XXX,XX +XXX,XX @@ in the description of a field.
35
bit is unset, the bitmaps extension data must be
36
considered inconsistent.
37
38
- Bits 1-63: Reserved (set to 0)
39
+ Bit 1: If this bit is set, the external data file can
40
+ be read as a consistent standalone raw image
41
+ without looking at the qcow2 metadata.
42
+
43
+ Setting this bit has a performance impact for
44
+ some operations on the image (e.g. writing
45
+ zeros requires writing to the data file instead
46
+ of only setting the zero flag in the L2 table
47
+ entry) and conflicts with backing files.
48
+
49
+ This bit may only be set if the External Data
50
+ File bit (incompatible feature bit 1) is also
51
+ set.
52
+
53
+ Bits 2-63: Reserved (set to 0)
54
55
96 - 99: refcount_order
56
Describes the width of a reference count block entry (width
57
@@ -XXX,XX +XXX,XX @@ be stored. Each extension has a structure like the following:
58
0x6803f857 - Feature name table
59
0x23852875 - Bitmaps extension
60
0x0537be77 - Full disk encryption header pointer
61
+ 0x44415441 - External data file name
62
other - Unknown header extension, can be safely
63
ignored
64
65
@@ -XXX,XX +XXX,XX @@ L2 table entry:
66
This information is only accurate in L2 tables
67
that are reachable from the active L1 table.
68
69
+ With external data files, all guest clusters have an
70
+ implicit refcount of 1 (because of the fixed host = guest
71
+ mapping for guest cluster offsets), so this bit should be 1
72
+ for all allocated clusters.
73
+
74
Standard Cluster Descriptor:
75
76
Bit 0: If set to 1, the cluster reads as all zeros. The host
77
@@ -XXX,XX +XXX,XX @@ Standard Cluster Descriptor:
78
1 - 8: Reserved (set to 0)
79
80
9 - 55: Bits 9-55 of host cluster offset. Must be aligned to a
81
- cluster boundary. If the offset is 0, the cluster is
82
- unallocated.
83
+ cluster boundary. If the offset is 0 and bit 63 is clear,
84
+ the cluster is unallocated. The offset may only be 0 with
85
+ bit 63 set (indicating a host cluster offset of 0) when an
86
+ external data file is used.
87
88
56 - 61: Reserved (set to 0)
89
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
This adds basic constants, struct fields and helper function for
2
external data file support to the implementation.
3
1
4
QCOW2_INCOMPAT_MASK and QCOW2_AUTOCLEAR_MASK are not updated yet so that
5
opening images with an external data file still fails (we don't handle
6
them correctly yet).
7
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
block/qcow2.h | 32 ++++++++++++++++++++++----------
11
block/qcow2.c | 9 +++++++++
12
tests/qemu-iotests/031.out | 8 ++++----
13
tests/qemu-iotests/036.out | 4 ++--
14
tests/qemu-iotests/061.out | 14 +++++++-------
15
5 files changed, 44 insertions(+), 23 deletions(-)
16
17
diff --git a/block/qcow2.h b/block/qcow2.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.h
20
+++ b/block/qcow2.h
21
@@ -XXX,XX +XXX,XX @@ enum {
22
23
/* Incompatible feature bits */
24
enum {
25
- QCOW2_INCOMPAT_DIRTY_BITNR = 0,
26
- QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
27
- QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
28
- QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
29
-
30
- QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
31
- | QCOW2_INCOMPAT_CORRUPT,
32
+ QCOW2_INCOMPAT_DIRTY_BITNR = 0,
33
+ QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
34
+ QCOW2_INCOMPAT_DATA_FILE_BITNR = 2,
35
+ QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
36
+ QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
37
+ QCOW2_INCOMPAT_DATA_FILE = 1 << QCOW2_INCOMPAT_DATA_FILE_BITNR,
38
+
39
+ QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
40
+ | QCOW2_INCOMPAT_CORRUPT,
41
};
42
43
/* Compatible feature bits */
44
@@ -XXX,XX +XXX,XX @@ enum {
45
46
/* Autoclear feature bits */
47
enum {
48
- QCOW2_AUTOCLEAR_BITMAPS_BITNR = 0,
49
- QCOW2_AUTOCLEAR_BITMAPS = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR,
50
+ QCOW2_AUTOCLEAR_BITMAPS_BITNR = 0,
51
+ QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR = 1,
52
+ QCOW2_AUTOCLEAR_BITMAPS = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR,
53
+ QCOW2_AUTOCLEAR_DATA_FILE_RAW = 1 << QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR,
54
55
- QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS,
56
+ QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS,
57
};
58
59
enum qcow2_discard_type {
60
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State {
61
62
CoQueue compress_wait_queue;
63
int nb_compress_threads;
64
+
65
+ BdrvChild *data_file;
66
} BDRVQcow2State;
67
68
typedef struct Qcow2COWRegion {
69
@@ -XXX,XX +XXX,XX @@ typedef enum QCow2MetadataOverlap {
70
71
#define REFT_OFFSET_MASK 0xfffffffffffffe00ULL
72
73
+static inline bool has_data_file(BlockDriverState *bs)
74
+{
75
+ BDRVQcow2State *s = bs->opaque;
76
+ return (s->data_file != bs->file);
77
+}
78
+
79
static inline int64_t start_of_cluster(BDRVQcow2State *s, int64_t offset)
80
{
81
return offset & ~(s->cluster_size - 1);
82
diff --git a/block/qcow2.c b/block/qcow2.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/block/qcow2.c
85
+++ b/block/qcow2.c
86
@@ -XXX,XX +XXX,XX @@ typedef struct {
87
#define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
88
#define QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
89
#define QCOW2_EXT_MAGIC_BITMAPS 0x23852875
90
+#define QCOW2_EXT_MAGIC_DATA_FILE 0x44415441
91
92
static int coroutine_fn
93
qcow2_co_preadv_compressed(BlockDriverState *bs,
94
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
95
goto fail;
96
}
97
98
+ /* TODO Open external data file */
99
+ s->data_file = bs->file;
100
+
101
/* qcow2_read_extension may have set up the crypto context
102
* if the crypt method needs a header region, some methods
103
* don't need header extensions, so must check here
104
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
105
.bit = QCOW2_INCOMPAT_CORRUPT_BITNR,
106
.name = "corrupt bit",
107
},
108
+ {
109
+ .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
110
+ .bit = QCOW2_INCOMPAT_DATA_FILE_BITNR,
111
+ .name = "external data file",
112
+ },
113
{
114
.type = QCOW2_FEAT_TYPE_COMPATIBLE,
115
.bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
116
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
117
index XXXXXXX..XXXXXXX 100644
118
--- a/tests/qemu-iotests/031.out
119
+++ b/tests/qemu-iotests/031.out
120
@@ -XXX,XX +XXX,XX @@ header_length 104
121
122
Header extension:
123
magic 0x6803f857
124
-length 144
125
+length 192
126
data <binary>
127
128
Header extension:
129
@@ -XXX,XX +XXX,XX @@ header_length 104
130
131
Header extension:
132
magic 0x6803f857
133
-length 144
134
+length 192
135
data <binary>
136
137
Header extension:
138
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
139
140
magic 0x514649fb
141
version 3
142
-backing_file_offset 0x148
143
+backing_file_offset 0x178
144
backing_file_size 0x17
145
cluster_bits 16
146
size 67108864
147
@@ -XXX,XX +XXX,XX @@ data 'host_device'
148
149
Header extension:
150
magic 0x6803f857
151
-length 144
152
+length 192
153
data <binary>
154
155
Header extension:
156
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
157
index XXXXXXX..XXXXXXX 100644
158
--- a/tests/qemu-iotests/036.out
159
+++ b/tests/qemu-iotests/036.out
160
@@ -XXX,XX +XXX,XX @@ header_length 104
161
162
Header extension:
163
magic 0x6803f857
164
-length 144
165
+length 192
166
data <binary>
167
168
169
@@ -XXX,XX +XXX,XX @@ header_length 104
170
171
Header extension:
172
magic 0x6803f857
173
-length 144
174
+length 192
175
data <binary>
176
177
*** done
178
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
179
index XXXXXXX..XXXXXXX 100644
180
--- a/tests/qemu-iotests/061.out
181
+++ b/tests/qemu-iotests/061.out
182
@@ -XXX,XX +XXX,XX @@ header_length 104
183
184
Header extension:
185
magic 0x6803f857
186
-length 144
187
+length 192
188
data <binary>
189
190
magic 0x514649fb
191
@@ -XXX,XX +XXX,XX @@ header_length 104
192
193
Header extension:
194
magic 0x6803f857
195
-length 144
196
+length 192
197
data <binary>
198
199
magic 0x514649fb
200
@@ -XXX,XX +XXX,XX @@ header_length 104
201
202
Header extension:
203
magic 0x6803f857
204
-length 144
205
+length 192
206
data <binary>
207
208
ERROR cluster 5 refcount=0 reference=1
209
@@ -XXX,XX +XXX,XX @@ header_length 104
210
211
Header extension:
212
magic 0x6803f857
213
-length 144
214
+length 192
215
data <binary>
216
217
magic 0x514649fb
218
@@ -XXX,XX +XXX,XX @@ header_length 104
219
220
Header extension:
221
magic 0x6803f857
222
-length 144
223
+length 192
224
data <binary>
225
226
read 65536/65536 bytes at offset 44040192
227
@@ -XXX,XX +XXX,XX @@ header_length 104
228
229
Header extension:
230
magic 0x6803f857
231
-length 144
232
+length 192
233
data <binary>
234
235
ERROR cluster 5 refcount=0 reference=1
236
@@ -XXX,XX +XXX,XX @@ header_length 104
237
238
Header extension:
239
magic 0x6803f857
240
-length 144
241
+length 192
242
data <binary>
243
244
read 131072/131072 bytes at offset 0
245
--
246
2.20.1
247
248
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
---
3
block/qcow2.h | 3 ++-
4
block/qcow2-cluster.c | 37 +++++++++++++++++++------------------
5
block/qcow2-refcount.c | 10 +++++-----
6
3 files changed, 26 insertions(+), 24 deletions(-)
7
1
8
diff --git a/block/qcow2.h b/block/qcow2.h
9
index XXXXXXX..XXXXXXX 100644
10
--- a/block/qcow2.h
11
+++ b/block/qcow2.h
12
@@ -XXX,XX +XXX,XX @@ static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
13
return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
14
}
15
16
-static inline QCow2ClusterType qcow2_get_cluster_type(uint64_t l2_entry)
17
+static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs,
18
+ uint64_t l2_entry)
19
{
20
if (l2_entry & QCOW_OFLAG_COMPRESSED) {
21
return QCOW2_CLUSTER_COMPRESSED;
22
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/qcow2-cluster.c
25
+++ b/block/qcow2-cluster.c
26
@@ -XXX,XX +XXX,XX @@ fail:
27
* as contiguous. (This allows it, for example, to stop at the first compressed
28
* cluster which may require a different handling)
29
*/
30
-static int count_contiguous_clusters(int nb_clusters, int cluster_size,
31
- uint64_t *l2_slice, uint64_t stop_flags)
32
+static int count_contiguous_clusters(BlockDriverState *bs, int nb_clusters,
33
+ int cluster_size, uint64_t *l2_slice, uint64_t stop_flags)
34
{
35
int i;
36
QCow2ClusterType first_cluster_type;
37
@@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters(int nb_clusters, int cluster_size,
38
}
39
40
/* must be allocated */
41
- first_cluster_type = qcow2_get_cluster_type(first_entry);
42
+ first_cluster_type = qcow2_get_cluster_type(bs, first_entry);
43
assert(first_cluster_type == QCOW2_CLUSTER_NORMAL ||
44
first_cluster_type == QCOW2_CLUSTER_ZERO_ALLOC);
45
46
@@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters(int nb_clusters, int cluster_size,
47
* Checks how many consecutive unallocated clusters in a given L2
48
* slice have the same cluster type.
49
*/
50
-static int count_contiguous_clusters_unallocated(int nb_clusters,
51
+static int count_contiguous_clusters_unallocated(BlockDriverState *bs,
52
+ int nb_clusters,
53
uint64_t *l2_slice,
54
QCow2ClusterType wanted_type)
55
{
56
@@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters_unallocated(int nb_clusters,
57
wanted_type == QCOW2_CLUSTER_UNALLOCATED);
58
for (i = 0; i < nb_clusters; i++) {
59
uint64_t entry = be64_to_cpu(l2_slice[i]);
60
- QCow2ClusterType type = qcow2_get_cluster_type(entry);
61
+ QCow2ClusterType type = qcow2_get_cluster_type(bs, entry);
62
63
if (type != wanted_type) {
64
break;
65
@@ -XXX,XX +XXX,XX @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
66
* true */
67
assert(nb_clusters <= INT_MAX);
68
69
- type = qcow2_get_cluster_type(*cluster_offset);
70
+ type = qcow2_get_cluster_type(bs, *cluster_offset);
71
if (s->qcow_version < 3 && (type == QCOW2_CLUSTER_ZERO_PLAIN ||
72
type == QCOW2_CLUSTER_ZERO_ALLOC)) {
73
qcow2_signal_corruption(bs, true, -1, -1, "Zero cluster entry found"
74
@@ -XXX,XX +XXX,XX @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
75
case QCOW2_CLUSTER_ZERO_PLAIN:
76
case QCOW2_CLUSTER_UNALLOCATED:
77
/* how many empty clusters ? */
78
- c = count_contiguous_clusters_unallocated(nb_clusters,
79
+ c = count_contiguous_clusters_unallocated(bs, nb_clusters,
80
&l2_slice[l2_index], type);
81
*cluster_offset = 0;
82
break;
83
case QCOW2_CLUSTER_ZERO_ALLOC:
84
case QCOW2_CLUSTER_NORMAL:
85
/* how many allocated clusters ? */
86
- c = count_contiguous_clusters(nb_clusters, s->cluster_size,
87
+ c = count_contiguous_clusters(bs, nb_clusters, s->cluster_size,
88
&l2_slice[l2_index], QCOW_OFLAG_ZERO);
89
*cluster_offset &= L2E_OFFSET_MASK;
90
if (offset_into_cluster(s, *cluster_offset)) {
91
@@ -XXX,XX +XXX,XX @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
92
* write, but require COW to be performed (this includes yet unallocated space,
93
* which must copy from the backing file)
94
*/
95
-static int count_cow_clusters(BDRVQcow2State *s, int nb_clusters,
96
+static int count_cow_clusters(BlockDriverState *bs, int nb_clusters,
97
uint64_t *l2_slice, int l2_index)
98
{
99
int i;
100
101
for (i = 0; i < nb_clusters; i++) {
102
uint64_t l2_entry = be64_to_cpu(l2_slice[l2_index + i]);
103
- QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry);
104
+ QCow2ClusterType cluster_type = qcow2_get_cluster_type(bs, l2_entry);
105
106
switch(cluster_type) {
107
case QCOW2_CLUSTER_NORMAL:
108
@@ -XXX,XX +XXX,XX @@ static int handle_copied(BlockDriverState *bs, uint64_t guest_offset,
109
cluster_offset = be64_to_cpu(l2_slice[l2_index]);
110
111
/* Check how many clusters are already allocated and don't need COW */
112
- if (qcow2_get_cluster_type(cluster_offset) == QCOW2_CLUSTER_NORMAL
113
+ if (qcow2_get_cluster_type(bs, cluster_offset) == QCOW2_CLUSTER_NORMAL
114
&& (cluster_offset & QCOW_OFLAG_COPIED))
115
{
116
/* If a specific host_offset is required, check it */
117
@@ -XXX,XX +XXX,XX @@ static int handle_copied(BlockDriverState *bs, uint64_t guest_offset,
118
119
/* We keep all QCOW_OFLAG_COPIED clusters */
120
keep_clusters =
121
- count_contiguous_clusters(nb_clusters, s->cluster_size,
122
+ count_contiguous_clusters(bs, nb_clusters, s->cluster_size,
123
&l2_slice[l2_index],
124
QCOW_OFLAG_COPIED | QCOW_OFLAG_ZERO);
125
assert(keep_clusters <= nb_clusters);
126
@@ -XXX,XX +XXX,XX @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
127
if (entry & QCOW_OFLAG_COMPRESSED) {
128
nb_clusters = 1;
129
} else {
130
- nb_clusters = count_cow_clusters(s, nb_clusters, l2_slice, l2_index);
131
+ nb_clusters = count_cow_clusters(bs, nb_clusters, l2_slice, l2_index);
132
}
133
134
/* This function is only called when there were no non-COW clusters, so if
135
@@ -XXX,XX +XXX,XX @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
136
* wrong with our code. */
137
assert(nb_clusters > 0);
138
139
- if (qcow2_get_cluster_type(entry) == QCOW2_CLUSTER_ZERO_ALLOC &&
140
+ if (qcow2_get_cluster_type(bs, entry) == QCOW2_CLUSTER_ZERO_ALLOC &&
141
(entry & QCOW_OFLAG_COPIED) &&
142
(!*host_offset ||
143
start_of_cluster(s, *host_offset) == (entry & L2E_OFFSET_MASK)))
144
@@ -XXX,XX +XXX,XX @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
145
* would be fine, too, but count_cow_clusters() above has limited
146
* nb_clusters already to a range of COW clusters */
147
preallocated_nb_clusters =
148
- count_contiguous_clusters(nb_clusters, s->cluster_size,
149
+ count_contiguous_clusters(bs, nb_clusters, s->cluster_size,
150
&l2_slice[l2_index], QCOW_OFLAG_COPIED);
151
assert(preallocated_nb_clusters > 0);
152
153
@@ -XXX,XX +XXX,XX @@ static int discard_in_l2_slice(BlockDriverState *bs, uint64_t offset,
154
* If full_discard is true, the sector should not read back as zeroes,
155
* but rather fall through to the backing file.
156
*/
157
- switch (qcow2_get_cluster_type(old_l2_entry)) {
158
+ switch (qcow2_get_cluster_type(bs, old_l2_entry)) {
159
case QCOW2_CLUSTER_UNALLOCATED:
160
if (full_discard || !bs->backing) {
161
continue;
162
@@ -XXX,XX +XXX,XX @@ static int zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
163
* Minimize L2 changes if the cluster already reads back as
164
* zeroes with correct allocation.
165
*/
166
- cluster_type = qcow2_get_cluster_type(old_offset);
167
+ cluster_type = qcow2_get_cluster_type(bs, old_offset);
168
if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN ||
169
(cluster_type == QCOW2_CLUSTER_ZERO_ALLOC && !unmap)) {
170
continue;
171
@@ -XXX,XX +XXX,XX @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
172
uint64_t l2_entry = be64_to_cpu(l2_slice[j]);
173
int64_t offset = l2_entry & L2E_OFFSET_MASK;
174
QCow2ClusterType cluster_type =
175
- qcow2_get_cluster_type(l2_entry);
176
+ qcow2_get_cluster_type(bs, l2_entry);
177
178
if (cluster_type != QCOW2_CLUSTER_ZERO_PLAIN &&
179
cluster_type != QCOW2_CLUSTER_ZERO_ALLOC) {
180
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/block/qcow2-refcount.c
183
+++ b/block/qcow2-refcount.c
184
@@ -XXX,XX +XXX,XX @@ void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry,
185
{
186
BDRVQcow2State *s = bs->opaque;
187
188
- switch (qcow2_get_cluster_type(l2_entry)) {
189
+ switch (qcow2_get_cluster_type(bs, l2_entry)) {
190
case QCOW2_CLUSTER_COMPRESSED:
191
{
192
int nb_csectors;
193
@@ -XXX,XX +XXX,XX @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
194
entry &= ~QCOW_OFLAG_COPIED;
195
offset = entry & L2E_OFFSET_MASK;
196
197
- switch (qcow2_get_cluster_type(entry)) {
198
+ switch (qcow2_get_cluster_type(bs, entry)) {
199
case QCOW2_CLUSTER_COMPRESSED:
200
nb_csectors = ((entry >> s->csize_shift) &
201
s->csize_mask) + 1;
202
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
203
for(i = 0; i < s->l2_size; i++) {
204
l2_entry = be64_to_cpu(l2_table[i]);
205
206
- switch (qcow2_get_cluster_type(l2_entry)) {
207
+ switch (qcow2_get_cluster_type(bs, l2_entry)) {
208
case QCOW2_CLUSTER_COMPRESSED:
209
/* Compressed clusters don't have QCOW_OFLAG_COPIED */
210
if (l2_entry & QCOW_OFLAG_COPIED) {
211
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
212
213
/* Correct offsets are cluster aligned */
214
if (offset_into_cluster(s, offset)) {
215
- if (qcow2_get_cluster_type(l2_entry) ==
216
+ if (qcow2_get_cluster_type(bs, l2_entry) ==
217
QCOW2_CLUSTER_ZERO_ALLOC)
218
{
219
fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated zero "
220
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
221
for (j = 0; j < s->l2_size; j++) {
222
uint64_t l2_entry = be64_to_cpu(l2_table[j]);
223
uint64_t data_offset = l2_entry & L2E_OFFSET_MASK;
224
- QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry);
225
+ QCow2ClusterType cluster_type = qcow2_get_cluster_type(bs, l2_entry);
226
227
if (cluster_type == QCOW2_CLUSTER_NORMAL ||
228
cluster_type == QCOW2_CLUSTER_ZERO_ALLOC) {
229
--
230
2.20.1
231
232
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
---
3
block/qcow2.h | 10 +++++++++-
4
1 file changed, 9 insertions(+), 1 deletion(-)
5
1
6
diff --git a/block/qcow2.h b/block/qcow2.h
7
index XXXXXXX..XXXXXXX 100644
8
--- a/block/qcow2.h
9
+++ b/block/qcow2.h
10
@@ -XXX,XX +XXX,XX @@ static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs,
11
}
12
return QCOW2_CLUSTER_ZERO_PLAIN;
13
} else if (!(l2_entry & L2E_OFFSET_MASK)) {
14
- return QCOW2_CLUSTER_UNALLOCATED;
15
+ /* Offset 0 generally means unallocated, but it is ambiguous with
16
+ * external data files because 0 is a valid offset there. However, all
17
+ * clusters in external data files always have refcount 1, so we can
18
+ * rely on QCOW_OFLAG_COPIED to disambiguate. */
19
+ if (has_data_file(bs) && (l2_entry & QCOW_OFLAG_COPIED)) {
20
+ return QCOW2_CLUSTER_NORMAL;
21
+ } else {
22
+ return QCOW2_CLUSTER_UNALLOCATED;
23
+ }
24
} else {
25
return QCOW2_CLUSTER_NORMAL;
26
}
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
1
For external data files, data clusters must be excluded from the
1
From: Max Reitz <mreitz@redhat.com>
2
refcount calculations. Instead, an implicit refcount of 1 is assumed for
3
the COPIED flag.
4
2
5
Compressed clusters and internal snapshots are incompatible with
3
We have to start by applying the permission restrictions to new_bs
6
external data files, so print an error if they are in use for images
4
before we can loosen them on old_bs. See the comment for the
7
with an external data file.
5
explanation.
8
6
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
10
---
11
block/qcow2-refcount.c | 41 ++++++++++++++++++++++++++++++-----------
11
block.c | 18 +++++++++++++-----
12
1 file changed, 30 insertions(+), 11 deletions(-)
12
1 file changed, 13 insertions(+), 5 deletions(-)
13
13
14
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
14
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/qcow2-refcount.c
16
--- a/block.c
17
+++ b/block/qcow2-refcount.c
17
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
18
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
19
res->corruptions++;
19
20
}
20
bdrv_replace_child_noperm(child, new_bs);
21
21
22
+ if (has_data_file(bs)) {
22
+ /*
23
+ fprintf(stderr, "ERROR compressed cluster %d with data file, "
23
+ * Start with the new node's permissions. If @new_bs is a (direct
24
+ "entry=0x%" PRIx64 "\n", i, l2_entry);
24
+ * or indirect) child of @old_bs, we must complete the permission
25
+ res->corruptions++;
25
+ * update on @new_bs before we loosen the restrictions on @old_bs.
26
+ break;
26
+ * Otherwise, bdrv_check_perm() on @old_bs would re-initiate
27
+ }
27
+ * updating the permissions of @new_bs, and thus not purely loosen
28
+
28
+ * restrictions.
29
/* Mark cluster as used */
29
+ */
30
nb_csectors = ((l2_entry >> s->csize_shift) &
30
+ if (new_bs) {
31
s->csize_mask) + 1;
31
+ bdrv_get_cumulative_perm(new_bs, &perm, &shared_perm);
32
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
32
+ bdrv_set_perm(new_bs, perm, shared_perm);
33
}
34
35
/* Mark cluster as used */
36
- ret = qcow2_inc_refcounts_imrt(bs, res,
37
- refcount_table, refcount_table_size,
38
- offset, s->cluster_size);
39
- if (ret < 0) {
40
- goto fail;
41
+ if (!has_data_file(bs)) {
42
+ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table,
43
+ refcount_table_size,
44
+ offset, s->cluster_size);
45
+ if (ret < 0) {
46
+ goto fail;
47
+ }
48
}
49
break;
50
}
51
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
52
53
if (cluster_type == QCOW2_CLUSTER_NORMAL ||
54
cluster_type == QCOW2_CLUSTER_ZERO_ALLOC) {
55
- ret = qcow2_get_refcount(bs,
56
- data_offset >> s->cluster_bits,
57
- &refcount);
58
- if (ret < 0) {
59
- /* don't print message nor increment check_errors */
60
- continue;
61
+ if (has_data_file(bs)) {
62
+ refcount = 1;
63
+ } else {
64
+ ret = qcow2_get_refcount(bs,
65
+ data_offset >> s->cluster_bits,
66
+ &refcount);
67
+ if (ret < 0) {
68
+ /* don't print message nor increment check_errors */
69
+ continue;
70
+ }
71
}
72
if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
73
fprintf(stderr, "%s OFLAG_COPIED data cluster: "
74
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
75
}
76
77
/* snapshots */
78
+ if (has_data_file(bs) && s->nb_snapshots) {
79
+ fprintf(stderr, "ERROR %d snapshots in image with data file\n",
80
+ s->nb_snapshots);
81
+ res->corruptions++;
82
+ }
33
+ }
83
+
34
+
84
for (i = 0; i < s->nb_snapshots; i++) {
35
if (old_bs) {
85
sn = s->snapshots + i;
36
/* Update permissions for old node. This is guaranteed to succeed
86
if (offset_into_cluster(s, sn->l1_table_offset)) {
37
* because we're just taking a parent away, so we're loosening
38
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
39
* node moves back to the main AioContext */
40
bdrv_try_set_aio_context(old_bs, qemu_get_aio_context(), NULL);
41
}
42
-
43
- if (new_bs) {
44
- bdrv_get_cumulative_perm(new_bs, &perm, &shared_perm);
45
- bdrv_set_perm(new_bs, perm, shared_perm);
46
- }
47
}
48
49
/*
87
--
50
--
88
2.20.1
51
2.20.1
89
52
90
53
diff view generated by jsdifflib
1
Offset 0 can be valid for normal (allocated) clusters now, so use
1
From: Max Reitz <mreitz@redhat.com>
2
qcow2_get_cluster_type() instead.
2
3
3
This patch makes three functions report whether the necessary permission
4
change tightens restrictions or not. These functions are:
5
- bdrv_check_perm()
6
- bdrv_check_update_perm()
7
- bdrv_child_check_perm()
8
9
Callers can use this result to decide whether a failure is fatal or not
10
(see the next patch).
11
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
14
---
6
block/qcow2-cluster.c | 4 ++--
15
block.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++-----------
7
1 file changed, 2 insertions(+), 2 deletions(-)
16
1 file changed, 70 insertions(+), 17 deletions(-)
8
17
9
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
18
diff --git a/block.c b/block.c
10
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
11
--- a/block/qcow2-cluster.c
20
--- a/block.c
12
+++ b/block/qcow2-cluster.c
21
+++ b/block.c
13
@@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters(BlockDriverState *bs, int nb_clusters,
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_fill_options(QDict **options, const char *filename,
14
uint64_t first_entry = be64_to_cpu(l2_slice[0]);
23
15
uint64_t offset = first_entry & mask;
24
static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
16
25
uint64_t perm, uint64_t shared,
17
- if (!offset) {
26
- GSList *ignore_children, Error **errp);
18
+ first_cluster_type = qcow2_get_cluster_type(bs, first_entry);
27
+ GSList *ignore_children,
19
+ if (first_cluster_type == QCOW2_CLUSTER_UNALLOCATED) {
28
+ bool *tighten_restrictions, Error **errp);
20
return 0;
29
static void bdrv_child_abort_perm_update(BdrvChild *c);
30
static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
31
static void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
32
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
33
* permissions of all its parents. This involves checking whether all necessary
34
* permission changes to child nodes can be performed.
35
*
36
+ * Will set *tighten_restrictions to true if and only if new permissions have to
37
+ * be taken or currently shared permissions are to be unshared. Otherwise,
38
+ * errors are not fatal as long as the caller accepts that the restrictions
39
+ * remain tighter than they need to be. The caller still has to abort the
40
+ * transaction.
41
+ * @tighten_restrictions cannot be used together with @q: When reopening, we may
42
+ * encounter fatal errors even though no restrictions are to be tightened. For
43
+ * example, changing a node from RW to RO will fail if the WRITE permission is
44
+ * to be kept.
45
+ *
46
* A call to this function must always be followed by a call to bdrv_set_perm()
47
* or bdrv_abort_perm_update().
48
*/
49
static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
50
uint64_t cumulative_perms,
51
uint64_t cumulative_shared_perms,
52
- GSList *ignore_children, Error **errp)
53
+ GSList *ignore_children,
54
+ bool *tighten_restrictions, Error **errp)
55
{
56
BlockDriver *drv = bs->drv;
57
BdrvChild *c;
58
int ret;
59
60
+ assert(!q || !tighten_restrictions);
61
+
62
+ if (tighten_restrictions) {
63
+ uint64_t current_perms, current_shared;
64
+ uint64_t added_perms, removed_shared_perms;
65
+
66
+ bdrv_get_cumulative_perm(bs, &current_perms, &current_shared);
67
+
68
+ added_perms = cumulative_perms & ~current_perms;
69
+ removed_shared_perms = current_shared & ~cumulative_shared_perms;
70
+
71
+ *tighten_restrictions = added_perms || removed_shared_perms;
72
+ }
73
+
74
/* Write permissions never work with read-only images */
75
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
76
!bdrv_is_writable_after_reopen(bs, q))
77
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
78
/* Check all children */
79
QLIST_FOREACH(c, &bs->children, next) {
80
uint64_t cur_perm, cur_shared;
81
+ bool child_tighten_restr;
82
+
83
bdrv_child_perm(bs, c->bs, c, c->role, q,
84
cumulative_perms, cumulative_shared_perms,
85
&cur_perm, &cur_shared);
86
- ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared,
87
- ignore_children, errp);
88
+ ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared, ignore_children,
89
+ tighten_restrictions ? &child_tighten_restr
90
+ : NULL,
91
+ errp);
92
+ if (tighten_restrictions) {
93
+ *tighten_restrictions |= child_tighten_restr;
94
+ }
95
if (ret < 0) {
96
return ret;
97
}
98
@@ -XXX,XX +XXX,XX @@ char *bdrv_perm_names(uint64_t perm)
99
* set, the BdrvChild objects in this list are ignored in the calculations;
100
* this allows checking permission updates for an existing reference.
101
*
102
+ * See bdrv_check_perm() for the semantics of @tighten_restrictions.
103
+ *
104
* Needs to be followed by a call to either bdrv_set_perm() or
105
* bdrv_abort_perm_update(). */
106
static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
107
uint64_t new_used_perm,
108
uint64_t new_shared_perm,
109
- GSList *ignore_children, Error **errp)
110
+ GSList *ignore_children,
111
+ bool *tighten_restrictions,
112
+ Error **errp)
113
{
114
BdrvChild *c;
115
uint64_t cumulative_perms = new_used_perm;
116
uint64_t cumulative_shared_perms = new_shared_perm;
117
118
+ assert(!q || !tighten_restrictions);
119
+
120
/* There is no reason why anyone couldn't tolerate write_unchanged */
121
assert(new_shared_perm & BLK_PERM_WRITE_UNCHANGED);
122
123
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
124
if ((new_used_perm & c->shared_perm) != new_used_perm) {
125
char *user = bdrv_child_user_desc(c);
126
char *perm_names = bdrv_perm_names(new_used_perm & ~c->shared_perm);
127
+
128
+ if (tighten_restrictions) {
129
+ *tighten_restrictions = true;
130
+ }
131
+
132
error_setg(errp, "Conflicts with use by %s as '%s', which does not "
133
"allow '%s' on %s",
134
user, c->name, perm_names, bdrv_get_node_name(c->bs));
135
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
136
if ((c->perm & new_shared_perm) != c->perm) {
137
char *user = bdrv_child_user_desc(c);
138
char *perm_names = bdrv_perm_names(c->perm & ~new_shared_perm);
139
+
140
+ if (tighten_restrictions) {
141
+ *tighten_restrictions = true;
142
+ }
143
+
144
error_setg(errp, "Conflicts with use by %s as '%s', which uses "
145
"'%s' on %s",
146
user, c->name, perm_names, bdrv_get_node_name(c->bs));
147
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
21
}
148
}
22
149
23
/* must be allocated */
150
return bdrv_check_perm(bs, q, cumulative_perms, cumulative_shared_perms,
24
- first_cluster_type = qcow2_get_cluster_type(bs, first_entry);
151
- ignore_children, errp);
25
assert(first_cluster_type == QCOW2_CLUSTER_NORMAL ||
152
+ ignore_children, tighten_restrictions, errp);
26
first_cluster_type == QCOW2_CLUSTER_ZERO_ALLOC);
153
}
154
155
/* Needs to be followed by a call to either bdrv_child_set_perm() or
156
* bdrv_child_abort_perm_update(). */
157
static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
158
uint64_t perm, uint64_t shared,
159
- GSList *ignore_children, Error **errp)
160
+ GSList *ignore_children,
161
+ bool *tighten_restrictions, Error **errp)
162
{
163
int ret;
164
165
ignore_children = g_slist_prepend(g_slist_copy(ignore_children), c);
166
- ret = bdrv_check_update_perm(c->bs, q, perm, shared, ignore_children, errp);
167
+ ret = bdrv_check_update_perm(c->bs, q, perm, shared, ignore_children,
168
+ tighten_restrictions, errp);
169
g_slist_free(ignore_children);
170
171
if (ret < 0) {
172
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
173
{
174
int ret;
175
176
- ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL, errp);
177
+ ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL, NULL, errp);
178
if (ret < 0) {
179
bdrv_child_abort_perm_update(c);
180
return ret;
181
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
182
* because we're just taking a parent away, so we're loosening
183
* restrictions. */
184
bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm);
185
- bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL, &error_abort);
186
+ bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL,
187
+ NULL, &error_abort);
188
bdrv_set_perm(old_bs, perm, shared_perm);
189
190
/* When the parent requiring a non-default AioContext is removed, the
191
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
192
Error *local_err = NULL;
193
int ret;
194
195
- ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, errp);
196
+ ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, NULL,
197
+ errp);
198
if (ret < 0) {
199
bdrv_abort_perm_update(child_bs);
200
bdrv_unref(child_bs);
201
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
202
QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
203
BDRVReopenState *state = &bs_entry->state;
204
ret = bdrv_check_perm(state->bs, bs_queue, state->perm,
205
- state->shared_perm, NULL, errp);
206
+ state->shared_perm, NULL, NULL, errp);
207
if (ret < 0) {
208
goto cleanup_perm;
209
}
210
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
211
state->perm, state->shared_perm,
212
&nperm, &nshared);
213
ret = bdrv_check_update_perm(state->new_backing_bs, NULL,
214
- nperm, nshared, NULL, errp);
215
+ nperm, nshared, NULL, NULL, errp);
216
if (ret < 0) {
217
goto cleanup_perm;
218
}
219
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
220
221
/* Check whether the required permissions can be granted on @to, ignoring
222
* all BdrvChild in @list so that they can't block themselves. */
223
- ret = bdrv_check_update_perm(to, NULL, perm, shared, list, errp);
224
+ ret = bdrv_check_update_perm(to, NULL, perm, shared, list, NULL, errp);
225
if (ret < 0) {
226
bdrv_abort_perm_update(to);
227
goto out;
228
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
229
/* Check whether we are allowed to switch c from top to base */
230
GSList *ignore_children = g_slist_prepend(NULL, c);
231
ret = bdrv_check_update_perm(base, NULL, c->perm, c->shared_perm,
232
- ignore_children, &local_err);
233
+ ignore_children, NULL, &local_err);
234
g_slist_free(ignore_children);
235
if (ret < 0) {
236
error_report_err(local_err);
237
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
238
*/
239
bs->open_flags &= ~BDRV_O_INACTIVE;
240
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
241
- ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &local_err);
242
+ ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &local_err);
243
if (ret < 0) {
244
bs->open_flags |= BDRV_O_INACTIVE;
245
error_propagate(errp, local_err);
246
@@ -XXX,XX +XXX,XX @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
247
248
/* Update permissions, they may differ for inactive nodes */
249
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
250
- bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &error_abort);
251
+ bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &error_abort);
252
bdrv_set_perm(bs, perm, shared_perm);
253
27
254
28
--
255
--
29
2.20.1
256
2.20.1
30
257
31
258
diff view generated by jsdifflib
Deleted patch
1
The cluster allocation code uses 0 as an invalid offset that is used in
2
case of errors or as "offset not yet determined". With external data
3
files, a host cluster offset of 0 becomes valid, though.
4
1
5
Define a constant INV_OFFSET (which is not cluster aligned and will
6
therefore never be a valid offset) that can be used for such purposes.
7
8
This removes the additional host_offset == 0 check that commit
9
ff52aab2df5 introduced; the confusion between an invalid offset and
10
(erroneous) allocation at offset 0 is removed with this change.
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/qcow2.h | 2 ++
15
block/qcow2-cluster.c | 59 ++++++++++++++++++++-----------------------
16
2 files changed, 29 insertions(+), 32 deletions(-)
17
18
diff --git a/block/qcow2.h b/block/qcow2.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2.h
21
+++ b/block/qcow2.h
22
@@ -XXX,XX +XXX,XX @@ typedef enum QCow2MetadataOverlap {
23
24
#define REFT_OFFSET_MASK 0xfffffffffffffe00ULL
25
26
+#define INV_OFFSET (-1ULL)
27
+
28
static inline bool has_data_file(BlockDriverState *bs)
29
{
30
BDRVQcow2State *s = bs->opaque;
31
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block/qcow2-cluster.c
34
+++ b/block/qcow2-cluster.c
35
@@ -XXX,XX +XXX,XX @@ static int handle_dependencies(BlockDriverState *bs, uint64_t guest_offset,
36
37
/*
38
* Checks how many already allocated clusters that don't require a copy on
39
- * write there are at the given guest_offset (up to *bytes). If
40
- * *host_offset is not zero, only physically contiguous clusters beginning at
41
- * this host offset are counted.
42
+ * write there are at the given guest_offset (up to *bytes). If *host_offset is
43
+ * not INV_OFFSET, only physically contiguous clusters beginning at this host
44
+ * offset are counted.
45
*
46
* Note that guest_offset may not be cluster aligned. In this case, the
47
* returned *host_offset points to exact byte referenced by guest_offset and
48
@@ -XXX,XX +XXX,XX @@ static int handle_copied(BlockDriverState *bs, uint64_t guest_offset,
49
trace_qcow2_handle_copied(qemu_coroutine_self(), guest_offset, *host_offset,
50
*bytes);
51
52
- assert(*host_offset == 0 || offset_into_cluster(s, guest_offset)
53
- == offset_into_cluster(s, *host_offset));
54
+ assert(*host_offset == INV_OFFSET || offset_into_cluster(s, guest_offset)
55
+ == offset_into_cluster(s, *host_offset));
56
57
/*
58
* Calculate the number of clusters to look for. We stop at L2 slice
59
@@ -XXX,XX +XXX,XX @@ static int handle_copied(BlockDriverState *bs, uint64_t guest_offset,
60
goto out;
61
}
62
63
- if (*host_offset != 0 && !offset_matches) {
64
+ if (*host_offset != INV_OFFSET && !offset_matches) {
65
*bytes = 0;
66
ret = 0;
67
goto out;
68
@@ -XXX,XX +XXX,XX @@ out:
69
* contain the number of clusters that have been allocated and are contiguous
70
* in the image file.
71
*
72
- * If *host_offset is non-zero, it specifies the offset in the image file at
73
- * which the new clusters must start. *nb_clusters can be 0 on return in this
74
- * case if the cluster at host_offset is already in use. If *host_offset is
75
- * zero, the clusters can be allocated anywhere in the image file.
76
+ * If *host_offset is not INV_OFFSET, it specifies the offset in the image file
77
+ * at which the new clusters must start. *nb_clusters can be 0 on return in
78
+ * this case if the cluster at host_offset is already in use. If *host_offset
79
+ * is INV_OFFSET, the clusters can be allocated anywhere in the image file.
80
*
81
* *host_offset is updated to contain the offset into the image file at which
82
* the first allocated cluster starts.
83
@@ -XXX,XX +XXX,XX @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
84
85
/* Allocate new clusters */
86
trace_qcow2_cluster_alloc_phys(qemu_coroutine_self());
87
- if (*host_offset == 0) {
88
+ if (*host_offset == INV_OFFSET) {
89
int64_t cluster_offset =
90
qcow2_alloc_clusters(bs, *nb_clusters * s->cluster_size);
91
if (cluster_offset < 0) {
92
@@ -XXX,XX +XXX,XX @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
93
94
/*
95
* Allocates new clusters for an area that either is yet unallocated or needs a
96
- * copy on write. If *host_offset is non-zero, clusters are only allocated if
97
- * the new allocation can match the specified host offset.
98
+ * copy on write. If *host_offset is not INV_OFFSET, clusters are only
99
+ * allocated if the new allocation can match the specified host offset.
100
*
101
* Note that guest_offset may not be cluster aligned. In this case, the
102
* returned *host_offset points to exact byte referenced by guest_offset and
103
@@ -XXX,XX +XXX,XX @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
104
int ret;
105
bool keep_old_clusters = false;
106
107
- uint64_t alloc_cluster_offset = 0;
108
+ uint64_t alloc_cluster_offset = INV_OFFSET;
109
110
trace_qcow2_handle_alloc(qemu_coroutine_self(), guest_offset, *host_offset,
111
*bytes);
112
@@ -XXX,XX +XXX,XX @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
113
114
if (qcow2_get_cluster_type(bs, entry) == QCOW2_CLUSTER_ZERO_ALLOC &&
115
(entry & QCOW_OFLAG_COPIED) &&
116
- (!*host_offset ||
117
+ (*host_offset == INV_OFFSET ||
118
start_of_cluster(s, *host_offset) == (entry & L2E_OFFSET_MASK)))
119
{
120
int preallocated_nb_clusters;
121
@@ -XXX,XX +XXX,XX @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
122
123
qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
124
125
- if (!alloc_cluster_offset) {
126
+ if (alloc_cluster_offset == INV_OFFSET) {
127
/* Allocate, if necessary at a given offset in the image file */
128
- alloc_cluster_offset = start_of_cluster(s, *host_offset);
129
+ alloc_cluster_offset = *host_offset == INV_OFFSET ? INV_OFFSET :
130
+ start_of_cluster(s, *host_offset);
131
ret = do_alloc_cluster_offset(bs, guest_offset, &alloc_cluster_offset,
132
&nb_clusters);
133
if (ret < 0) {
134
@@ -XXX,XX +XXX,XX @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
135
return 0;
136
}
137
138
- /* !*host_offset would overwrite the image header and is reserved for
139
- * "no host offset preferred". If 0 was a valid host offset, it'd
140
- * trigger the following overlap check; do that now to avoid having an
141
- * invalid value in *host_offset. */
142
- if (!alloc_cluster_offset) {
143
- ret = qcow2_pre_write_overlap_check(bs, 0, alloc_cluster_offset,
144
- nb_clusters * s->cluster_size);
145
- assert(ret < 0);
146
- goto fail;
147
- }
148
+ assert(alloc_cluster_offset != INV_OFFSET);
149
}
150
151
/*
152
@@ -XXX,XX +XXX,XX @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
153
again:
154
start = offset;
155
remaining = *bytes;
156
- cluster_offset = 0;
157
- *host_offset = 0;
158
+ cluster_offset = INV_OFFSET;
159
+ *host_offset = INV_OFFSET;
160
cur_bytes = 0;
161
*m = NULL;
162
163
while (true) {
164
165
- if (!*host_offset) {
166
+ if (*host_offset == INV_OFFSET && cluster_offset != INV_OFFSET) {
167
*host_offset = start_of_cluster(s, cluster_offset);
168
}
169
170
@@ -XXX,XX +XXX,XX @@ again:
171
172
start += cur_bytes;
173
remaining -= cur_bytes;
174
- cluster_offset += cur_bytes;
175
+
176
+ if (cluster_offset != INV_OFFSET) {
177
+ cluster_offset += cur_bytes;
178
+ }
179
180
if (remaining == 0) {
181
break;
182
@@ -XXX,XX +XXX,XX @@ again:
183
184
*bytes -= remaining;
185
assert(*bytes > 0);
186
- assert(*host_offset != 0);
187
+ assert(*host_offset != INV_OFFSET);
188
189
return 0;
190
}
191
--
192
2.20.1
193
194
diff view generated by jsdifflib
Deleted patch
1
Offset 0 cannot be assumed to mean an unallocated cluster any more.
2
Instead, the cluster type needs to be checked.
3
1
4
*file must refer to the data file instead of the image file if a valid
5
offset is returned from qcow2_co_block_status().
6
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/qcow2.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/block/qcow2.c b/block/qcow2.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/qcow2.c
15
+++ b/block/qcow2.c
16
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
17
18
*pnum = bytes;
19
20
- if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
21
+ if ((ret == QCOW2_CLUSTER_NORMAL || ret == QCOW2_CLUSTER_ZERO_ALLOC) &&
22
!s->crypto) {
23
index_in_cluster = offset & (s->cluster_size - 1);
24
*map = cluster_offset | index_in_cluster;
25
- *file = bs->file->bs;
26
+ *file = s->data_file->bs;
27
status |= BDRV_BLOCK_OFFSET_VALID;
28
}
29
if (ret == QCOW2_CLUSTER_ZERO_PLAIN || ret == QCOW2_CLUSTER_ZERO_ALLOC) {
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
1
Internal snapshots and an external data file are incompatible because
1
From: Max Reitz <mreitz@redhat.com>
2
snapshots require refcounting and non-linear mapping. Return an error
3
for all of the snapshot operations if an external data file is in use.
4
2
3
We generally assume that loosening permission restrictions can never
4
fail. We have seen in the past that this assumption is wrong. This has
5
led to crashes because we generally pass &error_abort when loosening
6
permissions.
7
8
However, a failure in such a case should actually be handled in quite
9
the opposite way: It is very much not fatal, so qemu may report it, but
10
still consider the operation successful. The only realistic problem is
11
that qemu may then retain permissions and thus locks on images it
12
actually does not require. But again, that is not fatal.
13
14
To implement this behavior, we make all functions that change
15
permissions and that pass &error_abort to the initiating function
16
(bdrv_check_perm() or bdrv_child_check_perm()) evaluate the
17
@loosen_restrictions value introduced in the previous patch. If it is
18
true and an error did occur, we abort the permission update, discard the
19
error, and instead report success to the caller.
20
21
bdrv_child_try_set_perm() itself does not pass &error_abort, but it is
22
the only public function to change permissions. As such, callers may
23
pass &error_abort to it, expecting dropping permission restrictions to
24
never fail.
25
26
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
28
---
7
block/qcow2-snapshot.c | 15 +++++++++++++++
29
block.c | 44 ++++++++++++++++++++++++++++++++++++++------
8
1 file changed, 15 insertions(+)
30
1 file changed, 38 insertions(+), 6 deletions(-)
9
31
10
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
32
diff --git a/block.c b/block.c
11
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
12
--- a/block/qcow2-snapshot.c
34
--- a/block.c
13
+++ b/block/qcow2-snapshot.c
35
+++ b/block.c
14
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
36
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_abort_perm_update(BdrvChild *c)
15
return -EFBIG;
37
int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
38
Error **errp)
39
{
40
+ Error *local_err = NULL;
41
int ret;
42
+ bool tighten_restrictions;
43
44
- ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL, NULL, errp);
45
+ ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL,
46
+ &tighten_restrictions, &local_err);
47
if (ret < 0) {
48
bdrv_child_abort_perm_update(c);
49
+ if (tighten_restrictions) {
50
+ error_propagate(errp, local_err);
51
+ } else {
52
+ /*
53
+ * Our caller may intend to only loosen restrictions and
54
+ * does not expect this function to fail. Errors are not
55
+ * fatal in such a case, so we can just hide them from our
56
+ * caller.
57
+ */
58
+ error_free(local_err);
59
+ ret = 0;
60
+ }
61
return ret;
16
}
62
}
17
63
18
+ if (has_data_file(bs)) {
64
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
19
+ return -ENOTSUP;
65
/* Update permissions for old node. This is guaranteed to succeed
66
* because we're just taking a parent away, so we're loosening
67
* restrictions. */
68
+ bool tighten_restrictions;
69
+ int ret;
70
+
71
bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm);
72
- bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL,
73
- NULL, &error_abort);
74
- bdrv_set_perm(old_bs, perm, shared_perm);
75
+ ret = bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL,
76
+ &tighten_restrictions, NULL);
77
+ assert(tighten_restrictions == false);
78
+ if (ret < 0) {
79
+ /* We only tried to loosen restrictions, so errors are not fatal */
80
+ bdrv_abort_perm_update(old_bs);
81
+ } else {
82
+ bdrv_set_perm(old_bs, perm, shared_perm);
83
+ }
84
85
/* When the parent requiring a non-default AioContext is removed, the
86
* node moves back to the main AioContext */
87
@@ -XXX,XX +XXX,XX @@ static bool bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
88
static int bdrv_inactivate_recurse(BlockDriverState *bs)
89
{
90
BdrvChild *child, *parent;
91
+ bool tighten_restrictions;
92
uint64_t perm, shared_perm;
93
int ret;
94
95
@@ -XXX,XX +XXX,XX @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
96
97
/* Update permissions, they may differ for inactive nodes */
98
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
99
- bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &error_abort);
100
- bdrv_set_perm(bs, perm, shared_perm);
101
+ ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL,
102
+ &tighten_restrictions, NULL);
103
+ assert(tighten_restrictions == false);
104
+ if (ret < 0) {
105
+ /* We only tried to loosen restrictions, so errors are not fatal */
106
+ bdrv_abort_perm_update(bs);
107
+ } else {
108
+ bdrv_set_perm(bs, perm, shared_perm);
20
+ }
109
+ }
21
+
110
22
memset(sn, 0, sizeof(*sn));
111
23
112
/* Recursively inactivate children */
24
/* Generate an ID */
25
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
26
int ret;
27
uint64_t *sn_l1_table = NULL;
28
29
+ if (has_data_file(bs)) {
30
+ return -ENOTSUP;
31
+ }
32
+
33
/* Search the snapshot */
34
snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
35
if (snapshot_index < 0) {
36
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_delete(BlockDriverState *bs,
37
QCowSnapshot sn;
38
int snapshot_index, ret;
39
40
+ if (has_data_file(bs)) {
41
+ return -ENOTSUP;
42
+ }
43
+
44
/* Search the snapshot */
45
snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);
46
if (snapshot_index < 0) {
47
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
48
QCowSnapshot *sn;
49
int i;
50
51
+ if (has_data_file(bs)) {
52
+ return -ENOTSUP;
53
+ }
54
if (!s->nb_snapshots) {
55
*psn_tab = NULL;
56
return s->nb_snapshots;
57
--
113
--
58
2.20.1
114
2.20.1
59
115
60
116
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
2
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
---
5
---
3
tests/qemu-iotests/061 | 45 ++++++++++++++++++-
6
tests/qemu-iotests/182 | 21 +++++++++++++++++++++
4
tests/qemu-iotests/061.out | 89 ++++++++++++++++++++++++++++++++++++++
7
tests/qemu-iotests/182.out | 6 ++++++
5
2 files changed, 133 insertions(+), 1 deletion(-)
8
2 files changed, 27 insertions(+)
6
9
7
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
10
diff --git a/tests/qemu-iotests/182 b/tests/qemu-iotests/182
8
index XXXXXXX..XXXXXXX 100755
11
index XXXXXXX..XXXXXXX 100755
9
--- a/tests/qemu-iotests/061
12
--- a/tests/qemu-iotests/182
10
+++ b/tests/qemu-iotests/061
13
+++ b/tests/qemu-iotests/182
11
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
14
@@ -XXX,XX +XXX,XX @@ success_or_failure=y _send_qemu_cmd $QEMU_HANDLE \
12
15
13
_cleanup()
16
_cleanup_qemu
14
{
15
-    _cleanup_test_img
16
+ _cleanup_test_img
17
+ rm -f $TEST_IMG.data
18
}
19
trap "_cleanup; exit \$status" 0 1 2 3 15
20
21
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG snapshot -c foo "$TEST_IMG"
22
$QEMU_IMG amend -p -o "compat=0.10" "$TEST_IMG"
23
_check_test_img
24
17
25
+echo
18
+echo
26
+echo "=== Testing version downgrade with external data file ==="
19
+echo '=== Testing failure to loosen restrictions ==='
27
+echo
20
+echo
28
+IMGOPTS="compat=1.1,data_file=$TEST_IMG.data" _make_test_img 64M
29
+$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
30
+_img_info --format-specific
31
+_check_test_img
32
+
21
+
33
+echo
22
+_launch_qemu -drive file=$TEST_IMG,if=none,file.locking=on
34
+echo "=== Try changing the external data file ==="
35
+echo
36
+IMGOPTS="compat=1.1" _make_test_img 64M
37
+$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
38
+
23
+
39
+echo
24
+_send_qemu_cmd $QEMU_HANDLE \
40
+IMGOPTS="compat=1.1,data_file=$TEST_IMG.data" _make_test_img 64M
25
+ "{'execute': 'qmp_capabilities'}" \
41
+$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
26
+ 'return'
42
+_img_info --format-specific
43
+TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
44
+
27
+
45
+echo
28
+_cleanup_test_img
46
+$QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG"
47
+_img_info --format-specific
48
+TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
49
+
29
+
50
+echo
30
+# When quitting qemu, it will try to drop its locks on the test image.
51
+echo "=== Clearing and setting data-file-raw ==="
31
+# Because that file no longer exists, it will be unable to do so.
52
+echo
32
+# However, that is not fatal, so it should just move on.
53
+IMGOPTS="compat=1.1,data_file=$TEST_IMG.data,data_file_raw=on" _make_test_img 64M
33
+_send_qemu_cmd $QEMU_HANDLE \
54
+$QEMU_IMG amend -o "data_file_raw=on" "$TEST_IMG"
34
+ "{'execute': 'quit'}" \
55
+_img_info --format-specific
35
+ 'return'
56
+_check_test_img
57
+
36
+
58
+$QEMU_IMG amend -o "data_file_raw=off" "$TEST_IMG"
37
+wait=1 _cleanup_qemu
59
+_img_info --format-specific
60
+_check_test_img
61
+
62
+$QEMU_IMG amend -o "data_file_raw=on" "$TEST_IMG"
63
+_img_info --format-specific
64
+_check_test_img
65
+
66
+
38
+
67
# success, all done
39
# success, all done
68
echo "*** done"
40
echo "*** done"
69
rm -f $seq.full
41
rm -f $seq.full
70
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
42
diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out
71
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
72
--- a/tests/qemu-iotests/061.out
44
--- a/tests/qemu-iotests/182.out
73
+++ b/tests/qemu-iotests/061.out
45
+++ b/tests/qemu-iotests/182.out
74
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 3221225472
46
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 size=197120 backing_file=TEST_D
75
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
47
{"return": {}}
76
(0.00/100%)
48
{"return": {}}
77
(6.25/100%)
49
{"return": {}}
78
(12.50/100%)
79
(18.75/100%)
80
(25.00/100%)
81
(31.25/100%)
82
(37.50/100%)
83
(43.75/100%)
84
(50.00/100%)
85
(56.25/100%)
86
(62.50/100%)
87
(68.75/100%)
88
(75.00/100%)
89
(81.25/100%)
90
(87.50/100%)
91
(93.75/100%)
92
(100.00/100%)
93
(100.00/100%)
94
No errors were found on the image.
95
+
50
+
96
+=== Testing version downgrade with external data file ===
51
+=== Testing failure to loosen restrictions ===
97
+
52
+
98
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
53
+{"return": {}}
99
+qemu-img: Cannot downgrade an image with a data file
54
+{"return": {}}
100
+image: TEST_DIR/t.IMGFMT
55
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
101
+file format: IMGFMT
102
+virtual size: 64M (67108864 bytes)
103
+cluster_size: 65536
104
+Format specific information:
105
+ compat: 1.1
106
+ lazy refcounts: false
107
+ refcount bits: 16
108
+ data file: TEST_DIR/t.IMGFMT.data
109
+ data file raw: false
110
+ corrupt: false
111
+No errors were found on the image.
112
+
113
+=== Try changing the external data file ===
114
+
115
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
116
+qemu-img: data-file can only be set for images that use an external data file
117
+
118
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
119
+qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory
120
+image: TEST_DIR/t.IMGFMT
121
+file format: IMGFMT
122
+virtual size: 64M (67108864 bytes)
123
+cluster_size: 65536
124
+Format specific information:
125
+ compat: 1.1
126
+ lazy refcounts: false
127
+ refcount bits: 16
128
+ data file: foo
129
+ data file raw: false
130
+ corrupt: false
131
+
132
+qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
133
+image: TEST_DIR/t.IMGFMT
134
+file format: IMGFMT
135
+virtual size: 64M (67108864 bytes)
136
+cluster_size: 65536
137
+Format specific information:
138
+ compat: 1.1
139
+ lazy refcounts: false
140
+ refcount bits: 16
141
+ data file raw: false
142
+ corrupt: false
143
+
144
+=== Clearing and setting data-file-raw ===
145
+
146
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on
147
+image: TEST_DIR/t.IMGFMT
148
+file format: IMGFMT
149
+virtual size: 64M (67108864 bytes)
150
+cluster_size: 65536
151
+Format specific information:
152
+ compat: 1.1
153
+ lazy refcounts: false
154
+ refcount bits: 16
155
+ data file: TEST_DIR/t.IMGFMT.data
156
+ data file raw: true
157
+ corrupt: false
158
+No errors were found on the image.
159
+image: TEST_DIR/t.IMGFMT
160
+file format: IMGFMT
161
+virtual size: 64M (67108864 bytes)
162
+cluster_size: 65536
163
+Format specific information:
164
+ compat: 1.1
165
+ lazy refcounts: false
166
+ refcount bits: 16
167
+ data file: TEST_DIR/t.IMGFMT.data
168
+ data file raw: false
169
+ corrupt: false
170
+No errors were found on the image.
171
+qemu-img: data-file-raw cannot be set on existing images
172
+image: TEST_DIR/t.IMGFMT
173
+file format: IMGFMT
174
+virtual size: 64M (67108864 bytes)
175
+cluster_size: 65536
176
+Format specific information:
177
+ compat: 1.1
178
+ lazy refcounts: false
179
+ refcount bits: 16
180
+ data file: TEST_DIR/t.IMGFMT.data
181
+ data file raw: false
182
+ corrupt: false
183
+No errors were found on the image.
184
*** done
56
*** done
185
--
57
--
186
2.20.1
58
2.20.1
187
59
188
60
diff view generated by jsdifflib
1
This adds a .bdrv_open option to specify the external data file node.
1
Commit cd219eb1e55 added the read-zeroes option for the null-co and
2
null-aio block driver, but forgot to add them to the QAPI schema.
3
Therefore, this option wasn't available in -blockdev and blockdev-add
4
until now.
5
6
Add the missing option in the schema to make it available there, too.
2
7
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
4
---
10
---
5
qapi/block-core.json | 7 ++++++-
11
qapi/block-core.json | 4 +++-
6
block/qcow2.h | 4 +++-
12
1 file changed, 3 insertions(+), 1 deletion(-)
7
block/qcow2.c | 34 ++++++++++++++++++++++++++++++++--
8
3 files changed, 41 insertions(+), 4 deletions(-)
9
13
10
diff --git a/qapi/block-core.json b/qapi/block-core.json
14
diff --git a/qapi/block-core.json b/qapi/block-core.json
11
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
12
--- a/qapi/block-core.json
16
--- a/qapi/block-core.json
13
+++ b/qapi/block-core.json
17
+++ b/qapi/block-core.json
14
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
15
# encrypted images, except when doing a metadata-only
19
# @latency-ns: emulated latency (in nanoseconds) in processing
16
# probe of the image. (since 2.10)
20
# requests. Default to zero which completes requests immediately.
21
# (Since 2.4)
22
+# @read-zeroes: if true, reads from the device produce zeroes; if false, the
23
+# buffer is left unchanged. (default: false; since: 4.1)
17
#
24
#
18
+# @data-file: reference to or definition of the external data file.
19
+# This may only be specified for images that require an
20
+# external data file. (since 4.0)
21
+#
22
# Since: 2.9
25
# Since: 2.9
23
##
26
##
24
{ 'struct': 'BlockdevOptionsQcow2',
27
{ 'struct': 'BlockdevOptionsNull',
25
@@ -XXX,XX +XXX,XX @@
28
- 'data': { '*size': 'int', '*latency-ns': 'uint64' } }
26
'*l2-cache-entry-size': 'int',
29
+ 'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
27
'*refcount-cache-size': 'int',
28
'*cache-clean-interval': 'int',
29
- '*encrypt': 'BlockdevQcow2Encryption' } }
30
+ '*encrypt': 'BlockdevQcow2Encryption',
31
+ '*data-file': 'BlockdevRef' } }
32
30
33
##
31
##
34
# @SshHostKeyCheckMode:
32
# @BlockdevOptionsNVMe:
35
diff --git a/block/qcow2.h b/block/qcow2.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/block/qcow2.h
38
+++ b/block/qcow2.h
39
@@ -XXX,XX +XXX,XX @@
40
41
#define DEFAULT_CLUSTER_SIZE 65536
42
43
+#define QCOW2_OPT_DATA_FILE "data-file"
44
#define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts"
45
#define QCOW2_OPT_DISCARD_REQUEST "pass-discard-request"
46
#define QCOW2_OPT_DISCARD_SNAPSHOT "pass-discard-snapshot"
47
@@ -XXX,XX +XXX,XX @@ enum {
48
QCOW2_INCOMPAT_DATA_FILE = 1 << QCOW2_INCOMPAT_DATA_FILE_BITNR,
49
50
QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
51
- | QCOW2_INCOMPAT_CORRUPT,
52
+ | QCOW2_INCOMPAT_CORRUPT
53
+ | QCOW2_INCOMPAT_DATA_FILE,
54
};
55
56
/* Compatible feature bits */
57
diff --git a/block/qcow2.c b/block/qcow2.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/qcow2.c
60
+++ b/block/qcow2.c
61
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
62
goto fail;
63
}
64
65
- /* TODO Open external data file */
66
- s->data_file = bs->file;
67
+ /* Open external data file */
68
+ s->data_file = bdrv_open_child(NULL, options, "data-file", bs, &child_file,
69
+ true, &local_err);
70
+ if (local_err) {
71
+ error_propagate(errp, local_err);
72
+ ret = -EINVAL;
73
+ goto fail;
74
+ }
75
+
76
+ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
77
+ if (!s->data_file) {
78
+ error_setg(errp, "'data-file' is required for this image");
79
+ ret = -EINVAL;
80
+ goto fail;
81
+ }
82
+ } else {
83
+ if (s->data_file) {
84
+ error_setg(errp, "'data-file' can only be set for images with an "
85
+ "external data file");
86
+ ret = -EINVAL;
87
+ goto fail;
88
+ } else {
89
+ s->data_file = bs->file;
90
+ }
91
+ }
92
93
/* qcow2_read_extension may have set up the crypto context
94
* if the crypt method needs a header region, some methods
95
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
96
return ret;
97
98
fail:
99
+ if (has_data_file(bs)) {
100
+ bdrv_unref_child(bs, s->data_file);
101
+ }
102
g_free(s->unknown_header_fields);
103
cleanup_unknown_header_ext(bs);
104
qcow2_free_snapshots(bs);
105
@@ -XXX,XX +XXX,XX @@ static void qcow2_close(BlockDriverState *bs)
106
g_free(s->image_backing_file);
107
g_free(s->image_backing_format);
108
109
+ if (has_data_file(bs)) {
110
+ bdrv_unref_child(bs, s->data_file);
111
+ }
112
+
113
qcow2_refcount_close(bs);
114
qcow2_free_snapshots(bs);
115
}
116
--
33
--
117
2.20.1
34
2.20.1
118
35
119
36
diff view generated by jsdifflib
Deleted patch
1
Test that preallocating metadata results in a somewhat larger qcow2
2
file, but preallocating data only affects the disk usage of the data
3
file and the qcow2 file stays small.
4
1
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
tests/qemu-iotests/243 | 22 ++++++++++++++++++++++
8
tests/qemu-iotests/243.out | 32 ++++++++++++++++++++++++++++++++
9
2 files changed, 54 insertions(+)
10
11
diff --git a/tests/qemu-iotests/243 b/tests/qemu-iotests/243
12
index XXXXXXX..XXXXXXX 100755
13
--- a/tests/qemu-iotests/243
14
+++ b/tests/qemu-iotests/243
15
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
16
_cleanup()
17
{
18
_cleanup_test_img
19
+ rm -f $TEST_IMG.data
20
}
21
trap "_cleanup; exit \$status" 0 1 2 3 15
22
23
@@ -XXX,XX +XXX,XX @@ for mode in off metadata falloc full; do
24
25
done
26
27
+for mode in off metadata falloc full; do
28
+
29
+ echo
30
+ echo "=== External data file: preallocation=$mode ==="
31
+ echo
32
+
33
+ IMGOPTS="data_file=$TEST_IMG.data,preallocation=$mode" _make_test_img 64M
34
+
35
+ echo -n "qcow2 file size: "
36
+ du -b $TEST_IMG | cut -f1
37
+ echo -n "data file size: "
38
+ du -b $TEST_IMG.data | cut -f1
39
+
40
+ # Can't use precise numbers here because they differ between filesystems
41
+ echo -n "qcow2 disk usage: "
42
+ [ $(du -B1 $TEST_IMG | cut -f1) -lt 1048576 ] && echo "low" || echo "high"
43
+ echo -n "data disk usage: "
44
+ [ $(du -B1 $TEST_IMG.data | cut -f1) -lt 1048576 ] && echo "low" || echo "high"
45
+
46
+done
47
+
48
# success, all done
49
echo "*** done"
50
rm -f $seq.full
51
diff --git a/tests/qemu-iotests/243.out b/tests/qemu-iotests/243.out
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/243.out
54
+++ b/tests/qemu-iotests/243.out
55
@@ -XXX,XX +XXX,XX @@ Disk usage: high
56
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 preallocation=full
57
File size: 67436544
58
Disk usage: high
59
+
60
+=== External data file: preallocation=off ===
61
+
62
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data preallocation=off
63
+qcow2 file size: 196616
64
+data file size: 67108864
65
+qcow2 disk usage: low
66
+data disk usage: low
67
+
68
+=== External data file: preallocation=metadata ===
69
+
70
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data preallocation=metadata
71
+qcow2 file size: 327680
72
+data file size: 67108864
73
+qcow2 disk usage: low
74
+data disk usage: low
75
+
76
+=== External data file: preallocation=falloc ===
77
+
78
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data preallocation=falloc
79
+qcow2 file size: 327680
80
+data file size: 67108864
81
+qcow2 disk usage: low
82
+data disk usage: high
83
+
84
+=== External data file: preallocation=full ===
85
+
86
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data preallocation=full
87
+qcow2 file size: 327680
88
+data file size: 67108864
89
+qcow2 disk usage: low
90
+data disk usage: high
91
*** done
92
--
93
2.20.1
94
95
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
---
3
tests/qemu-iotests/244 | 200 +++++++++++++++++++++++++++++++++++++
4
tests/qemu-iotests/244.out | 125 +++++++++++++++++++++++
5
tests/qemu-iotests/group | 1 +
6
3 files changed, 326 insertions(+)
7
create mode 100755 tests/qemu-iotests/244
8
create mode 100644 tests/qemu-iotests/244.out
9
1
10
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
11
new file mode 100755
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tests/qemu-iotests/244
15
@@ -XXX,XX +XXX,XX @@
16
+#!/bin/bash
17
+#
18
+# Test qcow2 with external data files
19
+#
20
+# Copyright (C) 2019 Red Hat, Inc.
21
+#
22
+# This program is free software; you can redistribute it and/or modify
23
+# it under the terms of the GNU General Public License as published by
24
+# the Free Software Foundation; either version 2 of the License, or
25
+# (at your option) any later version.
26
+#
27
+# This program is distributed in the hope that it will be useful,
28
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
29
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
+# GNU General Public License for more details.
31
+#
32
+# You should have received a copy of the GNU General Public License
33
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
34
+#
35
+
36
+# creator
37
+owner=kwolf@redhat.com
38
+
39
+seq=$(basename $0)
40
+echo "QA output created by $seq"
41
+
42
+status=1    # failure is the default!
43
+
44
+_cleanup()
45
+{
46
+ _cleanup_test_img
47
+ rm -f $TEST_IMG.data
48
+ rm -f $TEST_IMG.src
49
+}
50
+trap "_cleanup; exit \$status" 0 1 2 3 15
51
+
52
+# get standard environment, filters and checks
53
+. ./common.rc
54
+. ./common.filter
55
+
56
+_supported_fmt qcow2
57
+_supported_proto file
58
+_supported_os Linux
59
+
60
+echo
61
+echo "=== Create and open image with external data file ==="
62
+echo
63
+
64
+echo "With data file name in the image:"
65
+IMGOPTS="data_file=$TEST_IMG.data" _make_test_img 64M
66
+_check_test_img
67
+
68
+$QEMU_IO -c "open $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
69
+$QEMU_IO -c "open -odata-file.filename=$TEST_IMG.data $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
70
+$QEMU_IO -c "open -odata-file.filename=inexistent $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
71
+
72
+echo
73
+echo "Data file required, but without data file name in the image:"
74
+$QEMU_IMG amend -odata_file= $TEST_IMG
75
+
76
+$QEMU_IO -c "open $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
77
+$QEMU_IO -c "open -odata-file.filename=$TEST_IMG.data $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
78
+$QEMU_IO -c "open -odata-file.filename=inexistent $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
79
+
80
+echo
81
+echo "Setting data-file for an image with internal data:"
82
+_make_test_img 64M
83
+
84
+$QEMU_IO -c "open -odata-file.filename=$TEST_IMG.data $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
85
+$QEMU_IO -c "open -odata-file.filename=inexistent $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
86
+
87
+echo
88
+echo "=== Conflicting features ==="
89
+echo
90
+
91
+echo "Convert to compressed target with data file:"
92
+TEST_IMG="$TEST_IMG.src" _make_test_img 64M
93
+
94
+$QEMU_IO -c 'write -P 0x11 0 1M' \
95
+ -f $IMGFMT "$TEST_IMG.src" |
96
+ _filter_qemu_io
97
+
98
+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -c -odata_file="$TEST_IMG.data" \
99
+ "$TEST_IMG.src" "$TEST_IMG"
100
+
101
+echo
102
+echo "Convert uncompressed, then write compressed data manually:"
103
+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -odata_file="$TEST_IMG.data" \
104
+ "$TEST_IMG.src" "$TEST_IMG"
105
+$QEMU_IMG compare "$TEST_IMG.src" "$TEST_IMG"
106
+
107
+$QEMU_IO -c 'write -c -P 0x22 0 1M' \
108
+ -f $IMGFMT "$TEST_IMG" |
109
+ _filter_qemu_io
110
+_check_test_img
111
+
112
+echo
113
+echo "Take an internal snapshot:"
114
+
115
+$QEMU_IMG snapshot -c test "$TEST_IMG"
116
+_check_test_img
117
+
118
+echo
119
+echo "=== Standalone image with external data file (efficient) ==="
120
+echo
121
+
122
+IMGOPTS="data_file=$TEST_IMG.data" _make_test_img 64M
123
+
124
+echo -n "qcow2 file size before I/O: "
125
+du -b $TEST_IMG | cut -f1
126
+
127
+# Create image with the following layout
128
+# 0-1 MB: Unallocated
129
+# 1-2 MB: Written (pattern 0x11)
130
+# 2-3 MB: Discarded
131
+# 3-4 MB: Zero write over discarded space
132
+# 4-5 MB: Zero write over written space
133
+# 5-6 MB: Zero write over unallocated space
134
+
135
+echo
136
+$QEMU_IO -c 'write -P 0x11 1M 4M' \
137
+ -c 'discard 2M 2M' \
138
+ -c 'write -z 3M 3M' \
139
+ -f $IMGFMT "$TEST_IMG" |
140
+ _filter_qemu_io
141
+_check_test_img
142
+
143
+echo
144
+$QEMU_IMG map --output=json "$TEST_IMG"
145
+
146
+echo
147
+$QEMU_IO -c 'read -P 0 0 1M' \
148
+ -c 'read -P 0x11 1M 1M' \
149
+ -c 'read -P 0 2M 4M' \
150
+ -f $IMGFMT "$TEST_IMG" |
151
+ _filter_qemu_io
152
+
153
+# Zero clusters are only marked as such in the qcow2 metadata, but contain
154
+# stale data in the external data file
155
+echo
156
+$QEMU_IO -c 'read -P 0 0 1M' \
157
+ -c 'read -P 0x11 1M 1M' \
158
+ -c 'read -P 0 2M 2M' \
159
+ -c 'read -P 0x11 4M 1M' \
160
+ -c 'read -P 0 5M 1M' \
161
+ -f raw "$TEST_IMG.data" |
162
+ _filter_qemu_io
163
+
164
+
165
+echo -n "qcow2 file size after I/O: "
166
+du -b $TEST_IMG | cut -f1
167
+
168
+echo
169
+echo "=== Standalone image with external data file (valid raw) ==="
170
+echo
171
+
172
+IMGOPTS="data_file=$TEST_IMG.data,data_file_raw=on" _make_test_img 64M
173
+
174
+echo -n "qcow2 file size before I/O: "
175
+du -b $TEST_IMG | cut -f1
176
+
177
+echo
178
+$QEMU_IO -c 'write -P 0x11 1M 4M' \
179
+ -c 'discard 2M 2M' \
180
+ -c 'write -z 3M 3M' \
181
+ -f $IMGFMT "$TEST_IMG" |
182
+ _filter_qemu_io
183
+_check_test_img
184
+
185
+echo
186
+$QEMU_IMG map --output=json "$TEST_IMG"
187
+
188
+echo
189
+$QEMU_IO -c 'read -P 0 0 1M' \
190
+ -c 'read -P 0x11 1M 1M' \
191
+ -c 'read -P 0 2M 4M' \
192
+ -f $IMGFMT "$TEST_IMG" |
193
+ _filter_qemu_io
194
+
195
+echo
196
+$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.data"
197
+
198
+echo -n "qcow2 file size after I/O: "
199
+du -b $TEST_IMG | cut -f1
200
+
201
+echo
202
+echo "=== bdrv_co_block_status test for file and offset=0 ==="
203
+echo
204
+
205
+IMGOPTS="data_file=$TEST_IMG.data" _make_test_img 64M
206
+
207
+$QEMU_IO -c 'write -P 0x11 0 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
208
+$QEMU_IO -c 'read -P 0x11 0 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
209
+$QEMU_IMG map --output=human "$TEST_IMG" | _filter_testdir
210
+$QEMU_IMG map --output=json "$TEST_IMG"
211
+
212
+# success, all done
213
+echo "*** done"
214
+rm -f $seq.full
215
+status=0
216
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
217
new file mode 100644
218
index XXXXXXX..XXXXXXX
219
--- /dev/null
220
+++ b/tests/qemu-iotests/244.out
221
@@ -XXX,XX +XXX,XX @@
222
+QA output created by 244
223
+
224
+=== Create and open image with external data file ===
225
+
226
+With data file name in the image:
227
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
228
+No errors were found on the image.
229
+read 65536/65536 bytes at offset 0
230
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
231
+read 65536/65536 bytes at offset 0
232
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
233
+can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
234
+no file open, try 'help open'
235
+
236
+Data file required, but without data file name in the image:
237
+can't open device TEST_DIR/t.qcow2: 'data-file' is required for this image
238
+no file open, try 'help open'
239
+read 65536/65536 bytes at offset 0
240
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
241
+can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
242
+no file open, try 'help open'
243
+
244
+Setting data-file for an image with internal data:
245
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
246
+can't open device TEST_DIR/t.qcow2: 'data-file' can only be set for images with an external data file
247
+no file open, try 'help open'
248
+can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
249
+no file open, try 'help open'
250
+
251
+=== Conflicting features ===
252
+
253
+Convert to compressed target with data file:
254
+Formatting 'TEST_DIR/t.IMGFMT.src', fmt=IMGFMT size=67108864
255
+wrote 1048576/1048576 bytes at offset 0
256
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
257
+qemu-img: error while writing sector 0: Operation not supported
258
+
259
+Convert uncompressed, then write compressed data manually:
260
+Images are identical.
261
+write failed: Operation not supported
262
+No errors were found on the image.
263
+
264
+Take an internal snapshot:
265
+qemu-img: Could not create snapshot 'test': -95 (Operation not supported)
266
+No errors were found on the image.
267
+
268
+=== Standalone image with external data file (efficient) ===
269
+
270
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
271
+qcow2 file size before I/O: 196616
272
+
273
+wrote 4194304/4194304 bytes at offset 1048576
274
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
275
+discard 2097152/2097152 bytes at offset 2097152
276
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
277
+wrote 3145728/3145728 bytes at offset 3145728
278
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
279
+No errors were found on the image.
280
+
281
+[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false},
282
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": false, "data": true, "offset": 1048576},
283
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": true, "data": false},
284
+{ "start": 4194304, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": 4194304},
285
+{ "start": 5242880, "length": 61865984, "depth": 0, "zero": true, "data": false}]
286
+
287
+read 1048576/1048576 bytes at offset 0
288
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
289
+read 1048576/1048576 bytes at offset 1048576
290
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
291
+read 4194304/4194304 bytes at offset 2097152
292
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
293
+
294
+read 1048576/1048576 bytes at offset 0
295
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
296
+read 1048576/1048576 bytes at offset 1048576
297
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
298
+read 2097152/2097152 bytes at offset 2097152
299
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
300
+read 1048576/1048576 bytes at offset 4194304
301
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
302
+read 1048576/1048576 bytes at offset 5242880
303
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
304
+qcow2 file size after I/O: 327680
305
+
306
+=== Standalone image with external data file (valid raw) ===
307
+
308
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on
309
+qcow2 file size before I/O: 196616
310
+
311
+wrote 4194304/4194304 bytes at offset 1048576
312
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
313
+discard 2097152/2097152 bytes at offset 2097152
314
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
315
+wrote 3145728/3145728 bytes at offset 3145728
316
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
317
+No errors were found on the image.
318
+
319
+[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false},
320
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": false, "data": true, "offset": 1048576},
321
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": true, "data": false},
322
+{ "start": 4194304, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": 4194304},
323
+{ "start": 5242880, "length": 61865984, "depth": 0, "zero": true, "data": false}]
324
+
325
+read 1048576/1048576 bytes at offset 0
326
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
327
+read 1048576/1048576 bytes at offset 1048576
328
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
329
+read 4194304/4194304 bytes at offset 2097152
330
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
331
+
332
+Images are identical.
333
+qcow2 file size after I/O: 327680
334
+
335
+=== bdrv_co_block_status test for file and offset=0 ===
336
+
337
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
338
+wrote 1048576/1048576 bytes at offset 0
339
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
340
+read 1048576/1048576 bytes at offset 0
341
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
342
+Offset Length Mapped to File
343
+0 0x100000 0 TEST_DIR/t.qcow2.data
344
+[{ "start": 0, "length": 1048576, "depth": 0, "zero": false, "data": true, "offset": 0},
345
+{ "start": 1048576, "length": 66060288, "depth": 0, "zero": true, "data": false}]
346
+*** done
347
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
348
index XXXXXXX..XXXXXXX 100644
349
--- a/tests/qemu-iotests/group
350
+++ b/tests/qemu-iotests/group
351
@@ -XXX,XX +XXX,XX @@
352
240 auto quick
353
242 rw auto quick
354
243 rw auto quick
355
+244 rw auto quick
356
--
357
2.20.1
358
359
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Since the ahci-test uses qemu-img, add a dependency to build it
4
before using it.
5
This fixes:
6
7
$ gmake check-qtest V=1
8
QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 QTEST_QEMU_IMG=qemu-img tests/ahci-test
9
Failed to execute child process "/tmp/qemu-test.19tMRF/qemu-img" (No such file or directory)
10
ERROR:tests/libqos/libqos.c:192:mkimg: assertion failed: (ret && !err)
11
12
Reviewed-by: John Snow <jsnow@redhat.com>
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
tests/Makefile.include | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
18
19
diff --git a/tests/Makefile.include b/tests/Makefile.include
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/Makefile.include
22
+++ b/tests/Makefile.include
23
@@ -XXX,XX +XXX,XX @@ tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
24
tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
25
tests/fdc-test$(EXESUF): tests/fdc-test.o
26
tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
27
-tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y)
28
+tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) qemu-img$(EXESUF)
29
tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o
30
tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o
31
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Since a9660664fde, some iotests use qemu-nbd.
4
Add a dependency to build it before using it.
5
This fixes:
6
7
$ make check-block
8
GEN qemu-img-cmds.h
9
CC qemu-img.o
10
LINK qemu-img
11
CC qemu-io.o
12
LINK qemu-io
13
CC tests/qemu-iotests/socket_scm_helper.o
14
LINK tests/qemu-iotests/socket_scm_helper
15
tests/qemu-iotests-quick.sh
16
check: qemu-nbd not found
17
make: *** [tests/Makefile.include:1059: check-tests/qemu-iotests-quick.sh] Error 1
18
19
Reviewed-by: Eric Blake <eblake@redhat.com>
20
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
23
tests/Makefile.include | 2 +-
24
1 file changed, 1 insertion(+), 1 deletion(-)
25
26
diff --git a/tests/Makefile.include b/tests/Makefile.include
27
index XXXXXXX..XXXXXXX 100644
28
--- a/tests/Makefile.include
29
+++ b/tests/Makefile.include
30
@@ -XXX,XX +XXX,XX @@ clean-tcg: $(CLEAN_TCG_TARGET_RULES)
31
QEMU_IOTESTS_HELPERS-$(call land,$(CONFIG_SOFTMMU),$(CONFIG_LINUX)) = tests/qemu-iotests/socket_scm_helper$(EXESUF)
32
33
.PHONY: check-tests/qemu-iotests-quick.sh
34
-check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) $(QEMU_IOTESTS_HELPERS-y)
35
+check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) qemu-nbd$(EXESUF) $(QEMU_IOTESTS_HELPERS-y)
36
    $<
37
38
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
39
--
40
2.20.1
41
42
diff view generated by jsdifflib
Deleted patch
1
Be more specific about the string representation in header extensions.
2
1
3
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
8
docs/interop/qcow2.txt | 14 ++++++++++++--
9
1 file changed, 12 insertions(+), 2 deletions(-)
10
11
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
12
index XXXXXXX..XXXXXXX 100644
13
--- a/docs/interop/qcow2.txt
14
+++ b/docs/interop/qcow2.txt
15
@@ -XXX,XX +XXX,XX @@ be stored. Each extension has a structure like the following:
16
17
Byte 0 - 3: Header extension type:
18
0x00000000 - End of the header extension area
19
- 0xE2792ACA - Backing file format name
20
+ 0xE2792ACA - Backing file format name string
21
0x6803f857 - Feature name table
22
0x23852875 - Bitmaps extension
23
0x0537be77 - Full disk encryption header pointer
24
- 0x44415441 - External data file name
25
+ 0x44415441 - External data file name string
26
other - Unknown header extension, can be safely
27
ignored
28
29
@@ -XXX,XX +XXX,XX @@ data of compatible features that it doesn't support. Compatible features that
30
need space for additional data can use a header extension.
31
32
33
+== String header extensions ==
34
+
35
+Some header extensions (such as the backing file format name and the external
36
+data file name) are just a single string. In this case, the header extension
37
+length is the string length and the string is not '\0' terminated. (The header
38
+extension padding can make it look like a string is '\0' terminated, but
39
+neither is padding always necessary nor is there a guarantee that zero bytes
40
+are used for padding.)
41
+
42
+
43
== Feature name table ==
44
45
The feature name table is an optional header extension that contains the name
46
--
47
2.20.1
48
49
diff view generated by jsdifflib