#!/usr/bin/env bash
# group: rw
#
# Test preallocated growth of qcow2 images
#
# 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=hreitz@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_image_size_on_host()
{
    echo $(($(stat -c '%b * %B' "$TEST_IMG_FILE")))
}

# get standard environment and filters
. ./common.rc
. ./common.filter

_supported_fmt qcow2
_supported_proto file
# Growing a file with a backing file (without preallocation=full or
# =falloc) requires zeroing the newly added area, which is impossible
# to do quickly for v2 images, and hence is unsupported.
_unsupported_imgopts 'compat=0.10'

if [ -z "$TEST_IMG_FILE" ]; then
    TEST_IMG_FILE=$TEST_IMG
fi

# Test whether we are running on a broken XFS version.  There is this
# bug:

# $ rm -f foo
# $ touch foo
# $ block_size=4096 # Your FS's block size
# $ fallocate -o $((block_size / 2)) -l $block_size foo
# $ LANG=C xfs_bmap foo | grep hole
#         1: [8..15]: hole
#
# The problem is that the XFS driver rounds down the offset and
# rounds up the length to the block size, but independently.  As
# such, it only allocates the first block in the example above,
# even though it should allocate the first two blocks (because our
# request is to fallocate something that touches both the first
# two blocks).
#
# This means that when you then write to the beginning of the
# second block, the disk usage of the first two blocks grows.
#
# That is precisely what fallocate() promises, though: That when you
# write to an area that you have fallocated, no new blocks will have
# to be allocated.

touch "$TEST_IMG_FILE"
# Assuming there is no FS with a block size greater than 64k
fallocate -o 65535 -l 2 "$TEST_IMG_FILE"
len0=$(get_image_size_on_host)

# Write to something that in theory we have just fallocated
# (Thus, the on-disk size should not increase)
poke_file "$TEST_IMG_FILE" 65536 42
len1=$(get_image_size_on_host)

if [ $len1 -gt $len0 ]; then
    _notrun "the test filesystem's fallocate() is broken"
fi

rm -f "$TEST_IMG_FILE"

# Generally, we create some image with or without existing preallocation and
# then resize it. Then we write some data into the image and verify that its
# size does not change if we have used preallocation.

# With a cluster size of 512 B, one L2 table covers 64 * 512 B = 32 kB.
# One cluster of the L1 table covers 64 * 32 kB = 2 MB.
# There are multiple cases we want to test:
# (1) Grow an image without having to allocate a new L2 table.
# (2) Grow an image, having to allocate a new L2 table.
# (3) Grow an image, having to grow the L1 table.
# Therefore, we create an image that is 48 kB below 2 MB. Then:
# (1) We resize it to 2 MB - 32 kB. (+ 16 kB)
# (2) We resize it to 2 MB.         (+ 48 kB)
# (3) We resize it to 2 MB + 32 kB. (+ 80 kB)

# in B
CREATION_SIZE=$((2 * 1024 * 1024 - 48 * 1024))

# 512 is the actual test -- but it's good to test 64k as well, just to be sure.
for cluster_size in 512 64k; do
# in kB
for GROWTH_SIZE in 16 48 80; do
    for create_mode in off metadata falloc full; do
        for growth_mode in off metadata falloc full; do
            echo "--- cluster_size=$cluster_size growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"

            _make_test_img -o "preallocation=$create_mode,cluster_size=$cluster_size" ${CREATION_SIZE}
            $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K

            host_size_0=$(get_image_size_on_host)
            file_length_0=$(stat -c '%s' "$TEST_IMG_FILE")

            $QEMU_IO -c "write 0 $CREATION_SIZE" "$TEST_IMG" | _filter_qemu_io

            host_size_1=$(get_image_size_on_host)
            file_length_1=$(stat -c '%s' "$TEST_IMG_FILE")

            $QEMU_IO -c "write $CREATION_SIZE ${GROWTH_SIZE}K" "$TEST_IMG" | _filter_qemu_io

            host_size_2=$(get_image_size_on_host)
            file_length_2=$(stat -c '%s' "$TEST_IMG_FILE")

            # Test creation preallocation: Compare #0 against #1
            if [ $create_mode != off ]; then
                # The image length should not have grown
                if [ $file_length_1 -gt $file_length_0 ]; then
                    echo "ERROR (create): Image length has grown from $file_length_0 to $file_length_1"
                fi
                if [ $create_mode != metadata ]; then
                    # The host size should not have grown either
                    if [ $host_size_1 -gt $host_size_0 ]; then
                        echo "ERROR (create): Host size has grown from $host_size_0 to $host_size_1"
                    fi
                fi
            fi

            # Test resize preallocation: Compare #2 against #1
            if [ $growth_mode != off ]; then
                # The image length should not have grown
                if [ $file_length_2 -gt $file_length_1 ]; then
                    echo "ERROR (grow): Image length has grown from $file_length_1 to $file_length_2"
                fi
                if [ $growth_mode != metadata ]; then
                    # The host size should not have grown either
                    if [ $host_size_2 -gt $host_size_1 ]; then
                        echo "ERROR (grow): Host size has grown from $host_size_1 to $host_size_2"
                    fi
                fi
            fi

            echo
        done
    done
done
done

# Test image resizing using preallocation and unaligned offsets
$QEMU_IMG create -f raw "$TEST_IMG.base" 128k | _filter_img_create
$QEMU_IO -c 'write -q -P 1 0 128k' -f raw "$TEST_IMG.base"
for orig_size in 31k 33k; do
    for dst_size in 96k 128k; do
        for prealloc in metadata full; do
            echo "--- Resizing image from $orig_size to $dst_size (preallocation=$prealloc) ---"
            _make_test_img -F raw -b "$TEST_IMG.base" -o cluster_size=64k "$orig_size"
            $QEMU_IMG resize -f "$IMGFMT" --preallocation="$prealloc" "$TEST_IMG" "$dst_size"
            # The first part of the image should contain data from the backing file
            $QEMU_IO -c "read -q -P 1 0 ${orig_size}" "$TEST_IMG"
            # The resized part of the image should contain zeroes
            $QEMU_IO -c "read -q -P 0 ${orig_size} 63k" "$TEST_IMG"
            # If the image does not have an external data file we can also verify its
            # actual size. The resized image should have 7 clusters:
            # header, L1 table, L2 table, refcount table, refcount block, 2 data clusters
            if ! _get_data_file "$TEST_IMG" > /dev/null; then
                expected_file_length=$((65536 * 7))
                file_length=$(stat -c '%s' "$TEST_IMG_FILE")
                if [ "$file_length" != "$expected_file_length" ]; then
                    echo "ERROR: file length $file_length (expected $expected_file_length)"
                fi
            fi
            echo
        done
    done
done

# success, all done
echo '*** done'
rm -f $seq.full
status=0
