xemu/tests/qemu-iotests/112
Eric Blake 8cedcffdc1 iotests: Drop use of bash keyword 'function'
Bash allows functions to be declared with or without the leading
keyword 'function'; but including the keyword does not comply with
POSIX syntax, and is confusing to ksh users where the use of the
keyword changes the scoping rules for functions.  Stick to the
POSIX form through iotests.

Done mechanically with:
  sed -i 's/^function //' $(git ls-files tests/qemu-iotests)

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20181116215002.2124581-1-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2018-11-19 11:16:46 -06:00

295 lines
8.3 KiB
Bash
Executable File

#!/bin/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
_supported_os Linux
# This test will set refcount_bits on its own which would conflict with the
# manual setting; compat will be overridden as well
_unsupported_imgopts refcount_bits 'compat=0.10'
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)
IMGOPTS="$IMGOPTS,refcount_bits=0" _make_test_img 64M
# Must be positive (non-negative)
IMGOPTS="$IMGOPTS,refcount_bits=-1" _make_test_img 64M
# May not exceed 64
IMGOPTS="$IMGOPTS,refcount_bits=128" _make_test_img 64M
# Must be a power of two
IMGOPTS="$IMGOPTS,refcount_bits=42" _make_test_img 64M
# 1 is the minimum
IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M
print_refcount_bits
# 64 is the maximum
IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 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
IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=16" _make_test_img 64M
print_refcount_bits
# Should not work
IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=1" _make_test_img 64M
IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=64" _make_test_img 64M
echo
echo '=== Snapshot limit on refcount_bits=1 ==='
echo
IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 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
IMGOPTS="$IMGOPTS,refcount_bits=2" _make_test_img 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
IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 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
IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 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
IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 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
IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 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
IMGOPTS="$IMGOPTS,refcount_bits=1,cluster_size=512" _make_test_img 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