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