066 was supposed to be a test "for discarding preallocated zero clusters", but it did so incompletely: While it did check the image file's integrity after the operation, it did not confirm that the clusters are indeed freed. This patch adds this test. In addition, new cases for writing to preallocated zero clusters are added. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
191 lines
4.9 KiB
Bash
Executable file
191 lines
4.9 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# Test case for preallocated zero clusters in qcow2
|
|
#
|
|
# Copyright (C) 2013 Red Hat, Inc.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
# creator
|
|
owner=mreitz@redhat.com
|
|
|
|
seq="$(basename $0)"
|
|
echo "QA output created by $seq"
|
|
|
|
here="$PWD"
|
|
status=1 # failure is the default!
|
|
|
|
_cleanup()
|
|
{
|
|
_cleanup_test_img
|
|
}
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common.rc
|
|
. ./common.filter
|
|
|
|
# This tests qocw2-specific low-level functionality
|
|
_supported_fmt qcow2
|
|
_supported_proto generic
|
|
_supported_os Linux
|
|
|
|
# Intentionally create an unaligned image
|
|
IMGOPTS="compat=1.1"
|
|
IMG_SIZE=$((64 * 1024 * 1024 + 512))
|
|
|
|
echo
|
|
echo "=== Testing cluster discards ==="
|
|
echo
|
|
_make_test_img $IMG_SIZE
|
|
# Write some normal clusters, zero some of them (creating preallocated
|
|
# zero clusters) and discard everything. Everything should now read as 0.
|
|
$QEMU_IO -c "write 0 256k" -c "write -z 0 256k" -c "write 64M 512" \
|
|
-c "discard 0 $IMG_SIZE" -c "read -P 0 0 $IMG_SIZE" "$TEST_IMG" \
|
|
| _filter_qemu_io
|
|
|
|
# Check the image (there shouldn't be any leaks)
|
|
_check_test_img
|
|
# Map the image (we want all clusters to be gone)
|
|
$QEMU_IMG map "$TEST_IMG"
|
|
|
|
_cleanup_test_img
|
|
|
|
|
|
echo
|
|
echo '=== Writing to preallocated zero clusters ==='
|
|
echo
|
|
|
|
_make_test_img $IMG_SIZE
|
|
|
|
# Create data clusters (not aligned to an L2 table)
|
|
$QEMU_IO -c 'write -P 42 1M 256k' "$TEST_IMG" | _filter_qemu_io
|
|
orig_map=$($QEMU_IMG map --output=json "$TEST_IMG")
|
|
|
|
# Convert the data clusters to preallocated zero clusters
|
|
$QEMU_IO -c 'write -z 1M 256k' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Now write to them (with a COW needed for the head and tail)
|
|
$QEMU_IO -c "write -P 23 $(((1024 + 32) * 1024)) 192k" "$TEST_IMG" \
|
|
| _filter_qemu_io
|
|
|
|
# Check metadata correctness
|
|
_check_test_img
|
|
|
|
# Check data correctness
|
|
$QEMU_IO -c "read -P 0 $(( 1024 * 1024)) 32k" \
|
|
-c "read -P 23 $(((1024 + 32) * 1024)) 192k" \
|
|
-c "read -P 0 $(((1024 + 32 + 192) * 1024)) 32k" \
|
|
"$TEST_IMG" \
|
|
| _filter_qemu_io
|
|
|
|
# Check that we have actually reused the original area
|
|
new_map=$($QEMU_IMG map --output=json "$TEST_IMG")
|
|
if [ "$new_map" = "$orig_map" ]; then
|
|
echo 'Successfully reused original clusters.'
|
|
else
|
|
echo 'Failed to reuse original clusters.'
|
|
echo 'Original map:'
|
|
echo "$orig_map"
|
|
echo 'New map:'
|
|
echo "$new_map"
|
|
fi
|
|
|
|
_cleanup_test_img
|
|
|
|
|
|
echo
|
|
echo '=== Writing to a snapshotted preallocated zero cluster ==='
|
|
echo
|
|
|
|
_make_test_img 64k
|
|
|
|
# Create a preallocated zero cluster
|
|
$QEMU_IO -c 'write -P 42 0 64k' -c 'write -z 0 64k' "$TEST_IMG" \
|
|
| _filter_qemu_io
|
|
|
|
# Snapshot it
|
|
$QEMU_IMG snapshot -c foo "$TEST_IMG"
|
|
|
|
# Write to the cluster
|
|
$QEMU_IO -c 'write -P 23 0 64k' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Check metadata correctness
|
|
_check_test_img
|
|
|
|
# Check data correctness
|
|
$QEMU_IO -c 'read -P 23 0 64k' "$TEST_IMG" | _filter_qemu_io
|
|
$QEMU_IMG snapshot -a foo "$TEST_IMG"
|
|
$QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
_cleanup_test_img
|
|
|
|
|
|
echo
|
|
echo '=== Consecutive write to a preallocated zero cluster ==='
|
|
echo
|
|
|
|
_make_test_img 192k
|
|
|
|
# Create three normal clusters
|
|
$QEMU_IO -c 'write -P 42 0 192k' "$TEST_IMG" | _filter_qemu_io
|
|
orig_map=$($QEMU_IMG map --output=json "$TEST_IMG")
|
|
|
|
# Make the middle cluster a preallocated zero cluster
|
|
$QEMU_IO -c 'write -z 64k 64k' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Try to overwrite everything: This should reuse the whole range. To test that
|
|
# this only issues a single continuous write request, use blkdebug.
|
|
$QEMU_IO -c 'write -P 42 0 192k' \
|
|
"json:{
|
|
'driver': '$IMGFMT',
|
|
'file': {
|
|
'driver': 'blkdebug',
|
|
'image.filename': '$TEST_IMG',
|
|
'set-state': [{
|
|
'event': 'write_aio',
|
|
'new_state': 2
|
|
}],
|
|
'inject-error': [{
|
|
'event': 'write_aio',
|
|
'state': 2
|
|
}]
|
|
}
|
|
}" \
|
|
| _filter_qemu_io
|
|
|
|
# Check metadata correctness
|
|
_check_test_img
|
|
|
|
# Check that we have actually reused the original area
|
|
new_map=$($QEMU_IMG map --output=json "$TEST_IMG")
|
|
if [ "$new_map" = "$orig_map" ]; then
|
|
echo 'Successfully reused original clusters.'
|
|
else
|
|
echo 'Failed to reuse original clusters.'
|
|
echo 'Original map:'
|
|
echo "$orig_map"
|
|
echo 'New map:'
|
|
echo "$new_map"
|
|
fi
|
|
|
|
_cleanup_test_img
|
|
|
|
|
|
# success, all done
|
|
echo "*** done"
|
|
rm -f $seq.full
|
|
status=0
|