Commit 17b005f1 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

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: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
parent 5e5c4f63
Loading
Loading
Loading
Loading
+40 −36
Original line number Diff line number Diff line
@@ -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,7 +1076,15 @@ 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 (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) {
@@ -1095,16 +1098,19 @@ static int bdrv_fill_options(QDict **options, const char **pfilename, int flags,
                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;
            }
        }
    }

    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,21 +1496,16 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
            ret = -EINVAL;
            goto fail;
        }
    }

    if (!drv) {
        if (file) {
    } else if (file) {
        ret = find_image_format(file, filename, &drv, &local_err);
        if (ret < 0) {
            goto fail;
        }
    } else {
        error_setg(errp, "Must specify either driver or file");
        ret = -EINVAL;
        goto fail;
    }
    }

    if (!drv) {
        goto fail;
    }

    /* Open the image */
    ret = bdrv_open_common(bs, file, options, flags, drv, &local_err);
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ echo

run_qemu -drive file="$TEST_IMG",format=foo
run_qemu -drive file="$TEST_IMG",driver=foo
run_qemu -drive file="$TEST_IMG",driver=raw,format=qcow2

echo
echo === Overriding backing file ===
+4 −1
Original line number Diff line number Diff line
@@ -38,7 +38,10 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=foo
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=foo: 'foo' invalid format

Testing: -drive file=TEST_DIR/t.qcow2,driver=foo
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=foo: could not open disk image TEST_DIR/t.qcow2: Invalid driver: 'foo'
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=foo: could not open disk image TEST_DIR/t.qcow2: Unknown driver 'foo'

Testing: -drive file=TEST_DIR/t.qcow2,driver=raw,format=qcow2
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,format=qcow2: could not open disk image TEST_DIR/t.qcow2: Driver specified twice


=== Overriding backing file ===