summaryrefslogtreecommitdiffstats
path: root/block.c
diff options
context:
space:
mode:
authorKevin Wolf2015-05-08 17:07:31 +0200
committerKevin Wolf2015-12-18 14:34:42 +0100
commit2851810223a6f2a3f6c00613477feb6e33c10d34 (patch)
tree1718134c233a55aaee4e0e549ce1c7ace3583103 /block.c
parentblock: Allow specifying child options in reopen (diff)
downloadqemu-2851810223a6f2a3f6c00613477feb6e33c10d34.tar.gz
qemu-2851810223a6f2a3f6c00613477feb6e33c10d34.tar.xz
qemu-2851810223a6f2a3f6c00613477feb6e33c10d34.zip
block: reopen: Document option precedence and refactor accordingly
The interesting part of reopening an image is from which sources the effective options should be taken, i.e. which options take precedence over which other options. This patch documents the precedence that will be implemented in the following patches. It also refactors bdrv_reopen_queue(), so that the top-level reopened node is handled the same way as children are. Option/flag inheritance from the parent becomes just one item in the list and is done at the beginning of the function, similar to how the other items are/will be handled. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r--block.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/block.c b/block.c
index 9c42b17498..5fd6c444ac 100644
--- a/block.c
+++ b/block.c
@@ -1693,9 +1693,13 @@ typedef struct BlockReopenQueueEntry {
* bs_queue, or the existing bs_queue being used.
*
*/
-BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
- BlockDriverState *bs,
- QDict *options, int flags)
+static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
+ BlockDriverState *bs,
+ QDict *options,
+ int flags,
+ const BdrvChildRole *role,
+ QDict *parent_options,
+ int parent_flags)
{
assert(bs != NULL);
@@ -1712,6 +1716,22 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
options = qdict_new();
}
+ /*
+ * Precedence of options:
+ * 1. Explicitly passed in options (highest)
+ * 2. TODO Set in flags (only for top level)
+ * 3. TODO Retained from explicitly set options of bs
+ * 4. TODO Inherited from parent node
+ * 5. Retained from effective options of bs
+ */
+
+ /* Inherit from parent node */
+ if (parent_options) {
+ assert(!flags);
+ flags = role->inherit_flags(parent_flags);
+ }
+
+ /* Old values are used for options that aren't set yet */
old_options = qdict_clone_shallow(bs->options);
bdrv_join_options(bs, options, old_options);
QDECREF(old_options);
@@ -1722,7 +1742,6 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
QLIST_FOREACH(child, &bs->children, next) {
QDict *new_child_options;
char *child_key_dot;
- int child_flags;
/* reopen can only change the options of block devices that were
* implicitly created and inherited options. For other (referenced)
@@ -1735,8 +1754,8 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
qdict_extract_subqdict(options, &new_child_options, child_key_dot);
g_free(child_key_dot);
- child_flags = child->role->inherit_flags(flags);
- bdrv_reopen_queue(bs_queue, child->bs, new_child_options, child_flags);
+ bdrv_reopen_queue_child(bs_queue, child->bs, new_child_options, 0,
+ child->role, options, flags);
}
bs_entry = g_new0(BlockReopenQueueEntry, 1);
@@ -1749,6 +1768,14 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
return bs_queue;
}
+BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
+ BlockDriverState *bs,
+ QDict *options, int flags)
+{
+ return bdrv_reopen_queue_child(bs_queue, bs, options, flags,
+ NULL, NULL, 0);
+}
+
/*
* Reopen multiple BlockDriverStates atomically & transactionally.
*