aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c131
-rw-r--r--block/blkdebug.c54
-rw-r--r--block/blklogwrites.c22
-rw-r--r--block/blkverify.c16
-rw-r--r--block/commit.c2
-rw-r--r--block/mirror.c2
-rw-r--r--block/nbd.c23
-rw-r--r--block/nfs.c36
-rw-r--r--block/null.c22
-rw-r--r--block/nvme.c22
-rw-r--r--block/quorum.c30
-rw-r--r--include/block/block_int.h6
-rwxr-xr-xtests/qemu-iotests/2284
-rw-r--r--tests/qemu-iotests/228.out2
14 files changed, 81 insertions, 291 deletions
diff --git a/block.c b/block.c
index a6e523059d..23869623ea 100644
--- a/block.c
+++ b/block.c
@@ -5621,33 +5621,6 @@ static bool append_strong_runtime_options(QDict *d, BlockDriverState *bs)
return found_any;
}
-static bool append_open_options(QDict *d, BlockDriverState *bs)
-{
- const QDictEntry *entry;
- QemuOptDesc *desc;
- bool found_any = false;
-
- for (entry = qdict_first(bs->options); entry;
- entry = qdict_next(bs->options, entry))
- {
- /* Exclude all non-driver-specific options */
- for (desc = bdrv_runtime_opts.desc; desc->name; desc++) {
- if (!strcmp(qdict_entry_key(entry), desc->name)) {
- break;
- }
- }
- if (desc->name) {
- continue;
- }
-
- qdict_put_obj(d, qdict_entry_key(entry),
- qobject_ref(qdict_entry_value(entry)));
- found_any = true;
- }
-
- return found_any;
-}
-
/* Note: This function may return false positives; it may return true
* even if opening the backing file specified by bs's image header
* would result in exactly bs->backing. */
@@ -5681,6 +5654,8 @@ void bdrv_refresh_filename(BlockDriverState *bs)
BdrvChild *child;
QDict *opts;
bool backing_overridden;
+ bool generate_json_filename; /* Whether our default implementation should
+ fill exact_filename (false) or not (true) */
if (!drv) {
return;
@@ -5716,90 +5691,10 @@ void bdrv_refresh_filename(BlockDriverState *bs)
backing_overridden = false;
}
- if (drv->bdrv_refresh_filename) {
- /* Obsolete information is of no use here, so drop the old file name
- * information before refreshing it */
- bs->exact_filename[0] = '\0';
- if (bs->full_open_options) {
- qobject_unref(bs->full_open_options);
- bs->full_open_options = NULL;
- }
-
- opts = qdict_new();
- append_open_options(opts, bs);
- drv->bdrv_refresh_filename(bs, opts);
- qobject_unref(opts);
- } else if (bs->file) {
- /* Try to reconstruct valid information from the underlying file */
- bool has_open_options;
-
- bs->exact_filename[0] = '\0';
- if (bs->full_open_options) {
- qobject_unref(bs->full_open_options);
- bs->full_open_options = NULL;
- }
-
- opts = qdict_new();
- has_open_options = append_open_options(opts, bs);
- has_open_options |= backing_overridden;
-
- /* If no specific options have been given for this BDS, the filename of
- * the underlying file should suffice for this one as well */
- if (bs->file->bs->exact_filename[0] && !has_open_options) {
- strcpy(bs->exact_filename, bs->file->bs->exact_filename);
- }
- /* Reconstructing the full options QDict is simple for most format block
- * drivers, as long as the full options are known for the underlying
- * file BDS. The full options QDict of that file BDS should somehow
- * contain a representation of the filename, therefore the following
- * suffices without querying the (exact_)filename of this BDS. */
- if (bs->file->bs->full_open_options &&
- (!bs->backing || bs->backing->bs->full_open_options))
- {
- qdict_put_str(opts, "driver", drv->format_name);
- qdict_put(opts, "file",
- qobject_ref(bs->file->bs->full_open_options));
-
- if (bs->backing) {
- qdict_put(opts, "backing",
- qobject_ref(bs->backing->bs->full_open_options));
- } else if (backing_overridden) {
- qdict_put_null(opts, "backing");
- }
-
- bs->full_open_options = opts;
- } else {
- qobject_unref(opts);
- }
- } else if (!bs->full_open_options && qdict_size(bs->options)) {
- /* There is no underlying file BDS (at least referenced by BDS.file),
- * so the full options QDict should be equal to the options given
- * specifically for this block device when it was opened (plus the
- * driver specification).
- * Because those options don't change, there is no need to update
- * full_open_options when it's already set. */
-
- opts = qdict_new();
- append_open_options(opts, bs);
- qdict_put_str(opts, "driver", drv->format_name);
-
- if (bs->exact_filename[0]) {
- /* This may not work for all block protocol drivers (some may
- * require this filename to be parsed), but we have to find some
- * default solution here, so just include it. If some block driver
- * does not support pure options without any filename at all or
- * needs some special format of the options QDict, it needs to
- * implement the driver-specific bdrv_refresh_filename() function.
- */
- qdict_put_str(opts, "filename", bs->exact_filename);
- }
-
- bs->full_open_options = opts;
- }
-
/* Gather the options QDict */
opts = qdict_new();
- append_strong_runtime_options(opts, bs);
+ generate_json_filename = append_strong_runtime_options(opts, bs);
+ generate_json_filename |= backing_overridden;
if (drv->bdrv_gather_child_options) {
/* Some block drivers may not want to present all of their children's
@@ -5825,6 +5720,24 @@ void bdrv_refresh_filename(BlockDriverState *bs)
qobject_unref(bs->full_open_options);
bs->full_open_options = opts;
+ if (drv->bdrv_refresh_filename) {
+ /* Obsolete information is of no use here, so drop the old file name
+ * information before refreshing it */
+ bs->exact_filename[0] = '\0';
+
+ drv->bdrv_refresh_filename(bs);
+ } else if (bs->file) {
+ /* Try to reconstruct valid information from the underlying file */
+
+ bs->exact_filename[0] = '\0';
+
+ /* If no specific options have been given for this BDS, the filename of
+ * the underlying file should suffice for this one as well */
+ if (bs->file->bs->exact_filename[0] && !generate_json_filename) {
+ strcpy(bs->exact_filename, bs->file->bs->exact_filename);
+ }
+ }
+
if (bs->exact_filename[0]) {
pstrcpy(bs->filename, sizeof(bs->filename), bs->exact_filename);
} else {
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 71b4275b98..1ea835c2b9 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -811,51 +811,37 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
return bdrv_getlength(bs->file->bs);
}
-static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
+static void blkdebug_refresh_filename(BlockDriverState *bs)
{
BDRVBlkdebugState *s = bs->opaque;
- QDict *opts;
const QDictEntry *e;
- bool force_json = false;
-
- for (e = qdict_first(options); e; e = qdict_next(options, e)) {
- if (strcmp(qdict_entry_key(e), "config") &&
- strcmp(qdict_entry_key(e), "x-image"))
- {
- force_json = true;
- break;
- }
- }
+ int ret;
- if (force_json && !bs->file->bs->full_open_options) {
- /* The config file cannot be recreated, so creating a plain filename
- * is impossible */
+ if (!bs->file->bs->exact_filename[0]) {
return;
}
- if (!force_json && bs->file->bs->exact_filename[0]) {
- int ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "blkdebug:%s:%s", s->config_file ?: "",
- bs->file->bs->exact_filename);
- if (ret >= sizeof(bs->exact_filename)) {
- /* An overflow makes the filename unusable, so do not report any */
- bs->exact_filename[0] = 0;
+ for (e = qdict_first(bs->full_open_options); e;
+ e = qdict_next(bs->full_open_options, e))
+ {
+ /* Real child options are under "image", but "x-image" may
+ * contain a filename */
+ if (strcmp(qdict_entry_key(e), "config") &&
+ strcmp(qdict_entry_key(e), "image") &&
+ strcmp(qdict_entry_key(e), "x-image") &&
+ strcmp(qdict_entry_key(e), "driver"))
+ {
+ return;
}
}
- opts = qdict_new();
- qdict_put_str(opts, "driver", "blkdebug");
-
- qdict_put(opts, "image", qobject_ref(bs->file->bs->full_open_options));
-
- for (e = qdict_first(options); e; e = qdict_next(options, e)) {
- if (strcmp(qdict_entry_key(e), "x-image")) {
- qdict_put_obj(opts, qdict_entry_key(e),
- qobject_ref(qdict_entry_value(e)));
- }
+ ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+ "blkdebug:%s:%s",
+ s->config_file ?: "", bs->file->bs->exact_filename);
+ if (ret >= sizeof(bs->exact_filename)) {
+ /* An overflow makes the filename unusable, so do not report any */
+ bs->exact_filename[0] = 0;
}
-
- bs->full_open_options = opts;
}
static void blkdebug_refresh_limits(BlockDriverState *bs, Error **errp)
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
index 5da5df112d..eb2b4901a5 100644
--- a/block/blklogwrites.c
+++ b/block/blklogwrites.c
@@ -280,27 +280,6 @@ static int64_t blk_log_writes_getlength(BlockDriverState *bs)
return bdrv_getlength(bs->file->bs);
}
-static void blk_log_writes_refresh_filename(BlockDriverState *bs,
- QDict *options)
-{
- BDRVBlkLogWritesState *s = bs->opaque;
-
- if (bs->file->bs->full_open_options
- && s->log_file->bs->full_open_options)
- {
- QDict *opts = qdict_new();
- qdict_put_str(opts, "driver", "blklogwrites");
-
- qobject_ref(bs->file->bs->full_open_options);
- qdict_put(opts, "file", bs->file->bs->full_open_options);
- qobject_ref(s->log_file->bs->full_open_options);
- qdict_put(opts, "log", s->log_file->bs->full_open_options);
- qdict_put_int(opts, "log-sector-size", s->sectorsize);
-
- bs->full_open_options = opts;
- }
-}
-
static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *ro_q,
@@ -531,7 +510,6 @@ static BlockDriver bdrv_blk_log_writes = {
.bdrv_open = blk_log_writes_open,
.bdrv_close = blk_log_writes_close,
.bdrv_getlength = blk_log_writes_getlength,
- .bdrv_refresh_filename = blk_log_writes_refresh_filename,
.bdrv_child_perm = blk_log_writes_child_perm,
.bdrv_refresh_limits = blk_log_writes_refresh_limits,
diff --git a/block/blkverify.c b/block/blkverify.c
index 3c7d4c8729..3ff77ff49a 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -281,24 +281,10 @@ static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
return bdrv_recurse_is_first_non_filter(s->test_file->bs, candidate);
}
-static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
+static void blkverify_refresh_filename(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;
- if (bs->file->bs->full_open_options
- && s->test_file->bs->full_open_options)
- {
- QDict *opts = qdict_new();
- qdict_put_str(opts, "driver", "blkverify");
-
- qdict_put(opts, "raw",
- qobject_ref(bs->file->bs->full_open_options));
- qdict_put(opts, "test",
- qobject_ref(s->test_file->bs->full_open_options));
-
- bs->full_open_options = opts;
- }
-
if (bs->file->bs->exact_filename[0]
&& s->test_file->bs->exact_filename[0])
{
diff --git a/block/commit.c b/block/commit.c
index 614a8ca374..385fb98527 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -230,7 +230,7 @@ static int coroutine_fn bdrv_commit_top_preadv(BlockDriverState *bs,
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
}
-static void bdrv_commit_top_refresh_filename(BlockDriverState *bs, QDict *opts)
+static void bdrv_commit_top_refresh_filename(BlockDriverState *bs)
{
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
bs->backing->bs->filename);
diff --git a/block/mirror.c b/block/mirror.c
index 031c1aeaeb..726d3c27fb 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1431,7 +1431,7 @@ static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs,
NULL, 0);
}
-static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs, QDict *opts)
+static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs)
{
if (bs->backing == NULL) {
/* we can be here after failed bdrv_attach_child in
diff --git a/block/nbd.c b/block/nbd.c
index 318a58776c..2e72df528a 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -477,12 +477,9 @@ static void nbd_attach_aio_context(BlockDriverState *bs,
nbd_client_attach_aio_context(bs, new_context);
}
-static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
+static void nbd_refresh_filename(BlockDriverState *bs)
{
BDRVNBDState *s = bs->opaque;
- QDict *opts = qdict_new();
- QObject *saddr_qdict;
- Visitor *ov;
const char *host = NULL, *port = NULL, *path = NULL;
if (s->saddr->type == SOCKET_ADDRESS_TYPE_INET) {
@@ -495,8 +492,6 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
path = s->saddr->u.q_unix.path;
} /* else can't represent as pseudo-filename */
- qdict_put_str(opts, "driver", "nbd");
-
if (path && s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nbd+unix:///%s?socket=%s", s->export, path);
@@ -510,22 +505,6 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nbd://%s:%s", host, port);
}
-
- ov = qobject_output_visitor_new(&saddr_qdict);
- visit_type_SocketAddress(ov, NULL, &s->saddr, &error_abort);
- visit_complete(ov, &saddr_qdict);
- visit_free(ov);
- qdict_put_obj(opts, "server", saddr_qdict);
-
- if (s->export) {
- qdict_put_str(opts, "export", s->export);
- }
- if (s->tlscredsid) {
- qdict_put_str(opts, "tls-creds", s->tlscredsid);
- }
-
- qdict_flatten(opts);
- bs->full_open_options = opts;
}
static char *nbd_dirname(BlockDriverState *bs, Error **errp)
diff --git a/block/nfs.c b/block/nfs.c
index 6985a44b89..531903610b 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -799,14 +799,9 @@ static int nfs_reopen_prepare(BDRVReopenState *state,
return 0;
}
-static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
+static void nfs_refresh_filename(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
- QDict *opts = qdict_new();
- QObject *server_qdict;
- Visitor *ov;
-
- qdict_put_str(opts, "driver", "nfs");
if (client->uid && !client->gid) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
@@ -824,35 +819,6 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nfs://%s%s", client->server->host, client->path);
}
-
- ov = qobject_output_visitor_new(&server_qdict);
- visit_type_NFSServer(ov, NULL, &client->server, &error_abort);
- visit_complete(ov, &server_qdict);
- qdict_put_obj(opts, "server", server_qdict);
- qdict_put_str(opts, "path", client->path);
-
- if (client->uid) {
- qdict_put_int(opts, "user", client->uid);
- }
- if (client->gid) {
- qdict_put_int(opts, "group", client->gid);
- }
- if (client->tcp_syncnt) {
- qdict_put_int(opts, "tcp-syn-cnt", client->tcp_syncnt);
- }
- if (client->readahead) {
- qdict_put_int(opts, "readahead-size", client->readahead);
- }
- if (client->pagecache) {
- qdict_put_int(opts, "page-cache-size", client->pagecache);
- }
- if (client->debug) {
- qdict_put_int(opts, "debug", client->debug);
- }
-
- visit_free(ov);
- qdict_flatten(opts);
- bs->full_open_options = opts;
}
static char *nfs_dirname(BlockDriverState *bs, Error **errp)
diff --git a/block/null.c b/block/null.c
index 858892f0c4..1c56a0ef01 100644
--- a/block/null.c
+++ b/block/null.c
@@ -239,17 +239,23 @@ static int coroutine_fn null_co_block_status(BlockDriverState *bs,
return ret;
}
-static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
+static void null_refresh_filename(BlockDriverState *bs)
{
- qdict_del(opts, "filename");
-
- if (!qdict_size(opts)) {
- snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
- bs->drv->format_name);
+ const QDictEntry *e;
+
+ for (e = qdict_first(bs->full_open_options); e;
+ e = qdict_next(bs->full_open_options, e))
+ {
+ /* These options can be ignored */
+ if (strcmp(qdict_entry_key(e), "filename") &&
+ strcmp(qdict_entry_key(e), "driver"))
+ {
+ return;
+ }
}
- qdict_put_str(opts, "driver", bs->drv->format_name);
- bs->full_open_options = qobject_ref(opts);
+ snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
+ bs->drv->format_name);
}
static const char *const null_strong_runtime_opts[] = {
diff --git a/block/nvme.c b/block/nvme.c
index bf656b2bba..6b5845644b 100644
--- a/block/nvme.c
+++ b/block/nvme.c
@@ -1053,17 +1053,23 @@ static int nvme_reopen_prepare(BDRVReopenState *reopen_state,
return 0;
}
-static void nvme_refresh_filename(BlockDriverState *bs, QDict *opts)
+static void nvme_refresh_filename(BlockDriverState *bs)
{
- qdict_del(opts, "filename");
-
- if (!qdict_size(opts)) {
- snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
- bs->drv->format_name);
+ const QDictEntry *e;
+
+ for (e = qdict_first(bs->full_open_options); e;
+ e = qdict_next(bs->full_open_options, e))
+ {
+ /* These options can be ignored */
+ if (strcmp(qdict_entry_key(e), "filename") &&
+ strcmp(qdict_entry_key(e), "driver"))
+ {
+ return;
+ }
}
- qdict_put_str(opts, "driver", bs->drv->format_name);
- bs->full_open_options = qobject_ref(opts);
+ snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
+ bs->drv->format_name);
}
static void nvme_refresh_limits(BlockDriverState *bs, Error **errp)
diff --git a/block/quorum.c b/block/quorum.c
index 3984f0aa4f..352f729136 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1065,35 +1065,6 @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
bdrv_drained_end(bs);
}
-static void quorum_refresh_filename(BlockDriverState *bs, QDict *options)
-{
- BDRVQuorumState *s = bs->opaque;
- QDict *opts;
- QList *children;
- int i;
-
- for (i = 0; i < s->num_children; i++) {
- if (!s->children[i]->bs->full_open_options) {
- return;
- }
- }
-
- children = qlist_new();
- for (i = 0; i < s->num_children; i++) {
- qlist_append(children,
- qobject_ref(s->children[i]->bs->full_open_options));
- }
-
- opts = qdict_new();
- qdict_put_str(opts, "driver", "quorum");
- qdict_put_int(opts, QUORUM_OPT_VOTE_THRESHOLD, s->threshold);
- qdict_put_bool(opts, QUORUM_OPT_BLKVERIFY, s->is_blkverify);
- qdict_put_bool(opts, QUORUM_OPT_REWRITE, s->rewrite_corrupted);
- qdict_put(opts, "children", children);
-
- bs->full_open_options = opts;
-}
-
static void quorum_gather_child_options(BlockDriverState *bs, QDict *target,
bool backing_overridden)
{
@@ -1159,7 +1130,6 @@ static BlockDriver bdrv_quorum = {
.bdrv_open = quorum_open,
.bdrv_close = quorum_close,
- .bdrv_refresh_filename = quorum_refresh_filename,
.bdrv_gather_child_options = quorum_gather_child_options,
.bdrv_dirname = quorum_dirname,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index ab4cf2df07..836d67c1ae 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -139,7 +139,11 @@ struct BlockDriver {
Error **errp);
int (*bdrv_make_empty)(BlockDriverState *bs);
- void (*bdrv_refresh_filename)(BlockDriverState *bs, QDict *options);
+ /*
+ * Refreshes the bs->exact_filename field. If that is impossible,
+ * bs->exact_filename has to be left empty.
+ */
+ void (*bdrv_refresh_filename)(BlockDriverState *bs);
/*
* Gathers the open options for all children into @target.
diff --git a/tests/qemu-iotests/228 b/tests/qemu-iotests/228
index 7a57c41e29..9a50afd205 100755
--- a/tests/qemu-iotests/228
+++ b/tests/qemu-iotests/228
@@ -230,10 +230,6 @@ with iotests.FilePath('base.img') as base_img_path, \
overlay='node0')
# This should give us the original plain result
- # 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 393ab09164..4217df24fe 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:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}}
+bs->filename: TEST_DIR/PID-top.img
bs->backing_file: TEST_DIR/PID-base.img
bs->backing->bs->filename: TEST_DIR/PID-base.img