]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/commitdiff
change block layer to support both QemuOpts and QEMUOptionParamter
authorChunyan Liu <cyliu@suse.com>
Thu, 5 Jun 2014 09:20:51 +0000 (17:20 +0800)
committerStefan Hajnoczi <stefanha@redhat.com>
Mon, 16 Jun 2014 09:23:20 +0000 (17:23 +0800)
Change block layer to support both QemuOpts and QEMUOptionParameter.
After this patch, it will change backend drivers one by one. At the end,
QEMUOptionParameter will be removed and only QemuOpts is kept.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14 files changed:
block.c
block/cow.c
block/qcow.c
block/qcow2.c
block/qed.c
block/raw_bsd.c
block/vhdx.c
block/vmdk.c
block/vvfat.c
include/block/block.h
include/block/block_int.h
qemu-img.c
tests/qemu-iotests/049.out
tests/qemu-iotests/061.out

diff --git a/block.c b/block.c
index 17f763db792f621eb1a3e1eec4b50b9a11762412..3dd21945155fb80534e3f938cfd96b7e0686ac9e 100644 (file)
--- a/block.c
+++ b/block.c
@@ -329,6 +329,13 @@ void bdrv_register(BlockDriver *bdrv)
         }
     }
 
+    if (bdrv->bdrv_create) {
+        assert(!bdrv->bdrv_create2 && !bdrv->create_opts);
+        assert(!bdrv->bdrv_amend_options2);
+    } else if (bdrv->bdrv_create2) {
+        assert(!bdrv->bdrv_create && !bdrv->create_options);
+        assert(!bdrv->bdrv_amend_options);
+    }
     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
 }
 
@@ -425,6 +432,7 @@ typedef struct CreateCo {
     BlockDriver *drv;
     char *filename;
     QEMUOptionParameter *options;
+    QemuOpts *opts;
     int ret;
     Error *err;
 } CreateCo;
@@ -436,8 +444,28 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
 
     CreateCo *cco = opaque;
     assert(cco->drv);
+    assert(!(cco->options && cco->opts));
 
-    ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
+    if (cco->drv->bdrv_create2) {
+        QemuOptsList *opts_list = NULL;
+        if (cco->options) {
+            opts_list = params_to_opts(cco->options);
+            cco->opts = qemu_opts_create(opts_list, NULL, 0, &error_abort);
+        }
+        ret = cco->drv->bdrv_create2(cco->filename, cco->opts, &local_err);
+        if (cco->options) {
+            qemu_opts_del(cco->opts);
+            qemu_opts_free(opts_list);
+        }
+    } else {
+        if (cco->opts) {
+            cco->options = opts_to_params(cco->opts);
+        }
+        ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
+        if (cco->opts) {
+            free_option_parameters(cco->options);
+        }
+    }
     if (local_err) {
         error_propagate(&cco->err, local_err);
     }
@@ -445,7 +473,8 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
 }
 
 int bdrv_create(BlockDriver *drv, const char* filename,
-    QEMUOptionParameter *options, Error **errp)
+                QEMUOptionParameter *options,
+                QemuOpts *opts, Error **errp)
 {
     int ret;
 
@@ -454,11 +483,12 @@ int bdrv_create(BlockDriver *drv, const char* filename,
         .drv = drv,
         .filename = g_strdup(filename),
         .options = options,
+        .opts = opts,
         .ret = NOT_DONE,
         .err = NULL,
     };
 
-    if (!drv->bdrv_create) {
+    if (!drv->bdrv_create && !drv->bdrv_create2) {
         error_setg(errp, "Driver '%s' does not support image creation", drv->format_name);
         ret = -ENOTSUP;
         goto out;
@@ -490,7 +520,7 @@ out:
 }
 
 int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
-                     Error **errp)
+                     QemuOpts *opts, Error **errp)
 {
     BlockDriver *drv;
     Error *local_err = NULL;
@@ -502,7 +532,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
         return -ENOENT;
     }
 
-    ret = bdrv_create(drv, filename, options, &local_err);
+    ret = bdrv_create(drv, filename, options, opts, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
     }
@@ -1247,7 +1277,8 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
     char *tmp_filename = g_malloc0(PATH_MAX + 1);
     int64_t total_size;
     BlockDriver *bdrv_qcow2;
-    QEMUOptionParameter *create_options;
+    QemuOptsList *create_opts = NULL;
+    QemuOpts *opts = NULL;
     QDict *snapshot_options;
     BlockDriverState *bs_snapshot;
     Error *local_err;
@@ -1272,13 +1303,20 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
     }
 
     bdrv_qcow2 = bdrv_find_format("qcow2");
-    create_options = parse_option_parameters("", bdrv_qcow2->create_options,
-                                             NULL);
-
-    set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
 
-    ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
-    free_option_parameters(create_options);
+    assert(!(bdrv_qcow2->create_options && bdrv_qcow2->create_opts));
+    if (bdrv_qcow2->create_options) {
+        create_opts = params_to_opts(bdrv_qcow2->create_options);
+    } else {
+        create_opts = bdrv_qcow2->create_opts;
+    }
+    opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+    qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
+    ret = bdrv_create(bdrv_qcow2, tmp_filename, NULL, opts, &local_err);
+    qemu_opts_del(opts);
+    if (bdrv_qcow2->create_options) {
+        qemu_opts_free(create_opts);
+    }
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not create temporary overlay "
                          "'%s': %s", tmp_filename,
@@ -5519,8 +5557,10 @@ void bdrv_img_create(const char *filename, const char *fmt,
                      char *options, uint64_t img_size, int flags,
                      Error **errp, bool quiet)
 {
-    QEMUOptionParameter *param = NULL, *create_options = NULL;
-    QEMUOptionParameter *backing_fmt, *backing_file, *size;
+    QemuOptsList *create_opts = NULL;
+    QemuOpts *opts = NULL;
+    const char *backing_fmt, *backing_file;
+    int64_t size;
     BlockDriver *drv, *proto_drv;
     BlockDriver *backing_drv = NULL;
     Error *local_err = NULL;
@@ -5539,28 +5579,25 @@ void bdrv_img_create(const char *filename, const char *fmt,
         return;
     }
 
-    create_options = append_option_parameters(create_options,
-                                              drv->create_options);
-    create_options = append_option_parameters(create_options,
-                                              proto_drv->create_options);
+    create_opts = qemu_opts_append(create_opts, drv->create_opts,
+                                   drv->create_options);
+    create_opts = qemu_opts_append(create_opts, proto_drv->create_opts,
+                                   proto_drv->create_options);
 
     /* Create parameter list with default values */
-    param = parse_option_parameters("", create_options, param);
-
-    set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
+    opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+    qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size);
 
     /* Parse -o options */
     if (options) {
-        param = parse_option_parameters(options, create_options, param);
-        if (param == NULL) {
-            error_setg(errp, "Invalid options for file format '%s'.", fmt);
+        if (qemu_opts_do_parse(opts, options, NULL) != 0) {
+            error_setg(errp, "Invalid options for file format '%s'", fmt);
             goto out;
         }
     }
 
     if (base_filename) {
-        if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
-                                 base_filename)) {
+        if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename)) {
             error_setg(errp, "Backing file not supported for file format '%s'",
                        fmt);
             goto out;
@@ -5568,37 +5605,37 @@ void bdrv_img_create(const char *filename, const char *fmt,
     }
 
     if (base_fmt) {
-        if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
+        if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) {
             error_setg(errp, "Backing file format not supported for file "
                              "format '%s'", fmt);
             goto out;
         }
     }
 
-    backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
-    if (backing_file && backing_file->value.s) {
-        if (!strcmp(filename, backing_file->value.s)) {
+    backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
+    if (backing_file) {
+        if (!strcmp(filename, backing_file)) {
             error_setg(errp, "Error: Trying to create an image with the "
                              "same filename as the backing file");
             goto out;
         }
     }
 
-    backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
-    if (backing_fmt && backing_fmt->value.s) {
-        backing_drv = bdrv_find_format(backing_fmt->value.s);
+    backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
+    if (backing_fmt) {
+        backing_drv = bdrv_find_format(backing_fmt);
         if (!backing_drv) {
             error_setg(errp, "Unknown backing file format '%s'",
-                       backing_fmt->value.s);
+                       backing_fmt);
             goto out;
         }
     }
 
     // The size for the image must always be specified, with one exception:
     // If we are using a backing file, we can obtain the size from there
-    size = get_option_parameter(param, BLOCK_OPT_SIZE);
-    if (size && size->value.n == -1) {
-        if (backing_file && backing_file->value.s) {
+    size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
+    if (size == -1) {
+        if (backing_file) {
             BlockDriverState *bs;
             uint64_t size;
             char buf[32];
@@ -5609,11 +5646,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
                 flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
 
             bs = NULL;
-            ret = bdrv_open(&bs, backing_file->value.s, NULL, NULL, back_flags,
+            ret = bdrv_open(&bs, backing_file, NULL, NULL, back_flags,
                             backing_drv, &local_err);
             if (ret < 0) {
                 error_setg_errno(errp, -ret, "Could not open '%s': %s",
-                                 backing_file->value.s,
+                                 backing_file,
                                  error_get_pretty(local_err));
                 error_free(local_err);
                 local_err = NULL;
@@ -5623,7 +5660,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
             size *= 512;
 
             snprintf(buf, sizeof(buf), "%" PRId64, size);
-            set_option_parameter(param, BLOCK_OPT_SIZE, buf);
+            qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size);
 
             bdrv_unref(bs);
         } else {
@@ -5634,16 +5671,18 @@ void bdrv_img_create(const char *filename, const char *fmt,
 
     if (!quiet) {
         printf("Formatting '%s', fmt=%s ", filename, fmt);
-        print_option_parameters(param);
+        qemu_opts_print(opts);
         puts("");
     }
-    ret = bdrv_create(drv, filename, param, &local_err);
+
+    ret = bdrv_create(drv, filename, NULL, opts, &local_err);
+
     if (ret == -EFBIG) {
         /* This is generally a better message than whatever the driver would
          * deliver (especially because of the cluster_size_hint), since that
          * is most probably not much different from "image too large". */
         const char *cluster_size_hint = "";
-        if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
+        if (qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, 0)) {
             cluster_size_hint = " (try using a larger cluster size)";
         }
         error_setg(errp, "The image size is too large for file format '%s'"
@@ -5653,9 +5692,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
     }
 
 out:
-    free_option_parameters(create_options);
-    free_option_parameters(param);
-
+    qemu_opts_del(opts);
+    qemu_opts_free(create_opts);
     if (local_err) {
         error_propagate(errp, local_err);
     }
@@ -5731,12 +5769,36 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
     notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
 }
 
-int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
+int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options,
+                       QemuOpts *opts)
 {
-    if (bs->drv->bdrv_amend_options == NULL) {
+    int ret;
+    assert(!(options && opts));
+
+    if (!bs->drv->bdrv_amend_options && !bs->drv->bdrv_amend_options2) {
         return -ENOTSUP;
     }
-    return bs->drv->bdrv_amend_options(bs, options);
+    if (bs->drv->bdrv_amend_options2) {
+        QemuOptsList *opts_list = NULL;
+        if (options) {
+            opts_list = params_to_opts(options);
+            opts = qemu_opts_create(opts_list, NULL, 0, &error_abort);
+        }
+        ret = bs->drv->bdrv_amend_options2(bs, opts);
+        if (options) {
+            qemu_opts_del(opts);
+            qemu_opts_free(opts_list);
+        }
+    } else {
+        if (opts) {
+            options = opts_to_params(opts);
+        }
+        ret = bs->drv->bdrv_amend_options(bs, options);
+        if (opts) {
+            free_option_parameters(options);
+        }
+    }
+    return ret;
 }
 
 /* This function will be called by the bdrv_recurse_is_first_non_filter method
index 164759f3a3d5b89d82cfe2f8adecf0894a1fb358..7e610249f0dbc139fa6e9d49c6a4ef3244f6f282 100644 (file)
@@ -345,7 +345,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
         options++;
     }
 
-    ret = bdrv_create_file(filename, options, &local_err);
+    ret = bdrv_create_file(filename, options, NULL, &local_err);
     if (ret < 0) {
         error_propagate(errp, local_err);
         return ret;
index 7fd57d744aae343ef3d217bc57f739708ce2e327..32651ebc2494812e3f460c618ea341dcd4e03cec 100644 (file)
@@ -718,7 +718,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
         options++;
     }
 
-    ret = bdrv_create_file(filename, options, &local_err);
+    ret = bdrv_create_file(filename, options, NULL, &local_err);
     if (ret < 0) {
         error_propagate(errp, local_err);
         return ret;
index a54d2ba89710d50f4deaa535df1500386ae487de..6b95a7f3bd02fcf33b3ea415fc9d1bfc2f76a8fc 100644 (file)
@@ -1626,7 +1626,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
     Error *local_err = NULL;
     int ret;
 
-    ret = bdrv_create_file(filename, options, &local_err);
+    ret = bdrv_create_file(filename, options, NULL, &local_err);
     if (ret < 0) {
         error_propagate(errp, local_err);
         return ret;
index 79f5bd392af797eae2fd9552e24f42253d64c37b..9826ad8022949bbbd39d5a013822f3c9e3b73f90 100644 (file)
@@ -586,7 +586,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
     int ret = 0;
     BlockDriverState *bs;
 
-    ret = bdrv_create_file(filename, NULL, &local_err);
+    ret = bdrv_create_file(filename, NULL, NULL, &local_err);
     if (ret < 0) {
         error_propagate(errp, local_err);
         return ret;
index 01ea692a46d1ac996f5875728469db010d51e292..9ae5fc21d4a178f4783b0d177c99eb7c0d9c8a0f 100644 (file)
@@ -145,7 +145,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
     Error *local_err = NULL;
     int ret;
 
-    ret = bdrv_create_file(filename, options, &local_err);
+    ret = bdrv_create_file(filename, options, NULL, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
     }
index 353c74d35ff76b5eed17580ce8a839ff8b26eec7..ca7d5339481b45da5341fc74ba6e9588023196e8 100644 (file)
@@ -1803,7 +1803,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
     block_size = block_size > VHDX_BLOCK_SIZE_MAX ? VHDX_BLOCK_SIZE_MAX :
                                                     block_size;
 
-    ret = bdrv_create_file(filename, options, &local_err);
+    ret = bdrv_create_file(filename, options, NULL, &local_err);
     if (ret < 0) {
         error_propagate(errp, local_err);
         goto exit;
index b8a476278a8d5ca623204a6d9acde5f5de4c0100..b653f5ecef67372069005787b6abcb2731284b83 100644 (file)
@@ -1539,7 +1539,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
     uint32_t *gd_buf = NULL;
     int gd_buf_size;
 
-    ret = bdrv_create_file(filename, NULL, &local_err);
+    ret = bdrv_create_file(filename, NULL, NULL, &local_err);
     if (ret < 0) {
         error_propagate(errp, local_err);
         goto exit;
@@ -1879,7 +1879,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
     if (!split && !flat) {
         desc_offset = 0x200;
     } else {
-        ret = bdrv_create_file(filename, options, &local_err);
+        ret = bdrv_create_file(filename, options, NULL, &local_err);
         if (ret < 0) {
             error_propagate(errp, local_err);
             goto exit;
index 3cda19f2f3b9c5153d1baa2325af20e75246490f..d895582030a82e6b1938159f94e091a2e4ab09a5 100644 (file)
@@ -2930,7 +2930,7 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
     set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
     set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
 
-    ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, errp);
+    ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, NULL, errp);
     free_option_parameters(options);
     if (ret < 0) {
         goto err;
index 7d86e29cf4eda8339083616e0e54720f20327d4e..4312b8176e251a150d402822dd53d204ecc062bd 100644 (file)
@@ -204,9 +204,9 @@ BlockDriver *bdrv_find_format(const char *format_name);
 BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
                                           bool readonly);
 int bdrv_create(BlockDriver *drv, const char* filename,
-    QEMUOptionParameter *options, Error **errp);
+    QEMUOptionParameter *options, QemuOpts *opts, Error **errp);
 int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
-                     Error **errp);
+                     QemuOpts *opts, Error **errp);
 BlockDriverState *bdrv_new(const char *device_name, Error **errp);
 void bdrv_make_anon(BlockDriverState *bs);
 void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
@@ -312,7 +312,8 @@ typedef enum {
 
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
 
-int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options);
+int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options,
+                       QemuOpts *opts);
 
 /* external snapshots */
 bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
index 8d58334c1d37782cc881eab572d565e7ba5296ff..8a77d79f41a06de7f68b8a62b4b733ae3aa235c6 100644 (file)
@@ -118,6 +118,8 @@ struct BlockDriver {
     void (*bdrv_rebind)(BlockDriverState *bs);
     int (*bdrv_create)(const char *filename, QEMUOptionParameter *options,
                        Error **errp);
+    /* FIXME: will remove the duplicate and rename back to bdrv_create later */
+    int (*bdrv_create2)(const char *filename, QemuOpts *opts, Error **errp);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
     int (*bdrv_make_empty)(BlockDriverState *bs);
     /* aio */
@@ -217,7 +219,12 @@ struct BlockDriver {
 
     /* List of options for creating images, terminated by name == NULL */
     QEMUOptionParameter *create_options;
-
+    /* FIXME: will replace create_options.
+     * These two fields are mutually exclusive. At most one is non-NULL.
+     * create_options should only be set with bdrv_create, and create_opts
+     * should only be set with bdrv_create2.
+     */
+    QemuOptsList *create_opts;
 
     /*
      * Returns 0 for completed check, -errno for internal errors.
@@ -228,6 +235,10 @@ struct BlockDriver {
 
     int (*bdrv_amend_options)(BlockDriverState *bs,
         QEMUOptionParameter *options);
+    /* FIXME: will remove the duplicate and rename back to
+     * bdrv_amend_options later
+     */
+    int (*bdrv_amend_options2)(BlockDriverState *bs, QemuOpts *opts);
 
     void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
 
index aa89ba21fdfb414b18be5248da1b94b5b489ece6..8acdcca8bfc0a88fb9e86d589e8c5b7886d92c6c 100644 (file)
@@ -271,7 +271,7 @@ static int read_password(char *buf, int buf_size)
 static int print_block_option_help(const char *filename, const char *fmt)
 {
     BlockDriver *drv, *proto_drv;
-    QEMUOptionParameter *create_options = NULL;
+    QemuOptsList *create_opts = NULL;
 
     /* Find driver and parse its options */
     drv = bdrv_find_format(fmt);
@@ -280,22 +280,21 @@ static int print_block_option_help(const char *filename, const char *fmt)
         return 1;
     }
 
-    create_options = append_option_parameters(create_options,
-                                              drv->create_options);
-
+    create_opts = qemu_opts_append(create_opts, drv->create_opts,
+                                   drv->create_options);
     if (filename) {
         proto_drv = bdrv_find_protocol(filename, true);
         if (!proto_drv) {
             error_report("Unknown protocol '%s'", filename);
-            free_option_parameters(create_options);
+            qemu_opts_free(create_opts);
             return 1;
         }
-        create_options = append_option_parameters(create_options,
-                                                  proto_drv->create_options);
+        create_opts = qemu_opts_append(create_opts, proto_drv->create_opts,
+                                       proto_drv->create_options);
     }
 
-    print_option_help(create_options);
-    free_option_parameters(create_options);
+    qemu_opts_print_help(create_opts);
+    qemu_opts_free(create_opts);
     return 0;
 }
 
@@ -349,19 +348,19 @@ fail:
     return NULL;
 }
 
-static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
+static int add_old_style_options(const char *fmt, QemuOpts *opts,
                                  const char *base_filename,
                                  const char *base_fmt)
 {
     if (base_filename) {
-        if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
+        if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename)) {
             error_report("Backing file not supported for file format '%s'",
                          fmt);
             return -1;
         }
     }
     if (base_fmt) {
-        if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
+        if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) {
             error_report("Backing file format not supported for file "
                          "format '%s'", fmt);
             return -1;
@@ -1191,8 +1190,9 @@ static int img_convert(int argc, char **argv)
     size_t bufsectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE;
     const uint8_t *buf1;
     BlockDriverInfo bdi;
-    QEMUOptionParameter *param = NULL, *create_options = NULL;
-    QEMUOptionParameter *out_baseimg_param;
+    QemuOpts *opts = NULL;
+    QemuOptsList *create_opts = NULL;
+    const char *out_baseimg_param;
     char *options = NULL;
     const char *snapshot_name = NULL;
     int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
@@ -1381,40 +1381,36 @@ static int img_convert(int argc, char **argv)
         goto out;
     }
 
-    create_options = append_option_parameters(create_options,
-                                              drv->create_options);
-    create_options = append_option_parameters(create_options,
-                                              proto_drv->create_options);
+    create_opts = qemu_opts_append(create_opts, drv->create_opts,
+                                   drv->create_options);
+    create_opts = qemu_opts_append(create_opts, proto_drv->create_opts,
+                                   proto_drv->create_options);
 
-    if (options) {
-        param = parse_option_parameters(options, create_options, param);
-        if (param == NULL) {
-            error_report("Invalid options for file format '%s'.", out_fmt);
-            ret = -1;
-            goto out;
-        }
-    } else {
-        param = parse_option_parameters("", create_options, param);
+    opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+    if (options && qemu_opts_do_parse(opts, options, NULL)) {
+        error_report("Invalid options for file format '%s'", out_fmt);
+        ret = -1;
+        goto out;
     }
 
-    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
-    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
+    qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_sectors * 512);
+    ret = add_old_style_options(out_fmt, opts, out_baseimg, NULL);
     if (ret < 0) {
         goto out;
     }
 
     /* Get backing file name if -o backing_file was used */
-    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
+    out_baseimg_param = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
     if (out_baseimg_param) {
-        out_baseimg = out_baseimg_param->value.s;
+        out_baseimg = out_baseimg_param;
     }
 
     /* Check if compression is supported */
     if (compress) {
-        QEMUOptionParameter *encryption =
-            get_option_parameter(param, BLOCK_OPT_ENCRYPT);
-        QEMUOptionParameter *preallocation =
-            get_option_parameter(param, BLOCK_OPT_PREALLOC);
+        bool encryption =
+            qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, false);
+        const char *preallocation =
+            qemu_opt_get(opts, BLOCK_OPT_PREALLOC);
 
         if (!drv->bdrv_write_compressed) {
             error_report("Compression not supported for this file format");
@@ -1422,15 +1418,15 @@ static int img_convert(int argc, char **argv)
             goto out;
         }
 
-        if (encryption && encryption->value.n) {
+        if (encryption) {
             error_report("Compression and encryption not supported at "
                          "the same time");
             ret = -1;
             goto out;
         }
 
-        if (preallocation && preallocation->value.s
-            && strcmp(preallocation->value.s, "off"))
+        if (preallocation
+            && strcmp(preallocation, "off"))
         {
             error_report("Compression and preallocation not supported at "
                          "the same time");
@@ -1441,7 +1437,7 @@ static int img_convert(int argc, char **argv)
 
     if (!skip_create) {
         /* Create the new image */
-        ret = bdrv_create(drv, out_filename, param, &local_err);
+        ret = bdrv_create(drv, out_filename, NULL, opts, &local_err);
         if (ret < 0) {
             error_report("%s: error while converting %s: %s",
                          out_filename, out_fmt, error_get_pretty(local_err));
@@ -1706,8 +1702,8 @@ out:
         qemu_progress_print(100, 0);
     }
     qemu_progress_end();
-    free_option_parameters(create_options);
-    free_option_parameters(param);
+    qemu_opts_del(opts);
+    qemu_opts_free(create_opts);
     qemu_vfree(buf);
     if (sn_opts) {
         qemu_opts_del(sn_opts);
@@ -2698,7 +2694,8 @@ static int img_amend(int argc, char **argv)
 {
     int c, ret = 0;
     char *options = NULL;
-    QEMUOptionParameter *create_options = NULL, *options_param = NULL;
+    QemuOptsList *create_opts = NULL;
+    QemuOpts *opts = NULL;
     const char *fmt = NULL, *filename;
     bool quiet = false;
     BlockDriverState *bs = NULL;
@@ -2769,17 +2766,16 @@ static int img_amend(int argc, char **argv)
         goto out;
     }
 
-    create_options = append_option_parameters(create_options,
-            bs->drv->create_options);
-    options_param = parse_option_parameters(options, create_options,
-            options_param);
-    if (options_param == NULL) {
+    create_opts = qemu_opts_append(create_opts, bs->drv->create_opts,
+                                   bs->drv->create_options);
+    opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+    if (options && qemu_opts_do_parse(opts, options, NULL)) {
         error_report("Invalid options for file format '%s'", fmt);
         ret = -1;
         goto out;
     }
 
-    ret = bdrv_amend_options(bs, options_param);
+    ret = bdrv_amend_options(bs, NULL, opts);
     if (ret < 0) {
         error_report("Error while amending options: %s", strerror(-ret));
         goto out;
@@ -2789,8 +2785,8 @@ out:
     if (bs) {
         bdrv_unref(bs);
     }
-    free_option_parameters(create_options);
-    free_option_parameters(options_param);
+    qemu_opts_del(opts);
+    qemu_opts_free(create_opts);
     g_free(options);
 
     if (ret) {
index ceb23289fd9dc69b36bfe9ec2aa49e276d0864a0..71ca44d76b27e92e7fb47df4f5b139d19fbe46b8 100644 (file)
@@ -120,7 +120,7 @@ qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
 
 qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2
 qemu-img: Parameter 'size' expects a size
-qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'.
+qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'
 
 == Check correct interpretation of suffixes for cluster size ==
 
index 4027e0077ea60a057d283d98be854f1068efb471..e3724700b9f5e062d7dccf823dc4e971a1d34508 100644 (file)
@@ -281,7 +281,7 @@ Lazy refcounts only supported with compatibility level 1.1 and above (use compat
 qemu-img: Error while amending options: Invalid argument
 Unknown compatibility level 0.42.
 qemu-img: Error while amending options: Invalid argument
-Unknown option 'foo'
+qemu-img: Invalid parameter 'foo'
 qemu-img: Invalid options for file format 'qcow2'
 Changing the cluster size is not supported.
 qemu-img: Error while amending options: Operation not supported