* [Qemu-devel] [PATCH 0/2] qcow2/iotests: Add test for inactive L2 overlap
@ 2013-10-11 12:02 Max Reitz
2013-10-11 12:02 ` [Qemu-devel] [PATCH 1/2] qemu-io: Let "open" pass options to block driver Max Reitz
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Max Reitz @ 2013-10-11 12:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
With the ability to adjust the metadata overlap checks performed through
the command line, we can now add a test for checks not performed by the
default "cached" mode, i.e. those regarding inactive L2 tables.
In order to be able to use qemu-io for this test, however, it must first
be extended to allow specifying runtime options for the block driver
through the "open" command.
Max Reitz (2):
qemu-io: Let "open" pass options to block driver
qemu-iotests: Add test for inactive L2 overlap
qemu-io.c | 39 ++++++++++++++++++++++++++++++--------
tests/qemu-iotests/060 | 47 +++++++++++++++++++++++++++++++++++++++-------
tests/qemu-iotests/060.out | 40 ++++++++++++++++++++++++++++++++++++++-
3 files changed, 110 insertions(+), 16 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 1/2] qemu-io: Let "open" pass options to block driver
2013-10-11 12:02 [Qemu-devel] [PATCH 0/2] qcow2/iotests: Add test for inactive L2 overlap Max Reitz
@ 2013-10-11 12:02 ` Max Reitz
2013-10-11 12:02 ` [Qemu-devel] [PATCH 2/2] qemu-iotests: Add test for inactive L2 overlap Max Reitz
2013-10-11 12:18 ` [Qemu-devel] [PATCH 0/2] qcow2/iotests: " Kevin Wolf
2 siblings, 0 replies; 4+ messages in thread
From: Max Reitz @ 2013-10-11 12:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
Add an option to the open command to specify runtime options for the
block driver used.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
qemu-io.c | 39 +++++++++++++++++++++++++++++++--------
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/qemu-io.c b/qemu-io.c
index f4b8efc..3b3340a 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -16,6 +16,8 @@
#include "qemu-io.h"
#include "qemu/main-loop.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
#include "block/block_int.h"
#include "trace/control.h"
@@ -44,7 +46,7 @@ static const cmdinfo_t close_cmd = {
.oneline = "close the current open file",
};
-static int openfile(char *name, int flags, int growable)
+static int openfile(char *name, int flags, int growable, QDict *opts)
{
Error *local_err = NULL;
@@ -54,7 +56,7 @@ static int openfile(char *name, int flags, int growable)
}
if (growable) {
- if (bdrv_file_open(&qemuio_bs, name, NULL, flags, &local_err)) {
+ if (bdrv_file_open(&qemuio_bs, name, opts, flags, &local_err)) {
fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
error_get_pretty(local_err));
error_free(local_err);
@@ -63,7 +65,7 @@ static int openfile(char *name, int flags, int growable)
} else {
qemuio_bs = bdrv_new("hda");
- if (bdrv_open(qemuio_bs, name, NULL, flags, NULL, &local_err) < 0) {
+ if (bdrv_open(qemuio_bs, name, opts, flags, NULL, &local_err) < 0) {
fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
error_get_pretty(local_err));
error_free(local_err);
@@ -89,7 +91,8 @@ static void open_help(void)
" -r, -- open file read-only\n"
" -s, -- use snapshot file\n"
" -n, -- disable host cache\n"
-" -g, -- allow file to grow (only applies to protocols)"
+" -g, -- allow file to grow (only applies to protocols)\n"
+" -o, -- options to be given to the block driver"
"\n");
}
@@ -102,19 +105,30 @@ static const cmdinfo_t open_cmd = {
.argmin = 1,
.argmax = -1,
.flags = CMD_NOFILE_OK,
- .args = "[-Crsn] [path]",
+ .args = "[-Crsn] [-o options] [path]",
.oneline = "open the file specified by path",
.help = open_help,
};
+static QemuOptsList empty_opts = {
+ .name = "drive",
+ .head = QTAILQ_HEAD_INITIALIZER(empty_opts.head),
+ .desc = {
+ /* no elements => accept any params */
+ { /* end of list */ }
+ },
+};
+
static int open_f(BlockDriverState *bs, int argc, char **argv)
{
int flags = 0;
int readonly = 0;
int growable = 0;
int c;
+ QemuOpts *qopts;
+ QDict *opts = NULL;
- while ((c = getopt(argc, argv, "snrg")) != EOF) {
+ while ((c = getopt(argc, argv, "snrgo:")) != EOF) {
switch (c) {
case 's':
flags |= BDRV_O_SNAPSHOT;
@@ -128,6 +142,15 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
case 'g':
growable = 1;
break;
+ case 'o':
+ qopts = qemu_opts_parse(&empty_opts, optarg, 0);
+ if (qopts == NULL) {
+ printf("could not parse option list -- %s\n", optarg);
+ return 0;
+ }
+ opts = qemu_opts_to_qdict(qopts, opts);
+ qemu_opts_del(qopts);
+ break;
default:
return qemuio_command_usage(&open_cmd);
}
@@ -141,7 +164,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
return qemuio_command_usage(&open_cmd);
}
- return openfile(argv[optind], flags, growable);
+ return openfile(argv[optind], flags, growable, opts);
}
static int quit_f(BlockDriverState *bs, int argc, char **argv)
@@ -418,7 +441,7 @@ int main(int argc, char **argv)
}
if ((argc - optind) == 1) {
- openfile(argv[optind], flags, growable);
+ openfile(argv[optind], flags, growable, NULL);
}
command_loop();
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 2/2] qemu-iotests: Add test for inactive L2 overlap
2013-10-11 12:02 [Qemu-devel] [PATCH 0/2] qcow2/iotests: Add test for inactive L2 overlap Max Reitz
2013-10-11 12:02 ` [Qemu-devel] [PATCH 1/2] qemu-io: Let "open" pass options to block driver Max Reitz
@ 2013-10-11 12:02 ` Max Reitz
2013-10-11 12:18 ` [Qemu-devel] [PATCH 0/2] qcow2/iotests: " Kevin Wolf
2 siblings, 0 replies; 4+ messages in thread
From: Max Reitz @ 2013-10-11 12:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
Extend 060 by a test which creates a corrupted image with an active L2
entry pointing to an inactive L2 table and writes to the corresponding
guest offset.
Also, use overlap-check=all for all tests in 060.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
tests/qemu-iotests/060 | 47 +++++++++++++++++++++++++++++++++++++++-------
tests/qemu-iotests/060.out | 40 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 79 insertions(+), 8 deletions(-)
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
index 9bbc43b..bbb1909 100755
--- a/tests/qemu-iotests/060
+++ b/tests/qemu-iotests/060
@@ -21,10 +21,10 @@
# creator
owner=mreitz@redhat.com
-seq=`basename $0`
+seq="$(basename $0)"
echo "QA output created by $seq"
-here=`pwd`
+here="$PWD"
tmp=/tmp/$$
status=1 # failure is the default!
@@ -47,9 +47,15 @@ rt_offset=65536 # 0x10000 (XXX: just an assumption)
rb_offset=131072 # 0x20000 (XXX: just an assumption)
l1_offset=196608 # 0x30000 (XXX: just an assumption)
l2_offset=262144 # 0x40000 (XXX: just an assumption)
+l2_offset_after_snapshot=524288 # 0x80000 (XXX: just an assumption)
IMGOPTS="compat=1.1"
+OPEN_RW="open -o overlap-check=all $TEST_IMG"
+# Overlap checks are done before write operations only, therefore opening an
+# image read-only makes the overlap-check option irrelevant
+OPEN_RO="open -r $TEST_IMG"
+
echo
echo "=== Testing L2 reference into L1 ==="
echo
@@ -65,16 +71,18 @@ _check_test_img
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
# Try to write something, thereby forcing the corrupt bit to be set
-$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
# The corrupt bit must now be set
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
# Try to open the image R/W (which should fail)
-$QEMU_IO -c "read 0 512" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir | _filter_imgfmt
+$QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \
+ | _filter_testdir \
+ | _filter_imgfmt
# Try to open it RO (which should succeed)
-$QEMU_IO -c "read 0 512" -r "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "$OPEN_RO" -c "read 0 512" | _filter_qemu_io
# We could now try to fix the image, but this would probably fail (how should an
# L2 table linked onto the L1 table be fixed?)
@@ -92,7 +100,7 @@ poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01"
poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00"
_check_test_img
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
-$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
# Try to fix it
@@ -102,8 +110,33 @@ _check_test_img -r all
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
# Look if it's really really fixed
-$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+echo
+echo "=== Testing cluster data reference into inactive L2 table ==="
+echo
+_make_test_img 64M
+$QEMU_IO -c "$OPEN_RW" -c "write -P 1 0 512" | _filter_qemu_io
+$QEMU_IMG snapshot -c foo "$TEST_IMG"
+$QEMU_IO -c "$OPEN_RW" -c "write -P 2 0 512" | _filter_qemu_io
+# The inactive L2 table remains at its old offset
+poke_file "$TEST_IMG" "$l2_offset_after_snapshot" \
+ "\x80\x00\x00\x00\x00\x04\x00\x00"
+_check_test_img
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$QEMU_IO -c "$OPEN_RW" -c "write -P 3 0 512" | _filter_qemu_io
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+_check_test_img -r all
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$QEMU_IO -c "$OPEN_RW" -c "write -P 4 0 512" | _filter_qemu_io
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Check data
+$QEMU_IO -c "$OPEN_RO" -c "read -P 4 0 512" | _filter_qemu_io
+$QEMU_IMG snapshot -a foo "$TEST_IMG"
+_check_test_img
+$QEMU_IO -c "$OPEN_RO" -c "read -P 1 0 512" | _filter_qemu_io
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
index 648f743..6c7bdbb 100644
--- a/tests/qemu-iotests/060.out
+++ b/tests/qemu-iotests/060.out
@@ -12,7 +12,6 @@ qcow2: Preventing invalid write on metadata (overlaps with active L1 table); ima
write failed: Input/output error
incompatible_features 0x2
qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
-no file open, try 'help open'
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -40,4 +39,43 @@ incompatible_features 0x0
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
incompatible_features 0x0
+
+=== Testing cluster data reference into inactive L2 table ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ERROR cluster 4 refcount=1 reference=2
+Leaked cluster 9 refcount=1 reference=0
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+
+1 leaked clusters were found on the image.
+This means waste of disk space, but no harm to data.
+incompatible_features 0x0
+qcow2: Preventing invalid write on metadata (overlaps with inactive L2 table); image marked as corrupt.
+write failed: Input/output error
+incompatible_features 0x2
+Repairing cluster 4 refcount=1 reference=2
+Repairing cluster 9 refcount=1 reference=0
+Repairing OFLAG_COPIED data cluster: l2_entry=8000000000040000 refcount=2
+The following inconsistencies were found and repaired:
+
+ 1 leaked clusters
+ 2 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+incompatible_features 0x0
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+incompatible_features 0x0
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+No errors were found on the image.
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] qcow2/iotests: Add test for inactive L2 overlap
2013-10-11 12:02 [Qemu-devel] [PATCH 0/2] qcow2/iotests: Add test for inactive L2 overlap Max Reitz
2013-10-11 12:02 ` [Qemu-devel] [PATCH 1/2] qemu-io: Let "open" pass options to block driver Max Reitz
2013-10-11 12:02 ` [Qemu-devel] [PATCH 2/2] qemu-iotests: Add test for inactive L2 overlap Max Reitz
@ 2013-10-11 12:18 ` Kevin Wolf
2 siblings, 0 replies; 4+ messages in thread
From: Kevin Wolf @ 2013-10-11 12:18 UTC (permalink / raw)
To: Max Reitz; +Cc: qemu-devel, Stefan Hajnoczi
Am 11.10.2013 um 14:02 hat Max Reitz geschrieben:
> With the ability to adjust the metadata overlap checks performed through
> the command line, we can now add a test for checks not performed by the
> default "cached" mode, i.e. those regarding inactive L2 tables.
>
> In order to be able to use qemu-io for this test, however, it must first
> be extended to allow specifying runtime options for the block driver
> through the "open" command.
>
> Max Reitz (2):
> qemu-io: Let "open" pass options to block driver
> qemu-iotests: Add test for inactive L2 overlap
>
> qemu-io.c | 39 ++++++++++++++++++++++++++++++--------
> tests/qemu-iotests/060 | 47 +++++++++++++++++++++++++++++++++++++++-------
> tests/qemu-iotests/060.out | 40 ++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 110 insertions(+), 16 deletions(-)
Thanks, applied to the block branch.
Kevin
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-10-11 12:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-11 12:02 [Qemu-devel] [PATCH 0/2] qcow2/iotests: Add test for inactive L2 overlap Max Reitz
2013-10-11 12:02 ` [Qemu-devel] [PATCH 1/2] qemu-io: Let "open" pass options to block driver Max Reitz
2013-10-11 12:02 ` [Qemu-devel] [PATCH 2/2] qemu-iotests: Add test for inactive L2 overlap Max Reitz
2013-10-11 12:18 ` [Qemu-devel] [PATCH 0/2] qcow2/iotests: " Kevin Wolf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).