xref: /openbmc/qemu/tests/qemu-iotests/122 (revision 831734cc)
1#!/usr/bin/env bash
2# group: rw
3#
4# Test some qemu-img convert cases
5#
6# Copyright (C) 2015 Red Hat, Inc.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20#
21
22# creator
23owner=kwolf@redhat.com
24
25seq="$(basename $0)"
26echo "QA output created by $seq"
27
28status=1	# failure is the default!
29
30_cleanup()
31{
32    for img in "$TEST_IMG".[123]; do
33        _rm_test_img "$img"
34    done
35    _cleanup_test_img
36}
37trap "_cleanup; exit \$status" 0 1 2 3 15
38
39# get standard environment, filters and checks
40. ./common.rc
41. ./common.filter
42
43_supported_fmt qcow2
44_supported_proto file
45_supported_os Linux
46
47
48TEST_IMG="$TEST_IMG".base _make_test_img 64M
49$QEMU_IO -c "write -P 0x11 0 64M" "$TEST_IMG".base 2>&1 | _filter_qemu_io | _filter_testdir
50
51
52echo
53echo "=== Check allocation status regression with -B ==="
54echo
55
56_make_test_img -b "$TEST_IMG".base -F $IMGFMT
57$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
58$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base \
59    -o backing_fmt=$IMGFMT "$TEST_IMG" "$TEST_IMG".orig
60$QEMU_IMG map "$TEST_IMG".orig | _filter_qemu_img_map
61
62
63echo
64echo "=== Check that zero clusters are kept in overlay ==="
65echo
66
67_make_test_img -b "$TEST_IMG".base -F $IMGFMT
68
69$QEMU_IO -c "write -P 0 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
70$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -o backing_fmt=$IMGFMT \
71    "$TEST_IMG" "$TEST_IMG".orig
72$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
73$QEMU_IMG convert -O $IMGFMT -c -B "$TEST_IMG".base -o backing_fmt=$IMGFMT \
74    "$TEST_IMG" "$TEST_IMG".orig
75$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
76
77$QEMU_IO -c "write -z 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
78$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -o backing_fmt=$IMGFMT \
79    "$TEST_IMG" "$TEST_IMG".orig
80$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
81$QEMU_IMG convert -O $IMGFMT -c -B "$TEST_IMG".base -o backing_fmt=$IMGFMT \
82    "$TEST_IMG" "$TEST_IMG".orig
83$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
84
85
86echo
87echo "=== Converting to an overlay larger than its backing file ==="
88echo
89
90TEST_IMG="$TEST_IMG".base _make_test_img 256M
91# Needs to be at least how much an L2 table covers
92# (64 kB/entry * 64 kB / 8 B/entry = 512 MB)
93# That way, qcow2 will yield at least two status request responses.
94# With just a single response, it would always say "Allocated in the
95# backing file", so the optimization qemu-img convert tries to do is
96# done automatically.  Once it has to be queried twice, however (and
97# one of the queries is completely after the end of the backing file),
98# the block layer will automatically add a ZERO flag that qemu-img
99# convert used to follow up with a zero write to the target.
100# We do not want such a zero write, however, because we are past the
101# end of the backing file on the target as well, so we do not need to
102# write anything there.
103_make_test_img -b "$TEST_IMG".base 768M -F $IMGFMT
104
105# Use compat=0.10 as the output so there is no zero cluster support
106$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -o compat=0.10 \
107    -o backing_fmt=$IMGFMT "$TEST_IMG" "$TEST_IMG".orig
108# See that nothing has been allocated past 64M
109$QEMU_IMG map "$TEST_IMG".orig | _filter_qemu_img_map
110
111echo
112
113# Just before the end of the backing file
114$QEMU_IO -c 'write -P 0x11 255M 1M' "$TEST_IMG".base 2>&1 | _filter_qemu_io
115# Somewhere in the second L2 table
116$QEMU_IO -c 'write -P 0x22 600M 1M' "$TEST_IMG" 2>&1 | _filter_qemu_io
117
118$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -o compat=0.10 \
119    -o backing_fmt=$IMGFMT "$TEST_IMG" "$TEST_IMG".orig
120
121$QEMU_IMG map "$TEST_IMG".orig | _filter_qemu_img_map
122$QEMU_IO -c 'read -P 0x11 255M 1M' \
123         -c 'read -P 0x22 600M 1M' \
124         "$TEST_IMG".orig \
125    | _filter_qemu_io
126
127
128echo
129echo "=== Concatenate multiple source images ==="
130echo
131
132TEST_IMG="$TEST_IMG".1 _make_test_img 4M
133TEST_IMG="$TEST_IMG".2 _make_test_img 4M
134TEST_IMG="$TEST_IMG".3 _make_test_img 4M
135
136$QEMU_IO -c "write -P 0x11 0 64k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
137$QEMU_IO -c "write -P 0x22 0 64k" "$TEST_IMG".2 2>&1 | _filter_qemu_io | _filter_testdir
138$QEMU_IO -c "write -P 0x33 0 64k" "$TEST_IMG".3 2>&1 | _filter_qemu_io | _filter_testdir
139
140$QEMU_IMG convert -O $IMGFMT "$TEST_IMG".[123] "$TEST_IMG"
141$QEMU_IMG map "$TEST_IMG" | _filter_qemu_img_map
142$QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
143$QEMU_IO -c "read -P 0x22 4M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
144$QEMU_IO -c "read -P 0x33 8M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
145
146$QEMU_IMG convert -c -O $IMGFMT "$TEST_IMG".[123] "$TEST_IMG"
147$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
148$QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
149$QEMU_IO -c "read -P 0x22 4M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
150$QEMU_IO -c "read -P 0x33 8M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
151
152# -B can't be combined with concatenation
153$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG".[123] "$TEST_IMG"
154$QEMU_IMG convert -O $IMGFMT -c -B "$TEST_IMG".base "$TEST_IMG".[123] "$TEST_IMG"
155
156
157echo
158echo "=== Compression with misaligned allocations and image sizes ==="
159echo
160
161TEST_IMG="$TEST_IMG".1 _make_test_img 1023k -o cluster_size=1024
162TEST_IMG="$TEST_IMG".2 _make_test_img 1023k -o cluster_size=1024
163
164$QEMU_IO -c "write -P 0x11   16k  16k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
165$QEMU_IO -c "write -P 0x22  130k 130k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
166$QEMU_IO -c "write -P 0x33 1022k   1k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
167$QEMU_IO -c "write -P 0x44    0k   1k" "$TEST_IMG".2 2>&1 | _filter_qemu_io | _filter_testdir
168
169$QEMU_IMG convert -c -O $IMGFMT "$TEST_IMG".[12] "$TEST_IMG"
170$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
171$QEMU_IO -c "read -P 0       0k   16k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
172$QEMU_IO -c "read -P 0x11   16k   16k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
173$QEMU_IO -c "read -P 0      32k   98k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
174$QEMU_IO -c "read -P 0x22  130k  130k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
175$QEMU_IO -c "read -P 0     260k  762k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
176$QEMU_IO -c "read -P 0x33 1022k    1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
177$QEMU_IO -c "read -P 0x44 1023k    1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
178$QEMU_IO -c "read -P 0    1024k 1022k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
179
180
181echo
182echo "=== Full allocation with -S 0 ==="
183echo
184
185# Standalone image
186_make_test_img 64M
187$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
188$QEMU_IO -c "write -P 0 3M 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
189
190echo
191echo convert -S 0:
192$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
193$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
194$QEMU_IO -c "read -P 0 3M 61M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
195$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
196
197echo
198echo convert -c -S 0:
199$QEMU_IMG convert -O $IMGFMT -c -S 0 "$TEST_IMG" "$TEST_IMG".orig
200$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
201$QEMU_IO -c "read -P 0 3M 61M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
202$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
203
204# With backing file
205TEST_IMG="$TEST_IMG".base _make_test_img 64M
206$QEMU_IO -c "write -P 0x11 0 32M" "$TEST_IMG".base 2>&1 | _filter_qemu_io | _filter_testdir
207
208_make_test_img -b "$TEST_IMG".base 64M -F $IMGFMT
209$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
210
211echo
212echo convert -S 0 with source backing file:
213$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
214$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
215$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
216$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
217$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
218
219echo
220echo convert -c -S 0 with source backing file:
221$QEMU_IMG convert -O $IMGFMT -c -S 0 "$TEST_IMG" "$TEST_IMG".orig
222$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
223$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
224$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
225$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
226
227# With keeping the backing file
228echo
229echo convert -S 0 -B ...
230$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
231$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
232$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
233$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
234$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
235
236echo
237echo convert -c -S 0 -B ...
238$QEMU_IMG convert -O $IMGFMT -c -S 0 "$TEST_IMG" "$TEST_IMG".orig
239$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
240$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
241$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
242$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
243
244
245echo
246echo "=== Non-zero -S ==="
247echo
248
249_make_test_img 64M -o cluster_size=1k
250$QEMU_IO -c "write -P 0 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
251$QEMU_IO -c "write 0 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
252$QEMU_IO -c "write 8k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
253$QEMU_IO -c "write 17k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
254
255for min_sparse in 4k 8k; do
256    echo
257    echo convert -S $min_sparse
258    $QEMU_IMG convert -O $IMGFMT -o cluster_size=1k -S $min_sparse "$TEST_IMG" "$TEST_IMG".orig
259    $QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
260
261    echo
262    echo convert -c -S $min_sparse
263    # For compressed images, -S values other than 0 are ignored
264    $QEMU_IMG convert -O $IMGFMT -o cluster_size=1k -c -S $min_sparse "$TEST_IMG" "$TEST_IMG".orig
265    $QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
266done
267
268
269echo
270echo '=== -n to a non-zero image ==='
271echo
272
273# Keep source zero
274_make_test_img 64M
275
276# Output is not zero, but has bdrv_has_zero_init() == 1
277TEST_IMG="$TEST_IMG".orig _make_test_img 64M
278$QEMU_IO -c "write -P 42 0 64k" "$TEST_IMG".orig | _filter_qemu_io
279
280# Convert with -n, which should not assume that the target is zeroed
281$QEMU_IMG convert -O $IMGFMT -n "$TEST_IMG" "$TEST_IMG".orig
282
283$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG".orig
284
285echo
286echo '=== -n to an empty image ==='
287echo
288
289TEST_IMG="$TEST_IMG".orig _make_test_img 64M
290
291# Convert with -n, which should not result in a fully allocated image, not even
292# with compat=0.10 (because the target doesn't have a backing file)
293for compat in "1.1" "0.10"; do
294    IMGOPTS="compat=$compat" _make_test_img 64M
295    $QEMU_IMG convert -O $IMGFMT -n "$TEST_IMG".orig "$TEST_IMG"
296    $QEMU_IMG map --output=json "$TEST_IMG"
297done
298
299echo
300echo '=== -n to an empty image with a backing file ==='
301echo
302
303TEST_IMG="$TEST_IMG".orig _make_test_img 64M
304TEST_IMG="$TEST_IMG".base _make_test_img 64M
305
306# Convert with -n, which should still not result in a fully allocated image for
307# compat=1.1 (because it can use zero clusters), but it should be fully
308# allocated with compat=0.10
309for compat in "1.1" "0.10"; do
310    IMGOPTS="compat=$compat" _make_test_img -b "$TEST_IMG".base -F $IMGFMT 64M
311    $QEMU_IMG convert -O $IMGFMT -n "$TEST_IMG".orig "$TEST_IMG"
312    $QEMU_IMG map --output=json "$TEST_IMG"
313done
314
315echo
316echo '=== -n -B to an image without a backing file ==='
317echo
318
319# Base for the output
320TEST_IMG="$TEST_IMG".base _make_test_img 64M
321
322# Output that does have $TEST_IMG.base set as its (implicit) backing file
323TEST_IMG="$TEST_IMG".orig _make_test_img 64M
324
325# Convert with -n, which should not confuse -B with "target BDS has a
326# backing file"
327$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -n "$TEST_IMG" "$TEST_IMG".orig
328
329echo
330echo '=== -n incompatible with -o ==='
331echo
332
333$QEMU_IMG convert -O $IMGFMT -o preallocation=metadata -n \
334	  "$TEST_IMG" "$TEST_IMG".orig && echo "unexpected success"
335
336# success, all done
337echo '*** done'
338rm -f $seq.full
339status=0
340