summaryrefslogtreecommitdiffstats
path: root/block.c
diff options
context:
space:
mode:
authorAlberto Garcia2018-06-29 13:37:02 +0200
committerKevin Wolf2018-08-15 12:50:39 +0200
commit4c8350fe1729b072473417dc22fa6410a4383127 (patch)
treefa0ea6ac45fbbc089354475206444b7f2e89b18d /block.c
parentblock: Simplify bdrv_reopen_abort() (diff)
downloadqemu-4c8350fe1729b072473417dc22fa6410a4383127.tar.gz
qemu-4c8350fe1729b072473417dc22fa6410a4383127.tar.xz
qemu-4c8350fe1729b072473417dc22fa6410a4383127.zip
block: Update bs->options if bdrv_reopen() succeeds
If bdrv_reopen() succeeds then bs->explicit_options is updated with the new values, but bs->options never changes. Here's an example: { "execute": "blockdev-add", "arguments": { "driver": "qcow2", "node-name": "hd0", "overlap-check": "all", "file": { "driver": "file", "filename": "hd0.qcow2" } } } After this, both bs->options and bs->explicit_options contain "overlap-check": "all". Now let's change that using qemu-io's reopen command: (qemu) qemu-io hd0 "reopen -o overlap-check=none" After this, bs->explicit_options contains the new value but bs->options still keeps the old one. This patch updates bs->options after a BDS has been successfully reopened. Signed-off-by: Alberto Garcia <berto@igalia.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r--block.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/block.c b/block.c
index e82cfa6fe2..8c95f9893a 100644
--- a/block.c
+++ b/block.c
@@ -3055,8 +3055,8 @@ cleanup:
bdrv_reopen_abort(&bs_entry->state);
}
qobject_unref(bs_entry->state.explicit_options);
+ qobject_unref(bs_entry->state.options);
}
- qobject_unref(bs_entry->state.options);
g_free(bs_entry);
}
g_free(bs_queue);
@@ -3156,6 +3156,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
Error *local_err = NULL;
BlockDriver *drv;
QemuOpts *opts;
+ QDict *orig_reopen_opts;
const char *value;
bool read_only;
@@ -3163,6 +3164,11 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
assert(reopen_state->bs->drv != NULL);
drv = reopen_state->bs->drv;
+ /* This function and each driver's bdrv_reopen_prepare() remove
+ * entries from reopen_state->options as they are processed, so
+ * we need to make a copy of the original QDict. */
+ orig_reopen_opts = qdict_clone_shallow(reopen_state->options);
+
/* Process generic block layer options */
opts = qemu_opts_create(&bdrv_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, reopen_state->options, &local_err);
@@ -3269,8 +3275,13 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
ret = 0;
+ /* Restore the original reopen_state->options QDict */
+ qobject_unref(reopen_state->options);
+ reopen_state->options = qobject_ref(orig_reopen_opts);
+
error:
qemu_opts_del(opts);
+ qobject_unref(orig_reopen_opts);
return ret;
}
@@ -3300,8 +3311,10 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
/* set BDS specific flags now */
qobject_unref(bs->explicit_options);
+ qobject_unref(bs->options);
bs->explicit_options = reopen_state->explicit_options;
+ bs->options = reopen_state->options;
bs->open_flags = reopen_state->flags;
bs->read_only = !(reopen_state->flags & BDRV_O_RDWR);