qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-block] [RFC PATCH 08/10] block: Add bdrv_reset_options_allowed()


From: Alberto Garcia
Subject: [Qemu-block] [RFC PATCH 08/10] block: Add bdrv_reset_options_allowed()
Date: Thu, 14 Jun 2018 18:49:05 +0300

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 keeping 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, 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 QemuOptsList with the options of a block
driver and checks if there's any that was explicitly set but is not
present in the BDRVReopenState.

If the option is present in both sets we don't need to check that it
keeps the same value. The loop at the end of bdrv_reopen_prepare()
already takes care of that.

Signed-off-by: Alberto Garcia <address@hidden>
---
 block.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/block.c b/block.c
index 91fff6361f..4aa40f7f10 100644
--- a/block.c
+++ b/block.c
@@ -2823,6 +2823,43 @@ BlockDriverState *bdrv_open(const char *filename, const 
char *reference,
 }
 
 /*
+ * For every option in @list, check that if it is present in
+ * @state->bs->explicit_options then it is also present in
+ * @state->options. Options present in @mutable_opts are skipped.
+ *
+ * @mutable_opts is either NULL or a NULL-terminated array of option
+ * names.
+ *
+ * Return 0 on success, -EINVAL otherwise.
+ */
+static int bdrv_reset_options_allowed(BDRVReopenState *state,
+                                      QemuOptsList *list,
+                                      const char *const mutable_opts[],
+                                      Error **errp)
+{
+    QemuOptDesc *desc;
+    for (desc = list->desc; desc && desc->name; desc++) {
+        unsigned i;
+        bool skip_option = false;
+        for (i = 0; mutable_opts && mutable_opts[i] != 0; i++) {
+            if (!strcmp(desc->name, mutable_opts[i])) {
+                skip_option = true;
+                break;
+            }
+        }
+
+        if (!skip_option && !qdict_haskey(state->options, desc->name) &&
+            qdict_haskey(state->bs->explicit_options, desc->name)) {
+            error_setg(errp, "Option '%s' can't be reset to its default value",
+                       desc->name);
+            return -EINVAL;
+        }
+    }
+
+    return 0;
+}
+
+/*
  * Returns true if @child can be reached recursively from @bs
  */
 static bool bdrv_recurse_has_child(BlockDriverState *bs,
@@ -3254,6 +3291,18 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, 
BlockReopenQueue *queue,
     }
 
     if (drv->bdrv_reopen_prepare) {
+        /* If a driver-specified option is missing, it means that we
+         * should reset it to its default value. Not all options can
+         * be modified, so we need to check that first */
+        if (drv->runtime_opts) {
+            ret = bdrv_reset_options_allowed(reopen_state, drv->runtime_opts,
+                                             drv->mutable_opts, &local_err);
+            if (ret) {
+                error_propagate(errp, local_err);
+                goto error;
+            }
+        }
+
         ret = drv->bdrv_reopen_prepare(reopen_state, queue, &local_err);
         if (ret) {
             if (local_err != NULL) {
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]