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