qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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).