e2f938265e
Add testcase which checks that allocations during copy-on-read are performed on the subcluster basis when subclusters are enabled in target image. This testcase also triggers the following assert with previous commit not being applied, so we check that as well: qemu-io: ../block/io.c:1236: bdrv_co_do_copy_on_readv: Assertion `skip_bytes < pnum' failed. Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Denis V. Lunev <den@openvz.org> Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-ID: <20230711172553.234055-4-andrey.drobyshev@virtuozzo.com>
157 lines
5.1 KiB
Bash
Executable File
157 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# group: rw quick
|
|
#
|
|
# Test case for copy-on-read into qcow2
|
|
#
|
|
# Copyright (C) 2017 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=eblake@redhat.com
|
|
|
|
seq="$(basename $0)"
|
|
echo "QA output created by $seq"
|
|
|
|
status=1 # failure is the default!
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common.rc
|
|
. ./common.filter
|
|
|
|
TEST_WRAP="$TEST_DIR/t.wrap.qcow2"
|
|
BLKDBG_CONF="$TEST_DIR/blkdebug.conf"
|
|
|
|
# Sanity check: our use of blkdebug fails if $TEST_DIR contains spaces
|
|
# or other problems
|
|
case "$TEST_DIR" in
|
|
*[^-_a-zA-Z0-9/]*)
|
|
_notrun "Suspicious TEST_DIR='$TEST_DIR', cowardly refusing to run" ;;
|
|
esac
|
|
|
|
_cleanup()
|
|
{
|
|
_cleanup_test_img
|
|
_rm_test_img "$TEST_WRAP"
|
|
rm -f "$BLKDBG_CONF"
|
|
}
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
# Test is supported for any backing file; but we force qcow2 for our wrapper.
|
|
_supported_fmt generic
|
|
_supported_proto generic
|
|
# LUKS support may be possible, but it complicates things.
|
|
_unsupported_fmt luks
|
|
_unsupported_imgopts "subformat=streamOptimized"
|
|
|
|
echo
|
|
echo '=== Copy-on-read ==='
|
|
echo
|
|
|
|
# Prep the images
|
|
# VPC rounds image sizes to a specific geometry, force a specific size.
|
|
if [ "$IMGFMT" = "vpc" ]; then
|
|
IMGOPTS=$(_optstr_add "$IMGOPTS" "force_size")
|
|
fi
|
|
_make_test_img 4G
|
|
$QEMU_IO -c "write -P 55 3G 1k" "$TEST_IMG" | _filter_qemu_io
|
|
IMGPROTO=file IMGFMT=qcow2 TEST_IMG_FILE="$TEST_WRAP" \
|
|
_make_test_img --no-opts -F "$IMGFMT" -b "$TEST_IMG" | _filter_img_create
|
|
$QEMU_IO -f qcow2 -c "write -z -u 1M 64k" "$TEST_WRAP" | _filter_qemu_io
|
|
|
|
# Ensure that a read of two clusters, but where one is already allocated,
|
|
# does not re-write the allocated cluster
|
|
cat > "$BLKDBG_CONF" <<EOF
|
|
[inject-error]
|
|
event = "cor_write"
|
|
sector = "2048"
|
|
EOF
|
|
$QEMU_IO -c "open -C \
|
|
-o driver=blkdebug,config=$BLKDBG_CONF,image.driver=qcow2 $TEST_WRAP" \
|
|
-c "read -P 0 1M 128k" | _filter_qemu_io
|
|
|
|
# Read the areas we want copied. A zero-length read should still be a
|
|
# no-op. The next read is under 2G, but aligned so that rounding to
|
|
# clusters copies more than 2G of zeroes. The final read will pick up
|
|
# the non-zero data in the same cluster. Since a 2G read may exhaust
|
|
# memory on some machines (particularly 32-bit), we skip the test if
|
|
# that fails due to memory pressure.
|
|
$QEMU_IO -f qcow2 -C -c "read 0 0" "$TEST_WRAP" | _filter_qemu_io
|
|
output=$($QEMU_IO -f qcow2 -C -c "read -P 0 1k $((2*1024*1024*1024 - 512))" \
|
|
"$TEST_WRAP" 2>&1 | _filter_qemu_io)
|
|
case $output in
|
|
*allocate*)
|
|
_notrun "Insufficent memory to run test" ;;
|
|
*) printf '%s\n' "$output" ;;
|
|
esac
|
|
$QEMU_IO -f qcow2 -C -c "read -P 0 $((3*1024*1024*1024 + 1024)) 1k" \
|
|
"$TEST_WRAP" | _filter_qemu_io
|
|
|
|
# Copy-on-read is incompatible with read-only
|
|
$QEMU_IO -f qcow2 -C -r "$TEST_WRAP" 2>&1 | _filter_testdir
|
|
|
|
# Break the backing chain, and show that images are identical, and that
|
|
# we properly copied over explicit zeros.
|
|
$QEMU_IMG rebase -u -b "" -f qcow2 "$TEST_WRAP"
|
|
$QEMU_IO -f qcow2 -c map "$TEST_WRAP"
|
|
_check_test_img
|
|
$QEMU_IMG compare -f $IMGFMT -F qcow2 "$TEST_IMG" "$TEST_WRAP"
|
|
|
|
echo
|
|
echo '=== Partial final cluster ==='
|
|
echo
|
|
|
|
# Force compat=1.1, because writing zeroes on a v2 image without a
|
|
# backing file would just result in an unallocated cluster
|
|
# (Also, note that this is really a pure qcow2 test.)
|
|
IMGPROTO=file IMGFMT=qcow2 TEST_IMG_FILE="$TEST_WRAP" \
|
|
_make_test_img --no-opts -o compat=1.1 1024
|
|
$QEMU_IO -f qcow2 -C -c 'read 0 1024' "$TEST_WRAP" | _filter_qemu_io
|
|
$QEMU_IO -f qcow2 -c map "$TEST_WRAP"
|
|
_check_test_img
|
|
|
|
echo
|
|
echo '=== Copy-on-read with subclusters ==='
|
|
echo
|
|
|
|
# Create base and top images 64K (1 cluster) each. Make subclusters enabled
|
|
# for the top image
|
|
_make_test_img 64K
|
|
IMGPROTO=file IMGFMT=qcow2 TEST_IMG_FILE="$TEST_WRAP" \
|
|
_make_test_img --no-opts -o extended_l2=true -F "$IMGFMT" -b "$TEST_IMG" \
|
|
64K | _filter_img_create
|
|
|
|
$QEMU_IO -c "write -P 0xaa 0 64k" "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Allocate individual subclusters in the top image, and not the whole cluster
|
|
$QEMU_IO -c "write -P 0xbb 28K 2K" -c "write -P 0xcc 34K 2K" "$TEST_WRAP" \
|
|
| _filter_qemu_io
|
|
|
|
# Only 2 subclusters should be allocated in the top image at this point
|
|
$QEMU_IMG map "$TEST_WRAP" | _filter_qemu_img_map
|
|
|
|
# Actual copy-on-read operation
|
|
$QEMU_IO -C -c "read -P 0xaa 30K 4K" "$TEST_WRAP" | _filter_qemu_io
|
|
|
|
# And here we should have 4 subclusters allocated right in the middle of the
|
|
# top image. Make sure the whole cluster remains unallocated
|
|
$QEMU_IMG map "$TEST_WRAP" | _filter_qemu_img_map
|
|
|
|
_check_test_img
|
|
|
|
# success, all done
|
|
echo '*** done'
|
|
status=0
|