xref: /qemu/tests/qemu-iotests/122 (revision 7ee9edfd)
1#!/bin/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
27here="$PWD"
28status=1	# failure is the default!
29
30_cleanup()
31{
32    rm -f "$TEST_IMG".[123]
33	_cleanup_test_img
34}
35trap "_cleanup; exit \$status" 0 1 2 3 15
36
37# get standard environment, filters and checks
38. ./common.rc
39. ./common.filter
40
41_supported_fmt qcow2
42_supported_proto file
43_supported_os Linux
44
45
46TEST_IMG="$TEST_IMG".base _make_test_img 64M
47$QEMU_IO -c "write -P 0x11 0 64M" "$TEST_IMG".base 2>&1 | _filter_qemu_io | _filter_testdir
48
49
50echo
51echo "=== Check allocation status regression with -B ==="
52echo
53
54_make_test_img -b "$TEST_IMG".base
55$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
56$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG" "$TEST_IMG".orig
57$QEMU_IMG map "$TEST_IMG".orig | _filter_qemu_img_map
58
59
60echo
61echo "=== Check that zero clusters are kept in overlay ==="
62echo
63
64_make_test_img -b "$TEST_IMG".base
65
66$QEMU_IO -c "write -P 0 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
67$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG" "$TEST_IMG".orig
68$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
69$QEMU_IMG convert -O $IMGFMT -c -B "$TEST_IMG".base "$TEST_IMG" "$TEST_IMG".orig
70$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
71
72$QEMU_IO -c "write -z 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
73$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG" "$TEST_IMG".orig
74$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
75$QEMU_IMG convert -O $IMGFMT -c -B "$TEST_IMG".base "$TEST_IMG" "$TEST_IMG".orig
76$QEMU_IO -c "read -P 0 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
77
78
79echo
80echo "=== Concatenate multiple source images ==="
81echo
82
83TEST_IMG="$TEST_IMG".1 _make_test_img 4M
84TEST_IMG="$TEST_IMG".2 _make_test_img 4M
85TEST_IMG="$TEST_IMG".3 _make_test_img 4M
86
87$QEMU_IO -c "write -P 0x11 0 64k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
88$QEMU_IO -c "write -P 0x22 0 64k" "$TEST_IMG".2 2>&1 | _filter_qemu_io | _filter_testdir
89$QEMU_IO -c "write -P 0x33 0 64k" "$TEST_IMG".3 2>&1 | _filter_qemu_io | _filter_testdir
90
91$QEMU_IMG convert -O $IMGFMT "$TEST_IMG".[123] "$TEST_IMG"
92$QEMU_IMG map "$TEST_IMG" | _filter_qemu_img_map
93$QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
94$QEMU_IO -c "read -P 0x22 4M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
95$QEMU_IO -c "read -P 0x33 8M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
96
97$QEMU_IMG convert -c -O $IMGFMT "$TEST_IMG".[123] "$TEST_IMG"
98$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
99$QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
100$QEMU_IO -c "read -P 0x22 4M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
101$QEMU_IO -c "read -P 0x33 8M 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
102
103# -B can't be combined with concatenation
104$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base "$TEST_IMG".[123] "$TEST_IMG"
105$QEMU_IMG convert -O $IMGFMT -c -B "$TEST_IMG".base "$TEST_IMG".[123] "$TEST_IMG"
106
107
108echo
109echo "=== Compression with misaligned allocations and image sizes ==="
110echo
111
112TEST_IMG="$TEST_IMG".1 _make_test_img 1023k -o cluster_size=1024
113TEST_IMG="$TEST_IMG".2 _make_test_img 1023k -o cluster_size=1024
114
115$QEMU_IO -c "write -P 0x11   16k  16k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
116$QEMU_IO -c "write -P 0x22  130k 130k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
117$QEMU_IO -c "write -P 0x33 1022k   1k" "$TEST_IMG".1 2>&1 | _filter_qemu_io | _filter_testdir
118$QEMU_IO -c "write -P 0x44    0k   1k" "$TEST_IMG".2 2>&1 | _filter_qemu_io | _filter_testdir
119
120$QEMU_IMG convert -c -O $IMGFMT "$TEST_IMG".[12] "$TEST_IMG"
121$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
122$QEMU_IO -c "read -P 0       0k   16k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
123$QEMU_IO -c "read -P 0x11   16k   16k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
124$QEMU_IO -c "read -P 0      32k   98k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
125$QEMU_IO -c "read -P 0x22  130k  130k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
126$QEMU_IO -c "read -P 0     260k  762k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
127$QEMU_IO -c "read -P 0x33 1022k    1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
128$QEMU_IO -c "read -P 0x44 1023k    1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
129$QEMU_IO -c "read -P 0    1024k 1022k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
130
131
132echo
133echo "=== Corrupted size field in compressed cluster descriptor ==="
134echo
135# Create an empty image and fill half of it with compressed data.
136# The L2 entries of the two compressed clusters are located at
137# 0x800000 and 0x800008, their original values are 0x4008000000a00000
138# and 0x4008000000a00802 (5 sectors for compressed data each).
139_make_test_img 8M -o cluster_size=2M
140$QEMU_IO -c "write -c -P 0x11 0 2M" -c "write -c -P 0x11 2M 2M" "$TEST_IMG" \
141         2>&1 | _filter_qemu_io | _filter_testdir
142
143# Reduce size of compressed data to 4 sectors: this corrupts the image.
144poke_file "$TEST_IMG" $((0x800000)) "\x40\x06"
145$QEMU_IO -c "read  -P 0x11 0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
146
147# 'qemu-img check' however doesn't see anything wrong because it
148# doesn't try to decompress the data and the refcounts are consistent.
149# TODO: update qemu-img so this can be detected.
150_check_test_img
151
152# Increase size of compressed data to the maximum (8192 sectors).
153# This makes QEMU read more data (8192 sectors instead of 5, host
154# addresses [0xa00000, 0xdfffff]), but the decompression algorithm
155# stops once we have enough to restore the uncompressed cluster, so
156# the rest of the data is ignored.
157poke_file "$TEST_IMG" $((0x800000)) "\x7f\xfe"
158# Do it also for the second compressed cluster (L2 entry at 0x800008).
159# In this case the compressed data would span 3 host clusters
160# (host addresses: [0xa00802, 0xe00801])
161poke_file "$TEST_IMG" $((0x800008)) "\x7f\xfe"
162
163# Here the image is too small so we're asking QEMU to read beyond the
164# end of the image.
165$QEMU_IO -c "read  -P 0x11  0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
166# But if we grow the image we won't be reading beyond its end anymore.
167$QEMU_IO -c "write -P 0x22 4M 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
168$QEMU_IO -c "read  -P 0x11  0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
169
170# The refcount data is however wrong because due to the increased size
171# of the compressed data it now reaches the following host clusters.
172# This can be repaired by qemu-img check by increasing the refcount of
173# those clusters.
174# TODO: update qemu-img to correct the compressed cluster size instead.
175_check_test_img -r all
176$QEMU_IO -c "read  -P 0x11  0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
177$QEMU_IO -c "read  -P 0x22 4M 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
178
179echo
180echo "=== Full allocation with -S 0 ==="
181echo
182
183# Standalone image
184_make_test_img 64M
185$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
186$QEMU_IO -c "write -P 0 3M 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
187
188echo
189echo convert -S 0:
190$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
191$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
192$QEMU_IO -c "read -P 0 3M 61M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
193$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
194
195echo
196echo convert -c -S 0:
197$QEMU_IMG convert -O $IMGFMT -c -S 0 "$TEST_IMG" "$TEST_IMG".orig
198$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
199$QEMU_IO -c "read -P 0 3M 61M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
200$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
201
202# With backing file
203TEST_IMG="$TEST_IMG".base _make_test_img 64M
204$QEMU_IO -c "write -P 0x11 0 32M" "$TEST_IMG".base 2>&1 | _filter_qemu_io | _filter_testdir
205
206_make_test_img -b "$TEST_IMG".base 64M
207$QEMU_IO -c "write -P 0x22 0 3M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
208
209echo
210echo convert -S 0 with source backing file:
211$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
212$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
213$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
214$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
215$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
216
217echo
218echo convert -c -S 0 with source backing file:
219$QEMU_IMG convert -O $IMGFMT -c -S 0 "$TEST_IMG" "$TEST_IMG".orig
220$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
221$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
222$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
223$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
224
225# With keeping the backing file
226echo
227echo convert -S 0 -B ...
228$QEMU_IMG convert -O $IMGFMT -S 0 "$TEST_IMG" "$TEST_IMG".orig
229$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
230$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
231$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
232$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
233
234echo
235echo convert -c -S 0 -B ...
236$QEMU_IMG convert -O $IMGFMT -c -S 0 "$TEST_IMG" "$TEST_IMG".orig
237$QEMU_IO -c "read -P 0x22 0 3M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
238$QEMU_IO -c "read -P 0x11 3M 29M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
239$QEMU_IO -c "read -P 0 32M 32M" "$TEST_IMG".orig 2>&1 | _filter_qemu_io | _filter_testdir
240$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
241
242
243echo
244echo "=== Non-zero -S ==="
245echo
246
247_make_test_img 64M -o cluster_size=1k
248$QEMU_IO -c "write -P 0 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
249$QEMU_IO -c "write 0 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
250$QEMU_IO -c "write 8k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
251$QEMU_IO -c "write 17k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
252
253for min_sparse in 4k 8k; do
254    echo
255    echo convert -S $min_sparse
256    $QEMU_IMG convert -O $IMGFMT -o cluster_size=1k -S $min_sparse "$TEST_IMG" "$TEST_IMG".orig
257    $QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
258
259    echo
260    echo convert -c -S $min_sparse
261    # For compressed images, -S values other than 0 are ignored
262    $QEMU_IMG convert -O $IMGFMT -o cluster_size=1k -c -S $min_sparse "$TEST_IMG" "$TEST_IMG".orig
263    $QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
264done
265
266# success, all done
267echo '*** done'
268rm -f $seq.full
269status=0
270