block: Allow "driver" option on the top level

This is traditionally -drive format=..., which is now translated into
the new driver option. This gives us a more consistent way to select the
driver of BlockDriverStates that can be used in QMP context, too.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Kevin Wolf 2013-07-09 11:09:02 +02:00
parent 69dd62dfd6
commit 74fe54f2a1
2 changed files with 17 additions and 10 deletions

View File

@ -970,6 +970,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
char tmp_filename[PATH_MAX + 1]; char tmp_filename[PATH_MAX + 1];
BlockDriverState *file = NULL; BlockDriverState *file = NULL;
QDict *file_options = NULL; QDict *file_options = NULL;
const char *drvname;
/* NULL means an empty set of options */ /* NULL means an empty set of options */
if (options == NULL) { if (options == NULL) {
@ -1059,6 +1060,12 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
} }
/* Find the right image format driver */ /* Find the right image format driver */
drvname = qdict_get_try_str(options, "driver");
if (drvname) {
drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
qdict_del(options, "driver");
}
if (!drv) { if (!drv) {
ret = find_image_format(file, filename, &drv); ret = find_image_format(file, filename, &drv);
} }

View File

@ -322,7 +322,6 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
enum { MEDIA_DISK, MEDIA_CDROM } media; enum { MEDIA_DISK, MEDIA_CDROM } media;
int bus_id, unit_id; int bus_id, unit_id;
int cyls, heads, secs, translation; int cyls, heads, secs, translation;
BlockDriver *drv = NULL;
int max_devs; int max_devs;
int index; int index;
int ro = 0; int ro = 0;
@ -338,6 +337,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
QemuOpts *opts; QemuOpts *opts;
QDict *bs_opts; QDict *bs_opts;
const char *id; const char *id;
bool has_driver_specific_opts;
translation = BIOS_ATA_TRANSLATION_AUTO; translation = BIOS_ATA_TRANSLATION_AUTO;
media = MEDIA_DISK; media = MEDIA_DISK;
@ -365,6 +365,8 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
qdict_del(bs_opts, "id"); qdict_del(bs_opts, "id");
} }
has_driver_specific_opts = !!qdict_size(bs_opts);
/* extract parameters */ /* extract parameters */
bus_id = qemu_opt_get_number(opts, "bus", 0); bus_id = qemu_opt_get_number(opts, "bus", 0);
unit_id = qemu_opt_get_number(opts, "unit", -1); unit_id = qemu_opt_get_number(opts, "unit", -1);
@ -477,11 +479,8 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
error_printf("\n"); error_printf("\n");
return NULL; return NULL;
} }
drv = bdrv_find_whitelisted_format(buf, ro);
if (!drv) { qdict_put(bs_opts, "driver", qstring_from_str(buf));
error_report("'%s' invalid format", buf);
return NULL;
}
} }
/* disk I/O throttling */ /* disk I/O throttling */
@ -658,7 +657,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
abort(); abort();
} }
if (!file || !*file) { if (!file || !*file) {
if (qdict_size(bs_opts)) { if (has_driver_specific_opts) {
file = NULL; file = NULL;
} else { } else {
return dinfo; return dinfo;
@ -695,13 +694,13 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
error_report("warning: disabling copy_on_read on readonly drive"); error_report("warning: disabling copy_on_read on readonly drive");
} }
ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv); QINCREF(bs_opts);
bs_opts = NULL; ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, NULL);
if (ret < 0) { if (ret < 0) {
if (ret == -EMEDIUMTYPE) { if (ret == -EMEDIUMTYPE) {
error_report("could not open disk image %s: not in %s format", error_report("could not open disk image %s: not in %s format",
file ?: dinfo->id, drv->format_name); file ?: dinfo->id, qdict_get_str(bs_opts, "driver"));
} else { } else {
error_report("could not open disk image %s: %s", error_report("could not open disk image %s: %s",
file ?: dinfo->id, strerror(-ret)); file ?: dinfo->id, strerror(-ret));
@ -712,6 +711,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
if (bdrv_key_required(dinfo->bdrv)) if (bdrv_key_required(dinfo->bdrv))
autostart = 0; autostart = 0;
QDECREF(bs_opts);
qemu_opts_del(opts); qemu_opts_del(opts);
return dinfo; return dinfo;