qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes
@ 2014-09-12 19:26 Markus Armbruster
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation Markus Armbruster
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: Markus Armbruster @ 2014-09-12 19:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

More random crap I ran into while iterating on BlockBackends.

Markus Armbruster (4):
  blockdev: Disentangle BlockDriverState and DriveInfo creation
  block: Keep DriveInfo alive until BlockDriverState dies
  qemu-nbd: Destroy the BlockDriverState properly
  block: Improve message for device name clashing with node name

 block.c                    |  5 ++++-
 blockdev.c                 | 56 +++++++++++++++++++++++++---------------------
 include/sysemu/blockdev.h  |  1 +
 qemu-nbd.c                 |  2 +-
 stubs/Makefile.objs        |  1 +
 stubs/blockdev.c           | 12 ++++++++++
 tests/qemu-iotests/087.out |  2 +-
 7 files changed, 51 insertions(+), 28 deletions(-)
 create mode 100644 stubs/blockdev.c

-- 
1.9.3

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

* [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation
  2014-09-12 19:26 [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Markus Armbruster
@ 2014-09-12 19:26 ` Markus Armbruster
  2014-09-13 18:36   ` Max Reitz
  2014-09-15 11:17   ` Benoît Canet
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies Markus Armbruster
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 16+ messages in thread
From: Markus Armbruster @ 2014-09-12 19:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

blockdev_init() mixes up BlockDriverState and DriveInfo initialization
Finish the BlockDriverState job before starting to mess with
DriveInfo.  Easier on the eyes.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 blockdev.c | 43 +++++++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index b361fbb..5ec4635 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -301,6 +301,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     int ro = 0;
     int bdrv_flags = 0;
     int on_read_error, on_write_error;
+    BlockDriverState *bs;
     DriveInfo *dinfo;
     ThrottleConfig cfg;
     int snapshot = 0;
@@ -456,26 +457,27 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     }
 
     /* init */
+    bs = bdrv_new(qemu_opts_id(opts), errp);
+    if (!bs) {
+        goto early_err;
+    }
+    bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
+    bs->read_only = ro;
+    bs->detect_zeroes = detect_zeroes;
+
+    bdrv_set_on_error(bs, on_read_error, on_write_error);
+
+    /* disk I/O throttling */
+    if (throttle_enabled(&cfg)) {
+        bdrv_io_limits_enable(bs);
+        bdrv_set_io_limits(bs, &cfg);
+    }
+
     dinfo = g_malloc0(sizeof(*dinfo));
     dinfo->id = g_strdup(qemu_opts_id(opts));
-    dinfo->bdrv = bdrv_new(dinfo->id, &error);
-    if (error) {
-        error_propagate(errp, error);
-        goto bdrv_new_err;
-    }
-    dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
-    dinfo->bdrv->read_only = ro;
-    dinfo->bdrv->detect_zeroes = detect_zeroes;
+    dinfo->bdrv = bs;
     QTAILQ_INSERT_TAIL(&drives, dinfo, next);
 
-    bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
-
-    /* disk I/O throttling */
-    if (throttle_enabled(&cfg)) {
-        bdrv_io_limits_enable(dinfo->bdrv);
-        bdrv_set_io_limits(dinfo->bdrv, &cfg);
-    }
-
     if (!file || !*file) {
         if (has_driver_specific_opts) {
             file = NULL;
@@ -502,7 +504,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
 
     QINCREF(bs_opts);
-    ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, &error);
+    ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
+    assert(bs == dinfo->bdrv);
 
     if (ret < 0) {
         error_setg(errp, "could not open disk image %s: %s",
@@ -511,8 +514,9 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
         goto err;
     }
 
-    if (bdrv_key_required(dinfo->bdrv))
+    if (bdrv_key_required(bs)) {
         autostart = 0;
+    }
 
     QDECREF(bs_opts);
     qemu_opts_del(opts);
@@ -520,9 +524,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     return dinfo;
 
 err:
-    bdrv_unref(dinfo->bdrv);
+    bdrv_unref(bs);
     QTAILQ_REMOVE(&drives, dinfo, next);
-bdrv_new_err:
     g_free(dinfo->id);
     g_free(dinfo);
 early_err:
-- 
1.9.3

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

* [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies
  2014-09-12 19:26 [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Markus Armbruster
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation Markus Armbruster
@ 2014-09-12 19:26 ` Markus Armbruster
  2014-09-13 19:32   ` Max Reitz
                     ` (2 more replies)
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 3/4] qemu-nbd: Destroy the BlockDriverState properly Markus Armbruster
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 16+ messages in thread
From: Markus Armbruster @ 2014-09-12 19:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

If the BDS's refcnt > 0, drive_del() destroys the DriveInfo, but not
the BDS.  This can happen in three places:

* Device model destruction during unplug: blockdev_auto_del()

* Xen IDE unplug: pci_piix3_xen_ide_unplug()

* drive_del command when no device model is attached: do_drive_del()

The other callers of drive_del are on error paths where refcnt == 1.

If the user somehow manages to plug in a device model using a BDS that
has gone through drive_del(), the legacy configuration passed in
DriveInfo doesn't reach the device model, and automatic deletion on
unplug doesn't work.  Worse, some device models such as scsi-disk
crash when DriveInfo doesn't exist.

This is theoretical; I didn't research an actual reproducer.

Fix by keeping DriveInfo alive until its BDS dies.

This affects qemu_drive_opts: now you can't reuse the same ID for new
drive options until the BDS dies.  Before, you could, but since the
code always attempts to create a BDS with the same ID next, the
enclosing operation "create a new drive" failed anyway.  Different
error path, same result.

Unfortunately, the fix involves use of blockdev.c stuff from block.c,
which is a layering violation.  Fortunately, my forthcoming
BlockBackend work will get rid of it again.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c                   |  2 ++
 blockdev.c                | 13 ++++++++-----
 include/sysemu/blockdev.h |  1 +
 stubs/Makefile.objs       |  1 +
 stubs/blockdev.c          | 12 ++++++++++++
 5 files changed, 24 insertions(+), 5 deletions(-)
 create mode 100644 stubs/blockdev.c

diff --git a/block.c b/block.c
index d06dd51..6faf36f 100644
--- a/block.c
+++ b/block.c
@@ -29,6 +29,7 @@
 #include "qemu/module.h"
 #include "qapi/qmp/qjson.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/blockdev.h"    /* FIXME layering violation */
 #include "qemu/notify.h"
 #include "block/coroutine.h"
 #include "block/qapi.h"
@@ -2110,6 +2111,7 @@ static void bdrv_delete(BlockDriverState *bs)
     /* remove from list, if necessary */
     bdrv_make_anon(bs);
 
+    drive_info_del(drive_get_by_blockdev(bs));
     g_free(bs);
 }
 
diff --git a/blockdev.c b/blockdev.c
index 5ec4635..450f95c 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -216,11 +216,17 @@ static void bdrv_format_print(void *opaque, const char *name)
 
 void drive_del(DriveInfo *dinfo)
 {
+    bdrv_unref(dinfo->bdrv);
+}
+
+void drive_info_del(DriveInfo *dinfo)
+{
+    if (!dinfo) {
+        return;
+    }
     if (dinfo->opts) {
         qemu_opts_del(dinfo->opts);
     }
-
-    bdrv_unref(dinfo->bdrv);
     g_free(dinfo->id);
     QTAILQ_REMOVE(&drives, dinfo, next);
     g_free(dinfo->serial);
@@ -525,9 +531,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
 
 err:
     bdrv_unref(bs);
-    QTAILQ_REMOVE(&drives, dinfo, next);
-    g_free(dinfo->id);
-    g_free(dinfo);
 early_err:
     qemu_opts_del(opts);
 err_no_opts:
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 23a5d10..abec381 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -56,6 +56,7 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
                     const char *optstr);
 DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
 void drive_del(DriveInfo *dinfo);
+void drive_info_del(DriveInfo *dinfo);
 
 /* device-hotplug */
 
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 5e347d0..c0b1f6a 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,5 +1,6 @@
 stub-obj-y += arch-query-cpu-def.o
 stub-obj-y += bdrv-commit-all.o
+stub-obj-y += blockdev.o
 stub-obj-y += chr-baum-init.o
 stub-obj-y += chr-msmouse.o
 stub-obj-y += chr-testdev.o
diff --git a/stubs/blockdev.c b/stubs/blockdev.c
new file mode 100644
index 0000000..5d0a79c
--- /dev/null
+++ b/stubs/blockdev.c
@@ -0,0 +1,12 @@
+#include <assert.h>
+#include "sysemu/blockdev.h"
+
+DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
+{
+    return NULL;
+}
+
+void drive_info_del(DriveInfo *dinfo)
+{
+    assert(!dinfo);
+}
-- 
1.9.3

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

* [Qemu-devel] [PATCH 3/4] qemu-nbd: Destroy the BlockDriverState properly
  2014-09-12 19:26 [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Markus Armbruster
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation Markus Armbruster
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies Markus Armbruster
@ 2014-09-12 19:26 ` Markus Armbruster
  2014-09-13 12:49   ` Paolo Bonzini
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name Markus Armbruster
  2014-09-22 16:31 ` [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Kevin Wolf
  4 siblings, 1 reply; 16+ messages in thread
From: Markus Armbruster @ 2014-09-12 19:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Match the bdrv_new() with a bdrv_unref(), just to be tidy.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qemu-nbd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 9bc152e..f3cf8a2 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -769,7 +769,7 @@ int main(int argc, char **argv)
         }
     } while (state != TERMINATED);
 
-    bdrv_close(bs);
+    bdrv_unref(bs);
     if (sockpath) {
         unlink(sockpath);
     }
-- 
1.9.3

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

* [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name
  2014-09-12 19:26 [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Markus Armbruster
                   ` (2 preceding siblings ...)
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 3/4] qemu-nbd: Destroy the BlockDriverState properly Markus Armbruster
@ 2014-09-12 19:26 ` Markus Armbruster
  2014-09-13 15:47   ` Eric Blake
  2014-09-13 18:52   ` Benoît Canet
  2014-09-22 16:31 ` [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Kevin Wolf
  4 siblings, 2 replies; 16+ messages in thread
From: Markus Armbruster @ 2014-09-12 19:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Suggested-by: Benoit Canet <benoit.canet@nodalink.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c                    | 3 ++-
 tests/qemu-iotests/087.out | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index 6faf36f..02ea90f 100644
--- a/block.c
+++ b/block.c
@@ -347,7 +347,8 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
         return NULL;
     }
     if (bdrv_find_node(device_name)) {
-        error_setg(errp, "Device with node-name '%s' already exists",
+        error_setg(errp,
+                   "Device name '%s' conflicts with an existing node name",
                    device_name);
         return NULL;
     }
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
index 7fbee3f..75a54e0 100644
--- a/tests/qemu-iotests/087.out
+++ b/tests/qemu-iotests/087.out
@@ -20,7 +20,7 @@ QMP_VERSION
 {"return": {}}
 {"return": {}}
 {"error": {"class": "GenericError", "desc": "Device with id 'disk' already exists"}}
-{"error": {"class": "GenericError", "desc": "Device with node-name 'test-node' already exists"}}
+{"error": {"class": "GenericError", "desc": "Device name 'test-node' conflicts with an existing node name"}}
 main-loop: WARNING: I/O thread spun for 1000 iterations
 {"error": {"class": "GenericError", "desc": "could not open disk image disk2: node-name=disk is conflicting with a device id"}}
 {"error": {"class": "GenericError", "desc": "could not open disk image disk2: Duplicate node name"}}
-- 
1.9.3

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

* Re: [Qemu-devel] [PATCH 3/4] qemu-nbd: Destroy the BlockDriverState properly
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 3/4] qemu-nbd: Destroy the BlockDriverState properly Markus Armbruster
@ 2014-09-13 12:49   ` Paolo Bonzini
  0 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2014-09-13 12:49 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Il 12/09/2014 21:26, Markus Armbruster ha scritto:
> Match the bdrv_new() with a bdrv_unref(), just to be tidy.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  qemu-nbd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/qemu-nbd.c b/qemu-nbd.c
> index 9bc152e..f3cf8a2 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -769,7 +769,7 @@ int main(int argc, char **argv)
>          }
>      } while (state != TERMINATED);
>  
> -    bdrv_close(bs);
> +    bdrv_unref(bs);
>      if (sockpath) {
>          unlink(sockpath);
>      }
> 

Applying to nbd-next, thanks.

Paolo

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

* Re: [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name Markus Armbruster
@ 2014-09-13 15:47   ` Eric Blake
  2014-09-13 18:52   ` Benoît Canet
  1 sibling, 0 replies; 16+ messages in thread
From: Eric Blake @ 2014-09-13 15:47 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel; +Cc: kwolf, benoit.canet, stefanha

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

On 09/12/2014 01:26 PM, Markus Armbruster wrote:
> Suggested-by: Benoit Canet <benoit.canet@nodalink.com>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  block.c                    | 3 ++-
>  tests/qemu-iotests/087.out | 2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)

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

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


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

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

* Re: [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation Markus Armbruster
@ 2014-09-13 18:36   ` Max Reitz
  2014-09-15  6:35     ` Markus Armbruster
  2014-09-15 11:17   ` Benoît Canet
  1 sibling, 1 reply; 16+ messages in thread
From: Max Reitz @ 2014-09-13 18:36 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel; +Cc: kwolf, benoit.canet, stefanha

On 12.09.2014 21:26, Markus Armbruster wrote:
> blockdev_init() mixes up BlockDriverState and DriveInfo initialization
> Finish the BlockDriverState job before starting to mess with
> DriveInfo.  Easier on the eyes.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>   blockdev.c | 43 +++++++++++++++++++++++--------------------
>   1 file changed, 23 insertions(+), 20 deletions(-)
>
> diff --git a/blockdev.c b/blockdev.c
> index b361fbb..5ec4635 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -301,6 +301,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>       int ro = 0;
>       int bdrv_flags = 0;
>       int on_read_error, on_write_error;
> +    BlockDriverState *bs;
>       DriveInfo *dinfo;
>       ThrottleConfig cfg;
>       int snapshot = 0;
> @@ -456,26 +457,27 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>       }
>   
>       /* init */
> +    bs = bdrv_new(qemu_opts_id(opts), errp);
> +    if (!bs) {
> +        goto early_err;
> +    }
> +    bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
> +    bs->read_only = ro;
> +    bs->detect_zeroes = detect_zeroes;
> +
> +    bdrv_set_on_error(bs, on_read_error, on_write_error);
> +
> +    /* disk I/O throttling */
> +    if (throttle_enabled(&cfg)) {
> +        bdrv_io_limits_enable(bs);
> +        bdrv_set_io_limits(bs, &cfg);
> +    }
> +
>       dinfo = g_malloc0(sizeof(*dinfo));

Could've changed this to g_new0 in the process, but you're the expert 
for that, so I'll leave it up to you. ;-)

>       dinfo->id = g_strdup(qemu_opts_id(opts));
> -    dinfo->bdrv = bdrv_new(dinfo->id, &error);
> -    if (error) {
> -        error_propagate(errp, error);
> -        goto bdrv_new_err;
> -    }
> -    dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
> -    dinfo->bdrv->read_only = ro;
> -    dinfo->bdrv->detect_zeroes = detect_zeroes;
> +    dinfo->bdrv = bs;
>       QTAILQ_INSERT_TAIL(&drives, dinfo, next);
>   
> -    bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
> -
> -    /* disk I/O throttling */
> -    if (throttle_enabled(&cfg)) {
> -        bdrv_io_limits_enable(dinfo->bdrv);
> -        bdrv_set_io_limits(dinfo->bdrv, &cfg);
> -    }
> -
>       if (!file || !*file) {
>           if (has_driver_specific_opts) {
>               file = NULL;
> @@ -502,7 +504,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>       bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
>   
>       QINCREF(bs_opts);
> -    ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, &error);
> +    ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
> +    assert(bs == dinfo->bdrv);

Well, this is guaranteed by bdrv_open(), but of course better having too 
many assertions than too few.

With or without g_new0:

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

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

* Re: [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name Markus Armbruster
  2014-09-13 15:47   ` Eric Blake
@ 2014-09-13 18:52   ` Benoît Canet
  1 sibling, 0 replies; 16+ messages in thread
From: Benoît Canet @ 2014-09-13 18:52 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, benoit.canet, qemu-devel, stefanha

The Friday 12 Sep 2014 à 21:26:24 (+0200), Markus Armbruster wrote :
> Suggested-by: Benoit Canet <benoit.canet@nodalink.com>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  block.c                    | 3 ++-
>  tests/qemu-iotests/087.out | 2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 6faf36f..02ea90f 100644
> --- a/block.c
> +++ b/block.c
> @@ -347,7 +347,8 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
>          return NULL;
>      }
>      if (bdrv_find_node(device_name)) {
> -        error_setg(errp, "Device with node-name '%s' already exists",
> +        error_setg(errp,
> +                   "Device name '%s' conflicts with an existing node name",
>                     device_name);
>          return NULL;
>      }
> diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
> index 7fbee3f..75a54e0 100644
> --- a/tests/qemu-iotests/087.out
> +++ b/tests/qemu-iotests/087.out
> @@ -20,7 +20,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"error": {"class": "GenericError", "desc": "Device with id 'disk' already exists"}}
> -{"error": {"class": "GenericError", "desc": "Device with node-name 'test-node' already exists"}}
> +{"error": {"class": "GenericError", "desc": "Device name 'test-node' conflicts with an existing node name"}}
>  main-loop: WARNING: I/O thread spun for 1000 iterations
>  {"error": {"class": "GenericError", "desc": "could not open disk image disk2: node-name=disk is conflicting with a device id"}}
>  {"error": {"class": "GenericError", "desc": "could not open disk image disk2: Duplicate node name"}}
> -- 
> 1.9.3
> 

Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

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

* Re: [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies Markus Armbruster
@ 2014-09-13 19:32   ` Max Reitz
  2014-09-15  6:23   ` Markus Armbruster
  2014-09-15 11:38   ` Benoît Canet
  2 siblings, 0 replies; 16+ messages in thread
From: Max Reitz @ 2014-09-13 19:32 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel; +Cc: kwolf, benoit.canet, stefanha

On 12.09.2014 21:26, Markus Armbruster wrote:
> If the BDS's refcnt > 0, drive_del() destroys the DriveInfo, but not
> the BDS.  This can happen in three places:
>
> * Device model destruction during unplug: blockdev_auto_del()
>
> * Xen IDE unplug: pci_piix3_xen_ide_unplug()
>
> * drive_del command when no device model is attached: do_drive_del()
>
> The other callers of drive_del are on error paths where refcnt == 1.
>
> If the user somehow manages to plug in a device model using a BDS that
> has gone through drive_del(), the legacy configuration passed in
> DriveInfo doesn't reach the device model, and automatic deletion on
> unplug doesn't work.  Worse, some device models such as scsi-disk
> crash when DriveInfo doesn't exist.
>
> This is theoretical; I didn't research an actual reproducer.
>
> Fix by keeping DriveInfo alive until its BDS dies.
>
> This affects qemu_drive_opts: now you can't reuse the same ID for new
> drive options until the BDS dies.  Before, you could, but since the
> code always attempts to create a BDS with the same ID next, the
> enclosing operation "create a new drive" failed anyway.  Different
> error path, same result.
>
> Unfortunately, the fix involves use of blockdev.c stuff from block.c,
> which is a layering violation.  Fortunately, my forthcoming
> BlockBackend work will get rid of it again.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>   block.c                   |  2 ++
>   blockdev.c                | 13 ++++++++-----
>   include/sysemu/blockdev.h |  1 +
>   stubs/Makefile.objs       |  1 +
>   stubs/blockdev.c          | 12 ++++++++++++
>   5 files changed, 24 insertions(+), 5 deletions(-)
>   create mode 100644 stubs/blockdev.c

Seems reasonable.

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

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

* Re: [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies Markus Armbruster
  2014-09-13 19:32   ` Max Reitz
@ 2014-09-15  6:23   ` Markus Armbruster
  2014-09-15 11:38   ` Benoît Canet
  2 siblings, 0 replies; 16+ messages in thread
From: Markus Armbruster @ 2014-09-15  6:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Markus Armbruster <armbru@redhat.com> writes:

> If the BDS's refcnt > 0, drive_del() destroys the DriveInfo, but not
> the BDS.  This can happen in three places:
>
> * Device model destruction during unplug: blockdev_auto_del()
>
> * Xen IDE unplug: pci_piix3_xen_ide_unplug()
>
> * drive_del command when no device model is attached: do_drive_del()
>
> The other callers of drive_del are on error paths where refcnt == 1.
>
> If the user somehow manages to plug in a device model using a BDS that
> has gone through drive_del(), the legacy configuration passed in
> DriveInfo doesn't reach the device model, and automatic deletion on
> unplug doesn't work.  Worse, some device models such as scsi-disk
> crash when DriveInfo doesn't exist.
>
> This is theoretical; I didn't research an actual reproducer.

Broken when we replaced DriveInfo reference counting by BDS reference
counting in commit a94a3fa..fa510eb.

Kevin, would you mind inserting that into the commit message?

> Fix by keeping DriveInfo alive until its BDS dies.
>
> This affects qemu_drive_opts: now you can't reuse the same ID for new
> drive options until the BDS dies.  Before, you could, but since the
> code always attempts to create a BDS with the same ID next, the
> enclosing operation "create a new drive" failed anyway.  Different
> error path, same result.
>
> Unfortunately, the fix involves use of blockdev.c stuff from block.c,
> which is a layering violation.  Fortunately, my forthcoming
> BlockBackend work will get rid of it again.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
[...]

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

* Re: [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation
  2014-09-13 18:36   ` Max Reitz
@ 2014-09-15  6:35     ` Markus Armbruster
  0 siblings, 0 replies; 16+ messages in thread
From: Markus Armbruster @ 2014-09-15  6:35 UTC (permalink / raw)
  To: Max Reitz; +Cc: kwolf, benoit.canet, qemu-devel, stefanha

Max Reitz <mreitz@redhat.com> writes:

> On 12.09.2014 21:26, Markus Armbruster wrote:
>> blockdev_init() mixes up BlockDriverState and DriveInfo initialization
>> Finish the BlockDriverState job before starting to mess with
>> DriveInfo.  Easier on the eyes.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>   blockdev.c | 43 +++++++++++++++++++++++--------------------
>>   1 file changed, 23 insertions(+), 20 deletions(-)
>>
>> diff --git a/blockdev.c b/blockdev.c
>> index b361fbb..5ec4635 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -301,6 +301,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>       int ro = 0;
>>       int bdrv_flags = 0;
>>       int on_read_error, on_write_error;
>> +    BlockDriverState *bs;
>>       DriveInfo *dinfo;
>>       ThrottleConfig cfg;
>>       int snapshot = 0;
>> @@ -456,26 +457,27 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>       }
>>         /* init */
>> +    bs = bdrv_new(qemu_opts_id(opts), errp);
>> +    if (!bs) {
>> +        goto early_err;
>> +    }
>> +    bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
>> +    bs->read_only = ro;
>> +    bs->detect_zeroes = detect_zeroes;
>> +
>> +    bdrv_set_on_error(bs, on_read_error, on_write_error);
>> +
>> +    /* disk I/O throttling */
>> +    if (throttle_enabled(&cfg)) {
>> +        bdrv_io_limits_enable(bs);
>> +        bdrv_set_io_limits(bs, &cfg);
>> +    }
>> +
>>       dinfo = g_malloc0(sizeof(*dinfo));
>
> Could've changed this to g_new0 in the process, but you're the expert
> for that, so I'll leave it up to you. ;-)

When I made block use g_new() & friends, I only converted patterns like
p = g_malloc(sizeof(T)), not patterns like p = g_malloc(sizeof(*p)).

In the former case, p = g_new(T) is a clear improvement, because now the
compiler checks T matches typeof(*p).

In the latter case, we trade some visible obviousness for type safety.
Matter of taste.

If we agree to prefer type safety in block land, I'll gladly do the
conversion work.

>>       dinfo->id = g_strdup(qemu_opts_id(opts));
>> -    dinfo->bdrv = bdrv_new(dinfo->id, &error);
>> -    if (error) {
>> -        error_propagate(errp, error);
>> -        goto bdrv_new_err;
>> -    }
>> -    dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
>> -    dinfo->bdrv->read_only = ro;
>> -    dinfo->bdrv->detect_zeroes = detect_zeroes;
>> +    dinfo->bdrv = bs;
>>       QTAILQ_INSERT_TAIL(&drives, dinfo, next);
>>   -    bdrv_set_on_error(dinfo->bdrv, on_read_error,
>> on_write_error);
>> -
>> -    /* disk I/O throttling */
>> -    if (throttle_enabled(&cfg)) {
>> -        bdrv_io_limits_enable(dinfo->bdrv);
>> -        bdrv_set_io_limits(dinfo->bdrv, &cfg);
>> -    }
>> -
>>       if (!file || !*file) {
>>           if (has_driver_specific_opts) {
>>               file = NULL;
>> @@ -502,7 +504,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>       bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
>>         QINCREF(bs_opts);
>> -    ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, &error);
>> +    ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
>> +    assert(bs == dinfo->bdrv);
>
> Well, this is guaranteed by bdrv_open(), but of course better having
> too many assertions than too few.

Indeed.  bdrv_open() is in another file, and its function comment
doesn't quite spell out this part of its contract.

Assertions do double-duty: they check assumptions are valid, and they
remind the reader of assumptions.  The second part can be useful even
when the first part is trivial.

> With or without g_new0:
>
> Reviewed-by: Max Reitz <mreitz@redhat.com>

Thanks!

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

* Re: [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation Markus Armbruster
  2014-09-13 18:36   ` Max Reitz
@ 2014-09-15 11:17   ` Benoît Canet
  2014-09-15 11:52     ` Markus Armbruster
  1 sibling, 1 reply; 16+ messages in thread
From: Benoît Canet @ 2014-09-15 11:17 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, benoit.canet, qemu-devel, stefanha

The Friday 12 Sep 2014 à 21:26:21 (+0200), Markus Armbruster wrote :
> blockdev_init() mixes up BlockDriverState and DriveInfo initialization
> Finish the BlockDriverState job before starting to mess with
> DriveInfo.  Easier on the eyes.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  blockdev.c | 43 +++++++++++++++++++++++--------------------
>  1 file changed, 23 insertions(+), 20 deletions(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index b361fbb..5ec4635 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -301,6 +301,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>      int ro = 0;
>      int bdrv_flags = 0;
>      int on_read_error, on_write_error;
> +    BlockDriverState *bs;
>      DriveInfo *dinfo;
>      ThrottleConfig cfg;
>      int snapshot = 0;
> @@ -456,26 +457,27 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>      }
>  
>      /* init */
> +    bs = bdrv_new(qemu_opts_id(opts), errp);
> +    if (!bs) {
> +        goto early_err;
> +    }
> +    bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
> +    bs->read_only = ro;
> +    bs->detect_zeroes = detect_zeroes;
> +
> +    bdrv_set_on_error(bs, on_read_error, on_write_error);
> +
> +    /* disk I/O throttling */
> +    if (throttle_enabled(&cfg)) {
> +        bdrv_io_limits_enable(bs);
> +        bdrv_set_io_limits(bs, &cfg);
> +    }
> +
>      dinfo = g_malloc0(sizeof(*dinfo));
>      dinfo->id = g_strdup(qemu_opts_id(opts));
> -    dinfo->bdrv = bdrv_new(dinfo->id, &error);
> -    if (error) {
> -        error_propagate(errp, error);
> -        goto bdrv_new_err;
> -    }
> -    dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
> -    dinfo->bdrv->read_only = ro;
> -    dinfo->bdrv->detect_zeroes = detect_zeroes;
> +    dinfo->bdrv = bs;
>      QTAILQ_INSERT_TAIL(&drives, dinfo, next);
>  
> -    bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
> -
> -    /* disk I/O throttling */
> -    if (throttle_enabled(&cfg)) {
> -        bdrv_io_limits_enable(dinfo->bdrv);
> -        bdrv_set_io_limits(dinfo->bdrv, &cfg);
> -    }
> -
>      if (!file || !*file) {
>          if (has_driver_specific_opts) {
>              file = NULL;
> @@ -502,7 +504,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>      bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
>  
>      QINCREF(bs_opts);
> -    ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, &error);
> +    ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
> +    assert(bs == dinfo->bdrv);
>  
>      if (ret < 0) {
>          error_setg(errp, "could not open disk image %s: %s",
> @@ -511,8 +514,9 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>          goto err;
>      }
>  
> -    if (bdrv_key_required(dinfo->bdrv))
> +    if (bdrv_key_required(bs)) {
>          autostart = 0;
> +    }
>  
>      QDECREF(bs_opts);
>      qemu_opts_del(opts);
> @@ -520,9 +524,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>      return dinfo;
>  
>  err:
> -    bdrv_unref(dinfo->bdrv);

> +    bdrv_unref(bs);
I would have moved this.

>      QTAILQ_REMOVE(&drives, dinfo, next);
> -bdrv_new_err:
>      g_free(dinfo->id);
>      g_free(dinfo);

To Here.

No functional difference but it would reflect it's goto chain role:
being in the reverse order of the allocations.

>  early_err:
> -- 
> 1.9.3

Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>
> 

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

* Re: [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies Markus Armbruster
  2014-09-13 19:32   ` Max Reitz
  2014-09-15  6:23   ` Markus Armbruster
@ 2014-09-15 11:38   ` Benoît Canet
  2 siblings, 0 replies; 16+ messages in thread
From: Benoît Canet @ 2014-09-15 11:38 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, benoit.canet, qemu-devel, stefanha

The Friday 12 Sep 2014 à 21:26:22 (+0200), Markus Armbruster wrote :
> If the BDS's refcnt > 0, drive_del() destroys the DriveInfo, but not
> the BDS.  This can happen in three places:
> 
> * Device model destruction during unplug: blockdev_auto_del()
> 
> * Xen IDE unplug: pci_piix3_xen_ide_unplug()
> 
> * drive_del command when no device model is attached: do_drive_del()
> 
> The other callers of drive_del are on error paths where refcnt == 1.
> 
> If the user somehow manages to plug in a device model using a BDS that
> has gone through drive_del(), the legacy configuration passed in
> DriveInfo doesn't reach the device model, and automatic deletion on
> unplug doesn't work.  Worse, some device models such as scsi-disk
> crash when DriveInfo doesn't exist.
> 
> This is theoretical; I didn't research an actual reproducer.
> 
> Fix by keeping DriveInfo alive until its BDS dies.
> 
> This affects qemu_drive_opts: now you can't reuse the same ID for new
> drive options until the BDS dies.  Before, you could, but since the
> code always attempts to create a BDS with the same ID next, the
> enclosing operation "create a new drive" failed anyway.  Different
> error path, same result.
> 
> Unfortunately, the fix involves use of blockdev.c stuff from block.c,
> which is a layering violation.  Fortunately, my forthcoming
> BlockBackend work will get rid of it again.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  block.c                   |  2 ++
>  blockdev.c                | 13 ++++++++-----
>  include/sysemu/blockdev.h |  1 +
>  stubs/Makefile.objs       |  1 +
>  stubs/blockdev.c          | 12 ++++++++++++
>  5 files changed, 24 insertions(+), 5 deletions(-)
>  create mode 100644 stubs/blockdev.c
> 
> diff --git a/block.c b/block.c
> index d06dd51..6faf36f 100644
> --- a/block.c
> +++ b/block.c
> @@ -29,6 +29,7 @@
>  #include "qemu/module.h"
>  #include "qapi/qmp/qjson.h"
>  #include "sysemu/sysemu.h"
> +#include "sysemu/blockdev.h"    /* FIXME layering violation */
>  #include "qemu/notify.h"
>  #include "block/coroutine.h"
>  #include "block/qapi.h"
> @@ -2110,6 +2111,7 @@ static void bdrv_delete(BlockDriverState *bs)
>      /* remove from list, if necessary */
>      bdrv_make_anon(bs);
>  
> +    drive_info_del(drive_get_by_blockdev(bs));
>      g_free(bs);
>  }
>  
> diff --git a/blockdev.c b/blockdev.c
> index 5ec4635..450f95c 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -216,11 +216,17 @@ static void bdrv_format_print(void *opaque, const char *name)
>  
>  void drive_del(DriveInfo *dinfo)
>  {
> +    bdrv_unref(dinfo->bdrv);
> +}
> +
> +void drive_info_del(DriveInfo *dinfo)
> +{
> +    if (!dinfo) {
> +        return;
> +    }
>      if (dinfo->opts) {
>          qemu_opts_del(dinfo->opts);
>      }
> -
> -    bdrv_unref(dinfo->bdrv);
>      g_free(dinfo->id);
>      QTAILQ_REMOVE(&drives, dinfo, next);
>      g_free(dinfo->serial);
> @@ -525,9 +531,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>  
>  err:
>      bdrv_unref(bs);
> -    QTAILQ_REMOVE(&drives, dinfo, next);
> -    g_free(dinfo->id);
> -    g_free(dinfo);
>  early_err:
>      qemu_opts_del(opts);
>  err_no_opts:
> diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> index 23a5d10..abec381 100644
> --- a/include/sysemu/blockdev.h
> +++ b/include/sysemu/blockdev.h
> @@ -56,6 +56,7 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
>                      const char *optstr);
>  DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
>  void drive_del(DriveInfo *dinfo);
> +void drive_info_del(DriveInfo *dinfo);
>  
>  /* device-hotplug */
>  
> diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
> index 5e347d0..c0b1f6a 100644
> --- a/stubs/Makefile.objs
> +++ b/stubs/Makefile.objs
> @@ -1,5 +1,6 @@
>  stub-obj-y += arch-query-cpu-def.o
>  stub-obj-y += bdrv-commit-all.o
> +stub-obj-y += blockdev.o
>  stub-obj-y += chr-baum-init.o
>  stub-obj-y += chr-msmouse.o
>  stub-obj-y += chr-testdev.o
> diff --git a/stubs/blockdev.c b/stubs/blockdev.c
> new file mode 100644
> index 0000000..5d0a79c
> --- /dev/null
> +++ b/stubs/blockdev.c
> @@ -0,0 +1,12 @@
> +#include <assert.h>
> +#include "sysemu/blockdev.h"
> +
> +DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
> +{
> +    return NULL;
> +}
> +
> +void drive_info_del(DriveInfo *dinfo)
> +{
> +    assert(!dinfo);
> +}
> -- 
> 1.9.3
>


Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

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

* Re: [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation
  2014-09-15 11:17   ` Benoît Canet
@ 2014-09-15 11:52     ` Markus Armbruster
  0 siblings, 0 replies; 16+ messages in thread
From: Markus Armbruster @ 2014-09-15 11:52 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Benoît Canet <benoit.canet@irqsave.net> writes:

> The Friday 12 Sep 2014 à 21:26:21 (+0200), Markus Armbruster wrote :
>> blockdev_init() mixes up BlockDriverState and DriveInfo initialization
>> Finish the BlockDriverState job before starting to mess with
>> DriveInfo.  Easier on the eyes.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  blockdev.c | 43 +++++++++++++++++++++++--------------------
>>  1 file changed, 23 insertions(+), 20 deletions(-)
>> 
>> diff --git a/blockdev.c b/blockdev.c
>> index b361fbb..5ec4635 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -301,6 +301,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>      int ro = 0;
>>      int bdrv_flags = 0;
>>      int on_read_error, on_write_error;
>> +    BlockDriverState *bs;
>>      DriveInfo *dinfo;
>>      ThrottleConfig cfg;
>>      int snapshot = 0;
>> @@ -456,26 +457,27 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>      }
>>  
>>      /* init */
>> +    bs = bdrv_new(qemu_opts_id(opts), errp);
>> +    if (!bs) {
>> +        goto early_err;
>> +    }
>> +    bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
>> +    bs->read_only = ro;
>> +    bs->detect_zeroes = detect_zeroes;
>> +
>> +    bdrv_set_on_error(bs, on_read_error, on_write_error);
>> +
>> +    /* disk I/O throttling */
>> +    if (throttle_enabled(&cfg)) {
>> +        bdrv_io_limits_enable(bs);
>> +        bdrv_set_io_limits(bs, &cfg);
>> +    }
>> +
>>      dinfo = g_malloc0(sizeof(*dinfo));
>>      dinfo->id = g_strdup(qemu_opts_id(opts));
>> -    dinfo->bdrv = bdrv_new(dinfo->id, &error);
>> -    if (error) {
>> -        error_propagate(errp, error);
>> -        goto bdrv_new_err;
>> -    }
>> -    dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
>> -    dinfo->bdrv->read_only = ro;
>> -    dinfo->bdrv->detect_zeroes = detect_zeroes;
>> +    dinfo->bdrv = bs;
>>      QTAILQ_INSERT_TAIL(&drives, dinfo, next);
>>  
>> -    bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
>> -
>> -    /* disk I/O throttling */
>> -    if (throttle_enabled(&cfg)) {
>> -        bdrv_io_limits_enable(dinfo->bdrv);
>> -        bdrv_set_io_limits(dinfo->bdrv, &cfg);
>> -    }
>> -
>>      if (!file || !*file) {
>>          if (has_driver_specific_opts) {
>>              file = NULL;
>> @@ -502,7 +504,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>      bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
>>  
>>      QINCREF(bs_opts);
>> -    ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, &error);
>> +    ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
>> +    assert(bs == dinfo->bdrv);
>>  
>>      if (ret < 0) {
>>          error_setg(errp, "could not open disk image %s: %s",
>> @@ -511,8 +514,9 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>          goto err;
>>      }
>>  
>> -    if (bdrv_key_required(dinfo->bdrv))
>> +    if (bdrv_key_required(bs)) {
>>          autostart = 0;
>> +    }
>>  
>>      QDECREF(bs_opts);
>>      qemu_opts_del(opts);
>> @@ -520,9 +524,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>      return dinfo;
>>  
>>  err:
>> -    bdrv_unref(dinfo->bdrv);
>
>> +    bdrv_unref(bs);
> I would have moved this.
>
>>      QTAILQ_REMOVE(&drives, dinfo, next);
>> -bdrv_new_err:
>>      g_free(dinfo->id);
>>      g_free(dinfo);
>
> To Here.
>
> No functional difference but it would reflect it's goto chain role:
> being in the reverse order of the allocations.

You're right.

In the BlockBackend series, this becomes just

    err:
        blk_unref(blk);
    early_err:

so the disorder is just temporary.  I'll change it anyway if I have to
respin for some other reason.

>>  early_err:
>> -- 
>> 1.9.3
>
> Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

Thanks!

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

* Re: [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes
  2014-09-12 19:26 [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Markus Armbruster
                   ` (3 preceding siblings ...)
  2014-09-12 19:26 ` [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name Markus Armbruster
@ 2014-09-22 16:31 ` Kevin Wolf
  4 siblings, 0 replies; 16+ messages in thread
From: Kevin Wolf @ 2014-09-22 16:31 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: benoit.canet, qemu-devel, stefanha

Am 12.09.2014 um 21:26 hat Markus Armbruster geschrieben:
> More random crap I ran into while iterating on BlockBackends.
> 
> Markus Armbruster (4):
>   blockdev: Disentangle BlockDriverState and DriveInfo creation
>   block: Keep DriveInfo alive until BlockDriverState dies
>   qemu-nbd: Destroy the BlockDriverState properly
>   block: Improve message for device name clashing with node name

Thanks, applied all to the block branch.

Kevin

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

end of thread, other threads:[~2014-09-22 16:32 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-12 19:26 [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Markus Armbruster
2014-09-12 19:26 ` [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation Markus Armbruster
2014-09-13 18:36   ` Max Reitz
2014-09-15  6:35     ` Markus Armbruster
2014-09-15 11:17   ` Benoît Canet
2014-09-15 11:52     ` Markus Armbruster
2014-09-12 19:26 ` [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies Markus Armbruster
2014-09-13 19:32   ` Max Reitz
2014-09-15  6:23   ` Markus Armbruster
2014-09-15 11:38   ` Benoît Canet
2014-09-12 19:26 ` [Qemu-devel] [PATCH 3/4] qemu-nbd: Destroy the BlockDriverState properly Markus Armbruster
2014-09-13 12:49   ` Paolo Bonzini
2014-09-12 19:26 ` [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name Markus Armbruster
2014-09-13 15:47   ` Eric Blake
2014-09-13 18:52   ` Benoît Canet
2014-09-22 16:31 ` [Qemu-devel] [PATCH 0/4] Miscellaneous block fixes Kevin Wolf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).