[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 07/23] block: Allow specifying driver-specific option
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 07/23] block: Allow specifying driver-specific options to reopen |
Date: |
Fri, 11 Sep 2015 21:40:47 +0200 |
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Max Reitz <address@hidden>
---
block.c | 42 +++++++++++++++++++++++++++++++++++++++---
block/commit.c | 4 ++--
include/block/block.h | 4 +++-
3 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/block.c b/block.c
index 3de83e6..6268e37 100644
--- a/block.c
+++ b/block.c
@@ -1636,6 +1636,9 @@ typedef struct BlockReopenQueueEntry {
*
* bs is the BlockDriverState to add to the reopen queue.
*
+ * options contains the changed options for the associated bs
+ * (the BlockReopenQueue takes ownership)
+ *
* flags contains the open flags for the associated bs
*
* returns a pointer to bs_queue, which is either the newly allocated
@@ -1643,18 +1646,28 @@ typedef struct BlockReopenQueueEntry {
*
*/
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
- BlockDriverState *bs, int flags)
+ BlockDriverState *bs,
+ QDict *options, int flags)
{
assert(bs != NULL);
BlockReopenQueueEntry *bs_entry;
BdrvChild *child;
+ QDict *old_options;
if (bs_queue == NULL) {
bs_queue = g_new0(BlockReopenQueue, 1);
QSIMPLEQ_INIT(bs_queue);
}
+ if (!options) {
+ options = qdict_new();
+ }
+
+ old_options = qdict_clone_shallow(bs->options);
+ qdict_join(options, old_options, false);
+ QDECREF(old_options);
+
/* bdrv_open() masks this flag out */
flags &= ~BDRV_O_PROTOCOL;
@@ -1666,13 +1679,15 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue
*bs_queue,
}
child_flags = child->role->inherit_flags(flags);
- bdrv_reopen_queue(bs_queue, child->bs, child_flags);
+ /* TODO Pass down child flags (backing.*, extents.*, ...) */
+ bdrv_reopen_queue(bs_queue, child->bs, NULL, child_flags);
}
bs_entry = g_new0(BlockReopenQueueEntry, 1);
QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
bs_entry->state.bs = bs;
+ bs_entry->state.options = options;
bs_entry->state.flags = flags;
return bs_queue;
@@ -1725,6 +1740,7 @@ cleanup:
if (ret && bs_entry->prepared) {
bdrv_reopen_abort(&bs_entry->state);
}
+ QDECREF(bs_entry->state.options);
g_free(bs_entry);
}
g_free(bs_queue);
@@ -1737,7 +1753,7 @@ int bdrv_reopen(BlockDriverState *bs, int bdrv_flags,
Error **errp)
{
int ret = -1;
Error *local_err = NULL;
- BlockReopenQueue *queue = bdrv_reopen_queue(NULL, bs, bdrv_flags);
+ BlockReopenQueue *queue = bdrv_reopen_queue(NULL, bs, NULL, bdrv_flags);
ret = bdrv_reopen_multiple(queue, &local_err);
if (local_err != NULL) {
@@ -1813,6 +1829,26 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
BlockReopenQueue *queue,
goto error;
}
+ /* Options that are not handled are only okay if they are unchanged
+ * compared to the old state. It is expected that some options are only
+ * used for the initial open, but not reopen (e.g. filename) */
+ if (qdict_size(reopen_state->options)) {
+ const QDictEntry *entry = qdict_first(reopen_state->options);
+
+ do {
+ QString *new_obj = qobject_to_qstring(entry->value);
+ const char *new = qstring_get_str(new_obj);
+ const char *old = qdict_get_try_str(reopen_state->bs->options,
+ entry->key);
+
+ if (!old || strcmp(new, old)) {
+ error_setg(errp, "Cannot change the option '%s'", entry->key);
+ ret = -EINVAL;
+ goto error;
+ }
+ } while ((entry = qdict_next(reopen_state->options, entry)));
+ }
+
ret = 0;
error:
diff --git a/block/commit.c b/block/commit.c
index 7312a5b..d12e26f 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -236,11 +236,11 @@ void commit_start(BlockDriverState *bs, BlockDriverState
*base,
/* convert base & overlay_bs to r/w, if necessary */
if (!(orig_base_flags & BDRV_O_RDWR)) {
- reopen_queue = bdrv_reopen_queue(reopen_queue, base,
+ reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,
orig_base_flags | BDRV_O_RDWR);
}
if (!(orig_overlay_flags & BDRV_O_RDWR)) {
- reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs,
+ reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,
orig_overlay_flags | BDRV_O_RDWR);
}
if (reopen_queue) {
diff --git a/include/block/block.h b/include/block/block.h
index e539194..ef67353 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -147,6 +147,7 @@ typedef QSIMPLEQ_HEAD(BlockReopenQueue,
BlockReopenQueueEntry) BlockReopenQueue;
typedef struct BDRVReopenState {
BlockDriverState *bs;
int flags;
+ QDict *options;
void *opaque;
} BDRVReopenState;
@@ -218,7 +219,8 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int
flags, Error **errp);
int bdrv_open(BlockDriverState **pbs, const char *filename,
const char *reference, QDict *options, int flags, Error **errp);
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
- BlockDriverState *bs, int flags);
+ BlockDriverState *bs,
+ QDict *options, int flags);
int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp);
int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
--
1.8.3.1
- [Qemu-block] [PULL 00/23] Block layer patches, Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 02/23] block: Drop drv parameter from bdrv_open(), Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 05/23] block: Drop bdrv_find_whitelisted_format(), Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 03/23] block: Drop drv parameter from bdrv_open_inherit(), Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 01/23] block: Always pass NULL as drv for bdrv_open(), Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 04/23] block: Drop drv parameter from bdrv_fill_options(), Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 08/23] qemu-io: Remove duplicate 'open' error message, Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 07/23] block: Allow specifying driver-specific options to reopen,
Kevin Wolf <=
- [Qemu-block] [PULL 09/23] qemu-io: Add command 'reopen', Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 10/23] qcow2: Improve error message, Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 06/23] qcow2: Rename BDRVQcowState to BDRVQcow2State, Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 11/23] qcow2: Factor out qcow2_update_options(), Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 12/23] qcow2: Move qcow2_update_options() call up, Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 13/23] qcow2: Move rest of option handling to qcow2_update_options(), Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 15/23] qcow2: Fix memory leak in qcow2_update_options() error path, Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 14/23] qcow2: Leave s unchanged on qcow2_update_options() failure, Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 23/23] qcow2: Make qcow2_alloc_bytes() more explicit, Kevin Wolf, 2015/09/11
- [Qemu-block] [PULL 21/23] iotests: Add test for checking large image files, Kevin Wolf, 2015/09/11