xref: /openbmc/qemu/tests/qemu-iotests/060 (revision ca0eca91)
1*ca0eca91SMax Reitz#!/bin/bash
2*ca0eca91SMax Reitz#
3*ca0eca91SMax Reitz# Test case for image corruption (overlapping data structures) in qcow2
4*ca0eca91SMax Reitz#
5*ca0eca91SMax Reitz# Copyright (C) 2013 Red Hat, Inc.
6*ca0eca91SMax Reitz#
7*ca0eca91SMax Reitz# This program is free software; you can redistribute it and/or modify
8*ca0eca91SMax Reitz# it under the terms of the GNU General Public License as published by
9*ca0eca91SMax Reitz# the Free Software Foundation; either version 2 of the License, or
10*ca0eca91SMax Reitz# (at your option) any later version.
11*ca0eca91SMax Reitz#
12*ca0eca91SMax Reitz# This program is distributed in the hope that it will be useful,
13*ca0eca91SMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of
14*ca0eca91SMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*ca0eca91SMax Reitz# GNU General Public License for more details.
16*ca0eca91SMax Reitz#
17*ca0eca91SMax Reitz# You should have received a copy of the GNU General Public License
18*ca0eca91SMax Reitz# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19*ca0eca91SMax Reitz#
20*ca0eca91SMax Reitz
21*ca0eca91SMax Reitz# creator
22*ca0eca91SMax Reitzowner=mreitz@redhat.com
23*ca0eca91SMax Reitz
24*ca0eca91SMax Reitzseq=`basename $0`
25*ca0eca91SMax Reitzecho "QA output created by $seq"
26*ca0eca91SMax Reitz
27*ca0eca91SMax Reitzhere=`pwd`
28*ca0eca91SMax Reitztmp=/tmp/$$
29*ca0eca91SMax Reitzstatus=1	# failure is the default!
30*ca0eca91SMax Reitz
31*ca0eca91SMax Reitz_cleanup()
32*ca0eca91SMax Reitz{
33*ca0eca91SMax Reitz	_cleanup_test_img
34*ca0eca91SMax Reitz}
35*ca0eca91SMax Reitztrap "_cleanup; exit \$status" 0 1 2 3 15
36*ca0eca91SMax Reitz
37*ca0eca91SMax Reitz# get standard environment, filters and checks
38*ca0eca91SMax Reitz. ./common.rc
39*ca0eca91SMax Reitz. ./common.filter
40*ca0eca91SMax Reitz
41*ca0eca91SMax Reitz# This tests qocw2-specific low-level functionality
42*ca0eca91SMax Reitz_supported_fmt qcow2
43*ca0eca91SMax Reitz_supported_proto generic
44*ca0eca91SMax Reitz_supported_os Linux
45*ca0eca91SMax Reitz
46*ca0eca91SMax Reitzrt_offset=65536  # 0x10000 (XXX: just an assumption)
47*ca0eca91SMax Reitzrb_offset=131072 # 0x20000 (XXX: just an assumption)
48*ca0eca91SMax Reitzl1_offset=196608 # 0x30000 (XXX: just an assumption)
49*ca0eca91SMax Reitzl2_offset=262144 # 0x40000 (XXX: just an assumption)
50*ca0eca91SMax Reitz
51*ca0eca91SMax ReitzIMGOPTS="compat=1.1"
52*ca0eca91SMax Reitz
53*ca0eca91SMax Reitzecho
54*ca0eca91SMax Reitzecho "=== Testing L2 reference into L1 ==="
55*ca0eca91SMax Reitzecho
56*ca0eca91SMax Reitz_make_test_img 64M
57*ca0eca91SMax Reitz# Link first L1 entry (first L2 table) onto itself
58*ca0eca91SMax Reitz# (Note the MSb in the L1 entry is set, ensuring the refcount is one - else any
59*ca0eca91SMax Reitz# later write will result in a COW operation, effectively ruining this attempt
60*ca0eca91SMax Reitz# on image corruption)
61*ca0eca91SMax Reitzpoke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x03\x00\x00"
62*ca0eca91SMax Reitz_check_test_img
63*ca0eca91SMax Reitz
64*ca0eca91SMax Reitz# The corrupt bit should not be set anyway
65*ca0eca91SMax Reitz./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
66*ca0eca91SMax Reitz
67*ca0eca91SMax Reitz# Try to write something, thereby forcing the corrupt bit to be set
68*ca0eca91SMax Reitz$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
69*ca0eca91SMax Reitz
70*ca0eca91SMax Reitz# The corrupt bit must now be set
71*ca0eca91SMax Reitz./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
72*ca0eca91SMax Reitz
73*ca0eca91SMax Reitz# Try to open the image R/W (which should fail)
74*ca0eca91SMax Reitz$QEMU_IO -c "read 0 512" "$TEST_IMG" 2>&1 | _filter_qemu_io | sed -e "s/can't open device .*$/can't open device/"
75*ca0eca91SMax Reitz
76*ca0eca91SMax Reitz# Try to open it RO (which should succeed)
77*ca0eca91SMax Reitz$QEMU_IO -c "read 0 512" -r "$TEST_IMG" | _filter_qemu_io
78*ca0eca91SMax Reitz
79*ca0eca91SMax Reitz# We could now try to fix the image, but this would probably fail (how should an
80*ca0eca91SMax Reitz# L2 table linked onto the L1 table be fixed?)
81*ca0eca91SMax Reitz
82*ca0eca91SMax Reitzecho
83*ca0eca91SMax Reitzecho "=== Testing cluster data reference into refcount block ==="
84*ca0eca91SMax Reitzecho
85*ca0eca91SMax Reitz_make_test_img 64M
86*ca0eca91SMax Reitz# Allocate L2 table
87*ca0eca91SMax Reitztruncate -s "$(($l2_offset+65536))" "$TEST_IMG"
88*ca0eca91SMax Reitzpoke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x04\x00\x00"
89*ca0eca91SMax Reitz# Mark cluster as used
90*ca0eca91SMax Reitzpoke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01"
91*ca0eca91SMax Reitz# Redirect new data cluster onto refcount block
92*ca0eca91SMax Reitzpoke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00"
93*ca0eca91SMax Reitz_check_test_img
94*ca0eca91SMax Reitz./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
95*ca0eca91SMax Reitz$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
96*ca0eca91SMax Reitz./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
97*ca0eca91SMax Reitz
98*ca0eca91SMax Reitz# Try to fix it
99*ca0eca91SMax Reitz_check_test_img -r all
100*ca0eca91SMax Reitz
101*ca0eca91SMax Reitz# The corrupt bit should be cleared
102*ca0eca91SMax Reitz./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
103*ca0eca91SMax Reitz
104*ca0eca91SMax Reitz# Look if it's really really fixed
105*ca0eca91SMax Reitz$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
106*ca0eca91SMax Reitz./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
107*ca0eca91SMax Reitz
108*ca0eca91SMax Reitz# success, all done
109*ca0eca91SMax Reitzecho "*** done"
110*ca0eca91SMax Reitzrm -f $seq.full
111*ca0eca91SMax Reitzstatus=0
112