aboutsummaryrefslogtreecommitdiff
path: root/block.c
diff options
context:
space:
mode:
authorMax Reitz <mreitz@redhat.com>2017-11-14 19:01:26 +0100
committerMax Reitz <mreitz@redhat.com>2017-11-17 18:21:30 +0100
commit54fd1b0d260cf9615d3385c93702277e81f0b639 (patch)
treee4d88946aee3a5b5dcda3674c980b944c9fde383 /block.c
parentb38dd678a21582e03ecd2dec76ccf8290455628a (diff)
block: qobject_is_equal() in bdrv_reopen_prepare()
Currently, bdrv_reopen_prepare() assumes that all BDS options are strings. However, this is not the case if the BDS has been created through the json: pseudo-protocol or blockdev-add. Note that the user-invokable reopen command is an HMP command, so you can only specify strings there. Therefore, specifying a non-string option with the "same" value as it was when originally created will now return an error because the values are supposedly similar (and there is no way for the user to circumvent this but to just not specify the option again -- however, this is still strictly better than just crashing). Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-id: 20171114180128.17076-5-mreitz@redhat.com Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r--block.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/block.c b/block.c
index 752fe6192b..70c6d7cf94 100644
--- a/block.c
+++ b/block.c
@@ -3074,19 +3074,26 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
const QDictEntry *entry = qdict_first(reopen_state->options);
do {
- QString *new_obj = qobject_to_qstring(entry->value);
- const char *new = qstring_get_str(new_obj);
+ QObject *new = entry->value;
+ QObject *old = qdict_get(reopen_state->bs->options, entry->key);
+
/*
- * Caution: while qdict_get_try_str() is fine, getting
- * non-string types would require more care. When
- * bs->options come from -blockdev or blockdev_add, its
- * members are typed according to the QAPI schema, but
- * when they come from -drive, they're all QString.
+ * TODO: When using -drive to specify blockdev options, all values
+ * will be strings; however, when using -blockdev, blockdev-add or
+ * filenames using the json:{} pseudo-protocol, they will be
+ * correctly typed.
+ * In contrast, reopening options are (currently) always strings
+ * (because you can only specify them through qemu-io; all other
+ * callers do not specify any options).
+ * Therefore, when using anything other than -drive to create a BDS,
+ * this cannot detect non-string options as unchanged, because
+ * qobject_is_equal() always returns false for objects of different
+ * type. In the future, this should be remedied by correctly typing
+ * all options. For now, this is not too big of an issue because
+ * the user can simply omit options which cannot be changed anyway,
+ * so they will stay unchanged.
*/
- const char *old = qdict_get_try_str(reopen_state->bs->options,
- entry->key);
-
- if (!old || strcmp(new, old)) {
+ if (!qobject_is_equal(new, old)) {
error_setg(errp, "Cannot change the option '%s'", entry->key);
ret = -EINVAL;
goto error;