1#!/bin/bash 2# 3# Test case for repairing qcow2 images which cannot be repaired using 4# the on-disk refcount structures 5# 6# Copyright (C) 2014 Red Hat, Inc. 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program. If not, see <http://www.gnu.org/licenses/>. 20# 21 22# creator 23owner=mreitz@redhat.com 24 25seq="$(basename $0)" 26echo "QA output created by $seq" 27 28here="$PWD" 29status=1 # failure is the default! 30 31_cleanup() 32{ 33 _cleanup_test_img 34} 35trap "_cleanup; exit \$status" 0 1 2 3 15 36 37# get standard environment, filters and checks 38. ./common.rc 39. ./common.filter 40 41# This tests qocw2-specific low-level functionality 42_supported_fmt qcow2 43_supported_proto file 44_supported_os Linux 45# This test directly modifies a refblock so it relies on refcount_bits being 16 46_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' 47 48echo 49echo '=== Repairing an image without any refcount table ===' 50echo 51 52_make_test_img 64M 53# just write some data 54$QEMU_IO -c 'write -P 42 0 64k' "$TEST_IMG" | _filter_qemu_io 55 56# refcount_table_offset 57poke_file "$TEST_IMG" $((0x30)) "\x00\x00\x00\x00\x00\x00\x00\x00" 58# refcount_table_clusters 59poke_file "$TEST_IMG" $((0x38)) "\x00\x00\x00\x00" 60 61_check_test_img -r all 62 63$QEMU_IO -c 'read -P 42 0 64k' "$TEST_IMG" | _filter_qemu_io 64 65echo 66echo '=== Repairing unreferenced data cluster in new refblock area ===' 67echo 68 69IMGOPTS='cluster_size=512' _make_test_img 64M 70# Allocate the first 128 kB in the image (first refblock) 71$QEMU_IO -c 'write 0 0x1b200' "$TEST_IMG" | _filter_qemu_io 72# should be 131072 == 0x20000 73stat -c '%s' "$TEST_IMG" 74 75# Enter a cluster at 128 kB (0x20000) 76# XXX: This should be the first free entry in the last L2 table, but we cannot 77# be certain 78poke_file "$TEST_IMG" $((0x1ccc8)) "\x80\x00\x00\x00\x00\x02\x00\x00" 79 80# Fill the cluster 81truncate -s $((0x20200)) "$TEST_IMG" 82$QEMU_IO -c "open -o driver=raw $TEST_IMG" -c 'write -P 42 128k 512' \ 83 | _filter_qemu_io 84 85# The data should now appear at this guest offset 86$QEMU_IO -c 'read -P 42 0x1b200 512' "$TEST_IMG" | _filter_qemu_io 87 88# This cluster is unallocated; fix it 89_check_test_img -r all 90 91# This repair operation must have allocated a new refblock; and that refblock 92# should not overlap with the unallocated data cluster. If it does, the data 93# will be damaged, so check it. 94$QEMU_IO -c 'read -P 42 0x1b200 512' "$TEST_IMG" | _filter_qemu_io 95 96echo 97echo '=== Repairing refblock beyond the image end ===' 98echo 99 100echo 101echo '--- Otherwise clean ---' 102echo 103 104_make_test_img 64M 105# Normally, qemu doesn't create empty refblocks, so we just have to do it by 106# hand 107# XXX: This should be the entry for the second refblock 108poke_file "$TEST_IMG" $((0x10008)) "\x00\x00\x00\x00\x00\x10\x00\x00" 109# Mark that refblock as used 110# XXX: This should be the 17th entry (cluster 16) of the first 111# refblock 112poke_file "$TEST_IMG" $((0x20020)) "\x00\x01" 113_check_test_img -r all 114 115echo 116echo '--- Refblock is unallocated ---' 117echo 118 119_make_test_img 64M 120poke_file "$TEST_IMG" $((0x10008)) "\x00\x00\x00\x00\x00\x10\x00\x00" 121_check_test_img -r all 122 123echo 124echo '--- Signed overflow after the refblock ---' 125echo 126 127_make_test_img 64M 128poke_file "$TEST_IMG" $((0x10008)) "\x7f\xff\xff\xff\xff\xff\x00\x00" 129_check_test_img -r all 130 131echo 132echo '--- Unsigned overflow after the refblock ---' 133echo 134 135_make_test_img 64M 136poke_file "$TEST_IMG" $((0x10008)) "\xff\xff\xff\xff\xff\xff\x00\x00" 137_check_test_img -r all 138 139# success, all done 140echo '*** done' 141rm -f $seq.full 142status=0 143