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 279echo 280echo '=== -n -B to an image without a backing file ===' 281echo 282 283# Base for the output 284TEST_IMG="$TEST_IMG".base _make_test_img 64M 285 286# Output that does have $TEST_IMG.base set as its (implicit) backing file 287TEST_IMG="$TEST_IMG".orig _make_test_img 64M 288 289# Convert with -n, which should not confuse -B with "target BDS has a 290# backing file" 291$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -n "$TEST_IMG" "$TEST_IMG".orig 292 293# success, all done 294echo '*** done' 295rm -f $seq.full 296status=0 297