All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/27] Block layer patches
@ 2019-02-01 16:34 Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 01/27] mirror: Release the dirty bitmap if mirror_start_job() fails Kevin Wolf
                   ` (31 more replies)
  0 siblings, 32 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

The following changes since commit cfe6c547690b06fbce54a6d0f7b05dd7f18e36ea:

  Merge remote-tracking branch 'remotes/xanclic/tags/pull-block-2019-01-31' into staging (2019-01-31 19:26:09 +0000)

are available in the Git repository at:

  git://repo.or.cz/qemu/kevin.git tags/for-upstream

for you to fetch changes up to 7471a649fc3a391dd497297013fb2525ca9821ba:

  scsi-disk: Add device_id property (2019-02-01 13:48:11 +0100)

----------------------------------------------------------------
Block layer patches:

- vmdk: Support for blockdev-create
- block: Apply auto-read-only for ro-whitelist drivers
- virtio-scsi: Fixes related to attaching/detaching iothreads
- scsi-disk: Fixed erroneously detected multipath setup with multiple
  disks created with node-names. Added device_id property.
- block: Fix hangs in synchronous APIs with iothreads
- block: Fix invalidate_cache error path for parent activation
- block-backend, mirror, qcow2, vpc, vdi, qemu-iotests:
  Minor fixes and code improvements

----------------------------------------------------------------
Alberto Garcia (7):
      mirror: Release the dirty bitmap if mirror_start_job() fails
      mirror: Block the source BlockDriverState in mirror_start_job()
      qcow2: Assert that refcount block offsets fit in the refcount table
      virtio-scsi: Move BlockBackend back to the main AioContext on unplug
      scsi-disk: Acquire the AioContext in scsi_*_realize()
      virtio-scsi: Forbid devices with different iothreads sharing a blockdev
      qtest.py: Wait for the result of qtest commands

Fam Zheng (3):
      vmdk: Refactor vmdk_create_extent
      vmdk: Implement .bdrv_co_create callback
      iotests: Filter cid numbers in VMDK extent info

John Snow (1):
      iotests/236: fix transaction kwarg order

Kevin Wolf (7):
      block: Fix hangs in synchronous APIs with iothreads
      iotests: Add VMDK tests for blockdev-create
      vmdk: Reject excess extents in blockdev-create
      block: Apply auto-read-only for ro-whitelist drivers
      block: Fix invalidate_cache error path for parent activation
      scsi-disk: Don't use empty string as device id
      scsi-disk: Add device_id property

Markus Armbruster (2):
      block: Replace qdict_put() by qdict_put_obj() where appropriate
      block: Eliminate the S_1KiB, S_2KiB, ... macros

Max Reitz (2):
      iotests: Make 234 stable
      iotests: Filter second BLOCK_JOB_ERROR from 229

Peter Maydell (3):
      block/vpc: Don't take address of fields in packed structs
      block/vdi: Don't take address of fields in packed structs
      uuid: Make qemu_uuid_bswap() take and return a QemuUUID

Thomas Huth (1):
      block: Remove blk_attach_dev_legacy() / legacy_dev code

yuchenlin (1):
      qemu-iotests: add test case for dmg

 qapi/block-core.json                               |  71 +++
 qapi/qapi-schema.json                              |  16 +-
 block/qcow2.h                                      |  10 +-
 include/qemu/units.h                               |  73 ---
 include/qemu/uuid.h                                |   2 +-
 include/sysemu/block-backend.h                     |   5 +-
 block.c                                            |  27 +-
 block/blklogwrites.c                               |   5 +-
 block/block-backend.c                              |  59 +--
 block/io.c                                         |   8 +-
 block/mirror.c                                     |  11 +
 block/nbd-client.c                                 |   1 +
 block/nvme.c                                       |   1 +
 block/qcow2-refcount.c                             |   3 +
 block/qcow2.c                                      |   1 +
 block/qed.c                                        |   1 +
 block/vdi.c                                        |  57 ++-
 block/vmdk.c                                       | 532 +++++++++++++++------
 block/vpc.c                                        |   4 +-
 hw/acpi/vmgenid.c                                  |   6 +-
 hw/scsi/scsi-disk.c                                |  59 ++-
 hw/scsi/virtio-scsi.c                              |  13 +
 tests/test-block-iothread.c                        | 372 ++++++++++++++
 tests/vmgenid-test.c                               |   2 +-
 util/uuid.c                                        |  10 +-
 scripts/qtest.py                                   |   6 +
 tests/Makefile.include                             |   2 +
 tests/qemu-iotests/141.out                         |   4 +-
 tests/qemu-iotests/229                             |   6 +-
 tests/qemu-iotests/229.out                         |   1 -
 tests/qemu-iotests/234                             |  56 ++-
 tests/qemu-iotests/234.out                         |  10 +-
 tests/qemu-iotests/236.out                         |  56 +--
 tests/qemu-iotests/237                             | 237 +++++++++
 tests/qemu-iotests/237.out                         | 348 ++++++++++++++
 tests/qemu-iotests/239                             |  53 ++
 tests/qemu-iotests/239.out                         |   4 +
 tests/qemu-iotests/240                             | 129 +++++
 tests/qemu-iotests/240.out                         |  54 +++
 tests/qemu-iotests/check                           |   7 +
 tests/qemu-iotests/common.filter                   |   1 +
 tests/qemu-iotests/group                           |   3 +
 tests/qemu-iotests/iotests.py                      |  22 +-
 .../qemu-iotests/sample_images/simple-dmg.dmg.bz2  | Bin 0 -> 3479 bytes
 44 files changed, 1931 insertions(+), 417 deletions(-)
 create mode 100644 tests/test-block-iothread.c
 create mode 100755 tests/qemu-iotests/237
 create mode 100644 tests/qemu-iotests/237.out
 create mode 100755 tests/qemu-iotests/239
 create mode 100644 tests/qemu-iotests/239.out
 create mode 100755 tests/qemu-iotests/240
 create mode 100644 tests/qemu-iotests/240.out
 create mode 100644 tests/qemu-iotests/sample_images/simple-dmg.dmg.bz2

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

* [Qemu-devel] [PULL 01/27] mirror: Release the dirty bitmap if mirror_start_job() fails
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
@ 2019-02-01 16:34 ` Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 02/27] mirror: Block the source BlockDriverState in mirror_start_job() Kevin Wolf
                   ` (30 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Alberto Garcia <berto@igalia.com>

At the moment I don't see how to make this function fail after the
dirty bitmap has been created, but if that was possible then we would
hit the assert(QLIST_EMPTY(&bs->dirty_bitmaps)) in bdrv_close().

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/mirror.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/mirror.c b/block/mirror.c
index 24ede6fdaa..4cf1c088c0 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1649,6 +1649,9 @@ fail:
         g_free(s->replaces);
         blk_unref(s->target);
         bs_opaque->job = NULL;
+        if (s->dirty_bitmap) {
+            bdrv_release_dirty_bitmap(bs, s->dirty_bitmap);
+        }
         job_early_fail(&s->common.job);
     }
 
-- 
2.20.1

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

* [Qemu-devel] [PULL 02/27] mirror: Block the source BlockDriverState in mirror_start_job()
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 01/27] mirror: Release the dirty bitmap if mirror_start_job() fails Kevin Wolf
@ 2019-02-01 16:34 ` Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 03/27] qcow2: Assert that refcount block offsets fit in the refcount table Kevin Wolf
                   ` (29 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Alberto Garcia <berto@igalia.com>

The mirror_start_job() function used for the commit-active job blocks
the source, target and all intermediate nodes for the duration of the
job.

   target <- intermediate <- source

Since 4ef85a9c2339 this function creates a dummy mirror_top_bs that
goes on top of the source node, and it is this dummy node that gets
blocked instead. The source node is never blocked or added to the
job's list of nodes.

   target <- intermediate <- source <- mirror_top

At the moment I don't think it is possible to exploit this problem
because any additional job on 'source' would either be forbidden for
other reasons or it would need to involve an additional node that is
blocked, causing an error.

This can be seen in the error messages, however, because they never
refer to the source node being blocked:

  $ qemu-img create -f qcow2 hd0.qcow2 1M
  $ qemu-img create -f qcow2 -b hd0.qcow2 hd1.qcow2
  $ qemu-io -c 'write 0 1M' hd0.qcow2
  $ $QEMU -drive if=none,file=hd1.qcow2,node-name=hd1
  { "execute": "qmp_capabilities" }
  { "execute": "block-commit", "arguments": {"device": "hd1", "speed": 256}}
  { "execute": "block-stream", "arguments": {"device": "hd1"}}
  { "error": {"class": "GenericError",
    "desc": "Node 'hd0' is busy: block device is in use by block job: commit"}}

After this patch the error message refers to 'hd1', as it should.

The expected output of iotest 141 also needs to be updated for the
same reason.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/mirror.c             | 8 ++++++++
 tests/qemu-iotests/141.out | 4 ++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index 4cf1c088c0..b67b0120f8 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1612,6 +1612,14 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
         goto fail;
     }
 
+    ret = block_job_add_bdrv(&s->common, "source", bs, 0,
+                             BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
+                             BLK_PERM_CONSISTENT_READ,
+                             errp);
+    if (ret < 0) {
+        goto fail;
+    }
+
     /* Required permissions are already taken with blk_new() */
     block_job_add_bdrv(&s->common, "target", target, 0, BLK_PERM_ALL,
                        &error_abort);
diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
index f252c86875..41c7291258 100644
--- a/tests/qemu-iotests/141.out
+++ b/tests/qemu-iotests/141.out
@@ -28,7 +28,7 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
 {"return": {}}
-{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
+{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
@@ -45,7 +45,7 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
 {"return": {}}
-{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
+{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
-- 
2.20.1

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

* [Qemu-devel] [PULL 03/27] qcow2: Assert that refcount block offsets fit in the refcount table
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 01/27] mirror: Release the dirty bitmap if mirror_start_job() fails Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 02/27] mirror: Block the source BlockDriverState in mirror_start_job() Kevin Wolf
@ 2019-02-01 16:34 ` Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 04/27] qemu-iotests: add test case for dmg Kevin Wolf
                   ` (28 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Alberto Garcia <berto@igalia.com>

Refcount table entries have a field to store the offset of the
refcount block. The rest of the bits of the entry are currently
reserved.

The offset is always taken from the entry using REFT_OFFSET_MASK to
ensure that we only use the bits that belong to that field.

While that mask is used every time we read from the refcount table, it
is never used when we write to it. Due to the other constraints of the
qcow2 format QEMU can never produce refcount block offsets that don't
fit in that field so any such offset when allocating a refcount block
would indicate a bug in QEMU.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-refcount.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 1c63ac244a..6f13d470d3 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -368,6 +368,9 @@ static int alloc_refcount_block(BlockDriverState *bs,
         return new_block;
     }
 
+    /* The offset must fit in the offset field of the refcount table entry */
+    assert((new_block & REFT_OFFSET_MASK) == new_block);
+
     /* If we're allocating the block at offset 0 then something is wrong */
     if (new_block == 0) {
         qcow2_signal_corruption(bs, true, -1, -1, "Preventing invalid "
-- 
2.20.1

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

* [Qemu-devel] [PULL 04/27] qemu-iotests: add test case for dmg
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (2 preceding siblings ...)
  2019-02-01 16:34 ` [Qemu-devel] [PULL 03/27] qcow2: Assert that refcount block offsets fit in the refcount table Kevin Wolf
@ 2019-02-01 16:34 ` Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 05/27] block: Replace qdict_put() by qdict_put_obj() where appropriate Kevin Wolf
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: yuchenlin <npes87184@gmail.com>

Recently, some bugs in dmg file have been fixed. To prevent reading dmg
is broken someday in the future, add a simple test which ensures the
conversion from dmg to raw should not hang or face any I/O error.

Signed-off-by: yuchenlin <npes87184@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/239                        |  53 ++++++++++++++++++
 tests/qemu-iotests/239.out                    |   4 ++
 tests/qemu-iotests/check                      |   7 +++
 tests/qemu-iotests/group                      |   1 +
 .../sample_images/simple-dmg.dmg.bz2          | Bin 0 -> 3479 bytes
 5 files changed, 65 insertions(+)
 create mode 100755 tests/qemu-iotests/239
 create mode 100644 tests/qemu-iotests/239.out
 create mode 100644 tests/qemu-iotests/sample_images/simple-dmg.dmg.bz2

diff --git a/tests/qemu-iotests/239 b/tests/qemu-iotests/239
new file mode 100755
index 0000000000..6f085d573d
--- /dev/null
+++ b/tests/qemu-iotests/239
@@ -0,0 +1,53 @@
+#!/bin/bash
+#
+# Test case for dmg
+#
+# Copyright (C) 2019 yuchenlin <npes87184@gmail.com>
+#
+# 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=npes87184@gmail.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1	# failure is the default!
+
+_cleanup()
+{
+    rm -f "$TEST_IMG.raw"
+    _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+
+_supported_fmt dmg
+_supported_proto file
+_supported_os Linux
+
+echo
+echo "== Testing conversion to raw should success =="
+_use_sample_img simple-dmg.dmg.bz2
+if ! $QEMU_IMG convert -f $IMGFMT -O raw "$TEST_IMG" "$TEST_IMG.raw" ; then
+    exit 1
+fi
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/239.out b/tests/qemu-iotests/239.out
new file mode 100644
index 0000000000..bedbad065b
--- /dev/null
+++ b/tests/qemu-iotests/239.out
@@ -0,0 +1,4 @@
+QA output created by 239
+
+== Testing conversion to raw should success ==
+*** done
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 89ed275988..895e1e3dcb 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -237,6 +237,7 @@ image format options
     -vhdx               test vhdx
     -vmdk               test vmdk
     -luks               test luks
+    -dmg                test dmg
 
 image protocol options
     -file               test file (default)
@@ -304,6 +305,12 @@ testlist options
             xpand=false
             ;;
 
+        -dmg)
+            IMGFMT=dmg
+            IMGFMT_GENERIC=false
+            xpand=false
+            ;;
+
         -qed)
             IMGFMT=qed
             xpand=false
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 0f1c3f9cdf..3e310c7f87 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -235,3 +235,4 @@
 235 auto quick
 236 auto quick
 238 auto quick
+239 rw auto quick
diff --git a/tests/qemu-iotests/sample_images/simple-dmg.dmg.bz2 b/tests/qemu-iotests/sample_images/simple-dmg.dmg.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..05e719d03d48d6df4f0e995dd8bae1ce54c9f5f0
GIT binary patch
literal 3479
zcmV;I4QTR0T4*^jL0KkKS(36)s{k7pfB*mg|NsC0|NsC0|NsC0|NsC0|Ns5}|NsC0
z|NsC0|Nr0#eji@i`+e|w_jjtUioUNn9=bhi?FYz+8lea^Pt`n6Q`GfM=uI^|rccqR
z#)^4QQ(&j0^vx-<6U8+BMo&{rPgMO9KU6<bdYee{L&A*HX-%dfJg1{mX^f|mdZ(%S
zYHDfZWgn$BPgL<R4Jqj~+M0TvOq0bPDe8Glf++<WdYU|=X+1Rn(<i9%Lp2zh4IZY3
zjXgCzA?gg9Q$~!`&}h@t^qy1H^iL_WjXgCzK-!HSQ%^=sO&L8COn}g7>K>tx+G-x7
zKxhH7gFqfr)EbhWqfmN7Xqi0_(|U$T%^~Te(<9O!s(P57)gFnX(HMqCnW^apCLkWB
zfB?c`7=Y8$P|yP*p{9YL8X6e}jSLZ{Kmat*Y9I=F1s<p9DB4Cq^#`bE4Ff^74GlCj
z05tUmngG$D8fXFP0MPXVMoj}i&;S4$8UdgN)B`|zgFpae5-JoYqMnhSqz_5zX!RaX
zN@?n8p`%8PJdIB%dW@MKrbdHIo}+1?O{io&O{DTNL5K|i44$J2gHSf0dW_JG15ZRS
zO#>jv(V%IjnFNxA1T<(7k~Y;aPez3F!fB&IWZEW%)byHqn^PtYN0c*2G<pJPF%2|&
zjXg~oX{V%Vqb8bZplqPgw1%2w9-*VtQR*}r00xGQ4G24kA+jG=o`xW*WTQp80#*@D
zGI^@e0Fq218g7gWKQ0-!!d?<+0Zg$VQi&#k#L$@->*ZllN2a;wYb5Z@K!FpiLKS04
zAXF_RNbYzNTvjprs6=NSa4=(xVBCm>1#>twBnc>5NRuJv+UXVcw)$K?45Ra5gMtys
z5#=tTi{6o_Dolm>AW0*9z$7i33Gt*7^pYSUXUfIy=|9=(Y5F2D)W#);#I!)dBq)W~
zrFlJ*pf<%<p!?|?K4A)WKmn>vEyY-2j;_z6FzSi8mQn!dfdGLU#z+u}O%{xk@FlI`
z^B@Tz!-52v0~!WxwY>yM5j2L!wDW07lb>SjKuGF1Bv7*3#(>;&j=WH?%<2(%C(%mi
z3SK&{tsN6|F+h=$fRF|SAT&YV;=$CM8UPyf&KPGXD@;hw?Ie+ur$Ms`<R|DnF>?n=
z=TVuCRg<`%CTS#rC3Rqi{8+-#G7{}$If&w>{u-}tqnXQGZ1vrDn(W+-ydtwD_5(m9
zUlJm4YF$|a547Ok)VNY_1&|O<rL!z~wcz}tQxE~Dj4cXB5;0mM5(lt%*IA;POn}RT
z;6QRRmFhId9Am|k#g{Q@hX6cXxi&WKM_|eXL97PF^DAB*Vbz~zQKTvZ??`1m>?|T)
z42v8J{j@}JBoR7501!b0TQLa}5=%fGiZ01vc2PsfW3IL_R4y29^38$G<bvvm5nFd0
zCwO?LU{=bViG0S0Zh^;{@n#!Kdu|V}*6A@n-bN2myQ=@_`vaVL_~0ObLdRRH{)&n2
zWjQqZq-v&|Sm)GU$5#3E-aM@MWEDTSJ=WXyvX!Ka^MIpH)wR_6>N@}eFEu8;#~W3O
zhYo*p2)1qo0FWCdNC$P6JWDI)lRL3RsCq~;CddNVfDeUAK|}zQbl`V}JlvEcUSn8M
zpVIf%kFZ>u>OO0J!nRehCj34b&G%X*%F`iNsN=6_pV&CdsRu0CM-x>qqFshZ5Cm<o
zjS+4gAk-oc*IeI*Cm4uELVya|XwQV9;aJZ7Mzx<=On?m(0@tY~UQVHbY{wZn;D)7@
z(k#N&X0YCEm2rAN!X56ASS+#z7ao9>#cE(tAoIY<O8RkL;gL@lE`rM`9JnB2CEx^z
z6c8i@0n%FhZje3Zxg#iF@R@T1Isa_wb*LjCgn+!DWDcYQh#WxZLepa#PQjgE{rMz?
zBq1<j2VVpX$Xd;K6V+q_hhHJtdWTbjuPi#R=(f&lykmQl$pDZgP%wm~nI*Ni#z^FO
zE-eT!OaQHD1y1DHB8`9}p<+T&reFk;4s}MH%)0IXH1auiL(e%0z#SY_Q4bA>;2;n;
z>6lWK8VC|iQ`TBT@eh_haUvW?s0F~|jWOEDBrNGaBoJh|LX9lsM4vqVlOYszX7pdA
z{D&2t%ysWP&xa%2Q6LEk#Gf-=1UdvZ5a1%=kY@b_PJ?B`u>CaLI&B7em_7b|;n=Za
zp~fR)pUI5+fvC#Km(lVCNpb=XW#mzCYrKf$7gM(TqYzYBKqz54qqz-xcv$fGQrdYy
zRD%pqsY(=-5JXlPYst2Xv=#sccTUb6A-KFq8XNZ`G)4wExi9zHxBO=zO;AbFM}`M!
zOk?+aXaO;H02oI0Bn>Mv09F(z2D>5BS#O#$P6Hjd6boVGU|fj(_>6Wj@RrKIn;8EB
zble1^sy2Z1#DvynHzELF0f+`WC;nB6;l*sYRsG&{OT)PkEN{C-fC@>voA`)pYKBGR
zy0qd5hS(-IOAKl(iXY}a|K}p1?TmbyuKT-Qeer)gFKD88^Tpxr*kmLy;0FL}C&d#`
zQ|v00fv3#W*mSyZs|-K<h+d6pNO}MT^KN@JOgvk`m2@p1X~U$!#uswfANXB%a*2}d
zwEVT6lZMv@K`D!LB_I^fo)latwZp8vy|3yBt&R41ACiQf!d~t-ftA7uBb30|`l#aR
zSAZd~7y#5rmLOyX5*DtKB=1^~pw$7YjAzU-OkBe`h(K#GCV;6Q6}-9*#6ZQEesARr
zwQh_HsY@9IS)I<~d1n7@4@41T%tXY@5h1NOcGB0n$$P2^q!Iwg96-Ypa~Me&Mkg03
zx4>{zsMn+fmSxpq9<;PGzUke*7{Vc;ba?~~Fp@>uleN{!WoS8VmG%z%nuX9{w6QC^
z>cY}_BnH5wp)m6ur<d4axiRctR|XVPR-dd0=6w1P3>Z5+Eu`$-#pj&flXy9V9wq!p
zo^)}9fQDYjW6Ab;cYA9~3Cm@szFUBpm=2bWB#w0?id*4t_2g7y|0*g1ylSPW9s834
ztjELX^xWJGpL*3Qc>%uRKQna>8~ayaq=0g~k?u90E|+R&pb}xi6sAxgk{0I9Tdk7g
zC&mCT7%%O`$bs$IGS?S?7$DVck$e==@QS_=nF(o3(InF7Dn=3k=Ls-^Fw9D7{(U3k
zK*%{w#OE;-n}5J@QnW~k0W^>q6Frr!p|88#+Wy;ioe~<*h=i%&J;)%alO@Pegg+7j
zs``QTeEyD)x7p(92)N`E@8T8H#s^c%*24OW;aGvPuVQef*wBsRpU@6A_g9zdDt9$k
z2zRm#rdLi0A^}Fb?sXZ{X@%WaZzShTNF-5=Fu)3i@t^qa`TwT<VRADXi9j*Cww!Bk
z$ofZn`qc*}gV@O>ucE88qh>EN`Jdw+s*<*u-@$9+o1#_6XJ989lqI=az!E}P5riY*
zHPwYH$BT`e?rVGc3nGpD(|bD_E!3{ti_*;NZZ0isXL2=SVRX$Ti~X!dedY#W1K<$#
zh_IvD035p;=Ek~DC$}ZJd(G3-dd#k6CG#xgT;mmS6+SLid1tQO-9<Sl@O^GuLUz-u
z417&euHAlM4ypAfeUp|&``-9llf#`5`nX06abKLfN@~l%nAq{U{u*UfSI+fFc$+Nq
zjSkQ*mer2Rs5nuStK%0w;knBzMKh|{QO!^DPwP)t^4~w3qnO*hZDo{4^>~P#9iv%f
zd!`qvbczBF)AAe0yE+WI*}DYOL2J~*ZCc}JWiu0LShw&6`-5`^SkNJY!gsi|e-MHy
zZlN9Lb5NbuT7S&4oY6v}13BpeQ|?u0c*7n)Ku*p%ZDF?$7zjKXj(9#K?tO1dMW=8&
z;MDsGo0=CLWp{b5$Kk0kxAl*^l^ziX<28c4->Ed%#N16IrySH$q`4%gn}5ksr>_0H
zs-;Y4Bb7U_pNGMK075wJ%DahB2ArR=jC`2UWMe`ID;mPgA25l6GVc9>Rqybi7N6(i
z3BcjbfprP7Ivcy%+Vs~Z6Hw>JB!kJcD>mdTThTpO$(fg`Ds7pY<YTYWgmqU8=Xlve
zCriGy+iG;z+{{27v*;>N4BN<|%(+#T+h1sdgPjUAWN73ki+$-%j_&6PZ$I2$HnSEa
zQ?n{BB*A3zmlLHvH@o+ZJm1NSC9(?ka<7OppIcAi{V`Nj+^8SL!ywYLI$v(ivC_){
z5anb)=MQS%<PN>hUHR@_HKDhdDPf*Hm`w^E{GT!Yq<}Hg8Ia{?PyA70;yx8nD^~B|
zjuGESS<A^!S2=(y_Dz2Z3)U+>*z1(bcT1?|;LuVOg&xLebEk(1uB(fZJN&W3!xADj
zQD;ugVYYpOt=NBu$Bi07WcepgHm6q}1y>vxs^oJetK;=ix$9i9M#>O`?6X2pJoXi;
z#0mlFG2eK~z-yqErVC2`l5B&)s}jKZMRZxCyQ0^?cp$L5J>4{eoCysx+#X0J?r^+C
z#R8d5A5=5V#(QMr1?kT}qh|eQ8{a94K6_Sq=vcWz&WH@!TREj$F3%=NwMQ3YR-$or
zlXmr#8-D_(N;#e;g#CE1WYh8byF-ojSdtGh>P8pbz39Ew5qWHa^1-M77ji{7P>_<c
FP^-7hd6WPE

literal 0
HcmV?d00001

-- 
2.20.1

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

* [Qemu-devel] [PULL 05/27] block: Replace qdict_put() by qdict_put_obj() where appropriate
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (3 preceding siblings ...)
  2019-02-01 16:34 ` [Qemu-devel] [PULL 04/27] qemu-iotests: add test case for dmg Kevin Wolf
@ 2019-02-01 16:34 ` Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 06/27] block: Fix hangs in synchronous APIs with iothreads Kevin Wolf
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Markus Armbruster <armbru@redhat.com>

Patch created mechanically by rerunning:

  $  spatch --sp-file scripts/coccinelle/qobject.cocci \
	    --macro-file scripts/cocci-macro-file.h \
	    --dir block --in-place

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/blklogwrites.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/block/blklogwrites.c b/block/blklogwrites.c
index ff98cd5533..d2e01bdb1d 100644
--- a/block/blklogwrites.c
+++ b/block/blklogwrites.c
@@ -295,10 +295,9 @@ static void blk_log_writes_refresh_filename(BlockDriverState *bs,
         qdict_put_str(opts, "driver", "blklogwrites");
 
         qobject_ref(bs->file->bs->full_open_options);
-        qdict_put_obj(opts, "file", QOBJECT(bs->file->bs->full_open_options));
+        qdict_put(opts, "file", bs->file->bs->full_open_options);
         qobject_ref(s->log_file->bs->full_open_options);
-        qdict_put_obj(opts, "log",
-                      QOBJECT(s->log_file->bs->full_open_options));
+        qdict_put(opts, "log", s->log_file->bs->full_open_options);
         qdict_put_int(opts, "log-sector-size", s->sectorsize);
 
         bs->full_open_options = opts;
-- 
2.20.1

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

* [Qemu-devel] [PULL 06/27] block: Fix hangs in synchronous APIs with iothreads
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (4 preceding siblings ...)
  2019-02-01 16:34 ` [Qemu-devel] [PULL 05/27] block: Replace qdict_put() by qdict_put_obj() where appropriate Kevin Wolf
@ 2019-02-01 16:34 ` Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 07/27] iotests: Make 234 stable Kevin Wolf
                   ` (25 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

In the block layer, synchronous APIs are often implemented by creating a
coroutine that calls the asynchronous coroutine-based implementation and
then waiting for completion with BDRV_POLL_WHILE().

For this to work with iothreads (more specifically, when the synchronous
API is called in a thread that is not the home thread of the block
device, so that the coroutine will run in a different thread), we must
make sure to call aio_wait_kick() at the end of the operation. Many
places are missing this, so that BDRV_POLL_WHILE() keeps hanging even if
the condition has long become false.

Note that bdrv_dec_in_flight() involves an aio_wait_kick() call. This
corresponds to the BDRV_POLL_WHILE() in the drain functions, but it is
generally not enough for most other operations because they haven't set
the return value in the coroutine entry stub yet. To avoid race
conditions there, we need to kick after setting the return value.

The race window is small enough that the problem doesn't usually surface
in the common path. However, it does surface and causes easily
reproducible hangs if the operation can return early before even calling
bdrv_inc/dec_in_flight, which many of them do (trivial error or no-op
success paths).

The bug in bdrv_truncate(), bdrv_check() and bdrv_invalidate_cache() is
slightly different: These functions even neglected to schedule the
coroutine in the home thread of the node. This avoids the hang, but is
obviously wrong, too. Fix those to schedule the coroutine in the right
AioContext in addition to adding aio_wait_kick() calls.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c                     |   6 +-
 block/block-backend.c       |   5 +
 block/io.c                  |   8 +-
 block/nbd-client.c          |   1 +
 block/nvme.c                |   1 +
 block/qcow2.c               |   1 +
 block/qed.c                 |   1 +
 tests/test-block-iothread.c | 372 ++++++++++++++++++++++++++++++++++++
 tests/Makefile.include      |   2 +
 9 files changed, 394 insertions(+), 3 deletions(-)
 create mode 100644 tests/test-block-iothread.c

diff --git a/block.c b/block.c
index e795a7c5de..0c5d1f11a5 100644
--- a/block.c
+++ b/block.c
@@ -3725,6 +3725,7 @@ static void bdrv_check_co_entry(void *opaque)
 {
     CheckCo *cco = opaque;
     cco->ret = bdrv_co_check(cco->bs, cco->res, cco->fix);
+    aio_wait_kick();
 }
 
 int bdrv_check(BlockDriverState *bs,
@@ -3743,7 +3744,7 @@ int bdrv_check(BlockDriverState *bs,
         bdrv_check_co_entry(&cco);
     } else {
         co = qemu_coroutine_create(bdrv_check_co_entry, &cco);
-        qemu_coroutine_enter(co);
+        bdrv_coroutine_enter(bs, co);
         BDRV_POLL_WHILE(bs, cco.ret == -EINPROGRESS);
     }
 
@@ -4708,6 +4709,7 @@ static void coroutine_fn bdrv_invalidate_cache_co_entry(void *opaque)
     InvalidateCacheCo *ico = opaque;
     bdrv_co_invalidate_cache(ico->bs, ico->errp);
     ico->done = true;
+    aio_wait_kick();
 }
 
 void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
@@ -4724,7 +4726,7 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
         bdrv_invalidate_cache_co_entry(&ico);
     } else {
         co = qemu_coroutine_create(bdrv_invalidate_cache_co_entry, &ico);
-        qemu_coroutine_enter(co);
+        bdrv_coroutine_enter(bs, co);
         BDRV_POLL_WHILE(bs, !ico.done);
     }
 }
diff --git a/block/block-backend.c b/block/block-backend.c
index cf05abd89d..f0be0d9039 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1220,6 +1220,7 @@ static void blk_read_entry(void *opaque)
 
     rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, qiov->size,
                               qiov, rwco->flags);
+    aio_wait_kick();
 }
 
 static void blk_write_entry(void *opaque)
@@ -1229,6 +1230,7 @@ static void blk_write_entry(void *opaque)
 
     rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, qiov->size,
                                qiov, rwco->flags);
+    aio_wait_kick();
 }
 
 static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
@@ -1540,6 +1542,7 @@ static void blk_ioctl_entry(void *opaque)
 
     rwco->ret = blk_co_ioctl(rwco->blk, rwco->offset,
                              qiov->iov[0].iov_base);
+    aio_wait_kick();
 }
 
 int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
@@ -1586,6 +1589,7 @@ static void blk_flush_entry(void *opaque)
 {
     BlkRwCo *rwco = opaque;
     rwco->ret = blk_co_flush(rwco->blk);
+    aio_wait_kick();
 }
 
 int blk_flush(BlockBackend *blk)
@@ -2018,6 +2022,7 @@ static void blk_pdiscard_entry(void *opaque)
     QEMUIOVector *qiov = rwco->iobuf;
 
     rwco->ret = blk_co_pdiscard(rwco->blk, rwco->offset, qiov->size);
+    aio_wait_kick();
 }
 
 int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
diff --git a/block/io.c b/block/io.c
index bd9d688f8b..213ca03d8d 100644
--- a/block/io.c
+++ b/block/io.c
@@ -806,6 +806,7 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
                                     rwco->qiov->size, rwco->qiov,
                                     rwco->flags);
     }
+    aio_wait_kick();
 }
 
 /*
@@ -2279,6 +2280,7 @@ static void coroutine_fn bdrv_block_status_above_co_entry(void *opaque)
                                            data->offset, data->bytes,
                                            data->pnum, data->map, data->file);
     data->done = true;
+    aio_wait_kick();
 }
 
 /*
@@ -2438,6 +2440,7 @@ static void coroutine_fn bdrv_co_rw_vmstate_entry(void *opaque)
 {
     BdrvVmstateCo *co = opaque;
     co->ret = bdrv_co_rw_vmstate(co->bs, co->qiov, co->pos, co->is_read);
+    aio_wait_kick();
 }
 
 static inline int
@@ -2559,6 +2562,7 @@ static void coroutine_fn bdrv_flush_co_entry(void *opaque)
     FlushCo *rwco = opaque;
 
     rwco->ret = bdrv_co_flush(rwco->bs);
+    aio_wait_kick();
 }
 
 int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
@@ -2704,6 +2708,7 @@ static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
     DiscardCo *rwco = opaque;
 
     rwco->ret = bdrv_co_pdiscard(rwco->child, rwco->offset, rwco->bytes);
+    aio_wait_kick();
 }
 
 int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
@@ -3217,6 +3222,7 @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
     TruncateCo *tco = opaque;
     tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->prealloc,
                                 tco->errp);
+    aio_wait_kick();
 }
 
 int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
@@ -3236,7 +3242,7 @@ int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
         bdrv_truncate_co_entry(&tco);
     } else {
         co = qemu_coroutine_create(bdrv_truncate_co_entry, &tco);
-        qemu_coroutine_enter(co);
+        bdrv_coroutine_enter(child->bs, co);
         BDRV_POLL_WHILE(child->bs, tco.ret == NOT_DONE);
     }
 
diff --git a/block/nbd-client.c b/block/nbd-client.c
index 813539676d..50a8dadd85 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -119,6 +119,7 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
     s->quit = true;
     nbd_recv_coroutines_wake_all(s);
     s->read_reply_co = NULL;
+    aio_wait_kick();
 }
 
 static int nbd_co_send_request(BlockDriverState *bs,
diff --git a/block/nvme.c b/block/nvme.c
index 982097b5b1..b5952c9b08 100644
--- a/block/nvme.c
+++ b/block/nvme.c
@@ -390,6 +390,7 @@ static void nvme_cmd_sync_cb(void *opaque, int ret)
 {
     int *pret = opaque;
     *pret = ret;
+    aio_wait_kick();
 }
 
 static int nvme_cmd_sync(BlockDriverState *bs, NVMeQueuePair *q,
diff --git a/block/qcow2.c b/block/qcow2.c
index 4897abae5e..8c91b92865 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1671,6 +1671,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
         /* From bdrv_co_create.  */
         qcow2_open_entry(&qoc);
     } else {
+        assert(qemu_get_current_aio_context() == qemu_get_aio_context());
         qemu_coroutine_enter(qemu_coroutine_create(qcow2_open_entry, &qoc));
         BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
     }
diff --git a/block/qed.c b/block/qed.c
index 9377c0b7ad..1280870024 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -559,6 +559,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
     if (qemu_in_coroutine()) {
         bdrv_qed_open_entry(&qoc);
     } else {
+        assert(qemu_get_current_aio_context() == qemu_get_aio_context());
         qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc));
         BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
     }
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
new file mode 100644
index 0000000000..97ac0b159d
--- /dev/null
+++ b/tests/test-block-iothread.c
@@ -0,0 +1,372 @@
+/*
+ * Block tests for iothreads
+ *
+ * Copyright (c) 2018 Kevin Wolf <kwolf@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "block/block.h"
+#include "block/blockjob_int.h"
+#include "sysemu/block-backend.h"
+#include "qapi/error.h"
+#include "iothread.h"
+
+static int coroutine_fn bdrv_test_co_prwv(BlockDriverState *bs,
+                                          uint64_t offset, uint64_t bytes,
+                                          QEMUIOVector *qiov, int flags)
+{
+    return 0;
+}
+
+static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
+                                              int64_t offset, int bytes)
+{
+    return 0;
+}
+
+static int coroutine_fn
+bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset,
+                      PreallocMode prealloc, Error **errp)
+{
+    return 0;
+}
+
+static int coroutine_fn bdrv_test_co_block_status(BlockDriverState *bs,
+                                                  bool want_zero,
+                                                  int64_t offset, int64_t count,
+                                                  int64_t *pnum, int64_t *map,
+                                                  BlockDriverState **file)
+{
+    *pnum = count;
+    return 0;
+}
+
+static BlockDriver bdrv_test = {
+    .format_name            = "test",
+    .instance_size          = 1,
+
+    .bdrv_co_preadv         = bdrv_test_co_prwv,
+    .bdrv_co_pwritev        = bdrv_test_co_prwv,
+    .bdrv_co_pdiscard       = bdrv_test_co_pdiscard,
+    .bdrv_co_truncate       = bdrv_test_co_truncate,
+    .bdrv_co_block_status   = bdrv_test_co_block_status,
+};
+
+static void test_sync_op_pread(BdrvChild *c)
+{
+    uint8_t buf[512];
+    int ret;
+
+    /* Success */
+    ret = bdrv_pread(c, 0, buf, sizeof(buf));
+    g_assert_cmpint(ret, ==, 512);
+
+    /* Early error: Negative offset */
+    ret = bdrv_pread(c, -2, buf, sizeof(buf));
+    g_assert_cmpint(ret, ==, -EIO);
+}
+
+static void test_sync_op_pwrite(BdrvChild *c)
+{
+    uint8_t buf[512];
+    int ret;
+
+    /* Success */
+    ret = bdrv_pwrite(c, 0, buf, sizeof(buf));
+    g_assert_cmpint(ret, ==, 512);
+
+    /* Early error: Negative offset */
+    ret = bdrv_pwrite(c, -2, buf, sizeof(buf));
+    g_assert_cmpint(ret, ==, -EIO);
+}
+
+static void test_sync_op_blk_pread(BlockBackend *blk)
+{
+    uint8_t buf[512];
+    int ret;
+
+    /* Success */
+    ret = blk_pread(blk, 0, buf, sizeof(buf));
+    g_assert_cmpint(ret, ==, 512);
+
+    /* Early error: Negative offset */
+    ret = blk_pread(blk, -2, buf, sizeof(buf));
+    g_assert_cmpint(ret, ==, -EIO);
+}
+
+static void test_sync_op_blk_pwrite(BlockBackend *blk)
+{
+    uint8_t buf[512];
+    int ret;
+
+    /* Success */
+    ret = blk_pwrite(blk, 0, buf, sizeof(buf), 0);
+    g_assert_cmpint(ret, ==, 512);
+
+    /* Early error: Negative offset */
+    ret = blk_pwrite(blk, -2, buf, sizeof(buf), 0);
+    g_assert_cmpint(ret, ==, -EIO);
+}
+
+static void test_sync_op_load_vmstate(BdrvChild *c)
+{
+    uint8_t buf[512];
+    int ret;
+
+    /* Error: Driver does not support snapshots */
+    ret = bdrv_load_vmstate(c->bs, buf, 0, sizeof(buf));
+    g_assert_cmpint(ret, ==, -ENOTSUP);
+}
+
+static void test_sync_op_save_vmstate(BdrvChild *c)
+{
+    uint8_t buf[512];
+    int ret;
+
+    /* Error: Driver does not support snapshots */
+    ret = bdrv_save_vmstate(c->bs, buf, 0, sizeof(buf));
+    g_assert_cmpint(ret, ==, -ENOTSUP);
+}
+
+static void test_sync_op_pdiscard(BdrvChild *c)
+{
+    int ret;
+
+    /* Normal success path */
+    c->bs->open_flags |= BDRV_O_UNMAP;
+    ret = bdrv_pdiscard(c, 0, 512);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Early success: UNMAP not supported */
+    c->bs->open_flags &= ~BDRV_O_UNMAP;
+    ret = bdrv_pdiscard(c, 0, 512);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Early error: Negative offset */
+    ret = bdrv_pdiscard(c, -2, 512);
+    g_assert_cmpint(ret, ==, -EIO);
+}
+
+static void test_sync_op_blk_pdiscard(BlockBackend *blk)
+{
+    int ret;
+
+    /* Early success: UNMAP not supported */
+    ret = blk_pdiscard(blk, 0, 512);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Early error: Negative offset */
+    ret = blk_pdiscard(blk, -2, 512);
+    g_assert_cmpint(ret, ==, -EIO);
+}
+
+static void test_sync_op_truncate(BdrvChild *c)
+{
+    int ret;
+
+    /* Normal success path */
+    ret = bdrv_truncate(c, 65536, PREALLOC_MODE_OFF, NULL);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Early error: Negative offset */
+    ret = bdrv_truncate(c, -2, PREALLOC_MODE_OFF, NULL);
+    g_assert_cmpint(ret, ==, -EINVAL);
+
+    /* Error: Read-only image */
+    c->bs->read_only = true;
+    c->bs->open_flags &= ~BDRV_O_RDWR;
+
+    ret = bdrv_truncate(c, 65536, PREALLOC_MODE_OFF, NULL);
+    g_assert_cmpint(ret, ==, -EACCES);
+
+    c->bs->read_only = false;
+    c->bs->open_flags |= BDRV_O_RDWR;
+}
+
+static void test_sync_op_block_status(BdrvChild *c)
+{
+    int ret;
+    int64_t n;
+
+    /* Normal success path */
+    ret = bdrv_is_allocated(c->bs, 0, 65536, &n);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Early success: No driver support */
+    bdrv_test.bdrv_co_block_status = NULL;
+    ret = bdrv_is_allocated(c->bs, 0, 65536, &n);
+    g_assert_cmpint(ret, ==, 1);
+
+    /* Early success: bytes = 0 */
+    ret = bdrv_is_allocated(c->bs, 0, 0, &n);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Early success: Offset > image size*/
+    ret = bdrv_is_allocated(c->bs, 0x1000000, 0x1000000, &n);
+    g_assert_cmpint(ret, ==, 0);
+}
+
+static void test_sync_op_flush(BdrvChild *c)
+{
+    int ret;
+
+    /* Normal success path */
+    ret = bdrv_flush(c->bs);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Early success: Read-only image */
+    c->bs->read_only = true;
+    c->bs->open_flags &= ~BDRV_O_RDWR;
+
+    ret = bdrv_flush(c->bs);
+    g_assert_cmpint(ret, ==, 0);
+
+    c->bs->read_only = false;
+    c->bs->open_flags |= BDRV_O_RDWR;
+}
+
+static void test_sync_op_blk_flush(BlockBackend *blk)
+{
+    BlockDriverState *bs = blk_bs(blk);
+    int ret;
+
+    /* Normal success path */
+    ret = blk_flush(blk);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Early success: Read-only image */
+    bs->read_only = true;
+    bs->open_flags &= ~BDRV_O_RDWR;
+
+    ret = blk_flush(blk);
+    g_assert_cmpint(ret, ==, 0);
+
+    bs->read_only = false;
+    bs->open_flags |= BDRV_O_RDWR;
+}
+
+static void test_sync_op_check(BdrvChild *c)
+{
+    BdrvCheckResult result;
+    int ret;
+
+    /* Error: Driver does not implement check */
+    ret = bdrv_check(c->bs, &result, 0);
+    g_assert_cmpint(ret, ==, -ENOTSUP);
+}
+
+static void test_sync_op_invalidate_cache(BdrvChild *c)
+{
+    /* Early success: Image is not inactive */
+    bdrv_invalidate_cache(c->bs, NULL);
+}
+
+
+typedef struct SyncOpTest {
+    const char *name;
+    void (*fn)(BdrvChild *c);
+    void (*blkfn)(BlockBackend *blk);
+} SyncOpTest;
+
+const SyncOpTest sync_op_tests[] = {
+    {
+        .name   = "/sync-op/pread",
+        .fn     = test_sync_op_pread,
+        .blkfn  = test_sync_op_blk_pread,
+    }, {
+        .name   = "/sync-op/pwrite",
+        .fn     = test_sync_op_pwrite,
+        .blkfn  = test_sync_op_blk_pwrite,
+    }, {
+        .name   = "/sync-op/load_vmstate",
+        .fn     = test_sync_op_load_vmstate,
+    }, {
+        .name   = "/sync-op/save_vmstate",
+        .fn     = test_sync_op_save_vmstate,
+    }, {
+        .name   = "/sync-op/pdiscard",
+        .fn     = test_sync_op_pdiscard,
+        .blkfn  = test_sync_op_blk_pdiscard,
+    }, {
+        .name   = "/sync-op/truncate",
+        .fn     = test_sync_op_truncate,
+    }, {
+        .name   = "/sync-op/block_status",
+        .fn     = test_sync_op_block_status,
+    }, {
+        .name   = "/sync-op/flush",
+        .fn     = test_sync_op_flush,
+        .blkfn  = test_sync_op_blk_flush,
+    }, {
+        .name   = "/sync-op/check",
+        .fn     = test_sync_op_check,
+    }, {
+        .name   = "/sync-op/invalidate_cache",
+        .fn     = test_sync_op_invalidate_cache,
+    },
+};
+
+/* Test synchronous operations that run in a different iothread, so we have to
+ * poll for the coroutine there to return. */
+static void test_sync_op(const void *opaque)
+{
+    const SyncOpTest *t = opaque;
+    IOThread *iothread = iothread_new();
+    AioContext *ctx = iothread_get_aio_context(iothread);
+    BlockBackend *blk;
+    BlockDriverState *bs;
+    BdrvChild *c;
+
+    blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
+    bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
+    bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
+    blk_insert_bs(blk, bs, &error_abort);
+    c = QLIST_FIRST(&bs->parents);
+
+    blk_set_aio_context(blk, ctx);
+    aio_context_acquire(ctx);
+    t->fn(c);
+    if (t->blkfn) {
+        t->blkfn(blk);
+    }
+    aio_context_release(ctx);
+    blk_set_aio_context(blk, qemu_get_aio_context());
+
+    bdrv_unref(bs);
+    blk_unref(blk);
+}
+
+int main(int argc, char **argv)
+{
+    int i;
+
+    bdrv_init();
+    qemu_init_main_loop(&error_abort);
+
+    g_test_init(&argc, &argv, NULL);
+
+    for (i = 0; i < ARRAY_SIZE(sync_op_tests); i++) {
+        const SyncOpTest *t = &sync_op_tests[i];
+        g_test_add_data_func(t->name, t, test_sync_op);
+    }
+
+    return g_test_run();
+}
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 19b4c0a696..75ad9c0dd3 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -73,6 +73,7 @@ check-unit-y += tests/test-bdrv-drain$(EXESUF)
 check-unit-y += tests/test-blockjob$(EXESUF)
 check-unit-y += tests/test-blockjob-txn$(EXESUF)
 check-unit-y += tests/test-block-backend$(EXESUF)
+check-unit-y += tests/test-block-iothread$(EXESUF)
 check-unit-y += tests/test-image-locking$(EXESUF)
 check-unit-y += tests/test-x86-cpuid$(EXESUF)
 # all code tested by test-x86-cpuid is inside topology.h
@@ -557,6 +558,7 @@ tests/test-bdrv-drain$(EXESUF): tests/test-bdrv-drain.o $(test-block-obj-y) $(te
 tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
 tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
 tests/test-block-backend$(EXESUF): tests/test-block-backend.o $(test-block-obj-y) $(test-util-obj-y)
+tests/test-block-iothread$(EXESUF): tests/test-block-iothread.o $(test-block-obj-y) $(test-util-obj-y)
 tests/test-image-locking$(EXESUF): tests/test-image-locking.o $(test-block-obj-y) $(test-util-obj-y)
 tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
 tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
-- 
2.20.1

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

* [Qemu-devel] [PULL 07/27] iotests: Make 234 stable
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (5 preceding siblings ...)
  2019-02-01 16:34 ` [Qemu-devel] [PULL 06/27] block: Fix hangs in synchronous APIs with iothreads Kevin Wolf
@ 2019-02-01 16:34 ` Kevin Wolf
  2019-02-01 16:34 ` [Qemu-devel] [PULL 08/27] vmdk: Refactor vmdk_create_extent Kevin Wolf
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Max Reitz <mreitz@redhat.com>

This test waits for a MIGRATION event with status=completed on the
source VM before querying the migration status on both source and
destination.  However, just because the source says migration has
completed does not mean the destination thinks the same.  Therefore, in
some cases, the destination VM may still report "active" instead of
"completed" when asked for its migration status.

Fix this by enabling migration events on both VMs and waiting until both
source and destination emit a status=completed MIGRATION event.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/234     | 56 ++++++++++++++++++++------------------
 tests/qemu-iotests/234.out | 10 +++++--
 2 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/tests/qemu-iotests/234 b/tests/qemu-iotests/234
index a8185b4360..c4c26bc21e 100755
--- a/tests/qemu-iotests/234
+++ b/tests/qemu-iotests/234
@@ -26,6 +26,22 @@ import os
 iotests.verify_image_format(supported_fmts=['qcow2'])
 iotests.verify_platform(['linux'])
 
+def enable_migration_events(vm, name):
+    iotests.log('Enabling migration QMP events on %s...' % name)
+    iotests.log(vm.qmp('migrate-set-capabilities', capabilities=[
+        {
+            'capability': 'events',
+            'state': True
+        }
+    ]))
+
+def wait_migration(vm):
+    while True:
+        event = vm.event_wait('MIGRATION')
+        iotests.log(event, filters=[iotests.filter_qmp_event])
+        if event['data']['status'] == 'completed':
+            break
+
 with iotests.FilePath('img') as img_path, \
      iotests.FilePath('backing') as backing_path, \
      iotests.FilePath('mig_fifo_a') as fifo_a, \
@@ -46,6 +62,8 @@ with iotests.FilePath('img') as img_path, \
          .add_blockdev('%s,file=drive0-backing-file,node-name=drive0-backing' % (iotests.imgfmt))
          .launch())
 
+    enable_migration_events(vm_a, 'A')
+
     iotests.log('Launching destination VM...')
     (vm_b.add_blockdev('file,filename=%s,node-name=drive0-file' % (img_path))
          .add_blockdev('%s,file=drive0-file,node-name=drive0' % (iotests.imgfmt))
@@ -54,6 +72,8 @@ with iotests.FilePath('img') as img_path, \
          .add_incoming("exec: cat '%s'" % (fifo_a))
          .launch())
 
+    enable_migration_events(vm_b, 'B')
+
     # Add a child node that was created after the parent node. The reverse case
     # is covered by the -blockdev options above.
     iotests.log(vm_a.qmp('blockdev-snapshot', node='drive0-backing',
@@ -61,22 +81,13 @@ with iotests.FilePath('img') as img_path, \
     iotests.log(vm_b.qmp('blockdev-snapshot', node='drive0-backing',
                          overlay='drive0'))
 
-    iotests.log('Enabling migration QMP events on A...')
-    iotests.log(vm_a.qmp('migrate-set-capabilities', capabilities=[
-        {
-            'capability': 'events',
-            'state': True
-        }
-    ]))
-
     iotests.log('Starting migration to B...')
     iotests.log(vm_a.qmp('migrate', uri='exec:cat >%s' % (fifo_a)))
     with iotests.Timeout(3, 'Migration does not complete'):
-        while True:
-            event = vm_a.event_wait('MIGRATION')
-            iotests.log(event, filters=[iotests.filter_qmp_event])
-            if event['data']['status'] == 'completed':
-                break
+        # Wait for the source first (which includes setup=setup)
+        wait_migration(vm_a)
+        # Wait for the destination second (which does not)
+        wait_migration(vm_b)
 
     iotests.log(vm_a.qmp('query-migrate')['return']['status'])
     iotests.log(vm_b.qmp('query-migrate')['return']['status'])
@@ -94,25 +105,18 @@ with iotests.FilePath('img') as img_path, \
          .add_incoming("exec: cat '%s'" % (fifo_b))
          .launch())
 
+    enable_migration_events(vm_a, 'A')
+
     iotests.log(vm_a.qmp('blockdev-snapshot', node='drive0-backing',
                          overlay='drive0'))
 
-    iotests.log('Enabling migration QMP events on B...')
-    iotests.log(vm_b.qmp('migrate-set-capabilities', capabilities=[
-        {
-            'capability': 'events',
-            'state': True
-        }
-    ]))
-
     iotests.log('Starting migration back to A...')
     iotests.log(vm_b.qmp('migrate', uri='exec:cat >%s' % (fifo_b)))
     with iotests.Timeout(3, 'Migration does not complete'):
-        while True:
-            event = vm_b.event_wait('MIGRATION')
-            iotests.log(event, filters=[iotests.filter_qmp_event])
-            if event['data']['status'] == 'completed':
-                break
+        # Wait for the source first (which includes setup=setup)
+        wait_migration(vm_b)
+        # Wait for the destination second (which does not)
+        wait_migration(vm_a)
 
     iotests.log(vm_a.qmp('query-migrate')['return']['status'])
     iotests.log(vm_b.qmp('query-migrate')['return']['status'])
diff --git a/tests/qemu-iotests/234.out b/tests/qemu-iotests/234.out
index b9ed910b1a..692976d1c6 100644
--- a/tests/qemu-iotests/234.out
+++ b/tests/qemu-iotests/234.out
@@ -1,14 +1,18 @@
 Launching source VM...
+Enabling migration QMP events on A...
+{"return": {}}
 Launching destination VM...
+Enabling migration QMP events on B...
 {"return": {}}
 {"return": {}}
-Enabling migration QMP events on A...
 {"return": {}}
 Starting migration to B...
 {"return": {}}
 {"data": {"status": "setup"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
 {"data": {"status": "active"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
 {"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
+{"data": {"status": "active"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
+{"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
 completed
 completed
 {"return": {"running": false, "singlestep": false, "status": "postmigrate"}}
@@ -16,14 +20,16 @@ completed
 Add a second parent to drive0-file...
 {"return": {}}
 Restart A with -incoming and second parent...
+Enabling migration QMP events on A...
 {"return": {}}
-Enabling migration QMP events on B...
 {"return": {}}
 Starting migration back to A...
 {"return": {}}
 {"data": {"status": "setup"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
 {"data": {"status": "active"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
 {"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
+{"data": {"status": "active"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
+{"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
 completed
 completed
 {"return": {"running": true, "singlestep": false, "status": "running"}}
-- 
2.20.1

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

* [Qemu-devel] [PULL 08/27] vmdk: Refactor vmdk_create_extent
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (6 preceding siblings ...)
  2019-02-01 16:34 ` [Qemu-devel] [PULL 07/27] iotests: Make 234 stable Kevin Wolf
@ 2019-02-01 16:34 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 09/27] vmdk: Implement .bdrv_co_create callback Kevin Wolf
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Fam Zheng <famz@redhat.com>

The extracted vmdk_init_extent takes a BlockBackend object and
initializes the format metadata. It is the common part between "qemu-img
create" and "blockdev-create".

Add a "BlockBackend *pbb" parameter to vmdk_create_extent, to return the
opened BB to the caller in the next patch.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c | 69 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 43 insertions(+), 26 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 2c9e86d98f..32fc2c84b3 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1741,35 +1741,17 @@ static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs,
     return ret;
 }
 
-static int vmdk_create_extent(const char *filename, int64_t filesize,
-                              bool flat, bool compress, bool zeroed_grain,
-                              QemuOpts *opts, Error **errp)
+static int vmdk_init_extent(BlockBackend *blk,
+                            int64_t filesize, bool flat,
+                            bool compress, bool zeroed_grain,
+                            Error **errp)
 {
     int ret, i;
-    BlockBackend *blk = NULL;
     VMDK4Header header;
-    Error *local_err = NULL;
     uint32_t tmp, magic, grains, gd_sectors, gt_size, gt_count;
     uint32_t *gd_buf = NULL;
     int gd_buf_size;
 
-    ret = bdrv_create_file(filename, opts, &local_err);
-    if (ret < 0) {
-        error_propagate(errp, local_err);
-        goto exit;
-    }
-
-    blk = blk_new_open(filename, NULL, NULL,
-                       BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
-                       &local_err);
-    if (blk == NULL) {
-        error_propagate(errp, local_err);
-        ret = -EIO;
-        goto exit;
-    }
-
-    blk_set_allow_write_beyond_eof(blk, true);
-
     if (flat) {
         ret = blk_truncate(blk, filesize, PREALLOC_MODE_OFF, errp);
         goto exit;
@@ -1863,15 +1845,50 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
                      gd_buf, gd_buf_size, 0);
     if (ret < 0) {
         error_setg(errp, QERR_IO_ERROR);
-        goto exit;
     }
 
     ret = 0;
+exit:
+    g_free(gd_buf);
+    return ret;
+}
+
+static int vmdk_create_extent(const char *filename, int64_t filesize,
+                              bool flat, bool compress, bool zeroed_grain,
+                              BlockBackend **pbb,
+                              QemuOpts *opts, Error **errp)
+{
+    int ret;
+    BlockBackend *blk = NULL;
+    Error *local_err = NULL;
+
+    ret = bdrv_create_file(filename, opts, &local_err);
+    if (ret < 0) {
+        error_propagate(errp, local_err);
+        goto exit;
+    }
+
+    blk = blk_new_open(filename, NULL, NULL,
+                       BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
+                       &local_err);
+    if (blk == NULL) {
+        error_propagate(errp, local_err);
+        ret = -EIO;
+        goto exit;
+    }
+
+    blk_set_allow_write_beyond_eof(blk, true);
+
+    ret = vmdk_init_extent(blk, filesize, flat, compress, zeroed_grain, errp);
 exit:
     if (blk) {
-        blk_unref(blk);
+        if (pbb) {
+            *pbb = blk;
+        } else {
+            blk_unref(blk);
+            blk = NULL;
+        }
     }
-    g_free(gd_buf);
     return ret;
 }
 
@@ -2094,7 +2111,7 @@ static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts
         snprintf(ext_filename, PATH_MAX, "%s%s", path, desc_filename);
 
         if (vmdk_create_extent(ext_filename, size,
-                               flat, compress, zeroed_grain, opts, errp)) {
+                               flat, compress, zeroed_grain, NULL, opts, errp)) {
             ret = -EINVAL;
             goto exit;
         }
-- 
2.20.1

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

* [Qemu-devel] [PULL 09/27] vmdk: Implement .bdrv_co_create callback
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (7 preceding siblings ...)
  2019-02-01 16:34 ` [Qemu-devel] [PULL 08/27] vmdk: Refactor vmdk_create_extent Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 10/27] iotests: Filter cid numbers in VMDK extent info Kevin Wolf
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Fam Zheng <famz@redhat.com>

This makes VMDK support blockdev-create. The implementation reuses the
image creation code in vmdk_co_create_opts which now acceptes a callback
pointer to "retrieve" BlockBackend pointers from the caller. This way we
separate the logic between file/extent acquisition and initialization.

The QAPI command parameters are mostly the same as the old create_opts
except the dropped legacy @compat6 switch, which is redundant with
@hwversion.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qapi/block-core.json  |  70 +++++++
 qapi/qapi-schema.json |  16 +-
 block/vmdk.c          | 448 ++++++++++++++++++++++++++++++------------
 3 files changed, 400 insertions(+), 134 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index cde1b53708..a5924b40af 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4137,6 +4137,75 @@
             'size':             'size',
             '*cluster-size' :   'size' } }
 
+##
+# @BlockdevVmdkSubformat:
+#
+# Subformat options for VMDK images
+#
+# @monolithicSparse:     Single file image with sparse cluster allocation
+#
+# @monolithicFlat:       Single flat data image and a descriptor file
+#
+# @twoGbMaxExtentSparse: Data is split into 2GB (per virtual LBA) sparse extent
+#                        files, in addition to a descriptor file
+#
+# @twoGbMaxExtentFlat:   Data is split into 2GB (per virtual LBA) flat extent
+#                        files, in addition to a descriptor file
+#
+# @streamOptimized:      Single file image sparse cluster allocation, optimized
+#                        for streaming over network.
+#
+# Since: 4.0
+##
+{ 'enum': 'BlockdevVmdkSubformat',
+  'data': [ 'monolithicSparse', 'monolithicFlat', 'twoGbMaxExtentSparse',
+            'twoGbMaxExtentFlat', 'streamOptimized'] }
+
+##
+# @BlockdevVmdkAdapterType:
+#
+# Adapter type info for VMDK images
+#
+# Since: 4.0
+##
+{ 'enum': 'BlockdevVmdkAdapterType',
+  'data': [ 'ide', 'buslogic', 'lsilogic', 'legacyESX'] }
+
+##
+# @BlockdevCreateOptionsVmdk:
+#
+# Driver specific image creation options for VMDK.
+#
+# @file         Where to store the new image file. This refers to the image
+#               file for monolithcSparse and streamOptimized format, or the
+#               descriptor file for other formats.
+# @size         Size of the virtual disk in bytes
+# @extents      Where to store the data extents. Required for monolithcFlat,
+#               twoGbMaxExtentSparse and twoGbMaxExtentFlat formats. For
+#               monolithicFlat, only one entry is required; for
+#               twoGbMaxExtent* formats, the number of entries required is
+#               calculated as extent_number = virtual_size / 2GB.
+# @subformat    The subformat of the VMDK image. Default: "monolithicSparse".
+# @backing-file The path of backing file. Default: no backing file is used.
+# @adapter-type The adapter type used to fill in the descriptor. Default: ide.
+# @hwversion    Hardware version. The meaningful options are "4" or "6".
+#               Default: "4".
+# @zeroed-grain Whether to enable zeroed-grain feature for sparse subformats.
+#               Default: false.
+#
+# Since: 4.0
+##
+{ 'struct': 'BlockdevCreateOptionsVmdk',
+  'data': { 'file':             'BlockdevRef',
+            'size':             'size',
+            '*extents':          ['BlockdevRef'],
+            '*subformat':       'BlockdevVmdkSubformat',
+            '*backing-file':    'str',
+            '*adapter-type':    'BlockdevVmdkAdapterType',
+            '*hwversion':       'str',
+            '*zeroed-grain':    'bool' } }
+
+
 ##
 # @SheepdogRedundancyType:
 #
@@ -4331,6 +4400,7 @@
       'ssh':            'BlockdevCreateOptionsSsh',
       'vdi':            'BlockdevCreateOptionsVdi',
       'vhdx':           'BlockdevCreateOptionsVhdx',
+      'vmdk':           'BlockdevCreateOptionsVmdk',
       'vpc':            'BlockdevCreateOptionsVpc'
   } }
 
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index 3bbdfcee84..1845aa78ff 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -63,13 +63,15 @@
         'query-tpm-types',
         'ringbuf-read' ],
     'name-case-whitelist': [
-        'ACPISlotType',         # DIMM, visible through query-acpi-ospm-status
-        'CpuInfoMIPS',          # PC, visible through query-cpu
-        'CpuInfoTricore',       # PC, visible through query-cpu
-        'QapiErrorClass',       # all members, visible through errors
-        'UuidInfo',             # UUID, visible through query-uuid
-        'X86CPURegister32',     # all members, visible indirectly through qom-get
-        'q_obj_CpuInfo-base'    # CPU, visible through query-cpu
+        'ACPISlotType',             # DIMM, visible through query-acpi-ospm-status
+        'CpuInfoMIPS',              # PC, visible through query-cpu
+        'CpuInfoTricore',           # PC, visible through query-cpu
+        'BlockdevVmdkSubformat',    # all members, to match VMDK spec spellings
+        'BlockdevVmdkAdapterType',  # legacyESX, to match VMDK spec spellings
+        'QapiErrorClass',           # all members, visible through errors
+        'UuidInfo',                 # UUID, visible through query-uuid
+        'X86CPURegister32',         # all members, visible indirectly through qom-get
+        'q_obj_CpuInfo-base'        # CPU, visible through query-cpu
     ] } }
 
 # Documentation generated with qapi-gen.py is in source order, with
diff --git a/block/vmdk.c b/block/vmdk.c
index 32fc2c84b3..5a162ee85c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1932,33 +1932,56 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
     return VMDK_OK;
 }
 
-static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts,
-                                            Error **errp)
+/*
+ * idx == 0: get or create the descriptor file (also the image file if in a
+ *           non-split format.
+ * idx >= 1: get the n-th extent if in a split subformat
+ */
+typedef BlockBackend *(*vmdk_create_extent_fn)(int64_t size,
+                                               int idx,
+                                               bool flat,
+                                               bool split,
+                                               bool compress,
+                                               bool zeroed_grain,
+                                               void *opaque,
+                                               Error **errp);
+
+static void vmdk_desc_add_extent(GString *desc,
+                                 const char *extent_line_fmt,
+                                 int64_t size, const char *filename)
+{
+    char *basename = g_path_get_basename(filename);
+
+    g_string_append_printf(desc, extent_line_fmt,
+                           DIV_ROUND_UP(size, BDRV_SECTOR_SIZE), basename);
+    g_free(basename);
+}
+
+static int coroutine_fn vmdk_co_do_create(int64_t size,
+                                          BlockdevVmdkSubformat subformat,
+                                          BlockdevVmdkAdapterType adapter_type,
+                                          const char *backing_file,
+                                          const char *hw_version,
+                                          bool compat6,
+                                          bool zeroed_grain,
+                                          vmdk_create_extent_fn extent_fn,
+                                          void *opaque,
+                                          Error **errp)
 {
-    int idx = 0;
-    BlockBackend *new_blk = NULL;
+    int extent_idx;
+    BlockBackend *blk = NULL;
     Error *local_err = NULL;
     char *desc = NULL;
-    int64_t total_size = 0, filesize;
-    char *adapter_type = NULL;
-    char *backing_file = NULL;
-    char *hw_version = NULL;
-    char *fmt = NULL;
     int ret = 0;
     bool flat, split, compress;
     GString *ext_desc_lines;
-    char *path = g_malloc0(PATH_MAX);
-    char *prefix = g_malloc0(PATH_MAX);
-    char *postfix = g_malloc0(PATH_MAX);
-    char *desc_line = g_malloc0(BUF_SIZE);
-    char *ext_filename = g_malloc0(PATH_MAX);
-    char *desc_filename = g_malloc0(PATH_MAX);
     const int64_t split_size = 0x80000000;  /* VMDK has constant split size */
-    const char *desc_extent_line;
+    int64_t extent_size;
+    int64_t created_size = 0;
+    const char *extent_line_fmt;
     char *parent_desc_line = g_malloc0(BUF_SIZE);
     uint32_t parent_cid = 0xffffffff;
     uint32_t number_heads = 16;
-    bool zeroed_grain = false;
     uint32_t desc_offset = 0, desc_len;
     const char desc_template[] =
         "# Disk DescriptorFile\n"
@@ -1982,71 +2005,35 @@ static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts
 
     ext_desc_lines = g_string_new(NULL);
 
-    if (filename_decompose(filename, path, prefix, postfix, PATH_MAX, errp)) {
-        ret = -EINVAL;
-        goto exit;
-    }
     /* Read out options */
-    total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-                          BDRV_SECTOR_SIZE);
-    adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
-    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
-    hw_version = qemu_opt_get_del(opts, BLOCK_OPT_HWVERSION);
-    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) {
-        if (strcmp(hw_version, "undefined")) {
+    if (compat6) {
+        if (hw_version) {
             error_setg(errp,
                        "compat6 cannot be enabled with hwversion set");
             ret = -EINVAL;
             goto exit;
         }
-        g_free(hw_version);
-        hw_version = g_strdup("6");
-    }
-    if (strcmp(hw_version, "undefined") == 0) {
-        g_free(hw_version);
-        hw_version = g_strdup("4");
+        hw_version = "6";
     }
-    fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
-    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
-        zeroed_grain = true;
+    if (!hw_version) {
+        hw_version = "4";
     }
 
-    if (!adapter_type) {
-        adapter_type = g_strdup("ide");
-    } else if (strcmp(adapter_type, "ide") &&
-               strcmp(adapter_type, "buslogic") &&
-               strcmp(adapter_type, "lsilogic") &&
-               strcmp(adapter_type, "legacyESX")) {
-        error_setg(errp, "Unknown adapter type: '%s'", adapter_type);
-        ret = -EINVAL;
-        goto exit;
-    }
-    if (strcmp(adapter_type, "ide") != 0) {
+    if (adapter_type != BLOCKDEV_VMDK_ADAPTER_TYPE_IDE) {
         /* that's the number of heads with which vmware operates when
            creating, exporting, etc. vmdk files with a non-ide adapter type */
         number_heads = 255;
     }
-    if (!fmt) {
-        /* Default format to monolithicSparse */
-        fmt = g_strdup("monolithicSparse");
-    } else if (strcmp(fmt, "monolithicFlat") &&
-               strcmp(fmt, "monolithicSparse") &&
-               strcmp(fmt, "twoGbMaxExtentSparse") &&
-               strcmp(fmt, "twoGbMaxExtentFlat") &&
-               strcmp(fmt, "streamOptimized")) {
-        error_setg(errp, "Unknown subformat: '%s'", fmt);
-        ret = -EINVAL;
-        goto exit;
-    }
-    split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
-              strcmp(fmt, "twoGbMaxExtentSparse"));
-    flat = !(strcmp(fmt, "monolithicFlat") &&
-             strcmp(fmt, "twoGbMaxExtentFlat"));
-    compress = !strcmp(fmt, "streamOptimized");
+    split = (subformat == BLOCKDEV_VMDK_SUBFORMAT_TWOGBMAXEXTENTFLAT) ||
+            (subformat == BLOCKDEV_VMDK_SUBFORMAT_TWOGBMAXEXTENTSPARSE);
+    flat = (subformat == BLOCKDEV_VMDK_SUBFORMAT_MONOLITHICFLAT) ||
+           (subformat == BLOCKDEV_VMDK_SUBFORMAT_TWOGBMAXEXTENTFLAT);
+    compress = subformat == BLOCKDEV_VMDK_SUBFORMAT_STREAMOPTIMIZED;
+
     if (flat) {
-        desc_extent_line = "RW %" PRId64 " FLAT \"%s\" 0\n";
+        extent_line_fmt = "RW %" PRId64 " FLAT \"%s\" 0\n";
     } else {
-        desc_extent_line = "RW %" PRId64 " SPARSE \"%s\"\n";
+        extent_line_fmt = "RW %" PRId64 " SPARSE \"%s\"\n";
     }
     if (flat && backing_file) {
         error_setg(errp, "Flat image can't have backing file");
@@ -2058,10 +2045,34 @@ static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts
         ret = -ENOTSUP;
         goto exit;
     }
+
+    /* Create extents */
+    if (split) {
+        extent_size = split_size;
+    } else {
+        extent_size = size;
+    }
+    if (!split && !flat) {
+        created_size = extent_size;
+    } else {
+        created_size = 0;
+    }
+    /* Get the descriptor file BDS */
+    blk = extent_fn(created_size, 0, flat, split, compress, zeroed_grain,
+                    opaque, errp);
+    if (!blk) {
+        ret = -EIO;
+        goto exit;
+    }
+    if (!split && !flat) {
+        vmdk_desc_add_extent(ext_desc_lines, extent_line_fmt, created_size,
+                             blk_bs(blk)->filename);
+    }
+
     if (backing_file) {
-        BlockBackend *blk;
+        BlockBackend *backing;
         char *full_backing = g_new0(char, PATH_MAX);
-        bdrv_get_full_backing_filename_from_filename(filename, backing_file,
+        bdrv_get_full_backing_filename_from_filename(blk_bs(blk)->filename, backing_file,
                                                      full_backing, PATH_MAX,
                                                      &local_err);
         if (local_err) {
@@ -2071,106 +2082,211 @@ static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts
             goto exit;
         }
 
-        blk = blk_new_open(full_backing, NULL, NULL,
-                           BDRV_O_NO_BACKING, errp);
+        backing = blk_new_open(full_backing, NULL, NULL,
+                               BDRV_O_NO_BACKING, errp);
         g_free(full_backing);
-        if (blk == NULL) {
+        if (backing == NULL) {
             ret = -EIO;
             goto exit;
         }
-        if (strcmp(blk_bs(blk)->drv->format_name, "vmdk")) {
-            blk_unref(blk);
+        if (strcmp(blk_bs(backing)->drv->format_name, "vmdk")) {
+            error_setg(errp, "Invalid backing file format: %s. Must be vmdk",
+                       blk_bs(backing)->drv->format_name);
+            blk_unref(backing);
             ret = -EINVAL;
             goto exit;
         }
-        ret = vmdk_read_cid(blk_bs(blk), 0, &parent_cid);
-        blk_unref(blk);
+        ret = vmdk_read_cid(blk_bs(backing), 0, &parent_cid);
+        blk_unref(backing);
         if (ret) {
+            error_setg(errp, "Failed to read parent CID");
             goto exit;
         }
         snprintf(parent_desc_line, BUF_SIZE,
                 "parentFileNameHint=\"%s\"", backing_file);
     }
-
-    /* Create extents */
-    filesize = total_size;
-    while (filesize > 0) {
-        int64_t size = filesize;
-
-        if (split && size > split_size) {
-            size = split_size;
-        }
-        if (split) {
-            snprintf(desc_filename, PATH_MAX, "%s-%c%03d%s",
-                    prefix, flat ? 'f' : 's', ++idx, postfix);
-        } else if (flat) {
-            snprintf(desc_filename, PATH_MAX, "%s-flat%s", prefix, postfix);
-        } else {
-            snprintf(desc_filename, PATH_MAX, "%s%s", prefix, postfix);
-        }
-        snprintf(ext_filename, PATH_MAX, "%s%s", path, desc_filename);
-
-        if (vmdk_create_extent(ext_filename, size,
-                               flat, compress, zeroed_grain, NULL, opts, errp)) {
+    extent_idx = 1;
+    while (created_size < size) {
+        BlockBackend *extent_blk;
+        int64_t cur_size = MIN(size - created_size, extent_size);
+        extent_blk = extent_fn(cur_size, extent_idx, flat, split, compress,
+                               zeroed_grain, opaque, errp);
+        if (!extent_blk) {
             ret = -EINVAL;
             goto exit;
         }
-        filesize -= size;
-
-        /* Format description line */
-        snprintf(desc_line, BUF_SIZE,
-                    desc_extent_line, size / BDRV_SECTOR_SIZE, desc_filename);
-        g_string_append(ext_desc_lines, desc_line);
+        vmdk_desc_add_extent(ext_desc_lines, extent_line_fmt, cur_size,
+                             blk_bs(extent_blk)->filename);
+        created_size += cur_size;
+        extent_idx++;
+        blk_unref(extent_blk);
     }
     /* generate descriptor file */
     desc = g_strdup_printf(desc_template,
                            g_random_int(),
                            parent_cid,
-                           fmt,
+                           BlockdevVmdkSubformat_str(subformat),
                            parent_desc_line,
                            ext_desc_lines->str,
                            hw_version,
-                           total_size /
+                           size /
                                (int64_t)(63 * number_heads * BDRV_SECTOR_SIZE),
                            number_heads,
-                           adapter_type);
+                           BlockdevVmdkAdapterType_str(adapter_type));
     desc_len = strlen(desc);
     /* the descriptor offset = 0x200 */
     if (!split && !flat) {
         desc_offset = 0x200;
-    } else {
-        ret = bdrv_create_file(filename, opts, &local_err);
+    }
+
+    ret = blk_pwrite(blk, desc_offset, desc, desc_len, 0);
+    if (ret < 0) {
+        error_setg_errno(errp, -ret, "Could not write description");
+        goto exit;
+    }
+    /* bdrv_pwrite write padding zeros to align to sector, we don't need that
+     * for description file */
+    if (desc_offset == 0) {
+        ret = blk_truncate(blk, desc_len, PREALLOC_MODE_OFF, errp);
         if (ret < 0) {
-            error_propagate(errp, local_err);
             goto exit;
         }
     }
+    ret = 0;
+exit:
+    if (blk) {
+        blk_unref(blk);
+    }
+    g_free(desc);
+    g_free(parent_desc_line);
+    g_string_free(ext_desc_lines, true);
+    return ret;
+}
 
-    new_blk = blk_new_open(filename, NULL, NULL,
-                           BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
-                           &local_err);
-    if (new_blk == NULL) {
-        error_propagate(errp, local_err);
-        ret = -EIO;
+typedef struct {
+    char *path;
+    char *prefix;
+    char *postfix;
+    QemuOpts *opts;
+} VMDKCreateOptsData;
+
+static BlockBackend *vmdk_co_create_opts_cb(int64_t size, int idx,
+                                            bool flat, bool split, bool compress,
+                                            bool zeroed_grain, void *opaque,
+                                            Error **errp)
+{
+    BlockBackend *blk = NULL;
+    BlockDriverState *bs = NULL;
+    VMDKCreateOptsData *data = opaque;
+    char *ext_filename = NULL;
+    char *rel_filename = NULL;
+
+    if (idx == 0) {
+        rel_filename = g_strdup_printf("%s%s", data->prefix, data->postfix);
+    } else if (split) {
+        rel_filename = g_strdup_printf("%s-%c%03d%s",
+                                       data->prefix,
+                                       flat ? 'f' : 's', idx, data->postfix);
+    } else {
+        assert(idx == 1);
+        rel_filename = g_strdup_printf("%s-flat%s", data->prefix, data->postfix);
+    }
+
+    ext_filename = g_strdup_printf("%s%s", data->path, rel_filename);
+    g_free(rel_filename);
+
+    if (vmdk_create_extent(ext_filename, size,
+                           flat, compress, zeroed_grain, &blk, data->opts,
+                           errp)) {
         goto exit;
     }
+    bdrv_unref(bs);
+exit:
+    g_free(ext_filename);
+    return blk;
+}
 
-    blk_set_allow_write_beyond_eof(new_blk, true);
+static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts,
+                                            Error **errp)
+{
+    Error *local_err = NULL;
+    char *desc = NULL;
+    int64_t total_size = 0;
+    char *adapter_type = NULL;
+    BlockdevVmdkAdapterType adapter_type_enum;
+    char *backing_file = NULL;
+    char *hw_version = NULL;
+    char *fmt = NULL;
+    BlockdevVmdkSubformat subformat;
+    int ret = 0;
+    char *path = g_malloc0(PATH_MAX);
+    char *prefix = g_malloc0(PATH_MAX);
+    char *postfix = g_malloc0(PATH_MAX);
+    char *desc_line = g_malloc0(BUF_SIZE);
+    char *ext_filename = g_malloc0(PATH_MAX);
+    char *desc_filename = g_malloc0(PATH_MAX);
+    char *parent_desc_line = g_malloc0(BUF_SIZE);
+    bool zeroed_grain;
+    bool compat6;
+    VMDKCreateOptsData data;
 
-    ret = blk_pwrite(new_blk, desc_offset, desc, desc_len, 0);
-    if (ret < 0) {
-        error_setg_errno(errp, -ret, "Could not write description");
+    if (filename_decompose(filename, path, prefix, postfix, PATH_MAX, errp)) {
+        ret = -EINVAL;
         goto exit;
     }
-    /* bdrv_pwrite write padding zeros to align to sector, we don't need that
-     * for description file */
-    if (desc_offset == 0) {
-        ret = blk_truncate(new_blk, desc_len, PREALLOC_MODE_OFF, errp);
+    /* Read out options */
+    total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+                          BDRV_SECTOR_SIZE);
+    adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
+    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+    hw_version = qemu_opt_get_del(opts, BLOCK_OPT_HWVERSION);
+    compat6 = qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false);
+    if (strcmp(hw_version, "undefined") == 0) {
+        g_free(hw_version);
+        hw_version = g_strdup("4");
     }
-exit:
-    if (new_blk) {
-        blk_unref(new_blk);
+    fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
+    zeroed_grain = qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false);
+
+    if (adapter_type) {
+        adapter_type_enum = qapi_enum_parse(&BlockdevVmdkAdapterType_lookup,
+                                            adapter_type,
+                                            BLOCKDEV_VMDK_ADAPTER_TYPE_IDE,
+                                            &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            ret = -EINVAL;
+            goto exit;
+        }
+    } else {
+        adapter_type_enum = BLOCKDEV_VMDK_ADAPTER_TYPE_IDE;
     }
+
+    if (!fmt) {
+        /* Default format to monolithicSparse */
+        subformat = BLOCKDEV_VMDK_SUBFORMAT_MONOLITHICSPARSE;
+    } else {
+        subformat = qapi_enum_parse(&BlockdevVmdkSubformat_lookup,
+                                    fmt,
+                                    BLOCKDEV_VMDK_SUBFORMAT_MONOLITHICSPARSE,
+                                    &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            ret = -EINVAL;
+            goto exit;
+        }
+    }
+    data = (VMDKCreateOptsData){
+        .prefix = prefix,
+        .postfix = postfix,
+        .path = path,
+        .opts = opts,
+    };
+    ret = vmdk_co_do_create(total_size, subformat, adapter_type_enum,
+                            backing_file, hw_version, compat6, zeroed_grain,
+                            vmdk_co_create_opts_cb, &data, errp);
+
+exit:
     g_free(adapter_type);
     g_free(backing_file);
     g_free(hw_version);
@@ -2183,7 +2299,84 @@ exit:
     g_free(ext_filename);
     g_free(desc_filename);
     g_free(parent_desc_line);
-    g_string_free(ext_desc_lines, true);
+    return ret;
+}
+
+static BlockBackend *vmdk_co_create_cb(int64_t size, int idx,
+                                       bool flat, bool split, bool compress,
+                                       bool zeroed_grain, void *opaque,
+                                       Error **errp)
+{
+    int ret;
+    BlockDriverState *bs;
+    BlockBackend *blk;
+    BlockdevCreateOptionsVmdk *opts = opaque;
+
+    if (idx == 0) {
+        bs = bdrv_open_blockdev_ref(opts->file, errp);
+    } else {
+        int i;
+        BlockdevRefList *list = opts->extents;
+        for (i = 1; i < idx; i++) {
+            if (!list || !list->next) {
+                error_setg(errp, "Extent [%d] not specified", i);
+                return NULL;
+            }
+            list = list->next;
+        }
+        if (!list) {
+            error_setg(errp, "Extent [%d] not specified", idx - 1);
+            return NULL;
+        }
+        bs = bdrv_open_blockdev_ref(list->value, errp);
+    }
+    if (!bs) {
+        return NULL;
+    }
+    blk = blk_new(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE,
+                  BLK_PERM_ALL);
+    if (blk_insert_bs(blk, bs, errp)) {
+        bdrv_unref(bs);
+        return NULL;
+    }
+    blk_set_allow_write_beyond_eof(blk, true);
+    bdrv_unref(bs);
+
+    ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
+    if (ret) {
+        blk_unref(blk);
+        blk = NULL;
+    }
+    return blk;
+}
+
+static int coroutine_fn vmdk_co_create(BlockdevCreateOptions *create_options,
+                                       Error **errp)
+{
+    int ret;
+    BlockdevCreateOptionsVmdk *opts;
+
+    opts = &create_options->u.vmdk;
+
+    /* Validate options */
+    if (!QEMU_IS_ALIGNED(opts->size, BDRV_SECTOR_SIZE)) {
+        error_setg(errp, "Image size must be a multiple of 512 bytes");
+        ret = -EINVAL;
+        goto out;
+    }
+
+    ret = vmdk_co_do_create(opts->size,
+                            opts->subformat,
+                            opts->adapter_type,
+                            opts->backing_file,
+                            opts->hwversion,
+                            false,
+                            opts->zeroed_grain,
+                            vmdk_co_create_cb,
+                            opts, errp);
+    return ret;
+
+out:
     return ret;
 }
 
@@ -2451,6 +2644,7 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_co_pwrite_zeroes        = vmdk_co_pwrite_zeroes,
     .bdrv_close                   = vmdk_close,
     .bdrv_co_create_opts          = vmdk_co_create_opts,
+    .bdrv_co_create               = vmdk_co_create,
     .bdrv_co_flush_to_disk        = vmdk_co_flush,
     .bdrv_co_block_status         = vmdk_co_block_status,
     .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
-- 
2.20.1

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

* [Qemu-devel] [PULL 10/27] iotests: Filter cid numbers in VMDK extent info
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (8 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 09/27] vmdk: Implement .bdrv_co_create callback Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 11/27] iotests: Add VMDK tests for blockdev-create Kevin Wolf
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Fam Zheng <famz@redhat.com>

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/common.filter | 1 +
 tests/qemu-iotests/iotests.py    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 2031e353a5..1aa7d57140 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -165,6 +165,7 @@ _filter_img_info()
         -e "/table_size: [0-9]\\+/d" \
         -e "/compat: '[^']*'/d" \
         -e "/compat6: \\(on\\|off\\)/d" \
+        -e "s/cid: [0-9]\+/cid: XXXXXXXXXX/" \
         -e "/static: \\(on\\|off\\)/d" \
         -e "/zeroed_grain: \\(on\\|off\\)/d" \
         -e "/subformat: '[^']*'/d" \
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 009c614ef7..71214d46b5 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -299,6 +299,7 @@ def filter_img_info(output, filename):
                    .replace(imgfmt, 'IMGFMT')
         line = re.sub('iters: [0-9]+', 'iters: XXX', line)
         line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
+        line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
         lines.append(line)
     return '\n'.join(lines)
 
-- 
2.20.1

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

* [Qemu-devel] [PULL 11/27] iotests: Add VMDK tests for blockdev-create
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (9 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 10/27] iotests: Filter cid numbers in VMDK extent info Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 12/27] vmdk: Reject excess extents in blockdev-create Kevin Wolf
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/237     | 233 +++++++++++++++++++++++++
 tests/qemu-iotests/237.out | 347 +++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/group   |   1 +
 3 files changed, 581 insertions(+)
 create mode 100755 tests/qemu-iotests/237
 create mode 100644 tests/qemu-iotests/237.out

diff --git a/tests/qemu-iotests/237 b/tests/qemu-iotests/237
new file mode 100755
index 0000000000..e04a1ac6be
--- /dev/null
+++ b/tests/qemu-iotests/237
@@ -0,0 +1,233 @@
+#!/usr/bin/env python
+#
+# Test vmdk and file image creation
+#
+# Copyright (C) 2018 Red Hat, Inc.
+#
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
+#
+# 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/>.
+#
+
+import iotests
+from iotests import imgfmt
+
+iotests.verify_image_format(supported_fmts=['vmdk'])
+
+def blockdev_create(vm, options):
+    result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
+
+    if 'return' in result:
+        assert result['return'] == {}
+        vm.run_job('job0')
+    iotests.log("")
+
+with iotests.FilePath('t.vmdk') as disk_path, \
+     iotests.FilePath('t.vmdk.1') as extent1_path, \
+     iotests.FilePath('t.vmdk.2') as extent2_path, \
+     iotests.FilePath('t.vmdk.3') as extent3_path, \
+     iotests.VM() as vm:
+
+    #
+    # Successful image creation (defaults)
+    #
+    iotests.log("=== Successful image creation (defaults) ===")
+    iotests.log("")
+
+    size = 5 * 1024 * 1024 * 1024
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': 'file',
+                          'filename': disk_path,
+                          'size': 0 })
+
+    vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
+               node_name='imgfile')
+
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': 'imgfile',
+                          'size': size })
+    vm.shutdown()
+
+    iotests.img_info_log(disk_path)
+
+    #
+    # Successful image creation (inline blockdev-add, explicit defaults)
+    #
+    iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===")
+    iotests.log("")
+
+    # Choose a different size to show that we got a new image
+    size = 64 * 1024 * 1024
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': 'file',
+                          'filename': disk_path,
+                          'size': 0 })
+
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': {
+                              'driver': 'file',
+                              'filename': disk_path,
+                          },
+                          'size': size,
+                          'extents': [],
+                          'subformat': 'monolithicSparse',
+                          'adapter-type': 'ide',
+                          'hwversion': '4',
+                          'zeroed-grain': False })
+    vm.shutdown()
+
+    iotests.img_info_log(disk_path)
+
+    #
+    # Successful image creation (non-default options)
+    #
+    iotests.log("=== Successful image creation (with non-default options) ===")
+    iotests.log("")
+
+    # Choose a different size to show that we got a new image
+    size = 32 * 1024 * 1024
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': 'file',
+                          'filename': disk_path,
+                          'size': 0 })
+
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': {
+                              'driver': 'file',
+                              'filename': disk_path,
+                          },
+                          'size': size,
+                          'extents': [],
+                          'subformat': 'monolithicSparse',
+                          'adapter-type': 'buslogic',
+                          'zeroed-grain': True })
+    vm.shutdown()
+
+    iotests.img_info_log(disk_path)
+
+    #
+    # Invalid BlockdevRef
+    #
+    iotests.log("=== Invalid BlockdevRef ===")
+    iotests.log("")
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': "this doesn't exist",
+                          'size': size })
+    vm.shutdown()
+
+    #
+    # Adapter types
+    #
+
+    iotests.log("=== Adapter types ===")
+    iotests.log("")
+
+    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
+
+    # Valid
+    iotests.log("== Valid adapter types ==")
+    iotests.log("")
+
+    vm.launch()
+    for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]:
+        blockdev_create(vm, { 'driver': imgfmt,
+                              'file': 'node0',
+                              'size': size,
+                              'adapter-type': adapter_type })
+    vm.shutdown()
+
+    # Invalid
+    iotests.log("== Invalid adapter types ==")
+    iotests.log("")
+
+    vm.launch()
+    for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]:
+        blockdev_create(vm, { 'driver': imgfmt,
+                              'file': 'node0',
+                              'size': size,
+                              'adapter-type': adapter_type })
+    vm.shutdown()
+
+    #
+    # Other subformats
+    #
+    iotests.log("=== Other subformats ===")
+    iotests.log("")
+
+    for path in [ extent1_path, extent2_path, extent3_path ]:
+        msg = iotests.qemu_img_pipe('create', '-f', imgfmt, path, '0')
+        iotests.log(msg, [iotests.filter_testfiles])
+
+    vm.add_blockdev('driver=file,filename=%s,node-name=ext1' % (extent1_path))
+    vm.add_blockdev('driver=file,filename=%s,node-name=ext2' % (extent2_path))
+    vm.add_blockdev('driver=file,filename=%s,node-name=ext3' % (extent3_path))
+
+    # Missing extent
+    iotests.log("== Missing extent ==")
+    iotests.log("")
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': 'node0',
+                          'size': size,
+                          'subformat': 'monolithicFlat' })
+    vm.shutdown()
+
+    # Correct extent
+    iotests.log("== Correct extent ==")
+    iotests.log("")
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': 'node0',
+                          'size': size,
+                          'subformat': 'monolithicFlat',
+                          'extents': ['ext1'] })
+    vm.shutdown()
+
+    # Extra extent
+    iotests.log("== Extra extent ==")
+    iotests.log("")
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': 'node0',
+                          'size': 512,
+                          'subformat': 'monolithicFlat',
+                          'extents': ['ext1', 'ext2', 'ext3'] })
+    vm.shutdown()
+
+    # Split formats
+    iotests.log("== Split formats ==")
+    iotests.log("")
+
+    for size in [ 512, 1073741824, 2147483648, 5368709120 ]:
+        for subfmt in [ 'twoGbMaxExtentFlat', 'twoGbMaxExtentSparse' ]:
+            iotests.log("= %s %d =" % (subfmt, size))
+            iotests.log("")
+
+            vm.launch()
+            blockdev_create(vm, { 'driver': imgfmt,
+                                  'file': 'node0',
+                                  'size': size,
+                                  'subformat': subfmt,
+                                  'extents': ['ext1', 'ext2', 'ext3'] })
+            vm.shutdown()
+
+            iotests.img_info_log(disk_path)
diff --git a/tests/qemu-iotests/237.out b/tests/qemu-iotests/237.out
new file mode 100644
index 0000000000..1aa9aad349
--- /dev/null
+++ b/tests/qemu-iotests/237.out
@@ -0,0 +1,347 @@
+=== Successful image creation (defaults) ===
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "node_name": "imgfile"}}
+{"return": {}}
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "imgfile", "size": 5368709120}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 5.0G (5368709120 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: monolithicSparse
+    extents:
+        [0]:
+            virtual size: 5368709120
+            filename: TEST_IMG
+            cluster size: 65536
+            format: 
+
+=== Successful image creation (inline blockdev-add, explicit defaults) ===
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "ide", "driver": "vmdk", "extents": [], "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk"}, "hwversion": "4", "size": 67108864, "subformat": "monolithicSparse", "zeroed-grain": false}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 64M (67108864 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: monolithicSparse
+    extents:
+        [0]:
+            virtual size: 67108864
+            filename: TEST_IMG
+            cluster size: 65536
+            format: 
+
+=== Successful image creation (with non-default options) ===
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "buslogic", "driver": "vmdk", "extents": [], "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk"}, "size": 33554432, "subformat": "monolithicSparse", "zeroed-grain": true}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 32M (33554432 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: monolithicSparse
+    extents:
+        [0]:
+            virtual size: 33554432
+            filename: TEST_IMG
+            cluster size: 65536
+            format: 
+
+=== Invalid BlockdevRef ===
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "this doesn't exist", "size": 33554432}}}
+{"return": {}}
+Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+=== Adapter types ===
+
+== Valid adapter types ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "ide", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "buslogic", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "lsilogic", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "legacyESX", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+== Invalid adapter types ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "foo", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter 'foo'"}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "IDE", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter 'IDE'"}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "legacyesx", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter 'legacyesx'"}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": 1, "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'options.adapter-type', expected: string"}}
+
+=== Other subformats ===
+
+Formatting 'TEST_DIR/PID-t.vmdk.1', fmt=vmdk size=0 compat6=off hwversion=undefined
+
+Formatting 'TEST_DIR/PID-t.vmdk.2', fmt=vmdk size=0 compat6=off hwversion=undefined
+
+Formatting 'TEST_DIR/PID-t.vmdk.3', fmt=vmdk size=0 compat6=off hwversion=undefined
+
+== Missing extent ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "node0", "size": 33554432, "subformat": "monolithicFlat"}}}
+{"return": {}}
+Job failed: Extent [0] not specified
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+== Correct extent ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 33554432, "subformat": "monolithicFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+== Extra extent ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "monolithicFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+== Split formats ==
+
+= twoGbMaxExtentFlat 512 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 512 (512 bytes)
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentFlat
+    extents:
+        [0]:
+            virtual size: 512
+            filename: TEST_IMG.1
+            format: FLAT
+
+= twoGbMaxExtentSparse 512 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentSparse"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 512 (512 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentSparse
+    extents:
+        [0]:
+            virtual size: 512
+            filename: TEST_IMG.1
+            cluster size: 65536
+            format: SPARSE
+
+= twoGbMaxExtentFlat 1073741824 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 1.0G (1073741824 bytes)
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentFlat
+    extents:
+        [0]:
+            virtual size: 1073741824
+            filename: TEST_IMG.1
+            format: FLAT
+
+= twoGbMaxExtentSparse 1073741824 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentSparse"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 1.0G (1073741824 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentSparse
+    extents:
+        [0]:
+            virtual size: 1073741824
+            filename: TEST_IMG.1
+            cluster size: 65536
+            format: SPARSE
+
+= twoGbMaxExtentFlat 2147483648 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 2.0G (2147483648 bytes)
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentFlat
+    extents:
+        [0]:
+            virtual size: 2147483648
+            filename: TEST_IMG.1
+            format: FLAT
+
+= twoGbMaxExtentSparse 2147483648 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentSparse"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 2.0G (2147483648 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentSparse
+    extents:
+        [0]:
+            virtual size: 2147483648
+            filename: TEST_IMG.1
+            cluster size: 65536
+            format: SPARSE
+
+= twoGbMaxExtentFlat 5368709120 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 5368709120, "subformat": "twoGbMaxExtentFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 5.0G (5368709120 bytes)
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentFlat
+    extents:
+        [0]:
+            virtual size: 2147483648
+            filename: TEST_IMG.1
+            format: FLAT
+        [1]:
+            virtual size: 2147483648
+            filename: TEST_IMG.2
+            format: FLAT
+        [2]:
+            virtual size: 1073741824
+            filename: TEST_IMG.3
+            format: FLAT
+
+= twoGbMaxExtentSparse 5368709120 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 5368709120, "subformat": "twoGbMaxExtentSparse"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 5.0G (5368709120 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentSparse
+    extents:
+        [0]:
+            virtual size: 2147483648
+            filename: TEST_IMG.1
+            cluster size: 65536
+            format: SPARSE
+        [1]:
+            virtual size: 2147483648
+            filename: TEST_IMG.2
+            cluster size: 65536
+            format: SPARSE
+        [2]:
+            virtual size: 1073741824
+            filename: TEST_IMG.3
+            cluster size: 65536
+            format: SPARSE
+
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 3e310c7f87..c87400f497 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -234,5 +234,6 @@
 234 auto quick migration
 235 auto quick
 236 auto quick
+237 rw auto quick
 238 auto quick
 239 rw auto quick
-- 
2.20.1

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

* [Qemu-devel] [PULL 12/27] vmdk: Reject excess extents in blockdev-create
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (10 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 11/27] iotests: Add VMDK tests for blockdev-create Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 13/27] block/vpc: Don't take address of fields in packed structs Kevin Wolf
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

Clarify that the number of extents provided in BlockdevCreateOptionsVmdk
must match the number of extents that will actually be used. Providing
more extents will result in an error now.

This requires adapting the test case to provide the right number of
extents.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
 qapi/block-core.json       |  3 ++-
 block/vmdk.c               | 29 ++++++++++++++++++++++++-----
 tests/qemu-iotests/237     |  6 +++++-
 tests/qemu-iotests/237.out | 13 +++++++------
 4 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index a5924b40af..5f17d67d71 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4184,7 +4184,8 @@
 #               twoGbMaxExtentSparse and twoGbMaxExtentFlat formats. For
 #               monolithicFlat, only one entry is required; for
 #               twoGbMaxExtent* formats, the number of entries required is
-#               calculated as extent_number = virtual_size / 2GB.
+#               calculated as extent_number = virtual_size / 2GB. Providing
+#               more extents than will be used is an error.
 # @subformat    The subformat of the VMDK image. Default: "monolithicSparse".
 # @backing-file The path of backing file. Default: no backing file is used.
 # @adapter-type The adapter type used to fill in the descriptor. Default: ide.
diff --git a/block/vmdk.c b/block/vmdk.c
index 5a162ee85c..682ad93aa1 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1970,6 +1970,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
 {
     int extent_idx;
     BlockBackend *blk = NULL;
+    BlockBackend *extent_blk;
     Error *local_err = NULL;
     char *desc = NULL;
     int ret = 0;
@@ -2107,7 +2108,6 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
     }
     extent_idx = 1;
     while (created_size < size) {
-        BlockBackend *extent_blk;
         int64_t cur_size = MIN(size - created_size, extent_size);
         extent_blk = extent_fn(cur_size, extent_idx, flat, split, compress,
                                zeroed_grain, opaque, errp);
@@ -2121,6 +2121,17 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
         extent_idx++;
         blk_unref(extent_blk);
     }
+
+    /* Check whether we got excess extents */
+    extent_blk = extent_fn(-1, extent_idx, flat, split, compress, zeroed_grain,
+                           opaque, NULL);
+    if (extent_blk) {
+        blk_unref(extent_blk);
+        error_setg(errp, "List of extents contains unused extents");
+        ret = -EINVAL;
+        goto exit;
+    }
+
     /* generate descriptor file */
     desc = g_strdup_printf(desc_template,
                            g_random_int(),
@@ -2181,6 +2192,12 @@ static BlockBackend *vmdk_co_create_opts_cb(int64_t size, int idx,
     char *ext_filename = NULL;
     char *rel_filename = NULL;
 
+    /* We're done, don't create excess extents. */
+    if (size == -1) {
+        assert(errp == NULL);
+        return NULL;
+    }
+
     if (idx == 0) {
         rel_filename = g_strdup_printf("%s%s", data->prefix, data->postfix);
     } else if (split) {
@@ -2342,10 +2359,12 @@ static BlockBackend *vmdk_co_create_cb(int64_t size, int idx,
     blk_set_allow_write_beyond_eof(blk, true);
     bdrv_unref(bs);
 
-    ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
-    if (ret) {
-        blk_unref(blk);
-        blk = NULL;
+    if (size != -1) {
+        ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
+        if (ret) {
+            blk_unref(blk);
+            blk = NULL;
+        }
     }
     return blk;
 }
diff --git a/tests/qemu-iotests/237 b/tests/qemu-iotests/237
index e04a1ac6be..251771d7fb 100755
--- a/tests/qemu-iotests/237
+++ b/tests/qemu-iotests/237
@@ -20,6 +20,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+import math
 import iotests
 from iotests import imgfmt
 
@@ -222,12 +223,15 @@ with iotests.FilePath('t.vmdk') as disk_path, \
             iotests.log("= %s %d =" % (subfmt, size))
             iotests.log("")
 
+            num_extents = math.ceil(size / 2.0**31)
+            extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ]
+
             vm.launch()
             blockdev_create(vm, { 'driver': imgfmt,
                                   'file': 'node0',
                                   'size': size,
                                   'subformat': subfmt,
-                                  'extents': ['ext1', 'ext2', 'ext3'] })
+                                  'extents': extents })
             vm.shutdown()
 
             iotests.img_info_log(disk_path)
diff --git a/tests/qemu-iotests/237.out b/tests/qemu-iotests/237.out
index 1aa9aad349..241c864369 100644
--- a/tests/qemu-iotests/237.out
+++ b/tests/qemu-iotests/237.out
@@ -154,6 +154,7 @@ Job failed: Extent [0] not specified
 
 {"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "monolithicFlat"}}}
 {"return": {}}
+Job failed: List of extents contains unused extents
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
 
@@ -161,7 +162,7 @@ Job failed: Extent [0] not specified
 
 = twoGbMaxExtentFlat 512 =
 
-{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentFlat"}}}
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentFlat"}}}
 {"return": {}}
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
@@ -181,7 +182,7 @@ Format specific information:
 
 = twoGbMaxExtentSparse 512 =
 
-{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentSparse"}}}
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentSparse"}}}
 {"return": {}}
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
@@ -203,7 +204,7 @@ Format specific information:
 
 = twoGbMaxExtentFlat 1073741824 =
 
-{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentFlat"}}}
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentFlat"}}}
 {"return": {}}
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
@@ -223,7 +224,7 @@ Format specific information:
 
 = twoGbMaxExtentSparse 1073741824 =
 
-{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentSparse"}}}
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentSparse"}}}
 {"return": {}}
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
@@ -245,7 +246,7 @@ Format specific information:
 
 = twoGbMaxExtentFlat 2147483648 =
 
-{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentFlat"}}}
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentFlat"}}}
 {"return": {}}
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
@@ -265,7 +266,7 @@ Format specific information:
 
 = twoGbMaxExtentSparse 2147483648 =
 
-{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentSparse"}}}
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentSparse"}}}
 {"return": {}}
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
-- 
2.20.1

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

* [Qemu-devel] [PULL 13/27] block/vpc: Don't take address of fields in packed structs
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (11 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 12/27] vmdk: Reject excess extents in blockdev-create Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 14/27] block/vdi: " Kevin Wolf
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Peter Maydell <peter.maydell@linaro.org>

Taking the address of a field in a packed struct is a bad idea, because
it might not be actually aligned enough for that pointer type (and
thus cause a crash on dereference on some host architectures). Newer
versions of clang warn about this. Avoid the bug by generating the
UUID into a local variable which is definitely safely aligned and
then copying it into place.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vpc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/block/vpc.c b/block/vpc.c
index d886465b7e..52ab717642 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -979,6 +979,7 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
     int64_t total_size;
     int disk_type;
     int ret = -EIO;
+    QemuUUID uuid;
 
     assert(opts->driver == BLOCKDEV_DRIVER_VPC);
     vpc_opts = &opts->u.vpc;
@@ -1062,7 +1063,8 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
 
     footer->type = cpu_to_be32(disk_type);
 
-    qemu_uuid_generate(&footer->uuid);
+    qemu_uuid_generate(&uuid);
+    footer->uuid = uuid;
 
     footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE));
 
-- 
2.20.1

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

* [Qemu-devel] [PULL 14/27] block/vdi: Don't take address of fields in packed structs
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (12 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 13/27] block/vpc: Don't take address of fields in packed structs Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 15/27] uuid: Make qemu_uuid_bswap() take and return a QemuUUID Kevin Wolf
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Peter Maydell <peter.maydell@linaro.org>

Taking the address of a field in a packed struct is a bad idea, because
it might not be actually aligned enough for that pointer type (and
thus cause a crash on dereference on some host architectures). Newer
versions of clang warn about this.

Instead of passing UUID related functions the address of a possibly
unaligned QemuUUID struct, use local variables and then copy to/from
the struct field as appropriate.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vdi.c | 38 +++++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/block/vdi.c b/block/vdi.c
index 2380daa583..4cc726047c 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -235,7 +235,8 @@ static void vdi_header_to_le(VdiHeader *header)
 
 static void vdi_header_print(VdiHeader *header)
 {
-    char uuid[37];
+    char uuidstr[37];
+    QemuUUID uuid;
     logout("text        %s", header->text);
     logout("signature   0x%08x\n", header->signature);
     logout("header size 0x%04x\n", header->header_size);
@@ -254,14 +255,18 @@ static void vdi_header_print(VdiHeader *header)
     logout("block extra 0x%04x\n", header->block_extra);
     logout("blocks tot. 0x%04x\n", header->blocks_in_image);
     logout("blocks all. 0x%04x\n", header->blocks_allocated);
-    qemu_uuid_unparse(&header->uuid_image, uuid);
-    logout("uuid image  %s\n", uuid);
-    qemu_uuid_unparse(&header->uuid_last_snap, uuid);
-    logout("uuid snap   %s\n", uuid);
-    qemu_uuid_unparse(&header->uuid_link, uuid);
-    logout("uuid link   %s\n", uuid);
-    qemu_uuid_unparse(&header->uuid_parent, uuid);
-    logout("uuid parent %s\n", uuid);
+    uuid = header->uuid_image;
+    qemu_uuid_unparse(&uuid, uuidstr);
+    logout("uuid image  %s\n", uuidstr);
+    uuid = header->uuid_last_snap;
+    qemu_uuid_unparse(&uuid, uuidstr);
+    logout("uuid snap   %s\n", uuidstr);
+    uuid = header->uuid_link;
+    qemu_uuid_unparse(&uuid, uuidstr);
+    logout("uuid link   %s\n", uuidstr);
+    uuid = header->uuid_parent;
+    qemu_uuid_unparse(&uuid, uuidstr);
+    logout("uuid parent %s\n", uuidstr);
 }
 
 static int coroutine_fn vdi_co_check(BlockDriverState *bs, BdrvCheckResult *res,
@@ -368,6 +373,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
     size_t bmap_size;
     int ret;
     Error *local_err = NULL;
+    QemuUUID uuid_link, uuid_parent;
 
     bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
                                false, errp);
@@ -395,6 +401,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
         goto fail;
     }
 
+    uuid_link = header.uuid_link;
+    uuid_parent = header.uuid_parent;
+
     if (header.disk_size % SECTOR_SIZE != 0) {
         /* 'VBoxManage convertfromraw' can create images with odd disk sizes.
            We accept them but round the disk size to the next multiple of
@@ -444,11 +453,11 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
                    (uint64_t)header.blocks_in_image * header.block_size);
         ret = -ENOTSUP;
         goto fail;
-    } else if (!qemu_uuid_is_null(&header.uuid_link)) {
+    } else if (!qemu_uuid_is_null(&uuid_link)) {
         error_setg(errp, "unsupported VDI image (non-NULL link UUID)");
         ret = -ENOTSUP;
         goto fail;
-    } else if (!qemu_uuid_is_null(&header.uuid_parent)) {
+    } else if (!qemu_uuid_is_null(&uuid_parent)) {
         error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
         ret = -ENOTSUP;
         goto fail;
@@ -733,6 +742,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
     BlockDriverState *bs_file = NULL;
     BlockBackend *blk = NULL;
     uint32_t *bmap = NULL;
+    QemuUUID uuid;
 
     assert(create_options->driver == BLOCKDEV_DRIVER_VDI);
     vdi_opts = &create_options->u.vdi;
@@ -819,8 +829,10 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
     if (image_type == VDI_TYPE_STATIC) {
         header.blocks_allocated = blocks;
     }
-    qemu_uuid_generate(&header.uuid_image);
-    qemu_uuid_generate(&header.uuid_last_snap);
+    qemu_uuid_generate(&uuid);
+    header.uuid_image = uuid;
+    qemu_uuid_generate(&uuid);
+    header.uuid_last_snap = uuid;
     /* There is no need to set header.uuid_link or header.uuid_parent here. */
     if (VDI_DEBUG) {
         vdi_header_print(&header);
-- 
2.20.1

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

* [Qemu-devel] [PULL 15/27] uuid: Make qemu_uuid_bswap() take and return a QemuUUID
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (13 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 14/27] block/vdi: " Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 16/27] block: Apply auto-read-only for ro-whitelist drivers Kevin Wolf
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Peter Maydell <peter.maydell@linaro.org>

Currently qemu_uuid_bswap() takes a pointer to the QemuUUID to
be byte-swapped. This means it can't be used when the UUID
to be swapped is in a packed member of a struct. It's also
out of line with the general bswap*() functions we provide
in bswap.h, which take the value to be swapped and return it.

Make qemu_uuid_bswap() take a QemuUUID and return the swapped version.

This fixes some clang warnings about taking the address of
a packed struct member in block/vdi.c.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 include/qemu/uuid.h  |  2 +-
 block/vdi.c          | 16 ++++++++--------
 hw/acpi/vmgenid.c    |  6 ++----
 tests/vmgenid-test.c |  2 +-
 util/uuid.c          | 10 +++++-----
 5 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/include/qemu/uuid.h b/include/qemu/uuid.h
index 09489ce5c5..037357d990 100644
--- a/include/qemu/uuid.h
+++ b/include/qemu/uuid.h
@@ -56,6 +56,6 @@ char *qemu_uuid_unparse_strdup(const QemuUUID *uuid);
 
 int qemu_uuid_parse(const char *str, QemuUUID *uuid);
 
-void qemu_uuid_bswap(QemuUUID *uuid);
+QemuUUID qemu_uuid_bswap(QemuUUID uuid);
 
 #endif
diff --git a/block/vdi.c b/block/vdi.c
index 4cc726047c..0c34f6bae4 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -203,10 +203,10 @@ static void vdi_header_to_cpu(VdiHeader *header)
     header->block_extra = le32_to_cpu(header->block_extra);
     header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
     header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
-    qemu_uuid_bswap(&header->uuid_image);
-    qemu_uuid_bswap(&header->uuid_last_snap);
-    qemu_uuid_bswap(&header->uuid_link);
-    qemu_uuid_bswap(&header->uuid_parent);
+    header->uuid_image = qemu_uuid_bswap(header->uuid_image);
+    header->uuid_last_snap = qemu_uuid_bswap(header->uuid_last_snap);
+    header->uuid_link = qemu_uuid_bswap(header->uuid_link);
+    header->uuid_parent = qemu_uuid_bswap(header->uuid_parent);
 }
 
 static void vdi_header_to_le(VdiHeader *header)
@@ -227,10 +227,10 @@ static void vdi_header_to_le(VdiHeader *header)
     header->block_extra = cpu_to_le32(header->block_extra);
     header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
     header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
-    qemu_uuid_bswap(&header->uuid_image);
-    qemu_uuid_bswap(&header->uuid_last_snap);
-    qemu_uuid_bswap(&header->uuid_link);
-    qemu_uuid_bswap(&header->uuid_parent);
+    header->uuid_image = qemu_uuid_bswap(header->uuid_image);
+    header->uuid_last_snap = qemu_uuid_bswap(header->uuid_last_snap);
+    header->uuid_link = qemu_uuid_bswap(header->uuid_link);
+    header->uuid_parent = qemu_uuid_bswap(header->uuid_parent);
 }
 
 static void vdi_header_print(VdiHeader *header)
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
index d78b579a20..02717a8b0d 100644
--- a/hw/acpi/vmgenid.c
+++ b/hw/acpi/vmgenid.c
@@ -30,8 +30,7 @@ void vmgenid_build_acpi(VmGenIdState *vms, GArray *table_data, GArray *guid,
      * first, since that's what the guest expects
      */
     g_array_set_size(guid, VMGENID_FW_CFG_SIZE - ARRAY_SIZE(guid_le.data));
-    guid_le = vms->guid;
-    qemu_uuid_bswap(&guid_le);
+    guid_le = qemu_uuid_bswap(vms->guid);
     /* The GUID is written at a fixed offset into the fw_cfg file
      * in order to implement the "OVMF SDT Header probe suppressor"
      * see docs/specs/vmgenid.txt for more details
@@ -149,8 +148,7 @@ static void vmgenid_update_guest(VmGenIdState *vms)
              * however, will expect the fields to be little-endian.
              * Perform a byte swap immediately before writing.
              */
-            guid_le = vms->guid;
-            qemu_uuid_bswap(&guid_le);
+            guid_le = qemu_uuid_bswap(vms->guid);
             /* The GUID is written at a fixed offset into the fw_cfg file
              * in order to implement the "OVMF SDT Header probe suppressor"
              * see docs/specs/vmgenid.txt for more details.
diff --git a/tests/vmgenid-test.c b/tests/vmgenid-test.c
index 52cdd83ec0..ae38ee5ac0 100644
--- a/tests/vmgenid-test.c
+++ b/tests/vmgenid-test.c
@@ -88,7 +88,7 @@ static void read_guid_from_memory(QTestState *qts, QemuUUID *guid)
     /* The GUID is in little-endian format in the guest, while QEMU
      * uses big-endian.  Swap after reading.
      */
-    qemu_uuid_bswap(guid);
+    *guid = qemu_uuid_bswap(*guid);
 }
 
 static void read_guid_from_monitor(QTestState *qts, QemuUUID *guid)
diff --git a/util/uuid.c b/util/uuid.c
index ebf06c049a..5787f0978c 100644
--- a/util/uuid.c
+++ b/util/uuid.c
@@ -110,10 +110,10 @@ int qemu_uuid_parse(const char *str, QemuUUID *uuid)
 
 /* Swap from UUID format endian (BE) to the opposite or vice versa.
  */
-void qemu_uuid_bswap(QemuUUID *uuid)
+QemuUUID qemu_uuid_bswap(QemuUUID uuid)
 {
-    assert(QEMU_PTR_IS_ALIGNED(uuid, sizeof(uint32_t)));
-    bswap32s(&uuid->fields.time_low);
-    bswap16s(&uuid->fields.time_mid);
-    bswap16s(&uuid->fields.time_high_and_version);
+    bswap32s(&uuid.fields.time_low);
+    bswap16s(&uuid.fields.time_mid);
+    bswap16s(&uuid.fields.time_high_and_version);
+    return uuid;
 }
-- 
2.20.1

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

* [Qemu-devel] [PULL 16/27] block: Apply auto-read-only for ro-whitelist drivers
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (14 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 15/27] uuid: Make qemu_uuid_bswap() take and return a QemuUUID Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 17/27] block: Remove blk_attach_dev_legacy() / legacy_dev code Kevin Wolf
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

If QEMU was configured with a driver in --block-drv-ro-whitelist, trying
to use that driver read-write resulted in an error message even if
auto-read-only=on was set.

Consider auto-read-only=on for the whitelist checking and use it to
automatically degrade to read-only for block drivers on the read-only
whitelist.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/block.c b/block.c
index 0c5d1f11a5..5a4d27173e 100644
--- a/block.c
+++ b/block.c
@@ -1438,13 +1438,19 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
     bs->read_only = !(bs->open_flags & BDRV_O_RDWR);
 
     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {
-        error_setg(errp,
-                   !bs->read_only && bdrv_is_whitelisted(drv, true)
-                        ? "Driver '%s' can only be used for read-only devices"
-                        : "Driver '%s' is not whitelisted",
-                   drv->format_name);
-        ret = -ENOTSUP;
-        goto fail_opts;
+        if (!bs->read_only && bdrv_is_whitelisted(drv, true)) {
+            ret = bdrv_apply_auto_read_only(bs, NULL, NULL);
+        } else {
+            ret = -ENOTSUP;
+        }
+        if (ret < 0) {
+            error_setg(errp,
+                       !bs->read_only && bdrv_is_whitelisted(drv, true)
+                       ? "Driver '%s' can only be used for read-only devices"
+                       : "Driver '%s' is not whitelisted",
+                       drv->format_name);
+            goto fail_opts;
+        }
     }
 
     /* bdrv_new() and bdrv_close() make it so */
-- 
2.20.1

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

* [Qemu-devel] [PULL 17/27] block: Remove blk_attach_dev_legacy() / legacy_dev code
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (15 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 16/27] block: Apply auto-read-only for ro-whitelist drivers Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 18/27] block: Eliminate the S_1KiB, S_2KiB, ... macros Kevin Wolf
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Thomas Huth <thuth@redhat.com>

The last user of blk_attach_dev_legacy() was the code in xen_disk which
has recently been reworked. Now there is no user for this legacy function
anymore. Thus we can finally remove all code related to the "legacy_dev"
flag, too, and turn the related "void *" in block-backend.c into proper
"DeviceState *" to fix some of the remaining TODOs there.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 include/sysemu/block-backend.h |  5 ++--
 block/block-backend.c          | 54 ++++++----------------------------
 2 files changed, 11 insertions(+), 48 deletions(-)

diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index c8f816a200..832a4bf168 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -110,9 +110,8 @@ void blk_iostatus_disable(BlockBackend *blk);
 void blk_iostatus_reset(BlockBackend *blk);
 void blk_iostatus_set_err(BlockBackend *blk, int error);
 int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
-void blk_attach_dev_legacy(BlockBackend *blk, void *dev);
-void blk_detach_dev(BlockBackend *blk, void *dev);
-void *blk_get_attached_dev(BlockBackend *blk);
+void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
+DeviceState *blk_get_attached_dev(BlockBackend *blk);
 char *blk_get_attached_dev_id(BlockBackend *blk);
 BlockBackend *blk_by_dev(void *dev);
 BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
diff --git a/block/block-backend.c b/block/block-backend.c
index f0be0d9039..f6ea824308 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -47,9 +47,7 @@ struct BlockBackend {
     QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
     BlockBackendPublic public;
 
-    void *dev;                  /* attached device model, if any */
-    bool legacy_dev;            /* true if dev is not a DeviceState */
-    /* TODO change to DeviceState when all users are qdevified */
+    DeviceState *dev;           /* attached device model, if any */
     const BlockDevOps *dev_ops;
     void *dev_opaque;
 
@@ -836,7 +834,11 @@ void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
     *shared_perm = blk->shared_perm;
 }
 
-static int blk_do_attach_dev(BlockBackend *blk, void *dev)
+/*
+ * Attach device model @dev to @blk.
+ * Return 0 on success, -EBUSY when a device model is attached already.
+ */
+int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
 {
     if (blk->dev) {
         return -EBUSY;
@@ -851,40 +853,16 @@ static int blk_do_attach_dev(BlockBackend *blk, void *dev)
 
     blk_ref(blk);
     blk->dev = dev;
-    blk->legacy_dev = false;
     blk_iostatus_reset(blk);
 
     return 0;
 }
 
-/*
- * Attach device model @dev to @blk.
- * Return 0 on success, -EBUSY when a device model is attached already.
- */
-int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
-{
-    return blk_do_attach_dev(blk, dev);
-}
-
-/*
- * Attach device model @dev to @blk.
- * @blk must not have a device model attached already.
- * TODO qdevified devices don't use this, remove when devices are qdevified
- */
-void blk_attach_dev_legacy(BlockBackend *blk, void *dev)
-{
-    if (blk_do_attach_dev(blk, dev) < 0) {
-        abort();
-    }
-    blk->legacy_dev = true;
-}
-
 /*
  * Detach device model @dev from @blk.
  * @dev must be currently attached to @blk.
  */
-void blk_detach_dev(BlockBackend *blk, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
+void blk_detach_dev(BlockBackend *blk, DeviceState *dev)
 {
     assert(blk->dev == dev);
     blk->dev = NULL;
@@ -898,8 +876,7 @@ void blk_detach_dev(BlockBackend *blk, void *dev)
 /*
  * Return the device model attached to @blk if any, else null.
  */
-void *blk_get_attached_dev(BlockBackend *blk)
-/* TODO change to return DeviceState * when all users are qdevified */
+DeviceState *blk_get_attached_dev(BlockBackend *blk)
 {
     return blk->dev;
 }
@@ -908,10 +885,7 @@ void *blk_get_attached_dev(BlockBackend *blk)
  * device attached to the BlockBackend. */
 char *blk_get_attached_dev_id(BlockBackend *blk)
 {
-    DeviceState *dev;
-
-    assert(!blk->legacy_dev);
-    dev = blk->dev;
+    DeviceState *dev = blk->dev;
 
     if (!dev) {
         return g_strdup("");
@@ -949,11 +923,6 @@ BlockBackend *blk_by_dev(void *dev)
 void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
                      void *opaque)
 {
-    /* All drivers that use blk_set_dev_ops() are qdevified and we want to keep
-     * it that way, so we can assume blk->dev, if present, is a DeviceState if
-     * blk->dev_ops is set. Non-device users may use dev_ops without device. */
-    assert(!blk->legacy_dev);
-
     blk->dev_ops = ops;
     blk->dev_opaque = opaque;
 
@@ -979,8 +948,6 @@ void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp)
         bool tray_was_open, tray_is_open;
         Error *local_err = NULL;
 
-        assert(!blk->legacy_dev);
-
         tray_was_open = blk_dev_is_tray_open(blk);
         blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err);
         if (local_err) {
@@ -1783,9 +1750,6 @@ void blk_eject(BlockBackend *blk, bool eject_flag)
     BlockDriverState *bs = blk_bs(blk);
     char *id;
 
-    /* blk_eject is only called by qdevified devices */
-    assert(!blk->legacy_dev);
-
     if (bs) {
         bdrv_eject(bs, eject_flag);
     }
-- 
2.20.1

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

* [Qemu-devel] [PULL 18/27] block: Eliminate the S_1KiB, S_2KiB, ... macros
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (16 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 17/27] block: Remove blk_attach_dev_legacy() / legacy_dev code Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 19/27] virtio-scsi: Move BlockBackend back to the main AioContext on unplug Kevin Wolf
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Markus Armbruster <armbru@redhat.com>

We define 54 macros for the powers of two >= 1024.  We use six, in six
macro definitions.  Four of them could just as well use the common MiB
macro, so do that.  The remaining two can't, because they get passed
to stringify.  Replace the macro by the literal number there.
Slightly harder to read in one instance (1048576 vs. S_1MiB), so add a
comment there.  The other instance is a wash: 65536 vs S_64KiB.  65536
has been good enough for more than seven years there.

This effectively reverts commit 540b8492618 and 1240ac558d3.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2.h        | 10 +++---
 include/qemu/units.h | 73 --------------------------------------------
 block/vdi.c          |  3 +-
 3 files changed, 7 insertions(+), 79 deletions(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index 438a1dee9e..32cce9eee2 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -50,11 +50,11 @@
 
 /* 8 MB refcount table is enough for 2 PB images at 64k cluster size
  * (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
-#define QCOW_MAX_REFTABLE_SIZE S_8MiB
+#define QCOW_MAX_REFTABLE_SIZE (8 * MiB)
 
 /* 32 MB L1 table is enough for 2 PB images at 64k cluster size
  * (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
-#define QCOW_MAX_L1_SIZE S_32MiB
+#define QCOW_MAX_L1_SIZE (32 * MiB)
 
 /* Allow for an average of 1k per snapshot table entry, should be plenty of
  * space for snapshot names and IDs */
@@ -81,15 +81,15 @@
 #define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */
 
 #ifdef CONFIG_LINUX
-#define DEFAULT_L2_CACHE_MAX_SIZE S_32MiB
+#define DEFAULT_L2_CACHE_MAX_SIZE (32 * MiB)
 #define DEFAULT_CACHE_CLEAN_INTERVAL 600  /* seconds */
 #else
-#define DEFAULT_L2_CACHE_MAX_SIZE S_8MiB
+#define DEFAULT_L2_CACHE_MAX_SIZE (8 * MiB)
 /* Cache clean interval is currently available only on Linux, so must be 0 */
 #define DEFAULT_CACHE_CLEAN_INTERVAL 0
 #endif
 
-#define DEFAULT_CLUSTER_SIZE S_64KiB
+#define DEFAULT_CLUSTER_SIZE 65536
 
 #define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts"
 #define QCOW2_OPT_DISCARD_REQUEST "pass-discard-request"
diff --git a/include/qemu/units.h b/include/qemu/units.h
index 1c959d182e..692db3fbb2 100644
--- a/include/qemu/units.h
+++ b/include/qemu/units.h
@@ -17,77 +17,4 @@
 #define PiB     (INT64_C(1) << 50)
 #define EiB     (INT64_C(1) << 60)
 
-/*
- * The following lookup table is intended to be used when a literal string of
- * the number of bytes is required (for example if it needs to be stringified).
- * It can also be used for generic shortcuts of power-of-two sizes.
- * This table is generated using the AWK script below:
- *
- *  BEGIN {
- *      suffix="KMGTPE";
- *      for(i=10; i<64; i++) {
- *          val=2**i;
- *          s=substr(suffix, int(i/10), 1);
- *          n=2**(i%10);
- *          pad=21-int(log(n)/log(10));
- *          printf("#define S_%d%siB %*d\n", n, s, pad, val);
- *      }
- *  }
- */
-
-#define S_1KiB                  1024
-#define S_2KiB                  2048
-#define S_4KiB                  4096
-#define S_8KiB                  8192
-#define S_16KiB                16384
-#define S_32KiB                32768
-#define S_64KiB                65536
-#define S_128KiB              131072
-#define S_256KiB              262144
-#define S_512KiB              524288
-#define S_1MiB               1048576
-#define S_2MiB               2097152
-#define S_4MiB               4194304
-#define S_8MiB               8388608
-#define S_16MiB             16777216
-#define S_32MiB             33554432
-#define S_64MiB             67108864
-#define S_128MiB           134217728
-#define S_256MiB           268435456
-#define S_512MiB           536870912
-#define S_1GiB            1073741824
-#define S_2GiB            2147483648
-#define S_4GiB            4294967296
-#define S_8GiB            8589934592
-#define S_16GiB          17179869184
-#define S_32GiB          34359738368
-#define S_64GiB          68719476736
-#define S_128GiB        137438953472
-#define S_256GiB        274877906944
-#define S_512GiB        549755813888
-#define S_1TiB         1099511627776
-#define S_2TiB         2199023255552
-#define S_4TiB         4398046511104
-#define S_8TiB         8796093022208
-#define S_16TiB       17592186044416
-#define S_32TiB       35184372088832
-#define S_64TiB       70368744177664
-#define S_128TiB     140737488355328
-#define S_256TiB     281474976710656
-#define S_512TiB     562949953421312
-#define S_1PiB      1125899906842624
-#define S_2PiB      2251799813685248
-#define S_4PiB      4503599627370496
-#define S_8PiB      9007199254740992
-#define S_16PiB    18014398509481984
-#define S_32PiB    36028797018963968
-#define S_64PiB    72057594037927936
-#define S_128PiB  144115188075855872
-#define S_256PiB  288230376151711744
-#define S_512PiB  576460752303423488
-#define S_1EiB   1152921504606846976
-#define S_2EiB   2305843009213693952
-#define S_4EiB   4611686018427387904
-#define S_8EiB   9223372036854775808
-
 #endif
diff --git a/block/vdi.c b/block/vdi.c
index 0c34f6bae4..e1c42ad732 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -85,7 +85,8 @@
 #define BLOCK_OPT_STATIC "static"
 
 #define SECTOR_SIZE 512
-#define DEFAULT_CLUSTER_SIZE S_1MiB
+#define DEFAULT_CLUSTER_SIZE 1048576
+/* Note: can't use 1 * MiB, because it's passed to stringify() */
 
 #if defined(CONFIG_VDI_DEBUG)
 #define VDI_DEBUG 1
-- 
2.20.1

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

* [Qemu-devel] [PULL 19/27] virtio-scsi: Move BlockBackend back to the main AioContext on unplug
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (17 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 18/27] block: Eliminate the S_1KiB, S_2KiB, ... macros Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 20/27] scsi-disk: Acquire the AioContext in scsi_*_realize() Kevin Wolf
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Alberto Garcia <berto@igalia.com>

This fixes a crash when attaching a disk to a SCSI device using
iothreads, then detaching it and reattaching it again. Test case
included.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/scsi/virtio-scsi.c      |  6 +++
 tests/qemu-iotests/240     | 89 ++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/240.out | 18 ++++++++
 tests/qemu-iotests/group   |  1 +
 4 files changed, 114 insertions(+)
 create mode 100755 tests/qemu-iotests/240
 create mode 100644 tests/qemu-iotests/240.out

diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 3aa99717e2..e1f7b208c7 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -824,6 +824,12 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
         virtio_scsi_release(s);
     }
 
+    if (s->ctx) {
+        virtio_scsi_acquire(s);
+        blk_set_aio_context(sd->conf.blk, qemu_get_aio_context());
+        virtio_scsi_release(s);
+    }
+
     qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
 }
 
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
new file mode 100755
index 0000000000..ead7ee08eb
--- /dev/null
+++ b/tests/qemu-iotests/240
@@ -0,0 +1,89 @@
+#!/bin/bash
+#
+# Test hot plugging and unplugging with iothreads
+#
+# Copyright (C) 2019 Igalia, S.L.
+# Author: Alberto Garcia <berto@igalia.com>
+#
+# 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=berto@igalia.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1	# failure is the default!
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt generic
+_supported_proto generic
+_supported_os Linux
+
+do_run_qemu()
+{
+    echo Testing: "$@"
+    $QEMU -nographic -qmp stdio -serial none "$@"
+    echo
+}
+
+# Remove QMP events from (pretty-printed) output. Doesn't handle
+# nested dicts correctly, but we don't get any of those in this test.
+_filter_qmp_events()
+{
+    tr '\n' '\t' | sed -e \
+	's/{\s*"timestamp":\s*{[^}]*},\s*"event":[^,}]*\(,\s*"data":\s*{[^}]*}\)\?\s*}\s*//g' \
+	| tr '\t' '\n'
+}
+
+run_qemu()
+{
+    do_run_qemu "$@" 2>&1 | _filter_qmp | _filter_qmp_events
+}
+
+case "$QEMU_DEFAULT_MACHINE" in
+  s390-ccw-virtio)
+      virtio_scsi=virtio-scsi-ccw
+      ;;
+  *)
+      virtio_scsi=virtio-scsi-pci
+      ;;
+esac
+
+echo
+echo === Unplug a SCSI disk and then plug it again ===
+echo
+
+run_qemu <<EOF
+{ "execute": "qmp_capabilities" }
+{ "execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0"}}
+{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi0", "driver": "${virtio_scsi}", "iothread": "iothread0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi-hd0", "driver": "scsi-hd", "drive": "hd0"}}
+{ "execute": "device_del", "arguments": {"id": "scsi-hd0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi-hd0", "driver": "scsi-hd", "drive": "hd0"}}
+{ "execute": "device_del", "arguments": {"id": "scsi-hd0"}}
+{ "execute": "device_del", "arguments": {"id": "scsi0"}}
+{ "execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
+{ "execute": "quit"}
+EOF
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
new file mode 100644
index 0000000000..432d98111c
--- /dev/null
+++ b/tests/qemu-iotests/240.out
@@ -0,0 +1,18 @@
+QA output created by 240
+
+=== Unplug a SCSI disk and then plug it again ===
+
+Testing:
+QMP_VERSION
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index c87400f497..959ffe85fc 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -237,3 +237,4 @@
 237 rw auto quick
 238 auto quick
 239 rw auto quick
+240 auto quick
-- 
2.20.1

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

* [Qemu-devel] [PULL 20/27] scsi-disk: Acquire the AioContext in scsi_*_realize()
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (18 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 19/27] virtio-scsi: Move BlockBackend back to the main AioContext on unplug Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 21/27] virtio-scsi: Forbid devices with different iothreads sharing a blockdev Kevin Wolf
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Alberto Garcia <berto@igalia.com>

This fixes a crash when attaching two disks with the same blockdev to
a SCSI device that is using iothreads. Test case included.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/scsi/scsi-disk.c        | 23 ++++++++++++++++++++---
 tests/qemu-iotests/240     | 18 ++++++++++++++++++
 tests/qemu-iotests/240.out | 16 ++++++++++++++++
 3 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 0e9027c8f3..b049026219 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2381,10 +2381,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
 static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+    AioContext *ctx = NULL;
     /* can happen for devices without drive. The error message for missing
      * backend will be issued in scsi_realize
      */
     if (s->qdev.conf.blk) {
+        ctx = blk_get_aio_context(s->qdev.conf.blk);
+        aio_context_acquire(ctx);
         blkconf_blocksizes(&s->qdev.conf);
     }
     s->qdev.blocksize = s->qdev.conf.logical_block_size;
@@ -2393,11 +2396,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
         s->product = g_strdup("QEMU HARDDISK");
     }
     scsi_realize(&s->qdev, errp);
+    if (ctx) {
+        aio_context_release(ctx);
+    }
 }
 
 static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+    AioContext *ctx;
     int ret;
 
     if (!dev->conf.blk) {
@@ -2408,6 +2415,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
         assert(ret == 0);
     }
 
+    ctx = blk_get_aio_context(dev->conf.blk);
+    aio_context_acquire(ctx);
     s->qdev.blocksize = 2048;
     s->qdev.type = TYPE_ROM;
     s->features |= 1 << SCSI_DISK_F_REMOVABLE;
@@ -2415,6 +2424,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
         s->product = g_strdup("QEMU CD-ROM");
     }
     scsi_realize(&s->qdev, errp);
+    aio_context_release(ctx);
 }
 
 static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
@@ -2553,6 +2563,7 @@ static int get_device_type(SCSIDiskState *s)
 static void scsi_block_realize(SCSIDevice *dev, Error **errp)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+    AioContext *ctx;
     int sg_version;
     int rc;
 
@@ -2567,6 +2578,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
                           "be removed in a future version");
     }
 
+    ctx = blk_get_aio_context(s->qdev.conf.blk);
+    aio_context_acquire(ctx);
+
     /* check we are using a driver managing SG_IO (version 3 and after) */
     rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
     if (rc < 0) {
@@ -2574,18 +2588,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
         if (rc != -EPERM) {
             error_append_hint(errp, "Is this a SCSI device?\n");
         }
-        return;
+        goto out;
     }
     if (sg_version < 30000) {
         error_setg(errp, "scsi generic interface too old");
-        return;
+        goto out;
     }
 
     /* get device type from INQUIRY data */
     rc = get_device_type(s);
     if (rc < 0) {
         error_setg(errp, "INQUIRY failed");
-        return;
+        goto out;
     }
 
     /* Make a guess for the block size, we'll fix it when the guest sends.
@@ -2605,6 +2619,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
 
     scsi_realize(&s->qdev, errp);
     scsi_generic_read_device_inquiry(&s->qdev);
+
+out:
+    aio_context_release(ctx);
 }
 
 typedef struct SCSIBlockReq {
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
index ead7ee08eb..5d499c9a00 100755
--- a/tests/qemu-iotests/240
+++ b/tests/qemu-iotests/240
@@ -83,6 +83,24 @@ run_qemu <<EOF
 { "execute": "quit"}
 EOF
 
+echo
+echo === Attach two SCSI disks using the same block device and the same iothread ===
+echo
+
+run_qemu <<EOF
+{ "execute": "qmp_capabilities" }
+{ "execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true}}
+{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi0", "driver": "${virtio_scsi}", "iothread": "iothread0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi-hd0", "driver": "scsi-hd", "drive": "hd0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi-hd1", "driver": "scsi-hd", "drive": "hd0"}}
+{ "execute": "device_del", "arguments": {"id": "scsi-hd0"}}
+{ "execute": "device_del", "arguments": {"id": "scsi-hd1"}}
+{ "execute": "device_del", "arguments": {"id": "scsi0"}}
+{ "execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
+{ "execute": "quit"}
+EOF
+
 # success, all done
 echo "*** done"
 rm -f $seq.full
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
index 432d98111c..701cb5c7d2 100644
--- a/tests/qemu-iotests/240.out
+++ b/tests/qemu-iotests/240.out
@@ -2,6 +2,22 @@ QA output created by 240
 
 === Unplug a SCSI disk and then plug it again ===
 
+Testing:
+QMP_VERSION
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+
+=== Attach two SCSI disks using the same block device and the same iothread ===
+
 Testing:
 QMP_VERSION
 {"return": {}}
-- 
2.20.1

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

* [Qemu-devel] [PULL 21/27] virtio-scsi: Forbid devices with different iothreads sharing a blockdev
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (19 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 20/27] scsi-disk: Acquire the AioContext in scsi_*_realize() Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 22/27] iotests: Filter second BLOCK_JOB_ERROR from 229 Kevin Wolf
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Alberto Garcia <berto@igalia.com>

This patch forbids attaching a disk to a SCSI device if its using a
different AioContext. Test case included.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/scsi/virtio-scsi.c      |  7 +++++++
 tests/qemu-iotests/240     | 22 ++++++++++++++++++++++
 tests/qemu-iotests/240.out | 20 ++++++++++++++++++++
 3 files changed, 49 insertions(+)

diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index e1f7b208c7..eb90288f47 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -791,9 +791,16 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
     SCSIDevice *sd = SCSI_DEVICE(dev);
 
     if (s->ctx && !s->dataplane_fenced) {
+        AioContext *ctx;
         if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
             return;
         }
+        ctx = blk_get_aio_context(sd->conf.blk);
+        if (ctx != s->ctx && ctx != qemu_get_aio_context()) {
+            error_setg(errp, "Cannot attach a blockdev that is using "
+                       "a different iothread");
+            return;
+        }
         virtio_scsi_acquire(s);
         blk_set_aio_context(sd->conf.blk, s->ctx);
         virtio_scsi_release(s);
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
index 5d499c9a00..65cc3b39b1 100755
--- a/tests/qemu-iotests/240
+++ b/tests/qemu-iotests/240
@@ -101,6 +101,28 @@ run_qemu <<EOF
 { "execute": "quit"}
 EOF
 
+echo
+echo === Attach two SCSI disks using the same block device but different iothreads ===
+echo
+
+run_qemu <<EOF
+{ "execute": "qmp_capabilities" }
+{ "execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true}}
+{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread0"}}
+{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread1"}}
+{ "execute": "device_add", "arguments": {"id": "scsi0", "driver": "${virtio_scsi}", "iothread": "iothread0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi1", "driver": "${virtio_scsi}", "iothread": "iothread1"}}
+{ "execute": "device_add", "arguments": {"id": "scsi-hd0", "driver": "scsi-hd", "drive": "hd0", "bus": "scsi0.0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi-hd1", "driver": "scsi-hd", "drive": "hd0", "bus": "scsi1.0"}}
+{ "execute": "device_del", "arguments": {"id": "scsi-hd0"}}
+{ "execute": "device_add", "arguments": {"id": "scsi-hd1", "driver": "scsi-hd", "drive": "hd0", "bus": "scsi1.0"}}
+{ "execute": "device_del", "arguments": {"id": "scsi-hd1"}}
+{ "execute": "device_del", "arguments": {"id": "scsi0"}}
+{ "execute": "device_del", "arguments": {"id": "scsi1"}}
+{ "execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
+{ "execute": "quit"}
+EOF
+
 # success, all done
 echo "*** done"
 rm -f $seq.full
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
index 701cb5c7d2..d76392966c 100644
--- a/tests/qemu-iotests/240.out
+++ b/tests/qemu-iotests/240.out
@@ -31,4 +31,24 @@ QMP_VERSION
 {"return": {}}
 {"return": {}}
 {"return": {}}
+
+=== Attach two SCSI disks using the same block device but different iothreads ===
+
+Testing:
+QMP_VERSION
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"error": {"class": "GenericError", "desc": "Cannot attach a blockdev that is using a different iothread"}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
 *** done
-- 
2.20.1

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

* [Qemu-devel] [PULL 22/27] iotests: Filter second BLOCK_JOB_ERROR from 229
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (20 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 21/27] virtio-scsi: Forbid devices with different iothreads sharing a blockdev Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 23/27] iotests/236: fix transaction kwarg order Kevin Wolf
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Max Reitz <mreitz@redhat.com>

Without this filter, this test sometimes fails.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/229     | 6 +++++-
 tests/qemu-iotests/229.out | 1 -
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
index 893d098ad2..b0d4885fa6 100755
--- a/tests/qemu-iotests/229
+++ b/tests/qemu-iotests/229
@@ -81,11 +81,15 @@ echo
 echo '=== Force cancel job paused in error state  ==='
 echo
 
+# Filter out BLOCK_JOB_ERROR events because they may or may not occur.
+# Cancelling the job means resuming it for a bit before it is actually
+# aborted, and in that time it may or may not re-encounter the error.
 success_or_failure="y" _send_qemu_cmd $QEMU_HANDLE \
     "{'execute': 'block-job-cancel',
                  'arguments': { 'device': 'testdisk',
                                 'force': true}}" \
-     "BLOCK_JOB_CANCELLED" "Assertion"
+     "BLOCK_JOB_CANCELLED" "Assertion" \
+    | grep -v '"BLOCK_JOB_ERROR"'
 
 # success, all done
 echo "*** done"
diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
index 4c4112805f..a3eb33788a 100644
--- a/tests/qemu-iotests/229.out
+++ b/tests/qemu-iotests/229.out
@@ -17,7 +17,6 @@ wrote 2097152/2097152 bytes at offset 0
 
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": 1048576, "speed": 0, "type": "mirror"}}
 *** done
-- 
2.20.1

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

* [Qemu-devel] [PULL 23/27] iotests/236: fix transaction kwarg order
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (21 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 22/27] iotests: Filter second BLOCK_JOB_ERROR from 229 Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 24/27] block: Fix invalidate_cache error path for parent activation Kevin Wolf
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: John Snow <jsnow@redhat.com>

It's not enough to order the kwargs for consistent QMP log output,
we must also sort any sub-dictionaries in lists that appear as values.

Reported-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/236.out    | 56 +++++++++++++++++------------------
 tests/qemu-iotests/iotests.py | 21 ++++++-------
 2 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/tests/qemu-iotests/236.out b/tests/qemu-iotests/236.out
index 1dad24db0d..bb2d71ea5e 100644
--- a/tests/qemu-iotests/236.out
+++ b/tests/qemu-iotests/236.out
@@ -45,23 +45,23 @@ write -P0xcd 0x3ff0000 64k
     "actions": [
       {
         "data": {
-          "node": "drive0",
-          "name": "bitmapB"
+          "name": "bitmapB",
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-disable"
       },
       {
         "data": {
-          "node": "drive0",
+          "granularity": 65536,
           "name": "bitmapC",
-          "granularity": 65536
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-add"
       },
       {
         "data": {
-          "node": "drive0",
-          "name": "bitmapA"
+          "name": "bitmapA",
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-clear"
       },
@@ -105,30 +105,30 @@ write -P0xcd 0x3ff0000 64k
     "actions": [
       {
         "data": {
-          "node": "drive0",
-          "name": "bitmapB"
+          "name": "bitmapB",
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-disable"
       },
       {
         "data": {
-          "node": "drive0",
+          "granularity": 65536,
           "name": "bitmapC",
-          "granularity": 65536
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-add"
       },
       {
         "data": {
-          "node": "drive0",
-          "name": "bitmapC"
+          "name": "bitmapC",
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-disable"
       },
       {
         "data": {
-          "node": "drive0",
-          "name": "bitmapC"
+          "name": "bitmapC",
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-enable"
       }
@@ -158,15 +158,15 @@ write -P0xea 0x3fe0000 64k
     "actions": [
       {
         "data": {
-          "node": "drive0",
-          "name": "bitmapA"
+          "name": "bitmapA",
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-disable"
       },
       {
         "data": {
-          "node": "drive0",
-          "name": "bitmapC"
+          "name": "bitmapC",
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-disable"
       }
@@ -209,21 +209,21 @@ write -P0xea 0x3fe0000 64k
     "actions": [
       {
         "data": {
-          "node": "drive0",
           "disabled": true,
+          "granularity": 65536,
           "name": "bitmapD",
-          "granularity": 65536
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-add"
       },
       {
         "data": {
-          "node": "drive0",
-          "target": "bitmapD",
           "bitmaps": [
             "bitmapB",
             "bitmapC"
-          ]
+          ],
+          "node": "drive0",
+          "target": "bitmapD"
         },
         "type": "block-dirty-bitmap-merge"
       },
@@ -273,21 +273,21 @@ write -P0xea 0x3fe0000 64k
     "actions": [
       {
         "data": {
-          "node": "drive0",
           "disabled": true,
+          "granularity": 65536,
           "name": "bitmapD",
-          "granularity": 65536
+          "node": "drive0"
         },
         "type": "block-dirty-bitmap-add"
       },
       {
         "data": {
-          "node": "drive0",
-          "target": "bitmapD",
           "bitmaps": [
             "bitmapB",
             "bitmapC"
-          ]
+          ],
+          "node": "drive0",
+          "target": "bitmapD"
         },
         "type": "block-dirty-bitmap-merge"
       }
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 71214d46b5..b461f53abf 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -76,15 +76,16 @@ def qemu_img(*args):
         sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args))))
     return exitcode
 
-def ordered_kwargs(kwargs):
-    # kwargs prior to 3.6 are not ordered, so:
-    od = OrderedDict()
-    for k, v in sorted(kwargs.items()):
-        if isinstance(v, dict):
-            od[k] = ordered_kwargs(v)
-        else:
-            od[k] = v
-    return od
+def ordered_qmp(qmsg):
+    # Dictionaries are not ordered prior to 3.6, therefore:
+    if isinstance(qmsg, list):
+        return [ordered_qmp(atom) for atom in qmsg]
+    if isinstance(qmsg, dict):
+        od = OrderedDict()
+        for k, v in sorted(qmsg.items()):
+            od[k] = ordered_qmp(v)
+        return od
+    return qmsg
 
 def qemu_img_create(*args):
     args = list(args)
@@ -506,7 +507,7 @@ class VM(qtest.QEMUQtestMachine):
     def qmp_log(self, cmd, filters=[], indent=None, **kwargs):
         full_cmd = OrderedDict((
             ("execute", cmd),
-            ("arguments", ordered_kwargs(kwargs))
+            ("arguments", ordered_qmp(kwargs))
         ))
         log(full_cmd, filters, indent=indent)
         result = self.qmp(cmd, **kwargs)
-- 
2.20.1

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

* [Qemu-devel] [PULL 24/27] block: Fix invalidate_cache error path for parent activation
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (22 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 23/27] iotests/236: fix transaction kwarg order Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 25/27] qtest.py: Wait for the result of qtest commands Kevin Wolf
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

bdrv_co_invalidate_cache() clears the BDRV_O_INACTIVE flag before
actually activating a node so that the correct permissions etc. are
taken. In case of errors, the flag must be restored so that the next
call to bdrv_co_invalidate_cache() retries activation.

Restoring the flag was missing in the error path for a failed
parent->role->activate() call. The consequence is that this attempt to
activate all images correctly fails because we still set errp, however
on the next attempt BDRV_O_INACTIVE is already clear, so we return
success without actually retrying the failed action.

An example where this is observable in practice is migration to a QEMU
instance that has a raw format block node attached to a guest device
with share-rw=off (the default) while another process holds
BLK_PERM_WRITE for the same image. In this case, all activation steps
before parent->role->activate() succeed because raw can tolerate other
writers to the image. Only the parent callback (in particular
blk_root_activate()) tries to implement the share-rw=on property and
requests exclusive write permissions. This fails when the migration
completes and correctly displays an error. However, a manual 'cont' will
incorrectly resume the VM without calling blk_root_activate() again.

This case is described in more detail in the following bug report:
https://bugzilla.redhat.com/show_bug.cgi?id=1531888

Fix this by correctly restoring the BDRV_O_INACTIVE flag in the error
path.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block.c b/block.c
index 5a4d27173e..b67d9b7b65 100644
--- a/block.c
+++ b/block.c
@@ -4697,6 +4697,7 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
         if (parent->role->activate) {
             parent->role->activate(parent, &local_err);
             if (local_err) {
+                bs->open_flags |= BDRV_O_INACTIVE;
                 error_propagate(errp, local_err);
                 return;
             }
-- 
2.20.1

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

* [Qemu-devel] [PULL 25/27] qtest.py: Wait for the result of qtest commands
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (23 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 24/27] block: Fix invalidate_cache error path for parent activation Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 26/27] scsi-disk: Don't use empty string as device id Kevin Wolf
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

From: Alberto Garcia <berto@igalia.com>

The cmd() method of the QEMUQtestProtocol class sends a qtest command
to QEMU but doesn't wait for the return message ("OK", "FAIL", "ERR").
Because of this, it can return control to the caller before the
command has actually finished.

In cases like clock_step or clock_set this means that cmd() can return
before all the timers triggered by the clock change have been fired.
This can be fixed by making cmd() wait for the output of the qtest
command.

This fixes iotests 093 and 136, which are flaky since commit
8258292e18c39480b64eba9f3551 when the machine is under heavy workload.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 scripts/qtest.py | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/scripts/qtest.py b/scripts/qtest.py
index adf1fe3f26..afac3fe900 100644
--- a/scripts/qtest.py
+++ b/scripts/qtest.py
@@ -31,6 +31,7 @@ class QEMUQtestProtocol(object):
         """
         self._address = address
         self._sock = self._get_sock()
+        self._sockfile = None
         if server:
             self._sock.bind(self._address)
             self._sock.listen(1)
@@ -49,6 +50,7 @@ class QEMUQtestProtocol(object):
         @raise socket.error on socket connection errors
         """
         self._sock.connect(self._address)
+        self._sockfile = self._sock.makefile()
 
     def accept(self):
         """
@@ -57,6 +59,7 @@ class QEMUQtestProtocol(object):
         @raise socket.error on socket connection errors
         """
         self._sock, _ = self._sock.accept()
+        self._sockfile = self._sock.makefile()
 
     def cmd(self, qtest_cmd):
         """
@@ -65,9 +68,12 @@ class QEMUQtestProtocol(object):
         @param qtest_cmd: qtest command text to be sent
         """
         self._sock.sendall((qtest_cmd + "\n").encode('utf-8'))
+        resp = self._sockfile.readline()
+        return resp
 
     def close(self):
         self._sock.close()
+        self._sockfile.close()
 
     def settimeout(self, timeout):
         self._sock.settimeout(timeout)
-- 
2.20.1

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

* [Qemu-devel] [PULL 26/27] scsi-disk: Don't use empty string as device id
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (24 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 25/27] qtest.py: Wait for the result of qtest commands Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 16:35 ` [Qemu-devel] [PULL 27/27] scsi-disk: Add device_id property Kevin Wolf
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

scsi-disk includes in the Device Identification VPD page, depending on
configuration amongst others, a vendor specific designator that consists
either of the serial number if given or the BlockBackend name (which is
a host detail that better shouldn't have been leaked to the guest, but
now we have to maintain it for compatibility).

With anonymous BlockBackends, i.e. scsi-disk devices constructed with
drive=<node-name>, and no serial number explicitly specified, this ends
up as an empty string. If this happens to more than one disk, we have
accidentally signalled to the OS that this is a multipath setup, which
is obviously not what was intended.

Instead of using an empty string for the vendor specific designator,
simply leave out that designator, which makes Linux detect such setups
as separate disks again.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/scsi/scsi-disk.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index b049026219..11392a8db8 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -652,12 +652,14 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
         DPRINTF("Inquiry EVPD[Device identification] "
                 "buffer size %zd\n", req->cmd.xfer);
 
-        outbuf[buflen++] = 0x2; /* ASCII */
-        outbuf[buflen++] = 0;   /* not officially assigned */
-        outbuf[buflen++] = 0;   /* reserved */
-        outbuf[buflen++] = id_len; /* length of data following */
-        memcpy(outbuf + buflen, str, id_len);
-        buflen += id_len;
+        if (id_len) {
+            outbuf[buflen++] = 0x2; /* ASCII */
+            outbuf[buflen++] = 0;   /* not officially assigned */
+            outbuf[buflen++] = 0;   /* reserved */
+            outbuf[buflen++] = id_len; /* length of data following */
+            memcpy(outbuf + buflen, str, id_len);
+            buflen += id_len;
+        }
 
         if (s->qdev.wwn) {
             outbuf[buflen++] = 0x1; /* Binary */
-- 
2.20.1

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

* [Qemu-devel] [PULL 27/27] scsi-disk: Add device_id property
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (25 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 26/27] scsi-disk: Don't use empty string as device id Kevin Wolf
@ 2019-02-01 16:35 ` Kevin Wolf
  2019-02-01 17:24 ` [Qemu-devel] [PULL 00/27] Block layer patches no-reply
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2019-02-01 16:35 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel

The new device_id property specifies which value to use for the vendor
specific designator in the Device Identification VPD page.

In particular, this is necessary for libvirt to maintain guest ABI
compatibility when no serial number is given and a VM is switched from
-drive (where the BlockBackend name is used) to -blockdev (where the
vendor specific designator is left out by default).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 hw/scsi/scsi-disk.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 11392a8db8..e6db6d7c15 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -104,6 +104,7 @@ typedef struct SCSIDiskState
     char *serial;
     char *vendor;
     char *product;
+    char *device_id;
     bool tray_open;
     bool tray_locked;
     /*
@@ -642,13 +643,8 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
 
     case 0x83: /* Device identification page, mandatory */
     {
-        const char *str = s->serial ?: blk_name(s->qdev.conf.blk);
-        int max_len = s->serial ? 20 : 255 - 8;
-        int id_len = strlen(str);
+        int id_len = s->device_id ? MIN(strlen(s->device_id), 255 - 8) : 0;
 
-        if (id_len > max_len) {
-            id_len = max_len;
-        }
         DPRINTF("Inquiry EVPD[Device identification] "
                 "buffer size %zd\n", req->cmd.xfer);
 
@@ -657,7 +653,7 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
             outbuf[buflen++] = 0;   /* not officially assigned */
             outbuf[buflen++] = 0;   /* reserved */
             outbuf[buflen++] = id_len; /* length of data following */
-            memcpy(outbuf + buflen, str, id_len);
+            memcpy(outbuf + buflen, s->device_id, id_len);
             buflen += id_len;
         }
 
@@ -2363,6 +2359,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
     if (!s->vendor) {
         s->vendor = g_strdup("QEMU");
     }
+    if (!s->device_id) {
+        if (s->serial) {
+            s->device_id = g_strdup_printf("%.20s", s->serial);
+        } else {
+            const char *str = blk_name(s->qdev.conf.blk);
+            if (str && *str) {
+                s->device_id = g_strdup(str);
+            }
+        }
+    }
 
     if (blk_is_sg(s->qdev.conf.blk)) {
         error_setg(errp, "unwanted /dev/sg*");
@@ -2921,7 +2927,9 @@ static const TypeInfo scsi_disk_base_info = {
     DEFINE_PROP_STRING("ver", SCSIDiskState, version),               \
     DEFINE_PROP_STRING("serial", SCSIDiskState, serial),             \
     DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor),             \
-    DEFINE_PROP_STRING("product", SCSIDiskState, product)
+    DEFINE_PROP_STRING("product", SCSIDiskState, product),           \
+    DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id)
+
 
 static Property scsi_hd_properties[] = {
     DEFINE_SCSI_DISK_PROPERTIES(),
-- 
2.20.1

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

* Re: [Qemu-devel] [PULL 00/27] Block layer patches
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (26 preceding siblings ...)
  2019-02-01 16:35 ` [Qemu-devel] [PULL 27/27] scsi-disk: Add device_id property Kevin Wolf
@ 2019-02-01 17:24 ` no-reply
  2019-02-01 17:24 ` no-reply
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: no-reply @ 2019-02-01 17:24 UTC (permalink / raw)
  To: kwolf; +Cc: fam, qemu-block, peter.maydell, qemu-devel

Patchew URL: https://patchew.org/QEMU/20190201163518.31157-1-kwolf@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [Qemu-devel] [PULL 00/27] Block layer patches
Type: series
Message-id: 20190201163518.31157-1-kwolf@redhat.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]               patchew/20190201163518.31157-1-kwolf@redhat.com -> patchew/20190201163518.31157-1-kwolf@redhat.com
Switched to a new branch 'test'
efda24f484 scsi-disk: Add device_id property
e2900fcf89 scsi-disk: Don't use empty string as device id
0839ab44d2 qtest.py: Wait for the result of qtest commands
4d30da6acf block: Fix invalidate_cache error path for parent activation
22f30810a6 iotests/236: fix transaction kwarg order
7a0e2eabf7 iotests: Filter second BLOCK_JOB_ERROR from 229
64be774a1d virtio-scsi: Forbid devices with different iothreads sharing a blockdev
26077d4126 scsi-disk: Acquire the AioContext in scsi_*_realize()
bf177638a4 virtio-scsi: Move BlockBackend back to the main AioContext on unplug
925ffa2853 block: Eliminate the S_1KiB, S_2KiB, ... macros
cd95c7ec25 block: Remove blk_attach_dev_legacy() / legacy_dev code
42f5a22f03 block: Apply auto-read-only for ro-whitelist drivers
15999b8662 uuid: Make qemu_uuid_bswap() take and return a QemuUUID
ac89b289a8 block/vdi: Don't take address of fields in packed structs
d1124190ec block/vpc: Don't take address of fields in packed structs
cbbb11d650 vmdk: Reject excess extents in blockdev-create
197749ef35 iotests: Add VMDK tests for blockdev-create
e0ff53ef8f iotests: Filter cid numbers in VMDK extent info
b4db4e6f37 vmdk: Implement .bdrv_co_create callback
d57f723d9f vmdk: Refactor vmdk_create_extent
9e413c8109 iotests: Make 234 stable
02cde0d15b block: Fix hangs in synchronous APIs with iothreads
7cc628dd75 block: Replace qdict_put() by qdict_put_obj() where appropriate
7b62d1fcaa qemu-iotests: add test case for dmg
3768be89c8 qcow2: Assert that refcount block offsets fit in the refcount table
5853e2cbf7 mirror: Block the source BlockDriverState in mirror_start_job()
67b66ab807 mirror: Release the dirty bitmap if mirror_start_job() fails

=== OUTPUT BEGIN ===
1/27 Checking commit 67b66ab807fe (mirror: Release the dirty bitmap if mirror_start_job() fails)
2/27 Checking commit 5853e2cbf763 (mirror: Block the source BlockDriverState in mirror_start_job())
3/27 Checking commit 3768be89c8a6 (qcow2: Assert that refcount block offsets fit in the refcount table)
4/27 Checking commit 7b62d1fcaac8 (qemu-iotests: add test case for dmg)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#17: 
new file mode 100755

total: 0 errors, 1 warnings, 80 lines checked

Patch 4/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
5/27 Checking commit 7cc628dd759a (block: Replace qdict_put() by qdict_put_obj() where appropriate)
6/27 Checking commit 02cde0d15bcd (block: Fix hangs in synchronous APIs with iothreads)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#253: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#584: FILE: tests/test-block-iothread.c:327:
+/* Test synchronous operations that run in a different iothread, so we have to

WARNING: Block comments use a trailing */ on a separate line
#585: FILE: tests/test-block-iothread.c:328:
+ * poll for the coroutine there to return. */

total: 0 errors, 3 warnings, 529 lines checked

Patch 6/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
7/27 Checking commit 9e413c810961 (iotests: Make 234 stable)
8/27 Checking commit d57f723d9fc7 (vmdk: Refactor vmdk_create_extent)
WARNING: line over 80 characters
#126: FILE: block/vmdk.c:2114:
+                               flat, compress, zeroed_grain, NULL, opts, errp)) {

total: 0 errors, 1 warnings, 104 lines checked

Patch 8/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/27 Checking commit b4db4e6f3761 (vmdk: Implement .bdrv_co_create callback)
WARNING: line over 80 characters
#218: FILE: block/vmdk.c:2075:
+        bdrv_get_full_backing_filename_from_filename(blk_bs(blk)->filename, backing_file,

WARNING: line over 80 characters
#373: FILE: block/vmdk.c:2174:
+                                            bool flat, bool split, bool compress,

WARNING: line over 80 characters
#391: FILE: block/vmdk.c:2192:
+        rel_filename = g_strdup_printf("%s-flat%s", data->prefix, data->postfix);

WARNING: line over 80 characters
#408: FILE: block/vmdk.c:2209:
+static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts,

total: 0 errors, 4 warnings, 658 lines checked

Patch 9/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
10/27 Checking commit e0ff53ef8fd6 (iotests: Filter cid numbers in VMDK extent info)
11/27 Checking commit 197749ef359c (iotests: Add VMDK tests for blockdev-create)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#12: 
new file mode 100755

ERROR: trailing whitespace
#283: FILE: tests/qemu-iotests/237.out:28:
+            format: $

ERROR: trailing whitespace
#310: FILE: tests/qemu-iotests/237.out:55:
+            format: $

ERROR: trailing whitespace
#337: FILE: tests/qemu-iotests/237.out:82:
+            format: $

total: 3 errors, 1 warnings, 586 lines checked

Patch 11/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

12/27 Checking commit cbbb11d6502a (vmdk: Reject excess extents in blockdev-create)
13/27 Checking commit d1124190ecfc (block/vpc: Don't take address of fields in packed structs)
14/27 Checking commit ac89b289a8db (block/vdi: Don't take address of fields in packed structs)
15/27 Checking commit 15999b866202 (uuid: Make qemu_uuid_bswap() take and return a QemuUUID)
16/27 Checking commit 42f5a22f03e8 (block: Apply auto-read-only for ro-whitelist drivers)
17/27 Checking commit cd95c7ec2558 (block: Remove blk_attach_dev_legacy() / legacy_dev code)
18/27 Checking commit 925ffa2853e3 (block: Eliminate the S_1KiB, S_2KiB, ... macros)
19/27 Checking commit bf177638a426 (virtio-scsi: Move BlockBackend back to the main AioContext on unplug)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#33: 
new file mode 100755

total: 0 errors, 1 warnings, 123 lines checked

Patch 19/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
20/27 Checking commit 26077d4126c7 (scsi-disk: Acquire the AioContext in scsi_*_realize())
21/27 Checking commit 64be774a1d82 (virtio-scsi: Forbid devices with different iothreads sharing a blockdev)
22/27 Checking commit 7a0e2eabf7c1 (iotests: Filter second BLOCK_JOB_ERROR from 229)
23/27 Checking commit 22f30810a6be (iotests/236: fix transaction kwarg order)
24/27 Checking commit 4d30da6acfc5 (block: Fix invalidate_cache error path for parent activation)
25/27 Checking commit 0839ab44d2bf (qtest.py: Wait for the result of qtest commands)
26/27 Checking commit e2900fcf8987 (scsi-disk: Don't use empty string as device id)
27/27 Checking commit efda24f4843e (scsi-disk: Add device_id property)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190201163518.31157-1-kwolf@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [Qemu-devel] [PULL 00/27] Block layer patches
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (27 preceding siblings ...)
  2019-02-01 17:24 ` [Qemu-devel] [PULL 00/27] Block layer patches no-reply
@ 2019-02-01 17:24 ` no-reply
  2019-02-01 17:27 ` no-reply
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: no-reply @ 2019-02-01 17:24 UTC (permalink / raw)
  To: kwolf; +Cc: fam, qemu-block, peter.maydell, qemu-devel

Patchew URL: https://patchew.org/QEMU/20190201163518.31157-1-kwolf@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20190201163518.31157-1-kwolf@redhat.com
Subject: [Qemu-devel] [PULL 00/27] Block layer patches

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/1548942405-760115-1-git-send-email-andrey.shinkevich@virtuozzo.com -> patchew/1548942405-760115-1-git-send-email-andrey.shinkevich@virtuozzo.com
 - [tag update]      patchew/20190201145035.22739-1-peter.maydell@linaro.org -> patchew/20190201145035.22739-1-peter.maydell@linaro.org
 * [new tag]         patchew/20190201163518.31157-1-kwolf@redhat.com -> patchew/20190201163518.31157-1-kwolf@redhat.com
Switched to a new branch 'test'
efda24f scsi-disk: Add device_id property
e2900fc scsi-disk: Don't use empty string as device id
0839ab4 qtest.py: Wait for the result of qtest commands
4d30da6 block: Fix invalidate_cache error path for parent activation
22f3081 iotests/236: fix transaction kwarg order
7a0e2ea iotests: Filter second BLOCK_JOB_ERROR from 229
64be774 virtio-scsi: Forbid devices with different iothreads sharing a blockdev
26077d4 scsi-disk: Acquire the AioContext in scsi_*_realize()
bf17763 virtio-scsi: Move BlockBackend back to the main AioContext on unplug
925ffa2 block: Eliminate the S_1KiB, S_2KiB, ... macros
cd95c7e block: Remove blk_attach_dev_legacy() / legacy_dev code
42f5a22 block: Apply auto-read-only for ro-whitelist drivers
15999b8 uuid: Make qemu_uuid_bswap() take and return a QemuUUID
ac89b28 block/vdi: Don't take address of fields in packed structs
d112419 block/vpc: Don't take address of fields in packed structs
cbbb11d vmdk: Reject excess extents in blockdev-create
197749e iotests: Add VMDK tests for blockdev-create
e0ff53e iotests: Filter cid numbers in VMDK extent info
b4db4e6 vmdk: Implement .bdrv_co_create callback
d57f723 vmdk: Refactor vmdk_create_extent
9e413c8 iotests: Make 234 stable
02cde0d block: Fix hangs in synchronous APIs with iothreads
7cc628d block: Replace qdict_put() by qdict_put_obj() where appropriate
7b62d1f qemu-iotests: add test case for dmg
3768be8 qcow2: Assert that refcount block offsets fit in the refcount table
5853e2c mirror: Block the source BlockDriverState in mirror_start_job()
67b66ab mirror: Release the dirty bitmap if mirror_start_job() fails

=== OUTPUT BEGIN ===
1/27 Checking commit 67b66ab807fe (mirror: Release the dirty bitmap if mirror_start_job() fails)
2/27 Checking commit 5853e2cbf763 (mirror: Block the source BlockDriverState in mirror_start_job())
3/27 Checking commit 3768be89c8a6 (qcow2: Assert that refcount block offsets fit in the refcount table)
4/27 Checking commit 7b62d1fcaac8 (qemu-iotests: add test case for dmg)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#17: 
new file mode 100755

total: 0 errors, 1 warnings, 80 lines checked

Patch 4/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
5/27 Checking commit 7cc628dd759a (block: Replace qdict_put() by qdict_put_obj() where appropriate)
6/27 Checking commit 02cde0d15bcd (block: Fix hangs in synchronous APIs with iothreads)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#253: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#584: FILE: tests/test-block-iothread.c:327:
+/* Test synchronous operations that run in a different iothread, so we have to

WARNING: Block comments use a trailing */ on a separate line
#585: FILE: tests/test-block-iothread.c:328:
+ * poll for the coroutine there to return. */

total: 0 errors, 3 warnings, 529 lines checked

Patch 6/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
7/27 Checking commit 9e413c810961 (iotests: Make 234 stable)
8/27 Checking commit d57f723d9fc7 (vmdk: Refactor vmdk_create_extent)
WARNING: line over 80 characters
#126: FILE: block/vmdk.c:2114:
+                               flat, compress, zeroed_grain, NULL, opts, errp)) {

total: 0 errors, 1 warnings, 104 lines checked

Patch 8/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/27 Checking commit b4db4e6f3761 (vmdk: Implement .bdrv_co_create callback)
WARNING: line over 80 characters
#218: FILE: block/vmdk.c:2075:
+        bdrv_get_full_backing_filename_from_filename(blk_bs(blk)->filename, backing_file,

WARNING: line over 80 characters
#373: FILE: block/vmdk.c:2174:
+                                            bool flat, bool split, bool compress,

WARNING: line over 80 characters
#391: FILE: block/vmdk.c:2192:
+        rel_filename = g_strdup_printf("%s-flat%s", data->prefix, data->postfix);

WARNING: line over 80 characters
#408: FILE: block/vmdk.c:2209:
+static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts,

total: 0 errors, 4 warnings, 658 lines checked

Patch 9/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
10/27 Checking commit e0ff53ef8fd6 (iotests: Filter cid numbers in VMDK extent info)
11/27 Checking commit 197749ef359c (iotests: Add VMDK tests for blockdev-create)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#12: 
new file mode 100755

ERROR: trailing whitespace
#283: FILE: tests/qemu-iotests/237.out:28:
+            format: $

ERROR: trailing whitespace
#310: FILE: tests/qemu-iotests/237.out:55:
+            format: $

ERROR: trailing whitespace
#337: FILE: tests/qemu-iotests/237.out:82:
+            format: $

total: 3 errors, 1 warnings, 586 lines checked

Patch 11/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

12/27 Checking commit cbbb11d6502a (vmdk: Reject excess extents in blockdev-create)
13/27 Checking commit d1124190ecfc (block/vpc: Don't take address of fields in packed structs)
14/27 Checking commit ac89b289a8db (block/vdi: Don't take address of fields in packed structs)
15/27 Checking commit 15999b866202 (uuid: Make qemu_uuid_bswap() take and return a QemuUUID)
16/27 Checking commit 42f5a22f03e8 (block: Apply auto-read-only for ro-whitelist drivers)
17/27 Checking commit cd95c7ec2558 (block: Remove blk_attach_dev_legacy() / legacy_dev code)
18/27 Checking commit 925ffa2853e3 (block: Eliminate the S_1KiB, S_2KiB, ... macros)
19/27 Checking commit bf177638a426 (virtio-scsi: Move BlockBackend back to the main AioContext on unplug)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#33: 
new file mode 100755

total: 0 errors, 1 warnings, 123 lines checked

Patch 19/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
20/27 Checking commit 26077d4126c7 (scsi-disk: Acquire the AioContext in scsi_*_realize())
21/27 Checking commit 64be774a1d82 (virtio-scsi: Forbid devices with different iothreads sharing a blockdev)
22/27 Checking commit 7a0e2eabf7c1 (iotests: Filter second BLOCK_JOB_ERROR from 229)
23/27 Checking commit 22f30810a6be (iotests/236: fix transaction kwarg order)
24/27 Checking commit 4d30da6acfc5 (block: Fix invalidate_cache error path for parent activation)
25/27 Checking commit 0839ab44d2bf (qtest.py: Wait for the result of qtest commands)
26/27 Checking commit e2900fcf8987 (scsi-disk: Don't use empty string as device id)
27/27 Checking commit efda24f4843e (scsi-disk: Add device_id property)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190201163518.31157-1-kwolf@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [Qemu-devel] [PULL 00/27] Block layer patches
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (28 preceding siblings ...)
  2019-02-01 17:24 ` no-reply
@ 2019-02-01 17:27 ` no-reply
  2019-02-01 19:05 ` Peter Maydell
  2019-02-03 15:10 ` no-reply
  31 siblings, 0 replies; 36+ messages in thread
From: no-reply @ 2019-02-01 17:27 UTC (permalink / raw)
  To: kwolf; +Cc: fam, qemu-block, peter.maydell, qemu-devel

Patchew URL: https://patchew.org/QEMU/20190201163518.31157-1-kwolf@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [Qemu-devel] [PULL 00/27] Block layer patches
Message-id: 20190201163518.31157-1-kwolf@redhat.com
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/1548942405-760115-1-git-send-email-andrey.shinkevich@virtuozzo.com -> patchew/1548942405-760115-1-git-send-email-andrey.shinkevich@virtuozzo.com
 - [tag update]      patchew/20190201145035.22739-1-peter.maydell@linaro.org -> patchew/20190201145035.22739-1-peter.maydell@linaro.org
 * [new tag]         patchew/20190201163518.31157-1-kwolf@redhat.com -> patchew/20190201163518.31157-1-kwolf@redhat.com
Submodule 'capstone' (https://git.qemu.org/git/capstone.git) registered for path 'capstone'
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (https://git.qemu.org/git/QemuMacDrivers.git) registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (https://git.qemu.org/git/SLOF.git) registered for path 'roms/SLOF'
Submodule 'roms/ipxe' (https://git.qemu.org/git/ipxe.git) registered for path 'roms/ipxe'
Submodule 'roms/openbios' (https://git.qemu.org/git/openbios.git) registered for path 'roms/openbios'
Submodule 'roms/openhackware' (https://git.qemu.org/git/openhackware.git) registered for path 'roms/openhackware'
Submodule 'roms/qemu-palcode' (https://git.qemu.org/git/qemu-palcode.git) registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (https://git.qemu.org/git/seabios.git/) registered for path 'roms/seabios'
Submodule 'roms/seabios-hppa' (https://github.com/hdeller/seabios-hppa.git) registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (https://git.qemu.org/git/sgabios.git) registered for path 'roms/sgabios'
Submodule 'roms/skiboot' (https://git.qemu.org/git/skiboot.git) registered for path 'roms/skiboot'
Submodule 'roms/u-boot' (https://git.qemu.org/git/u-boot.git) registered for path 'roms/u-boot'
Submodule 'roms/u-boot-sam460ex' (https://git.qemu.org/git/u-boot-sam460ex.git) registered for path 'roms/u-boot-sam460ex'
Submodule 'tests/fp/berkeley-softfloat-3' (https://github.com/cota/berkeley-softfloat-3) registered for path 'tests/fp/berkeley-softfloat-3'
Submodule 'tests/fp/berkeley-testfloat-3' (https://github.com/cota/berkeley-testfloat-3) registered for path 'tests/fp/berkeley-testfloat-3'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out '22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out 'd4e7d7ac663fcb55f1b93575445fcbca372f17a7'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out '9b7ab2fa020341dee8bf9df6c9cf40003e0136df'
Cloning into 'roms/ipxe'...
Submodule path 'roms/ipxe': checked out 'de4565cbe76ea9f7913a01f331be3ee901bb6e17'
Cloning into 'roms/openbios'...
Submodule path 'roms/openbios': checked out '441a84d3a642a10b948369c63f32367e8ff6395b'
Cloning into 'roms/openhackware'...
Submodule path 'roms/openhackware': checked out 'c559da7c8eec5e45ef1f67978827af6f0b9546f5'
Cloning into 'roms/qemu-palcode'...
Submodule path 'roms/qemu-palcode': checked out '51c237d7e20d05100eacadee2f61abc17e6bc097'
Cloning into 'roms/seabios'...
Submodule path 'roms/seabios': checked out 'a698c8995ffb2838296ec284fe3c4ad33dfca307'
Cloning into 'roms/seabios-hppa'...
Submodule path 'roms/seabios-hppa': checked out '1ef99a01572c2581c30e16e6fe69e9ea2ef92ce0'
Cloning into 'roms/sgabios'...
Submodule path 'roms/sgabios': checked out 'cbaee52287e5f32373181cff50a00b6c4ac9015a'
Cloning into 'roms/skiboot'...
Submodule path 'roms/skiboot': checked out 'e0ee24c27a172bcf482f6f2bc905e6211c134bcc'
Cloning into 'roms/u-boot'...
Submodule path 'roms/u-boot': checked out 'd85ca029f257b53a96da6c2fb421e78a003a9943'
Cloning into 'roms/u-boot-sam460ex'...
Submodule path 'roms/u-boot-sam460ex': checked out '60b3916f33e617a815973c5a6df77055b2e3a588'
Cloning into 'tests/fp/berkeley-softfloat-3'...
Submodule path 'tests/fp/berkeley-softfloat-3': checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'tests/fp/berkeley-testfloat-3'...
Submodule path 'tests/fp/berkeley-testfloat-3': checked out '5a59dcec19327396a011a17fd924aed4fec416b3'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out '6b3d716e2b6472eb7189d3220552280ef3d832ce'
Switched to a new branch 'test'
efda24f scsi-disk: Add device_id property
e2900fc scsi-disk: Don't use empty string as device id
0839ab4 qtest.py: Wait for the result of qtest commands
4d30da6 block: Fix invalidate_cache error path for parent activation
22f3081 iotests/236: fix transaction kwarg order
7a0e2ea iotests: Filter second BLOCK_JOB_ERROR from 229
64be774 virtio-scsi: Forbid devices with different iothreads sharing a blockdev
26077d4 scsi-disk: Acquire the AioContext in scsi_*_realize()
bf17763 virtio-scsi: Move BlockBackend back to the main AioContext on unplug
925ffa2 block: Eliminate the S_1KiB, S_2KiB, ... macros
cd95c7e block: Remove blk_attach_dev_legacy() / legacy_dev code
42f5a22 block: Apply auto-read-only for ro-whitelist drivers
15999b8 uuid: Make qemu_uuid_bswap() take and return a QemuUUID
ac89b28 block/vdi: Don't take address of fields in packed structs
d112419 block/vpc: Don't take address of fields in packed structs
cbbb11d vmdk: Reject excess extents in blockdev-create
197749e iotests: Add VMDK tests for blockdev-create
e0ff53e iotests: Filter cid numbers in VMDK extent info
b4db4e6 vmdk: Implement .bdrv_co_create callback
d57f723 vmdk: Refactor vmdk_create_extent
9e413c8 iotests: Make 234 stable
02cde0d block: Fix hangs in synchronous APIs with iothreads
7cc628d block: Replace qdict_put() by qdict_put_obj() where appropriate
7b62d1f qemu-iotests: add test case for dmg
3768be8 qcow2: Assert that refcount block offsets fit in the refcount table
5853e2c mirror: Block the source BlockDriverState in mirror_start_job()
67b66ab mirror: Release the dirty bitmap if mirror_start_job() fails

=== OUTPUT BEGIN ===
1/27 Checking commit 67b66ab807fe (mirror: Release the dirty bitmap if mirror_start_job() fails)
2/27 Checking commit 5853e2cbf763 (mirror: Block the source BlockDriverState in mirror_start_job())
3/27 Checking commit 3768be89c8a6 (qcow2: Assert that refcount block offsets fit in the refcount table)
4/27 Checking commit 7b62d1fcaac8 (qemu-iotests: add test case for dmg)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#17: 
new file mode 100755

total: 0 errors, 1 warnings, 80 lines checked

Patch 4/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
5/27 Checking commit 7cc628dd759a (block: Replace qdict_put() by qdict_put_obj() where appropriate)
6/27 Checking commit 02cde0d15bcd (block: Fix hangs in synchronous APIs with iothreads)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#253: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#584: FILE: tests/test-block-iothread.c:327:
+/* Test synchronous operations that run in a different iothread, so we have to

WARNING: Block comments use a trailing */ on a separate line
#585: FILE: tests/test-block-iothread.c:328:
+ * poll for the coroutine there to return. */

total: 0 errors, 3 warnings, 529 lines checked

Patch 6/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
7/27 Checking commit 9e413c810961 (iotests: Make 234 stable)
8/27 Checking commit d57f723d9fc7 (vmdk: Refactor vmdk_create_extent)
WARNING: line over 80 characters
#126: FILE: block/vmdk.c:2114:
+                               flat, compress, zeroed_grain, NULL, opts, errp)) {

total: 0 errors, 1 warnings, 104 lines checked

Patch 8/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/27 Checking commit b4db4e6f3761 (vmdk: Implement .bdrv_co_create callback)
WARNING: line over 80 characters
#218: FILE: block/vmdk.c:2075:
+        bdrv_get_full_backing_filename_from_filename(blk_bs(blk)->filename, backing_file,

WARNING: line over 80 characters
#373: FILE: block/vmdk.c:2174:
+                                            bool flat, bool split, bool compress,

WARNING: line over 80 characters
#391: FILE: block/vmdk.c:2192:
+        rel_filename = g_strdup_printf("%s-flat%s", data->prefix, data->postfix);

WARNING: line over 80 characters
#408: FILE: block/vmdk.c:2209:
+static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts,

total: 0 errors, 4 warnings, 658 lines checked

Patch 9/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
10/27 Checking commit e0ff53ef8fd6 (iotests: Filter cid numbers in VMDK extent info)
11/27 Checking commit 197749ef359c (iotests: Add VMDK tests for blockdev-create)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#12: 
new file mode 100755

ERROR: trailing whitespace
#283: FILE: tests/qemu-iotests/237.out:28:
+            format: $

ERROR: trailing whitespace
#310: FILE: tests/qemu-iotests/237.out:55:
+            format: $

ERROR: trailing whitespace
#337: FILE: tests/qemu-iotests/237.out:82:
+            format: $

total: 3 errors, 1 warnings, 586 lines checked

Patch 11/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

12/27 Checking commit cbbb11d6502a (vmdk: Reject excess extents in blockdev-create)
13/27 Checking commit d1124190ecfc (block/vpc: Don't take address of fields in packed structs)
14/27 Checking commit ac89b289a8db (block/vdi: Don't take address of fields in packed structs)
15/27 Checking commit 15999b866202 (uuid: Make qemu_uuid_bswap() take and return a QemuUUID)
16/27 Checking commit 42f5a22f03e8 (block: Apply auto-read-only for ro-whitelist drivers)
17/27 Checking commit cd95c7ec2558 (block: Remove blk_attach_dev_legacy() / legacy_dev code)
18/27 Checking commit 925ffa2853e3 (block: Eliminate the S_1KiB, S_2KiB, ... macros)
19/27 Checking commit bf177638a426 (virtio-scsi: Move BlockBackend back to the main AioContext on unplug)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#33: 
new file mode 100755

total: 0 errors, 1 warnings, 123 lines checked

Patch 19/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
20/27 Checking commit 26077d4126c7 (scsi-disk: Acquire the AioContext in scsi_*_realize())
21/27 Checking commit 64be774a1d82 (virtio-scsi: Forbid devices with different iothreads sharing a blockdev)
22/27 Checking commit 7a0e2eabf7c1 (iotests: Filter second BLOCK_JOB_ERROR from 229)
23/27 Checking commit 22f30810a6be (iotests/236: fix transaction kwarg order)
24/27 Checking commit 4d30da6acfc5 (block: Fix invalidate_cache error path for parent activation)
25/27 Checking commit 0839ab44d2bf (qtest.py: Wait for the result of qtest commands)
26/27 Checking commit e2900fcf8987 (scsi-disk: Don't use empty string as device id)
27/27 Checking commit efda24f4843e (scsi-disk: Add device_id property)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190201163518.31157-1-kwolf@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [Qemu-devel] [PULL 00/27] Block layer patches
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (29 preceding siblings ...)
  2019-02-01 17:27 ` no-reply
@ 2019-02-01 19:05 ` Peter Maydell
  2019-02-03 15:10 ` no-reply
  31 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2019-02-01 19:05 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: Qemu-block, QEMU Developers

On Fri, 1 Feb 2019 at 16:35, Kevin Wolf <kwolf@redhat.com> wrote:
>
> The following changes since commit cfe6c547690b06fbce54a6d0f7b05dd7f18e36ea:
>
>   Merge remote-tracking branch 'remotes/xanclic/tags/pull-block-2019-01-31' into staging (2019-01-31 19:26:09 +0000)
>
> are available in the Git repository at:
>
>   git://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to 7471a649fc3a391dd497297013fb2525ca9821ba:
>
>   scsi-disk: Add device_id property (2019-02-01 13:48:11 +0100)
>
> ----------------------------------------------------------------
> Block layer patches:
>
> - vmdk: Support for blockdev-create
> - block: Apply auto-read-only for ro-whitelist drivers
> - virtio-scsi: Fixes related to attaching/detaching iothreads
> - scsi-disk: Fixed erroneously detected multipath setup with multiple
>   disks created with node-names. Added device_id property.
> - block: Fix hangs in synchronous APIs with iothreads
> - block: Fix invalidate_cache error path for parent activation
> - block-backend, mirror, qcow2, vpc, vdi, qemu-iotests:
>   Minor fixes and code improvements


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.0
for any user-visible changes.

-- PMM

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

* Re: [Qemu-devel] [PULL 00/27] Block layer patches
  2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
                   ` (30 preceding siblings ...)
  2019-02-01 19:05 ` Peter Maydell
@ 2019-02-03 15:10 ` no-reply
  31 siblings, 0 replies; 36+ messages in thread
From: no-reply @ 2019-02-03 15:10 UTC (permalink / raw)
  To: kwolf; +Cc: fam, qemu-block, peter.maydell, qemu-devel

Patchew URL: https://patchew.org/QEMU/20190201163518.31157-1-kwolf@redhat.com/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-mingw@fedora SHOW_ENV=1 J=14
=== TEST SCRIPT END ===


Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/tmp/qemu-test/install --python=/usr/bin/python3 --cross-prefix=x86_64-w64-mingw32- --enable-trace-backends=simple --enable-gnutls --enable-nettle --enable-curl --enable-vnc --enable-bzip2 --enable-guest-agent --with-sdlabi=2.0
ERROR: unknown option --with-sdlabi=2.0
Try '/tmp/qemu-test/src/configure --help' for more information
# QEMU configure log Sun Feb  3 15:10:43 UTC 2019
# Configured with: '/tmp/qemu-test/src/configure' '--enable-werror' '--target-list=x86_64-softmmu,aarch64-softmmu' '--prefix=/tmp/qemu-test/install' '--python=/usr/bin/python3' '--cross-prefix=x86_64-w64-mingw32-' '--enable-trace-backends=simple' '--enable-gnutls' '--enable-nettle' '--enable-curl' '--enable-vnc' '--enable-bzip2' '--enable-guest-agent' '--with-sdlabi=2.0'
---
funcs: do_compiler do_cc compile_object check_define main
lines: 92 122 617 634 0
x86_64-w64-mingw32-gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -std=gnu99 -c -o config-temp/qemu-conf.o config-temp/qemu-conf.c
config-temp/qemu-conf.c:2:2: error: #error __linux__ not defined
 #error __linux__ not defined
  ^~~~~

---
funcs: do_compiler do_cc compile_object check_define main
lines: 92 122 617 686 0
x86_64-w64-mingw32-gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -std=gnu99 -c -o config-temp/qemu-conf.o config-temp/qemu-conf.c
config-temp/qemu-conf.c:2:2: error: #error __i386__ not defined
 #error __i386__ not defined
  ^~~~~

---
funcs: do_compiler do_cc compile_object check_define main
lines: 92 122 617 689 0
x86_64-w64-mingw32-gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -std=gnu99 -c -o config-temp/qemu-conf.o config-temp/qemu-conf.c
config-temp/qemu-conf.c:2:2: error: #error __ILP32__ not defined
 #error __ILP32__ not defined
  ^~~~~

---
lines: 92 128 920 0
x86_64-w64-mingw32-gcc -mthreads -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -std=gnu99 -o config-temp/qemu-conf.exe config-temp/qemu-conf.c -g -liberty
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -liberty
collect2: error: ld returned 1 exit status
Failed to run 'configure'
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 563, in <module>


The full log is available at
http://patchew.org/logs/20190201163518.31157-1-kwolf@redhat.com/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [Qemu-devel] [PULL 00/27] Block layer patches
@ 2019-04-30 16:57   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2019-04-30 16:57 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: Qemu-block, QEMU Developers

On Tue, 30 Apr 2019 at 17:01, Kevin Wolf <kwolf@redhat.com> wrote:
>
> The following changes since commit 22d96eac64877c4d96f9928babb6f2fcc68faacf:
>
>   Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2019-04-29 19:11:15 +0100)
>
> are available in the Git repository at:
>
>   git://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to 54277a2aab876aba7b55c7e88e2b372691849741:
>
>   block/qed: add missed coroutine_fn markers (2019-04-30 15:29:00 +0200)
>
> ----------------------------------------------------------------
> Block layer patches:
>
> - iotests: Fix output of qemu-io related tests
> - Don't ignore bdrv_set_aio_context() for nodes with bs->drv = NUL
> - vmdk: Set vmdk parent backing_format to vmdk
> - qcow2: Preallocation fixes (especially for external data files)
> - Add linear-buffer-based APIs (as wrappers around qiov-based ones)
> - Various code cleanups and small corner case fixes
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.1
for any user-visible changes.

-- PMM

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

* Re: [Qemu-devel] [PULL 00/27] Block layer patches
@ 2019-04-30 16:57   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2019-04-30 16:57 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: QEMU Developers, Qemu-block

On Tue, 30 Apr 2019 at 17:01, Kevin Wolf <kwolf@redhat.com> wrote:
>
> The following changes since commit 22d96eac64877c4d96f9928babb6f2fcc68faacf:
>
>   Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2019-04-29 19:11:15 +0100)
>
> are available in the Git repository at:
>
>   git://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to 54277a2aab876aba7b55c7e88e2b372691849741:
>
>   block/qed: add missed coroutine_fn markers (2019-04-30 15:29:00 +0200)
>
> ----------------------------------------------------------------
> Block layer patches:
>
> - iotests: Fix output of qemu-io related tests
> - Don't ignore bdrv_set_aio_context() for nodes with bs->drv = NUL
> - vmdk: Set vmdk parent backing_format to vmdk
> - qcow2: Preallocation fixes (especially for external data files)
> - Add linear-buffer-based APIs (as wrappers around qiov-based ones)
> - Various code cleanups and small corner case fixes
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.1
for any user-visible changes.

-- PMM


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

* [Qemu-devel] [PULL 00/27] Block layer patches
@ 2019-04-30 15:42 Kevin Wolf
  2019-04-30 16:57   ` Peter Maydell
  0 siblings, 1 reply; 36+ messages in thread
From: Kevin Wolf @ 2019-04-30 15:42 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, qemu-devel

The following changes since commit 22d96eac64877c4d96f9928babb6f2fcc68faacf:

  Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2019-04-29 19:11:15 +0100)

are available in the Git repository at:

  git://repo.or.cz/qemu/kevin.git tags/for-upstream

for you to fetch changes up to 54277a2aab876aba7b55c7e88e2b372691849741:

  block/qed: add missed coroutine_fn markers (2019-04-30 15:29:00 +0200)

----------------------------------------------------------------
Block layer patches:

- iotests: Fix output of qemu-io related tests
- Don't ignore bdrv_set_aio_context() for nodes with bs->drv = NUL
- vmdk: Set vmdk parent backing_format to vmdk
- qcow2: Preallocation fixes (especially for external data files)
- Add linear-buffer-based APIs (as wrappers around qiov-based ones)
- Various code cleanups and small corner case fixes

----------------------------------------------------------------
Alberto Garcia (3):
      qcow2: Fix error handling in the compression code
      commit: Make base read-only if there is an early failure
      iotests: Check that images are in read-only mode after block-commit

Eric Blake (2):
      cutils: Fix size_to_str() on 32-bit platforms
      qemu-img: Saner printing of large file sizes

Kevin Wolf (5):
      block: Fix AioContext switch for bs->drv == NULL
      qcow2: Avoid COW during metadata preallocation
      qcow2: Add errp to preallocate_co()
      qcow2: Fix full preallocation with external data file
      qcow2: Fix qcow2_make_empty() with external data file

Max Reitz (2):
      iotests: Perform the correct test in 082
      qemu-img: Make create hint at protocol options

Sam Eiderman (1):
      vmdk: Set vmdk parent backing_format to vmdk

Stefano Garzarella (2):
      block/vhdx: Remove redundant IEC binary prefixes definition
      block/vhdx: Use IEC binary prefixes for size constants

Thomas Huth (1):
      tests/qemu-iotests: Fix output of qemu-io related tests

Vladimir Sementsov-Ogievskiy (10):
      block: introduce byte-based io helpers
      block/qcow2: use buffer-based io
      block/qcow: use buffer-based io
      block/qed: use buffer-based io
      block/parallels: use buffer-based io
      block/backup: use buffer-based io
      block/commit: use buffer-based io
      block/stream: use buffer-based io
      qemu-img: use buffer-based io
      block/qed: add missed coroutine_fn markers

Zhengui li (1):
      vpc: unlock Coroutine lock to make IO submit Concurrently

 block/qed.h                    |  28 ++++---
 block/vhdx.h                   |  16 ++--
 include/block/block_int.h      |  16 ++++
 include/sysemu/block-backend.h |  19 +++++
 block.c                        |  12 +--
 block/backup.c                 |  14 ++--
 block/commit.c                 |   8 +-
 block/parallels.c              |  14 ++--
 block/qapi.c                   |  49 +++---------
 block/qcow.c                   |  19 ++---
 block/qcow2.c                  |  80 ++++++++++----------
 block/qed-check.c              |   4 +-
 block/qed-table.c              |  45 ++++++-----
 block/qed.c                    |  11 ++-
 block/stream.c                 |   4 +-
 block/vhdx-log.c               |   2 +-
 block/vhdx.c                   |   7 +-
 block/vmdk.c                   |   2 +
 block/vpc.c                    |   4 +
 qemu-img.c                     |  26 ++++---
 util/cutils.c                  |   2 +-
 tests/qemu-iotests/026.out     | 168 ++++++++++++++++++++---------------------
 tests/qemu-iotests/043.out     |   6 +-
 tests/qemu-iotests/053.out     |   2 +-
 tests/qemu-iotests/059.out     |  10 +--
 tests/qemu-iotests/060.out     |  16 ++--
 tests/qemu-iotests/061.out     |  12 +--
 tests/qemu-iotests/069.out     |   2 +-
 tests/qemu-iotests/070.out     |   4 +-
 tests/qemu-iotests/075.out     |  14 ++--
 tests/qemu-iotests/076.out     |   6 +-
 tests/qemu-iotests/078.out     |  12 +--
 tests/qemu-iotests/080.out     |  40 +++++-----
 tests/qemu-iotests/081.out     |   2 +-
 tests/qemu-iotests/082         |   5 +-
 tests/qemu-iotests/082.out     |  51 ++++++++-----
 tests/qemu-iotests/084.out     |   8 +-
 tests/qemu-iotests/088.out     |  12 +--
 tests/qemu-iotests/089.out     |   2 +-
 tests/qemu-iotests/095.out     |   4 +-
 tests/qemu-iotests/103.out     |  14 ++--
 tests/qemu-iotests/104.out     |   6 +-
 tests/qemu-iotests/110.out     |   6 +-
 tests/qemu-iotests/114.out     |   4 +-
 tests/qemu-iotests/116.out     |  14 ++--
 tests/qemu-iotests/126.out     |   4 +-
 tests/qemu-iotests/130.out     |  10 +--
 tests/qemu-iotests/131.out     |   2 +-
 tests/qemu-iotests/133.out     |  30 ++++----
 tests/qemu-iotests/137.out     |  28 +++----
 tests/qemu-iotests/140.out     |   2 +-
 tests/qemu-iotests/143.out     |   2 +-
 tests/qemu-iotests/153.out     |  32 ++++----
 tests/qemu-iotests/187.out     |   6 +-
 tests/qemu-iotests/188.out     |   2 +-
 tests/qemu-iotests/191.out     |   8 +-
 tests/qemu-iotests/195.out     |   4 +-
 tests/qemu-iotests/197.out     |   2 +-
 tests/qemu-iotests/198.out     |   4 +-
 tests/qemu-iotests/205         |   2 +-
 tests/qemu-iotests/206.out     |  10 +--
 tests/qemu-iotests/207.out     |  12 +--
 tests/qemu-iotests/210.out     |   8 +-
 tests/qemu-iotests/211.out     |  10 +--
 tests/qemu-iotests/212.out     |  10 +--
 tests/qemu-iotests/213.out     |  10 +--
 tests/qemu-iotests/215.out     |   2 +-
 tests/qemu-iotests/226.out     |  16 ++--
 tests/qemu-iotests/233.out     |   4 +-
 tests/qemu-iotests/237.out     |  22 +++---
 tests/qemu-iotests/242.out     |  10 +--
 tests/qemu-iotests/244.out     |  10 +--
 tests/qemu-iotests/249         | 115 ++++++++++++++++++++++++++++
 tests/qemu-iotests/249.out     |  35 +++++++++
 tests/qemu-iotests/group       |   1 +
 75 files changed, 696 insertions(+), 519 deletions(-)
 create mode 100755 tests/qemu-iotests/249
 create mode 100644 tests/qemu-iotests/249.out

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

end of thread, other threads:[~2019-04-30 17:22 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-01 16:34 [Qemu-devel] [PULL 00/27] Block layer patches Kevin Wolf
2019-02-01 16:34 ` [Qemu-devel] [PULL 01/27] mirror: Release the dirty bitmap if mirror_start_job() fails Kevin Wolf
2019-02-01 16:34 ` [Qemu-devel] [PULL 02/27] mirror: Block the source BlockDriverState in mirror_start_job() Kevin Wolf
2019-02-01 16:34 ` [Qemu-devel] [PULL 03/27] qcow2: Assert that refcount block offsets fit in the refcount table Kevin Wolf
2019-02-01 16:34 ` [Qemu-devel] [PULL 04/27] qemu-iotests: add test case for dmg Kevin Wolf
2019-02-01 16:34 ` [Qemu-devel] [PULL 05/27] block: Replace qdict_put() by qdict_put_obj() where appropriate Kevin Wolf
2019-02-01 16:34 ` [Qemu-devel] [PULL 06/27] block: Fix hangs in synchronous APIs with iothreads Kevin Wolf
2019-02-01 16:34 ` [Qemu-devel] [PULL 07/27] iotests: Make 234 stable Kevin Wolf
2019-02-01 16:34 ` [Qemu-devel] [PULL 08/27] vmdk: Refactor vmdk_create_extent Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 09/27] vmdk: Implement .bdrv_co_create callback Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 10/27] iotests: Filter cid numbers in VMDK extent info Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 11/27] iotests: Add VMDK tests for blockdev-create Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 12/27] vmdk: Reject excess extents in blockdev-create Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 13/27] block/vpc: Don't take address of fields in packed structs Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 14/27] block/vdi: " Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 15/27] uuid: Make qemu_uuid_bswap() take and return a QemuUUID Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 16/27] block: Apply auto-read-only for ro-whitelist drivers Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 17/27] block: Remove blk_attach_dev_legacy() / legacy_dev code Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 18/27] block: Eliminate the S_1KiB, S_2KiB, ... macros Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 19/27] virtio-scsi: Move BlockBackend back to the main AioContext on unplug Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 20/27] scsi-disk: Acquire the AioContext in scsi_*_realize() Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 21/27] virtio-scsi: Forbid devices with different iothreads sharing a blockdev Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 22/27] iotests: Filter second BLOCK_JOB_ERROR from 229 Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 23/27] iotests/236: fix transaction kwarg order Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 24/27] block: Fix invalidate_cache error path for parent activation Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 25/27] qtest.py: Wait for the result of qtest commands Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 26/27] scsi-disk: Don't use empty string as device id Kevin Wolf
2019-02-01 16:35 ` [Qemu-devel] [PULL 27/27] scsi-disk: Add device_id property Kevin Wolf
2019-02-01 17:24 ` [Qemu-devel] [PULL 00/27] Block layer patches no-reply
2019-02-01 17:24 ` no-reply
2019-02-01 17:27 ` no-reply
2019-02-01 19:05 ` Peter Maydell
2019-02-03 15:10 ` no-reply
2019-04-30 15:42 Kevin Wolf
2019-04-30 16:57 ` Peter Maydell
2019-04-30 16:57   ` Peter Maydell

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.