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