]> xenbits.xensource.com Git - qemu-xen.git/commitdiff
block: Fix reopen with semantically overlapping options
authorKevin Wolf <kwolf@redhat.com>
Mon, 16 Nov 2015 15:43:27 +0000 (16:43 +0100)
committerKevin Wolf <kwolf@redhat.com>
Fri, 18 Dec 2015 13:34:42 +0000 (14:34 +0100)
This fixes bdrv_reopen() calls like the following one:

    qemu-io -c 'open -o overlap-check.template=all /tmp/test.qcow2' \
    -c 'reopen -o overlap-check=none'

The approach taken so far would result in an options QDict that has both
"overlap-check.template=all" and "overlap-check=none", which obviously
conflicts. In this case, the old option should be overridden by the
newly specified option.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
block.c

diff --git a/block.c b/block.c
index 9971976c3828b5876c0a721b1e3b090fc858db9e..57bf8fc23ad25a060001fabfd5e50154335e8510 100644 (file)
--- a/block.c
+++ b/block.c
@@ -623,6 +623,20 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
     return 0;
 }
 
+/**
+ * Combines a QDict of new block driver @options with any missing options taken
+ * from @old_options, so that leaving out an option defaults to its old value.
+ */
+static void bdrv_join_options(BlockDriverState *bs, QDict *options,
+                              QDict *old_options)
+{
+    if (bs->drv && bs->drv->bdrv_join_options) {
+        bs->drv->bdrv_join_options(options, old_options);
+    } else {
+        qdict_join(options, old_options, false);
+    }
+}
+
 /**
  * Set open flags for a given discard mode
  *
@@ -1663,7 +1677,7 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
     }
 
     old_options = qdict_clone_shallow(bs->options);
-    qdict_join(options, old_options, false);
+    bdrv_join_options(bs, options, old_options);
     QDECREF(old_options);
 
     /* bdrv_open() masks this flag out */