1#!/bin/bash 2# 3# Test case for preallocated zero clusters in qcow2 4# 5# Copyright (C) 2013 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=mreitz@redhat.com 23 24seq="$(basename $0)" 25echo "QA output created by $seq" 26 27status=1 # failure is the default! 28 29_cleanup() 30{ 31 _cleanup_test_img 32} 33trap "_cleanup; exit \$status" 0 1 2 3 15 34 35# get standard environment, filters and checks 36. ./common.rc 37. ./common.filter 38 39# This tests qocw2-specific low-level functionality 40_supported_fmt qcow2 41_supported_proto generic 42_supported_os Linux 43 44# Intentionally create an unaligned image 45IMGOPTS="compat=1.1" 46IMG_SIZE=$((64 * 1024 * 1024 + 512)) 47 48echo 49echo "=== Testing cluster discards ===" 50echo 51_make_test_img $IMG_SIZE 52# Write some normal clusters, zero some of them (creating preallocated 53# zero clusters) and discard everything. Everything should now read as 0. 54$QEMU_IO -c "write 0 256k" -c "write -z 0 256k" -c "write 64M 512" \ 55 -c "discard 0 $IMG_SIZE" -c "read -P 0 0 $IMG_SIZE" "$TEST_IMG" \ 56 | _filter_qemu_io 57 58# Check the image (there shouldn't be any leaks) 59_check_test_img 60# Map the image (we want all clusters to be gone) 61$QEMU_IMG map "$TEST_IMG" 62 63_cleanup_test_img 64 65 66echo 67echo '=== Writing to preallocated zero clusters ===' 68echo 69 70_make_test_img $IMG_SIZE 71 72# Create data clusters (not aligned to an L2 table) 73$QEMU_IO -c 'write -P 42 1M 256k' "$TEST_IMG" | _filter_qemu_io 74orig_map=$($QEMU_IMG map --output=json "$TEST_IMG") 75 76# Convert the data clusters to preallocated zero clusters 77$QEMU_IO -c 'write -z 1M 256k' "$TEST_IMG" | _filter_qemu_io 78 79# Now write to them (with a COW needed for the head and tail) 80$QEMU_IO -c "write -P 23 $(((1024 + 32) * 1024)) 192k" "$TEST_IMG" \ 81 | _filter_qemu_io 82 83# Check metadata correctness 84_check_test_img 85 86# Check data correctness 87$QEMU_IO -c "read -P 0 $(( 1024 * 1024)) 32k" \ 88 -c "read -P 23 $(((1024 + 32) * 1024)) 192k" \ 89 -c "read -P 0 $(((1024 + 32 + 192) * 1024)) 32k" \ 90 "$TEST_IMG" \ 91 | _filter_qemu_io 92 93# Check that we have actually reused the original area 94new_map=$($QEMU_IMG map --output=json "$TEST_IMG") 95if [ "$new_map" = "$orig_map" ]; then 96 echo 'Successfully reused original clusters.' 97else 98 echo 'Failed to reuse original clusters.' 99 echo 'Original map:' 100 echo "$orig_map" 101 echo 'New map:' 102 echo "$new_map" 103fi 104 105_cleanup_test_img 106 107 108echo 109echo '=== Writing to a snapshotted preallocated zero cluster ===' 110echo 111 112_make_test_img 64k 113 114# Create a preallocated zero cluster 115$QEMU_IO -c 'write -P 42 0 64k' -c 'write -z 0 64k' "$TEST_IMG" \ 116 | _filter_qemu_io 117 118# Snapshot it 119$QEMU_IMG snapshot -c foo "$TEST_IMG" 120 121# Write to the cluster 122$QEMU_IO -c 'write -P 23 0 64k' "$TEST_IMG" | _filter_qemu_io 123 124# Check metadata correctness 125_check_test_img 126 127# Check data correctness 128$QEMU_IO -c 'read -P 23 0 64k' "$TEST_IMG" | _filter_qemu_io 129$QEMU_IMG snapshot -a foo "$TEST_IMG" 130$QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io 131 132_cleanup_test_img 133 134 135echo 136echo '=== Consecutive write to a preallocated zero cluster ===' 137echo 138 139_make_test_img 192k 140 141# Create three normal clusters 142$QEMU_IO -c 'write -P 42 0 192k' "$TEST_IMG" | _filter_qemu_io 143orig_map=$($QEMU_IMG map --output=json "$TEST_IMG") 144 145# Make the middle cluster a preallocated zero cluster 146$QEMU_IO -c 'write -z 64k 64k' "$TEST_IMG" | _filter_qemu_io 147 148# Try to overwrite everything: This should reuse the whole range. To test that 149# this only issues a single continuous write request, use blkdebug. 150$QEMU_IO -c 'write -P 42 0 192k' \ 151 "json:{ 152 'driver': '$IMGFMT', 153 'file': { 154 'driver': 'blkdebug', 155 'image.filename': '$TEST_IMG', 156 'set-state': [{ 157 'event': 'write_aio', 158 'new_state': 2 159 }], 160 'inject-error': [{ 161 'event': 'write_aio', 162 'state': 2 163 }] 164 } 165 }" \ 166 | _filter_qemu_io 167 168# Check metadata correctness 169_check_test_img 170 171# Check that we have actually reused the original area 172new_map=$($QEMU_IMG map --output=json "$TEST_IMG") 173if [ "$new_map" = "$orig_map" ]; then 174 echo 'Successfully reused original clusters.' 175else 176 echo 'Failed to reuse original clusters.' 177 echo 'Original map:' 178 echo "$orig_map" 179 echo 'New map:' 180 echo "$new_map" 181fi 182 183_cleanup_test_img 184 185 186# success, all done 187echo "*** done" 188rm -f $seq.full 189status=0 190