|
|
05bba0 |
From de5dd97bab0923fdd8cd4ffebbbf3c031446030c Mon Sep 17 00:00:00 2001
|
|
|
05bba0 |
From: Max Reitz <mreitz@redhat.com>
|
|
|
05bba0 |
Date: Sat, 13 Jun 2015 16:22:25 +0200
|
|
|
05bba0 |
Subject: [PATCH 31/42] iotests: Add test for potentially damaging repairs
|
|
|
05bba0 |
|
|
|
05bba0 |
Message-id: <1434212556-3927-32-git-send-email-mreitz@redhat.com>
|
|
|
05bba0 |
Patchwork-id: 66050
|
|
|
05bba0 |
O-Subject: [RHEL-7.2 qemu-kvm PATCH 31/42] iotests: Add test for potentially damaging repairs
|
|
|
05bba0 |
Bugzilla: 1129893
|
|
|
05bba0 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
05bba0 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
05bba0 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
BZ: 1129893
|
|
|
05bba0 |
|
|
|
05bba0 |
There are certain cases where repairing a qcow2 image might actually
|
|
|
05bba0 |
damage it further (or rather, where repairing it has in fact damaged it
|
|
|
05bba0 |
further with the old qcow2 check implementation). This should not
|
|
|
05bba0 |
happen, so add a test for these cases.
|
|
|
05bba0 |
|
|
|
05bba0 |
Furthermore, the repair function now repairs refblocks beyond the image
|
|
|
05bba0 |
end by resizing the image accordingly. Add several tests for this as
|
|
|
05bba0 |
well.
|
|
|
05bba0 |
|
|
|
05bba0 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
05bba0 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
05bba0 |
(cherry picked from commit 234764eed1aab56a657a161e9a0c65730442e6f8)
|
|
|
05bba0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
Conflicts:
|
|
|
05bba0 |
tests/qemu-iotests/group
|
|
|
05bba0 |
|
|
|
05bba0 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
05bba0 |
---
|
|
|
05bba0 |
tests/qemu-iotests/108 | 141 +++++++++++++++++++++++++++++++++++++++++++++
|
|
|
05bba0 |
tests/qemu-iotests/108.out | 110 +++++++++++++++++++++++++++++++++++
|
|
|
05bba0 |
tests/qemu-iotests/group | 1 +
|
|
|
05bba0 |
3 files changed, 252 insertions(+)
|
|
|
05bba0 |
create mode 100755 tests/qemu-iotests/108
|
|
|
05bba0 |
create mode 100644 tests/qemu-iotests/108.out
|
|
|
05bba0 |
|
|
|
05bba0 |
diff --git a/tests/qemu-iotests/108 b/tests/qemu-iotests/108
|
|
|
05bba0 |
new file mode 100755
|
|
|
05bba0 |
index 0000000..12fc92a
|
|
|
05bba0 |
--- /dev/null
|
|
|
05bba0 |
+++ b/tests/qemu-iotests/108
|
|
|
05bba0 |
@@ -0,0 +1,141 @@
|
|
|
05bba0 |
+#!/bin/bash
|
|
|
05bba0 |
+#
|
|
|
05bba0 |
+# Test case for repairing qcow2 images which cannot be repaired using
|
|
|
05bba0 |
+# the on-disk refcount structures
|
|
|
05bba0 |
+#
|
|
|
05bba0 |
+# Copyright (C) 2014 Red Hat, Inc.
|
|
|
05bba0 |
+#
|
|
|
05bba0 |
+# This program is free software; you can redistribute it and/or modify
|
|
|
05bba0 |
+# it under the terms of the GNU General Public License as published by
|
|
|
05bba0 |
+# the Free Software Foundation; either version 2 of the License, or
|
|
|
05bba0 |
+# (at your option) any later version.
|
|
|
05bba0 |
+#
|
|
|
05bba0 |
+# This program is distributed in the hope that it will be useful,
|
|
|
05bba0 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
05bba0 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
05bba0 |
+# GNU General Public License for more details.
|
|
|
05bba0 |
+#
|
|
|
05bba0 |
+# You should have received a copy of the GNU General Public License
|
|
|
05bba0 |
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
05bba0 |
+#
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# creator
|
|
|
05bba0 |
+owner=mreitz@redhat.com
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+seq="$(basename $0)"
|
|
|
05bba0 |
+echo "QA output created by $seq"
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+here="$PWD"
|
|
|
05bba0 |
+tmp=/tmp/$$
|
|
|
05bba0 |
+status=1 # failure is the default!
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+_cleanup()
|
|
|
05bba0 |
+{
|
|
|
05bba0 |
+ _cleanup_test_img
|
|
|
05bba0 |
+}
|
|
|
05bba0 |
+trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# get standard environment, filters and checks
|
|
|
05bba0 |
+. ./common.rc
|
|
|
05bba0 |
+. ./common.filter
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# This tests qocw2-specific low-level functionality
|
|
|
05bba0 |
+_supported_fmt qcow2
|
|
|
05bba0 |
+_supported_proto file
|
|
|
05bba0 |
+_supported_os Linux
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+echo '=== Repairing an image without any refcount table ==='
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+_make_test_img 64M
|
|
|
05bba0 |
+# just write some data
|
|
|
05bba0 |
+$QEMU_IO -c 'write -P 42 0 64k' "$TEST_IMG" | _filter_qemu_io
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# refcount_table_offset
|
|
|
05bba0 |
+poke_file "$TEST_IMG" $((0x30)) "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
|
05bba0 |
+# refcount_table_clusters
|
|
|
05bba0 |
+poke_file "$TEST_IMG" $((0x38)) "\x00\x00\x00\x00"
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+_check_test_img -r all
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+$QEMU_IO -c 'read -P 42 0 64k' "$TEST_IMG" | _filter_qemu_io
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+echo '=== Repairing unreferenced data cluster in new refblock area ==='
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+IMGOPTS='cluster_size=512' _make_test_img 64M
|
|
|
05bba0 |
+# Allocate the first 128 kB in the image (first refblock)
|
|
|
05bba0 |
+$QEMU_IO -c 'write 0 0x1b200' "$TEST_IMG" | _filter_qemu_io
|
|
|
05bba0 |
+# should be 131072 == 0x20000
|
|
|
05bba0 |
+stat -c '%s' "$TEST_IMG"
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# Enter a cluster at 128 kB (0x20000)
|
|
|
05bba0 |
+# XXX: This should be the first free entry in the last L2 table, but we cannot
|
|
|
05bba0 |
+# be certain
|
|
|
05bba0 |
+poke_file "$TEST_IMG" $((0x1ccc8)) "\x80\x00\x00\x00\x00\x02\x00\x00"
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# Fill the cluster
|
|
|
05bba0 |
+truncate -s $((0x20200)) "$TEST_IMG"
|
|
|
05bba0 |
+$QEMU_IO -c "open -o driver=raw $TEST_IMG" -c 'write -P 42 128k 512' \
|
|
|
05bba0 |
+ | _filter_qemu_io
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# The data should now appear at this guest offset
|
|
|
05bba0 |
+$QEMU_IO -c 'read -P 42 0x1b200 512' "$TEST_IMG" | _filter_qemu_io
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# This cluster is unallocated; fix it
|
|
|
05bba0 |
+_check_test_img -r all
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# This repair operation must have allocated a new refblock; and that refblock
|
|
|
05bba0 |
+# should not overlap with the unallocated data cluster. If it does, the data
|
|
|
05bba0 |
+# will be damaged, so check it.
|
|
|
05bba0 |
+$QEMU_IO -c 'read -P 42 0x1b200 512' "$TEST_IMG" | _filter_qemu_io
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+echo '=== Repairing refblock beyond the image end ==='
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+echo '--- Otherwise clean ---'
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+_make_test_img 64M
|
|
|
05bba0 |
+# Normally, qemu doesn't create empty refblocks, so we just have to do it by
|
|
|
05bba0 |
+# hand
|
|
|
05bba0 |
+# XXX: This should be the entry for the second refblock
|
|
|
05bba0 |
+poke_file "$TEST_IMG" $((0x10008)) "\x00\x00\x00\x00\x00\x10\x00\x00"
|
|
|
05bba0 |
+# Mark that refblock as used
|
|
|
05bba0 |
+# XXX: This should be the 17th entry (cluster 16) of the first
|
|
|
05bba0 |
+# refblock
|
|
|
05bba0 |
+poke_file "$TEST_IMG" $((0x20020)) "\x00\x01"
|
|
|
05bba0 |
+_check_test_img -r all
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+echo '--- Refblock is unallocated ---'
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+_make_test_img 64M
|
|
|
05bba0 |
+poke_file "$TEST_IMG" $((0x10008)) "\x00\x00\x00\x00\x00\x10\x00\x00"
|
|
|
05bba0 |
+_check_test_img -r all
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+echo '--- Signed overflow after the refblock ---'
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+_make_test_img 64M
|
|
|
05bba0 |
+poke_file "$TEST_IMG" $((0x10008)) "\x7f\xff\xff\xff\xff\xff\x00\x00"
|
|
|
05bba0 |
+_check_test_img -r all
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+echo '--- Unsigned overflow after the refblock ---'
|
|
|
05bba0 |
+echo
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+_make_test_img 64M
|
|
|
05bba0 |
+poke_file "$TEST_IMG" $((0x10008)) "\xff\xff\xff\xff\xff\xff\x00\x00"
|
|
|
05bba0 |
+_check_test_img -r all
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+# success, all done
|
|
|
05bba0 |
+echo '*** done'
|
|
|
05bba0 |
+rm -f $seq.full
|
|
|
05bba0 |
+status=0
|
|
|
05bba0 |
diff --git a/tests/qemu-iotests/108.out b/tests/qemu-iotests/108.out
|
|
|
05bba0 |
new file mode 100644
|
|
|
05bba0 |
index 0000000..824d5cf
|
|
|
05bba0 |
--- /dev/null
|
|
|
05bba0 |
+++ b/tests/qemu-iotests/108.out
|
|
|
05bba0 |
@@ -0,0 +1,110 @@
|
|
|
05bba0 |
+QA output created by 108
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+=== Repairing an image without any refcount table ===
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
|
05bba0 |
+wrote 65536/65536 bytes at offset 0
|
|
|
05bba0 |
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
|
05bba0 |
+ERROR cluster 0 refcount=0 reference=1
|
|
|
05bba0 |
+ERROR cluster 3 refcount=0 reference=1
|
|
|
05bba0 |
+ERROR cluster 4 refcount=0 reference=1
|
|
|
05bba0 |
+ERROR cluster 5 refcount=0 reference=1
|
|
|
05bba0 |
+Rebuilding refcount structure
|
|
|
05bba0 |
+The following inconsistencies were found and repaired:
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ 0 leaked clusters
|
|
|
05bba0 |
+ 4 corruptions
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Double checking the fixed image now...
|
|
|
05bba0 |
+No errors were found on the image.
|
|
|
05bba0 |
+read 65536/65536 bytes at offset 0
|
|
|
05bba0 |
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+=== Repairing unreferenced data cluster in new refblock area ===
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
|
05bba0 |
+wrote 111104/111104 bytes at offset 0
|
|
|
05bba0 |
+108.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
|
05bba0 |
+131072
|
|
|
05bba0 |
+wrote 512/512 bytes at offset 131072
|
|
|
05bba0 |
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
|
05bba0 |
+read 512/512 bytes at offset 111104
|
|
|
05bba0 |
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
|
05bba0 |
+ERROR cluster 256 refcount=0 reference=1
|
|
|
05bba0 |
+Rebuilding refcount structure
|
|
|
05bba0 |
+Repairing cluster 1 refcount=1 reference=0
|
|
|
05bba0 |
+Repairing cluster 2 refcount=1 reference=0
|
|
|
05bba0 |
+The following inconsistencies were found and repaired:
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ 0 leaked clusters
|
|
|
05bba0 |
+ 1 corruptions
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Double checking the fixed image now...
|
|
|
05bba0 |
+No errors were found on the image.
|
|
|
05bba0 |
+read 512/512 bytes at offset 111104
|
|
|
05bba0 |
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+=== Repairing refblock beyond the image end ===
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+--- Otherwise clean ---
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
|
05bba0 |
+Repairing refcount block 1 is outside image
|
|
|
05bba0 |
+The following inconsistencies were found and repaired:
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ 0 leaked clusters
|
|
|
05bba0 |
+ 1 corruptions
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Double checking the fixed image now...
|
|
|
05bba0 |
+No errors were found on the image.
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+--- Refblock is unallocated ---
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
|
05bba0 |
+Repairing refcount block 1 is outside image
|
|
|
05bba0 |
+ERROR cluster 16 refcount=0 reference=1
|
|
|
05bba0 |
+Rebuilding refcount structure
|
|
|
05bba0 |
+Repairing cluster 1 refcount=1 reference=0
|
|
|
05bba0 |
+Repairing cluster 2 refcount=1 reference=0
|
|
|
05bba0 |
+Repairing cluster 16 refcount=1 reference=0
|
|
|
05bba0 |
+The following inconsistencies were found and repaired:
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ 0 leaked clusters
|
|
|
05bba0 |
+ 2 corruptions
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Double checking the fixed image now...
|
|
|
05bba0 |
+No errors were found on the image.
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+--- Signed overflow after the refblock ---
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
|
05bba0 |
+Repairing refcount block 1 is outside image
|
|
|
05bba0 |
+ERROR could not resize image: Invalid argument
|
|
|
05bba0 |
+Rebuilding refcount structure
|
|
|
05bba0 |
+Repairing cluster 1 refcount=1 reference=0
|
|
|
05bba0 |
+Repairing cluster 2 refcount=1 reference=0
|
|
|
05bba0 |
+The following inconsistencies were found and repaired:
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ 0 leaked clusters
|
|
|
05bba0 |
+ 1 corruptions
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Double checking the fixed image now...
|
|
|
05bba0 |
+No errors were found on the image.
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+--- Unsigned overflow after the refblock ---
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
|
05bba0 |
+Repairing refcount block 1 is outside image
|
|
|
05bba0 |
+ERROR could not resize image: Invalid argument
|
|
|
05bba0 |
+Rebuilding refcount structure
|
|
|
05bba0 |
+Repairing cluster 1 refcount=1 reference=0
|
|
|
05bba0 |
+Repairing cluster 2 refcount=1 reference=0
|
|
|
05bba0 |
+The following inconsistencies were found and repaired:
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ 0 leaked clusters
|
|
|
05bba0 |
+ 1 corruptions
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+Double checking the fixed image now...
|
|
|
05bba0 |
+No errors were found on the image.
|
|
|
05bba0 |
+*** done
|
|
|
05bba0 |
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
|
|
|
05bba0 |
index dd3c5fe..695ab02 100644
|
|
|
05bba0 |
--- a/tests/qemu-iotests/group
|
|
|
05bba0 |
+++ b/tests/qemu-iotests/group
|
|
|
05bba0 |
@@ -87,3 +87,4 @@
|
|
|
05bba0 |
092 rw auto quick
|
|
|
05bba0 |
105 rw auto quick
|
|
|
05bba0 |
107 rw auto quick
|
|
|
05bba0 |
+108 rw auto quick
|
|
|
05bba0 |
--
|
|
|
05bba0 |
1.8.3.1
|
|
|
05bba0 |
|