111a82d14SPhilippe Mathieu-Daudé#!/usr/bin/env bash 2234764eeSMax Reitz# 3234764eeSMax Reitz# Test case for repairing qcow2 images which cannot be repaired using 4234764eeSMax Reitz# the on-disk refcount structures 5234764eeSMax Reitz# 6234764eeSMax Reitz# Copyright (C) 2014 Red Hat, Inc. 7234764eeSMax Reitz# 8234764eeSMax Reitz# This program is free software; you can redistribute it and/or modify 9234764eeSMax Reitz# it under the terms of the GNU General Public License as published by 10234764eeSMax Reitz# the Free Software Foundation; either version 2 of the License, or 11234764eeSMax Reitz# (at your option) any later version. 12234764eeSMax Reitz# 13234764eeSMax Reitz# This program is distributed in the hope that it will be useful, 14234764eeSMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of 15234764eeSMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16234764eeSMax Reitz# GNU General Public License for more details. 17234764eeSMax Reitz# 18234764eeSMax Reitz# You should have received a copy of the GNU General Public License 19234764eeSMax Reitz# along with this program. If not, see <http://www.gnu.org/licenses/>. 20234764eeSMax Reitz# 21234764eeSMax Reitz 22234764eeSMax Reitz# creator 23234764eeSMax Reitzowner=mreitz@redhat.com 24234764eeSMax Reitz 25234764eeSMax Reitzseq="$(basename $0)" 26234764eeSMax Reitzecho "QA output created by $seq" 27234764eeSMax Reitz 28234764eeSMax Reitzstatus=1 # failure is the default! 29234764eeSMax Reitz 30234764eeSMax Reitz_cleanup() 31234764eeSMax Reitz{ 32234764eeSMax Reitz _cleanup_test_img 33234764eeSMax Reitz} 34234764eeSMax Reitztrap "_cleanup; exit \$status" 0 1 2 3 15 35234764eeSMax Reitz 36234764eeSMax Reitz# get standard environment, filters and checks 37234764eeSMax Reitz. ./common.rc 38234764eeSMax Reitz. ./common.filter 39234764eeSMax Reitz 40*e696f335SMax Reitz# This tests qcow2-specific low-level functionality 41234764eeSMax Reitz_supported_fmt qcow2 42234764eeSMax Reitz_supported_proto file 43234764eeSMax Reitz_supported_os Linux 445262caa7SMax Reitz# This test directly modifies a refblock so it relies on refcount_bits being 16 455262caa7SMax Reitz_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' 46234764eeSMax Reitz 47234764eeSMax Reitzecho 48234764eeSMax Reitzecho '=== Repairing an image without any refcount table ===' 49234764eeSMax Reitzecho 50234764eeSMax Reitz 51234764eeSMax Reitz_make_test_img 64M 52234764eeSMax Reitz# just write some data 53234764eeSMax Reitz$QEMU_IO -c 'write -P 42 0 64k' "$TEST_IMG" | _filter_qemu_io 54234764eeSMax Reitz 55234764eeSMax Reitz# refcount_table_offset 56234764eeSMax Reitzpoke_file "$TEST_IMG" $((0x30)) "\x00\x00\x00\x00\x00\x00\x00\x00" 57234764eeSMax Reitz# refcount_table_clusters 58234764eeSMax Reitzpoke_file "$TEST_IMG" $((0x38)) "\x00\x00\x00\x00" 59234764eeSMax Reitz 60234764eeSMax Reitz_check_test_img -r all 61234764eeSMax Reitz 62234764eeSMax Reitz$QEMU_IO -c 'read -P 42 0 64k' "$TEST_IMG" | _filter_qemu_io 63234764eeSMax Reitz 64234764eeSMax Reitzecho 65234764eeSMax Reitzecho '=== Repairing unreferenced data cluster in new refblock area ===' 66234764eeSMax Reitzecho 67234764eeSMax Reitz 68234764eeSMax ReitzIMGOPTS='cluster_size=512' _make_test_img 64M 69234764eeSMax Reitz# Allocate the first 128 kB in the image (first refblock) 70234764eeSMax Reitz$QEMU_IO -c 'write 0 0x1b200' "$TEST_IMG" | _filter_qemu_io 71234764eeSMax Reitz# should be 131072 == 0x20000 72234764eeSMax Reitzstat -c '%s' "$TEST_IMG" 73234764eeSMax Reitz 74234764eeSMax Reitz# Enter a cluster at 128 kB (0x20000) 75234764eeSMax Reitz# XXX: This should be the first free entry in the last L2 table, but we cannot 76234764eeSMax Reitz# be certain 77234764eeSMax Reitzpoke_file "$TEST_IMG" $((0x1ccc8)) "\x80\x00\x00\x00\x00\x02\x00\x00" 78234764eeSMax Reitz 79234764eeSMax Reitz# Fill the cluster 80234764eeSMax Reitztruncate -s $((0x20200)) "$TEST_IMG" 81234764eeSMax Reitz$QEMU_IO -c "open -o driver=raw $TEST_IMG" -c 'write -P 42 128k 512' \ 82234764eeSMax Reitz | _filter_qemu_io 83234764eeSMax Reitz 84234764eeSMax Reitz# The data should now appear at this guest offset 85234764eeSMax Reitz$QEMU_IO -c 'read -P 42 0x1b200 512' "$TEST_IMG" | _filter_qemu_io 86234764eeSMax Reitz 87234764eeSMax Reitz# This cluster is unallocated; fix it 88234764eeSMax Reitz_check_test_img -r all 89234764eeSMax Reitz 90234764eeSMax Reitz# This repair operation must have allocated a new refblock; and that refblock 91234764eeSMax Reitz# should not overlap with the unallocated data cluster. If it does, the data 92234764eeSMax Reitz# will be damaged, so check it. 93234764eeSMax Reitz$QEMU_IO -c 'read -P 42 0x1b200 512' "$TEST_IMG" | _filter_qemu_io 94234764eeSMax Reitz 95234764eeSMax Reitzecho 96234764eeSMax Reitzecho '=== Repairing refblock beyond the image end ===' 97234764eeSMax Reitzecho 98234764eeSMax Reitz 99234764eeSMax Reitzecho 100234764eeSMax Reitzecho '--- Otherwise clean ---' 101234764eeSMax Reitzecho 102234764eeSMax Reitz 103234764eeSMax Reitz_make_test_img 64M 104234764eeSMax Reitz# Normally, qemu doesn't create empty refblocks, so we just have to do it by 105234764eeSMax Reitz# hand 106234764eeSMax Reitz# XXX: This should be the entry for the second refblock 107234764eeSMax Reitzpoke_file "$TEST_IMG" $((0x10008)) "\x00\x00\x00\x00\x00\x10\x00\x00" 108234764eeSMax Reitz# Mark that refblock as used 109234764eeSMax Reitz# XXX: This should be the 17th entry (cluster 16) of the first 110234764eeSMax Reitz# refblock 111234764eeSMax Reitzpoke_file "$TEST_IMG" $((0x20020)) "\x00\x01" 112234764eeSMax Reitz_check_test_img -r all 113234764eeSMax Reitz 114234764eeSMax Reitzecho 115234764eeSMax Reitzecho '--- Refblock is unallocated ---' 116234764eeSMax Reitzecho 117234764eeSMax Reitz 118234764eeSMax Reitz_make_test_img 64M 119234764eeSMax Reitzpoke_file "$TEST_IMG" $((0x10008)) "\x00\x00\x00\x00\x00\x10\x00\x00" 120234764eeSMax Reitz_check_test_img -r all 121234764eeSMax Reitz 122234764eeSMax Reitzecho 123234764eeSMax Reitzecho '--- Signed overflow after the refblock ---' 124234764eeSMax Reitzecho 125234764eeSMax Reitz 126234764eeSMax Reitz_make_test_img 64M 127234764eeSMax Reitzpoke_file "$TEST_IMG" $((0x10008)) "\x7f\xff\xff\xff\xff\xff\x00\x00" 128234764eeSMax Reitz_check_test_img -r all 129234764eeSMax Reitz 130234764eeSMax Reitzecho 131234764eeSMax Reitzecho '--- Unsigned overflow after the refblock ---' 132234764eeSMax Reitzecho 133234764eeSMax Reitz 134234764eeSMax Reitz_make_test_img 64M 135234764eeSMax Reitzpoke_file "$TEST_IMG" $((0x10008)) "\xff\xff\xff\xff\xff\xff\x00\x00" 136234764eeSMax Reitz_check_test_img -r all 137234764eeSMax Reitz 138234764eeSMax Reitz# success, all done 139234764eeSMax Reitzecho '*** done' 140234764eeSMax Reitzrm -f $seq.full 141234764eeSMax Reitzstatus=0 142