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