diff mbox

[RFC,5/6] block: Support driver specific options in drive_init()

Message ID 1361985955-15118-6-git-send-email-kwolf@redhat.com
State New
Headers show

Commit Message

Kevin Wolf Feb. 27, 2013, 5:25 p.m. UTC
Any non-default -drive options are now passed down to the block drivers.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 blockdev.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/blockdev.c b/blockdev.c
index f13f829..d6680a1 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -22,6 +22,7 @@ 
 #include "sysemu/arch_init.h"
 
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
+extern QemuOptsList qemu_common_drive_opts;
 
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
@@ -287,7 +288,26 @@  static bool do_check_io_limits(BlockIOLimit *io_limits, Error **errp)
     return true;
 }
 
-DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
+typedef struct AddCommonOptsData {
+    QemuOpts *opts;
+    QDict *bs_opts;
+} AddCommonOptsData;
+
+static int add_common_opts_cb(const char *name, const char *val, void *opaque)
+{
+    AddCommonOptsData *d = opaque;
+    Error *errp = NULL;
+
+    qemu_opt_set_err(d->opts, name, val, &errp);
+    if (error_is_set(&errp)) {
+        qdict_put(d->bs_opts, name, qstring_from_str(val));
+        error_free(errp);
+    }
+
+    return 0;
+}
+
+DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
 {
     const char *buf;
     const char *file = NULL;
@@ -310,10 +330,25 @@  DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
     bool copy_on_read;
     int ret;
     Error *error = NULL;
+    QemuOpts *opts;
+    QDict *bs_opts;
+    AddCommonOptsData add_common_opts_data;
 
     translation = BIOS_ATA_TRANSLATION_AUTO;
     media = MEDIA_DISK;
 
+    /* Check common options by copying from all_opts to opts, all other options
+     * are stored in bs_opts. */
+    opts = qemu_opts_create_nofail(&qemu_common_drive_opts);
+    bs_opts = qdict_new();
+
+    add_common_opts_data = (AddCommonOptsData) {
+        .opts       = opts,
+        .bs_opts    = bs_opts,
+    };
+
+    qemu_opt_foreach(all_opts, add_common_opts_cb, &add_common_opts_data, true);
+
     /* extract parameters */
     bus_id  = qemu_opt_get_number(opts, "bus", 0);
     unit_id = qemu_opt_get_number(opts, "unit", -1);
@@ -628,7 +663,7 @@  DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
         error_report("warning: disabling copy_on_read on readonly drive");
     }
 
-    ret = bdrv_open(dinfo->bdrv, file, NULL, bdrv_flags, drv);
+    ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv);
     if (ret < 0) {
         if (ret == -EMEDIUMTYPE) {
             error_report("could not open disk image %s: not in %s format",
@@ -1454,9 +1489,9 @@  BlockJobInfoList *qmp_query_block_jobs(Error **errp)
     return dummy.next;
 }
 
-QemuOptsList qemu_drive_opts = {
+QemuOptsList qemu_common_drive_opts = {
     .name = "drive",
-    .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
     .desc = {
         {
             .name = "bus",
@@ -1571,3 +1606,15 @@  QemuOptsList qemu_drive_opts = {
         { /* end of list */ }
     },
 };
+
+QemuOptsList qemu_drive_opts = {
+    .name = "drive",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
+    .desc = {
+        /*
+         * no elements => accept any params
+         * validation will happen later
+         */
+        { /* end of list */ }
+    },
+};