mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
block: driver should override flags in bdrv_open()
The BDRV_O_PROTOCOL flag should have an impact only if no driver is specified explicitly. Therefore, if bdrv_open() is called with an explicit block driver argument (either through the options QDict or through the drv parameter) and that block driver is a protocol block driver, BDRV_O_PROTOCOL should be set; if it is a format block driver, BDRV_O_PROTOCOL should be unset. While there was code to unset the flag in case a format block driver has been selected, it only followed the bdrv_fill_options() function call whereas the flag in fact needs to be adjusted before it is used there. With that change, BDRV_O_PROTOCOL will always be set if the BDS should be a protocol driver; if the driver has been specified explicitly, the new code will set it; and bdrv_fill_options() will only "probe" a protocol driver if BDRV_O_PROTOCOL is set. The probing after bdrv_fill_options() cannot select a protocol driver. Thus, bdrv_open_image() to open BDS.file is never called if a protocol BDS is about to be created. With that change in turn it is impossible to call bdrv_open_common() with a protocol drv and file != NULL, which allows us to remove the bdrv_swap() call. This change breaks a test case in qemu-iotest 051: "-drive file=t.qcow2,file.driver=qcow2" now works because the explicitly specified "qcow2" overrides the BDRV_O_PROTOCOL which is automatically set for the "file" BDS (and the filename is just passed down). Therefore, this patch removes that test case. Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
06207b0ff5
commit
53a2951312
49
block.c
49
block.c
|
@ -806,14 +806,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
|
||||||
}
|
}
|
||||||
qdict_del(options, "node-name");
|
qdict_del(options, "node-name");
|
||||||
|
|
||||||
/* bdrv_open() with directly using a protocol as drv. This layer is already
|
|
||||||
* opened, so assign it to bs (while file becomes a closed BlockDriverState)
|
|
||||||
* and return immediately. */
|
|
||||||
if (file != NULL && drv->bdrv_file_open) {
|
|
||||||
bdrv_swap(file, bs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bs->open_flags = flags;
|
bs->open_flags = flags;
|
||||||
bs->guest_block_size = 512;
|
bs->guest_block_size = 512;
|
||||||
bs->request_alignment = 512;
|
bs->request_alignment = 512;
|
||||||
|
@ -942,14 +934,17 @@ static QDict *parse_json_filename(const char *filename, Error **errp)
|
||||||
/*
|
/*
|
||||||
* Fills in default options for opening images and converts the legacy
|
* Fills in default options for opening images and converts the legacy
|
||||||
* filename/flags pair to option QDict entries.
|
* filename/flags pair to option QDict entries.
|
||||||
|
* The BDRV_O_PROTOCOL flag in *flags will be set or cleared accordingly if a
|
||||||
|
* block driver has been specified explicitly.
|
||||||
*/
|
*/
|
||||||
static int bdrv_fill_options(QDict **options, const char **pfilename, int flags,
|
static int bdrv_fill_options(QDict **options, const char **pfilename,
|
||||||
BlockDriver *drv, Error **errp)
|
int *flags, BlockDriver *drv, Error **errp)
|
||||||
{
|
{
|
||||||
const char *filename = *pfilename;
|
const char *filename = *pfilename;
|
||||||
const char *drvname;
|
const char *drvname;
|
||||||
bool protocol = flags & BDRV_O_PROTOCOL;
|
bool protocol = *flags & BDRV_O_PROTOCOL;
|
||||||
bool parse_filename = false;
|
bool parse_filename = false;
|
||||||
|
BlockDriver *tmp_drv;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
/* Parse json: pseudo-protocol */
|
/* Parse json: pseudo-protocol */
|
||||||
|
@ -967,6 +962,24 @@ static int bdrv_fill_options(QDict **options, const char **pfilename, int flags,
|
||||||
*pfilename = filename = NULL;
|
*pfilename = filename = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drvname = qdict_get_try_str(*options, "driver");
|
||||||
|
|
||||||
|
/* If the user has explicitly specified the driver, this choice should
|
||||||
|
* override the BDRV_O_PROTOCOL flag */
|
||||||
|
tmp_drv = drv;
|
||||||
|
if (!tmp_drv && drvname) {
|
||||||
|
tmp_drv = bdrv_find_format(drvname);
|
||||||
|
}
|
||||||
|
if (tmp_drv) {
|
||||||
|
protocol = tmp_drv->bdrv_file_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (protocol) {
|
||||||
|
*flags |= BDRV_O_PROTOCOL;
|
||||||
|
} else {
|
||||||
|
*flags &= ~BDRV_O_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fetch the file name from the options QDict if necessary */
|
/* Fetch the file name from the options QDict if necessary */
|
||||||
if (protocol && filename) {
|
if (protocol && filename) {
|
||||||
if (!qdict_haskey(*options, "filename")) {
|
if (!qdict_haskey(*options, "filename")) {
|
||||||
|
@ -981,7 +994,6 @@ static int bdrv_fill_options(QDict **options, const char **pfilename, int flags,
|
||||||
|
|
||||||
/* Find the right block driver */
|
/* Find the right block driver */
|
||||||
filename = qdict_get_try_str(*options, "filename");
|
filename = qdict_get_try_str(*options, "filename");
|
||||||
drvname = qdict_get_try_str(*options, "driver");
|
|
||||||
|
|
||||||
if (drv) {
|
if (drv) {
|
||||||
if (drvname) {
|
if (drvname) {
|
||||||
|
@ -1317,7 +1329,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
||||||
options = qdict_new();
|
options = qdict_new();
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_fill_options(&options, &filename, flags, drv, &local_err);
|
ret = bdrv_fill_options(&options, &filename, &flags, drv, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1336,11 +1348,6 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(drvname || !(flags & BDRV_O_PROTOCOL));
|
assert(drvname || !(flags & BDRV_O_PROTOCOL));
|
||||||
if (drv && !drv->bdrv_file_open) {
|
|
||||||
/* If the user explicitly wants a format driver here, we'll need to add
|
|
||||||
* another layer for the protocol in bs->file */
|
|
||||||
flags &= ~BDRV_O_PROTOCOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bs->options = options;
|
bs->options = options;
|
||||||
options = qdict_clone_shallow(options);
|
options = qdict_clone_shallow(options);
|
||||||
|
@ -1377,6 +1384,12 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* BDRV_O_PROTOCOL must be set iff a protocol BDS is about to be created */
|
||||||
|
assert(!!(flags & BDRV_O_PROTOCOL) == !!drv->bdrv_file_open);
|
||||||
|
/* file must be NULL if a protocol BDS is about to be created
|
||||||
|
* (the inverse results in an error message from bdrv_open_common()) */
|
||||||
|
assert(!(flags & BDRV_O_PROTOCOL) || !file);
|
||||||
|
|
||||||
/* Open the image */
|
/* Open the image */
|
||||||
ret = bdrv_open_common(bs, file, options, flags, drv, &local_err);
|
ret = bdrv_open_common(bs, file, options, flags, drv, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
@ -194,7 +194,6 @@ echo === Specifying the protocol layer ===
|
||||||
echo
|
echo
|
||||||
|
|
||||||
run_qemu -drive file="$TEST_IMG",file.driver=file
|
run_qemu -drive file="$TEST_IMG",file.driver=file
|
||||||
run_qemu -drive file="$TEST_IMG",file.driver=qcow2
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo === Leaving out required options ===
|
echo === Leaving out required options ===
|
||||||
|
|
|
@ -253,9 +253,6 @@ Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
|
||||||
QEMU X.Y.Z monitor - type 'help' for more information
|
QEMU X.Y.Z monitor - type 'help' for more information
|
||||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
|
|
||||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: Block format 'qcow2' used by device '' doesn't support the option 'filename'
|
|
||||||
|
|
||||||
|
|
||||||
=== Leaving out required options ===
|
=== Leaving out required options ===
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue