mirror of https://github.com/xemu-project/xemu.git
block: Add bdrv_open_image()
Add a common function for opening images to be used for block drivers specified through BlockdevRefs in an option QDict. The difference from bdrv_file_open() is that this function may invoke bdrv_open() instead, allowing auto-detection of the driver to be used; and second, it automatically extracts the BlockdevRef from the option QDict. Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
2a05cbe426
commit
da557aac18
73
block.c
73
block.c
|
@ -1040,6 +1040,79 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a disk image whose options are given as BlockdevRef in another block
|
||||
* device's options.
|
||||
*
|
||||
* If force_raw is true, bdrv_file_open() will be used, thereby preventing any
|
||||
* image format auto-detection. If it is false and a filename is given,
|
||||
* bdrv_open() will be used for auto-detection.
|
||||
*
|
||||
* If allow_none is true, no image will be opened if filename is false and no
|
||||
* BlockdevRef is given. *pbs will remain unchanged and 0 will be returned.
|
||||
*
|
||||
* bdrev_key specifies the key for the image's BlockdevRef in the options QDict.
|
||||
* That QDict has to be flattened; therefore, if the BlockdevRef is a QDict
|
||||
* itself, all options starting with "${bdref_key}." are considered part of the
|
||||
* BlockdevRef.
|
||||
*
|
||||
* The BlockdevRef will be removed from the options QDict.
|
||||
*/
|
||||
int bdrv_open_image(BlockDriverState **pbs, const char *filename,
|
||||
QDict *options, const char *bdref_key, int flags,
|
||||
bool force_raw, bool allow_none, Error **errp)
|
||||
{
|
||||
QDict *image_options;
|
||||
int ret;
|
||||
char *bdref_key_dot;
|
||||
const char *reference;
|
||||
|
||||
bdref_key_dot = g_strdup_printf("%s.", bdref_key);
|
||||
qdict_extract_subqdict(options, &image_options, bdref_key_dot);
|
||||
g_free(bdref_key_dot);
|
||||
|
||||
reference = qdict_get_try_str(options, bdref_key);
|
||||
if (!filename && !reference && !qdict_size(image_options)) {
|
||||
if (allow_none) {
|
||||
ret = 0;
|
||||
} else {
|
||||
error_setg(errp, "A block device must be specified for \"%s\"",
|
||||
bdref_key);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (filename && !force_raw) {
|
||||
/* If a filename is given and the block driver should be detected
|
||||
automatically (instead of using none), use bdrv_open() in order to do
|
||||
that auto-detection. */
|
||||
BlockDriverState *bs;
|
||||
|
||||
if (reference) {
|
||||
error_setg(errp, "Cannot reference an existing block device while "
|
||||
"giving a filename");
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
bs = bdrv_new("");
|
||||
ret = bdrv_open(bs, filename, image_options, flags, NULL, errp);
|
||||
if (ret < 0) {
|
||||
bdrv_unref(bs);
|
||||
} else {
|
||||
*pbs = bs;
|
||||
}
|
||||
} else {
|
||||
ret = bdrv_file_open(pbs, filename, reference, image_options, flags,
|
||||
errp);
|
||||
}
|
||||
|
||||
done:
|
||||
qdict_del(options, bdref_key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a disk image (raw, qcow2, vmdk, ...)
|
||||
*
|
||||
|
|
|
@ -186,6 +186,9 @@ int bdrv_parse_discard_flags(const char *mode, int *flags);
|
|||
int bdrv_file_open(BlockDriverState **pbs, const char *filename,
|
||||
const char *reference, QDict *options, int flags,
|
||||
Error **errp);
|
||||
int bdrv_open_image(BlockDriverState **pbs, const char *filename,
|
||||
QDict *options, const char *bdref_key, int flags,
|
||||
bool force_raw, bool allow_none, Error **errp);
|
||||
int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp);
|
||||
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
|
||||
int flags, BlockDriver *drv, Error **errp);
|
||||
|
|
Loading…
Reference in New Issue