[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 25/28] block: Add bdrv_reset_options_allowed()
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 25/28] block: Add bdrv_reset_options_allowed() |
Date: |
Tue, 12 Mar 2019 18:30:22 +0100 |
From: Alberto Garcia <address@hidden>
bdrv_reopen_prepare() receives a BDRVReopenState with (among other
things) a new set of options to be applied to that BlockDriverState.
If an option is missing then it means that we want to reset it to its
default value rather than keep the previous one. This way the state
of the block device after being reopened is comparable to that of a
device added with "blockdev-add" using the same set of options.
Not all options from all drivers can be changed this way, however.
If the user attempts to reset an immutable option to its default value
using this method then we must forbid it.
This new function takes a BlockDriverState and a new set of options
and checks if there's any option that was previously set but is
missing from the new set of options.
If the option is present in both sets we don't need to check that they
have the same value. The loop at the end of bdrv_reopen_prepare()
already takes care of that.
Signed-off-by: Alberto Garcia <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/block.c b/block.c
index c6786cd35b..a5e69ad81e 100644
--- a/block.c
+++ b/block.c
@@ -2983,6 +2983,53 @@ BlockDriverState *bdrv_open(const char *filename, const
char *reference,
NULL, errp);
}
+/* Return true if the NULL-terminated @list contains @str */
+static bool is_str_in_list(const char *str, const char *const *list)
+{
+ if (str && list) {
+ int i;
+ for (i = 0; list[i] != NULL; i++) {
+ if (!strcmp(str, list[i])) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/*
+ * Check that every option set in @bs->options is also set in
+ * @new_opts.
+ *
+ * Options listed in the common_options list and in
+ * @bs->drv->mutable_opts are skipped.
+ *
+ * Return 0 on success, otherwise return -EINVAL and set @errp.
+ */
+static int bdrv_reset_options_allowed(BlockDriverState *bs,
+ const QDict *new_opts, Error **errp)
+{
+ const QDictEntry *e;
+ /* These options are common to all block drivers and are handled
+ * in bdrv_reopen_prepare() so they can be left out of @new_opts */
+ const char *const common_options[] = {
+ "node-name", "discard", "cache.direct", "cache.no-flush",
+ "read-only", "auto-read-only", "detect-zeroes", NULL
+ };
+
+ for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
+ if (!qdict_haskey(new_opts, e->key) &&
+ !is_str_in_list(e->key, common_options) &&
+ !is_str_in_list(e->key, bs->drv->mutable_opts)) {
+ error_setg(errp, "Option '%s' cannot be reset "
+ "to its default value", e->key);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
/*
* Returns true if @child can be reached recursively from @bs
*/
@@ -3546,6 +3593,17 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
BlockReopenQueue *queue,
}
if (drv->bdrv_reopen_prepare) {
+ /*
+ * If a driver-specific option is missing, it means that we
+ * should reset it to its default value.
+ * But not all options allow that, so we need to check it first.
+ */
+ ret = bdrv_reset_options_allowed(reopen_state->bs,
+ reopen_state->options, errp);
+ if (ret) {
+ goto error;
+ }
+
ret = drv->bdrv_reopen_prepare(reopen_state, queue, &local_err);
if (ret) {
if (local_err != NULL) {
--
2.20.1
- [Qemu-block] [PULL 17/28] block: Freeze the backing chain for the duration of the commit job, (continued)
- [Qemu-block] [PULL 17/28] block: Freeze the backing chain for the duration of the commit job, Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 18/28] block: Freeze the backing chain for the duration of the mirror job, Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 19/28] block: Freeze the backing chain for the duration of the stream job, Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 20/28] block: Add 'keep_old_opts' parameter to bdrv_reopen_queue(), Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 22/28] block: Allow omitting the 'backing' option in certain cases, Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 21/28] block: Handle child references in bdrv_reopen_queue(), Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 24/28] block: Add a 'mutable_opts' field to BlockDriver, Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 23/28] block: Allow changing the backing file on reopen, Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 26/28] block: Remove the AioContext parameter from bdrv_reopen_multiple(), Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 27/28] block: Add an 'x-blockdev-reopen' QMP command, Kevin Wolf, 2019/03/12
- [Qemu-block] [PULL 25/28] block: Add bdrv_reset_options_allowed(),
Kevin Wolf <=
- [Qemu-block] [PULL 28/28] qemu-iotests: Test the x-blockdev-reopen QMP command, Kevin Wolf, 2019/03/12
- Re: [Qemu-block] [PULL 00/28] Block layer patches, Peter Maydell, 2019/03/13