diff mbox

[V18,23/25] block: clean temp code and use QemuOpts in block

Message ID 1376368326-7433-24-git-send-email-wdongxu@linux.vnet.ibm.com
State New
Headers show

Commit Message

Robert Wang Aug. 13, 2013, 4:32 a.m. UTC
Temp code are unnecessary now, so clean them and use QemuOpts parser
in block layer.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>

Conflicts:
	block/sheepdog.c
---
 block.c                   |  60 ++---------
 block/cow.c               |  83 +--------------
 block/gluster.c           |  61 +----------
 block/iscsi.c             |  64 +----------
 block/qcow.c              | 129 +----------------------
 block/qcow2.c             | 262 ++--------------------------------------------
 block/qed.c               | 151 +-------------------------
 block/raw-posix.c         |  91 ++--------------
 block/raw-win32.c         |  37 +------
 block/raw.c               |  20 +---
 block/rbd.c               |  98 +----------------
 block/sheepdog.c          | 119 +--------------------
 block/ssh.c               |  72 +------------
 block/vdi.c               | 132 +----------------------
 block/vmdk.c              | 232 +---------------------------------------
 block/vpc.c               | 123 +---------------------
 block/vvfat.c             |  11 +-
 include/block/block.h     |   7 +-
 include/block/block_int.h |   5 +-
 qemu-img.c                |  75 ++++++-------
 20 files changed, 80 insertions(+), 1752 deletions(-)
diff mbox

Patch

diff --git a/block.c b/block.c
index 9f52341..c1130b8 100644
--- a/block.c
+++ b/block.c
@@ -375,58 +375,10 @@  static void coroutine_fn bdrv_create_co_entry(void *opaque)
     CreateCo *cco = opaque;
     assert(cco->drv);
 
-    cco->ret = cco->drv->bdrv_create_new(cco->filename, cco->opts);
+    cco->ret = cco->drv->bdrv_create(cco->filename, cco->opts);
 }
 
-int bdrv_create(BlockDriver *drv, const char* filename,
-    QEMUOptionParameter *options)
-{
-    int ret;
-
-    Coroutine *co;
-    CreateCo cco = {
-        .drv = drv,
-        .filename = g_strdup(filename),
-        .options = options,
-        .ret = NOT_DONE,
-    };
-
-    if (!drv->bdrv_create) {
-        ret = -ENOTSUP;
-        goto out;
-    }
-
-    if (qemu_in_coroutine()) {
-        /* Fast-path if already in coroutine context */
-        bdrv_create_co_entry(&cco);
-    } else {
-        co = qemu_coroutine_create(bdrv_create_co_entry);
-        qemu_coroutine_enter(co, &cco);
-        while (cco.ret == NOT_DONE) {
-            qemu_aio_wait();
-        }
-    }
-
-    ret = cco.ret;
-
-out:
-    g_free(cco.filename);
-    return ret;
-}
-
-int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
-{
-    BlockDriver *drv;
-
-    drv = bdrv_find_protocol(filename, true);
-    if (drv == NULL) {
-        return -ENOENT;
-    }
-
-    return bdrv_create(drv, filename, options);
-}
-
-int bdrv_create_new(BlockDriver *drv, const char* filename, QemuOpts *opts)
+int bdrv_create(BlockDriver *drv, const char* filename, QemuOpts *opts)
 {
     int ret;
 
@@ -464,7 +416,7 @@  out:
     return ret;
 }
 
-int bdrv_create_file_new(const char *filename, QemuOpts *opts)
+int bdrv_create_file(const char *filename, QemuOpts *opts)
 {
     BlockDriver *drv;
 
@@ -473,7 +425,7 @@  int bdrv_create_file_new(const char *filename, QemuOpts *opts)
         return -ENOENT;
     }
 
-    return bdrv_create_new(drv, filename, opts);
+    return bdrv_create(drv, filename, opts);
 }
 
 /*
@@ -1083,7 +1035,7 @@  int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
             qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, drv->format_name);
         }
 
-        ret = bdrv_create_new(bdrv_qcow2, tmp_filename, opts);
+        ret = bdrv_create(bdrv_qcow2, tmp_filename, opts);
         qemu_opts_del(opts);
         if (ret < 0) {
             goto fail;
@@ -4622,7 +4574,7 @@  void bdrv_img_create(const char *filename, const char *fmt,
         qemu_opts_print(opts);
         puts("");
     }
-    ret = bdrv_create_new(drv, filename, opts);
+    ret = bdrv_create(drv, filename, opts);
     if (ret < 0) {
         if (ret == -ENOTSUP) {
             error_setg(errp,"Formatting or formatting option not supported for "
diff --git a/block/cow.c b/block/cow.c
index 3a0d450..9d4da10 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -255,84 +255,7 @@  static void cow_close(BlockDriverState *bs)
 {
 }
 
-static int cow_create(const char *filename, QEMUOptionParameter *options)
-{
-    struct cow_header_v2 cow_header;
-    struct stat st;
-    int64_t image_sectors = 0;
-    const char *image_filename = NULL;
-    int ret;
-    BlockDriverState *cow_bs;
-
-    /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            image_sectors = options->value.n / 512;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-            image_filename = options->value.s;
-        }
-        options++;
-    }
-
-    ret = bdrv_create_file(filename, options);
-    if (ret < 0) {
-        return ret;
-    }
-
-    ret = bdrv_file_open(&cow_bs, filename, NULL, BDRV_O_RDWR);
-    if (ret < 0) {
-        return ret;
-    }
-
-    memset(&cow_header, 0, sizeof(cow_header));
-    cow_header.magic = cpu_to_be32(COW_MAGIC);
-    cow_header.version = cpu_to_be32(COW_VERSION);
-    if (image_filename) {
-        /* Note: if no file, we put a dummy mtime */
-        cow_header.mtime = cpu_to_be32(0);
-
-        if (stat(image_filename, &st) != 0) {
-            goto mtime_fail;
-        }
-        cow_header.mtime = cpu_to_be32(st.st_mtime);
-    mtime_fail:
-        pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file),
-                image_filename);
-    }
-    cow_header.sectorsize = cpu_to_be32(512);
-    cow_header.size = cpu_to_be64(image_sectors * 512);
-    ret = bdrv_pwrite(cow_bs, 0, &cow_header, sizeof(cow_header));
-    if (ret < 0) {
-        goto exit;
-    }
-
-    /* resize to include at least all the bitmap */
-    ret = bdrv_truncate(cow_bs,
-        sizeof(cow_header) + ((image_sectors + 7) >> 3));
-    if (ret < 0) {
-        goto exit;
-    }
-
-exit:
-    bdrv_delete(cow_bs);
-    return ret;
-}
-
-static QEMUOptionParameter cow_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    {
-        .name = BLOCK_OPT_BACKING_FILE,
-        .type = OPT_STRING,
-        .help = "File name of a base image"
-    },
-    { NULL }
-};
-
-static int cow_create_new(const char *filename, QemuOpts *opts)
+static int cow_create(const char *filename, QemuOpts *opts)
 {
     struct cow_header_v2 cow_header;
     struct stat st;
@@ -345,7 +268,7 @@  static int cow_create_new(const char *filename, QemuOpts *opts)
     image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
     image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 
-    ret = bdrv_create_file_new(filename, opts);
+    ret = bdrv_create_file(filename, opts);
     if (ret < 0) {
         goto finish;
     }
@@ -417,14 +340,12 @@  static BlockDriver bdrv_cow = {
     .bdrv_open      = cow_open,
     .bdrv_close     = cow_close,
     .bdrv_create    = cow_create,
-    .bdrv_create_new = cow_create_new,
     .bdrv_has_zero_init     = bdrv_has_zero_init_1,
 
     .bdrv_read              = cow_co_read,
     .bdrv_write             = cow_co_write,
     .bdrv_co_is_allocated   = cow_co_is_allocated,
 
-    .create_options = cow_create_options,
     .bdrv_create_opts       = &cow_create_opts,
 };
 
diff --git a/block/gluster.c b/block/gluster.c
index eb9d644..3a7a35a 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -365,49 +365,7 @@  out:
     return ret;
 }
 
-static int qemu_gluster_create(const char *filename,
-        QEMUOptionParameter *options)
-{
-    struct glfs *glfs;
-    struct glfs_fd *fd;
-    int ret = 0;
-    int64_t total_size = 0;
-    GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
-
-    glfs = qemu_gluster_init(gconf, filename);
-    if (!glfs) {
-        ret = -errno;
-        goto out;
-    }
-
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            total_size = options->value.n / BDRV_SECTOR_SIZE;
-        }
-        options++;
-    }
-
-    fd = glfs_creat(glfs, gconf->image,
-        O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR);
-    if (!fd) {
-        ret = -errno;
-    } else {
-        if (glfs_ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
-            ret = -errno;
-        }
-        if (glfs_close(fd) != 0) {
-            ret = -errno;
-        }
-    }
-out:
-    qemu_gluster_gconf_free(gconf);
-    if (glfs) {
-        glfs_fini(glfs);
-    }
-    return ret;
-}
-
-static int qemu_gluster_create_new(const char *filename, QemuOpts *opts)
+static int qemu_gluster_create(const char *filename, QemuOpts *opts)
 {
     struct glfs *glfs;
     struct glfs_fd *fd;
@@ -663,15 +621,6 @@  static int qemu_gluster_has_zero_init(BlockDriverState *bs)
     return 0;
 }
 
-static QEMUOptionParameter qemu_gluster_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    { NULL }
-};
-
 static QemuOptsList qemu_gluster_create_opts = {
     .name = "qemu-gluster-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
@@ -692,7 +641,6 @@  static BlockDriver bdrv_gluster = {
     .bdrv_file_open               = qemu_gluster_open,
     .bdrv_close                   = qemu_gluster_close,
     .bdrv_create                  = qemu_gluster_create,
-    .bdrv_create_new              = qemu_gluster_create_new,
     .bdrv_getlength               = qemu_gluster_getlength,
     .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
     .bdrv_truncate                = qemu_gluster_truncate,
@@ -703,7 +651,6 @@  static BlockDriver bdrv_gluster = {
 #ifdef CONFIG_GLUSTERFS_DISCARD
     .bdrv_aio_discard             = qemu_gluster_aio_discard,
 #endif
-    .create_options               = qemu_gluster_create_options,
     .bdrv_create_opts             = &qemu_gluster_create_opts,
 };
 
@@ -714,7 +661,6 @@  static BlockDriver bdrv_gluster_tcp = {
     .bdrv_file_open               = qemu_gluster_open,
     .bdrv_close                   = qemu_gluster_close,
     .bdrv_create                  = qemu_gluster_create,
-    .bdrv_create_new              = qemu_gluster_create_new,
     .bdrv_getlength               = qemu_gluster_getlength,
     .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
     .bdrv_truncate                = qemu_gluster_truncate,
@@ -725,7 +671,6 @@  static BlockDriver bdrv_gluster_tcp = {
 #ifdef CONFIG_GLUSTERFS_DISCARD
     .bdrv_aio_discard             = qemu_gluster_aio_discard,
 #endif
-    .create_options               = qemu_gluster_create_options,
     .bdrv_create_opts             = &qemu_gluster_create_opts,
 };
 
@@ -736,7 +681,6 @@  static BlockDriver bdrv_gluster_unix = {
     .bdrv_file_open               = qemu_gluster_open,
     .bdrv_close                   = qemu_gluster_close,
     .bdrv_create                  = qemu_gluster_create,
-    .bdrv_create_new              = qemu_gluster_create_new,
     .bdrv_getlength               = qemu_gluster_getlength,
     .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
     .bdrv_truncate                = qemu_gluster_truncate,
@@ -747,7 +691,6 @@  static BlockDriver bdrv_gluster_unix = {
 #ifdef CONFIG_GLUSTERFS_DISCARD
     .bdrv_aio_discard             = qemu_gluster_aio_discard,
 #endif
-    .create_options               = qemu_gluster_create_options,
     .bdrv_create_opts             = &qemu_gluster_create_opts,
 };
 
@@ -758,7 +701,6 @@  static BlockDriver bdrv_gluster_rdma = {
     .bdrv_file_open               = qemu_gluster_open,
     .bdrv_close                   = qemu_gluster_close,
     .bdrv_create                  = qemu_gluster_create,
-    .bdrv_create_new              = qemu_gluster_create_new,
     .bdrv_getlength               = qemu_gluster_getlength,
     .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
     .bdrv_truncate                = qemu_gluster_truncate,
@@ -769,7 +711,6 @@  static BlockDriver bdrv_gluster_rdma = {
 #ifdef CONFIG_GLUSTERFS_DISCARD
     .bdrv_aio_discard             = qemu_gluster_aio_discard,
 #endif
-    .create_options               = qemu_gluster_create_options,
     .bdrv_create_opts             = &qemu_gluster_create_opts,
 };
 
diff --git a/block/iscsi.c b/block/iscsi.c
index de2fd8c..2bdb306 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1245,67 +1245,7 @@  static int iscsi_has_zero_init(BlockDriverState *bs)
     return 0;
 }
 
-static int iscsi_create(const char *filename, QEMUOptionParameter *options)
-{
-    int ret = 0;
-    int64_t total_size = 0;
-    BlockDriverState bs;
-    IscsiLun *iscsilun = NULL;
-    QDict *bs_options;
-
-    memset(&bs, 0, sizeof(BlockDriverState));
-
-    /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, "size")) {
-            total_size = options->value.n / BDRV_SECTOR_SIZE;
-        }
-        options++;
-    }
-
-    bs.opaque = g_malloc0(sizeof(struct IscsiLun));
-    iscsilun = bs.opaque;
-
-    bs_options = qdict_new();
-    qdict_put(bs_options, "filename", qstring_from_str(filename));
-    ret = iscsi_open(&bs, bs_options, 0);
-    QDECREF(bs_options);
-
-    if (ret != 0) {
-        goto out;
-    }
-    if (iscsilun->nop_timer) {
-        qemu_del_timer(iscsilun->nop_timer);
-        qemu_free_timer(iscsilun->nop_timer);
-    }
-    if (iscsilun->type != TYPE_DISK) {
-        ret = -ENODEV;
-        goto out;
-    }
-    if (bs.total_sectors < total_size) {
-        ret = -ENOSPC;
-        goto out;
-    }
-
-    ret = 0;
-out:
-    if (iscsilun->iscsi != NULL) {
-        iscsi_destroy_context(iscsilun->iscsi);
-    }
-    g_free(bs.opaque);
-    return ret;
-}
-
-static QEMUOptionParameter iscsi_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    { NULL }
-};
-
-static int iscsi_create_new(const char *filename, QemuOpts *opts)
+static int iscsi_create(const char *filename, QemuOpts *opts)
 {
     int ret = 0;
     int64_t total_size = 0;
@@ -1372,8 +1312,6 @@  static BlockDriver bdrv_iscsi = {
     .bdrv_file_open  = iscsi_open,
     .bdrv_close      = iscsi_close,
     .bdrv_create     = iscsi_create,
-    .bdrv_create_new = iscsi_create_new,
-    .create_options  = iscsi_create_options,
     .bdrv_create_opts = &iscsi_create_opts,
 
     .bdrv_getlength  = iscsi_getlength,
diff --git a/block/qcow.c b/block/qcow.c
index 5b572d3..8718c0d 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -651,111 +651,7 @@  static void qcow_close(BlockDriverState *bs)
     error_free(s->migration_blocker);
 }
 
-static int qcow_create(const char *filename, QEMUOptionParameter *options)
-{
-    int header_size, backing_filename_len, l1_size, shift, i;
-    QCowHeader header;
-    uint8_t *tmp;
-    int64_t total_size = 0;
-    const char *backing_file = NULL;
-    int flags = 0;
-    int ret;
-    BlockDriverState *qcow_bs;
-
-    /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            total_size = options->value.n / 512;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-            backing_file = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
-            flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
-        }
-        options++;
-    }
-
-    ret = bdrv_create_file(filename, options);
-    if (ret < 0) {
-        return ret;
-    }
-
-    ret = bdrv_file_open(&qcow_bs, filename, NULL, BDRV_O_RDWR);
-    if (ret < 0) {
-        return ret;
-    }
-
-    ret = bdrv_truncate(qcow_bs, 0);
-    if (ret < 0) {
-        goto exit;
-    }
-
-    memset(&header, 0, sizeof(header));
-    header.magic = cpu_to_be32(QCOW_MAGIC);
-    header.version = cpu_to_be32(QCOW_VERSION);
-    header.size = cpu_to_be64(total_size * 512);
-    header_size = sizeof(header);
-    backing_filename_len = 0;
-    if (backing_file) {
-        if (strcmp(backing_file, "fat:")) {
-            header.backing_file_offset = cpu_to_be64(header_size);
-            backing_filename_len = strlen(backing_file);
-            header.backing_file_size = cpu_to_be32(backing_filename_len);
-            header_size += backing_filename_len;
-        } else {
-            /* special backing file for vvfat */
-            backing_file = NULL;
-        }
-        header.cluster_bits = 9; /* 512 byte cluster to avoid copying
-                                    unmodifyed sectors */
-        header.l2_bits = 12; /* 32 KB L2 tables */
-    } else {
-        header.cluster_bits = 12; /* 4 KB clusters */
-        header.l2_bits = 9; /* 4 KB L2 tables */
-    }
-    header_size = (header_size + 7) & ~7;
-    shift = header.cluster_bits + header.l2_bits;
-    l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
-
-    header.l1_table_offset = cpu_to_be64(header_size);
-    if (flags & BLOCK_FLAG_ENCRYPT) {
-        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
-    } else {
-        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
-    }
-
-    /* write all the data */
-    ret = bdrv_pwrite(qcow_bs, 0, &header, sizeof(header));
-    if (ret != sizeof(header)) {
-        goto exit;
-    }
-
-    if (backing_file) {
-        ret = bdrv_pwrite(qcow_bs, sizeof(header),
-            backing_file, backing_filename_len);
-        if (ret != backing_filename_len) {
-            goto exit;
-        }
-    }
-
-    tmp = g_malloc0(BDRV_SECTOR_SIZE);
-    for (i = 0; i < ((sizeof(uint64_t)*l1_size + BDRV_SECTOR_SIZE - 1)/
-        BDRV_SECTOR_SIZE); i++) {
-        ret = bdrv_pwrite(qcow_bs, header_size +
-            BDRV_SECTOR_SIZE*i, tmp, BDRV_SECTOR_SIZE);
-        if (ret != BDRV_SECTOR_SIZE) {
-            g_free(tmp);
-            goto exit;
-        }
-    }
-
-    g_free(tmp);
-    ret = 0;
-exit:
-    bdrv_delete(qcow_bs);
-    return ret;
-}
-
-static int qcow_create_new(const char *filename, QemuOpts *opts)
+static int qcow_create(const char *filename, QemuOpts *opts)
 {
     int header_size, backing_filename_len, l1_size, shift, i;
     QCowHeader header;
@@ -773,7 +669,7 @@  static int qcow_create_new(const char *filename, QemuOpts *opts)
         flags |= BLOCK_FLAG_ENCRYPT;
     }
 
-    ret = bdrv_create_file_new(filename, opts);
+    ret = bdrv_create_file(filename, opts);
     if (ret < 0) {
         goto finish;
     }
@@ -989,25 +885,6 @@  static QemuOptsList qcow_create_opts = {
     }
 };
 
-static QEMUOptionParameter qcow_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    {
-        .name = BLOCK_OPT_BACKING_FILE,
-        .type = OPT_STRING,
-        .help = "File name of a base image"
-    },
-    {
-        .name = BLOCK_OPT_ENCRYPT,
-        .type = OPT_FLAG,
-        .help = "Encrypt the image"
-    },
-    { NULL }
-};
-
 static BlockDriver bdrv_qcow = {
     .format_name	= "qcow",
     .instance_size	= sizeof(BDRVQcowState),
@@ -1016,7 +893,6 @@  static BlockDriver bdrv_qcow = {
     .bdrv_close		= qcow_close,
     .bdrv_reopen_prepare = qcow_reopen_prepare,
     .bdrv_create	= qcow_create,
-    .bdrv_create_new = qcow_create_new,
     .bdrv_has_zero_init     = bdrv_has_zero_init_1,
 
     .bdrv_co_readv          = qcow_co_readv,
@@ -1028,7 +904,6 @@  static BlockDriver bdrv_qcow = {
     .bdrv_write_compressed  = qcow_write_compressed,
     .bdrv_get_info          = qcow_get_info,
 
-    .create_options = qcow_create_options,
     .bdrv_create_opts = &qcow_create_opts,
 };
 
diff --git a/block/qcow2.c b/block/qcow2.c
index 1c3249d..b876d96 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1258,212 +1258,9 @@  static int preallocate(BlockDriverState *bs)
 }
 
 static int qcow2_create2(const char *filename, int64_t total_size,
-                         const char *backing_file, const char *backing_format,
+                         char *backing_file, char *backing_format,
                          int flags, size_t cluster_size, int prealloc,
-                         QEMUOptionParameter *options, int version)
-{
-    /* Calculate cluster_bits */
-    int cluster_bits;
-    cluster_bits = ffs(cluster_size) - 1;
-    if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
-        (1 << cluster_bits) != cluster_size)
-    {
-        error_report(
-            "Cluster size must be a power of two between %d and %dk",
-            1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
-        return -EINVAL;
-    }
-
-    /*
-     * Open the image file and write a minimal qcow2 header.
-     *
-     * We keep things simple and start with a zero-sized image. We also
-     * do without refcount blocks or a L1 table for now. We'll fix the
-     * inconsistency later.
-     *
-     * We do need a refcount table because growing the refcount table means
-     * allocating two new refcount blocks - the seconds of which would be at
-     * 2 GB for 64k clusters, and we don't want to have a 2 GB initial file
-     * size for any qcow2 image.
-     */
-    BlockDriverState* bs;
-    QCowHeader header;
-    uint8_t* refcount_table;
-    int ret;
-
-    ret = bdrv_create_file(filename, options);
-    if (ret < 0) {
-        return ret;
-    }
-
-    ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR);
-    if (ret < 0) {
-        return ret;
-    }
-
-    /* Write the header */
-    memset(&header, 0, sizeof(header));
-    header.magic = cpu_to_be32(QCOW_MAGIC);
-    header.version = cpu_to_be32(version);
-    header.cluster_bits = cpu_to_be32(cluster_bits);
-    header.size = cpu_to_be64(0);
-    header.l1_table_offset = cpu_to_be64(0);
-    header.l1_size = cpu_to_be32(0);
-    header.refcount_table_offset = cpu_to_be64(cluster_size);
-    header.refcount_table_clusters = cpu_to_be32(1);
-    header.refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT);
-    header.header_length = cpu_to_be32(sizeof(header));
-
-    if (flags & BLOCK_FLAG_ENCRYPT) {
-        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
-    } else {
-        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
-    }
-
-    if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) {
-        header.compatible_features |=
-            cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS);
-    }
-
-    ret = bdrv_pwrite(bs, 0, &header, sizeof(header));
-    if (ret < 0) {
-        goto out;
-    }
-
-    /* Write an empty refcount table */
-    refcount_table = g_malloc0(cluster_size);
-    ret = bdrv_pwrite(bs, cluster_size, refcount_table, cluster_size);
-    g_free(refcount_table);
-
-    if (ret < 0) {
-        goto out;
-    }
-
-    bdrv_close(bs);
-
-    /*
-     * And now open the image and make it consistent first (i.e. increase the
-     * refcount of the cluster that is occupied by the header and the refcount
-     * table)
-     */
-    BlockDriver* drv = bdrv_find_format("qcow2");
-    assert(drv != NULL);
-    ret = bdrv_open(bs, filename, NULL,
-        BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv);
-    if (ret < 0) {
-        goto out;
-    }
-
-    ret = qcow2_alloc_clusters(bs, 2 * cluster_size);
-    if (ret < 0) {
-        goto out;
-
-    } else if (ret != 0) {
-        error_report("Huh, first cluster in empty image is already in use?");
-        abort();
-    }
-
-    /* Okay, now that we have a valid image, let's give it the right size */
-    ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE);
-    if (ret < 0) {
-        goto out;
-    }
-
-    /* Want a backing file? There you go.*/
-    if (backing_file) {
-        ret = bdrv_change_backing_file(bs, backing_file, backing_format);
-        if (ret < 0) {
-            goto out;
-        }
-    }
-
-    /* And if we're supposed to preallocate metadata, do that now */
-    if (prealloc) {
-        BDRVQcowState *s = bs->opaque;
-        qemu_co_mutex_lock(&s->lock);
-        ret = preallocate(bs);
-        qemu_co_mutex_unlock(&s->lock);
-        if (ret < 0) {
-            goto out;
-        }
-    }
-
-    ret = 0;
-out:
-    bdrv_delete(bs);
-    return ret;
-}
-
-static int qcow2_create(const char *filename, QEMUOptionParameter *options)
-{
-    const char *backing_file = NULL;
-    const char *backing_fmt = NULL;
-    uint64_t sectors = 0;
-    int flags = 0;
-    size_t cluster_size = DEFAULT_CLUSTER_SIZE;
-    int prealloc = 0;
-    int version = 2;
-
-    /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            sectors = options->value.n / 512;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-            backing_file = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
-            backing_fmt = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
-            flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
-        } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
-            if (options->value.n) {
-                cluster_size = options->value.n;
-            }
-        } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
-            if (!options->value.s || !strcmp(options->value.s, "off")) {
-                prealloc = 0;
-            } else if (!strcmp(options->value.s, "metadata")) {
-                prealloc = 1;
-            } else {
-                fprintf(stderr, "Invalid preallocation mode: '%s'\n",
-                    options->value.s);
-                return -EINVAL;
-            }
-        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) {
-            if (!options->value.s || !strcmp(options->value.s, "0.10")) {
-                version = 2;
-            } else if (!strcmp(options->value.s, "1.1")) {
-                version = 3;
-            } else {
-                fprintf(stderr, "Invalid compatibility level: '%s'\n",
-                    options->value.s);
-                return -EINVAL;
-            }
-        } else if (!strcmp(options->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
-            flags |= options->value.n ? BLOCK_FLAG_LAZY_REFCOUNTS : 0;
-        }
-        options++;
-    }
-
-    if (backing_file && prealloc) {
-        fprintf(stderr, "Backing file and preallocation cannot be used at "
-            "the same time\n");
-        return -EINVAL;
-    }
-
-    if (version < 3 && (flags & BLOCK_FLAG_LAZY_REFCOUNTS)) {
-        fprintf(stderr, "Lazy refcounts only supported with compatibility "
-                "level 1.1 and above (use compat=1.1 or greater)\n");
-        return -EINVAL;
-    }
-
-    return qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
-                         cluster_size, prealloc, options, version);
-}
-
-static int qcow2_create2_new(const char *filename, int64_t total_size,
-                             char *backing_file, char *backing_format,
-                             int flags, size_t cluster_size, int prealloc,
-                             QemuOpts *opts, int version)
+                         QemuOpts *opts, int version)
 {
     /* Calculate cluster_bits */
     int cluster_bits;
@@ -1494,7 +1291,7 @@  static int qcow2_create2_new(const char *filename, int64_t total_size,
     QCowHeader header;
     uint8_t *refcount_table;
 
-    ret = bdrv_create_file_new(filename, opts);
+    ret = bdrv_create_file(filename, opts);
     if (ret < 0) {
         goto finish;
     }
@@ -1600,7 +1397,7 @@  finish:
     return ret;
 }
 
-static int qcow2_create_new(const char *filename, QemuOpts *opts)
+static int qcow2_create(const char *filename, QemuOpts *opts)
 {
     char *backing_file = NULL;
     char *backing_fmt = NULL;
@@ -1663,8 +1460,8 @@  static int qcow2_create_new(const char *filename, QemuOpts *opts)
         goto finish;
     }
 
-    return qcow2_create2_new(filename, sectors, backing_file, backing_fmt, flags,
-                             cluster_size, prealloc, opts, version);
+    return qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
+                         cluster_size, prealloc, opts, version);
 finish:
     g_free(backing_file);
     g_free(backing_fmt);
@@ -1944,51 +1741,6 @@  static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
     return ret;
 }
 
-static QEMUOptionParameter qcow2_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    {
-        .name = BLOCK_OPT_COMPAT_LEVEL,
-        .type = OPT_STRING,
-        .help = "Compatibility level (0.10 or 1.1)"
-    },
-    {
-        .name = BLOCK_OPT_BACKING_FILE,
-        .type = OPT_STRING,
-        .help = "File name of a base image"
-    },
-    {
-        .name = BLOCK_OPT_BACKING_FMT,
-        .type = OPT_STRING,
-        .help = "Image format of the base image"
-    },
-    {
-        .name = BLOCK_OPT_ENCRYPT,
-        .type = OPT_FLAG,
-        .help = "Encrypt the image"
-    },
-    {
-        .name = BLOCK_OPT_CLUSTER_SIZE,
-        .type = OPT_SIZE,
-        .help = "qcow2 cluster size",
-        .value = { .n = DEFAULT_CLUSTER_SIZE },
-    },
-    {
-        .name = BLOCK_OPT_PREALLOC,
-        .type = OPT_STRING,
-        .help = "Preallocation mode (allowed values: off, metadata)"
-    },
-    {
-        .name = BLOCK_OPT_LAZY_REFCOUNTS,
-        .type = OPT_FLAG,
-        .help = "Postpone refcount updates",
-    },
-    { NULL }
-};
-
 static QemuOptsList qcow2_create_opts = {
     .name = "qcow2-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
@@ -2048,7 +1800,6 @@  static BlockDriver bdrv_qcow2 = {
     .bdrv_close         = qcow2_close,
     .bdrv_reopen_prepare  = qcow2_reopen_prepare,
     .bdrv_create        = qcow2_create,
-    .bdrv_create_new    = qcow2_create_new,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_co_is_allocated = qcow2_co_is_allocated,
     .bdrv_set_key       = qcow2_set_key,
@@ -2077,7 +1828,6 @@  static BlockDriver bdrv_qcow2 = {
 
     .bdrv_invalidate_cache      = qcow2_invalidate_cache,
 
-    .create_options = qcow2_create_options,
     .bdrv_create_opts = &qcow2_create_opts,
     .bdrv_check = qcow2_check,
 };
diff --git a/block/qed.c b/block/qed.c
index 348695f..6b02c47 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -603,126 +603,7 @@  out:
     return ret;
 }
 
-static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options)
-{
-    uint64_t image_size = 0;
-    uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
-    uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
-    const char *backing_file = NULL;
-    const char *backing_fmt = NULL;
-
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            image_size = options->value.n;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-            backing_file = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
-            backing_fmt = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
-            if (options->value.n) {
-                cluster_size = options->value.n;
-            }
-        } else if (!strcmp(options->name, BLOCK_OPT_TABLE_SIZE)) {
-            if (options->value.n) {
-                table_size = options->value.n;
-            }
-        }
-        options++;
-    }
-
-    if (!qed_is_cluster_size_valid(cluster_size)) {
-        fprintf(stderr, "QED cluster size must be within range [%u, %u] and power of 2\n",
-                QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE);
-        return -EINVAL;
-    }
-    if (!qed_is_table_size_valid(table_size)) {
-        fprintf(stderr, "QED table size must be within range [%u, %u] and power of 2\n",
-                QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE);
-        return -EINVAL;
-    }
-    if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) {
-        fprintf(stderr, "QED image size must be a non-zero multiple of "
-                        "cluster size and less than %" PRIu64 " bytes\n",
-                qed_max_image_size(cluster_size, table_size));
-        return -EINVAL;
-    }
-
-    return qed_create(filename, cluster_size, image_size, table_size,
-                      backing_file, backing_fmt);
-}
-
-static int qed_create_new(const char *filename, uint32_t cluster_size,
-                          uint64_t image_size, uint32_t table_size,
-                          const char *backing_file, const char *backing_fmt)
-{
-    QEDHeader header = {
-        .magic = QED_MAGIC,
-        .cluster_size = cluster_size,
-        .table_size = table_size,
-        .header_size = 1,
-        .features = 0,
-        .compat_features = 0,
-        .l1_table_offset = cluster_size,
-        .image_size = image_size,
-    };
-    QEDHeader le_header;
-    uint8_t *l1_table = NULL;
-    size_t l1_size = header.cluster_size * header.table_size;
-    int ret = 0;
-    BlockDriverState *bs = NULL;
-
-    ret = bdrv_create_file_new(filename, NULL);
-    if (ret < 0) {
-        goto finish;
-    }
-
-    ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB);
-    if (ret < 0) {
-        goto finish;
-    }
-
-    /* File must start empty and grow, check truncate is supported */
-    ret = bdrv_truncate(bs, 0);
-    if (ret < 0) {
-        goto out;
-    }
-
-    if (backing_file) {
-        header.features |= QED_F_BACKING_FILE;
-        header.backing_filename_offset = sizeof(le_header);
-        header.backing_filename_size = strlen(backing_file);
-
-        if (qed_fmt_is_raw(backing_fmt)) {
-            header.features |= QED_F_BACKING_FORMAT_NO_PROBE;
-        }
-    }
-
-    qed_header_cpu_to_le(&header, &le_header);
-    ret = bdrv_pwrite(bs, 0, &le_header, sizeof(le_header));
-    if (ret < 0) {
-        goto out;
-    }
-    ret = bdrv_pwrite(bs, sizeof(le_header), backing_file,
-                      header.backing_filename_size);
-    if (ret < 0) {
-        goto out;
-    }
-
-    l1_table = g_malloc0(l1_size);
-    ret = bdrv_pwrite(bs, header.l1_table_offset, l1_table, l1_size);
-    if (ret < 0) {
-        goto out;
-    }
-
-    ret = 0; /* success */
-out:
-    g_free(l1_table);
-    bdrv_delete(bs);
-finish:
-    return ret;
-}
-
-static int bdrv_qed_create_new(const char *filename, QemuOpts *opts)
+static int bdrv_qed_create(const char *filename, QemuOpts *opts)
 {
     uint64_t image_size = 0;
     uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
@@ -760,7 +641,7 @@  static int bdrv_qed_create_new(const char *filename, QemuOpts *opts)
         goto finish;
     }
 
-    ret = qed_create_new(filename, cluster_size, image_size, table_size,
+    ret = qed_create(filename, cluster_size, image_size, table_size,
                          backing_file, backing_fmt);
 
 finish:
@@ -1654,32 +1535,6 @@  static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
     return qed_check(s, result, !!fix);
 }
 
-static QEMUOptionParameter qed_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size (in bytes)"
-    }, {
-        .name = BLOCK_OPT_BACKING_FILE,
-        .type = OPT_STRING,
-        .help = "File name of a base image"
-    }, {
-        .name = BLOCK_OPT_BACKING_FMT,
-        .type = OPT_STRING,
-        .help = "Image format of the base image"
-    }, {
-        .name = BLOCK_OPT_CLUSTER_SIZE,
-        .type = OPT_SIZE,
-        .help = "Cluster size (in bytes)",
-        .value = { .n = QED_DEFAULT_CLUSTER_SIZE },
-    }, {
-        .name = BLOCK_OPT_TABLE_SIZE,
-        .type = OPT_SIZE,
-        .help = "L1/L2 table size (in clusters)"
-    },
-    { /* end of list */ }
-};
-
 static QemuOptsList qed_create_opts = {
     .name = "qed-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(qed_create_opts.head),
@@ -1717,7 +1572,6 @@  static QemuOptsList qed_create_opts = {
 static BlockDriver bdrv_qed = {
     .format_name              = "qed",
     .instance_size            = sizeof(BDRVQEDState),
-    .create_options           = qed_create_options,
     .bdrv_create_opts         = &qed_create_opts,
 
     .bdrv_probe               = bdrv_qed_probe,
@@ -1726,7 +1580,6 @@  static BlockDriver bdrv_qed = {
     .bdrv_close               = bdrv_qed_close,
     .bdrv_reopen_prepare      = bdrv_qed_reopen_prepare,
     .bdrv_create              = bdrv_qed_create,
-    .bdrv_create_new          = bdrv_qed_create_new,
     .bdrv_has_zero_init       = bdrv_has_zero_init_1,
     .bdrv_co_is_allocated     = bdrv_qed_co_is_allocated,
     .bdrv_make_empty          = bdrv_qed_make_empty,
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 528b3d1..a677bc5 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1040,36 +1040,7 @@  static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
     return (int64_t)st.st_blocks * 512;
 }
 
-static int raw_create(const char *filename, QEMUOptionParameter *options)
-{
-    int fd;
-    int result = 0;
-    int64_t total_size = 0;
-
-    /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            total_size = options->value.n / BDRV_SECTOR_SIZE;
-        }
-        options++;
-    }
-
-    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
-                   0644);
-    if (fd < 0) {
-        result = -errno;
-    } else {
-        if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
-            result = -errno;
-        }
-        if (qemu_close(fd) != 0) {
-            result = -errno;
-        }
-    }
-    return result;
-}
-
-static int raw_create_new(const char *filename, QemuOpts *opts)
+static int raw_create(const char *filename, QemuOpts *opts)
 {
     int fd;
     int result = 0;
@@ -1202,15 +1173,6 @@  static coroutine_fn BlockDriverAIOCB *raw_aio_discard(BlockDriverState *bs,
                        cb, opaque, QEMU_AIO_DISCARD);
 }
 
-static QEMUOptionParameter raw_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    { NULL }
-};
-
 static QemuOptsList raw_create_opts = {
     .name = "raw-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
@@ -1235,7 +1197,6 @@  static BlockDriver bdrv_file = {
     .bdrv_reopen_abort = raw_reopen_abort,
     .bdrv_close = raw_close,
     .bdrv_create = raw_create,
-    .bdrv_create_new = raw_create_new,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_co_is_allocated = raw_co_is_allocated,
 
@@ -1248,8 +1209,6 @@  static BlockDriver bdrv_file = {
     .bdrv_getlength = raw_getlength,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
-
-    .create_options = raw_create_options,
     .bdrv_create_opts = &raw_create_opts,
 };
 
@@ -1536,7 +1495,7 @@  static coroutine_fn BlockDriverAIOCB *hdev_aio_discard(BlockDriverState *bs,
                        cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
 }
 
-static int hdev_create(const char *filename, QEMUOptionParameter *options)
+static int hdev_create(const char *filename, QemuOpts *opts)
 {
     int fd;
     int ret = 0;
@@ -1544,12 +1503,8 @@  static int hdev_create(const char *filename, QEMUOptionParameter *options)
     int64_t total_size = 0;
 
     /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, "size")) {
-            total_size = options->value.n / BDRV_SECTOR_SIZE;
-        }
-        options++;
-    }
+    total_size =
+        qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
 
     fd = qemu_open(filename, O_WRONLY | O_BINARY);
     if (fd < 0)
@@ -1566,33 +1521,6 @@  static int hdev_create(const char *filename, QEMUOptionParameter *options)
     return ret;
 }
 
-static int hdev_create_new(const char *filename, QemuOpts *opts)
-{
-    int fd;
-    int ret = 0;
-    struct stat stat_buf;
-    int64_t total_size = 0;
-
-    total_size =
-        qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
-
-    fd = qemu_open(filename, O_WRONLY | O_BINARY);
-    if (fd < 0) {
-        return -errno;
-    }
-
-    if (fstat(fd, &stat_buf) < 0) {
-        ret = -errno;
-    } else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode)) {
-        ret = -ENODEV;
-    } else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE) {
-        ret = -ENOSPC;
-    }
-
-    qemu_close(fd);
-    return ret;
-}
-
 static BlockDriver bdrv_host_device = {
     .format_name        = "host_device",
     .protocol_name        = "host_device",
@@ -1604,8 +1532,6 @@  static BlockDriver bdrv_host_device = {
     .bdrv_reopen_commit  = raw_reopen_commit,
     .bdrv_reopen_abort   = raw_reopen_abort,
     .bdrv_create        = hdev_create,
-    .bdrv_create_new    = hdev_create_new,
-    .create_options     = raw_create_options,
     .bdrv_create_opts = &raw_create_opts,
 
     .bdrv_aio_readv	= raw_aio_readv,
@@ -1730,9 +1656,7 @@  static BlockDriver bdrv_host_floppy = {
     .bdrv_reopen_commit  = raw_reopen_commit,
     .bdrv_reopen_abort   = raw_reopen_abort,
     .bdrv_create        = hdev_create,
-    .bdrv_create_new    = hdev_create_new,
-    .create_options     = raw_create_options,
-    .bdrv_create_opts = &raw_create_opts,
+    .bdrv_create_opts   =  &raw_create_opts,
 
     .bdrv_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
@@ -1833,9 +1757,7 @@  static BlockDriver bdrv_host_cdrom = {
     .bdrv_reopen_commit  = raw_reopen_commit,
     .bdrv_reopen_abort   = raw_reopen_abort,
     .bdrv_create        = hdev_create,
-    .bdrv_create_new    = hdev_create_new,
-    .create_options     = raw_create_options,
-    .bdrv_create_opts = &raw_create_opts,
+    .bdrv_create_opts   = &raw_create_opts,
 
     .bdrv_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
@@ -1956,7 +1878,6 @@  static BlockDriver bdrv_host_cdrom = {
     .bdrv_reopen_commit  = raw_reopen_commit,
     .bdrv_reopen_abort   = raw_reopen_abort,
     .bdrv_create        = hdev_create,
-    .bdrv_create_new    = hdev_create_new,
     .create_options     = raw_create_options,
     .bdrv_create_opts = &raw_create_opts
 
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 78efc63..4a6afbd 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -420,40 +420,7 @@  static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
     return st.st_size;
 }
 
-static int raw_create(const char *filename, QEMUOptionParameter *options)
-{
-    int fd;
-    int64_t total_size = 0;
-
-    /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            total_size = options->value.n / 512;
-        }
-        options++;
-    }
-
-    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
-                   0644);
-    if (fd < 0)
-        return -EIO;
-    set_sparse(fd);
-    ftruncate(fd, total_size * 512);
-    qemu_close(fd);
-    return 0;
-}
-
-static QEMUOptionParameter raw_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    { NULL }
-};
-
-
-static int raw_create_new(const char *filename, QemuOpts *opts)
+static int raw_create(const char *filename, QemuOpts *opts)
 {
     int fd;
     int64_t total_size = 0;
@@ -493,7 +460,6 @@  static BlockDriver bdrv_file = {
     .bdrv_file_open	= raw_open,
     .bdrv_close		= raw_close,
     .bdrv_create	= raw_create,
-    .bdrv_create_new = raw_create_new,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
 
     .bdrv_aio_readv     = raw_aio_readv,
@@ -505,7 +471,6 @@  static BlockDriver bdrv_file = {
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
-    .create_options = raw_create_options,
     .bdrv_create_opts   = &raw_create_opts,
 };
 
diff --git a/block/raw.c b/block/raw.c
index 7636f6b..2ebe467 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -125,23 +125,9 @@  static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
    return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
 }
 
-static int raw_create(const char *filename, QEMUOptionParameter *options)
+static int raw_create(const char *filename, QemuOpts *opts)
 {
-    return bdrv_create_file(filename, options);
-}
-
-static QEMUOptionParameter raw_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    { NULL }
-};
-
-static int raw_create_new(const char *filename, QemuOpts *opts)
-{
-    return bdrv_create_file_new(filename, opts);
+    return bdrv_create_file(filename, opts);
 }
 
 static QemuOptsList raw_create_opts = {
@@ -198,8 +184,6 @@  static BlockDriver bdrv_raw = {
     .bdrv_aio_ioctl     = raw_aio_ioctl,
 
     .bdrv_create        = raw_create,
-    .bdrv_create_new    = raw_create_new,
-    .create_options     = raw_create_options,
     .bdrv_create_opts   = &raw_create_opts,
     .bdrv_has_zero_init = raw_has_zero_init,
 };
diff --git a/block/rbd.c b/block/rbd.c
index 4d5897c..b090738 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -288,87 +288,7 @@  static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
     return ret;
 }
 
-static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options)
-{
-    int64_t bytes = 0;
-    int64_t objsize;
-    int obj_order = 0;
-    char pool[RBD_MAX_POOL_NAME_SIZE];
-    char name[RBD_MAX_IMAGE_NAME_SIZE];
-    char snap_buf[RBD_MAX_SNAP_NAME_SIZE];
-    char conf[RBD_MAX_CONF_SIZE];
-    char clientname_buf[RBD_MAX_CONF_SIZE];
-    char *clientname;
-    rados_t cluster;
-    rados_ioctx_t io_ctx;
-    int ret;
-
-    if (qemu_rbd_parsename(filename, pool, sizeof(pool),
-                           snap_buf, sizeof(snap_buf),
-                           name, sizeof(name),
-                           conf, sizeof(conf)) < 0) {
-        return -EINVAL;
-    }
-
-    /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            bytes = options->value.n;
-        } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
-            if (options->value.n) {
-                objsize = options->value.n;
-                if ((objsize - 1) & objsize) {    /* not a power of 2? */
-                    error_report("obj size needs to be power of 2");
-                    return -EINVAL;
-                }
-                if (objsize < 4096) {
-                    error_report("obj size too small");
-                    return -EINVAL;
-                }
-                obj_order = ffs(objsize) - 1;
-            }
-        }
-        options++;
-    }
-
-    clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
-    if (rados_create(&cluster, clientname) < 0) {
-        error_report("error initializing");
-        return -EIO;
-    }
-
-    if (strstr(conf, "conf=") == NULL) {
-        /* try default location, but ignore failure */
-        rados_conf_read_file(cluster, NULL);
-    }
-
-    if (conf[0] != '\0' &&
-        qemu_rbd_set_conf(cluster, conf) < 0) {
-        error_report("error setting config options");
-        rados_shutdown(cluster);
-        return -EIO;
-    }
-
-    if (rados_connect(cluster) < 0) {
-        error_report("error connecting");
-        rados_shutdown(cluster);
-        return -EIO;
-    }
-
-    if (rados_ioctx_create(cluster, pool, &io_ctx) < 0) {
-        error_report("error opening pool %s", pool);
-        rados_shutdown(cluster);
-        return -EIO;
-    }
-
-    ret = rbd_create(io_ctx, name, bytes, &obj_order);
-    rados_ioctx_destroy(io_ctx);
-    rados_shutdown(cluster);
-
-    return ret;
-}
-
-static int qemu_rbd_create_new(const char *filename, QemuOpts *opts)
+static int qemu_rbd_create(const char *filename, QemuOpts *opts)
 {
     int64_t bytes = 0;
     int64_t objsize;
@@ -1050,20 +970,6 @@  static BlockDriverAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs,
 }
 #endif
 
-static QEMUOptionParameter qemu_rbd_create_options[] = {
-    {
-     .name = BLOCK_OPT_SIZE,
-     .type = OPT_SIZE,
-     .help = "Virtual disk size"
-    },
-    {
-     .name = BLOCK_OPT_CLUSTER_SIZE,
-     .type = OPT_SIZE,
-     .help = "RBD object size"
-    },
-    {NULL}
-};
-
 static QemuOptsList qemu_rbd_create_opts = {
     .name = "rbd-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_rbd_create_opts.head),
@@ -1089,10 +995,8 @@  static BlockDriver bdrv_rbd = {
     .bdrv_file_open     = qemu_rbd_open,
     .bdrv_close         = qemu_rbd_close,
     .bdrv_create        = qemu_rbd_create,
-    .bdrv_create_new    = qemu_rbd_create_new,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_get_info      = qemu_rbd_getinfo,
-    .create_options     = qemu_rbd_create_options,
     .bdrv_create_opts   = &qemu_rbd_create_opts,
     .bdrv_getlength     = qemu_rbd_getlength,
     .bdrv_truncate      = qemu_rbd_truncate,
diff --git a/block/sheepdog.c b/block/sheepdog.c
index b09b4fa..52e59c6 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1454,99 +1454,7 @@  out:
     return ret;
 }
 
-static int sd_create(const char *filename, QEMUOptionParameter *options)
-{
-    int ret = 0;
-    uint32_t vid = 0, base_vid = 0;
-    int64_t vdi_size = 0;
-    char *backing_file = NULL;
-    BDRVSheepdogState *s;
-    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
-    uint32_t snapid;
-    bool prealloc = false;
-
-    s = g_malloc0(sizeof(BDRVSheepdogState));
-
-    memset(vdi, 0, sizeof(vdi));
-    memset(tag, 0, sizeof(tag));
-    if (strstr(filename, "://")) {
-        ret = sd_parse_uri(s, filename, vdi, &snapid, tag);
-    } else {
-        ret = parse_vdiname(s, filename, vdi, &snapid, tag);
-    }
-    if (ret < 0) {
-        goto out;
-    }
-
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            vdi_size = options->value.n;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-            backing_file = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
-            if (!options->value.s || !strcmp(options->value.s, "off")) {
-                prealloc = false;
-            } else if (!strcmp(options->value.s, "full")) {
-                prealloc = true;
-            } else {
-                error_report("Invalid preallocation mode: '%s'",
-                             options->value.s);
-                ret = -EINVAL;
-                goto out;
-            }
-        }
-        options++;
-    }
-
-    if (vdi_size > SD_MAX_VDI_SIZE) {
-        error_report("too big image size");
-        ret = -EINVAL;
-        goto out;
-    }
-
-    if (backing_file) {
-        BlockDriverState *bs;
-        BDRVSheepdogState *s;
-        BlockDriver *drv;
-
-        /* Currently, only Sheepdog backing image is supported. */
-        drv = bdrv_find_protocol(backing_file, true);
-        if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
-            error_report("backing_file must be a sheepdog image");
-            ret = -EINVAL;
-            goto out;
-        }
-
-        ret = bdrv_file_open(&bs, backing_file, NULL, 0);
-        if (ret < 0) {
-            goto out;
-        }
-
-        s = bs->opaque;
-
-        if (!is_snapshot(&s->inode)) {
-            error_report("cannot clone from a non snapshot vdi");
-            bdrv_delete(bs);
-            ret = -EINVAL;
-            goto out;
-        }
-
-        base_vid = s->inode.vdi_id;
-        bdrv_delete(bs);
-    }
-
-    ret = do_sd_create(s, vdi, vdi_size, base_vid, &vid, 0);
-    if (!prealloc || ret) {
-        goto out;
-    }
-
-    ret = sd_prealloc(filename);
-out:
-    g_free(s);
-    return ret;
-}
-
-static int sd_create_new(const char *filename, QemuOpts *opts)
+static int sd_create(const char *filename, QemuOpts *opts)
 {
     int ret = 0;
     uint32_t vid = 0, base_vid = 0;
@@ -2407,25 +2315,6 @@  sd_co_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
     return ret;
 }
 
-static QEMUOptionParameter sd_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    {
-        .name = BLOCK_OPT_BACKING_FILE,
-        .type = OPT_STRING,
-        .help = "File name of a base image"
-    },
-    {
-        .name = BLOCK_OPT_PREALLOC,
-        .type = OPT_STRING,
-        .help = "Preallocation mode (allowed values: off, full)"
-    },
-    { NULL }
-};
-
 static QemuOptsList sd_create_opts = {
     .name = "sheepdog-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(sd_create_opts.head),
@@ -2456,7 +2345,6 @@  static BlockDriver bdrv_sheepdog = {
     .bdrv_file_open = sd_open,
     .bdrv_close     = sd_close,
     .bdrv_create    = sd_create,
-    .bdrv_create_new = sd_create_new,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_getlength = sd_getlength,
     .bdrv_truncate  = sd_truncate,
@@ -2475,7 +2363,6 @@  static BlockDriver bdrv_sheepdog = {
     .bdrv_save_vmstate  = sd_save_vmstate,
     .bdrv_load_vmstate  = sd_load_vmstate,
 
-    .create_options = sd_create_options,
     .bdrv_create_opts   = &sd_create_opts,
 };
 
@@ -2504,7 +2391,7 @@  static BlockDriver bdrv_sheepdog_tcp = {
     .bdrv_save_vmstate  = sd_save_vmstate,
     .bdrv_load_vmstate  = sd_load_vmstate,
 
-    .create_options = sd_create_options,
+    .bdrv_create_opts   = &sd_create_opts,
 };
 
 static BlockDriver bdrv_sheepdog_unix = {
@@ -2532,7 +2419,7 @@  static BlockDriver bdrv_sheepdog_unix = {
     .bdrv_save_vmstate  = sd_save_vmstate,
     .bdrv_load_vmstate  = sd_load_vmstate,
 
-    .create_options = sd_create_options,
+    .bdrv_create_opts   = &sd_create_opts,
 };
 
 static void bdrv_sheepdog_init(void)
diff --git a/block/ssh.c b/block/ssh.c
index 7f1d5d7..7b46d0e 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -641,74 +641,6 @@  static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags)
     return ret;
 }
 
-static QEMUOptionParameter ssh_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    { NULL }
-};
-
-static int ssh_create(const char *filename, QEMUOptionParameter *options)
-{
-    int r, ret;
-    Error *local_err = NULL;
-    int64_t total_size = 0;
-    QDict *uri_options = NULL;
-    BDRVSSHState s;
-    ssize_t r2;
-    char c[1] = { '\0' };
-
-    ssh_state_init(&s);
-
-    /* Get desired file size. */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            total_size = options->value.n;
-        }
-        options++;
-    }
-    DPRINTF("total_size=%" PRIi64, total_size);
-
-    uri_options = qdict_new();
-    r = parse_uri(filename, uri_options, &local_err);
-    if (r < 0) {
-        qerror_report_err(local_err);
-        error_free(local_err);
-        ret = r;
-        goto out;
-    }
-
-    r = connect_to_ssh(&s, uri_options,
-                       LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE|
-                       LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, 0644);
-    if (r < 0) {
-        ret = r;
-        goto out;
-    }
-
-    if (total_size > 0) {
-        libssh2_sftp_seek64(s.sftp_handle, total_size-1);
-        r2 = libssh2_sftp_write(s.sftp_handle, c, 1);
-        if (r2 < 0) {
-            sftp_error_report(&s, "truncate failed");
-            ret = -EINVAL;
-            goto out;
-        }
-        s.attrs.filesize = total_size;
-    }
-
-    ret = 0;
-
- out:
-    ssh_state_free(&s);
-    if (uri_options != NULL) {
-        QDECREF(uri_options);
-    }
-    return ret;
-}
-
 static QemuOptsList ssh_create_opts = {
     .name = "ssh-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(ssh_create_opts.head),
@@ -722,7 +654,7 @@  static QemuOptsList ssh_create_opts = {
     }
 };
 
-static int ssh_create_new(const char *filename, QemuOpts *opts)
+static int ssh_create(const char *filename, QemuOpts *opts)
 {
     int r, ret;
     Error *local_err = NULL;
@@ -1118,14 +1050,12 @@  static BlockDriver bdrv_ssh = {
     .bdrv_parse_filename          = ssh_parse_filename,
     .bdrv_file_open               = ssh_file_open,
     .bdrv_create                  = ssh_create,
-    .bdrv_create_new              = ssh_create_new,
     .bdrv_close                   = ssh_close,
     .bdrv_has_zero_init           = ssh_has_zero_init,
     .bdrv_co_readv                = ssh_co_readv,
     .bdrv_co_writev               = ssh_co_writev,
     .bdrv_getlength               = ssh_getlength,
     .bdrv_co_flush_to_disk        = ssh_co_flush,
-    .create_options               = ssh_create_options,
     .bdrv_create_opts             = &ssh_create_opts,
 };
 
diff --git a/block/vdi.c b/block/vdi.c
index 50bf24f..e883927 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -633,110 +633,7 @@  static int vdi_co_write(BlockDriverState *bs,
     return ret;
 }
 
-static int vdi_create(const char *filename, QEMUOptionParameter *options)
-{
-    int fd;
-    int result = 0;
-    uint64_t bytes = 0;
-    uint32_t blocks;
-    size_t block_size = DEFAULT_CLUSTER_SIZE;
-    uint32_t image_type = VDI_TYPE_DYNAMIC;
-    VdiHeader header;
-    size_t i;
-    size_t bmap_size;
-
-    logout("\n");
-
-    /* Read out options. */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            bytes = options->value.n;
-#if defined(CONFIG_VDI_BLOCK_SIZE)
-        } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
-            if (options->value.n) {
-                /* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
-                block_size = options->value.n;
-            }
-#endif
-#if defined(CONFIG_VDI_STATIC_IMAGE)
-        } else if (!strcmp(options->name, BLOCK_OPT_STATIC)) {
-            if (options->value.n) {
-                image_type = VDI_TYPE_STATIC;
-            }
-#endif
-        }
-        options++;
-    }
-
-    fd = qemu_open(filename,
-                   O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
-                   0644);
-    if (fd < 0) {
-        return -errno;
-    }
-
-    /* We need enough blocks to store the given disk size,
-       so always round up. */
-    blocks = (bytes + block_size - 1) / block_size;
-
-    bmap_size = blocks * sizeof(uint32_t);
-    bmap_size = ((bmap_size + SECTOR_SIZE - 1) & ~(SECTOR_SIZE -1));
-
-    memset(&header, 0, sizeof(header));
-    pstrcpy(header.text, sizeof(header.text), VDI_TEXT);
-    header.signature = VDI_SIGNATURE;
-    header.version = VDI_VERSION_1_1;
-    header.header_size = 0x180;
-    header.image_type = image_type;
-    header.offset_bmap = 0x200;
-    header.offset_data = 0x200 + bmap_size;
-    header.sector_size = SECTOR_SIZE;
-    header.disk_size = bytes;
-    header.block_size = block_size;
-    header.blocks_in_image = blocks;
-    if (image_type == VDI_TYPE_STATIC) {
-        header.blocks_allocated = blocks;
-    }
-    uuid_generate(header.uuid_image);
-    uuid_generate(header.uuid_last_snap);
-    /* There is no need to set header.uuid_link or header.uuid_parent here. */
-#if defined(CONFIG_VDI_DEBUG)
-    vdi_header_print(&header);
-#endif
-    vdi_header_to_le(&header);
-    if (write(fd, &header, sizeof(header)) < 0) {
-        result = -errno;
-    }
-
-    if (bmap_size > 0) {
-        uint32_t *bmap = g_malloc0(bmap_size);
-        for (i = 0; i < blocks; i++) {
-            if (image_type == VDI_TYPE_STATIC) {
-                bmap[i] = i;
-            } else {
-                bmap[i] = VDI_UNALLOCATED;
-            }
-        }
-        if (write(fd, bmap, bmap_size) < 0) {
-            result = -errno;
-        }
-        g_free(bmap);
-    }
-
-    if (image_type == VDI_TYPE_STATIC) {
-        if (ftruncate(fd, sizeof(header) + bmap_size + blocks * block_size)) {
-            result = -errno;
-        }
-    }
-
-    if (close(fd) < 0) {
-        result = -errno;
-    }
-
-    return result;
-}
-
-static int vdi_create_new(const char *filename, QemuOpts *opts)
+static int vdi_create(const char *filename, QemuOpts *opts)
 {
     int fd;
     int result = 0;
@@ -842,31 +739,6 @@  static void vdi_close(BlockDriverState *bs)
     error_free(s->migration_blocker);
 }
 
-static QEMUOptionParameter vdi_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-#if defined(CONFIG_VDI_BLOCK_SIZE)
-    {
-        .name = BLOCK_OPT_CLUSTER_SIZE,
-        .type = OPT_SIZE,
-        .help = "VDI cluster (block) size",
-        .value = { .n = DEFAULT_CLUSTER_SIZE },
-    },
-#endif
-#if defined(CONFIG_VDI_STATIC_IMAGE)
-    {
-        .name = BLOCK_OPT_STATIC,
-        .type = OPT_FLAG,
-        .help = "VDI static (pre-allocated) image"
-    },
-#endif
-    /* TODO: An additional option to set UUID values might be useful. */
-    { NULL }
-};
-
 static QemuOptsList vdi_create_opts = {
     .name = "vdi-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(vdi_create_opts.head),
@@ -905,7 +777,6 @@  static BlockDriver bdrv_vdi = {
     .bdrv_close = vdi_close,
     .bdrv_reopen_prepare = vdi_reopen_prepare,
     .bdrv_create = vdi_create,
-    .bdrv_create_new = vdi_create_new,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_co_is_allocated = vdi_co_is_allocated,
     .bdrv_make_empty = vdi_make_empty,
@@ -917,7 +788,6 @@  static BlockDriver bdrv_vdi = {
 
     .bdrv_get_info = vdi_get_info,
 
-    .create_options = vdi_create_options,
     .bdrv_create_opts = &vdi_create_opts,
     .bdrv_check = vdi_check,
 };
diff --git a/block/vmdk.c b/block/vmdk.c
index 5452aa2..550ccac 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1532,195 +1532,7 @@  static int filename_decompose(const char *filename, char *path, char *prefix,
     return VMDK_OK;
 }
 
-static int vmdk_create(const char *filename, QEMUOptionParameter *options)
-{
-    int fd, idx = 0;
-    char desc[BUF_SIZE];
-    int64_t total_size = 0, filesize;
-    const char *adapter_type = NULL;
-    const char *backing_file = NULL;
-    const char *fmt = NULL;
-    int flags = 0;
-    int ret = 0;
-    bool flat, split, compress;
-    char ext_desc_lines[BUF_SIZE] = "";
-    char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
-    const int64_t split_size = 0x80000000;  /* VMDK has constant split size */
-    const char *desc_extent_line;
-    char parent_desc_line[BUF_SIZE] = "";
-    uint32_t parent_cid = 0xffffffff;
-    uint32_t number_heads = 16;
-    bool zeroed_grain = false;
-    const char desc_template[] =
-        "# Disk DescriptorFile\n"
-        "version=1\n"
-        "CID=%x\n"
-        "parentCID=%x\n"
-        "createType=\"%s\"\n"
-        "%s"
-        "\n"
-        "# Extent description\n"
-        "%s"
-        "\n"
-        "# The Disk Data Base\n"
-        "#DDB\n"
-        "\n"
-        "ddb.virtualHWVersion = \"%d\"\n"
-        "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
-        "ddb.geometry.heads = \"%d\"\n"
-        "ddb.geometry.sectors = \"63\"\n"
-        "ddb.adapterType = \"%s\"\n";
-
-    if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
-        return -EINVAL;
-    }
-    /* Read out options */
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            total_size = options->value.n;
-        } else if (!strcmp(options->name, BLOCK_OPT_ADAPTER_TYPE)) {
-            adapter_type = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-            backing_file = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
-            flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
-        } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
-            fmt = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_ZEROED_GRAIN)) {
-            zeroed_grain |= options->value.n;
-        }
-        options++;
-    }
-    if (!adapter_type) {
-        adapter_type = "ide";
-    } else if (strcmp(adapter_type, "ide") &&
-               strcmp(adapter_type, "buslogic") &&
-               strcmp(adapter_type, "lsilogic") &&
-               strcmp(adapter_type, "legacyESX")) {
-        fprintf(stderr, "VMDK: Unknown adapter type: '%s'.\n", adapter_type);
-        return -EINVAL;
-    }
-    if (strcmp(adapter_type, "ide") != 0) {
-        /* that's the number of heads with which vmware operates when
-           creating, exporting, etc. vmdk files with a non-ide adapter type */
-        number_heads = 255;
-    }
-    if (!fmt) {
-        /* Default format to monolithicSparse */
-        fmt = "monolithicSparse";
-    } else if (strcmp(fmt, "monolithicFlat") &&
-               strcmp(fmt, "monolithicSparse") &&
-               strcmp(fmt, "twoGbMaxExtentSparse") &&
-               strcmp(fmt, "twoGbMaxExtentFlat") &&
-               strcmp(fmt, "streamOptimized")) {
-        fprintf(stderr, "VMDK: Unknown subformat: %s\n", fmt);
-        return -EINVAL;
-    }
-    split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
-              strcmp(fmt, "twoGbMaxExtentSparse"));
-    flat = !(strcmp(fmt, "monolithicFlat") &&
-             strcmp(fmt, "twoGbMaxExtentFlat"));
-    compress = !strcmp(fmt, "streamOptimized");
-    if (flat) {
-        desc_extent_line = "RW %lld FLAT \"%s\" 0\n";
-    } else {
-        desc_extent_line = "RW %lld SPARSE \"%s\"\n";
-    }
-    if (flat && backing_file) {
-        /* not supporting backing file for flat image */
-        return -ENOTSUP;
-    }
-    if (backing_file) {
-        BlockDriverState *bs = bdrv_new("");
-        ret = bdrv_open(bs, backing_file, NULL, 0, NULL);
-        if (ret != 0) {
-            bdrv_delete(bs);
-            return ret;
-        }
-        if (strcmp(bs->drv->format_name, "vmdk")) {
-            bdrv_delete(bs);
-            return -EINVAL;
-        }
-        parent_cid = vmdk_read_cid(bs, 0);
-        bdrv_delete(bs);
-        snprintf(parent_desc_line, sizeof(parent_desc_line),
-                "parentFileNameHint=\"%s\"", backing_file);
-    }
-
-    /* Create extents */
-    filesize = total_size;
-    while (filesize > 0) {
-        char desc_line[BUF_SIZE];
-        char ext_filename[PATH_MAX];
-        char desc_filename[PATH_MAX];
-        int64_t size = filesize;
-
-        if (split && size > split_size) {
-            size = split_size;
-        }
-        if (split) {
-            snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s",
-                    prefix, flat ? 'f' : 's', ++idx, postfix);
-        } else if (flat) {
-            snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s",
-                    prefix, postfix);
-        } else {
-            snprintf(desc_filename, sizeof(desc_filename), "%s%s",
-                    prefix, postfix);
-        }
-        snprintf(ext_filename, sizeof(ext_filename), "%s%s",
-                path, desc_filename);
-
-        if (vmdk_create_extent(ext_filename, size,
-                               flat, compress, zeroed_grain)) {
-            return -EINVAL;
-        }
-        filesize -= size;
-
-        /* Format description line */
-        snprintf(desc_line, sizeof(desc_line),
-                    desc_extent_line, size / 512, desc_filename);
-        pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line);
-    }
-    /* generate descriptor file */
-    snprintf(desc, sizeof(desc), desc_template,
-            (unsigned int)time(NULL),
-            parent_cid,
-            fmt,
-            parent_desc_line,
-            ext_desc_lines,
-            (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
-            total_size / (int64_t)(63 * number_heads * 512), number_heads,
-                adapter_type);
-    if (split || flat) {
-        fd = qemu_open(filename,
-                       O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
-                       0644);
-    } else {
-        fd = qemu_open(filename,
-                       O_WRONLY | O_BINARY | O_LARGEFILE,
-                       0644);
-    }
-    if (fd < 0) {
-        return -errno;
-    }
-    /* the descriptor offset = 0x200 */
-    if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) {
-        ret = -errno;
-        goto exit;
-    }
-    ret = qemu_write_full(fd, desc, strlen(desc));
-    if (ret != strlen(desc)) {
-        ret = -errno;
-        goto exit;
-    }
-    ret = 0;
-exit:
-    qemu_close(fd);
-    return ret;
-}
-
-static int vmdk_create_new(const char *filename, QemuOpts *opts)
+static int vmdk_create(const char *filename, QemuOpts *opts)
 {
     int fd, idx = 0;
     char desc[BUF_SIZE];
@@ -1977,43 +1789,6 @@  static int vmdk_has_zero_init(BlockDriverState *bs)
     return 1;
 }
 
-static QEMUOptionParameter vmdk_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    {
-        .name = BLOCK_OPT_ADAPTER_TYPE,
-        .type = OPT_STRING,
-        .help = "Virtual adapter type, can be one of "
-                "ide (default), lsilogic, buslogic or legacyESX"
-    },
-    {
-        .name = BLOCK_OPT_BACKING_FILE,
-        .type = OPT_STRING,
-        .help = "File name of a base image"
-    },
-    {
-        .name = BLOCK_OPT_COMPAT6,
-        .type = OPT_FLAG,
-        .help = "VMDK version 6 image"
-    },
-    {
-        .name = BLOCK_OPT_SUBFMT,
-        .type = OPT_STRING,
-        .help =
-            "VMDK flat extent format, can be one of "
-            "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
-    },
-    {
-        .name = BLOCK_OPT_ZEROED_GRAIN,
-        .type = OPT_FLAG,
-        .help = "Enable efficient zero writes using the zeroed-grain GTE feature"
-    },
-    { NULL }
-};
-
 static QemuOptsList vmdk_create_opts = {
     .name = "vmdk-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(vmdk_create_opts.head),
@@ -2068,14 +1843,11 @@  static BlockDriver bdrv_vmdk = {
     .bdrv_co_write_zeroes         = vmdk_co_write_zeroes,
     .bdrv_close                   = vmdk_close,
     .bdrv_create                  = vmdk_create,
-    .bdrv_create_new              = vmdk_create_new,
     .bdrv_co_flush_to_disk        = vmdk_co_flush,
     .bdrv_co_is_allocated         = vmdk_co_is_allocated,
     .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
     .bdrv_has_zero_init           = vmdk_has_zero_init,
-
-    .create_options               = vmdk_create_options,
-    .bdrv_create_opts = &vmdk_create_opts,
+    .bdrv_create_opts             = &vmdk_create_opts,
 };
 
 static void bdrv_vmdk_init(void)
diff --git a/block/vpc.c b/block/vpc.c
index aa1263a..1dc5c4d 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -683,110 +683,7 @@  static int create_fixed_disk(int fd, uint8_t *buf, int64_t total_size)
     return ret;
 }
 
-static int vpc_create(const char *filename, QEMUOptionParameter *options)
-{
-    uint8_t buf[1024];
-    struct vhd_footer *footer = (struct vhd_footer *) buf;
-    QEMUOptionParameter *disk_type_param;
-    int fd, i;
-    uint16_t cyls = 0;
-    uint8_t heads = 0;
-    uint8_t secs_per_cyl = 0;
-    int64_t total_sectors;
-    int64_t total_size;
-    int disk_type;
-    int ret = -EIO;
-
-    /* Read out options */
-    total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;
-
-    disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT);
-    if (disk_type_param && disk_type_param->value.s) {
-        if (!strcmp(disk_type_param->value.s, "dynamic")) {
-            disk_type = VHD_DYNAMIC;
-        } else if (!strcmp(disk_type_param->value.s, "fixed")) {
-            disk_type = VHD_FIXED;
-        } else {
-            return -EINVAL;
-        }
-    } else {
-        disk_type = VHD_DYNAMIC;
-    }
-
-    /* Create the file */
-    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-    if (fd < 0) {
-        return -EIO;
-    }
-
-    /*
-     * Calculate matching total_size and geometry. Increase the number of
-     * sectors requested until we get enough (or fail). This ensures that
-     * qemu-img convert doesn't truncate images, but rather rounds up.
-     */
-    total_sectors = total_size / BDRV_SECTOR_SIZE;
-    for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
-        if (calculate_geometry(total_sectors + i, &cyls, &heads,
-                               &secs_per_cyl))
-        {
-            ret = -EFBIG;
-            goto fail;
-        }
-    }
-
-    total_sectors = (int64_t) cyls * heads * secs_per_cyl;
-
-    /* Prepare the Hard Disk Footer */
-    memset(buf, 0, 1024);
-
-    memcpy(footer->creator, "conectix", 8);
-    /* TODO Check if "qemu" creator_app is ok for VPC */
-    memcpy(footer->creator_app, "qemu", 4);
-    memcpy(footer->creator_os, "Wi2k", 4);
-
-    footer->features = be32_to_cpu(0x02);
-    footer->version = be32_to_cpu(0x00010000);
-    if (disk_type == VHD_DYNAMIC) {
-        footer->data_offset = be64_to_cpu(HEADER_SIZE);
-    } else {
-        footer->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);
-    }
-    footer->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE);
-
-    /* Version of Virtual PC 2007 */
-    footer->major = be16_to_cpu(0x0005);
-    footer->minor = be16_to_cpu(0x0003);
-    if (disk_type == VHD_DYNAMIC) {
-        footer->orig_size = be64_to_cpu(total_sectors * 512);
-        footer->size = be64_to_cpu(total_sectors * 512);
-    } else {
-        footer->orig_size = be64_to_cpu(total_size);
-        footer->size = be64_to_cpu(total_size);
-    }
-    footer->cyls = be16_to_cpu(cyls);
-    footer->heads = heads;
-    footer->secs_per_cyl = secs_per_cyl;
-
-    footer->type = be32_to_cpu(disk_type);
-
-#if defined(CONFIG_UUID)
-    uuid_generate(footer->uuid);
-#endif
-
-    footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));
-
-    if (disk_type == VHD_DYNAMIC) {
-        ret = create_dynamic_disk(fd, buf, total_sectors);
-    } else {
-        ret = create_fixed_disk(fd, buf, total_size);
-    }
-
- fail:
-    qemu_close(fd);
-    return ret;
-}
-
-static int vpc_create_new(const char *filename, QemuOpts *opts)
+static int vpc_create(const char *filename, QemuOpts *opts)
 {
     uint8_t buf[1024];
     struct vhd_footer *footer = (struct vhd_footer *) buf;
@@ -913,22 +810,6 @@  static void vpc_close(BlockDriverState *bs)
     error_free(s->migration_blocker);
 }
 
-static QEMUOptionParameter vpc_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    {
-        .name = BLOCK_OPT_SUBFMT,
-        .type = OPT_STRING,
-        .help =
-            "Type of virtual hard disk format. Supported formats are "
-            "{dynamic (default) | fixed} "
-    },
-    { NULL }
-};
-
 static QemuOptsList vpc_create_opts = {
     .name = "vpc-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head),
@@ -958,12 +839,10 @@  static BlockDriver bdrv_vpc = {
     .bdrv_close             = vpc_close,
     .bdrv_reopen_prepare    = vpc_reopen_prepare,
     .bdrv_create            = vpc_create,
-    .bdrv_create_new        = vpc_create_new,
 
     .bdrv_read              = vpc_co_read,
     .bdrv_write             = vpc_co_write,
 
-    .create_options         = vpc_create_options,
     .bdrv_create_opts       = &vpc_create_opts,
     .bdrv_has_zero_init     = vpc_has_zero_init,
 };
diff --git a/block/vvfat.c b/block/vvfat.c
index cd3b8ed..d274e3e 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2907,7 +2907,7 @@  static BlockDriver vvfat_write_target = {
 static int enable_write_target(BDRVVVFATState *s)
 {
     BlockDriver *bdrv_qcow;
-    QEMUOptionParameter *options;
+    QemuOpts *opts;
     int ret;
     int size = sector2cluster(s, s->sector_count);
     s->used_clusters = calloc(size, 1);
@@ -2921,11 +2921,10 @@  static int enable_write_target(BDRVVVFATState *s)
     }
 
     bdrv_qcow = bdrv_find_format("qcow");
-    options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
-    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);
+    opts = qemu_opts_create_nofail(bdrv_qcow->bdrv_create_opts);
+    qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
+    qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
+    ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts);
     if (ret < 0) {
         goto err;
     }
diff --git a/include/block/block.h b/include/block/block.h
index efcaaa4..476d168 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -116,11 +116,8 @@  BlockDriver *bdrv_find_protocol(const char *filename,
 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);
-int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
-int bdrv_create_new(BlockDriver *drv, const char* filename, QemuOpts *opts);
-int bdrv_create_file_new(const char *filename, QemuOpts *opts);
+int bdrv_create(BlockDriver *drv, const char* filename, QemuOpts *opts);
+int bdrv_create_file(const char *filename, QemuOpts *opts);
 BlockDriverState *bdrv_new(const char *device_name);
 void bdrv_make_anon(BlockDriverState *bs);
 void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index fb12bba..09bf260 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -104,8 +104,7 @@  struct BlockDriver {
                       const uint8_t *buf, int nb_sectors);
     void (*bdrv_close)(BlockDriverState *bs);
     void (*bdrv_rebind)(BlockDriverState *bs);
-    int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
-    int (*bdrv_create_new)(const char *filename, QemuOpts *opts);
+    int (*bdrv_create)(const char *filename, QemuOpts *opts);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
     int (*bdrv_make_empty)(BlockDriverState *bs);
     /* aio */
@@ -195,10 +194,8 @@  struct BlockDriver {
         BlockDriverCompletionFunc *cb, void *opaque);
 
     /* List of options for creating images, terminated by name == NULL */
-    QEMUOptionParameter *create_options;
     QemuOptsList *bdrv_create_opts;
 
-
     /*
      * Returns 0 for completed check, -errno for internal errors.
      * The check results are stored in result.
diff --git a/qemu-img.c b/qemu-img.c
index b9a848d..fd9bea7 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -231,7 +231,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);
@@ -246,12 +246,10 @@  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_options = append_option_parameters(create_options,
-                                              proto_drv->create_options);
-    print_option_help(create_options);
-    free_option_parameters(create_options);
+    create_opts = qemu_opts_append(drv->bdrv_create_opts,
+                                   proto_drv->bdrv_create_opts);
+    qemu_opts_print_help(create_opts);
+    qemu_opts_free(create_opts);
     return 0;
 }
 
@@ -303,19 +301,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 *list,
                                  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(list, 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(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
             error_report("Backing file format not supported for file "
                          "format '%s'", fmt);
             return -1;
@@ -1126,8 +1124,9 @@  static int img_convert(int argc, char **argv)
     uint8_t * buf = NULL;
     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;
     float local_progress = 0;
@@ -1271,40 +1270,32 @@  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);
-
-    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);
+    create_opts = qemu_opts_append(drv->bdrv_create_opts,
+                                   proto_drv->bdrv_create_opts);
+    opts = qemu_opts_create_nofail(create_opts);
+    if (options && qemu_opts_do_parse_replace(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");
@@ -1312,15 +1303,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");
@@ -1330,7 +1321,7 @@  static int img_convert(int argc, char **argv)
     }
 
     /* Create the new image */
-    ret = bdrv_create(drv, out_filename, param);
+    ret = bdrv_create(drv, out_filename, opts);
     if (ret < 0) {
         if (ret == -ENOTSUP) {
             error_report("Formatting not supported for file format '%s'",
@@ -1534,8 +1525,10 @@  static int img_convert(int argc, char **argv)
     }
 out:
     qemu_progress_end();
-    free_option_parameters(create_options);
-    free_option_parameters(param);
+    qemu_opts_free(create_opts);
+    if (opts) {
+        qemu_opts_del(opts);
+    }
     qemu_vfree(buf);
     if (out_bs) {
         bdrv_delete(out_bs);