]>
Commit | Line | Data |
---|---|---|
0b1eb0ce | 1 | #!/usr/bin/env bash |
9dd003a9 | 2 | # group: rw auto quick |
0b1eb0ce HR |
3 | # |
4 | # Test qemu-img convert --salvage | |
5 | # | |
6 | # Copyright (C) 2019 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 | |
42a5009d | 23 | owner=hreitz@redhat.com |
0b1eb0ce HR |
24 | |
25 | seq=$(basename $0) | |
26 | echo "QA output created by $seq" | |
27 | ||
28 | status=1 # failure is the default! | |
29 | ||
30 | _cleanup() | |
31 | { | |
32 | _cleanup_test_img | |
33 | } | |
34 | trap "_cleanup; exit \$status" 0 1 2 3 15 | |
35 | ||
36 | # get standard environment, filters and checks | |
37 | . ./common.rc | |
38 | . ./common.filter | |
39 | . ./common.qemu | |
40 | ||
41 | _supported_fmt generic | |
42 | _supported_proto file | |
43 | _supported_os Linux | |
325dd915 | 44 | _unsupported_imgopts "subformat=streamOptimized" |
0b1eb0ce HR |
45 | |
46 | if [ "$IMGOPTSSYNTAX" = "true" ]; then | |
47 | # We use json:{} filenames here, so we cannot work with additional options. | |
48 | _unsupported_fmt $IMGFMT | |
49 | else | |
af8d43d3 PL |
50 | # - With VDI, the output is ordered differently. Just disable it. |
51 | # - VHDX has large clusters; because qemu-img convert tries to | |
52 | # align the requests to the cluster size, the output is ordered | |
53 | # differently, so disable it, too. | |
54 | _unsupported_fmt vdi vhdx | |
0b1eb0ce HR |
55 | fi |
56 | ||
57 | ||
58 | TEST_IMG="$TEST_IMG.orig" _make_test_img 64M | |
59 | ||
60 | $QEMU_IO -c 'write -P 42 0 64M' "$TEST_IMG.orig" | _filter_qemu_io | |
61 | ||
62 | ||
63 | sector_size=512 | |
64 | ||
65 | # Offsets on which to fail block-status. Keep in ascending order so | |
66 | # the indexing done by _filter_offsets will appear in ascending order | |
67 | # in the output as well. | |
68 | status_fail_offsets="$((16 * 1024 * 1024 + 8192)) | |
69 | $((33 * 1024 * 1024 + 512))" | |
70 | ||
71 | # Offsets on which to fail reads. Keep in ascending order for the | |
72 | # same reason. | |
73 | # The second element is shared with $status_fail_offsets on purpose. | |
74 | # Starting with the third element, we test what happens when a | |
75 | # continuous range of sectors is inaccessible. | |
76 | read_fail_offsets="$((32 * 1024 * 1024 - 65536)) | |
77 | $((33 * 1024 * 1024 + 512)) | |
78 | $(seq $((34 * 1024 * 1024)) $sector_size \ | |
79 | $((34 * 1024 * 1024 + 4096 - $sector_size)))" | |
80 | ||
81 | ||
82 | # blkdebug must be above the format layer so it can intercept all | |
83 | # block-status events | |
84 | source_img="json:{'driver': 'blkdebug', | |
85 | 'image': { | |
86 | 'driver': '$IMGFMT', | |
87 | 'file': { | |
88 | 'driver': 'file', | |
89 | 'filename': '$TEST_IMG.orig' | |
90 | } | |
91 | }, | |
92 | 'inject-error': [" | |
93 | ||
94 | for ofs in $status_fail_offsets | |
95 | do | |
96 | source_img+="{ 'event': 'none', | |
97 | 'iotype': 'block-status', | |
98 | 'errno': 5, | |
99 | 'sector': $((ofs / sector_size)) }," | |
100 | done | |
101 | ||
102 | for ofs in $read_fail_offsets | |
103 | do | |
104 | source_img+="{ 'event': 'none', | |
105 | 'iotype': 'read', | |
106 | 'errno': 5, | |
107 | 'sector': $((ofs / sector_size)) }," | |
108 | done | |
109 | ||
110 | # Remove the trailing comma and terminate @inject-error and json:{} | |
111 | source_img="${source_img%,} ] }" | |
112 | ||
113 | ||
114 | echo | |
115 | ||
116 | ||
117 | _filter_offsets() { | |
118 | filters= | |
119 | ||
120 | index=0 | |
121 | for ofs in $1 | |
122 | do | |
123 | filters+=" -e s/$ofs/status_fail_offset_$index/" | |
124 | index=$((index + 1)) | |
125 | done | |
126 | ||
127 | index=0 | |
128 | for ofs in $2 | |
129 | do | |
130 | filters+=" -e s/$ofs/read_fail_offset_$index/" | |
131 | index=$((index + 1)) | |
132 | done | |
133 | ||
134 | sed $filters | |
135 | } | |
136 | ||
137 | # While determining the number of allocated sectors in the input | |
138 | # image, we should see one block status warning per element of | |
139 | # $status_fail_offsets. | |
140 | # | |
141 | # Then, the image is read. Since the block status is queried in | |
142 | # basically the same way, the same warnings as in the previous step | |
143 | # should reappear. Interleaved with those we should see a read | |
144 | # warning per element of $read_fail_offsets. | |
145 | # Note that $read_fail_offsets and $status_fail_offsets share an | |
146 | # element (read_fail_offset_1 == status_fail_offset_1), so | |
147 | # "status_fail_offset_1" in the output is the same as | |
148 | # "read_fail_offset_1". | |
149 | $QEMU_IMG convert --salvage "$source_img" "$TEST_IMG" 2>&1 \ | |
150 | | _filter_offsets "$status_fail_offsets" "$read_fail_offsets" | |
151 | ||
152 | echo | |
153 | ||
154 | # The offsets where the block status could not be determined should | |
155 | # have been treated as containing data and thus should be correct in | |
156 | # the output image. | |
157 | # The offsets where reading failed altogether should be 0. Make them | |
158 | # 0 in the input image, too, so we can compare both images. | |
159 | for ofs in $read_fail_offsets | |
160 | do | |
161 | $QEMU_IO -c "write -z $ofs $sector_size" "$TEST_IMG.orig" \ | |
162 | | _filter_qemu_io \ | |
163 | | _filter_offsets '' "$read_fail_offsets" | |
164 | done | |
165 | ||
166 | echo | |
167 | ||
168 | # These should be equal now. | |
169 | $QEMU_IMG compare "$TEST_IMG.orig" "$TEST_IMG" | |
170 | ||
171 | ||
172 | # success, all done | |
173 | echo "*** done" | |
174 | rm -f $seq.full | |
175 | status=0 |