All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v11 0/9] add blkdebug tests
@ 2017-04-29 19:14 Eric Blake
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks Eric Blake
                   ` (9 more replies)
  0 siblings, 10 replies; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

Available as a tag at:
git fetch git://repo.or.cz/qemu/ericb.git nbd-blkdebug-v11

Prerequisites: Kevin's block pull request:
https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg05799.html

v10 was:
https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg05227.html

Since then:
- Rebase to Kevin's block branch (patches 7, 8)
- Split series in two - this focuses on just the (relatively stable)
blkdebug enhancements (v10 6-8, 12-17), and saves the qcow2 fixes
(v10 1-5, 9-11) for another day [Max]
- further tweaks to the qemu-io alloc/map commands (patch 1 retitled,
also affecting patch 2-3)

001/9:[down] 'qemu-io: Improve alignment checks'
002/9:[0022] [FC] 'qemu-io: Switch 'alloc' command to byte-based length'
003/9:[0066] [FC] 'qemu-io: Switch 'map' output to byte-based reporting'
004/9:[----] [--] 'blkdebug: Sanity check block layer guarantees'
005/9:[----] [--] 'blkdebug: Refactor error injection'
006/9:[----] [--] 'blkdebug: Add pass-through write_zero and discard support'
007/9:[0004] [FC] 'blkdebug: Simplify override logic'
008/9:[0010] [FC] 'blkdebug: Add ability to override unmap geometries'
009/9:[----] [-C] 'tests: Add coverage for recent block geometry fixes'

Eric Blake (9):
  qemu-io: Improve alignment checks
  qemu-io: Switch 'alloc' command to byte-based length
  qemu-io: Switch 'map' output to byte-based reporting
  blkdebug: Sanity check block layer guarantees
  blkdebug: Refactor error injection
  blkdebug: Add pass-through write_zero and discard support
  blkdebug: Simplify override logic
  blkdebug: Add ability to override unmap geometries
  tests: Add coverage for recent block geometry fixes

 qapi/block-core.json              |  33 ++++-
 block/blkdebug.c                  | 266 +++++++++++++++++++++++++++++++-------
 qemu-io-cmds.c                    |  61 +++++----
 tests/qemu-iotests/019.out        |   8 +-
 tests/qemu-iotests/102.out        |   4 +-
 tests/qemu-iotests/146.out        |  30 ++---
 tests/qemu-iotests/177            | 114 ++++++++++++++++
 tests/qemu-iotests/177.out        |  49 +++++++
 tests/qemu-iotests/common.pattern |   2 +-
 tests/qemu-iotests/group          |   1 +
 10 files changed, 468 insertions(+), 100 deletions(-)
 create mode 100755 tests/qemu-iotests/177
 create mode 100644 tests/qemu-iotests/177.out

-- 
2.9.3

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-04-29 22:39   ` Philippe Mathieu-Daudé
  2017-05-03 18:42   ` Max Reitz
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 2/9] qemu-io: Switch 'alloc' command to byte-based length Eric Blake
                   ` (8 subsequent siblings)
  9 siblings, 2 replies; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

Several copy-and-pasted alignment checks exist in qemu-io, which
could use some minor improvements:

- Manual comparison against 0x1ff is not as clean as using our
alignment macros (QEMU_IS_ALIGNED) from osdep.h.

- The error messages aren't quite grammatically correct.

Suggested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Suggested-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v11: retitle [was "qemu-io: Don't open-code QEMU_IS_ALIGNED"], improve
error messages
v10: new patch
---
 qemu-io-cmds.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 21af9e6..6a0024b 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -740,13 +740,13 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
     }

     if (bflag) {
-        if (offset & 0x1ff) {
-            printf("offset %" PRId64 " is not sector aligned\n",
+        if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
+            printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
                    offset);
             return 0;
         }
-        if (count & 0x1ff) {
-            printf("count %"PRId64" is not sector aligned\n",
+        if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
+            printf("%"PRId64" is not a sector-aligned value for 'count'\n",
                    count);
             return 0;
         }
@@ -1050,14 +1050,14 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
     }

     if (bflag || cflag) {
-        if (offset & 0x1ff) {
-            printf("offset %" PRId64 " is not sector aligned\n",
+        if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
+            printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
                    offset);
             return 0;
         }

-        if (count & 0x1ff) {
-            printf("count %"PRId64" is not sector aligned\n",
+        if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
+            printf("%"PRId64" is not a sector-aligned value for 'count'\n",
                    count);
             return 0;
         }
@@ -1769,8 +1769,8 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
     if (offset < 0) {
         print_cvtnum_err(offset, argv[1]);
         return 0;
-    } else if (offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
+    } else if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
+        printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
                offset);
         return 0;
     }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 2/9] qemu-io: Switch 'alloc' command to byte-based length
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-05-03 18:44   ` Max Reitz
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 3/9] qemu-io: Switch 'map' output to byte-based reporting Eric Blake
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

For the 'alloc' command, accepting an offset in bytes but a length
in sectors, and reporting output in sectors, is confusing.  Do
everything in bytes, and adjust the expected output accordingly.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v11: s/bytes/count/ for the parameter name, drop R-b
v10: rebase to code cleanup
v9: new patch
---
 qemu-io-cmds.c                    | 30 ++++++++++++++++++------------
 tests/qemu-iotests/019.out        |  8 ++++----
 tests/qemu-iotests/common.pattern |  2 +-
 3 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 6a0024b..1e0ebb4 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1760,7 +1760,7 @@ out:
 static int alloc_f(BlockBackend *blk, int argc, char **argv)
 {
     BlockDriverState *bs = blk_bs(blk);
-    int64_t offset, sector_num, nb_sectors, remaining;
+    int64_t offset, sector_num, nb_sectors, remaining, count;
     char s1[64];
     int num, ret;
     int64_t sum_alloc;
@@ -1776,18 +1776,24 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
     }

     if (argc == 3) {
-        nb_sectors = cvtnum(argv[2]);
-        if (nb_sectors < 0) {
-            print_cvtnum_err(nb_sectors, argv[2]);
+        count = cvtnum(argv[2]);
+        if (count < 0) {
+            print_cvtnum_err(count, argv[2]);
             return 0;
-        } else if (nb_sectors > INT_MAX) {
-            printf("length argument cannot exceed %d, given %s\n",
-                   INT_MAX, argv[2]);
+        } else if (count > INT_MAX * BDRV_SECTOR_SIZE) {
+            printf("length argument cannot exceed %llu, given %s\n",
+                   INT_MAX * BDRV_SECTOR_SIZE, argv[2]);
             return 0;
         }
     } else {
-        nb_sectors = 1;
+        count = BDRV_SECTOR_SIZE;
     }
+    if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
+        printf("%" PRId64 " is not a sector-aligned value for 'count'\n",
+               count);
+        return 0;
+    }
+    nb_sectors = count >> BDRV_SECTOR_BITS;

     remaining = nb_sectors;
     sum_alloc = 0;
@@ -1811,8 +1817,8 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)

     cvtstr(offset, s1, sizeof(s1));

-    printf("%"PRId64"/%"PRId64" sectors allocated at offset %s\n",
-           sum_alloc, nb_sectors, s1);
+    printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
+           sum_alloc << BDRV_SECTOR_BITS, nb_sectors << BDRV_SECTOR_BITS, s1);
     return 0;
 }

@@ -1822,8 +1828,8 @@ static const cmdinfo_t alloc_cmd = {
     .argmin     = 1,
     .argmax     = 2,
     .cfunc      = alloc_f,
-    .args       = "off [sectors]",
-    .oneline    = "checks if a sector is present in the file",
+    .args       = "offset [count]",
+    .oneline    = "checks if offset is allocated in the file",
 };


diff --git a/tests/qemu-iotests/019.out b/tests/qemu-iotests/019.out
index 0124264..17a7c03 100644
--- a/tests/qemu-iotests/019.out
+++ b/tests/qemu-iotests/019.out
@@ -542,8 +542,8 @@ Testing conversion with -B TEST_DIR/t.IMGFMT.base

 Checking if backing clusters are allocated when they shouldn't

-0/128 sectors allocated at offset 1 MiB
-0/128 sectors allocated at offset 4.001 GiB
+0/65536 bytes allocated at offset 1 MiB
+0/65536 bytes allocated at offset 4.001 GiB
 Reading

 === IO: pattern 42
@@ -1086,8 +1086,8 @@ Testing conversion with -o backing_file=TEST_DIR/t.IMGFMT.base

 Checking if backing clusters are allocated when they shouldn't

-0/128 sectors allocated at offset 1 MiB
-0/128 sectors allocated at offset 4.001 GiB
+0/65536 bytes allocated at offset 1 MiB
+0/65536 bytes allocated at offset 4.001 GiB
 Reading

 === IO: pattern 42
diff --git a/tests/qemu-iotests/common.pattern b/tests/qemu-iotests/common.pattern
index ddfbca1..34f4a8d 100644
--- a/tests/qemu-iotests/common.pattern
+++ b/tests/qemu-iotests/common.pattern
@@ -18,7 +18,7 @@

 function do_is_allocated() {
     local start=$1
-    local size=$(( $2 / 512))
+    local size=$2
     local step=$3
     local count=$4

-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 3/9] qemu-io: Switch 'map' output to byte-based reporting
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks Eric Blake
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 2/9] qemu-io: Switch 'alloc' command to byte-based length Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-05-03 18:54   ` Max Reitz
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 4/9] blkdebug: Sanity check block layer guarantees Eric Blake
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

Mixing byte offset and sector allocation counts is a bit
confusing.  Also, reporting n/m sectors, where m decreases
according to the remaining size of the file, isn't really
adding any useful information; and reporting an offset at
both the front and end of the line, with large amounts of
whitespace, is pointless.  Update the output to use byte
counts and shorter lines, then adjust the affected tests
(./check -qcow2 102, ./check -vpc 146).

Note that 'qemu-io map' is MUCH weaker than 'qemu-img map';
the former only shows which regions of the active layer are
allocated, without regards to where the allocation comes from
or whether the allocated portion is known to read as zero
(because it is using the weaker bdrv_is_allocated()); while the
latter (especially in --output=json mode) reports more details
from bdrv_get_block_status().

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v11: rebase to occur before test 179, shrink the output
v10: rebase to updated test 179
v9: new patch
---
 qemu-io-cmds.c             | 11 ++++++-----
 tests/qemu-iotests/102.out |  4 ++--
 tests/qemu-iotests/146.out | 30 +++++++++++++++---------------
 3 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 1e0ebb4..4b2278f 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1868,7 +1868,7 @@ static int map_f(BlockBackend *blk, int argc, char **argv)
 {
     int64_t offset;
     int64_t nb_sectors, total_sectors;
-    char s1[64];
+    char s1[64], s2[64];
     int64_t num;
     int ret;
     const char *retstr;
@@ -1894,10 +1894,11 @@ static int map_f(BlockBackend *blk, int argc, char **argv)
         }

         retstr = ret ? "    allocated" : "not allocated";
-        cvtstr(offset << 9ULL, s1, sizeof(s1));
-        printf("[% 24" PRId64 "] % 8" PRId64 "/% 8" PRId64 " sectors %s "
-               "at offset %s (%d)\n",
-               offset << 9ULL, num, nb_sectors, retstr, s1, ret);
+        cvtstr(num << BDRV_SECTOR_BITS, s1, sizeof(s1));
+        cvtstr(offset << BDRV_SECTOR_BITS, s2, sizeof(s2));
+        printf("%s (0x%" PRIx64 ") bytes %s at offset %s (0x%" PRIx64 ")\n",
+               s1, num << BDRV_SECTOR_BITS, retstr,
+               s2, offset << BDRV_SECTOR_BITS);

         offset += num;
         nb_sectors -= num;
diff --git a/tests/qemu-iotests/102.out b/tests/qemu-iotests/102.out
index eecde16..ccf172a 100644
--- a/tests/qemu-iotests/102.out
+++ b/tests/qemu-iotests/102.out
@@ -6,7 +6,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Image resized.
-[                       0]      128/     128 sectors     allocated at offset 0 bytes (1)
+64 KiB (0x10000) bytes     allocated at offset 0 bytes (0x0)
 Offset          Length          Mapped to       File

 === Testing map on an image file truncated outside of qemu ===
@@ -17,5 +17,5 @@ wrote 65536/65536 bytes at offset 0
 Image resized.
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qemu-io drv0 map
-[                       0]      128/     128 sectors     allocated at offset 0 bytes (1)
+64 KiB (0x10000) bytes     allocated at offset 0 bytes (0x0)
 *** done
diff --git a/tests/qemu-iotests/146.out b/tests/qemu-iotests/146.out
index 4f334d8..db6b296 100644
--- a/tests/qemu-iotests/146.out
+++ b/tests/qemu-iotests/146.out
@@ -2,39 +2,39 @@ QA output created by 146

 === Testing VPC Autodetect ===

-[                       0]  266334240/ 266334240 sectors not allocated at offset 0 bytes (0)
+126.998 GiB (0x1fbfe04000) bytes not allocated at offset 0 bytes (0x0)

 === Testing VPC with current_size force ===

-[                       0]  266338304/ 266338304 sectors not allocated at offset 0 bytes (0)
+127 GiB (0x1fc0000000) bytes not allocated at offset 0 bytes (0x0)

 === Testing VPC with chs force ===

-[                       0]  266334240/ 266334240 sectors not allocated at offset 0 bytes (0)
+126.998 GiB (0x1fbfe04000) bytes not allocated at offset 0 bytes (0x0)

 === Testing Hyper-V Autodetect ===

-[                       0]  266338304/ 266338304 sectors not allocated at offset 0 bytes (0)
+127 GiB (0x1fc0000000) bytes not allocated at offset 0 bytes (0x0)

 === Testing Hyper-V with current_size force ===

-[                       0]  266338304/ 266338304 sectors not allocated at offset 0 bytes (0)
+127 GiB (0x1fc0000000) bytes not allocated at offset 0 bytes (0x0)

 === Testing Hyper-V with chs force ===

-[                       0]  266334240/ 266334240 sectors not allocated at offset 0 bytes (0)
+126.998 GiB (0x1fbfe04000) bytes not allocated at offset 0 bytes (0x0)

 === Testing d2v Autodetect ===

-[                       0]   514560/  514560 sectors     allocated at offset 0 bytes (1)
+251.250 MiB (0xfb40000) bytes     allocated at offset 0 bytes (0x0)

 === Testing d2v with current_size force ===

-[                       0]   514560/  514560 sectors     allocated at offset 0 bytes (1)
+251.250 MiB (0xfb40000) bytes     allocated at offset 0 bytes (0x0)

 === Testing d2v with chs force ===

-[                       0]   514560/  514560 sectors     allocated at offset 0 bytes (1)
+251.250 MiB (0xfb40000) bytes     allocated at offset 0 bytes (0x0)

 === Testing Image create, default ===

@@ -42,15 +42,15 @@ Formatting 'TEST_DIR/IMGFMT-create-test.IMGFMT', fmt=IMGFMT size=4294967296

 === Read created image, default opts ====

-[                       0]  8389584/ 8389584 sectors not allocated at offset 0 bytes (0)
+4 GiB (0x10007a000) bytes not allocated at offset 0 bytes (0x0)

 === Read created image, force_size_calc=chs ====

-[                       0]  8389584/ 8389584 sectors not allocated at offset 0 bytes (0)
+4 GiB (0x10007a000) bytes not allocated at offset 0 bytes (0x0)

 === Read created image, force_size_calc=current_size ====

-[                       0]  8389584/ 8389584 sectors not allocated at offset 0 bytes (0)
+4 GiB (0x10007a000) bytes not allocated at offset 0 bytes (0x0)

 === Testing Image create, force_size ===

@@ -58,13 +58,13 @@ Formatting 'TEST_DIR/IMGFMT-create-test.IMGFMT', fmt=IMGFMT size=4294967296 forc

 === Read created image, default opts ====

-[                       0]  8388608/ 8388608 sectors not allocated at offset 0 bytes (0)
+4 GiB (0x100000000) bytes not allocated at offset 0 bytes (0x0)

 === Read created image, force_size_calc=chs ====

-[                       0]  8388608/ 8388608 sectors not allocated at offset 0 bytes (0)
+4 GiB (0x100000000) bytes not allocated at offset 0 bytes (0x0)

 === Read created image, force_size_calc=current_size ====

-[                       0]  8388608/ 8388608 sectors not allocated at offset 0 bytes (0)
+4 GiB (0x100000000) bytes not allocated at offset 0 bytes (0x0)
 *** done
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 4/9] blkdebug: Sanity check block layer guarantees
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
                   ` (2 preceding siblings ...)
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 3/9] qemu-io: Switch 'map' output to byte-based reporting Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 5/9] blkdebug: Refactor error injection Eric Blake
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

Commits 04ed95f4 and 1a62d0ac updated the block layer to auto-fragment
any I/O to fit within device boundaries. Additionally, when using a
minimum alignment of 4k, we want to ensure the block layer does proper
read-modify-write rather than requesting I/O on a slice of a sector.
Let's enforce that the contract is obeyed when using blkdebug.  For
now, blkdebug only allows alignment overrides, and just inherits other
limits from whatever device it is wrapping, but a future patch will
further enhance things.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>

---
v11: no change
v10: no change
v5-v9: no change
v4: no change
v3: rebase to byte-based interfaces
v2: new patch
---
 block/blkdebug.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index d2a7561..30ecb9d 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -429,6 +429,13 @@ blkdebug_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
     BDRVBlkdebugState *s = bs->opaque;
     BlkdebugRule *rule = NULL;

+    /* Sanity check block layer guarantees */
+    assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
+    assert(QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment));
+    if (bs->bl.max_transfer) {
+        assert(bytes <= bs->bl.max_transfer);
+    }
+
     QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
         uint64_t inject_offset = rule->options.inject.offset;

@@ -453,6 +460,13 @@ blkdebug_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
     BDRVBlkdebugState *s = bs->opaque;
     BlkdebugRule *rule = NULL;

+    /* Sanity check block layer guarantees */
+    assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
+    assert(QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment));
+    if (bs->bl.max_transfer) {
+        assert(bytes <= bs->bl.max_transfer);
+    }
+
     QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
         uint64_t inject_offset = rule->options.inject.offset;

-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 5/9] blkdebug: Refactor error injection
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
                   ` (3 preceding siblings ...)
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 4/9] blkdebug: Sanity check block layer guarantees Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 6/9] blkdebug: Add pass-through write_zero and discard support Eric Blake
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

Rather than repeat the logic at each caller of checking if a Rule
exists that warrants an error injection, fold that logic into
inject_error(); and rename it to rule_check() for legibility.
This will help the next patch, which adds two more callers that
need to check rules for the potential of injecting errors.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>

---
v11: no change
v10: no change
v9: no change
v7-v8: not submitted (earlier half of series sent for 2.9)
v6: new patch
---
 block/blkdebug.c | 74 +++++++++++++++++++++++++-------------------------------
 1 file changed, 33 insertions(+), 41 deletions(-)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index 30ecb9d..a2905ca 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -403,11 +403,30 @@ out:
     return ret;
 }

-static int inject_error(BlockDriverState *bs, BlkdebugRule *rule)
+static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes)
 {
     BDRVBlkdebugState *s = bs->opaque;
-    int error = rule->options.inject.error;
-    bool immediately = rule->options.inject.immediately;
+    BlkdebugRule *rule = NULL;
+    int error;
+    bool immediately;
+
+    QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
+        uint64_t inject_offset = rule->options.inject.offset;
+
+        if (inject_offset == -1 ||
+            (bytes && inject_offset >= offset &&
+             inject_offset < offset + bytes))
+        {
+            break;
+        }
+    }
+
+    if (!rule || !rule->options.inject.error) {
+        return 0;
+    }
+
+    immediately = rule->options.inject.immediately;
+    error = rule->options.inject.error;

     if (rule->options.inject.once) {
         QSIMPLEQ_REMOVE(&s->active_rules, rule, BlkdebugRule, active_next);
@@ -426,8 +445,7 @@ static int coroutine_fn
 blkdebug_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
                    QEMUIOVector *qiov, int flags)
 {
-    BDRVBlkdebugState *s = bs->opaque;
-    BlkdebugRule *rule = NULL;
+    int err;

     /* Sanity check block layer guarantees */
     assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
@@ -436,18 +454,9 @@ blkdebug_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
         assert(bytes <= bs->bl.max_transfer);
     }

-    QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
-        uint64_t inject_offset = rule->options.inject.offset;
-
-        if (inject_offset == -1 ||
-            (inject_offset >= offset && inject_offset < offset + bytes))
-        {
-            break;
-        }
-    }
-
-    if (rule && rule->options.inject.error) {
-        return inject_error(bs, rule);
+    err = rule_check(bs, offset, bytes);
+    if (err) {
+        return err;
     }

     return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
@@ -457,8 +466,7 @@ static int coroutine_fn
 blkdebug_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
                     QEMUIOVector *qiov, int flags)
 {
-    BDRVBlkdebugState *s = bs->opaque;
-    BlkdebugRule *rule = NULL;
+    int err;

     /* Sanity check block layer guarantees */
     assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
@@ -467,18 +475,9 @@ blkdebug_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
         assert(bytes <= bs->bl.max_transfer);
     }

-    QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
-        uint64_t inject_offset = rule->options.inject.offset;
-
-        if (inject_offset == -1 ||
-            (inject_offset >= offset && inject_offset < offset + bytes))
-        {
-            break;
-        }
-    }
-
-    if (rule && rule->options.inject.error) {
-        return inject_error(bs, rule);
+    err = rule_check(bs, offset, bytes);
+    if (err) {
+        return err;
     }

     return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
@@ -486,17 +485,10 @@ blkdebug_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,

 static int blkdebug_co_flush(BlockDriverState *bs)
 {
-    BDRVBlkdebugState *s = bs->opaque;
-    BlkdebugRule *rule = NULL;
+    int err = rule_check(bs, 0, 0);

-    QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
-        if (rule->options.inject.offset == -1) {
-            break;
-        }
-    }
-
-    if (rule && rule->options.inject.error) {
-        return inject_error(bs, rule);
+    if (err) {
+        return err;
     }

     return bdrv_co_flush(bs->file->bs);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 6/9] blkdebug: Add pass-through write_zero and discard support
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
                   ` (4 preceding siblings ...)
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 5/9] blkdebug: Refactor error injection Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 7/9] blkdebug: Simplify override logic Eric Blake
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

In order to test the effects of artificial geometry constraints
on operations like write zero or discard, we first need blkdebug
to manage these actions.  It also allows us to inject errors on
those operations, just like we can for read/write/flush.

We can also test the contract promised by the block layer; namely,
if a device has specified limits on alignment or maximum size,
then those limits must be obeyed (for now, the blkdebug driver
merely inherits limits from whatever it is wrapping, but the next
patch will further enhance it to allow specific limit overrides).

This patch intentionally refuses to service requests smaller than
the requested alignments; this is because an upcoming patch adds
a qemu-iotest to prove that the block layer is correctly handling
fragmentation, but the test only works if there is a way to tell
the difference at artificial alignment boundaries when blkdebug is
using a larger-than-default alignment.  If we let the blkdebug
layer always defer to the underlying layer, which potentially has
a smaller granularity, the iotest will be thwarted.

Tested by setting up an NBD server with export 'foo', then invoking:
$ ./qemu-io
qemu-io> open -o driver=blkdebug blkdebug::nbd://localhost:10809/foo
qemu-io> d 0 15M
qemu-io> w -z 0 15M

Pre-patch, the server never sees the discard (it was silently
eaten by the block layer); post-patch it is passed across the
wire.  Likewise, pre-patch the write is always passed with
NBD_WRITE (with 15M of zeroes on the wire), while post-patch
it can utilize NBD_WRITE_ZEROES (for less traffic).

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>

---
v11: no change
v10: no change
v9: no change
v7-v8: not submitted (earlier half of series sent for 2.9)
v6: tighten check of unaligned requests, rebase on rule check
refactoring, drop R-b
v5: include 2017 copyright
v4: correct error injection to respect byte range, tweak formatting
v3: rebase to byte-based read/write, improve docs on why no
partial write zero passthrough
v2: new patch
---
 block/blkdebug.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index a2905ca..6414f1c 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -1,6 +1,7 @@
 /*
  * Block protocol for I/O error injection
  *
+ * Copyright (C) 2016-2017 Red Hat, Inc.
  * Copyright (c) 2010 Kevin Wolf <kwolf@redhat.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -382,6 +383,11 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
         goto out;
     }

+    bs->supported_write_flags = BDRV_REQ_FUA &
+        bs->file->bs->supported_write_flags;
+    bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
+        bs->file->bs->supported_zero_flags;
+
     /* Set request alignment */
     align = qemu_opt_get_size(opts, "align", 0);
     if (align < INT_MAX && is_power_of_2(align)) {
@@ -494,6 +500,72 @@ static int blkdebug_co_flush(BlockDriverState *bs)
     return bdrv_co_flush(bs->file->bs);
 }

+static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
+                                                  int64_t offset, int count,
+                                                  BdrvRequestFlags flags)
+{
+    uint32_t align = MAX(bs->bl.request_alignment,
+                         bs->bl.pwrite_zeroes_alignment);
+    int err;
+
+    /* Only pass through requests that are larger than requested
+     * preferred alignment (so that we test the fallback to writes on
+     * unaligned portions), and check that the block layer never hands
+     * us anything unaligned that crosses an alignment boundary.  */
+    if (count < align) {
+        assert(QEMU_IS_ALIGNED(offset, align) ||
+               QEMU_IS_ALIGNED(offset + count, align) ||
+               DIV_ROUND_UP(offset, align) ==
+               DIV_ROUND_UP(offset + count, align));
+        return -ENOTSUP;
+    }
+    assert(QEMU_IS_ALIGNED(offset, align));
+    assert(QEMU_IS_ALIGNED(count, align));
+    if (bs->bl.max_pwrite_zeroes) {
+        assert(count <= bs->bl.max_pwrite_zeroes);
+    }
+
+    err = rule_check(bs, offset, count);
+    if (err) {
+        return err;
+    }
+
+    return bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
+}
+
+static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
+                                             int64_t offset, int count)
+{
+    uint32_t align = bs->bl.pdiscard_alignment;
+    int err;
+
+    /* Only pass through requests that are larger than requested
+     * minimum alignment, and ensure that unaligned requests do not
+     * cross optimum discard boundaries. */
+    if (count < bs->bl.request_alignment) {
+        assert(QEMU_IS_ALIGNED(offset, align) ||
+               QEMU_IS_ALIGNED(offset + count, align) ||
+               DIV_ROUND_UP(offset, align) ==
+               DIV_ROUND_UP(offset + count, align));
+        return -ENOTSUP;
+    }
+    assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
+    assert(QEMU_IS_ALIGNED(count, bs->bl.request_alignment));
+    if (align && count >= align) {
+        assert(QEMU_IS_ALIGNED(offset, align));
+        assert(QEMU_IS_ALIGNED(count, align));
+    }
+    if (bs->bl.max_pdiscard) {
+        assert(count <= bs->bl.max_pdiscard);
+    }
+
+    err = rule_check(bs, offset, count);
+    if (err) {
+        return err;
+    }
+
+    return bdrv_co_pdiscard(bs->file->bs, offset, count);
+}

 static void blkdebug_close(BlockDriverState *bs)
 {
@@ -748,6 +820,8 @@ static BlockDriver bdrv_blkdebug = {
     .bdrv_co_preadv         = blkdebug_co_preadv,
     .bdrv_co_pwritev        = blkdebug_co_pwritev,
     .bdrv_co_flush_to_disk  = blkdebug_co_flush,
+    .bdrv_co_pwrite_zeroes  = blkdebug_co_pwrite_zeroes,
+    .bdrv_co_pdiscard       = blkdebug_co_pdiscard,

     .bdrv_debug_event           = blkdebug_debug_event,
     .bdrv_debug_breakpoint      = blkdebug_debug_breakpoint,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 7/9] blkdebug: Simplify override logic
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
                   ` (5 preceding siblings ...)
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 6/9] blkdebug: Add pass-through write_zero and discard support Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-05-03 18:59   ` Max Reitz
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 8/9] blkdebug: Add ability to override unmap geometries Eric Blake
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

Rather than store into a local variable, then copy to the struct
if the value is valid, then reporting errors otherwise, it is
simpler to just store into the struct and report errors if the
value is invalid.  This however requires that the struct store
a 64-bit number, rather than a narrower type.  Likewise, setting
a sane errno value in ret prior to the sequence of parsing and
jumping to out: on error makes it easier for the next patch to
add a chain of similar checks.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v11: rebase to master, enough changed to drop R-b
v10: no change
v9: no change
v7-v8: not submitted (earlier half of series sent for 2.9)
v6: tweak error message, but R-b kept
v5: no change
v4: fix typo in commit message, move errno assignment
v3: new patch
---
 block/blkdebug.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index 6414f1c..8e0f596 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -38,7 +38,7 @@
 typedef struct BDRVBlkdebugState {
     int state;
     int new_state;
-    int align;
+    uint64_t align;

     /* For blkdebug_refresh_filename() */
     char *config_file;
@@ -353,7 +353,6 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
     BDRVBlkdebugState *s = bs->opaque;
     QemuOpts *opts;
     Error *local_err = NULL;
-    uint64_t align;
     int ret;

     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
@@ -387,20 +386,17 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
         bs->file->bs->supported_write_flags;
     bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
         bs->file->bs->supported_zero_flags;
+    ret = -EINVAL;

     /* Set request alignment */
-    align = qemu_opt_get_size(opts, "align", 0);
-    if (align < INT_MAX && is_power_of_2(align)) {
-        s->align = align;
-    } else if (align) {
-        error_setg(errp, "Invalid alignment");
-        ret = -EINVAL;
+    s->align = qemu_opt_get_size(opts, "align", 0);
+    if (s->align && (s->align >= INT_MAX || !is_power_of_2(s->align))) {
+        error_setg(errp, "Cannot meet constraints with align %" PRIu64,
+                   s->align);
         goto out;
     }

     ret = 0;
-    goto out;
-
 out:
     if (ret < 0) {
         g_free(s->config_file);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 8/9] blkdebug: Add ability to override unmap geometries
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
                   ` (6 preceding siblings ...)
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 7/9] blkdebug: Simplify override logic Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 9/9] tests: Add coverage for recent block geometry fixes Eric Blake
  2017-05-03 19:07 ` [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Max Reitz
  9 siblings, 0 replies; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block, Markus Armbruster

Make it easier to simulate various unusual hardware setups (for
example, recent commits 3482b9b and b8d0a98 affect the Dell
Equallogic iSCSI with its 15M preferred and maximum unmap and
write zero sizing, or b2f95fe deals with the Linux loopback
block device having a max_transfer of 64k), by allowing blkdebug
to wrap any other device with further restrictions on various
alignments.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>

---
v11: rebase (s/fail_unref/out/), R-b kept
v10: no change
v9: rebase to master (dropped #optional tags)
v7-v8: not submitted (earlier half of series sent for 2.9)
v6: more tweaks in docs and error messages
v5: tweak docs regarding max-transfer minimum
v4: relax 512 byte minimum now that blkdebug is byte-based, fix doc typo
v3: improve legibility of bounds checking, improve docs
v2: new patch
---
 qapi/block-core.json | 33 ++++++++++++++++--
 block/blkdebug.c     | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 125 insertions(+), 4 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 87fb747..2082242 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2430,8 +2430,33 @@
 #
 # @config:          filename of the configuration file
 #
-# @align:           required alignment for requests in bytes,
-#                   must be power of 2, or 0 for default
+# @align:           required alignment for requests in bytes, must be
+#                   positive power of 2, or 0 for default
+#
+# @max-transfer:    maximum size for I/O transfers in bytes, must be
+#                   positive multiple of @align and of the underlying
+#                   file's request alignment (but need not be a power of
+#                   2), or 0 for default (since 2.10)
+#
+# @opt-write-zero:  preferred alignment for write zero requests in bytes,
+#                   must be positive multiple of @align and of the
+#                   underlying file's request alignment (but need not be a
+#                   power of 2), or 0 for default (since 2.10)
+#
+# @max-write-zero:  maximum size for write zero requests in bytes, must be
+#                   positive multiple of @align, of @opt-write-zero, and of
+#                   the underlying file's request alignment (but need not
+#                   be a power of 2), or 0 for default (since 2.10)
+#
+# @opt-discard:     preferred alignment for discard requests in bytes, must
+#                   be positive multiple of @align and of the underlying
+#                   file's request alignment (but need not be a power of
+#                   2), or 0 for default (since 2.10)
+#
+# @max-discard:     maximum size for discard requests in bytes, must be
+#                   positive multiple of @align, of @opt-discard, and of
+#                   the underlying file's request alignment (but need not
+#                   be a power of 2), or 0 for default (since 2.10)
 #
 # @inject-error:    array of error injection descriptions
 #
@@ -2442,7 +2467,9 @@
 { 'struct': 'BlockdevOptionsBlkdebug',
   'data': { 'image': 'BlockdevRef',
             '*config': 'str',
-            '*align': 'int',
+            '*align': 'int', '*max-transfer': 'int32',
+            '*opt-write-zero': 'int32', '*max-write-zero': 'int32',
+            '*opt-discard': 'int32', '*max-discard': 'int32',
             '*inject-error': ['BlkdebugInjectErrorOptions'],
             '*set-state': ['BlkdebugSetStateOptions'] } }

diff --git a/block/blkdebug.c b/block/blkdebug.c
index 8e0f596..ede98a2 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -39,6 +39,11 @@ typedef struct BDRVBlkdebugState {
     int state;
     int new_state;
     uint64_t align;
+    uint64_t max_transfer;
+    uint64_t opt_write_zero;
+    uint64_t max_write_zero;
+    uint64_t opt_discard;
+    uint64_t max_discard;

     /* For blkdebug_refresh_filename() */
     char *config_file;
@@ -343,6 +348,31 @@ static QemuOptsList runtime_opts = {
             .type = QEMU_OPT_SIZE,
             .help = "Required alignment in bytes",
         },
+        {
+            .name = "max-transfer",
+            .type = QEMU_OPT_SIZE,
+            .help = "Maximum transfer size in bytes",
+        },
+        {
+            .name = "opt-write-zero",
+            .type = QEMU_OPT_SIZE,
+            .help = "Optimum write zero alignment in bytes",
+        },
+        {
+            .name = "max-write-zero",
+            .type = QEMU_OPT_SIZE,
+            .help = "Maximum write zero size in bytes",
+        },
+        {
+            .name = "opt-discard",
+            .type = QEMU_OPT_SIZE,
+            .help = "Optimum discard alignment in bytes",
+        },
+        {
+            .name = "max-discard",
+            .type = QEMU_OPT_SIZE,
+            .help = "Maximum discard size in bytes",
+        },
         { /* end of list */ }
     },
 };
@@ -354,6 +384,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
     QemuOpts *opts;
     Error *local_err = NULL;
     int ret;
+    uint64_t align;

     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
@@ -388,13 +419,61 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
         bs->file->bs->supported_zero_flags;
     ret = -EINVAL;

-    /* Set request alignment */
+    /* Set alignment overrides */
     s->align = qemu_opt_get_size(opts, "align", 0);
     if (s->align && (s->align >= INT_MAX || !is_power_of_2(s->align))) {
         error_setg(errp, "Cannot meet constraints with align %" PRIu64,
                    s->align);
         goto out;
     }
+    align = MAX(s->align, bs->file->bs->bl.request_alignment);
+
+    s->max_transfer = qemu_opt_get_size(opts, "max-transfer", 0);
+    if (s->max_transfer &&
+        (s->max_transfer >= INT_MAX ||
+         !QEMU_IS_ALIGNED(s->max_transfer, align))) {
+        error_setg(errp, "Cannot meet constraints with max-transfer %" PRIu64,
+                   s->max_transfer);
+        goto out;
+    }
+
+    s->opt_write_zero = qemu_opt_get_size(opts, "opt-write-zero", 0);
+    if (s->opt_write_zero &&
+        (s->opt_write_zero >= INT_MAX ||
+         !QEMU_IS_ALIGNED(s->opt_write_zero, align))) {
+        error_setg(errp, "Cannot meet constraints with opt-write-zero %" PRIu64,
+                   s->opt_write_zero);
+        goto out;
+    }
+
+    s->max_write_zero = qemu_opt_get_size(opts, "max-write-zero", 0);
+    if (s->max_write_zero &&
+        (s->max_write_zero >= INT_MAX ||
+         !QEMU_IS_ALIGNED(s->max_write_zero,
+                          MAX(s->opt_write_zero, align)))) {
+        error_setg(errp, "Cannot meet constraints with max-write-zero %" PRIu64,
+                   s->max_write_zero);
+        goto out;
+    }
+
+    s->opt_discard = qemu_opt_get_size(opts, "opt-discard", 0);
+    if (s->opt_discard &&
+        (s->opt_discard >= INT_MAX ||
+         !QEMU_IS_ALIGNED(s->opt_discard, align))) {
+        error_setg(errp, "Cannot meet constraints with opt-discard %" PRIu64,
+                   s->opt_discard);
+        goto out;
+    }
+
+    s->max_discard = qemu_opt_get_size(opts, "max-discard", 0);
+    if (s->max_discard &&
+        (s->max_discard >= INT_MAX ||
+         !QEMU_IS_ALIGNED(s->max_discard,
+                          MAX(s->opt_discard, align)))) {
+        error_setg(errp, "Cannot meet constraints with max-discard %" PRIu64,
+                   s->max_discard);
+        goto out;
+    }

     ret = 0;
 out:
@@ -789,6 +868,21 @@ static void blkdebug_refresh_limits(BlockDriverState *bs, Error **errp)
     if (s->align) {
         bs->bl.request_alignment = s->align;
     }
+    if (s->max_transfer) {
+        bs->bl.max_transfer = s->max_transfer;
+    }
+    if (s->opt_write_zero) {
+        bs->bl.pwrite_zeroes_alignment = s->opt_write_zero;
+    }
+    if (s->max_write_zero) {
+        bs->bl.max_pwrite_zeroes = s->max_write_zero;
+    }
+    if (s->opt_discard) {
+        bs->bl.pdiscard_alignment = s->opt_discard;
+    }
+    if (s->max_discard) {
+        bs->bl.max_pdiscard = s->max_discard;
+    }
 }

 static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v11 9/9] tests: Add coverage for recent block geometry fixes
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
                   ` (7 preceding siblings ...)
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 8/9] blkdebug: Add ability to override unmap geometries Eric Blake
@ 2017-04-29 19:14 ` Eric Blake
  2017-05-05 22:34   ` Max Reitz
  2017-05-03 19:07 ` [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Max Reitz
  9 siblings, 1 reply; 20+ messages in thread
From: Eric Blake @ 2017-04-29 19:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, mreitz, qemu-block

Use blkdebug's new geometry constraints to emulate setups that
have needed past regression fixes: write zeroes asserting
when running through a loopback block device with max-transfer
smaller than cluster size, and discard rounding away portions
of requests not aligned to preferred boundaries.  Also, add
coverage that the block layer is honoring max transfer limits.

For now, a single iotest performs all actions, with the idea
that we can add future blkdebug constraint test cases in the
same file; but it can be split into multiple iotests if we find
reason to run one portion of the test in more setups than what
are possible in the other.

For reference, the final portion of the test (checking whether
discard passes as much as possible to the lowest layers of the
stack) works as follows:

qemu-io: discard 30M at 80000001, passed to blkdebug
  blkdebug: discard 511 bytes at 80000001, -ENOTSUP (smaller than
blkdebug's 512 align)
  blkdebug: discard 14371328 bytes at 80000512, passed to qcow2
    qcow2: discard 739840 bytes at 80000512, -ENOTSUP (smaller than
qcow2's 1M align)
    qcow2: discard 13M bytes at 77M, succeeds
  blkdebug: discard 15M bytes at 90M, passed to qcow2
    qcow2: discard 15M bytes at 90M, succeeds
  blkdebug: discard 1356800 bytes at 105M, passed to qcow2
    qcow2: discard 1M at 105M, succeeds
    qcow2: discard 308224 bytes at 106M, -ENOTSUP (smaller than qcow2's
1M align)
  blkdebug: discard 1 byte at 111457280, -ENOTSUP (smaller than
blkdebug's 512 align)

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>

---
v11: rebase to context
v10: no change, rebase to context
v9: no change
v7-v8: not submitted (earlier half of series sent for 2.9)
v6: rebase to master by renumbering s/175/177/
v5: rebase to master by renumbering s/173/175/
v4: clean up some comments, nicer backing file creation, more commit message
v3: make comments tied more to test at hand, rather than the
particular hardware that led to the earlier patches being tested
v2: new patch
---
 tests/qemu-iotests/177     | 114 +++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/177.out |  49 +++++++++++++++++++
 tests/qemu-iotests/group   |   1 +
 3 files changed, 164 insertions(+)
 create mode 100755 tests/qemu-iotests/177
 create mode 100644 tests/qemu-iotests/177.out

diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177
new file mode 100755
index 0000000..e4ddec7
--- /dev/null
+++ b/tests/qemu-iotests/177
@@ -0,0 +1,114 @@
+#!/bin/bash
+#
+# Test corner cases with unusual block geometries
+#
+# Copyright (C) 2016-2017 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=eblake@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1	# failure is the default!
+
+_cleanup()
+{
+	_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto file
+
+CLUSTER_SIZE=1M
+size=128M
+options=driver=blkdebug,image.driver=qcow2
+
+echo
+echo "== setting up files =="
+
+TEST_IMG="$TEST_IMG.base" _make_test_img $size
+$QEMU_IO -c "write -P 11 0 $size" "$TEST_IMG.base" | _filter_qemu_io
+_make_test_img -b "$TEST_IMG.base"
+$QEMU_IO -c "write -P 22 0 $size" "$TEST_IMG" | _filter_qemu_io
+
+# Limited to 64k max-transfer
+echo
+echo "== constrained alignment and max-transfer =="
+limits=align=4k,max-transfer=64k
+$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
+         -c "write -P 33 1000 128k" -c "read -P 33 1000 128k" | _filter_qemu_io
+
+echo
+echo "== write zero with constrained max-transfer =="
+limits=align=512,max-transfer=64k,opt-write-zero=$CLUSTER_SIZE
+$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
+         -c "write -z 8003584 2093056" | _filter_qemu_io
+
+# non-power-of-2 write-zero/discard alignments
+echo
+echo "== non-power-of-2 write zeroes limits =="
+
+limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-discard=15M
+$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
+         -c "write -z 32M 32M" | _filter_qemu_io
+
+echo
+echo "== non-power-of-2 discard limits =="
+
+limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-discard=15M
+$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
+         -c "discard 80000001 30M" | _filter_qemu_io
+
+echo
+echo "== verify image content =="
+
+function verify_io()
+{
+    if ($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" |
+	    grep "compat: 0.10" > /dev/null); then
+        # For v2 images, discarded clusters are read from the backing file
+        discarded=11
+    else
+        # Discarded clusters are zeroed for v3 or later
+        discarded=0
+    fi
+
+    echo read -P 22 0 1000
+    echo read -P 33 1000 128k
+    echo read -P 22 132072 7871512
+    echo read -P 0 8003584 2093056
+    echo read -P 22 10096640 23457792
+    echo read -P 0 32M 32M
+    echo read -P 22 64M 13M
+    echo read -P $discarded 77M 29M
+    echo read -P 22 106M 22M
+}
+
+verify_io | $QEMU_IO "$TEST_IMG" | _filter_qemu_io
+
+_check_test_img
+
+# success, all done
+echo "*** done"
+status=0
diff --git a/tests/qemu-iotests/177.out b/tests/qemu-iotests/177.out
new file mode 100644
index 0000000..e887542
--- /dev/null
+++ b/tests/qemu-iotests/177.out
@@ -0,0 +1,49 @@
+QA output created by 177
+
+== setting up files ==
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
+wrote 134217728/134217728 bytes at offset 0
+128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
+wrote 134217728/134217728 bytes at offset 0
+128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== constrained alignment and max-transfer ==
+wrote 131072/131072 bytes at offset 1000
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 131072/131072 bytes at offset 1000
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== write zero with constrained max-transfer ==
+wrote 2093056/2093056 bytes at offset 8003584
+1.996 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== non-power-of-2 write zeroes limits ==
+wrote 33554432/33554432 bytes at offset 33554432
+32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== non-power-of-2 discard limits ==
+discard 31457280/31457280 bytes at offset 80000001
+30 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify image content ==
+read 1000/1000 bytes at offset 0
+1000 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 131072/131072 bytes at offset 1000
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 7871512/7871512 bytes at offset 132072
+7.507 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 2093056/2093056 bytes at offset 8003584
+1.996 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 23457792/23457792 bytes at offset 10096640
+22.371 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 33554432/33554432 bytes at offset 33554432
+32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 13631488/13631488 bytes at offset 67108864
+13 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 30408704/30408704 bytes at offset 80740352
+29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 23068672/23068672 bytes at offset 111149056
+22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+No errors were found on the image.
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 893962d..9b9bb4c 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -169,4 +169,5 @@
 174 auto
 175 auto quick
 176 rw auto backing
+177 rw auto quick
 181 rw auto migration
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks Eric Blake
@ 2017-04-29 22:39   ` Philippe Mathieu-Daudé
  2017-05-03 18:42   ` Max Reitz
  1 sibling, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-29 22:39 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: kwolf, qemu-block, mreitz

On 04/29/2017 04:14 PM, Eric Blake wrote:
> Several copy-and-pasted alignment checks exist in qemu-io, which
> could use some minor improvements:
>
> - Manual comparison against 0x1ff is not as clean as using our
> alignment macros (QEMU_IS_ALIGNED) from osdep.h.
>
> - The error messages aren't quite grammatically correct.
>
> Suggested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Suggested-by: Max Reitz <mreitz@redhat.com>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
> v11: retitle [was "qemu-io: Don't open-code QEMU_IS_ALIGNED"], improve
> error messages
> v10: new patch
> ---
>  qemu-io-cmds.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
> index 21af9e6..6a0024b 100644
> --- a/qemu-io-cmds.c
> +++ b/qemu-io-cmds.c
> @@ -740,13 +740,13 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
>      }
>
>      if (bflag) {
> -        if (offset & 0x1ff) {
> -            printf("offset %" PRId64 " is not sector aligned\n",
> +        if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
> +            printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
>                     offset);
>              return 0;
>          }
> -        if (count & 0x1ff) {
> -            printf("count %"PRId64" is not sector aligned\n",
> +        if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
> +            printf("%"PRId64" is not a sector-aligned value for 'count'\n",
>                     count);
>              return 0;
>          }
> @@ -1050,14 +1050,14 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
>      }
>
>      if (bflag || cflag) {
> -        if (offset & 0x1ff) {
> -            printf("offset %" PRId64 " is not sector aligned\n",
> +        if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
> +            printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
>                     offset);
>              return 0;
>          }
>
> -        if (count & 0x1ff) {
> -            printf("count %"PRId64" is not sector aligned\n",
> +        if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
> +            printf("%"PRId64" is not a sector-aligned value for 'count'\n",
>                     count);
>              return 0;
>          }
> @@ -1769,8 +1769,8 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
>      if (offset < 0) {
>          print_cvtnum_err(offset, argv[1]);
>          return 0;
> -    } else if (offset & 0x1ff) {
> -        printf("offset %" PRId64 " is not sector aligned\n",
> +    } else if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
> +        printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
>                 offset);
>          return 0;
>      }
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks Eric Blake
  2017-04-29 22:39   ` Philippe Mathieu-Daudé
@ 2017-05-03 18:42   ` Max Reitz
  1 sibling, 0 replies; 20+ messages in thread
From: Max Reitz @ 2017-05-03 18:42 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 3459 bytes --]

On 29.04.2017 21:14, Eric Blake wrote:
> Several copy-and-pasted alignment checks exist in qemu-io, which
> could use some minor improvements:
> 
> - Manual comparison against 0x1ff is not as clean as using our
> alignment macros (QEMU_IS_ALIGNED) from osdep.h.
> 
> - The error messages aren't quite grammatically correct.

Well, yes, s/sector aligned/sector-aligned/, but the rest was largely
correct, and I have to admit I liked them better how they were before --
if only because they were shorter. (Longer explanation: These are error
messages for an interface to be used by humans, and I as a human don't
like it very much if my programs are overly technical and cold to me. "X
is an invalid value for 'Y'" is very technical. "X is wrong for Y" or "X
Y does not work" sounds more familiar and nicer. I like my programs nice.)

But just a matter of taste, so:

Reviewed-by: Max Reitz <mreitz@redhat.com>

> Suggested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Suggested-by: Max Reitz <mreitz@redhat.com>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> 
> ---
> v11: retitle [was "qemu-io: Don't open-code QEMU_IS_ALIGNED"], improve
> error messages
> v10: new patch
> ---
>  qemu-io-cmds.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
> index 21af9e6..6a0024b 100644
> --- a/qemu-io-cmds.c
> +++ b/qemu-io-cmds.c
> @@ -740,13 +740,13 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
>      }
> 
>      if (bflag) {
> -        if (offset & 0x1ff) {
> -            printf("offset %" PRId64 " is not sector aligned\n",
> +        if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
> +            printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
>                     offset);
>              return 0;
>          }
> -        if (count & 0x1ff) {
> -            printf("count %"PRId64" is not sector aligned\n",
> +        if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
> +            printf("%"PRId64" is not a sector-aligned value for 'count'\n",
>                     count);
>              return 0;
>          }
> @@ -1050,14 +1050,14 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
>      }
> 
>      if (bflag || cflag) {
> -        if (offset & 0x1ff) {
> -            printf("offset %" PRId64 " is not sector aligned\n",
> +        if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
> +            printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
>                     offset);
>              return 0;
>          }
> 
> -        if (count & 0x1ff) {
> -            printf("count %"PRId64" is not sector aligned\n",
> +        if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
> +            printf("%"PRId64" is not a sector-aligned value for 'count'\n",
>                     count);
>              return 0;
>          }
> @@ -1769,8 +1769,8 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
>      if (offset < 0) {
>          print_cvtnum_err(offset, argv[1]);
>          return 0;
> -    } else if (offset & 0x1ff) {
> -        printf("offset %" PRId64 " is not sector aligned\n",
> +    } else if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
> +        printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
>                 offset);
>          return 0;
>      }
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 2/9] qemu-io: Switch 'alloc' command to byte-based length
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 2/9] qemu-io: Switch 'alloc' command to byte-based length Eric Blake
@ 2017-05-03 18:44   ` Max Reitz
  0 siblings, 0 replies; 20+ messages in thread
From: Max Reitz @ 2017-05-03 18:44 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 694 bytes --]

On 29.04.2017 21:14, Eric Blake wrote:
> For the 'alloc' command, accepting an offset in bytes but a length
> in sectors, and reporting output in sectors, is confusing.  Do
> everything in bytes, and adjust the expected output accordingly.
> 
> Signed-off-by: Eric Blake <eblake@redhat.com>
> 
> ---
> v11: s/bytes/count/ for the parameter name, drop R-b
> v10: rebase to code cleanup
> v9: new patch
> ---
>  qemu-io-cmds.c                    | 30 ++++++++++++++++++------------
>  tests/qemu-iotests/019.out        |  8 ++++----
>  tests/qemu-iotests/common.pattern |  2 +-
>  3 files changed, 23 insertions(+), 17 deletions(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 3/9] qemu-io: Switch 'map' output to byte-based reporting
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 3/9] qemu-io: Switch 'map' output to byte-based reporting Eric Blake
@ 2017-05-03 18:54   ` Max Reitz
  0 siblings, 0 replies; 20+ messages in thread
From: Max Reitz @ 2017-05-03 18:54 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 2419 bytes --]

On 29.04.2017 21:14, Eric Blake wrote:
> Mixing byte offset and sector allocation counts is a bit
> confusing.  Also, reporting n/m sectors, where m decreases
> according to the remaining size of the file, isn't really
> adding any useful information; and reporting an offset at
> both the front and end of the line, with large amounts of
> whitespace, is pointless.  Update the output to use byte
> counts and shorter lines, then adjust the affected tests
> (./check -qcow2 102, ./check -vpc 146).
> 
> Note that 'qemu-io map' is MUCH weaker than 'qemu-img map';
> the former only shows which regions of the active layer are
> allocated, without regards to where the allocation comes from
> or whether the allocated portion is known to read as zero
> (because it is using the weaker bdrv_is_allocated()); while the
> latter (especially in --output=json mode) reports more details
> from bdrv_get_block_status().
> 
> Signed-off-by: Eric Blake <eblake@redhat.com>
> 
> ---
> v11: rebase to occur before test 179, shrink the output
> v10: rebase to updated test 179
> v9: new patch
> ---
>  qemu-io-cmds.c             | 11 ++++++-----
>  tests/qemu-iotests/102.out |  4 ++--
>  tests/qemu-iotests/146.out | 30 +++++++++++++++---------------
>  3 files changed, 23 insertions(+), 22 deletions(-)

Reviwed-by: Max Reitz <mreitz@redhat.com>

> diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
> index 1e0ebb4..4b2278f 100644
> --- a/qemu-io-cmds.c
> +++ b/qemu-io-cmds.c

[...]

> @@ -1894,10 +1894,11 @@ static int map_f(BlockBackend *blk, int argc, char **argv)
>          }
> 
>          retstr = ret ? "    allocated" : "not allocated";
> -        cvtstr(offset << 9ULL, s1, sizeof(s1));
> -        printf("[% 24" PRId64 "] % 8" PRId64 "/% 8" PRId64 " sectors %s "
> -               "at offset %s (%d)\n",
> -               offset << 9ULL, num, nb_sectors, retstr, s1, ret);
> +        cvtstr(num << BDRV_SECTOR_BITS, s1, sizeof(s1));
> +        cvtstr(offset << BDRV_SECTOR_BITS, s2, sizeof(s2));
> +        printf("%s (0x%" PRIx64 ") bytes %s at offset %s (0x%" PRIx64 ")\n",

By the way, %# " PRIx64 " would work, too.


Just wanted to get out my kind-of-obscure printf knowledge.

Sorry.

> +               s1, num << BDRV_SECTOR_BITS, retstr,
> +               s2, offset << BDRV_SECTOR_BITS);
> 
>          offset += num;
>          nb_sectors -= num;


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 7/9] blkdebug: Simplify override logic
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 7/9] blkdebug: Simplify override logic Eric Blake
@ 2017-05-03 18:59   ` Max Reitz
  2017-05-03 19:01     ` Max Reitz
  2017-05-03 19:03     ` Eric Blake
  0 siblings, 2 replies; 20+ messages in thread
From: Max Reitz @ 2017-05-03 18:59 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 2785 bytes --]

On 29.04.2017 21:14, Eric Blake wrote:
> Rather than store into a local variable, then copy to the struct
> if the value is valid, then reporting errors otherwise, it is
> simpler to just store into the struct and report errors if the
> value is invalid.  This however requires that the struct store
> a 64-bit number, rather than a narrower type.  Likewise, setting
> a sane errno value in ret prior to the sequence of parsing and
> jumping to out: on error makes it easier for the next patch to
> add a chain of similar checks.
> 
> Signed-off-by: Eric Blake <eblake@redhat.com>
> 
> ---
> v11: rebase to master, enough changed to drop R-b
> v10: no change
> v9: no change
> v7-v8: not submitted (earlier half of series sent for 2.9)
> v6: tweak error message, but R-b kept
> v5: no change
> v4: fix typo in commit message, move errno assignment
> v3: new patch
> ---
>  block/blkdebug.c | 16 ++++++----------
>  1 file changed, 6 insertions(+), 10 deletions(-)
> 
> diff --git a/block/blkdebug.c b/block/blkdebug.c
> index 6414f1c..8e0f596 100644
> --- a/block/blkdebug.c
> +++ b/block/blkdebug.c
> @@ -38,7 +38,7 @@
>  typedef struct BDRVBlkdebugState {
>      int state;
>      int new_state;
> -    int align;
> +    uint64_t align;
> 
>      /* For blkdebug_refresh_filename() */
>      char *config_file;
> @@ -353,7 +353,6 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
>      BDRVBlkdebugState *s = bs->opaque;
>      QemuOpts *opts;
>      Error *local_err = NULL;
> -    uint64_t align;
>      int ret;
> 
>      opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
> @@ -387,20 +386,17 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
>          bs->file->bs->supported_write_flags;
>      bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
>          bs->file->bs->supported_zero_flags;
> +    ret = -EINVAL;
> 
>      /* Set request alignment */
> -    align = qemu_opt_get_size(opts, "align", 0);
> -    if (align < INT_MAX && is_power_of_2(align)) {
> -        s->align = align;
> -    } else if (align) {
> -        error_setg(errp, "Invalid alignment");
> -        ret = -EINVAL;
> +    s->align = qemu_opt_get_size(opts, "align", 0);
> +    if (s->align && (s->align >= INT_MAX || !is_power_of_2(s->align))) {
> +        error_setg(errp, "Cannot meet constraints with align %" PRIu64,
> +                   s->align);

Why don't you just keep the ret = -EINVAL here and not add it above?
It's not wrong, I just think it makes the code a bit weird to read.

Max

>          goto out;
>      }
> 
>      ret = 0;
> -    goto out;
> -
>  out:
>      if (ret < 0) {
>          g_free(s->config_file);
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 7/9] blkdebug: Simplify override logic
  2017-05-03 18:59   ` Max Reitz
@ 2017-05-03 19:01     ` Max Reitz
  2017-05-03 19:03     ` Eric Blake
  1 sibling, 0 replies; 20+ messages in thread
From: Max Reitz @ 2017-05-03 19:01 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 2941 bytes --]

On 03.05.2017 20:59, Max Reitz wrote:
> On 29.04.2017 21:14, Eric Blake wrote:
>> Rather than store into a local variable, then copy to the struct
>> if the value is valid, then reporting errors otherwise, it is
>> simpler to just store into the struct and report errors if the
>> value is invalid.  This however requires that the struct store
>> a 64-bit number, rather than a narrower type.  Likewise, setting
>> a sane errno value in ret prior to the sequence of parsing and
>> jumping to out: on error makes it easier for the next patch to
>> add a chain of similar checks.
>>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>
>> ---
>> v11: rebase to master, enough changed to drop R-b
>> v10: no change
>> v9: no change
>> v7-v8: not submitted (earlier half of series sent for 2.9)
>> v6: tweak error message, but R-b kept
>> v5: no change
>> v4: fix typo in commit message, move errno assignment
>> v3: new patch
>> ---
>>  block/blkdebug.c | 16 ++++++----------
>>  1 file changed, 6 insertions(+), 10 deletions(-)
>>
>> diff --git a/block/blkdebug.c b/block/blkdebug.c
>> index 6414f1c..8e0f596 100644
>> --- a/block/blkdebug.c
>> +++ b/block/blkdebug.c
>> @@ -38,7 +38,7 @@
>>  typedef struct BDRVBlkdebugState {
>>      int state;
>>      int new_state;
>> -    int align;
>> +    uint64_t align;
>>
>>      /* For blkdebug_refresh_filename() */
>>      char *config_file;
>> @@ -353,7 +353,6 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
>>      BDRVBlkdebugState *s = bs->opaque;
>>      QemuOpts *opts;
>>      Error *local_err = NULL;
>> -    uint64_t align;
>>      int ret;
>>
>>      opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
>> @@ -387,20 +386,17 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
>>          bs->file->bs->supported_write_flags;
>>      bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
>>          bs->file->bs->supported_zero_flags;
>> +    ret = -EINVAL;
>>
>>      /* Set request alignment */
>> -    align = qemu_opt_get_size(opts, "align", 0);
>> -    if (align < INT_MAX && is_power_of_2(align)) {
>> -        s->align = align;
>> -    } else if (align) {
>> -        error_setg(errp, "Invalid alignment");
>> -        ret = -EINVAL;
>> +    s->align = qemu_opt_get_size(opts, "align", 0);
>> +    if (s->align && (s->align >= INT_MAX || !is_power_of_2(s->align))) {
>> +        error_setg(errp, "Cannot meet constraints with align %" PRIu64,
>> +                   s->align);
> 
> Why don't you just keep the ret = -EINVAL here and not add it above?
> It's not wrong, I just think it makes the code a bit weird to read.

Ah. Read the next patch, that is why you don't. Well, I would've
probably still added it to each goto out;, but it does make sense to
just set it once here, so:

Reviewed-by: Max Reitz <mreitz@redhat.com>


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 7/9] blkdebug: Simplify override logic
  2017-05-03 18:59   ` Max Reitz
  2017-05-03 19:01     ` Max Reitz
@ 2017-05-03 19:03     ` Eric Blake
  1 sibling, 0 replies; 20+ messages in thread
From: Eric Blake @ 2017-05-03 19:03 UTC (permalink / raw)
  To: Max Reitz, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 2269 bytes --]

On 05/03/2017 01:59 PM, Max Reitz wrote:
> On 29.04.2017 21:14, Eric Blake wrote:
>> Rather than store into a local variable, then copy to the struct
>> if the value is valid, then reporting errors otherwise, it is
>> simpler to just store into the struct and report errors if the
>> value is invalid.  This however requires that the struct store
>> a 64-bit number, rather than a narrower type.  Likewise, setting
>> a sane errno value in ret prior to the sequence of parsing and
>> jumping to out: on error makes it easier for the next patch to
>> add a chain of similar checks.
>>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>
>> ---

>> @@ -387,20 +386,17 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
>>          bs->file->bs->supported_write_flags;
>>      bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
>>          bs->file->bs->supported_zero_flags;
>> +    ret = -EINVAL;
>>
>>      /* Set request alignment */
>> -    align = qemu_opt_get_size(opts, "align", 0);
>> -    if (align < INT_MAX && is_power_of_2(align)) {
>> -        s->align = align;
>> -    } else if (align) {
>> -        error_setg(errp, "Invalid alignment");
>> -        ret = -EINVAL;
>> +    s->align = qemu_opt_get_size(opts, "align", 0);
>> +    if (s->align && (s->align >= INT_MAX || !is_power_of_2(s->align))) {
>> +        error_setg(errp, "Cannot meet constraints with align %" PRIu64,
>> +                   s->align);
> 
> Why don't you just keep the ret = -EINVAL here and not add it above?
> It's not wrong, I just think it makes the code a bit weird to read.

Because the next patch would then have to add a 'ret = -EINVAL;' prior
to ever other added 'goto out;'.  It's easier to prep ret once, have a
bunch of intermediate gotos, and then have the final...

> 
> Max
> 
>>          goto out;
>>      }
>>
>>      ret = 0;
>> -    goto out;
>> -
>>  out:

...'ret = 0' reachable only on success, but it takes repeating the
pattern in the next patch to see that.

>>      if (ret < 0) {
>>          g_free(s->config_file);
>>
> 
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 0/9] add blkdebug tests
  2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
                   ` (8 preceding siblings ...)
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 9/9] tests: Add coverage for recent block geometry fixes Eric Blake
@ 2017-05-03 19:07 ` Max Reitz
  9 siblings, 0 replies; 20+ messages in thread
From: Max Reitz @ 2017-05-03 19:07 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 2588 bytes --]

On 29.04.2017 21:14, Eric Blake wrote:
> Available as a tag at:
> git fetch git://repo.or.cz/qemu/ericb.git nbd-blkdebug-v11
> 
> Prerequisites: Kevin's block pull request:
> https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg05799.html
> 
> v10 was:
> https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg05227.html
> 
> Since then:
> - Rebase to Kevin's block branch (patches 7, 8)
> - Split series in two - this focuses on just the (relatively stable)
> blkdebug enhancements (v10 6-8, 12-17), and saves the qcow2 fixes
> (v10 1-5, 9-11) for another day [Max]
> - further tweaks to the qemu-io alloc/map commands (patch 1 retitled,
> also affecting patch 2-3)
> 
> 001/9:[down] 'qemu-io: Improve alignment checks'
> 002/9:[0022] [FC] 'qemu-io: Switch 'alloc' command to byte-based length'
> 003/9:[0066] [FC] 'qemu-io: Switch 'map' output to byte-based reporting'
> 004/9:[----] [--] 'blkdebug: Sanity check block layer guarantees'
> 005/9:[----] [--] 'blkdebug: Refactor error injection'
> 006/9:[----] [--] 'blkdebug: Add pass-through write_zero and discard support'
> 007/9:[0004] [FC] 'blkdebug: Simplify override logic'
> 008/9:[0010] [FC] 'blkdebug: Add ability to override unmap geometries'
> 009/9:[----] [-C] 'tests: Add coverage for recent block geometry fixes'
> 
> Eric Blake (9):
>   qemu-io: Improve alignment checks
>   qemu-io: Switch 'alloc' command to byte-based length
>   qemu-io: Switch 'map' output to byte-based reporting
>   blkdebug: Sanity check block layer guarantees
>   blkdebug: Refactor error injection
>   blkdebug: Add pass-through write_zero and discard support
>   blkdebug: Simplify override logic
>   blkdebug: Add ability to override unmap geometries
>   tests: Add coverage for recent block geometry fixes
> 
>  qapi/block-core.json              |  33 ++++-
>  block/blkdebug.c                  | 266 +++++++++++++++++++++++++++++++-------
>  qemu-io-cmds.c                    |  61 +++++----
>  tests/qemu-iotests/019.out        |   8 +-
>  tests/qemu-iotests/102.out        |   4 +-
>  tests/qemu-iotests/146.out        |  30 ++---
>  tests/qemu-iotests/177            | 114 ++++++++++++++++
>  tests/qemu-iotests/177.out        |  49 +++++++
>  tests/qemu-iotests/common.pattern |   2 +-
>  tests/qemu-iotests/group          |   1 +
>  10 files changed, 468 insertions(+), 100 deletions(-)
>  create mode 100755 tests/qemu-iotests/177
>  create mode 100644 tests/qemu-iotests/177.out

Thanks, applied to my block branch:

https://github.com/XanClic/qemu/commits/block

Max


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 9/9] tests: Add coverage for recent block geometry fixes
  2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 9/9] tests: Add coverage for recent block geometry fixes Eric Blake
@ 2017-05-05 22:34   ` Max Reitz
  2017-05-05 22:48     ` Eric Blake
  0 siblings, 1 reply; 20+ messages in thread
From: Max Reitz @ 2017-05-05 22:34 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 3906 bytes --]

On 29.04.2017 21:14, Eric Blake wrote:
> Use blkdebug's new geometry constraints to emulate setups that
> have needed past regression fixes: write zeroes asserting
> when running through a loopback block device with max-transfer
> smaller than cluster size, and discard rounding away portions
> of requests not aligned to preferred boundaries.  Also, add
> coverage that the block layer is honoring max transfer limits.
> 
> For now, a single iotest performs all actions, with the idea
> that we can add future blkdebug constraint test cases in the
> same file; but it can be split into multiple iotests if we find
> reason to run one portion of the test in more setups than what
> are possible in the other.
> 
> For reference, the final portion of the test (checking whether
> discard passes as much as possible to the lowest layers of the
> stack) works as follows:
> 
> qemu-io: discard 30M at 80000001, passed to blkdebug
>   blkdebug: discard 511 bytes at 80000001, -ENOTSUP (smaller than
> blkdebug's 512 align)
>   blkdebug: discard 14371328 bytes at 80000512, passed to qcow2
>     qcow2: discard 739840 bytes at 80000512, -ENOTSUP (smaller than
> qcow2's 1M align)
>     qcow2: discard 13M bytes at 77M, succeeds
>   blkdebug: discard 15M bytes at 90M, passed to qcow2
>     qcow2: discard 15M bytes at 90M, succeeds
>   blkdebug: discard 1356800 bytes at 105M, passed to qcow2
>     qcow2: discard 1M at 105M, succeeds
>     qcow2: discard 308224 bytes at 106M, -ENOTSUP (smaller than qcow2's
> 1M align)
>   blkdebug: discard 1 byte at 111457280, -ENOTSUP (smaller than
> blkdebug's 512 align)
> 
> Signed-off-by: Eric Blake <eblake@redhat.com>
> Reviewed-by: Max Reitz <mreitz@redhat.com>
> 
> ---
> v11: rebase to context
> v10: no change, rebase to context
> v9: no change
> v7-v8: not submitted (earlier half of series sent for 2.9)
> v6: rebase to master by renumbering s/175/177/
> v5: rebase to master by renumbering s/173/175/
> v4: clean up some comments, nicer backing file creation, more commit message
> v3: make comments tied more to test at hand, rather than the
> particular hardware that led to the earlier patches being tested
> v2: new patch
> ---
>  tests/qemu-iotests/177     | 114 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/qemu-iotests/177.out |  49 +++++++++++++++++++
>  tests/qemu-iotests/group   |   1 +
>  3 files changed, 164 insertions(+)
>  create mode 100755 tests/qemu-iotests/177
>  create mode 100644 tests/qemu-iotests/177.out
> 
> diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177
> new file mode 100755
> index 0000000..e4ddec7
> --- /dev/null
> +++ b/tests/qemu-iotests/177

[...]

> +echo
> +echo "== verify image content =="
> +
> +function verify_io()
> +{
> +    if ($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" |
> +	    grep "compat: 0.10" > /dev/null); then
> +        # For v2 images, discarded clusters are read from the backing file
> +        discarded=11
> +    else
> +        # Discarded clusters are zeroed for v3 or later
> +        discarded=0
> +    fi
> +
> +    echo read -P 22 0 1000
> +    echo read -P 33 1000 128k
> +    echo read -P 22 132072 7871512
> +    echo read -P 0 8003584 2093056
> +    echo read -P 22 10096640 23457792
> +    echo read -P 0 32M 32M
> +    echo read -P 22 64M 13M
> +    echo read -P $discarded 77M 29M
> +    echo read -P 22 106M 22M
> +}
> +
> +verify_io | $QEMU_IO "$TEST_IMG" | _filter_qemu_io

This conflicts with Fam's image locking series that has been introduced
in the meantime (and unfortunately I'm the one who has to base his block
queue on Kevin's...). I suppose it's because the qemu_io process is
launched before the qemu_img info process.

Simply adding an -r to the qemu_io command fixes this, however. I'll do
so in my branch, assuming you're OK with that. :-)

Max


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v11 9/9] tests: Add coverage for recent block geometry fixes
  2017-05-05 22:34   ` Max Reitz
@ 2017-05-05 22:48     ` Eric Blake
  0 siblings, 0 replies; 20+ messages in thread
From: Eric Blake @ 2017-05-05 22:48 UTC (permalink / raw)
  To: Max Reitz, qemu-devel; +Cc: kwolf, qemu-block

[-- Attachment #1: Type: text/plain, Size: 1419 bytes --]

On 05/05/2017 05:34 PM, Max Reitz wrote:
> On 29.04.2017 21:14, Eric Blake wrote:
>> Use blkdebug's new geometry constraints to emulate setups that
>> have needed past regression fixes: write zeroes asserting
>> when running through a loopback block device with max-transfer
>> smaller than cluster size, and discard rounding away portions
>> of requests not aligned to preferred boundaries.  Also, add
>> coverage that the block layer is honoring max transfer limits.
>>

>> +function verify_io()
>> +{
>> +    if ($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" |

>> +
>> +verify_io | $QEMU_IO "$TEST_IMG" | _filter_qemu_io
> 
> This conflicts with Fam's image locking series that has been introduced
> in the meantime (and unfortunately I'm the one who has to base his block
> queue on Kevin's...). I suppose it's because the qemu_io process is
> launched before the qemu_img info process.

Indeed. My test was heavily modeled after 046; there, our solution
(currently commit 64ace79 on Kevin's tree) was to add -U, not -r.

> 
> Simply adding an -r to the qemu_io command fixes this, however. I'll do
> so in my branch, assuming you're OK with that. :-)

I'd lean towards -U, but yes, I'm fine if you make whatever one-line
tweak is needed to obey the rules.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2017-05-05 22:48 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-29 19:14 [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Eric Blake
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 1/9] qemu-io: Improve alignment checks Eric Blake
2017-04-29 22:39   ` Philippe Mathieu-Daudé
2017-05-03 18:42   ` Max Reitz
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 2/9] qemu-io: Switch 'alloc' command to byte-based length Eric Blake
2017-05-03 18:44   ` Max Reitz
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 3/9] qemu-io: Switch 'map' output to byte-based reporting Eric Blake
2017-05-03 18:54   ` Max Reitz
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 4/9] blkdebug: Sanity check block layer guarantees Eric Blake
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 5/9] blkdebug: Refactor error injection Eric Blake
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 6/9] blkdebug: Add pass-through write_zero and discard support Eric Blake
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 7/9] blkdebug: Simplify override logic Eric Blake
2017-05-03 18:59   ` Max Reitz
2017-05-03 19:01     ` Max Reitz
2017-05-03 19:03     ` Eric Blake
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 8/9] blkdebug: Add ability to override unmap geometries Eric Blake
2017-04-29 19:14 ` [Qemu-devel] [PATCH v11 9/9] tests: Add coverage for recent block geometry fixes Eric Blake
2017-05-05 22:34   ` Max Reitz
2017-05-05 22:48     ` Eric Blake
2017-05-03 19:07 ` [Qemu-devel] [PATCH v11 0/9] add blkdebug tests Max Reitz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.