1#!/bin/bash 2# 3# qcow2 specific bdrv_pwrite_zeroes tests with backing files (complements 034) 4# 5# Copyright (C) 2016 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 _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 44CLUSTER_SIZE=4k 45size=128M 46 47echo 48echo == backing file contains zeros == 49 50CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 51_make_test_img -b "$TEST_IMG.base" 52 53# Make sure that the whole cluster is allocated even for partial write_zeroes 54# when the backing file contains zeros 55 56# X = non-zero data sector in backing file 57# - = sector unallocated in whole backing chain 58# 0 = sector touched by write_zeroes request 59 60# 1. Tail unaligned: 00 00 -- -- 61# 2. Head unaligned: -- -- 00 00 62# 3. Both unaligned: -- 00 00 -- 63# 4. Both, 2 clusters: -- -- -- 00 | 00 -- -- -- 64 65$QEMU_IO -c "write -z 0 2k" "$TEST_IMG" | _filter_qemu_io 66$QEMU_IO -c "write -z 10k 2k" "$TEST_IMG" | _filter_qemu_io 67$QEMU_IO -c "write -z 17k 2k" "$TEST_IMG" | _filter_qemu_io 68$QEMU_IO -c "write -z 27k 2k" "$TEST_IMG" | _filter_qemu_io 69$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 70 71echo 72echo == backing file contains non-zero data before write_zeroes == 73 74CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 75_make_test_img -b "$TEST_IMG.base" 76 77# Single cluster; non-zero data at the cluster start 78# ... | XX -- 00 -- | ... 79$QEMU_IO -c "write -P 0x11 32k 1k" "$TEST_IMG.base" | _filter_qemu_io 80$QEMU_IO -c "write -z 34k 1k" "$TEST_IMG" | _filter_qemu_io 81$QEMU_IO -c "read -P 0x11 32k 1k" "$TEST_IMG" | _filter_qemu_io 82$QEMU_IO -c "read -P 0 33k 3k" "$TEST_IMG" | _filter_qemu_io 83 84# Single cluster; non-zero data exists, but not at the cluster start 85# ... | -- XX 00 -- | ... 86$QEMU_IO -c "write -P 0x11 65k 1k" "$TEST_IMG.base" | _filter_qemu_io 87$QEMU_IO -c "write -z 66k 1k" "$TEST_IMG" | _filter_qemu_io 88$QEMU_IO -c "read -P 0x11 65k 1k" "$TEST_IMG" | _filter_qemu_io 89$QEMU_IO -c "read -P 0 64k 1k" "$TEST_IMG" | _filter_qemu_io 90$QEMU_IO -c "read -P 0 66k 2k" "$TEST_IMG" | _filter_qemu_io 91 92$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 93 94echo 95echo == backing file contains non-zero data after write_zeroes == 96 97CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 98_make_test_img -b "$TEST_IMG.base" 99 100# Single cluster; non-zero data directly after request 101# ... | -- 00 XX -- | ... 102$QEMU_IO -c "write -P 0x11 34k 1k" "$TEST_IMG.base" | _filter_qemu_io 103$QEMU_IO -c "write -z 33k 1k" "$TEST_IMG" | _filter_qemu_io 104$QEMU_IO -c "read -P 0 32k 2k" "$TEST_IMG" | _filter_qemu_io 105$QEMU_IO -c "read -P 0x11 34k 1k" "$TEST_IMG" | _filter_qemu_io 106$QEMU_IO -c "read -P 0 35k 1k" "$TEST_IMG" | _filter_qemu_io 107 108# Single cluster; non-zero data exists, but not directly after request 109# ... | -- 00 -- XX | ... 110$QEMU_IO -c "write -P 0x11 43k 1k" "$TEST_IMG.base" | _filter_qemu_io 111$QEMU_IO -c "write -z 41k 1k" "$TEST_IMG" | _filter_qemu_io 112$QEMU_IO -c "read -P 0x11 43k 1k" "$TEST_IMG" | _filter_qemu_io 113$QEMU_IO -c "read -P 0 40k 3k" "$TEST_IMG" | _filter_qemu_io 114 115$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 116 117echo 118echo == write_zeroes covers non-zero data == 119 120CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 121_make_test_img -b "$TEST_IMG.base" 122 123# non-zero data at front of request 124# Backing file: -- XX -- -- 125# Active layer: -- 00 00 -- 126 127$QEMU_IO -c "write -P 0x11 5k 1k" "$TEST_IMG.base" | _filter_qemu_io 128$QEMU_IO -c "write -z 5k 2k" "$TEST_IMG" | _filter_qemu_io 129$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io 130 131# non-zero data at end of request 132# Backing file: -- -- XX -- 133# Active layer: -- 00 00 -- 134 135$QEMU_IO -c "write -P 0x11 14k 1k" "$TEST_IMG.base" | _filter_qemu_io 136$QEMU_IO -c "write -z 13k 2k" "$TEST_IMG" | _filter_qemu_io 137$QEMU_IO -c "read -P 0 12k 4k" "$TEST_IMG" | _filter_qemu_io 138 139# non-zero data matches size of request 140# Backing file: -- XX XX -- 141# Active layer: -- 00 00 -- 142 143$QEMU_IO -c "write -P 0x11 21k 2k" "$TEST_IMG.base" | _filter_qemu_io 144$QEMU_IO -c "write -z 21k 2k" "$TEST_IMG" | _filter_qemu_io 145$QEMU_IO -c "read -P 0 20k 4k" "$TEST_IMG" | _filter_qemu_io 146 147# non-zero data smaller than request 148# Backing file: -- -X X- -- 149# Active layer: -- 00 00 -- 150 151$QEMU_IO -c "write -P 0x11 30208 1k" "$TEST_IMG.base" | _filter_qemu_io 152$QEMU_IO -c "write -z 29k 2k" "$TEST_IMG" | _filter_qemu_io 153$QEMU_IO -c "read -P 0 28k 4k" "$TEST_IMG" | _filter_qemu_io 154 155$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 156 157echo 158echo == spanning two clusters, non-zero before request == 159 160CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 161_make_test_img -b "$TEST_IMG.base" 162 163# Two clusters; non-zero data before request: 164# 1. At cluster start: 32k: XX -- -- 00 | 00 -- -- -- 165# 2. Between unallocated space: 48k: -- XX -- 00 | 00 -- -- -- 166# 3. Directly before request: 64k: -- -- XX 00 | 00 -- -- -- 167 168$QEMU_IO -c "write -P 0x11 32k 1k" "$TEST_IMG.base" | _filter_qemu_io 169$QEMU_IO -c "write -z 35k 2k" "$TEST_IMG" | _filter_qemu_io 170$QEMU_IO -c "read -P 0x11 32k 1k" "$TEST_IMG" | _filter_qemu_io 171$QEMU_IO -c "read -P 0 33k 7k" "$TEST_IMG" | _filter_qemu_io 172 173$QEMU_IO -c "write -P 0x11 49k 1k" "$TEST_IMG.base" | _filter_qemu_io 174$QEMU_IO -c "write -z 51k 2k" "$TEST_IMG" | _filter_qemu_io 175$QEMU_IO -c "read -P 0 48k 1k" "$TEST_IMG" | _filter_qemu_io 176$QEMU_IO -c "read -P 0x11 49k 1k" "$TEST_IMG" | _filter_qemu_io 177$QEMU_IO -c "read -P 0 50k 6k" "$TEST_IMG" | _filter_qemu_io 178 179$QEMU_IO -c "write -P 0x11 66k 1k" "$TEST_IMG.base" | _filter_qemu_io 180$QEMU_IO -c "write -z 67k 2k" "$TEST_IMG" | _filter_qemu_io 181$QEMU_IO -c "read -P 0 64k 2k" "$TEST_IMG" | _filter_qemu_io 182$QEMU_IO -c "read -P 0x11 66k 1k" "$TEST_IMG" | _filter_qemu_io 183$QEMU_IO -c "read -P 0 67k 5k" "$TEST_IMG" | _filter_qemu_io 184 185$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 186 187echo 188echo == spanning two clusters, non-zero after request == 189 190CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 191_make_test_img -b "$TEST_IMG.base" 192 193# Two clusters; non-zero data after request: 194# 1. Directly after request: 32k: -- -- -- 00 | 00 XX -- -- 195# 2. Between unallocated space: 48k: -- -- -- 00 | 00 -- XX -- 196# 3. At cluster end: 64k: -- -- -- 00 | 00 -- -- XX 197 198$QEMU_IO -c "write -P 0x11 37k 1k" "$TEST_IMG.base" | _filter_qemu_io 199$QEMU_IO -c "write -z 35k 2k" "$TEST_IMG" | _filter_qemu_io 200$QEMU_IO -c "read -P 0 32k 5k" "$TEST_IMG" | _filter_qemu_io 201$QEMU_IO -c "read -P 0x11 37k 1k" "$TEST_IMG" | _filter_qemu_io 202$QEMU_IO -c "read -P 0 38k 2k" "$TEST_IMG" | _filter_qemu_io 203 204$QEMU_IO -c "write -P 0x11 54k 1k" "$TEST_IMG.base" | _filter_qemu_io 205$QEMU_IO -c "write -z 51k 2k" "$TEST_IMG" | _filter_qemu_io 206$QEMU_IO -c "read -P 0 48k 6k" "$TEST_IMG" | _filter_qemu_io 207$QEMU_IO -c "read -P 0x11 54k 1k" "$TEST_IMG" | _filter_qemu_io 208$QEMU_IO -c "read -P 0 55k 1k" "$TEST_IMG" | _filter_qemu_io 209 210$QEMU_IO -c "write -P 0x11 71k 1k" "$TEST_IMG.base" | _filter_qemu_io 211$QEMU_IO -c "write -z 67k 2k" "$TEST_IMG" | _filter_qemu_io 212$QEMU_IO -c "read -P 0 64k 7k" "$TEST_IMG" | _filter_qemu_io 213$QEMU_IO -c "read -P 0x11 71k 1k" "$TEST_IMG" | _filter_qemu_io 214 215$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 216 217echo 218echo == spanning two clusters, partially overwriting backing file == 219 220CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 221_make_test_img -b "$TEST_IMG.base" 222 223# Backing file: -- -- XX XX | XX XX -- -- 224# Active layer: -- -- XX 00 | 00 XX -- -- 225 226$QEMU_IO -c "write -P 0x11 2k 4k" "$TEST_IMG.base" | _filter_qemu_io 227$QEMU_IO -c "write -z 3k 2k" "$TEST_IMG" | _filter_qemu_io 228$QEMU_IO -c "read -P 0 0k 2k" "$TEST_IMG" | _filter_qemu_io 229$QEMU_IO -c "read -P 0x11 2k 1k" "$TEST_IMG" | _filter_qemu_io 230$QEMU_IO -c "read -P 0 3k 2k" "$TEST_IMG" | _filter_qemu_io 231$QEMU_IO -c "read -P 0x11 5k 1k" "$TEST_IMG" | _filter_qemu_io 232$QEMU_IO -c "read -P 0 6k 2k" "$TEST_IMG" | _filter_qemu_io 233 234$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 235 236echo 237echo == spanning multiple clusters, non-zero in first cluster == 238 239CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 240_make_test_img -b "$TEST_IMG.base" 241 242# Backing file: 64k: XX XX -- -- | -- -- -- -- | -- -- -- -- 243# Active layer: 64k: XX XX 00 00 | 00 00 00 00 | 00 -- -- -- 244 245$QEMU_IO -c "write -P 0x11 64k 2k" "$TEST_IMG.base" | _filter_qemu_io 246$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io 247$QEMU_IO -c "read -P 0x11 64k 2k" "$TEST_IMG" | _filter_qemu_io 248$QEMU_IO -c "read -P 0 66k 10k" "$TEST_IMG" | _filter_qemu_io 249 250$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 251 252echo 253echo == spanning multiple clusters, non-zero in intermediate cluster == 254 255CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 256_make_test_img -b "$TEST_IMG.base" 257 258# Backing file: 64k: -- -- -- -- | -- XX XX -- | -- -- -- -- 259# Active layer: 64k: -- -- 00 00 | 00 00 00 00 | 00 -- -- -- 260 261$QEMU_IO -c "write -P 0x11 69k 2k" "$TEST_IMG.base" | _filter_qemu_io 262$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io 263$QEMU_IO -c "read -P 0 64k 12k" "$TEST_IMG" | _filter_qemu_io 264 265$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 266 267echo 268echo == spanning multiple clusters, non-zero in final cluster == 269 270CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 271_make_test_img -b "$TEST_IMG.base" 272 273# Backing file: 64k: -- -- -- -- | -- -- -- -- | -- -- XX XX 274# Active layer: 64k: -- -- 00 00 | 00 00 00 00 | 00 -- XX XX 275 276$QEMU_IO -c "write -P 0x11 74k 2k" "$TEST_IMG.base" | _filter_qemu_io 277$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io 278$QEMU_IO -c "read -P 0 64k 10k" "$TEST_IMG" | _filter_qemu_io 279$QEMU_IO -c "read -P 0x11 74k 2k" "$TEST_IMG" | _filter_qemu_io 280 281$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 282 283echo 284echo == spanning multiple clusters, partially overwriting backing file == 285 286CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size 287_make_test_img -b "$TEST_IMG.base" 288 289# Backing file: 64k: -- XX XX XX | XX XX XX XX | XX XX XX -- 290# Active layer: 64k: -- XX 00 00 | 00 00 00 00 | 00 XX XX -- 291 292$QEMU_IO -c "write -P 0x11 65k 10k" "$TEST_IMG.base" | _filter_qemu_io 293$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io 294$QEMU_IO -c "read -P 0 64k 1k" "$TEST_IMG" | _filter_qemu_io 295$QEMU_IO -c "read -P 0x11 65k 1k" "$TEST_IMG" | _filter_qemu_io 296$QEMU_IO -c "read -P 0 66k 7k" "$TEST_IMG" | _filter_qemu_io 297$QEMU_IO -c "read -P 0x11 73k 2k" "$TEST_IMG" | _filter_qemu_io 298$QEMU_IO -c "read -P 0 75k 1k" "$TEST_IMG" | _filter_qemu_io 299 300$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map 301 302# success, all done 303echo "*** done" 304rm -f $seq.full 305status=0 306