xref: /qemu/tests/qemu-iotests/122 (revision ab9056ff)
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    rm -f "$TEST_IMG".[123]
32	_cleanup_test_img
33}
34trap "_cleanup; exit \$status" 0 1 2 3 15
35
36# get standard environment, filters and checks
37. ./common.rc
38. ./common.filter
39
40_supported_fmt qcow2
41_supported_proto file
42_supported_os Linux
43
44
45TEST_IMG="$TEST_IMG".base _make_test_img 64M
46$QEMU_IO -c "write -P 0x11 0 64M" "$TEST_IMG".base 2>&1 | _filter_qemu_io | _filter_testdir
47
48
49echo
50echo "=== Check allocation status regression with -B ==="
51echo
52
53_make_test_img -b "$TEST_IMG".base
54$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
55$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG" "$TEST_IMG".orig
56$QEMU_IMG map "$TEST_IMG".orig | _filter_qemu_img_map
57
58
59echo
60echo "=== Check that zero clusters are kept in overlay ==="
61echo
62
63_make_test_img -b "$TEST_IMG".base
64
65$QEMU_IO -c "write -P 0 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
66$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG" "$TEST_IMG".orig
67$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
68$QEMU_IMG convert -O $IMGFMT -c -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
71$QEMU_IO -c "write -z 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
72$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG" "$TEST_IMG".orig
73$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
74$QEMU_IMG convert -O $IMGFMT -c -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
77
78echo
79echo "=== Converting to an overlay larger than its backing file ==="
80echo
81
82TEST_IMG="$TEST_IMG".base _make_test_img 256M
83# Needs to be at least how much an L2 table covers
84# (64 kB/entry * 64 kB / 8 B/entry = 512 MB)
85# That way, qcow2 will yield at least two status request responses.
86# With just a single response, it would always say "Allocated in the
87# backing file", so the optimization qemu-img convert tries to do is
88# done automatically.  Once it has to be queried twice, however (and
89# one of the queries is completely after the end of the backing file),
90# the block layer will automatically add a ZERO flag that qemu-img
91# convert used to follow up with a zero write to the target.
92# We do not want such a zero write, however, because we are past the
93# end of the backing file on the target as well, so we do not need to
94# write anything there.
95_make_test_img -b "$TEST_IMG".base 768M
96
97# Use compat=0.10 as the output so there is no zero cluster support
98$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -o compat=0.10 \
99    "$TEST_IMG" "$TEST_IMG".orig
100# See that nothing has been allocated past 64M
101$QEMU_IMG map "$TEST_IMG".orig | _filter_qemu_img_map
102
103echo
104
105# Just before the end of the backing file
106$QEMU_IO -c 'write -P 0x11 255M 1M' "$TEST_IMG".base 2>&1 | _filter_qemu_io
107# Somewhere in the second L2 table
108$QEMU_IO -c 'write -P 0x22 600M 1M' "$TEST_IMG" 2>&1 | _filter_qemu_io
109
110$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -o compat=0.10 \
111    "$TEST_IMG" "$TEST_IMG".orig
112
113$QEMU_IMG map "$TEST_IMG".orig | _filter_qemu_img_map
114$QEMU_IO -c 'read -P 0x11 255M 1M' \
115         -c 'read -P 0x22 600M 1M' \
116         "$TEST_IMG".orig \
117    | _filter_qemu_io
118
119
120echo
121echo "=== Concatenate multiple source images ==="
122echo
123
124TEST_IMG="$TEST_IMG".1 _make_test_img 4M
125TEST_IMG="$TEST_IMG".2 _make_test_img 4M
126TEST_IMG="$TEST_IMG".3 _make_test_img 4M
127
128$QEMU_IO -c "write -P 0x11 0 64k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
129$QEMU_IO -c "write -P 0x22 0 64k" "$TEST_IMG".2 2>&1 | _filter_qemu_io | _filter_testdir
130$QEMU_IO -c "write -P 0x33 0 64k" "$TEST_IMG".3 2>&1 | _filter_qemu_io | _filter_testdir
131
132$QEMU_IMG convert -O $IMGFMT "$TEST_IMG".[123] "$TEST_IMG"
133$QEMU_IMG map "$TEST_IMG" | _filter_qemu_img_map
134$QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
135$QEMU_IO -c "read -P 0x22 4M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
136$QEMU_IO -c "read -P 0x33 8M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
137
138$QEMU_IMG convert -c -O $IMGFMT "$TEST_IMG".[123] "$TEST_IMG"
139$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
140$QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
141$QEMU_IO -c "read -P 0x22 4M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
142$QEMU_IO -c "read -P 0x33 8M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
143
144# -B can't be combined with concatenation
145$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG".[123] "$TEST_IMG"
146$QEMU_IMG convert -O $IMGFMT -c -B "$TEST_IMG".base "$TEST_IMG".[123] "$TEST_IMG"
147
148
149echo
150echo "=== Compression with misaligned allocations and image sizes ==="
151echo
152
153TEST_IMG="$TEST_IMG".1 _make_test_img 1023k -o cluster_size=1024
154TEST_IMG="$TEST_IMG".2 _make_test_img 1023k -o cluster_size=1024
155
156$QEMU_IO -c "write -P 0x11   16k  16k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
157$QEMU_IO -c "write -P 0x22  130k 130k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
158$QEMU_IO -c "write -P 0x33 1022k   1k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
159$QEMU_IO -c "write -P 0x44    0k   1k" "$TEST_IMG".2 2>&1 | _filter_qemu_io | _filter_testdir
160
161$QEMU_IMG convert -c -O $IMGFMT "$TEST_IMG".[12] "$TEST_IMG"
162$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
163$QEMU_IO -c "read -P 0       0k   16k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
164$QEMU_IO -c "read -P 0x11   16k   16k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
165$QEMU_IO -c "read -P 0      32k   98k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
166$QEMU_IO -c "read -P 0x22  130k  130k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
167$QEMU_IO -c "read -P 0     260k  762k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
168$QEMU_IO -c "read -P 0x33 1022k    1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
169$QEMU_IO -c "read -P 0x44 1023k    1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
170$QEMU_IO -c "read -P 0    1024k 1022k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
171
172
173echo
174echo "=== Full allocation with -S 0 ==="
175echo
176
177# Standalone image
178_make_test_img 64M
179$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
180$QEMU_IO -c "write -P 0 3M 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
181
182echo
183echo convert -S 0:
184$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
185$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
186$QEMU_IO -c "read -P 0 3M 61M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
187$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
188
189echo
190echo convert -c -S 0:
191$QEMU_IMG convert -O $IMGFMT -c -S 0 "$TEST_IMG" "$TEST_IMG".orig
192$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
193$QEMU_IO -c "read -P 0 3M 61M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
194$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
195
196# With backing file
197TEST_IMG="$TEST_IMG".base _make_test_img 64M
198$QEMU_IO -c "write -P 0x11 0 32M" "$TEST_IMG".base 2>&1 | _filter_qemu_io | _filter_testdir
199
200_make_test_img -b "$TEST_IMG".base 64M
201$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
202
203echo
204echo convert -S 0 with source backing file:
205$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
206$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
207$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
208$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
209$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
210
211echo
212echo convert -c -S 0 with source backing file:
213$QEMU_IMG convert -O $IMGFMT -c -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
219# With keeping the backing file
220echo
221echo convert -S 0 -B ...
222$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
223$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
224$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
225$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
226$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
227
228echo
229echo convert -c -S 0 -B ...
230$QEMU_IMG convert -O $IMGFMT -c -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
236
237echo
238echo "=== Non-zero -S ==="
239echo
240
241_make_test_img 64M -o cluster_size=1k
242$QEMU_IO -c "write -P 0 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
243$QEMU_IO -c "write 0 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
244$QEMU_IO -c "write 8k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
245$QEMU_IO -c "write 17k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
246
247for min_sparse in 4k 8k; do
248    echo
249    echo convert -S $min_sparse
250    $QEMU_IMG convert -O $IMGFMT -o cluster_size=1k -S $min_sparse "$TEST_IMG" "$TEST_IMG".orig
251    $QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
252
253    echo
254    echo convert -c -S $min_sparse
255    # For compressed images, -S values other than 0 are ignored
256    $QEMU_IMG convert -O $IMGFMT -o cluster_size=1k -c -S $min_sparse "$TEST_IMG" "$TEST_IMG".orig
257    $QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
258done
259
260
261echo
262echo '=== -n to a non-zero image ==='
263echo
264
265# Keep source zero
266_make_test_img 64M
267
268# Output is not zero, but has bdrv_has_zero_init() == 1
269TEST_IMG="$TEST_IMG".orig _make_test_img 64M
270$QEMU_IO -c "write -P 42 0 64k" "$TEST_IMG".orig | _filter_qemu_io
271
272# Convert with -n, which should not assume that the target is zeroed
273$QEMU_IMG convert -O $IMGFMT -n "$TEST_IMG" "$TEST_IMG".orig
274
275$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG".orig
276
277# success, all done
278echo '*** done'
279rm -f $seq.full
280status=0
281