57284d2ada
Many tests (that do not support generic protocols) can run just fine with FUSE-exported images, so allow them to. Note that this is no attempt at being definitely complete. There are some tests that might be modified to run on FUSE, but this patch still skips them. This patch only tries to pick the rather low-hanging fruits. Note that 221 and 250 only pass when .lseek is correctly implemented, which is only possible with a libfuse that is 3.8 or newer. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20201027190600.192171-20-mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
295 lines
8.1 KiB
Bash
Executable File
295 lines
8.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Test cases for different refcount_bits values
|
|
#
|
|
# Copyright (C) 2015 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"
|
|
|
|
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 qcow2-specific low-level functionality
|
|
_supported_fmt qcow2
|
|
_supported_proto file fuse
|
|
# This test will set refcount_bits on its own which would conflict with the
|
|
# manual setting; compat will be overridden as well;
|
|
# and external data files do not work well with our refcount testing
|
|
_unsupported_imgopts refcount_bits 'compat=0.10' data_file
|
|
|
|
print_refcount_bits()
|
|
{
|
|
$QEMU_IMG info "$TEST_IMG" | sed -n '/refcount bits:/ s/^ *//p'
|
|
}
|
|
|
|
echo
|
|
echo '=== refcount_bits limits ==='
|
|
echo
|
|
|
|
# Must be positive (non-zero)
|
|
_make_test_img -o "refcount_bits=0" 64M
|
|
# Must be positive (non-negative)
|
|
_make_test_img -o "refcount_bits=-1" 64M
|
|
# May not exceed 64
|
|
_make_test_img -o "refcount_bits=128" 64M
|
|
# Must be a power of two
|
|
_make_test_img -o "refcount_bits=42" 64M
|
|
|
|
# 1 is the minimum
|
|
_make_test_img -o "refcount_bits=1" 64M
|
|
print_refcount_bits
|
|
|
|
# 64 is the maximum
|
|
_make_test_img -o "refcount_bits=64" 64M
|
|
print_refcount_bits
|
|
|
|
# 16 is the default
|
|
_make_test_img 64M
|
|
print_refcount_bits
|
|
|
|
echo
|
|
echo '=== refcount_bits and compat=0.10 ==='
|
|
echo
|
|
|
|
# Should work
|
|
_make_test_img -o "compat=0.10,refcount_bits=16" 64M
|
|
print_refcount_bits
|
|
|
|
# Should not work
|
|
_make_test_img -o "compat=0.10,refcount_bits=1" 64M
|
|
_make_test_img -o "compat=0.10,refcount_bits=64" 64M
|
|
|
|
|
|
echo
|
|
echo '=== Snapshot limit on refcount_bits=1 ==='
|
|
echo
|
|
|
|
_make_test_img -o "refcount_bits=1" 64M
|
|
print_refcount_bits
|
|
|
|
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Should fail for now; in the future, this might be supported by automatically
|
|
# copying all clusters with overflowing refcount
|
|
$QEMU_IMG snapshot -c foo "$TEST_IMG"
|
|
|
|
# The new L1 table could/should be leaked
|
|
_check_test_img
|
|
|
|
echo
|
|
echo '=== Snapshot limit on refcount_bits=2 ==='
|
|
echo
|
|
|
|
_make_test_img -o "refcount_bits=2" 64M
|
|
print_refcount_bits
|
|
|
|
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Should succeed
|
|
$QEMU_IMG snapshot -c foo "$TEST_IMG"
|
|
$QEMU_IMG snapshot -c bar "$TEST_IMG"
|
|
# Should fail (4th reference)
|
|
$QEMU_IMG snapshot -c baz "$TEST_IMG"
|
|
|
|
# The new L1 table could/should be leaked
|
|
_check_test_img
|
|
|
|
echo
|
|
echo '=== Compressed clusters with refcount_bits=1 ==='
|
|
echo
|
|
|
|
_make_test_img -o "refcount_bits=1" 64M
|
|
print_refcount_bits
|
|
|
|
# Both should fit into a single host cluster; instead of failing to increase the
|
|
# refcount of that cluster, qemu should just allocate a new cluster and make
|
|
# this operation succeed
|
|
$QEMU_IO -c 'write -P 0 -c 0 64k' \
|
|
-c 'write -P 1 -c 64k 64k' \
|
|
"$TEST_IMG" | _filter_qemu_io
|
|
|
|
_check_test_img
|
|
|
|
echo
|
|
echo '=== MSb set in 64 bit refcount ==='
|
|
echo
|
|
|
|
_make_test_img -o "refcount_bits=64" 64M
|
|
print_refcount_bits
|
|
|
|
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Set the MSb in the refblock entry of the data cluster
|
|
poke_file "$TEST_IMG" $((0x20028)) "\x80\x00\x00\x00\x00\x00\x00\x00"
|
|
|
|
# Clear OFLAG_COPIED in the L2 entry of the data cluster
|
|
poke_file "$TEST_IMG" $((0x40000)) "\x00\x00\x00\x00\x00\x05\x00\x00"
|
|
|
|
# Try to write to that cluster (should work, even though the MSb is set)
|
|
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
echo
|
|
echo '=== Snapshot on maximum 64 bit refcount value ==='
|
|
echo
|
|
|
|
_make_test_img -o "refcount_bits=64" 64M
|
|
print_refcount_bits
|
|
|
|
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Set the refblock entry to the maximum value possible
|
|
poke_file "$TEST_IMG" $((0x20028)) "\xff\xff\xff\xff\xff\xff\xff\xff"
|
|
|
|
# Clear OFLAG_COPIED in the L2 entry of the data cluster
|
|
poke_file "$TEST_IMG" $((0x40000)) "\x00\x00\x00\x00\x00\x05\x00\x00"
|
|
|
|
# Try a snapshot (should correctly identify the overflow; may work in the future
|
|
# by falling back to COW)
|
|
$QEMU_IMG snapshot -c foo "$TEST_IMG"
|
|
|
|
# The new L1 table could/should be leaked; and obviously the data cluster is
|
|
# leaked (refcount=UINT64_MAX reference=1)
|
|
_check_test_img
|
|
|
|
echo
|
|
echo '=== Amend from refcount_bits=16 to refcount_bits=1 ==='
|
|
echo
|
|
|
|
_make_test_img 64M
|
|
print_refcount_bits
|
|
|
|
$QEMU_IO -c 'write 16M 32M' "$TEST_IMG" | _filter_qemu_io
|
|
$QEMU_IMG amend -o refcount_bits=1 "$TEST_IMG"
|
|
_check_test_img
|
|
print_refcount_bits
|
|
|
|
echo
|
|
echo '=== Amend from refcount_bits=1 to refcount_bits=64 ==='
|
|
echo
|
|
|
|
$QEMU_IMG amend -o refcount_bits=64 "$TEST_IMG"
|
|
_check_test_img
|
|
print_refcount_bits
|
|
|
|
echo
|
|
echo '=== Amend to compat=0.10 ==='
|
|
echo
|
|
|
|
# Should not work because refcount_bits needs to be 16 for compat=0.10
|
|
$QEMU_IMG amend -o compat=0.10 "$TEST_IMG"
|
|
print_refcount_bits
|
|
# Should work
|
|
$QEMU_IMG amend -o compat=0.10,refcount_bits=16 "$TEST_IMG"
|
|
_check_test_img
|
|
print_refcount_bits
|
|
|
|
# Get back to compat=1.1 and refcount_bits=16
|
|
$QEMU_IMG amend -o compat=1.1 "$TEST_IMG"
|
|
print_refcount_bits
|
|
# Should not work
|
|
$QEMU_IMG amend -o refcount_bits=32,compat=0.10 "$TEST_IMG"
|
|
print_refcount_bits
|
|
|
|
echo
|
|
echo '=== Amend with snapshot ==='
|
|
echo
|
|
|
|
$QEMU_IMG snapshot -c foo "$TEST_IMG"
|
|
# Just to have different refcounts across the image
|
|
$QEMU_IO -c 'write 0 16M' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Should not work (may work in the future by first decreasing all refcounts so
|
|
# they fit into the target range by copying them)
|
|
$QEMU_IMG amend -o refcount_bits=1 "$TEST_IMG"
|
|
_check_test_img
|
|
print_refcount_bits
|
|
|
|
# Should work
|
|
$QEMU_IMG amend -o refcount_bits=2 "$TEST_IMG"
|
|
_check_test_img
|
|
print_refcount_bits
|
|
|
|
echo
|
|
echo '=== Testing too many references for check ==='
|
|
echo
|
|
|
|
_make_test_img -o "refcount_bits=1" 64M
|
|
print_refcount_bits
|
|
|
|
# This cluster should be created at 0x50000
|
|
$QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
|
|
# Now make the second L2 entry (the L2 table should be at 0x40000) point to that
|
|
# cluster, so we have two references
|
|
poke_file "$TEST_IMG" $((0x40008)) "\x80\x00\x00\x00\x00\x05\x00\x00"
|
|
|
|
# This should say "please use amend"
|
|
_check_test_img -r all
|
|
|
|
# So we do that
|
|
$QEMU_IMG amend -o refcount_bits=2 "$TEST_IMG"
|
|
print_refcount_bits
|
|
|
|
# And try again
|
|
_check_test_img -r all
|
|
|
|
echo
|
|
echo '=== Multiple walks necessary during amend ==='
|
|
echo
|
|
|
|
_make_test_img -o "refcount_bits=1,cluster_size=512" 64k
|
|
|
|
# Cluster 0 is the image header, clusters 1 to 4 are used by the L1 table, a
|
|
# single L2 table, the reftable and a single refblock. This creates 58 data
|
|
# clusters (actually, the L2 table is created here, too), so in total there are
|
|
# then 63 used clusters in the image. With a refcount width of 64, one refblock
|
|
# describes 64 clusters (512 bytes / 64 bits/entry = 64 entries), so this will
|
|
# make the first refblock in the amended image have exactly one free entry.
|
|
$QEMU_IO -c "write 0 $((58 * 512))" "$TEST_IMG" | _filter_qemu_io
|
|
|
|
# Now change the refcount width; since the first new refblock will have exactly
|
|
# one free entry, that entry will be used to store its own reference. No other
|
|
# refblocks are needed, so then the new reftable will be allocated; since the
|
|
# first new refblock is completely filled up, this will require a new refblock
|
|
# which is why the refcount width changing function will need to run through
|
|
# everything one more time until the allocations are stable.
|
|
# Having more walks than usual should be visible as regressing progress (from
|
|
# 66.67 % (2/3 walks) to 50.00 % (2/4 walks)).
|
|
$QEMU_IMG amend -o refcount_bits=64 -p "$TEST_IMG" | tr '\r' '\n' \
|
|
| grep -A 1 '66.67'
|
|
print_refcount_bits
|
|
|
|
_check_test_img
|
|
|
|
|
|
# success, all done
|
|
echo '*** done'
|
|
rm -f $seq.full
|
|
status=0
|