summaryrefslogtreecommitdiffstats
path: root/block.c
diff options
context:
space:
mode:
authorKevin Wolf2014-05-27 10:50:29 +0200
committerKevin Wolf2014-06-26 13:51:01 +0200
commit17b005f1d422d4581f8ce95b75d603deb081f4f3 (patch)
treef9dd3865a5ba53dbe08fe7c68608651c19e8cde3 /block.c
parentblock: Move json: parsing to bdrv_fill_options() (diff)
downloadqemu-17b005f1d422d4581f8ce95b75d603deb081f4f3.tar.gz
qemu-17b005f1d422d4581f8ce95b75d603deb081f4f3.tar.xz
qemu-17b005f1d422d4581f8ce95b75d603deb081f4f3.zip
block: Always pass driver name through options QDict
The "driver" entry in the options QDict is now only missing if we're opening an image with format probing. We also catch cases now where both the drv argument and a "driver" option is specified, e.g. by specifying -drive format=qcow2,driver=raw Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r--block.c76
1 files changed, 40 insertions, 36 deletions
diff --git a/block.c b/block.c
index 0d97fde366..0aa444e6ba 100644
--- a/block.c
+++ b/block.c
@@ -1037,14 +1037,13 @@ static QDict *parse_json_filename(const char *filename, Error **errp)
* filename/flags pair to option QDict entries.
*/
static int bdrv_fill_options(QDict **options, const char **pfilename, int flags,
- Error **errp)
+ BlockDriver *drv, Error **errp)
{
const char *filename = *pfilename;
const char *drvname;
bool protocol = flags & BDRV_O_PROTOCOL;
bool parse_filename = false;
Error *local_err = NULL;
- BlockDriver *drv;
/* Parse json: pseudo-protocol */
if (filename && g_str_has_prefix(filename, "json:")) {
@@ -1061,12 +1060,8 @@ static int bdrv_fill_options(QDict **options, const char **pfilename, int flags,
*pfilename = filename = NULL;
}
- if (!protocol) {
- return 0;
- }
-
/* Fetch the file name from the options QDict if necessary */
- if (filename) {
+ if (protocol && filename) {
if (!qdict_haskey(*options, "filename")) {
qdict_put(*options, "filename", qstring_from_str(filename));
parse_filename = true;
@@ -1081,30 +1076,41 @@ static int bdrv_fill_options(QDict **options, const char **pfilename, int flags,
filename = qdict_get_try_str(*options, "filename");
drvname = qdict_get_try_str(*options, "driver");
- if (!drvname) {
- if (filename) {
- drv = bdrv_find_protocol(filename, parse_filename);
- if (!drv) {
- error_setg(errp, "Unknown protocol");
+ if (drv) {
+ if (drvname) {
+ error_setg(errp, "Driver specified twice");
+ return -EINVAL;
+ }
+ drvname = drv->format_name;
+ qdict_put(*options, "driver", qstring_from_str(drvname));
+ } else {
+ if (!drvname && protocol) {
+ if (filename) {
+ drv = bdrv_find_protocol(filename, parse_filename);
+ if (!drv) {
+ error_setg(errp, "Unknown protocol");
+ return -EINVAL;
+ }
+
+ drvname = drv->format_name;
+ qdict_put(*options, "driver", qstring_from_str(drvname));
+ } else {
+ error_setg(errp, "Must specify either driver or file");
return -EINVAL;
}
-
- drvname = drv->format_name;
- qdict_put(*options, "driver", qstring_from_str(drvname));
- } else {
- error_setg(errp, "Must specify either driver or file");
- return -EINVAL;
+ } else if (drvname) {
+ drv = bdrv_find_format(drvname);
+ if (!drv) {
+ error_setg(errp, "Unknown driver '%s'", drvname);
+ return -ENOENT;
+ }
}
}
- drv = bdrv_find_format(drvname);
- if (!drv) {
- error_setg(errp, "Unknown driver '%s'", drvname);
- return -ENOENT;
- }
+ assert(drv || !protocol);
/* Driver-specific filename parsing */
- if (drv->bdrv_parse_filename && parse_filename) {
+ if (drv && drv->bdrv_parse_filename && parse_filename) {
drv->bdrv_parse_filename(filename, *options, &local_err);
if (local_err) {
error_propagate(errp, local_err);
@@ -1438,7 +1444,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
options = qdict_new();
}
- ret = bdrv_fill_options(&options, &filename, flags, &local_err);
+ ret = bdrv_fill_options(&options, &filename, flags, drv, &local_err);
if (local_err) {
goto fail;
}
@@ -1478,7 +1484,10 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
}
/* Find the right image format driver */
+ drv = NULL;
drvname = qdict_get_try_str(options, "driver");
+ assert(drvname || !(flags & BDRV_O_PROTOCOL));
+
if (drvname) {
drv = bdrv_find_format(drvname);
qdict_del(options, "driver");
@@ -1487,19 +1496,14 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
ret = -EINVAL;
goto fail;
}
- }
-
- if (!drv) {
- if (file) {
- ret = find_image_format(file, filename, &drv, &local_err);
- } else {
- error_setg(errp, "Must specify either driver or file");
- ret = -EINVAL;
+ } else if (file) {
+ ret = find_image_format(file, filename, &drv, &local_err);
+ if (ret < 0) {
goto fail;
}
- }
-
- if (!drv) {
+ } else {
+ error_setg(errp, "Must specify either driver or file");
+ ret = -EINVAL;
goto fail;
}