1 | The following changes since commit 83ea23cd207a03c5736be0231acbf7f8b05dbf52: | 1 | The following changes since commit c4e0780ed1ffd056f205348d387a61b4136a45df: |
---|---|---|---|
2 | 2 | ||
3 | i386: hvf: Fix overrun of _decode_tbl1 (2018-12-03 15:09:55 +0000) | 3 | Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-4.0-pull-request' into staging (2019-03-07 18:40:43 +0000) |
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 db5e8210adbafe9c6383d8364345a8c545d38e62: | 9 | for you to fetch changes up to e88153ea9a40009a8ae7648282c0eac1b7f5494f: |
10 | 10 | ||
11 | iotests: simple mirror test with kvm on 1G image (2018-12-03 16:51:53 +0100) | 11 | qcow2 spec: Describe string header extensions (2019-03-08 12:26:46 +0100) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches: | 14 | Block layer patches: |
15 | 15 | ||
16 | - mirror: Fix deadlock | 16 | - qcow2: Support for external data files |
17 | - qcow2: Default to 4KB for the qcow2 cache entry size | ||
18 | - Apply block driver whitelist for -drive format=help | ||
19 | - Several qemu-iotests improvements | ||
17 | 20 | ||
18 | ---------------------------------------------------------------- | 21 | ---------------------------------------------------------------- |
19 | Vladimir Sementsov-Ogievskiy (2): | 22 | Alberto Garcia (1): |
20 | mirror: fix dead-lock | 23 | qcow2: Default to 4KB for the qcow2 cache entry size |
21 | iotests: simple mirror test with kvm on 1G image | 24 | |
22 | 25 | Andrey Shinkevich (4): | |
23 | block/mirror.c | 13 +++----- | 26 | iotests: open notrun files in text mode |
24 | tests/qemu-iotests/235 | 76 ++++++++++++++++++++++++++++++++++++++++++++++ | 27 | block: iterate_format with account of whitelisting |
25 | tests/qemu-iotests/235.out | 3 ++ | 28 | iotests: ask QEMU for supported formats |
26 | tests/qemu-iotests/group | 1 + | 29 | iotests: check whitelisted formats |
27 | 4 files changed, 85 insertions(+), 8 deletions(-) | 30 | |
28 | create mode 100755 tests/qemu-iotests/235 | 31 | Kevin Wolf (21): |
29 | create mode 100644 tests/qemu-iotests/235.out | 32 | qemu-iotests: Test qcow2 preallocation modes |
30 | 33 | qcow2: Simplify preallocation code | |
34 | qcow2: Extend spec for external data files | ||
35 | qcow2: Basic definitions for external data files | ||
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 | |||
54 | Philippe Mathieu-Daudé (6): | ||
55 | tests/multiboot: Improve portability by searching bash in the $PATH | ||
56 | tests/bios-tables: Improve portability by searching bash in the $PATH | ||
57 | qemu-iotests: Improve portability by searching bash in the $PATH | ||
58 | qemu-iotests: Ensure GNU sed is used | ||
59 | ahci-test: Add dependency to qemu-img tool | ||
60 | qemu-iotests: Add dependency to qemu-nbd tool | ||
61 | |||
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 |
New patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> | ||
1 | 2 | ||
3 | Replace the binary mode with the default text one when *.notrun | ||
4 | files are opened for skipped tests. That change is made for the | ||
5 | compatibility with Python 3 which returns error otherwise. | ||
6 | |||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | --- | ||
11 | tests/qemu-iotests/iotests.py | 2 +- | ||
12 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
13 | |||
14 | diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/tests/qemu-iotests/iotests.py | ||
17 | +++ b/tests/qemu-iotests/iotests.py | ||
18 | @@ -XXX,XX +XXX,XX @@ def notrun(reason): | ||
19 | # Each test in qemu-iotests has a number ("seq") | ||
20 | seq = os.path.basename(sys.argv[0]) | ||
21 | |||
22 | - open('%s/%s.notrun' % (output_dir, seq), 'wb').write(reason + '\n') | ||
23 | + open('%s/%s.notrun' % (output_dir, seq), 'w').write(reason + '\n') | ||
24 | print('%s not run: %s' % (seq, reason)) | ||
25 | sys.exit(0) | ||
26 | |||
27 | -- | ||
28 | 2.20.1 | ||
29 | |||
30 | diff view generated by jsdifflib |
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 1 | From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> |
---|---|---|---|
2 | 2 | ||
3 | Let start from the beginning: | 3 | bdrv_iterate_format (which is currently only used for printing out the |
4 | formats supported by the block layer) doesn't take format whitelisting | ||
5 | into account. | ||
4 | 6 | ||
5 | Commit b9e413dd375 (in 2.9) | 7 | This creates a problem for tests: they enumerate supported formats to |
6 | "block: explicitly acquire aiocontext in aio callbacks that need it" | 8 | decide which tests to enable, but then discover that QEMU doesn't let |
7 | added pairs of aio_context_acquire/release to mirror_write_complete and | 9 | them actually use some of those formats. |
8 | mirror_read_complete, when they were aio callbacks for blk_aio_* calls. | ||
9 | 10 | ||
10 | Then, commit 2e1990b26e5 (in 3.0) "block/mirror: Convert to coroutines" | 11 | To avoid that, exclude formats that are not whitelisted from |
11 | dropped these blk_aio_* calls, than mirror_write_complete and | 12 | enumeration, if whitelisting is in use. Since we have separate |
12 | mirror_read_complete are not callbacks more, and don't need additional | 13 | whitelists for r/w and r/o, take this a parameter to |
13 | aiocontext acquiring. Furthermore, mirror_read_complete calls | 14 | bdrv_iterate_format, and print two lists of supported formats (r/w and |
14 | blk_co_pwritev inside these pair of aio_context_acquire/release, which | 15 | r/o) in main qemu. |
15 | leads to the following dead-lock with mirror: | ||
16 | 16 | ||
17 | (gdb) info thr | 17 | Signed-off-by: Roman Kagan <rkagan@virtuozzo.com> |
18 | Id Target Id Frame | 18 | Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> |
19 | 3 Thread (LWP 145412) "qemu-system-x86" syscall () | ||
20 | 2 Thread (LWP 145416) "qemu-system-x86" __lll_lock_wait () | ||
21 | * 1 Thread (LWP 145411) "qemu-system-x86" __lll_lock_wait () | ||
22 | |||
23 | (gdb) bt | ||
24 | #0 __lll_lock_wait () | ||
25 | #1 _L_lock_812 () | ||
26 | #2 __GI___pthread_mutex_lock | ||
27 | #3 qemu_mutex_lock_impl (mutex=0x561032dce420 <qemu_global_mutex>, | ||
28 | file=0x5610327d8654 "util/main-loop.c", line=236) at | ||
29 | util/qemu-thread-posix.c:66 | ||
30 | #4 qemu_mutex_lock_iothread_impl | ||
31 | #5 os_host_main_loop_wait (timeout=480116000) at util/main-loop.c:236 | ||
32 | #6 main_loop_wait (nonblocking=0) at util/main-loop.c:497 | ||
33 | #7 main_loop () at vl.c:1892 | ||
34 | #8 main | ||
35 | |||
36 | Printing contents of qemu_global_mutex, I see that "__owner = 145416", | ||
37 | so, thr1 is main loop, and now it wants BQL, which is owned by thr2. | ||
38 | |||
39 | (gdb) thr 2 | ||
40 | (gdb) bt | ||
41 | #0 __lll_lock_wait () | ||
42 | #1 _L_lock_870 () | ||
43 | #2 __GI___pthread_mutex_lock | ||
44 | #3 qemu_mutex_lock_impl (mutex=0x561034d25dc0, ... | ||
45 | #4 aio_context_acquire (ctx=0x561034d25d60) | ||
46 | #5 dma_blk_cb | ||
47 | #6 dma_blk_io | ||
48 | #7 dma_blk_read | ||
49 | #8 ide_dma_cb | ||
50 | #9 bmdma_cmd_writeb | ||
51 | #10 bmdma_write | ||
52 | #11 memory_region_write_accessor | ||
53 | #12 access_with_adjusted_size | ||
54 | #15 flatview_write | ||
55 | #16 address_space_write | ||
56 | #17 address_space_rw | ||
57 | #18 kvm_handle_io | ||
58 | #19 kvm_cpu_exec | ||
59 | #20 qemu_kvm_cpu_thread_fn | ||
60 | #21 qemu_thread_start | ||
61 | #22 start_thread | ||
62 | #23 clone () | ||
63 | |||
64 | Printing mutex in fr 2, I see "__owner = 145411", so thr2 wants aio | ||
65 | context mutex, which is owned by thr1. Classic dead-lock. | ||
66 | |||
67 | Then, let's check that aio context is hold by mirror coroutine: just | ||
68 | print coroutine stack of first tracked request in mirror job target: | ||
69 | |||
70 | (gdb) [...] | ||
71 | (gdb) qemu coroutine 0x561035dd0860 | ||
72 | #0 qemu_coroutine_switch | ||
73 | #1 qemu_coroutine_yield | ||
74 | #2 qemu_co_mutex_lock_slowpath | ||
75 | #3 qemu_co_mutex_lock | ||
76 | #4 qcow2_co_pwritev | ||
77 | #5 bdrv_driver_pwritev | ||
78 | #6 bdrv_aligned_pwritev | ||
79 | #7 bdrv_co_pwritev | ||
80 | #8 blk_co_pwritev | ||
81 | #9 mirror_read_complete () at block/mirror.c:232 | ||
82 | #10 mirror_co_read () at block/mirror.c:370 | ||
83 | #11 coroutine_trampoline | ||
84 | #12 __start_context | ||
85 | |||
86 | Yes it is mirror_read_complete calling blk_co_pwritev after acquiring | ||
87 | aio context. | ||
88 | |||
89 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
90 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
91 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 19 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
92 | --- | 20 | --- |
93 | block/mirror.c | 13 +++++-------- | 21 | include/block/block.h | 2 +- |
94 | 1 file changed, 5 insertions(+), 8 deletions(-) | 22 | block.c | 23 +++++++++++++++++++---- |
23 | blockdev.c | 4 +++- | ||
24 | qemu-img.c | 2 +- | ||
25 | 4 files changed, 24 insertions(+), 7 deletions(-) | ||
95 | 26 | ||
96 | diff --git a/block/mirror.c b/block/mirror.c | 27 | diff --git a/include/block/block.h b/include/block/block.h |
97 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
98 | --- a/block/mirror.c | 29 | --- a/include/block/block.h |
99 | +++ b/block/mirror.c | 30 | +++ b/include/block/block.h |
100 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_write_complete(MirrorOp *op, int ret) | 31 | @@ -XXX,XX +XXX,XX @@ void bdrv_next_cleanup(BdrvNextIterator *it); |
32 | BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs); | ||
33 | bool bdrv_is_encrypted(BlockDriverState *bs); | ||
34 | void bdrv_iterate_format(void (*it)(void *opaque, const char *name), | ||
35 | - void *opaque); | ||
36 | + void *opaque, bool read_only); | ||
37 | const char *bdrv_get_node_name(const BlockDriverState *bs); | ||
38 | const char *bdrv_get_device_name(const BlockDriverState *bs); | ||
39 | const char *bdrv_get_device_or_node_name(const BlockDriverState *bs); | ||
40 | diff --git a/block.c b/block.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/block.c | ||
43 | +++ b/block.c | ||
44 | @@ -XXX,XX +XXX,XX @@ BlockDriver *bdrv_find_format(const char *format_name) | ||
45 | return bdrv_do_find_format(format_name); | ||
46 | } | ||
47 | |||
48 | -int bdrv_is_whitelisted(BlockDriver *drv, bool read_only) | ||
49 | +static int bdrv_format_is_whitelisted(const char *format_name, bool read_only) | ||
101 | { | 50 | { |
102 | MirrorBlockJob *s = op->s; | 51 | static const char *whitelist_rw[] = { |
103 | 52 | CONFIG_BDRV_RW_WHITELIST | |
104 | - aio_context_acquire(blk_get_aio_context(s->common.blk)); | 53 | @@ -XXX,XX +XXX,XX @@ int bdrv_is_whitelisted(BlockDriver *drv, bool read_only) |
105 | if (ret < 0) { | 54 | } |
106 | BlockErrorAction action; | 55 | |
107 | 56 | for (p = whitelist_rw; *p; p++) { | |
108 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_write_complete(MirrorOp *op, int ret) | 57 | - if (!strcmp(drv->format_name, *p)) { |
109 | s->ret = ret; | 58 | + if (!strcmp(format_name, *p)) { |
59 | return 1; | ||
110 | } | 60 | } |
111 | } | 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 | +} | ||
112 | + | 77 | + |
113 | mirror_iteration_done(op, ret); | 78 | bool bdrv_uses_whitelist(void) |
114 | - aio_context_release(blk_get_aio_context(s->common.blk)); | 79 | { |
80 | return use_bdrv_whitelist; | ||
81 | @@ -XXX,XX +XXX,XX @@ static int qsort_strcmp(const void *a, const void *b) | ||
115 | } | 82 | } |
116 | 83 | ||
117 | static void coroutine_fn mirror_read_complete(MirrorOp *op, int ret) | 84 | void bdrv_iterate_format(void (*it)(void *opaque, const char *name), |
85 | - void *opaque) | ||
86 | + void *opaque, bool read_only) | ||
118 | { | 87 | { |
119 | MirrorBlockJob *s = op->s; | 88 | BlockDriver *drv; |
120 | 89 | int count = 0; | |
121 | - aio_context_acquire(blk_get_aio_context(s->common.blk)); | 90 | @@ -XXX,XX +XXX,XX @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name), |
122 | if (ret < 0) { | 91 | if (drv->format_name) { |
123 | BlockErrorAction action; | 92 | bool found = false; |
124 | 93 | int i = count; | |
125 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_read_complete(MirrorOp *op, int ret) | 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 | ||
115 | index XXXXXXX..XXXXXXX 100644 | ||
116 | --- a/blockdev.c | ||
117 | +++ b/blockdev.c | ||
118 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, | ||
119 | if ((buf = qemu_opt_get(opts, "format")) != NULL) { | ||
120 | if (is_help_option(buf)) { | ||
121 | error_printf("Supported formats:"); | ||
122 | - bdrv_iterate_format(bdrv_format_print, NULL); | ||
123 | + bdrv_iterate_format(bdrv_format_print, NULL, false); | ||
124 | + error_printf("\nSupported formats (read-only):"); | ||
125 | + bdrv_iterate_format(bdrv_format_print, NULL, true); | ||
126 | error_printf("\n"); | ||
127 | goto early_err; | ||
126 | } | 128 | } |
127 | 129 | diff --git a/qemu-img.c b/qemu-img.c | |
128 | mirror_iteration_done(op, ret); | 130 | index XXXXXXX..XXXXXXX 100644 |
129 | - } else { | 131 | --- a/qemu-img.c |
130 | - ret = blk_co_pwritev(s->target, op->offset, | 132 | +++ b/qemu-img.c |
131 | - op->qiov.size, &op->qiov, 0); | 133 | @@ -XXX,XX +XXX,XX @@ static void QEMU_NORETURN help(void) |
132 | - mirror_write_complete(op, ret); | 134 | " 'skip=N' skip N bs-sized blocks at the start of input\n"; |
133 | + return; | 135 | |
134 | } | 136 | printf("%s\nSupported formats:", help_msg); |
135 | - aio_context_release(blk_get_aio_context(s->common.blk)); | 137 | - bdrv_iterate_format(format_print, NULL); |
136 | + | 138 | + bdrv_iterate_format(format_print, NULL, false); |
137 | + ret = blk_co_pwritev(s->target, op->offset, op->qiov.size, &op->qiov, 0); | 139 | printf("\n\n" QEMU_HELP_BOTTOM "\n"); |
138 | + mirror_write_complete(op, ret); | 140 | exit(EXIT_SUCCESS); |
139 | } | 141 | } |
140 | |||
141 | /* Clip bytes relative to offset to not exceed end-of-file */ | ||
142 | -- | 142 | -- |
143 | 2.19.2 | 143 | 2.20.1 |
144 | 144 | ||
145 | 145 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> | ||
1 | 2 | ||
3 | Supported formats listed by 'qemu' may differ from those listed by | ||
4 | 'qemu-img' due to whitelists. Some test cases require specific formats | ||
5 | that may be used with qemu. They can be inquired directly by running | ||
6 | 'qemu -drive format=help'. The response takes whitelists into account. | ||
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 | |||
12 | Suggested-by: Roman Kagan <rkagan@virtuozzo.com> | ||
13 | Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
14 | Suggested-by: Kevin Wolf <kwolf@redhat.com> | ||
15 | Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> | ||
16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | --- | ||
18 | tests/qemu-iotests/check | 13 ++++++++++- | ||
19 | tests/qemu-iotests/iotests.py | 43 +++++++++++++++++++++++++++++++++++ | ||
20 | 2 files changed, 55 insertions(+), 1 deletion(-) | ||
21 | |||
22 | diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check | ||
23 | index XXXXXXX..XXXXXXX 100755 | ||
24 | --- a/tests/qemu-iotests/check | ||
25 | +++ 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 | ||
47 | printf " " # prettier output with timestamps. | ||
48 | fi | ||
49 | rm -f core $seq.notrun | ||
50 | + rm -f $seq.casenotrun | ||
51 | |||
52 | start=$(_wallclock) | ||
53 | $timestamp && printf %s " [$(date "+%T")]" | ||
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 | -- | ||
129 | 2.20.1 | ||
130 | |||
131 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
1 | 2 | ||
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 |
New 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 | ||
1 | 10 | ||
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 |
New patch | |||
---|---|---|---|
1 | Image creation already involves a bdrv_co_truncate() call, which allows | ||
2 | to specify a preallocation mode. Just pass the right mode there and | ||
3 | remove the code that is made redundant by this. | ||
1 | 4 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | --- | ||
7 | block/qcow2.c | 28 +--------------------------- | ||
8 | 1 file changed, 1 insertion(+), 27 deletions(-) | ||
9 | |||
10 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
11 | index XXXXXXX..XXXXXXX 100644 | ||
12 | --- a/block/qcow2.c | ||
13 | +++ b/block/qcow2.c | ||
14 | @@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) | ||
15 | goto out; | ||
16 | } | ||
17 | |||
18 | - if (qcow2_opts->preallocation == PREALLOC_MODE_FULL || | ||
19 | - qcow2_opts->preallocation == PREALLOC_MODE_FALLOC) | ||
20 | - { | ||
21 | - int64_t prealloc_size = | ||
22 | - qcow2_calc_prealloc_size(qcow2_opts->size, cluster_size, | ||
23 | - refcount_order); | ||
24 | - | ||
25 | - ret = blk_truncate(blk, prealloc_size, qcow2_opts->preallocation, errp); | ||
26 | - if (ret < 0) { | ||
27 | - goto out; | ||
28 | - } | ||
29 | - } | ||
30 | - | ||
31 | /* Write the header */ | ||
32 | QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header)); | ||
33 | header = g_malloc0(cluster_size); | ||
34 | @@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) | ||
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 | } | ||
45 | } | ||
46 | |||
47 | - /* And if we're supposed to preallocate metadata, do that now */ | ||
48 | - if (qcow2_opts->preallocation != PREALLOC_MODE_OFF) { | ||
49 | - BDRVQcow2State *s = blk_bs(blk)->opaque; | ||
50 | - qemu_co_mutex_lock(&s->lock); | ||
51 | - ret = preallocate_co(blk_bs(blk), 0, qcow2_opts->size); | ||
52 | - qemu_co_mutex_unlock(&s->lock); | ||
53 | - | ||
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 | |||
63 | -- | ||
64 | 2.20.1 | ||
65 | |||
66 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | This adds external data file to the qcow2 spec as a new incompatible | ||
2 | feature. | ||
1 | 3 | ||
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 |
New patch | |||
---|---|---|---|
1 | 1 | This adds basic constants, struct fields and helper function for | |
2 | external data file support to the implementation. | ||
3 | |||
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 |
New 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(-) | ||
1 | 7 | ||
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 |
New patch | |||
---|---|---|---|
1 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
2 | --- | ||
3 | block/qcow2.h | 10 +++++++++- | ||
4 | 1 file changed, 9 insertions(+), 1 deletion(-) | ||
1 | 5 | ||
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 |
New patch | |||
---|---|---|---|
1 | Offset 0 can be valid for normal (allocated) clusters now, so use | ||
2 | qcow2_get_cluster_type() instead. | ||
1 | 3 | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | --- | ||
6 | block/qcow2-cluster.c | 4 ++-- | ||
7 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
8 | |||
9 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
10 | index XXXXXXX..XXXXXXX 100644 | ||
11 | --- a/block/qcow2-cluster.c | ||
12 | +++ b/block/qcow2-cluster.c | ||
13 | @@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters(BlockDriverState *bs, int nb_clusters, | ||
14 | uint64_t first_entry = be64_to_cpu(l2_slice[0]); | ||
15 | uint64_t offset = first_entry & mask; | ||
16 | |||
17 | - if (!offset) { | ||
18 | + first_cluster_type = qcow2_get_cluster_type(bs, first_entry); | ||
19 | + if (first_cluster_type == QCOW2_CLUSTER_UNALLOCATED) { | ||
20 | return 0; | ||
21 | } | ||
22 | |||
23 | /* must be allocated */ | ||
24 | - first_cluster_type = qcow2_get_cluster_type(bs, first_entry); | ||
25 | assert(first_cluster_type == QCOW2_CLUSTER_NORMAL || | ||
26 | first_cluster_type == QCOW2_CLUSTER_ZERO_ALLOC); | ||
27 | |||
28 | -- | ||
29 | 2.20.1 | ||
30 | |||
31 | diff view generated by jsdifflib |
New 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. | ||
1 | 4 | ||
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 |
New patch | |||
---|---|---|---|
1 | qcow2_alloc_compressed_cluster_offset() used to return the cluster | ||
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. | ||
1 | 4 | ||
5 | Similar to the change made to qcow2_alloc_cluster_offset() for | ||
6 | uncompressed clusters in commit 148da7ea9d6, make the function return | ||
7 | 0/-errno and return the allocated cluster offset in a by-reference | ||
8 | parameter. | ||
9 | |||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | --- | ||
12 | block/qcow2.h | 7 ++++--- | ||
13 | block/qcow2-cluster.c | 28 +++++++++++++--------------- | ||
14 | block/qcow2.c | 19 ++++++++----------- | ||
15 | tests/qemu-iotests/220.out | 2 +- | ||
16 | 4 files changed, 26 insertions(+), 30 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 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, | ||
23 | int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, | ||
24 | unsigned int *bytes, uint64_t *host_offset, | ||
25 | QCowL2Meta **m); | ||
26 | -uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, | ||
27 | - uint64_t offset, | ||
28 | - int compressed_size); | ||
29 | +int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, | ||
30 | + uint64_t offset, | ||
31 | + int compressed_size, | ||
32 | + uint64_t *host_offset); | ||
33 | |||
34 | int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m); | ||
35 | void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m); | ||
36 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/block/qcow2-cluster.c | ||
39 | +++ b/block/qcow2-cluster.c | ||
40 | @@ -XXX,XX +XXX,XX @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset, | ||
41 | /* | ||
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 | { | ||
66 | BDRVQcow2State *s = bs->opaque; | ||
67 | int l2_index, ret; | ||
68 | @@ -XXX,XX +XXX,XX @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, | ||
69 | |||
70 | ret = get_cluster_table(bs, offset, &l2_slice, &l2_index); | ||
71 | if (ret < 0) { | ||
72 | - return 0; | ||
73 | + return ret; | ||
74 | } | ||
75 | |||
76 | /* Compression can't overwrite anything. Fail if the cluster was already | ||
77 | @@ -XXX,XX +XXX,XX @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, | ||
78 | cluster_offset = be64_to_cpu(l2_slice[l2_index]); | ||
79 | if (cluster_offset & L2E_OFFSET_MASK) { | ||
80 | qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); | ||
81 | - return 0; | ||
82 | + return -EIO; | ||
83 | } | ||
84 | |||
85 | cluster_offset = qcow2_alloc_bytes(bs, compressed_size); | ||
86 | if (cluster_offset < 0) { | ||
87 | qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); | ||
88 | - return 0; | ||
89 | + return cluster_offset; | ||
90 | } | ||
91 | |||
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 | } | ||
101 | |||
102 | static int perform_cow(BlockDriverState *bs, QCowL2Meta *m) | ||
103 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
104 | index XXXXXXX..XXXXXXX 100644 | ||
105 | --- a/block/qcow2.c | ||
106 | +++ b/block/qcow2.c | ||
107 | @@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset, | ||
108 | int ret; | ||
109 | size_t out_len; | ||
110 | uint8_t *buf, *out_buf; | ||
111 | - int64_t cluster_offset; | ||
112 | + uint64_t cluster_offset; | ||
113 | |||
114 | if (bytes == 0) { | ||
115 | /* align end of file to a sector boundary to ease reading with | ||
116 | sector based I/Os */ | ||
117 | - cluster_offset = bdrv_getlength(bs->file->bs); | ||
118 | - if (cluster_offset < 0) { | ||
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 | -- | ||
162 | 2.20.1 | ||
163 | |||
164 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Offset 0 cannot be assumed to mean an unallocated cluster any more. | ||
2 | Instead, the cluster type needs to be checked. | ||
1 | 3 | ||
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 |
New patch | |||
---|---|---|---|
1 | This changes the qcow2 implementation to direct all guest data I/O to | ||
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. | ||
1 | 5 | ||
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
7 | --- | ||
8 | block/qcow2.h | 2 +- | ||
9 | block/qcow2-bitmap.c | 7 +++--- | ||
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 | |||
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 @@ void qcow2_process_discards(BlockDriverState *bs, int ret); | ||
22 | int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset, | ||
23 | int64_t size); | ||
24 | int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset, | ||
25 | - int64_t size); | ||
26 | + int64_t size, bool data_file); | ||
27 | int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res, | ||
28 | void **refcount_table, | ||
29 | int64_t *refcount_table_size, | ||
30 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/block/qcow2-bitmap.c | ||
33 | +++ b/block/qcow2-bitmap.c | ||
34 | @@ -XXX,XX +XXX,XX @@ static int bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list, | ||
35 | * directory in-place (actually, turn-off the extension), which is checked | ||
36 | * in qcow2_check_metadata_overlap() */ | ||
37 | ret = qcow2_pre_write_overlap_check( | ||
38 | - bs, in_place ? QCOW2_OL_BITMAP_DIRECTORY : 0, dir_offset, dir_size); | ||
39 | + bs, in_place ? QCOW2_OL_BITMAP_DIRECTORY : 0, dir_offset, dir_size, | ||
40 | + false); | ||
41 | if (ret < 0) { | ||
42 | goto fail; | ||
43 | } | ||
44 | @@ -XXX,XX +XXX,XX @@ static uint64_t *store_bitmap_data(BlockDriverState *bs, | ||
45 | memset(buf + write_size, 0, s->cluster_size - write_size); | ||
46 | } | ||
47 | |||
48 | - ret = qcow2_pre_write_overlap_check(bs, 0, off, s->cluster_size); | ||
49 | + ret = qcow2_pre_write_overlap_check(bs, 0, off, s->cluster_size, false); | ||
50 | if (ret < 0) { | ||
51 | error_setg_errno(errp, -ret, "Qcow2 overlap check failed"); | ||
52 | goto fail; | ||
53 | @@ -XXX,XX +XXX,XX @@ static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp) | ||
54 | } | ||
55 | |||
56 | ret = qcow2_pre_write_overlap_check(bs, 0, tb_offset, | ||
57 | - tb_size * sizeof(tb[0])); | ||
58 | + tb_size * sizeof(tb[0]), false); | ||
59 | if (ret < 0) { | ||
60 | error_setg_errno(errp, -ret, "Qcow2 overlap check failed"); | ||
61 | goto fail; | ||
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 | { | ||
109 | + BDRVQcow2State *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 | + | ||
170 | ret = get_cluster_table(bs, offset, &l2_slice, &l2_index); | ||
171 | if (ret < 0) { | ||
172 | return ret; | ||
173 | @@ -XXX,XX +XXX,XX @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset, | ||
174 | trace_qcow2_do_alloc_clusters_offset(qemu_coroutine_self(), guest_offset, | ||
175 | *host_offset, *nb_clusters); | ||
176 | |||
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; | ||
235 | + } | ||
236 | + | ||
237 | + switch (ctype) { | ||
238 | case QCOW2_CLUSTER_COMPRESSED: | ||
239 | { | ||
240 | int nb_csectors; | ||
241 | @@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, | ||
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 | } | ||
271 | |||
272 | ret = qcow2_pre_write_overlap_check(bs, 0, reftable_offset, | ||
273 | - reftable_size * sizeof(uint64_t)); | ||
274 | + reftable_size * sizeof(uint64_t), | ||
275 | + false); | ||
276 | if (ret < 0) { | ||
277 | fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret)); | ||
278 | goto fail; | ||
279 | @@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR != ARRAY_SIZE(metadata_ol_names)); | ||
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 | -- | ||
503 | 2.20.1 | ||
504 | |||
505 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Internal snapshots and an external data file are incompatible because | ||
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. | ||
1 | 4 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | --- | ||
7 | block/qcow2-snapshot.c | 15 +++++++++++++++ | ||
8 | 1 file changed, 15 insertions(+) | ||
9 | |||
10 | diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c | ||
11 | index XXXXXXX..XXXXXXX 100644 | ||
12 | --- a/block/qcow2-snapshot.c | ||
13 | +++ b/block/qcow2-snapshot.c | ||
14 | @@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) | ||
15 | return -EFBIG; | ||
16 | } | ||
17 | |||
18 | + if (has_data_file(bs)) { | ||
19 | + return -ENOTSUP; | ||
20 | + } | ||
21 | + | ||
22 | memset(sn, 0, sizeof(*sn)); | ||
23 | |||
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 | -- | ||
58 | 2.20.1 | ||
59 | |||
60 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | For external data files, data clusters must be excluded from the | ||
2 | refcount calculations. Instead, an implicit refcount of 1 is assumed for | ||
3 | the COPIED flag. | ||
1 | 4 | ||
5 | Compressed clusters and internal snapshots are incompatible with | ||
6 | external data files, so print an error if they are in use for images | ||
7 | with an external data file. | ||
8 | |||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | --- | ||
11 | block/qcow2-refcount.c | 41 ++++++++++++++++++++++++++++++----------- | ||
12 | 1 file changed, 30 insertions(+), 11 deletions(-) | ||
13 | |||
14 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/block/qcow2-refcount.c | ||
17 | +++ b/block/qcow2-refcount.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, | ||
19 | res->corruptions++; | ||
20 | } | ||
21 | |||
22 | + if (has_data_file(bs)) { | ||
23 | + fprintf(stderr, "ERROR compressed cluster %d with data file, " | ||
24 | + "entry=0x%" PRIx64 "\n", i, l2_entry); | ||
25 | + res->corruptions++; | ||
26 | + break; | ||
27 | + } | ||
28 | + | ||
29 | /* Mark cluster as used */ | ||
30 | nb_csectors = ((l2_entry >> s->csize_shift) & | ||
31 | s->csize_mask) + 1; | ||
32 | @@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, | ||
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 | + } | ||
83 | + | ||
84 | for (i = 0; i < s->nb_snapshots; i++) { | ||
85 | sn = s->snapshots + i; | ||
86 | if (offset_into_cluster(s, sn->l1_table_offset)) { | ||
87 | -- | ||
88 | 2.20.1 | ||
89 | |||
90 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | This adds a .bdrv_open option to specify the external data file node. | ||
1 | 2 | ||
3 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
4 | --- | ||
5 | qapi/block-core.json | 7 ++++++- | ||
6 | block/qcow2.h | 4 +++- | ||
7 | block/qcow2.c | 34 ++++++++++++++++++++++++++++++++-- | ||
8 | 3 files changed, 41 insertions(+), 4 deletions(-) | ||
9 | |||
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 | # encrypted images, except when doing a metadata-only | ||
16 | # probe of the image. (since 2.10) | ||
17 | # | ||
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 | ||
23 | ## | ||
24 | { 'struct': 'BlockdevOptionsQcow2', | ||
25 | @@ -XXX,XX +XXX,XX @@ | ||
26 | '*l2-cache-entry-size': 'int', | ||
27 | '*refcount-cache-size': 'int', | ||
28 | '*cache-clean-interval': 'int', | ||
29 | - '*encrypt': 'BlockdevQcow2Encryption' } } | ||
30 | + '*encrypt': 'BlockdevQcow2Encryption', | ||
31 | + '*data-file': 'BlockdevRef' } } | ||
32 | |||
33 | ## | ||
34 | # @SshHostKeyCheckMode: | ||
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 | -- | ||
117 | 2.20.1 | ||
118 | |||
119 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | This adds a .bdrv_create option to use an external data file. | ||
1 | 2 | ||
3 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
4 | --- | ||
5 | qapi/block-core.json | 4 ++++ | ||
6 | include/block/block_int.h | 1 + | ||
7 | block/qcow2.c | 26 ++++++++++++++++++++++++++ | ||
8 | 3 files changed, 31 insertions(+) | ||
9 | |||
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 | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/include/block/block_int.h | ||
35 | +++ b/include/block/block_int.h | ||
36 | @@ -XXX,XX +XXX,XX @@ | ||
37 | #define BLOCK_OPT_NOCOW "nocow" | ||
38 | #define BLOCK_OPT_OBJECT_SIZE "object_size" | ||
39 | #define BLOCK_OPT_REFCOUNT_BITS "refcount_bits" | ||
40 | +#define BLOCK_OPT_DATA_FILE "data_file" | ||
41 | |||
42 | #define BLOCK_PROBE_BUF_SIZE 512 | ||
43 | |||
44 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/block/qcow2.c | ||
47 | +++ b/block/qcow2.c | ||
48 | @@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) | ||
49 | */ | ||
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 | } | ||
115 | |||
116 | -- | ||
117 | 2.20.1 | ||
118 | |||
119 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Rather than requiring that the external data file node is passed | ||
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. | ||
1 | 5 | ||
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
7 | --- | ||
8 | qapi/block-core.json | 8 +++- | ||
9 | block/qcow2.h | 1 + | ||
10 | block/qcow2.c | 94 +++++++++++++++++++++++++++++++++++++- | ||
11 | tests/qemu-iotests/082.out | 27 +++++++++++ | ||
12 | 4 files changed, 128 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/qapi/block-core.json | ||
17 | +++ b/qapi/block-core.json | ||
18 | @@ -XXX,XX +XXX,XX @@ | ||
19 | # | ||
20 | # @compat: compatibility level | ||
21 | # | ||
22 | +# @data-file: the filename of the external data file that is stored in the | ||
23 | +# image and used as a default for opening the image (since: 4.0) | ||
24 | +# | ||
25 | # @lazy-refcounts: on or off; only valid for compat >= 1.1 | ||
26 | # | ||
27 | # @corrupt: true if the image has been marked corrupt; only valid for | ||
28 | @@ -XXX,XX +XXX,XX @@ | ||
29 | { 'struct': 'ImageInfoSpecificQCow2', | ||
30 | 'data': { | ||
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 | ||
49 | --- a/block/qcow2.h | ||
50 | +++ b/block/qcow2.h | ||
51 | @@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State { | ||
52 | * override) */ | ||
53 | char *image_backing_file; | ||
54 | char *image_backing_format; | ||
55 | + char *image_data_file; | ||
56 | |||
57 | CoQueue compress_wait_queue; | ||
58 | int nb_compress_threads; | ||
59 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
60 | index XXXXXXX..XXXXXXX 100644 | ||
61 | --- a/block/qcow2.c | ||
62 | +++ b/block/qcow2.c | ||
63 | @@ -XXX,XX +XXX,XX @@ static int qcow2_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 | } | ||
87 | |||
88 | if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) { | ||
89 | + if (!s->data_file && s->image_data_file) { | ||
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 | + } | ||
133 | + | ||
134 | /* Full disk encryption header pointer extension */ | ||
135 | if (s->crypto_header.offset != 0) { | ||
136 | s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset); | ||
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 | -- | ||
476 | 2.20.1 | ||
477 | |||
478 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Provide an option to force QEMU to always keep the external data file | ||
2 | consistent as a standalone read-only raw image. | ||
1 | 3 | ||
4 | At the moment, this means making sure that write_zeroes requests are | ||
5 | forwarded to the data file instead of just updating the metadata, and | ||
6 | checking that no backing file is used. | ||
7 | |||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | --- | ||
10 | qapi/block-core.json | 9 ++++++ | ||
11 | block/qcow2.h | 9 +++++- | ||
12 | include/block/block_int.h | 1 + | ||
13 | block/qcow2-cluster.c | 10 +++++++ | ||
14 | block/qcow2.c | 56 ++++++++++++++++++++++++++++++++++++-- | ||
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 | ||
87 | index XXXXXXX..XXXXXXX 100644 | ||
88 | --- a/include/block/block_int.h | ||
89 | +++ b/include/block/block_int.h | ||
90 | @@ -XXX,XX +XXX,XX @@ | ||
91 | #define BLOCK_OPT_OBJECT_SIZE "object_size" | ||
92 | #define BLOCK_OPT_REFCOUNT_BITS "refcount_bits" | ||
93 | #define BLOCK_OPT_DATA_FILE "data_file" | ||
94 | +#define BLOCK_OPT_DATA_FILE_RAW "data_file_raw" | ||
95 | |||
96 | #define BLOCK_PROBE_BUF_SIZE 512 | ||
97 | |||
98 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
99 | index XXXXXXX..XXXXXXX 100644 | ||
100 | --- a/block/qcow2-cluster.c | ||
101 | +++ b/block/qcow2-cluster.c | ||
102 | @@ -XXX,XX +XXX,XX @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset, | ||
103 | int64_t cleared; | ||
104 | int ret; | ||
105 | |||
106 | + /* If we have to stay in sync with an external data file, zero out | ||
107 | + * s->data_file first. */ | ||
108 | + if (data_file_is_raw(bs)) { | ||
109 | + assert(has_data_file(bs)); | ||
110 | + ret = bdrv_co_pwrite_zeroes(s->data_file, offset, bytes, flags); | ||
111 | + if (ret < 0) { | ||
112 | + return ret; | ||
113 | + } | ||
114 | + } | ||
115 | + | ||
116 | /* Caller must pass aligned values, except at image end */ | ||
117 | assert(QEMU_IS_ALIGNED(offset, s->cluster_size)); | ||
118 | assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) || | ||
119 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
120 | index XXXXXXX..XXXXXXX 100644 | ||
121 | --- a/block/qcow2.c | ||
122 | +++ b/block/qcow2.c | ||
123 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, | ||
124 | "external data file"); | ||
125 | ret = -EINVAL; | ||
126 | goto fail; | ||
127 | - } else { | ||
128 | - s->data_file = bs->file; | ||
129 | + } | ||
130 | + | ||
131 | + s->data_file = bs->file; | ||
132 | + | ||
133 | + if (data_file_is_raw(bs)) { | ||
134 | + error_setg(errp, "data-file-raw requires a data file"); | ||
135 | + ret = -EINVAL; | ||
136 | + goto fail; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | @@ -XXX,XX +XXX,XX @@ static int qcow2_change_backing_file(BlockDriverState *bs, | ||
141 | { | ||
142 | BDRVQcow2State *s = bs->opaque; | ||
143 | |||
144 | + /* Adding a backing file means that the external data file alone won't be | ||
145 | + * enough to make sense of the content */ | ||
146 | + if (backing_file && data_file_is_raw(bs)) { | ||
147 | + return -EINVAL; | ||
148 | + } | ||
149 | + | ||
150 | if (backing_file && strlen(backing_file) > 1023) { | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | @@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) | ||
154 | } | ||
155 | refcount_order = ctz32(qcow2_opts->refcount_bits); | ||
156 | |||
157 | + if (qcow2_opts->data_file_raw && !qcow2_opts->data_file) { | ||
158 | + error_setg(errp, "data-file-raw requires data-file"); | ||
159 | + ret = -EINVAL; | ||
160 | + goto out; | ||
161 | + } | ||
162 | + if (qcow2_opts->data_file_raw && qcow2_opts->has_backing_file) { | ||
163 | + error_setg(errp, "Backing file and data-file-raw cannot be used at " | ||
164 | + "the same time"); | ||
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 | -- | ||
470 | 2.20.1 | ||
471 | |||
472 | diff view generated by jsdifflib |
New 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. | ||
1 | 4 | ||
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 |
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
---|---|---|---|
2 | |||
3 | This test is broken without previous commit fixing dead-lock in mirror. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
7 | Acked-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 1 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
9 | --- | 2 | --- |
10 | tests/qemu-iotests/235 | 76 ++++++++++++++++++++++++++++++++++++++ | 3 | tests/qemu-iotests/244 | 200 +++++++++++++++++++++++++++++++++++++ |
11 | tests/qemu-iotests/235.out | 3 ++ | 4 | tests/qemu-iotests/244.out | 125 +++++++++++++++++++++++ |
12 | tests/qemu-iotests/group | 1 + | 5 | tests/qemu-iotests/group | 1 + |
13 | 3 files changed, 80 insertions(+) | 6 | 3 files changed, 326 insertions(+) |
14 | create mode 100755 tests/qemu-iotests/235 | 7 | create mode 100755 tests/qemu-iotests/244 |
15 | create mode 100644 tests/qemu-iotests/235.out | 8 | create mode 100644 tests/qemu-iotests/244.out |
16 | 9 | ||
17 | diff --git a/tests/qemu-iotests/235 b/tests/qemu-iotests/235 | 10 | diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244 |
18 | new file mode 100755 | 11 | new file mode 100755 |
19 | index XXXXXXX..XXXXXXX | 12 | index XXXXXXX..XXXXXXX |
20 | --- /dev/null | 13 | --- /dev/null |
21 | +++ b/tests/qemu-iotests/235 | 14 | +++ b/tests/qemu-iotests/244 |
22 | @@ -XXX,XX +XXX,XX @@ | 15 | @@ -XXX,XX +XXX,XX @@ |
23 | +#!/usr/bin/env python | 16 | +#!/bin/bash |
24 | +# | 17 | +# |
25 | +# Simple mirror test | 18 | +# Test qcow2 with external data files |
26 | +# | 19 | +# |
27 | +# Copyright (c) 2018 Virtuozzo International GmbH. All rights reserved. | 20 | +# Copyright (C) 2019 Red Hat, Inc. |
28 | +# | 21 | +# |
29 | +# This program is free software; you can redistribute it and/or modify | 22 | +# This program is free software; you can redistribute it and/or modify |
30 | +# it under the terms of the GNU General Public License as published by | 23 | +# it under the terms of the GNU General Public License as published by |
31 | +# the Free Software Foundation; either version 2 of the License, or | 24 | +# the Free Software Foundation; either version 2 of the License, or |
32 | +# (at your option) any later version. | 25 | +# (at your option) any later version. |
... | ... | ||
38 | +# | 31 | +# |
39 | +# You should have received a copy of the GNU General Public License | 32 | +# You should have received a copy of the GNU General Public License |
40 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | 33 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
41 | +# | 34 | +# |
42 | + | 35 | + |
43 | +import sys | 36 | +# creator |
44 | +import os | 37 | +owner=kwolf@redhat.com |
45 | +import iotests | 38 | + |
46 | +from iotests import qemu_img_create, qemu_io, file_path, log | 39 | +seq=$(basename $0) |
47 | + | 40 | +echo "QA output created by $seq" |
48 | +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts')) | 41 | + |
49 | + | 42 | +status=1 # failure is the default! |
50 | +from qemu import QEMUMachine | 43 | + |
51 | + | 44 | +_cleanup() |
52 | +# Note: | 45 | +{ |
53 | +# This test was added to check that mirror dead-lock was fixed (see previous | 46 | + _cleanup_test_img |
54 | +# commit before this test addition). | 47 | + rm -f $TEST_IMG.data |
55 | +# And it didn't reproduce if at least one of the following: | 48 | + rm -f $TEST_IMG.src |
56 | +# 1. use small image size | 49 | +} |
57 | +# 2. use raw format (not qcow2) | 50 | +trap "_cleanup; exit \$status" 0 1 2 3 15 |
58 | +# 3. drop kvm and use iotests.VM() (maybe, because of qtest) (however, it still | 51 | + |
59 | +# reproduces, if just drop kvm, but gdb failed to produce full backtraces | 52 | +# get standard environment, filters and checks |
60 | +# for me) | 53 | +. ./common.rc |
61 | +# 4. add iothread | 54 | +. ./common.filter |
62 | + | 55 | + |
63 | +size = 1 * 1024 * 1024 * 1024 | 56 | +_supported_fmt qcow2 |
64 | + | 57 | +_supported_proto file |
65 | +iotests.verify_image_format(supported_fmts=['qcow2']) | 58 | +_supported_os Linux |
66 | + | 59 | + |
67 | +disk = file_path('disk') | 60 | +echo |
68 | + | 61 | +echo "=== Create and open image with external data file ===" |
69 | +# prepare source image | 62 | +echo |
70 | +qemu_img_create('-f', iotests.imgfmt, '-o', 'preallocation=metadata', disk, | 63 | + |
71 | + str(size)) | 64 | +echo "With data file name in the image:" |
72 | + | 65 | +IMGOPTS="data_file=$TEST_IMG.data" _make_test_img 64M |
73 | +vm = QEMUMachine(iotests.qemu_prog) | 66 | +_check_test_img |
74 | +vm.add_args('-machine', 'pc,accel=kvm') | 67 | + |
75 | +vm.add_args('-drive', 'id=src,file=' + disk) | 68 | +$QEMU_IO -c "open $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir |
76 | +vm.launch() | 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 |
77 | + | 70 | +$QEMU_IO -c "open -odata-file.filename=inexistent $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir |
78 | +log(vm.qmp('object-add', qom_type='throttle-group', id='tg0', | 71 | + |
79 | + props={ 'x-bps-total': size })) | 72 | +echo |
80 | + | 73 | +echo "Data file required, but without data file name in the image:" |
81 | +log(vm.qmp('blockdev-add', | 74 | +$QEMU_IMG amend -odata_file= $TEST_IMG |
82 | + **{ 'node-name': 'target', | 75 | + |
83 | + 'driver': 'throttle', | 76 | +$QEMU_IO -c "open $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir |
84 | + 'throttle-group': 'tg0', | 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 |
85 | + 'file': { | 78 | +$QEMU_IO -c "open -odata-file.filename=inexistent $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir |
86 | + 'driver': 'null-co', | 79 | + |
87 | + 'size': size | 80 | +echo |
88 | + } })) | 81 | +echo "Setting data-file for an image with internal data:" |
89 | + | 82 | +_make_test_img 64M |
90 | +log(vm.qmp('blockdev-mirror', device='src', target='target', sync='full')) | 83 | + |
91 | + | 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 |
92 | +try: | 85 | +$QEMU_IO -c "open -odata-file.filename=inexistent $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir |
93 | + vm.event_wait('BLOCK_JOB_READY', timeout=10.0) | 86 | + |
94 | +except: | 87 | +echo |
95 | + vm.shutdown() | 88 | +echo "=== Conflicting features ===" |
96 | + raise | 89 | +echo |
97 | + | 90 | + |
98 | +vm.shutdown() | 91 | +echo "Convert to compressed target with data file:" |
99 | diff --git a/tests/qemu-iotests/235.out b/tests/qemu-iotests/235.out | 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 | ||
100 | new file mode 100644 | 217 | new file mode 100644 |
101 | index XXXXXXX..XXXXXXX | 218 | index XXXXXXX..XXXXXXX |
102 | --- /dev/null | 219 | --- /dev/null |
103 | +++ b/tests/qemu-iotests/235.out | 220 | +++ b/tests/qemu-iotests/244.out |
104 | @@ -XXX,XX +XXX,XX @@ | 221 | @@ -XXX,XX +XXX,XX @@ |
105 | +{"return": {}} | 222 | +QA output created by 244 |
106 | +{"return": {}} | 223 | + |
107 | +{"return": {}} | 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 | ||
108 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | 347 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group |
109 | index XXXXXXX..XXXXXXX 100644 | 348 | index XXXXXXX..XXXXXXX 100644 |
110 | --- a/tests/qemu-iotests/group | 349 | --- a/tests/qemu-iotests/group |
111 | +++ b/tests/qemu-iotests/group | 350 | +++ b/tests/qemu-iotests/group |
112 | @@ -XXX,XX +XXX,XX @@ | 351 | @@ -XXX,XX +XXX,XX @@ |
113 | 232 auto quick | 352 | 240 auto quick |
114 | 233 auto quick | 353 | 242 rw auto quick |
115 | 234 auto quick migration | 354 | 243 rw auto quick |
116 | +235 auto quick | 355 | +244 rw auto quick |
117 | -- | 356 | -- |
118 | 2.19.2 | 357 | 2.20.1 |
119 | 358 | ||
120 | 359 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
2 | --- | ||
3 | tests/qemu-iotests/061 | 45 ++++++++++++++++++- | ||
4 | tests/qemu-iotests/061.out | 89 ++++++++++++++++++++++++++++++++++++++ | ||
5 | 2 files changed, 133 insertions(+), 1 deletion(-) | ||
1 | 6 | ||
7 | diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061 | ||
8 | index XXXXXXX..XXXXXXX 100755 | ||
9 | --- a/tests/qemu-iotests/061 | ||
10 | +++ b/tests/qemu-iotests/061 | ||
11 | @@ -XXX,XX +XXX,XX @@ status=1 # failure is the default! | ||
12 | |||
13 | _cleanup() | ||
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 | |||
25 | +echo | ||
26 | +echo "=== Testing version downgrade with external data file ===" | ||
27 | +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 | + | ||
33 | +echo | ||
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 | + | ||
39 | +echo | ||
40 | +IMGOPTS="compat=1.1,data_file=$TEST_IMG.data" _make_test_img 64M | ||
41 | +$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" | ||
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 | + | ||
45 | +echo | ||
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 | + | ||
50 | +echo | ||
51 | +echo "=== Clearing and setting data-file-raw ===" | ||
52 | +echo | ||
53 | +IMGOPTS="compat=1.1,data_file=$TEST_IMG.data,data_file_raw=on" _make_test_img 64M | ||
54 | +$QEMU_IMG amend -o "data_file_raw=on" "$TEST_IMG" | ||
55 | +_img_info --format-specific | ||
56 | +_check_test_img | ||
57 | + | ||
58 | +$QEMU_IMG amend -o "data_file_raw=off" "$TEST_IMG" | ||
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 | + | ||
67 | # success, all done | ||
68 | echo "*** done" | ||
69 | rm -f $seq.full | ||
70 | diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out | ||
71 | index XXXXXXX..XXXXXXX 100644 | ||
72 | --- a/tests/qemu-iotests/061.out | ||
73 | +++ b/tests/qemu-iotests/061.out | ||
74 | @@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 3221225472 | ||
75 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
76 | (0.00/100%) | ||
77 | (6.25/100%) | ||
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 | + | ||
96 | +=== Testing version downgrade with external data file === | ||
97 | + | ||
98 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data | ||
99 | +qemu-img: Cannot downgrade an image with a data file | ||
100 | +image: TEST_DIR/t.IMGFMT | ||
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 | ||
185 | -- | ||
186 | 2.20.1 | ||
187 | |||
188 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | Be more specific about the string representation in header extensions. | ||
1 | 2 | ||
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 |