060 3.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
#!/bin/bash
#
# Test case for image corruption (overlapping data structures) 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`
tmp=/tmp/$$
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

rt_offset=65536  # 0x10000 (XXX: just an assumption)
rb_offset=131072 # 0x20000 (XXX: just an assumption)
l1_offset=196608 # 0x30000 (XXX: just an assumption)
l2_offset=262144 # 0x40000 (XXX: just an assumption)

IMGOPTS="compat=1.1"

echo
echo "=== Testing L2 reference into L1 ==="
echo
_make_test_img 64M
# Link first L1 entry (first L2 table) onto itself
# (Note the MSb in the L1 entry is set, ensuring the refcount is one - else any
# later write will result in a COW operation, effectively ruining this attempt
# on image corruption)
poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x03\x00\x00"
_check_test_img

# The corrupt bit should not be set anyway
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features

# Try to write something, thereby forcing the corrupt bit to be set
$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io

# The corrupt bit must now be set
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features

# Try to open the image R/W (which should fail)
74
$QEMU_IO -c "read 0 512" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir | _filter_imgfmt
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

# Try to open it RO (which should succeed)
$QEMU_IO -c "read 0 512" -r "$TEST_IMG" | _filter_qemu_io

# We could now try to fix the image, but this would probably fail (how should an
# L2 table linked onto the L1 table be fixed?)

echo
echo "=== Testing cluster data reference into refcount block ==="
echo
_make_test_img 64M
# Allocate L2 table
truncate -s "$(($l2_offset+65536))" "$TEST_IMG"
poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x04\x00\x00"
# Mark cluster as used
poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01"
# Redirect new data cluster onto refcount block
poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00"
_check_test_img
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features

# Try to fix it
_check_test_img -r all

# The corrupt bit should be cleared
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features

# Look if it's really really fixed
$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features

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