[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 49/71] block: Generically refresh runtime options
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 49/71] block: Generically refresh runtime options |
Date: |
Mon, 25 Feb 2019 16:20:31 +0100 |
From: Max Reitz <address@hidden>
Instead of having every block driver which implements
bdrv_refresh_filename() copy all of the strong runtime options over to
bs->full_open_options, implement this process generically in
bdrv_refresh_filename().
This patch only adds this new generic implementation, it does not remove
the old functionality. This is done in a follow-up patch.
With this patch, some superfluous information (that should never have
been there) may be removed from some JSON filenames, as can be seen in
the change to iotests 110's and 228's reference outputs.
Signed-off-by: Max Reitz <address@hidden>
Message-id: address@hidden
Signed-off-by: Max Reitz <address@hidden>
---
block.c | 116 ++++++++++++++++++++++++++++++++++++-
tests/qemu-iotests/110.out | 2 +-
tests/qemu-iotests/228 | 7 ++-
tests/qemu-iotests/228.out | 2 +-
4 files changed, 121 insertions(+), 6 deletions(-)
diff --git a/block.c b/block.c
index 185475ab00..a6e523059d 100644
--- a/block.c
+++ b/block.c
@@ -5535,6 +5535,92 @@ out:
return to_replace_bs;
}
+/**
+ * Iterates through the list of runtime option keys that are said to
+ * be "strong" for a BDS. An option is called "strong" if it changes
+ * a BDS's data. For example, the null block driver's "size" and
+ * "read-zeroes" options are strong, but its "latency-ns" option is
+ * not.
+ *
+ * If a key returned by this function ends with a dot, all options
+ * starting with that prefix are strong.
+ */
+static const char *const *strong_options(BlockDriverState *bs,
+ const char *const *curopt)
+{
+ static const char *const global_options[] = {
+ "driver", "filename", NULL
+ };
+
+ if (!curopt) {
+ return &global_options[0];
+ }
+
+ curopt++;
+ if (curopt == &global_options[ARRAY_SIZE(global_options) - 1] && bs->drv) {
+ curopt = bs->drv->strong_runtime_opts;
+ }
+
+ return (curopt && *curopt) ? curopt : NULL;
+}
+
+/**
+ * Copies all strong runtime options from bs->options to the given
+ * QDict. The set of strong option keys is determined by invoking
+ * strong_options().
+ *
+ * Returns true iff any strong option was present in bs->options (and
+ * thus copied to the target QDict) with the exception of "filename"
+ * and "driver". The caller is expected to use this value to decide
+ * whether the existence of strong options prevents the generation of
+ * a plain filename.
+ */
+static bool append_strong_runtime_options(QDict *d, BlockDriverState *bs)
+{
+ bool found_any = false;
+ const char *const *option_name = NULL;
+
+ if (!bs->drv) {
+ return false;
+ }
+
+ while ((option_name = strong_options(bs, option_name))) {
+ bool option_given = false;
+
+ assert(strlen(*option_name) > 0);
+ if ((*option_name)[strlen(*option_name) - 1] != '.') {
+ QObject *entry = qdict_get(bs->options, *option_name);
+ if (!entry) {
+ continue;
+ }
+
+ qdict_put_obj(d, *option_name, qobject_ref(entry));
+ option_given = true;
+ } else {
+ const QDictEntry *entry;
+ for (entry = qdict_first(bs->options); entry;
+ entry = qdict_next(bs->options, entry))
+ {
+ if (strstart(qdict_entry_key(entry), *option_name, NULL)) {
+ qdict_put_obj(d, qdict_entry_key(entry),
+ qobject_ref(qdict_entry_value(entry)));
+ option_given = true;
+ }
+ }
+ }
+
+ /* While "driver" and "filename" need to be included in a JSON
filename,
+ * their existence does not prohibit generation of a plain filename. */
+ if (!found_any && option_given &&
+ strcmp(*option_name, "driver") && strcmp(*option_name, "filename"))
+ {
+ found_any = true;
+ }
+ }
+
+ return found_any;
+}
+
static bool append_open_options(QDict *d, BlockDriverState *bs)
{
const QDictEntry *entry;
@@ -5711,9 +5797,37 @@ void bdrv_refresh_filename(BlockDriverState *bs)
bs->full_open_options = opts;
}
+ /* Gather the options QDict */
+ opts = qdict_new();
+ append_strong_runtime_options(opts, bs);
+
+ if (drv->bdrv_gather_child_options) {
+ /* Some block drivers may not want to present all of their children's
+ * options, or name them differently from BdrvChild.name */
+ drv->bdrv_gather_child_options(bs, opts, backing_overridden);
+ } else {
+ QLIST_FOREACH(child, &bs->children, next) {
+ if (child->role == &child_backing && !backing_overridden) {
+ /* We can skip the backing BDS if it has not been overridden */
+ continue;
+ }
+
+ qdict_put(opts, child->name,
+ qobject_ref(child->bs->full_open_options));
+ }
+
+ if (backing_overridden && !bs->backing) {
+ /* Force no backing file */
+ qdict_put_null(opts, "backing");
+ }
+ }
+
+ qobject_unref(bs->full_open_options);
+ bs->full_open_options = opts;
+
if (bs->exact_filename[0]) {
pstrcpy(bs->filename, sizeof(bs->filename), bs->exact_filename);
- } else if (bs->full_open_options) {
+ } else {
QString *json = qobject_to_json(QOBJECT(bs->full_open_options));
snprintf(bs->filename, sizeof(bs->filename), "json:%s",
qstring_get_str(json));
diff --git a/tests/qemu-iotests/110.out b/tests/qemu-iotests/110.out
index 1d0b2475cc..46e6a60510 100644
--- a/tests/qemu-iotests/110.out
+++ b/tests/qemu-iotests/110.out
@@ -22,7 +22,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
backing_file=t.IMGFMT.b
=== Nodes without a common directory ===
-image: json:{"driver": "IMGFMT", "file": {"children": [{"driver": "file",
"filename": "TEST_DIR/t.IMGFMT"}, {"driver": "file", "filename":
"TEST_DIR/t.IMGFMT.copy"}], "driver": "quorum", "blkverify": false,
"rewrite-corrupted": false, "vote-threshold": 1}}
+image: json:{"driver": "IMGFMT", "file": {"children": [{"driver": "file",
"filename": "TEST_DIR/t.IMGFMT"}, {"driver": "file", "filename":
"TEST_DIR/t.IMGFMT.copy"}], "driver": "quorum", "vote-threshold": 1}}
file format: IMGFMT
virtual size: 64M (67108864 bytes)
backing file: t.IMGFMT.base (cannot determine actual path)
diff --git a/tests/qemu-iotests/228 b/tests/qemu-iotests/228
index 2930f8442c..7a57c41e29 100755
--- a/tests/qemu-iotests/228
+++ b/tests/qemu-iotests/228
@@ -230,9 +230,10 @@ with iotests.FilePath('base.img') as base_img_path, \
overlay='node0')
# This should give us the original plain result
- # FIXME: Currently, the block layer considers the runtime backing
- # file to be different from the image header, which is
- # wrong. This is fixed by a future patch.
+ # FIXME: Currently, it yields a json:{} filename even though it
+ # only contains a @driver and a @file entry, so a plain
+ # filename would obviously suffice. This is fixed by a
+ # future patch.
log_node_info(vm.node_info('node0'))
diff --git a/tests/qemu-iotests/228.out b/tests/qemu-iotests/228.out
index 57fe97d4bc..393ab09164 100644
--- a/tests/qemu-iotests/228.out
+++ b/tests/qemu-iotests/228.out
@@ -74,7 +74,7 @@ bs->backing: (none)
{"execute": "blockdev-snapshot", "arguments": {"node": "original-backing",
"overlay": "node0"}}
{"return": {}}
-bs->filename: json:{"backing": {"driver": "IMGFMT", "file": {"driver": "file",
"filename": "TEST_DIR/PID-base.img"}}, "driver": "IMGFMT", "file": {"driver":
"file", "filename": "TEST_DIR/PID-top.img"}}
+bs->filename: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename":
"TEST_DIR/PID-top.img"}}
bs->backing_file: TEST_DIR/PID-base.img
bs->backing->bs->filename: TEST_DIR/PID-base.img
--
2.20.1
- [Qemu-block] [PULL 43/71] block/nbd: Make bdrv_dirname() return NULL, (continued)
- [Qemu-block] [PULL 43/71] block/nbd: Make bdrv_dirname() return NULL, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 31/71] block: Respect backing bs in bdrv_refresh_filename, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 27/71] block: Use bdrv_refresh_filename() to pull, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 39/71] block: Fix bdrv_find_backing_image(), Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 44/71] block/nfs: Implement bdrv_dirname(), Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 45/71] block: Use bdrv_dirname() for relative filenames, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 47/71] block: Add strong_runtime_opts to BlockDriver, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 46/71] iotests: Add quorum case to test 110, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 51/71] block: Do not copy exact_filename from format file, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 48/71] block: Add BlockDriver.bdrv_gather_child_options, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 49/71] block: Generically refresh runtime options,
Kevin Wolf <=
- [Qemu-block] [PULL 52/71] block/nvme: Fix bdrv_refresh_filename(), Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 54/71] block/curl: Implement bdrv_refresh_filename(), Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 50/71] block: Purify .bdrv_refresh_filename(), Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 55/71] block/null: Generate filename even with latency-ns, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 53/71] block/curl: Harmonize option defaults, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 56/71] block: BDS options may lack the "driver" option, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 57/71] iotests: Test json:{} filenames of internal BDSs, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 58/71] iotests: Re-add filename filters, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 59/71] iotests: Fix 237 for Python 2.x, Kevin Wolf, 2019/02/25
- [Qemu-block] [PULL 60/71] iotests: Remove superfluous rm from 232, Kevin Wolf, 2019/02/25