qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser
@ 2013-08-13  4:31 Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print Dong Xu Wang
                   ` (24 more replies)
  0 siblings, 25 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

v17->v18:
1) split into small patches, by each image format.
2) opt->str store digit, without suffixes in QemuOpt

Dong Xu Wang (25):
  qemu-option: add def_value_str in QemuOptDesc struct and rewrite
    qemu_opts_print
  qemu-option: avoid duplication of default value in QemuOpts
  qemu-option: create four QemuOptsList related functions
  qemu-option: create some QemuOpts functons
  qemu-option: opt->str store digit, without suffixes
  add interface to block
  block: add QemuOpts support for cow.c
  block: add QemuOpts support for gluster.c
  block: add QemuOpts support for iscsi.c
  block: add QemuOpts support for qcow.c
  block: add QemuOpts support for qcow2.c
  block: add QemuOpts support for qed.c
  block: add QemuOpts support for raw-posix.c
  block: add QemuOpts support for raw-win32.c
  block: add QemuOpts support for raw.c
  block: add QemuOpts support for rbd.c
  block: add QemuOpts support for sheepdog.c
  block: add QemuOpts support for ssh.c
  block: add QemuOpts support for vdi.c
  block: add QemuOpts support for vmdk.c
  block: add QemuOpts support for vpc.c
  block: add QemuOpts support for block.c
  block: clean temp code and use QemuOpts in block
  qapi: query-command-line-options outputs def_value_str
  qemu-option: remove QEMUOptionParameter related functions and struct

 block.c                   | 100 ++++----
 block/cow.c               |  54 ++---
 block/gluster.c           |  37 ++-
 block/iscsi.c             |  31 ++-
 block/qcow.c              |  69 +++---
 block/qcow2.c             | 213 +++++++++--------
 block/qed.c               | 112 ++++-----
 block/qed.h               |   3 +-
 block/raw-posix.c         |  50 ++--
 block/raw-win32.c         |  31 +--
 block/raw.c               |  30 +--
 block/rbd.c               |  61 +++--
 block/sheepdog.c          |  80 ++++---
 block/ssh.c               |  29 ++-
 block/vdi.c               |  72 +++---
 block/vmdk.c              | 136 +++++------
 block/vpc.c               |  68 +++---
 block/vvfat.c             |  11 +-
 include/block/block.h     |   5 +-
 include/block/block_int.h |   5 +-
 include/qemu/option.h     |  56 ++---
 qapi-schema.json          |   8 +-
 qemu-img.c                |  75 +++---
 qmp-commands.hx           |   2 +
 util/qemu-config.c        |   4 +
 util/qemu-option.c        | 576 +++++++++++++++++++++-------------------------
 26 files changed, 928 insertions(+), 990 deletions(-)

-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-27 13:49   ` Kevin Wolf
  2013-08-28 12:53   ` Eric Blake
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 02/25] qemu-option: avoid duplication of default value in QemuOpts Dong Xu Wang
                   ` (23 subsequent siblings)
  24 siblings, 2 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

qemu_opts_print has no user now, so can re-write the function safely.

qemu_opts_print is used while using "qemu-img create", it
produces the same output as previous code.

The behavior of this function has changed:

1. Print every possible option, whether a value has been set or not.
2. Option descriptors may provide a default value.
3. Print to stdout instead of stderr.

Previously the behavior was to print every option that has been set.
Options that have not been set would be skipped.

v17->v18:
1) print opt->value.uint directly while type is QEMU_OPT_SIZE. 

v13->v14:
1) fix memory leak.
2) make opt_set do not accpet null value argument.

v12->v13
1) re-write commit message.

v11->v12
1) make def_value_str become the real default value string in opt_set
function.

v10->v11:
1) print all values that have actually been assigned while accept-any
cases.

v7->v8:
1) print "elements => accept any params" while opts_accepts_any() ==
true.
2) since def_print_str is the default value if an option isn't set,
so rename it to def_value_str.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 include/qemu/option.h |  3 ++-
 util/qemu-option.c    | 34 ++++++++++++++++++++++++++++------
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 7a58e47..bbbdea3 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -96,6 +96,7 @@ typedef struct QemuOptDesc {
     const char *name;
     enum QemuOptType type;
     const char *help;
+    const char *def_value_str;
 } QemuOptDesc;
 
 struct QemuOptsList {
@@ -153,7 +154,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
 void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
 
 typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
-int qemu_opts_print(QemuOpts *opts, void *dummy);
+int qemu_opts_print(QemuOpts *opts);
 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
                       int abort_on_failure);
 
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 4ebdc4c..9bf7018 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -840,16 +840,38 @@ void qemu_opts_del(QemuOpts *opts)
     g_free(opts);
 }
 
-int qemu_opts_print(QemuOpts *opts, void *dummy)
+int qemu_opts_print(QemuOpts *opts)
 {
     QemuOpt *opt;
+    QemuOptDesc *desc = opts->list->desc;
 
-    fprintf(stderr, "%s: %s:", opts->list->name,
-            opts->id ? opts->id : "<noid>");
-    QTAILQ_FOREACH(opt, &opts->head, next) {
-        fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
+    if (desc[0].name == NULL) {
+        QTAILQ_FOREACH(opt, &opts->head, next) {
+            printf("%s=\"%s\" ", opt->name, opt->str);
+        }
+        return 0;
+    }
+    for (; desc && desc->name; desc++) {
+        const char *value = desc->def_value_str;
+        QemuOpt *opt;
+
+        opt = qemu_opt_find(opts, desc->name);
+        if (opt) {
+            value = opt->str;
+        }
+
+        if (!value) {
+            continue;
+        }
+
+        if (desc->type == QEMU_OPT_STRING) {
+            printf("%s='%s' ", desc->name, value);
+        } else if (desc->type == QEMU_OPT_SIZE && opt) {
+            printf("%s=%" PRIu64 " ", desc->name, opt->value.uint);
+        } else {
+            printf("%s=%s ", desc->name, value);
+        }
     }
-    fprintf(stderr, "\n");
     return 0;
 }
 
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 02/25] qemu-option: avoid duplication of default value in QemuOpts
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-28 12:57   ` Eric Blake
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 03/25] qemu-option: create four QemuOptsList related functions Dong Xu Wang
                   ` (22 subsequent siblings)
  24 siblings, 1 reply; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

This patch moves the default value entirely to QemuOptDesc.

When getting the value of an option that hasn't been set, and
QemuOptDesc has a default value, return that.  Else, behave as
before.

Example: qemu_opt_get_number(opts, "foo", 42)

   If "foo" has been set in opts, return its value.

   Else, if opt's QemuOptDesc has a default value for "foo", return
   that.

   Else, return 42.

   Note that the last argument is useless when QemuOptDesc has a
   default value.  Ugly.  If it bothers us, we could assert.

Example: qemu_opt_get(opts, "bar")

   If "bar" has been set in opts, return its value.

   Else, if opt's QemuOptDesc has a default value for "bar", return
   that.

   Else, return NULL.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>

v13->v14:
1) change code style.
2) assert errors.

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

Conflicts:
	util/qemu-option.c
---
 util/qemu-option.c | 66 ++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 49 insertions(+), 17 deletions(-)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index 9bf7018..a3c3c17 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -495,9 +495,31 @@ static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
     return NULL;
 }
 
+static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
+                                            const char *name)
+{
+    int i;
+
+    for (i = 0; desc[i].name != NULL; i++) {
+        if (strcmp(desc[i].name, name) == 0) {
+            return &desc[i];
+        }
+    }
+
+    return NULL;
+}
+
 const char *qemu_opt_get(QemuOpts *opts, const char *name)
 {
     QemuOpt *opt = qemu_opt_find(opts, name);
+    const QemuOptDesc *desc;
+
+    if (!opt) {
+        desc = find_desc_by_name(opts->list->desc, name);
+        if (desc && desc->def_value_str) {
+            return desc->def_value_str;
+        }
+    }
     return opt ? opt->str : NULL;
 }
 
@@ -516,9 +538,17 @@ bool qemu_opt_has_help_opt(QemuOpts *opts)
 bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
 {
     QemuOpt *opt = qemu_opt_find(opts, name);
+    const QemuOptDesc *desc;
+    Error *local_err = NULL;
 
-    if (opt == NULL)
+    if (opt == NULL) {
+        desc = find_desc_by_name(opts->list->desc, name);
+        if (desc && desc->def_value_str) {
+            parse_option_bool(name, desc->def_value_str, &defval, &local_err);
+            assert(!local_err);
+        }
         return defval;
+    }
     assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
     return opt->value.boolean;
 }
@@ -526,9 +556,17 @@ bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
 {
     QemuOpt *opt = qemu_opt_find(opts, name);
+    const QemuOptDesc *desc;
+    Error *local_err = NULL;
 
-    if (opt == NULL)
+    if (opt == NULL) {
+        desc = find_desc_by_name(opts->list->desc, name);
+        if (desc && desc->def_value_str) {
+            parse_option_number(name, desc->def_value_str, &defval, &local_err);
+            assert(!local_err);
+        }
         return defval;
+    }
     assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
     return opt->value.uint;
 }
@@ -536,9 +574,17 @@ uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
 {
     QemuOpt *opt = qemu_opt_find(opts, name);
+    const QemuOptDesc *desc;
+    Error *local_err = NULL;
 
-    if (opt == NULL)
+    if (opt == NULL) {
+        desc = find_desc_by_name(opts->list->desc, name);
+        if (desc && desc->def_value_str) {
+            parse_option_size(name, desc->def_value_str, &defval, &local_err);
+            assert(!local_err);
+        }
         return defval;
+    }
     assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
     return opt->value.uint;
 }
@@ -579,20 +625,6 @@ static bool opts_accepts_any(const QemuOpts *opts)
     return opts->list->desc[0].name == NULL;
 }
 
-static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
-                                            const char *name)
-{
-    int i;
-
-    for (i = 0; desc[i].name != NULL; i++) {
-        if (strcmp(desc[i].name, name) == 0) {
-            return &desc[i];
-        }
-    }
-
-    return NULL;
-}
-
 int qemu_opt_unset(QemuOpts *opts, const char *name)
 {
     QemuOpt *opt = qemu_opt_find(opts, name);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 03/25] qemu-option: create four QemuOptsList related functions
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 02/25] qemu-option: avoid duplication of default value in QemuOpts Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-27 13:54   ` Kevin Wolf
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 04/25] qemu-option: create some QemuOpts functons Dong Xu Wang
                   ` (21 subsequent siblings)
  24 siblings, 1 reply; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

This patch creates 4 functions, count_opts_list, qemu_opts_append,
qemu_opts_free and qemu_opts_print_help, they are used in following
commits.

v16->v17:
1) fix indentation.
2) fix typo.

v15->v16:
1) discard double-initialization.
2) use pointer directly, not g_strdup.

v12->v13:
1) simply assert that neither argument has merge_lists set.
2) drop superfluous paranthesesis around p == first.

v11->v12:
1) renmae functions.
2) fix loop styles and code styles.
3) qemu_opts_apend will not return NULL now.
4) merge_lists value is from arguments in qemu_opts_append.

v6->v7:
1) Fix typo.

v5->v6:
1) allocate enough space in append_opts_list function.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 include/qemu/option.h |  3 +++
 util/qemu-option.c    | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index bbbdea3..3b514bb 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -158,4 +158,7 @@ int qemu_opts_print(QemuOpts *opts);
 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
                       int abort_on_failure);
 
+QemuOptsList *qemu_opts_append(QemuOptsList *first, QemuOptsList *second);
+void qemu_opts_free(QemuOptsList *list);
+void qemu_opts_print_help(QemuOptsList *list);
 #endif
diff --git a/util/qemu-option.c b/util/qemu-option.c
index a3c3c17..2a5447c 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1201,3 +1201,76 @@ int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
     loc_pop(&loc);
     return rc;
 }
+
+static size_t count_opts_list(QemuOptsList *list)
+{
+    size_t i;
+
+    for (i = 0; list && list->desc[i].name; i++) {
+        ;
+    }
+
+    return i;
+}
+
+/* Create a new QemuOptsList with a desc of the merge of the first
+ * and second. It will allocate space for one new QemuOptsList plus
+ * enough space for QemuOptDesc in first and second QemuOptsList.
+ * First argument's QemuOptDesc members take precedence over second's.
+ * The result's name and implied_opt_name are not copied from them.
+ * Both merge_lists should not be set. Both lists can be NULL.
+ */
+QemuOptsList *qemu_opts_append(QemuOptsList *first,
+                               QemuOptsList *second)
+{
+    size_t num_first_opts, num_second_opts;
+    QemuOptsList *dest = NULL;
+    int i;
+    int index = 0;
+    QemuOptsList *p = first;
+
+    num_first_opts = count_opts_list(first);
+    num_second_opts = count_opts_list(second);
+
+    dest = g_malloc0(sizeof(QemuOptsList)
+        + (num_first_opts + num_second_opts + 1) * sizeof(QemuOptDesc));
+
+    dest->name = "append_opts_list";
+    dest->implied_opt_name = NULL;
+    assert((!first || !first->merge_lists)
+           && (!second || !second->merge_lists));
+    QTAILQ_INIT(&dest->head);
+
+    for (i = 0; p && p->desc[i].name; i++) {
+        if (!find_desc_by_name(dest->desc, p->desc[i].name)) {
+            dest->desc[index].name = p->desc[i].name;
+            dest->desc[index].help = p->desc[i].help;
+            dest->desc[index].type = p->desc[i].type;
+            dest->desc[index].def_value_str =  p->desc[i].def_value_str;
+            index++;
+        }
+        if (p == first && p && !p->desc[i].name) {
+            p = second;
+            i = 0;
+        }
+    }
+    dest->desc[index].name = NULL;
+    return dest;
+}
+
+/* free a QemuOptsList, can accept NULL as arguments */
+void qemu_opts_free(QemuOptsList *list)
+{
+    g_free(list);
+}
+
+void qemu_opts_print_help(QemuOptsList *list)
+{
+    int i;
+    printf("Supported options:\n");
+    for (i = 0; list && list->desc[i].name; i++) {
+        printf("%-16s %s\n", list->desc[i].name,
+               list->desc[i].help ?
+               list->desc[i].help : "No description available");
+    }
+}
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 04/25] qemu-option: create some QemuOpts functons
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (2 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 03/25] qemu-option: create four QemuOptsList related functions Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-27 13:58   ` Kevin Wolf
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 05/25] qemu-option: opt->str store digit, without suffixes Dong Xu Wang
                   ` (20 subsequent siblings)
  24 siblings, 1 reply; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

These functions will be used in next commit.

qemu_opt_get_(*)_del functions are used to make sure we
have the same behaviors as before: in block layer, after
parsing a parameter value, parameter list will delete it
to avoid parsing it twice.

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

v16->v17:
1) return "char *" instead of "const char*"

v13->v14:
1) rewrite commit message.
2) use def_value_str in qemu_opt_get_FOO_del() and qemu_opt_get_del().
3) delete redundant qemu_opt_del(opt).
---
 include/qemu/option.h |  11 ++++-
 util/qemu-option.c    | 130 ++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 125 insertions(+), 16 deletions(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 3b514bb..64d7327 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -108,6 +108,7 @@ struct QemuOptsList {
 };
 
 const char *qemu_opt_get(QemuOpts *opts, const char *name);
+char *qemu_opt_get_del(QemuOpts *opts, const char *name);
 /**
  * qemu_opt_has_help_opt:
  * @opts: options to search for a help request
@@ -121,14 +122,19 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name);
  */
 bool qemu_opt_has_help_opt(QemuOpts *opts);
 bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
+bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval);
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
 int qemu_opt_unset(QemuOpts *opts, const char *name);
+uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
+                               uint64_t defval);
 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
+int qemu_opt_replace_set(QemuOpts *opts, const char *name, const char *value);
 void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
                       Error **errp);
 int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val);
 int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val);
+int qemu_opt_replace_set_number(QemuOpts *opts, const char *name, int64_t val);
 typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque);
 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
                      int abort_on_failure);
@@ -145,7 +151,10 @@ const char *qemu_opts_id(QemuOpts *opts);
 void qemu_opts_del(QemuOpts *opts);
 void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
-QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int permit_abbrev);
+int qemu_opts_do_parse_replace(QemuOpts *opts, const char *params,
+                               const char *firstname);
+QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
+                          int permit_abbrev);
 void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
                             int permit_abbrev);
 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 2a5447c..b939e8a 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -523,6 +523,32 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
     return opt ? opt->str : NULL;
 }
 
+static void qemu_opt_del(QemuOpt *opt)
+{
+    QTAILQ_REMOVE(&opt->opts->head, opt, next);
+    g_free((/* !const */ char*)opt->name);
+    g_free((/* !const */ char*)opt->str);
+    g_free(opt);
+}
+
+char *qemu_opt_get_del(QemuOpts *opts, const char *name)
+{
+    QemuOpt *opt = qemu_opt_find(opts, name);
+    const QemuOptDesc *desc;
+    char *str = NULL;
+
+    if (!opt) {
+        desc = find_desc_by_name(opts->list->desc, name);
+        if (desc && desc->def_value_str) {
+            str = g_strdup(desc->def_value_str);
+        }
+    } else {
+        str = g_strdup(opt->str);
+        qemu_opt_del(opt);
+    }
+    return str;
+}
+
 bool qemu_opt_has_help_opt(QemuOpts *opts)
 {
     QemuOpt *opt;
@@ -553,6 +579,27 @@ bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
     return opt->value.boolean;
 }
 
+bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval)
+{
+    QemuOpt *opt = qemu_opt_find(opts, name);
+    const QemuOptDesc *desc;
+    Error *local_err = NULL;
+    bool ret = defval;
+
+    if (opt == NULL) {
+        desc = find_desc_by_name(opts->list->desc, name);
+        if (desc && desc->def_value_str) {
+            parse_option_bool(name, desc->def_value_str, &ret, &local_err);
+            assert(!local_err);
+        }
+        return ret;
+    }
+    assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
+    ret = opt->value.boolean;
+    qemu_opt_del(opt);
+    return ret;
+}
+
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
 {
     QemuOpt *opt = qemu_opt_find(opts, name);
@@ -589,6 +636,28 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
     return opt->value.uint;
 }
 
+uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
+                               uint64_t defval)
+{
+    QemuOpt *opt = qemu_opt_find(opts, name);
+    const QemuOptDesc *desc;
+    Error *local_err = NULL;
+    uint64_t ret = defval;
+
+    if (opt == NULL) {
+        desc = find_desc_by_name(opts->list->desc, name);
+        if (desc && desc->def_value_str) {
+            parse_option_size(name, desc->def_value_str, &ret, &local_err);
+            assert(!local_err);
+        }
+        return ret;
+    }
+    assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
+    ret = opt->value.uint;
+    qemu_opt_del(opt);
+    return ret;
+}
+
 static void qemu_opt_parse(QemuOpt *opt, Error **errp)
 {
     if (opt->desc == NULL)
@@ -612,14 +681,6 @@ static void qemu_opt_parse(QemuOpt *opt, Error **errp)
     }
 }
 
-static void qemu_opt_del(QemuOpt *opt)
-{
-    QTAILQ_REMOVE(&opt->opts->head, opt, next);
-    g_free((/* !const */ char*)opt->name);
-    g_free((/* !const */ char*)opt->str);
-    g_free(opt);
-}
-
 static bool opts_accepts_any(const QemuOpts *opts)
 {
     return opts->list->desc[0].name == NULL;
@@ -640,7 +701,7 @@ int qemu_opt_unset(QemuOpts *opts, const char *name)
 }
 
 static void opt_set(QemuOpts *opts, const char *name, const char *value,
-                    bool prepend, Error **errp)
+                    bool prepend, bool replace, Error **errp)
 {
     QemuOpt *opt;
     const QemuOptDesc *desc;
@@ -652,6 +713,11 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
         return;
     }
 
+    opt = qemu_opt_find(opts, name);
+    if (replace && opt) {
+        qemu_opt_del(opt);
+    }
+
     opt = g_malloc0(sizeof(*opt));
     opt->name = g_strdup(name);
     opt->opts = opts;
@@ -673,7 +739,25 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
 {
     Error *local_err = NULL;
 
-    opt_set(opts, name, value, false, &local_err);
+    opt_set(opts, name, value, false, false, &local_err);
+    if (error_is_set(&local_err)) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+
+    return 0;
+}
+
+/*
+ * If name exists, the function will delete the opt first and then add a new
+ * one.
+ */
+int qemu_opt_replace_set(QemuOpts *opts, const char *name, const char *value)
+{
+    Error *local_err = NULL;
+
+    opt_set(opts, name, value, false, true, &local_err);
     if (error_is_set(&local_err)) {
         qerror_report_err(local_err);
         error_free(local_err);
@@ -686,7 +770,7 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
 void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
                       Error **errp)
 {
-    opt_set(opts, name, value, false, errp);
+    opt_set(opts, name, value, false, false, errp);
 }
 
 int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
@@ -733,6 +817,16 @@ int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
     return 0;
 }
 
+int qemu_opt_replace_set_number(QemuOpts *opts, const char *name, int64_t val)
+{
+    QemuOpt *opt = qemu_opt_find(opts, name);
+
+    if (opt) {
+        qemu_opt_del(opt);
+    }
+    return qemu_opt_set_number(opts, name, val);
+}
+
 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
                      int abort_on_failure)
 {
@@ -908,7 +1002,7 @@ int qemu_opts_print(QemuOpts *opts)
 }
 
 static int opts_do_parse(QemuOpts *opts, const char *params,
-                         const char *firstname, bool prepend)
+                         const char *firstname, bool prepend, bool replace)
 {
     char option[128], value[1024];
     const char *p,*pe,*pc;
@@ -944,7 +1038,7 @@ static int opts_do_parse(QemuOpts *opts, const char *params,
         }
         if (strcmp(option, "id") != 0) {
             /* store and parse */
-            opt_set(opts, option, value, prepend, &local_err);
+            opt_set(opts, option, value, prepend, replace, &local_err);
             if (error_is_set(&local_err)) {
                 qerror_report_err(local_err);
                 error_free(local_err);
@@ -960,7 +1054,13 @@ static int opts_do_parse(QemuOpts *opts, const char *params,
 
 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
 {
-    return opts_do_parse(opts, params, firstname, false);
+    return opts_do_parse(opts, params, firstname, false, false);
+}
+
+int qemu_opts_do_parse_replace(QemuOpts *opts, const char *params,
+                               const char *firstname)
+{
+    return opts_do_parse(opts, params, firstname, false, true);
 }
 
 static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
@@ -1000,7 +1100,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
         return NULL;
     }
 
-    if (opts_do_parse(opts, params, firstname, defaults) != 0) {
+    if (opts_do_parse(opts, params, firstname, defaults, false) != 0) {
         qemu_opts_del(opts);
         return NULL;
     }
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 05/25] qemu-option: opt->str store digit, without suffixes
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (3 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 04/25] qemu-option: create some QemuOpts functons Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-27 14:01   ` Kevin Wolf
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 06/25] add interface to block Dong Xu Wang
                   ` (19 subsequent siblings)
  24 siblings, 1 reply; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

To produce same output while using "qemu-img create", opt->str
should store pure digit, without suffixes.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 util/qemu-option.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index b939e8a..861929d 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -675,6 +675,8 @@ static void qemu_opt_parse(QemuOpt *opt, Error **errp)
         break;
     case QEMU_OPT_SIZE:
         parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
+        g_free((char *)opt->str);
+        opt->str = g_strdup(stringify(opt->value_uint));
         break;
     default:
         abort();
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 06/25] add interface to block
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (4 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 05/25] qemu-option: opt->str store digit, without suffixes Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-27 14:08   ` Kevin Wolf
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 07/25] block: add QemuOpts support for cow.c Dong Xu Wang
                   ` (18 subsequent siblings)
  24 siblings, 1 reply; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

To make patches easy for reviewing, each block format is
a single patch. Add a new interface to block layer to make
sure origin code can compile and do not change any code
logic.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block.c                   | 51 +++++++++++++++++++++++++++++++++++++++++++++++
 include/block/block.h     |  2 ++
 include/block/block_int.h |  2 ++
 3 files changed, 55 insertions(+)

diff --git a/block.c b/block.c
index 01b66d8..25090dc 100644
--- a/block.c
+++ b/block.c
@@ -366,6 +366,7 @@ typedef struct CreateCo {
     BlockDriver *drv;
     char *filename;
     QEMUOptionParameter *options;
+    QemuOpts *opts;
     int ret;
 } CreateCo;
 
@@ -425,6 +426,56 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
     return bdrv_create(drv, filename, options);
 }
 
+int bdrv_create_new(BlockDriver *drv, const char* filename, QemuOpts *opts)
+{
+    int ret;
+
+    Coroutine *co;
+    CreateCo cco = {
+        .drv = drv,
+        .filename = g_strdup(filename),
+        .opts = opts ?: qemu_opts_create_nofail(drv->bdrv_create_opts),
+        .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:
+    if (!opts) {
+        qemu_opts_del(cco.opts);
+    }
+    g_free(cco.filename);
+    return ret;
+}
+
+int bdrv_create_file_new(const char *filename, QemuOpts *opts)
+{
+    BlockDriver *drv;
+
+    drv = bdrv_find_protocol(filename, true);
+    if (drv == NULL) {
+        return -ENOENT;
+    }
+
+    return bdrv_create_new(drv, filename, opts);
+}
+
 /*
  * Create a uniquely-named empty temporary file.
  * Return 0 upon success, otherwise a negative errno value.
diff --git a/include/block/block.h b/include/block/block.h
index 742fce5..efcaaa4 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -119,6 +119,8 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
 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);
 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 e45f2a0..fb12bba 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -105,6 +105,7 @@ struct BlockDriver {
     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_set_key)(BlockDriverState *bs, const char *key);
     int (*bdrv_make_empty)(BlockDriverState *bs);
     /* aio */
@@ -195,6 +196,7 @@ struct BlockDriver {
 
     /* List of options for creating images, terminated by name == NULL */
     QEMUOptionParameter *create_options;
+    QemuOptsList *bdrv_create_opts;
 
 
     /*
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 07/25] block: add QemuOpts support for cow.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (5 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 06/25] add interface to block Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 08/25] block: add QemuOpts support for gluster.c Dong Xu Wang
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang


Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/cow.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/block/cow.c b/block/cow.c
index 1cc2e89..3a0d450 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -332,6 +332,83 @@ static QEMUOptionParameter cow_create_options[] = {
     { NULL }
 };
 
+static int cow_create_new(const char *filename, QemuOpts *opts)
+{
+    struct cow_header_v2 cow_header;
+    struct stat st;
+    int64_t image_sectors = 0;
+    char *image_filename = NULL;
+    int ret;
+    BlockDriverState *cow_bs;
+
+    /* Read out 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);
+    if (ret < 0) {
+        goto finish;
+    }
+
+    ret = bdrv_file_open(&cow_bs, filename, NULL, BDRV_O_RDWR);
+    if (ret < 0) {
+        goto finish;
+    }
+
+    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);
+finish:
+    g_free(image_filename);
+    return ret;
+}
+
+static QemuOptsList cow_create_opts = {
+    .name = "cow-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(cow_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_BACKING_FILE,
+            .type = QEMU_OPT_STRING,
+            .help = "File name of a base image"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_cow = {
     .format_name    = "cow",
     .instance_size  = sizeof(BDRVCowState),
@@ -340,6 +417,7 @@ 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,
@@ -347,6 +425,7 @@ static BlockDriver bdrv_cow = {
     .bdrv_co_is_allocated   = cow_co_is_allocated,
 
     .create_options = cow_create_options,
+    .bdrv_create_opts       = &cow_create_opts,
 };
 
 static void bdrv_cow_init(void)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 08/25] block: add QemuOpts support for gluster.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (6 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 07/25] block: add QemuOpts support for cow.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 09/25] block: add QemuOpts support for iscsi.c Dong Xu Wang
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang


Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/gluster.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/block/gluster.c b/block/gluster.c
index 645b7f1..eb9d644 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -407,6 +407,43 @@ out:
     return ret;
 }
 
+static int qemu_gluster_create_new(const char *filename, QemuOpts *opts)
+{
+    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;
+    }
+
+    total_size =
+        qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+
+    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 void qemu_gluster_aio_cancel(BlockDriverAIOCB *blockacb)
 {
     GlusterAIOCB *acb = (GlusterAIOCB *)blockacb;
@@ -635,6 +672,19 @@ static QEMUOptionParameter qemu_gluster_create_options[] = {
     { NULL }
 };
 
+static QemuOptsList qemu_gluster_create_opts = {
+    .name = "qemu-gluster-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_gluster = {
     .format_name                  = "gluster",
     .protocol_name                = "gluster",
@@ -642,6 +692,7 @@ 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,
@@ -653,6 +704,7 @@ static BlockDriver bdrv_gluster = {
     .bdrv_aio_discard             = qemu_gluster_aio_discard,
 #endif
     .create_options               = qemu_gluster_create_options,
+    .bdrv_create_opts             = &qemu_gluster_create_opts,
 };
 
 static BlockDriver bdrv_gluster_tcp = {
@@ -662,6 +714,7 @@ 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,
@@ -673,6 +726,7 @@ static BlockDriver bdrv_gluster_tcp = {
     .bdrv_aio_discard             = qemu_gluster_aio_discard,
 #endif
     .create_options               = qemu_gluster_create_options,
+    .bdrv_create_opts             = &qemu_gluster_create_opts,
 };
 
 static BlockDriver bdrv_gluster_unix = {
@@ -682,6 +736,7 @@ 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,
@@ -693,6 +748,7 @@ static BlockDriver bdrv_gluster_unix = {
     .bdrv_aio_discard             = qemu_gluster_aio_discard,
 #endif
     .create_options               = qemu_gluster_create_options,
+    .bdrv_create_opts             = &qemu_gluster_create_opts,
 };
 
 static BlockDriver bdrv_gluster_rdma = {
@@ -702,6 +758,7 @@ 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,
@@ -713,6 +770,7 @@ static BlockDriver bdrv_gluster_rdma = {
     .bdrv_aio_discard             = qemu_gluster_aio_discard,
 #endif
     .create_options               = qemu_gluster_create_options,
+    .bdrv_create_opts             = &qemu_gluster_create_opts,
 };
 
 static void bdrv_gluster_init(void)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 09/25] block: add QemuOpts support for iscsi.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (7 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 08/25] block: add QemuOpts support for gluster.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 10/25] block: add QemuOpts support for qcow.c Dong Xu Wang
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/iscsi.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/block/iscsi.c b/block/iscsi.c
index e7c1c2b..de2fd8c 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1305,6 +1305,65 @@ static QEMUOptionParameter iscsi_create_options[] = {
     { NULL }
 };
 
+static int iscsi_create_new(const char *filename, QemuOpts *opts)
+{
+    int ret = 0;
+    int64_t total_size = 0;
+    BlockDriverState bs;
+    IscsiLun *iscsilun = NULL;
+    QDict *bs_options;
+
+    memset(&bs, 0, sizeof(BlockDriverState));
+
+    /* Read out options */
+    total_size =
+        qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+    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 QemuOptsList iscsi_create_opts = {
+    .name = "iscsi-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(iscsi_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_iscsi = {
     .format_name     = "iscsi",
     .protocol_name   = "iscsi",
@@ -1313,7 +1372,9 @@ 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,
     .bdrv_truncate   = iscsi_truncate,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 10/25] block: add QemuOpts support for qcow.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (8 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 09/25] block: add QemuOpts support for iscsi.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 11/25] block: add QemuOpts support for qcow2.c Dong Xu Wang
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/qcow.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/block/qcow.c b/block/qcow.c
index 5239bd6..5b572d3 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -755,6 +755,107 @@ exit:
     return ret;
 }
 
+static int qcow_create_new(const char *filename, QemuOpts *opts)
+{
+    int header_size, backing_filename_len, l1_size, shift, i;
+    QCowHeader header;
+    uint8_t *tmp;
+    int64_t total_size = 0;
+    char *backing_file = NULL;
+    int flags = 0;
+    int ret;
+    BlockDriverState *qcow_bs;
+
+    /* Read out opts */
+    total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
+        flags |= BLOCK_FLAG_ENCRYPT;
+    }
+
+    ret = bdrv_create_file_new(filename, opts);
+    if (ret < 0) {
+        goto finish;
+    }
+
+    ret = bdrv_file_open(&qcow_bs, filename, NULL, BDRV_O_RDWR);
+    if (ret < 0) {
+        goto finish;
+    }
+
+    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);
+finish:
+    g_free(backing_file);
+    return ret;
+}
+
 static int qcow_make_empty(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
@@ -864,6 +965,29 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     return 0;
 }
 
+static QemuOptsList qcow_create_opts = {
+    .name = "qcow-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(qcow_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_BACKING_FILE,
+            .type = QEMU_OPT_STRING,
+            .help = "File name of a base image"
+        },
+        {
+            .name = BLOCK_OPT_ENCRYPT,
+            .type = QEMU_OPT_BOOL,
+            .help = "Encrypt the image",
+            .def_value_str = "off"
+        },
+        { /* end of list */ }
+    }
+};
 
 static QEMUOptionParameter qcow_create_options[] = {
     {
@@ -892,6 +1016,7 @@ 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,
@@ -904,6 +1029,7 @@ static BlockDriver bdrv_qcow = {
     .bdrv_get_info          = qcow_get_info,
 
     .create_options = qcow_create_options,
+    .bdrv_create_opts = &qcow_create_opts,
 };
 
 static void bdrv_qcow_init(void)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 11/25] block: add QemuOpts support for qcow2.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (9 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 10/25] block: add QemuOpts support for qcow.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 12/25] block: add QemuOpts support for qed.c Dong Xu Wang
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/qcow2.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 265 insertions(+)

diff --git a/block/qcow2.c b/block/qcow2.c
index 3376901..1c3249d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1460,6 +1460,218 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
                          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)
+{
+    /* Calculate cluster_bits */
+    int cluster_bits;
+    int ret = 0;
+    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));
+        ret = -EINVAL;
+        goto finish;
+    }
+
+    /*
+     * 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;
+
+    ret = bdrv_create_file_new(filename, opts);
+    if (ret < 0) {
+        goto finish;
+    }
+
+    ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR);
+    if (ret < 0) {
+        goto finish;
+    }
+
+    /* 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);
+finish:
+    g_free(backing_file);
+    g_free(backing_format);
+    return ret;
+}
+
+static int qcow2_create_new(const char *filename, QemuOpts *opts)
+{
+    char *backing_file = NULL;
+    char *backing_fmt = NULL;
+    uint64_t sectors = 0;
+    int flags = 0;
+    size_t cluster_size = DEFAULT_CLUSTER_SIZE;
+    int prealloc = 0;
+    int version = 2;
+    char *buf;
+    int ret = 0;
+
+    /* Read out options */
+    sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+    backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
+    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
+        flags |= BLOCK_FLAG_ENCRYPT;
+    }
+    cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
+                                         DEFAULT_CLUSTER_SIZE);
+    buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+    if (!buf || !strcmp(buf, "off")) {
+        prealloc = 0;
+    } else if (!strcmp(buf, "metadata")) {
+        prealloc = 1;
+    } else {
+        fprintf(stderr, "Invalid preallocation mode: '%s'\n",
+            buf);
+        ret = -EINVAL;
+        goto finish;
+    }
+    g_free(buf);
+    buf = qemu_opt_get_del(opts, BLOCK_OPT_COMPAT_LEVEL);
+    if (!buf || !strcmp(buf, "0.10")) {
+        version = 2;
+    } else if (!strcmp(buf, "1.1")) {
+        version = 3;
+    } else {
+        fprintf(stderr, "Invalid compatibility level: '%s'\n",
+            buf);
+        ret = -EINVAL;
+        goto finish;
+    }
+
+    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_LAZY_REFCOUNTS, false)) {
+        flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
+    }
+
+    if (backing_file && prealloc) {
+        fprintf(stderr, "Backing file and preallocation cannot be used at "
+            "the same time\n");
+        ret = -EINVAL;
+        goto finish;
+    }
+
+    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");
+        ret = -EINVAL;
+        goto finish;
+    }
+
+    return qcow2_create2_new(filename, sectors, backing_file, backing_fmt, flags,
+                             cluster_size, prealloc, opts, version);
+finish:
+    g_free(backing_file);
+    g_free(backing_fmt);
+    g_free(buf);
+    return ret;
+}
+
 static int qcow2_make_empty(BlockDriverState *bs)
 {
 #if 0
@@ -1777,6 +1989,57 @@ static QEMUOptionParameter qcow2_create_options[] = {
     { NULL }
 };
 
+static QemuOptsList qcow2_create_opts = {
+    .name = "qcow2-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_COMPAT_LEVEL,
+            .type = QEMU_OPT_STRING,
+            .help = "Compatibility level (0.10 or 1.1)"
+        },
+        {
+            .name = BLOCK_OPT_BACKING_FILE,
+            .type = QEMU_OPT_STRING,
+            .help = "File name of a base image"
+        },
+        {
+            .name = BLOCK_OPT_BACKING_FMT,
+            .type = QEMU_OPT_STRING,
+            .help = "Image format of the base image"
+        },
+        {
+            .name = BLOCK_OPT_ENCRYPT,
+            .type = QEMU_OPT_BOOL,
+            .help = "Encrypt the image",
+            .def_value_str = "off"
+        },
+        {
+            .name = BLOCK_OPT_CLUSTER_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "qcow2 cluster size",
+            .def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
+        },
+        {
+            .name = BLOCK_OPT_PREALLOC,
+            .type = QEMU_OPT_STRING,
+            .help = "Preallocation mode (allowed values: off, metadata)"
+        },
+        {
+            .name = BLOCK_OPT_LAZY_REFCOUNTS,
+            .type = QEMU_OPT_BOOL,
+            .help = "Postpone refcount updates",
+            .def_value_str = "off"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_qcow2 = {
     .format_name        = "qcow2",
     .instance_size      = sizeof(BDRVQcowState),
@@ -1785,6 +2048,7 @@ 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,
@@ -1814,6 +2078,7 @@ 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,
 };
 
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 12/25] block: add QemuOpts support for qed.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (10 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 11/25] block: add QemuOpts support for qcow2.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 13/25] block: add QemuOpts support for raw-posix.c Dong Xu Wang
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/qed.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 block/qed.h |   3 +-
 2 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/block/qed.c b/block/qed.c
index f767b05..348695f 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -651,6 +651,123 @@ static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options)
                       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)
+{
+    uint64_t image_size = 0;
+    uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
+    uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
+    char *backing_file = NULL;
+    char *backing_fmt = NULL;
+    int ret = 0;
+
+    image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+    backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
+    cluster_size = qemu_opt_get_size_del(opts,
+                                         BLOCK_OPT_CLUSTER_SIZE,
+                                         QED_DEFAULT_CLUSTER_SIZE);
+    table_size = qemu_opt_get_size_del(opts, BLOCK_OPT_TABLE_SIZE,
+                                       QED_DEFAULT_TABLE_SIZE);
+
+    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);
+        ret = -EINVAL;
+        goto finish;
+    }
+    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);
+        ret = -EINVAL;
+        goto finish;
+    }
+    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));
+        ret = -EINVAL;
+        goto finish;
+    }
+
+    ret = qed_create_new(filename, cluster_size, image_size, table_size,
+                         backing_file, backing_fmt);
+
+finish:
+    g_free(backing_file);
+    g_free(backing_fmt);
+    return ret;
+}
 typedef struct {
     Coroutine *co;
     int is_allocated;
@@ -1563,10 +1680,45 @@ static QEMUOptionParameter qed_create_options[] = {
     { /* end of list */ }
 };
 
+static QemuOptsList qed_create_opts = {
+    .name = "qed-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(qed_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_BACKING_FILE,
+            .type = QEMU_OPT_STRING,
+            .help = "File name of a base image"
+        },
+        {
+            .name = BLOCK_OPT_BACKING_FMT,
+            .type = QEMU_OPT_STRING,
+            .help = "Image format of the base image"
+        },
+        {
+            .name = BLOCK_OPT_CLUSTER_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Cluster size (in bytes)",
+            .def_value_str = stringify(QED_DEFAULT_CLUSTER_SIZE),
+        },
+        {
+            .name = BLOCK_OPT_TABLE_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "L1/L2 table size (in clusters)"
+        },
+        { /* end of list */ }
+    }
+};
+
 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,
     .bdrv_rebind              = bdrv_qed_rebind,
@@ -1574,6 +1726,7 @@ 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/qed.h b/block/qed.h
index 2b4dded..29e1619 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -44,6 +44,8 @@
  * All fields are little-endian on disk.
  */
 
+#define  QED_DEFAULT_CLUSTER_SIZE  65536
+
 enum {
     QED_MAGIC = 'Q' | 'E' << 8 | 'D' << 16 | '\0' << 24,
 
@@ -69,7 +71,6 @@ enum {
      */
     QED_MIN_CLUSTER_SIZE = 4 * 1024, /* in bytes */
     QED_MAX_CLUSTER_SIZE = 64 * 1024 * 1024,
-    QED_DEFAULT_CLUSTER_SIZE = 64 * 1024,
 
     /* Allocated clusters are tracked using a 2-level pagetable.  Table size is
      * a multiple of clusters so large maximum image sizes can be supported
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 13/25] block: add QemuOpts support for raw-posix.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (11 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 12/25] block: add QemuOpts support for qed.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 14/25] block: add QemuOpts support for raw-win32.c Dong Xu Wang
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/raw-posix.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index ba721d3..528b3d1 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1069,6 +1069,29 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
     return result;
 }
 
+static int raw_create_new(const char *filename, QemuOpts *opts)
+{
+    int fd;
+    int result = 0;
+    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_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;
+}
+
 /*
  * Returns true iff the specified sector is present in the disk image. Drivers
  * not implementing the functionality are assumed to not support backing files,
@@ -1188,6 +1211,19 @@ static QEMUOptionParameter raw_create_options[] = {
     { NULL }
 };
 
+static QemuOptsList raw_create_opts = {
+    .name = "raw-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_file = {
     .format_name = "file",
     .protocol_name = "file",
@@ -1199,6 +1235,7 @@ 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,
 
@@ -1213,6 +1250,7 @@ static BlockDriver bdrv_file = {
                         = raw_get_allocated_file_size,
 
     .create_options = raw_create_options,
+    .bdrv_create_opts = &raw_create_opts,
 };
 
 /***********************************************/
@@ -1528,6 +1566,33 @@ 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",
@@ -1539,7 +1604,9 @@ 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,
     .bdrv_aio_writev	= raw_aio_writev,
@@ -1663,7 +1730,9 @@ 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_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
@@ -1764,7 +1833,9 @@ 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_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
@@ -1885,7 +1956,9 @@ 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_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 14/25] block: add QemuOpts support for raw-win32.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (12 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 13/25] block: add QemuOpts support for raw-posix.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 15/25] block: add QemuOpts support for raw.c Dong Xu Wang
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/raw-win32.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/block/raw-win32.c b/block/raw-win32.c
index 9b5b2af..78efc63 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -452,6 +452,40 @@ static QEMUOptionParameter raw_create_options[] = {
     { NULL }
 };
 
+
+static int raw_create_new(const char *filename, QemuOpts *opts)
+{
+    int fd;
+    int64_t total_size = 0;
+
+    /* Read out options */
+
+    total_size =
+        qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+
+    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 QemuOptsList raw_create_opts = {
+    .name = "raw-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_file = {
     .format_name	= "file",
     .protocol_name	= "file",
@@ -459,6 +493,7 @@ 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,
@@ -471,6 +506,7 @@ static BlockDriver bdrv_file = {
                         = raw_get_allocated_file_size,
 
     .create_options = raw_create_options,
+    .bdrv_create_opts   = &raw_create_opts,
 };
 
 /***********************************************/
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 15/25] block: add QemuOpts support for raw.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (13 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 14/25] block: add QemuOpts support for raw-win32.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 16/25] block: add QemuOpts support for rbd.c Dong Xu Wang
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/raw.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/block/raw.c b/block/raw.c
index 4751825..7636f6b 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -139,6 +139,24 @@ static QEMUOptionParameter raw_create_options[] = {
     { NULL }
 };
 
+static int raw_create_new(const char *filename, QemuOpts *opts)
+{
+    return bdrv_create_file_new(filename, opts);
+}
+
+static QemuOptsList raw_create_opts = {
+    .name = "raw-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        { /* end of list */ }
+    }
+};
+
 static int raw_has_zero_init(BlockDriverState *bs)
 {
     return bdrv_has_zero_init(bs->file);
@@ -180,7 +198,9 @@ 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,
 };
 
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 16/25] block: add QemuOpts support for rbd.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (14 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 15/25] block: add QemuOpts support for raw.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 17/25] block: add QemuOpts support for sheepdog.c Dong Xu Wang
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/rbd.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/block/rbd.c b/block/rbd.c
index cb71751..4d5897c 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -368,6 +368,80 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options)
     return ret;
 }
 
+static int qemu_rbd_create_new(const char *filename, QemuOpts *opts)
+{
+    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 */
+    bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+    objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0);
+    if (objsize) {
+        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;
+    }
+
+    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;
+}
+
 /*
  * This aio completion is being called from qemu_rbd_aio_event_reader()
  * and runs in qemu context. It schedules a bh, but just in case the aio
@@ -990,15 +1064,36 @@ static QEMUOptionParameter qemu_rbd_create_options[] = {
     {NULL}
 };
 
+static QemuOptsList qemu_rbd_create_opts = {
+    .name = "rbd-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_rbd_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_CLUSTER_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "RBD object size",
+            .def_value_str = stringify(0),
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_rbd = {
     .format_name        = "rbd",
     .instance_size      = sizeof(BDRVRBDState),
     .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,
     .protocol_name      = "rbd",
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 17/25] block: add QemuOpts support for sheepdog.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (15 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 16/25] block: add QemuOpts support for rbd.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 18/25] block: add QemuOpts support for ssh.c Dong Xu Wang
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Conflicts:
	block/sheepdog.c

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/sheepdog.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index afe0533..b09b4fa 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1546,6 +1546,92 @@ out:
     return ret;
 }
 
+static int sd_create_new(const char *filename, QemuOpts *opts)
+{
+    int ret = 0;
+    uint32_t vid = 0, base_vid = 0;
+    int64_t vdi_size = 0;
+    char *backing_file = NULL, *buf = 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;
+    }
+
+    vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+    buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+    if (!buf || !strcmp(buf, "off")) {
+        prealloc = false;
+    } else if (!strcmp(buf, "full")) {
+        prealloc = true;
+    } else {
+        error_report("Invalid preallocation mode: '%s'", buf);
+        ret = -EINVAL;
+        goto out;
+    }
+    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(backing_file);
+    g_free(buf);
+    g_free(s);
+    return ret;
+}
+
 static void sd_close(BlockDriverState *bs)
 {
     BDRVSheepdogState *s = bs->opaque;
@@ -2340,6 +2426,29 @@ static QEMUOptionParameter sd_create_options[] = {
     { NULL }
 };
 
+static QemuOptsList sd_create_opts = {
+    .name = "sheepdog-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(sd_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_BACKING_FILE,
+            .type = QEMU_OPT_STRING,
+            .help = "File name of a base image"
+        },
+        {
+            .name = BLOCK_OPT_PREALLOC,
+            .type = QEMU_OPT_STRING,
+            .help = "Preallocation mode (allowed values: off, full)"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_sheepdog = {
     .format_name    = "sheepdog",
     .protocol_name  = "sheepdog",
@@ -2347,6 +2456,7 @@ 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,
@@ -2366,6 +2476,7 @@ static BlockDriver bdrv_sheepdog = {
     .bdrv_load_vmstate  = sd_load_vmstate,
 
     .create_options = sd_create_options,
+    .bdrv_create_opts   = &sd_create_opts,
 };
 
 static BlockDriver bdrv_sheepdog_tcp = {
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 18/25] block: add QemuOpts support for ssh.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (16 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 17/25] block: add QemuOpts support for sheepdog.c Dong Xu Wang
@ 2013-08-13  4:31 ` Dong Xu Wang
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 19/25] block: add QemuOpts support for vdi.c Dong Xu Wang
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/ssh.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/block/ssh.c b/block/ssh.c
index d7e7bf8..7f1d5d7 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -709,6 +709,73 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options)
     return ret;
 }
 
+static QemuOptsList ssh_create_opts = {
+    .name = "ssh-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(ssh_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        { /* end of list */ }
+    }
+};
+
+static int ssh_create_new(const char *filename, QemuOpts *opts)
+{
+    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. */
+    total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+    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 void ssh_close(BlockDriverState *bs)
 {
     BDRVSSHState *s = bs->opaque;
@@ -1051,6 +1118,7 @@ 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,
@@ -1058,6 +1126,7 @@ static BlockDriver bdrv_ssh = {
     .bdrv_getlength               = ssh_getlength,
     .bdrv_co_flush_to_disk        = ssh_co_flush,
     .create_options               = ssh_create_options,
+    .bdrv_create_opts             = &ssh_create_opts,
 };
 
 static void bdrv_ssh_init(void)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 19/25] block: add QemuOpts support for vdi.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (17 preceding siblings ...)
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 18/25] block: add QemuOpts support for ssh.c Dong Xu Wang
@ 2013-08-13  4:32 ` Dong Xu Wang
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 20/25] block: add QemuOpts support for vmdk.c Dong Xu Wang
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/vdi.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/block/vdi.c b/block/vdi.c
index 8a91525..50bf24f 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -736,6 +736,102 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
     return result;
 }
 
+static int vdi_create_new(const char *filename, QemuOpts *opts)
+{
+    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. */
+    bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+#if defined(CONFIG_VDI_BLOCK_SIZE)
+    /* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
+    block_size = qemu_opt_get_size_del(opts,
+                                       BLOCK_OPT_CLUSTER_SIZE,
+                                       DEFAULT_CLUSTER_SIZE);
+#endif
+#if defined(CONFIG_VDI_STATIC_IMAGE)
+    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_STATIC, false)) {
+        image_type = VDI_TYPE_STATIC;
+    }
+#endif
+
+    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 void vdi_close(BlockDriverState *bs)
 {
     BDRVVdiState *s = bs->opaque;
@@ -771,6 +867,36 @@ static QEMUOptionParameter vdi_create_options[] = {
     { NULL }
 };
 
+static QemuOptsList vdi_create_opts = {
+    .name = "vdi-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(vdi_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+#if defined(CONFIG_VDI_BLOCK_SIZE)
+        {
+            .name = BLOCK_OPT_CLUSTER_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "VDI cluster (block) size",
+            .def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
+        },
+#endif
+#if defined(CONFIG_VDI_STATIC_IMAGE)
+        {
+            .name = BLOCK_OPT_STATIC,
+            .type = QEMU_OPT_BOOL,
+            .help = "VDI static (pre-allocated) image",
+            .def_value_str = "off"
+        },
+#endif
+        /* TODO: An additional option to set UUID values might be useful. */
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_vdi = {
     .format_name = "vdi",
     .instance_size = sizeof(BDRVVdiState),
@@ -779,6 +905,7 @@ 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,
@@ -791,6 +918,7 @@ 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,
 };
 
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 20/25] block: add QemuOpts support for vmdk.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (18 preceding siblings ...)
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 19/25] block: add QemuOpts support for vdi.c Dong Xu Wang
@ 2013-08-13  4:32 ` Dong Xu Wang
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 21/25] block: add QemuOpts support for vpc.c Dong Xu Wang
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/vmdk.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 236 insertions(+)

diff --git a/block/vmdk.c b/block/vmdk.c
index 346bb5c..5452aa2 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1720,6 +1720,197 @@ exit:
     return ret;
 }
 
+static int vmdk_create_new(const char *filename, QemuOpts *opts)
+{
+    int fd, idx = 0;
+    char desc[BUF_SIZE];
+    int64_t total_size = 0, filesize;
+    char *adapter_type = NULL;
+    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)) {
+        ret = -EINVAL;
+        goto finish;
+    }
+    /* Read out opts */
+    total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+    adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
+    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) {
+        flags |= BLOCK_FLAG_COMPAT6;
+    }
+    fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
+    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
+        zeroed_grain = true;
+    }
+    if (!adapter_type) {
+        adapter_type = g_strdup("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);
+        ret = -EINVAL;
+        goto finish;
+    }
+    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);
+        ret = -EINVAL;
+        goto finish;
+    }
+    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 */
+        ret = -ENOTSUP;
+        goto finish;
+    }
+    if (backing_file) {
+        BlockDriverState *bs = bdrv_new("");
+        ret = bdrv_open(bs, backing_file, NULL, 0, NULL);
+        if (ret != 0) {
+            bdrv_delete(bs);
+            goto finish;
+        }
+        if (strcmp(bs->drv->format_name, "vmdk")) {
+            bdrv_delete(bs);
+            ret = -EINVAL;
+            goto finish;
+        }
+        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) {
+        ret = -errno;
+        goto finish;
+    }
+    /* 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);
+finish:
+    g_free(adapter_type);
+    g_free(backing_file);
+    return ret;
+}
+
 static void vmdk_close(BlockDriverState *bs)
 {
     BDRVVmdkState *s = bs->opaque;
@@ -1823,6 +2014,49 @@ static QEMUOptionParameter vmdk_create_options[] = {
     { NULL }
 };
 
+static QemuOptsList vmdk_create_opts = {
+    .name = "vmdk-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(vmdk_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_ADAPTER_TYPE,
+            .type = QEMU_OPT_STRING,
+            .help = "Virtual adapter type, can be one of "
+                    "ide (default), lsilogic, buslogic or legacyESX"
+        },
+        {
+            .name = BLOCK_OPT_BACKING_FILE,
+            .type = QEMU_OPT_STRING,
+            .help = "File name of a base image"
+        },
+        {
+            .name = BLOCK_OPT_COMPAT6,
+            .type = QEMU_OPT_BOOL,
+            .help = "VMDK version 6 image",
+            .def_value_str = "off"
+        },
+        {
+            .name = BLOCK_OPT_SUBFMT,
+            .type = QEMU_OPT_STRING,
+            .help =
+                "VMDK flat extent format, can be one of "
+                "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
+        },
+        {
+            .name = BLOCK_OPT_ZEROED_GRAIN,
+            .type = QEMU_OPT_BOOL,
+            .help = "Enable efficient zero writes "
+                    "using the zeroed-grain GTE feature"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_vmdk = {
     .format_name                  = "vmdk",
     .instance_size                = sizeof(BDRVVmdkState),
@@ -1834,12 +2068,14 @@ 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,
 };
 
 static void bdrv_vmdk_init(void)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 21/25] block: add QemuOpts support for vpc.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (19 preceding siblings ...)
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 20/25] block: add QemuOpts support for vmdk.c Dong Xu Wang
@ 2013-08-13  4:32 ` Dong Xu Wang
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 22/25] block: add QemuOpts support for block.c Dong Xu Wang
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/vpc.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/block/vpc.c b/block/vpc.c
index fe4f311..aa1263a 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -786,6 +786,109 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options)
     return ret;
 }
 
+static int vpc_create_new(const char *filename, QemuOpts *opts)
+{
+    uint8_t buf[1024];
+    struct vhd_footer *footer = (struct vhd_footer *) buf;
+    char *disk_type_param = NULL;
+    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 = 0;
+    int disk_type = VHD_DYNAMIC;
+    int ret = -EIO;
+
+    /* Read out opts */
+    total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+    disk_type_param = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
+    if (disk_type_param) {
+        if (!strcmp(disk_type_param, "dynamic")) {
+            disk_type = VHD_DYNAMIC;
+        } else if (!strcmp(disk_type_param, "fixed")) {
+            disk_type = VHD_FIXED;
+        } else {
+            ret = -EINVAL;
+            goto finish;
+        }
+    }
+
+    /* Create the file */
+    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+    if (fd < 0) {
+        ret = -EIO;
+        goto finish;
+    }
+
+    /*
+     * 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);
+finish:
+    g_free(disk_type_param);
+    return ret;
+}
+
 static int vpc_has_zero_init(BlockDriverState *bs)
 {
     BDRVVPCState *s = bs->opaque;
@@ -826,6 +929,26 @@ static QEMUOptionParameter vpc_create_options[] = {
     { NULL }
 };
 
+static QemuOptsList vpc_create_opts = {
+    .name = "vpc-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_SUBFMT,
+            .type = QEMU_OPT_STRING,
+            .help =
+                "Type of virtual hard disk format. Supported formats are "
+                "{dynamic (default) | fixed} "
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriver bdrv_vpc = {
     .format_name    = "vpc",
     .instance_size  = sizeof(BDRVVPCState),
@@ -835,11 +958,13 @@ 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,
 };
 
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 22/25] block: add QemuOpts support for block.c
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (20 preceding siblings ...)
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 21/25] block: add QemuOpts support for vpc.c Dong Xu Wang
@ 2013-08-13  4:32 ` Dong Xu Wang
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 23/25] block: clean temp code and use QemuOpts in block Dong Xu Wang
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang


Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block.c | 86 ++++++++++++++++++++++++++++++-----------------------------------
 1 file changed, 39 insertions(+), 47 deletions(-)

diff --git a/block.c b/block.c
index 25090dc..9f52341 100644
--- a/block.c
+++ b/block.c
@@ -375,7 +375,7 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
     CreateCo *cco = opaque;
     assert(cco->drv);
 
-    cco->ret = cco->drv->bdrv_create(cco->filename, cco->options);
+    cco->ret = cco->drv->bdrv_create_new(cco->filename, cco->opts);
 }
 
 int bdrv_create(BlockDriver *drv, const char* filename,
@@ -1036,7 +1036,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
         BlockDriverState *bs1;
         int64_t total_size;
         BlockDriver *bdrv_qcow2;
-        QEMUOptionParameter *create_options;
+        QemuOpts *opts;
         char backing_filename[PATH_MAX];
 
         if (qdict_size(options) != 0) {
@@ -1075,19 +1075,16 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
         }
 
         bdrv_qcow2 = bdrv_find_format("qcow2");
-        create_options = parse_option_parameters("", bdrv_qcow2->create_options,
-                                                 NULL);
+        opts = qemu_opts_create_nofail(bdrv_qcow2->bdrv_create_opts);
 
-        set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
-        set_option_parameter(create_options, BLOCK_OPT_BACKING_FILE,
-                             backing_filename);
+        qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
+        qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, backing_filename);
         if (drv) {
-            set_option_parameter(create_options, BLOCK_OPT_BACKING_FMT,
-                drv->format_name);
+            qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, drv->format_name);
         }
 
-        ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options);
-        free_option_parameters(create_options);
+        ret = bdrv_create_new(bdrv_qcow2, tmp_filename, opts);
+        qemu_opts_del(opts);
         if (ret < 0) {
             goto fail;
         }
@@ -4519,8 +4516,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;
+    QemuOpts *opts = NULL;
+    QemuOptsList *create_opts = NULL;
+    const char *backing_fmt, *backing_file;
+    int64_t size;
     BlockDriverState *bs = NULL;
     BlockDriver *drv, *proto_drv;
     BlockDriver *backing_drv = NULL;
@@ -4538,28 +4537,23 @@ void bdrv_img_create(const char *filename, const char *fmt,
         error_setg(errp, "Unknown protocol '%s'", filename);
         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(drv->bdrv_create_opts,
+                                   proto_drv->bdrv_create_opts);
     /* Create parameter list with default values */
-    param = parse_option_parameters("", create_options, param);
+    opts = qemu_opts_create_nofail(create_opts);
 
-    set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
+    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) {
+        if (qemu_opts_do_parse_replace(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,
+        if (qemu_opt_replace_set(opts, BLOCK_OPT_BACKING_FILE,
                                  base_filename)) {
             error_setg(errp, "Backing file not supported for file format '%s'",
                        fmt);
@@ -4568,39 +4562,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_replace_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);
+            error_setg(errp, "Unknown backing file format '%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) {
             uint64_t size;
-            char buf[32];
             int back_flags;
 
             /* backing files always opened read-only */
@@ -4609,18 +4601,16 @@ void bdrv_img_create(const char *filename, const char *fmt,
 
             bs = bdrv_new("");
 
-            ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
-                            backing_drv);
+            ret = bdrv_open(bs, backing_file, NULL, back_flags, backing_drv);
             if (ret < 0) {
                 error_setg_errno(errp, -ret, "Could not open '%s'",
-                                 backing_file->value.s);
+                                 backing_file);
                 goto out;
             }
             bdrv_get_geometry(bs, &size);
             size *= 512;
 
-            snprintf(buf, sizeof(buf), "%" PRId64, size);
-            set_option_parameter(param, BLOCK_OPT_SIZE, buf);
+            qemu_opt_replace_set_number(opts, BLOCK_OPT_SIZE, size);
         } else {
             error_setg(errp, "Image creation needs a size parameter");
             goto out;
@@ -4629,17 +4619,17 @@ 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);
+    ret = bdrv_create_new(drv, filename, opts);
     if (ret < 0) {
         if (ret == -ENOTSUP) {
             error_setg(errp,"Formatting or formatting option not supported for "
                             "file format '%s'", fmt);
         } else if (ret == -EFBIG) {
             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'%s",
@@ -4651,8 +4641,10 @@ void bdrv_img_create(const char *filename, const char *fmt,
     }
 
 out:
-    free_option_parameters(create_options);
-    free_option_parameters(param);
+    if (opts) {
+        qemu_opts_del(opts);
+    }
+    qemu_opts_free(create_opts);
 
     if (bs) {
         bdrv_delete(bs);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 23/25] block: clean temp code and use QemuOpts in block
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (21 preceding siblings ...)
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 22/25] block: add QemuOpts support for block.c Dong Xu Wang
@ 2013-08-13  4:32 ` Dong Xu Wang
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str Dong Xu Wang
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 25/25] qemu-option: remove QEMUOptionParameter related functions and struct Dong Xu Wang
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

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 --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);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (22 preceding siblings ...)
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 23/25] block: clean temp code and use QemuOpts in block Dong Xu Wang
@ 2013-08-13  4:32 ` Dong Xu Wang
  2013-08-27 14:12   ` Kevin Wolf
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 25/25] qemu-option: remove QEMUOptionParameter related functions and struct Dong Xu Wang
  24 siblings, 1 reply; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

QMP command query-command-line-options shows details information of
parameters, since added def_value_str, also output it in the QMP
command.

v16->v17:
1) add "Since 1.6" tag.
2) rename def_str_value to "default".

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 qapi-schema.json   | 8 ++++++--
 qmp-commands.hx    | 2 ++
 util/qemu-config.c | 4 ++++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index a51f7d2..aa18d84 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3630,12 +3630,16 @@
 #
 # @help: #optional human readable text string, not suitable for parsing.
 #
-# Since 1.5
+# @default: #optional string representation of the default used
+#           if the option is omitted.
+#
+# Since 1.6
 ##
 { 'type': 'CommandLineParameterInfo',
   'data': { 'name': 'str',
             'type': 'CommandLineParameterType',
-            '*help': 'str' } }
+            '*help': 'str',
+            '*default': 'str'} }
 
 ##
 # @CommandLineOptionInfo:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index cf47e3f..3c6ab30 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2575,6 +2575,8 @@ Each array entry contains the following:
               or 'size')
     - "help": human readable description of the parameter
               (json-string, optional)
+    - "default": default value string for the parameter
+                 (json-string, optional)
 
 Example:
 
diff --git a/util/qemu-config.c b/util/qemu-config.c
index a59568d..315ecbf 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -67,6 +67,10 @@ static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
             info->has_help = true;
             info->help = g_strdup(desc[i].help);
         }
+        if (desc[i].def_value_str) {
+            info->has_q_default = true;
+            info->q_default = g_strdup(desc[i].def_value_str);
+        }
 
         entry = g_malloc0(sizeof(*entry));
         entry->value = info;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [Qemu-devel] [PATCH V18 25/25] qemu-option: remove QEMUOptionParameter related functions and struct
  2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
                   ` (23 preceding siblings ...)
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str Dong Xu Wang
@ 2013-08-13  4:32 ` Dong Xu Wang
  24 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-13  4:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, wdongxu, stefanha, Dong Xu Wang

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

Conflicts:
	include/qemu/option.h
---
 block.c               |   1 -
 include/qemu/option.h |  39 -------
 util/qemu-option.c    | 285 --------------------------------------------------
 3 files changed, 325 deletions(-)

diff --git a/block.c b/block.c
index c1130b8..e7ed659 100644
--- a/block.c
+++ b/block.c
@@ -365,7 +365,6 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
 typedef struct CreateCo {
     BlockDriver *drv;
     char *filename;
-    QEMUOptionParameter *options;
     QemuOpts *opts;
     int ret;
 } CreateCo;
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 64d7327..c7c8379 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -31,24 +31,6 @@
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 
-enum QEMUOptionParType {
-    OPT_FLAG,
-    OPT_NUMBER,
-    OPT_SIZE,
-    OPT_STRING,
-};
-
-typedef struct QEMUOptionParameter {
-    const char *name;
-    enum QEMUOptionParType type;
-    union {
-        uint64_t n;
-        char* s;
-    } value;
-    const char *help;
-} QEMUOptionParameter;
-
-
 const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
 const char *get_opt_value(char *buf, int buf_size, const char *p);
 int get_next_param_value(char *buf, int buf_size,
@@ -56,29 +38,8 @@ int get_next_param_value(char *buf, int buf_size,
 int get_param_value(char *buf, int buf_size,
                     const char *tag, const char *str);
 
-
-/*
- * The following functions take a parameter list as input. This is a pointer to
- * the first element of a QEMUOptionParameter array which is terminated by an
- * entry with entry->name == NULL.
- */
-
-QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
-    const char *name);
-int set_option_parameter(QEMUOptionParameter *list, const char *name,
-    const char *value);
-int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
-    uint64_t value);
-QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
-    QEMUOptionParameter *list);
-QEMUOptionParameter *parse_option_parameters(const char *param,
-    QEMUOptionParameter *list, QEMUOptionParameter *dest);
 void parse_option_size(const char *name, const char *value,
                        uint64_t *ret, Error **errp);
-void free_option_parameters(QEMUOptionParameter *list);
-void print_option_parameters(QEMUOptionParameter *list);
-void print_option_help(QEMUOptionParameter *list);
-
 /* ------------------------------------------------------------------ */
 
 typedef struct QemuOpt QemuOpt;
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 861929d..94e0339 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -123,22 +123,6 @@ int get_param_value(char *buf, int buf_size,
     return get_next_param_value(buf, buf_size, tag, &str);
 }
 
-/*
- * Searches an option list for an option with the given name
- */
-QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
-    const char *name)
-{
-    while (list && list->name) {
-        if (!strcmp(list->name, name)) {
-            return list;
-        }
-        list++;
-    }
-
-    return NULL;
-}
-
 static void parse_option_bool(const char *name, const char *value, bool *ret,
                               Error **errp)
 {
@@ -212,275 +196,6 @@ void parse_option_size(const char *name, const char *value,
     }
 }
 
-/*
- * Sets the value of a parameter in a given option list. The parsing of the
- * value depends on the type of option:
- *
- * OPT_FLAG (uses value.n):
- *      If no value is given, the flag is set to 1.
- *      Otherwise the value must be "on" (set to 1) or "off" (set to 0)
- *
- * OPT_STRING (uses value.s):
- *      value is strdup()ed and assigned as option value
- *
- * OPT_SIZE (uses value.n):
- *      The value is converted to an integer. Suffixes for kilobytes etc. are
- *      allowed (powers of 1024).
- *
- * Returns 0 on succes, -1 in error cases
- */
-int set_option_parameter(QEMUOptionParameter *list, const char *name,
-    const char *value)
-{
-    bool flag;
-    Error *local_err = NULL;
-
-    // Find a matching parameter
-    list = get_option_parameter(list, name);
-    if (list == NULL) {
-        fprintf(stderr, "Unknown option '%s'\n", name);
-        return -1;
-    }
-
-    // Process parameter
-    switch (list->type) {
-    case OPT_FLAG:
-        parse_option_bool(name, value, &flag, &local_err);
-        if (!error_is_set(&local_err)) {
-            list->value.n = flag;
-        }
-        break;
-
-    case OPT_STRING:
-        if (value != NULL) {
-            list->value.s = g_strdup(value);
-        } else {
-            fprintf(stderr, "Option '%s' needs a parameter\n", name);
-            return -1;
-        }
-        break;
-
-    case OPT_SIZE:
-        parse_option_size(name, value, &list->value.n, &local_err);
-        break;
-
-    default:
-        fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
-        return -1;
-    }
-
-    if (error_is_set(&local_err)) {
-        qerror_report_err(local_err);
-        error_free(local_err);
-        return -1;
-    }
-
-    return 0;
-}
-
-/*
- * Sets the given parameter to an integer instead of a string.
- * This function cannot be used to set string options.
- *
- * Returns 0 on success, -1 in error cases
- */
-int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
-    uint64_t value)
-{
-    // Find a matching parameter
-    list = get_option_parameter(list, name);
-    if (list == NULL) {
-        fprintf(stderr, "Unknown option '%s'\n", name);
-        return -1;
-    }
-
-    // Process parameter
-    switch (list->type) {
-    case OPT_FLAG:
-    case OPT_NUMBER:
-    case OPT_SIZE:
-        list->value.n = value;
-        break;
-
-    default:
-        return -1;
-    }
-
-    return 0;
-}
-
-/*
- * Frees a option list. If it contains strings, the strings are freed as well.
- */
-void free_option_parameters(QEMUOptionParameter *list)
-{
-    QEMUOptionParameter *cur = list;
-
-    while (cur && cur->name) {
-        if (cur->type == OPT_STRING) {
-            g_free(cur->value.s);
-        }
-        cur++;
-    }
-
-    g_free(list);
-}
-
-/*
- * Count valid options in list
- */
-static size_t count_option_parameters(QEMUOptionParameter *list)
-{
-    size_t num_options = 0;
-
-    while (list && list->name) {
-        num_options++;
-        list++;
-    }
-
-    return num_options;
-}
-
-/*
- * Append an option list (list) to an option list (dest).
- *
- * If dest is NULL, a new copy of list is created.
- *
- * Returns a pointer to the first element of dest (or the newly allocated copy)
- */
-QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
-    QEMUOptionParameter *list)
-{
-    size_t num_options, num_dest_options;
-
-    num_options = count_option_parameters(dest);
-    num_dest_options = num_options;
-
-    num_options += count_option_parameters(list);
-
-    dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
-    dest[num_dest_options].name = NULL;
-
-    while (list && list->name) {
-        if (get_option_parameter(dest, list->name) == NULL) {
-            dest[num_dest_options++] = *list;
-            dest[num_dest_options].name = NULL;
-        }
-        list++;
-    }
-
-    return dest;
-}
-
-/*
- * Parses a parameter string (param) into an option list (dest).
- *
- * list is the template option list. If dest is NULL, a new copy of list is
- * created. If list is NULL, this function fails.
- *
- * A parameter string consists of one or more parameters, separated by commas.
- * Each parameter consists of its name and possibly of a value. In the latter
- * case, the value is delimited by an = character. To specify a value which
- * contains commas, double each comma so it won't be recognized as the end of
- * the parameter.
- *
- * For more details of the parsing see above.
- *
- * Returns a pointer to the first element of dest (or the newly allocated copy)
- * or NULL in error cases
- */
-QEMUOptionParameter *parse_option_parameters(const char *param,
-    QEMUOptionParameter *list, QEMUOptionParameter *dest)
-{
-    QEMUOptionParameter *allocated = NULL;
-    char name[256];
-    char value[256];
-    char *param_delim, *value_delim;
-    char next_delim;
-
-    if (list == NULL) {
-        return NULL;
-    }
-
-    if (dest == NULL) {
-        dest = allocated = append_option_parameters(NULL, list);
-    }
-
-    while (*param) {
-
-        // Find parameter name and value in the string
-        param_delim = strchr(param, ',');
-        value_delim = strchr(param, '=');
-
-        if (value_delim && (value_delim < param_delim || !param_delim)) {
-            next_delim = '=';
-        } else {
-            next_delim = ',';
-            value_delim = NULL;
-        }
-
-        param = get_opt_name(name, sizeof(name), param, next_delim);
-        if (value_delim) {
-            param = get_opt_value(value, sizeof(value), param + 1);
-        }
-        if (*param != '\0') {
-            param++;
-        }
-
-        // Set the parameter
-        if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
-            goto fail;
-        }
-    }
-
-    return dest;
-
-fail:
-    // Only free the list if it was newly allocated
-    free_option_parameters(allocated);
-    return NULL;
-}
-
-/*
- * Prints all options of a list that have a value to stdout
- */
-void print_option_parameters(QEMUOptionParameter *list)
-{
-    while (list && list->name) {
-        switch (list->type) {
-            case OPT_STRING:
-                 if (list->value.s != NULL) {
-                     printf("%s='%s' ", list->name, list->value.s);
-                 }
-                break;
-            case OPT_FLAG:
-                printf("%s=%s ", list->name, list->value.n ? "on" : "off");
-                break;
-            case OPT_SIZE:
-            case OPT_NUMBER:
-                printf("%s=%" PRId64 " ", list->name, list->value.n);
-                break;
-            default:
-                printf("%s=(unknown type) ", list->name);
-                break;
-        }
-        list++;
-    }
-}
-
-/*
- * Prints an overview of all available options
- */
-void print_option_help(QEMUOptionParameter *list)
-{
-    printf("Supported options:\n");
-    while (list && list->name) {
-        printf("%-16s %s\n", list->name,
-            list->help ? list->help : "No description available");
-        list++;
-    }
-}
-
 /* ------------------------------------------------------------------ */
 
 static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print Dong Xu Wang
@ 2013-08-27 13:49   ` Kevin Wolf
  2013-08-28  8:55     ` Dong Xu Wang
  2013-08-28 12:53   ` Eric Blake
  1 sibling, 1 reply; 39+ messages in thread
From: Kevin Wolf @ 2013-08-27 13:49 UTC (permalink / raw)
  To: Dong Xu Wang; +Cc: wdongxu, qemu-devel, stefanha

Am 13.08.2013 um 06:31 hat Dong Xu Wang geschrieben:
> qemu_opts_print has no user now, so can re-write the function safely.
> 
> qemu_opts_print is used while using "qemu-img create", it
> produces the same output as previous code.
> 
> The behavior of this function has changed:
> 
> 1. Print every possible option, whether a value has been set or not.
> 2. Option descriptors may provide a default value.
> 3. Print to stdout instead of stderr.
> 
> Previously the behavior was to print every option that has been set.
> Options that have not been set would be skipped.
> 
> v17->v18:
> 1) print opt->value.uint directly while type is QEMU_OPT_SIZE. 
> 
> v13->v14:
> 1) fix memory leak.
> 2) make opt_set do not accpet null value argument.
> 
> v12->v13
> 1) re-write commit message.
> 
> v11->v12
> 1) make def_value_str become the real default value string in opt_set
> function.
> 
> v10->v11:
> 1) print all values that have actually been assigned while accept-any
> cases.
> 
> v7->v8:
> 1) print "elements => accept any params" while opts_accepts_any() ==
> true.
> 2) since def_print_str is the default value if an option isn't set,
> so rename it to def_value_str.
> 
> Reviewed-by: Eric Blake <eblake@redhat.com>
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> ---

Please put the version history after the "---" line so that git am
removes it when applying the patch.

>  include/qemu/option.h |  3 ++-
>  util/qemu-option.c    | 34 ++++++++++++++++++++++++++++------
>  2 files changed, 30 insertions(+), 7 deletions(-)
> 
> diff --git a/include/qemu/option.h b/include/qemu/option.h
> index 7a58e47..bbbdea3 100644
> --- a/include/qemu/option.h
> +++ b/include/qemu/option.h
> @@ -96,6 +96,7 @@ typedef struct QemuOptDesc {
>      const char *name;
>      enum QemuOptType type;
>      const char *help;
> +    const char *def_value_str;
>  } QemuOptDesc;
>  
>  struct QemuOptsList {
> @@ -153,7 +154,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
>  void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
>  
>  typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
> -int qemu_opts_print(QemuOpts *opts, void *dummy);
> +int qemu_opts_print(QemuOpts *opts);

Should be a void function, it can only return 0 anyway.

Kevin

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 03/25] qemu-option: create four QemuOptsList related functions
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 03/25] qemu-option: create four QemuOptsList related functions Dong Xu Wang
@ 2013-08-27 13:54   ` Kevin Wolf
  0 siblings, 0 replies; 39+ messages in thread
From: Kevin Wolf @ 2013-08-27 13:54 UTC (permalink / raw)
  To: Dong Xu Wang; +Cc: wdongxu, qemu-devel, stefanha

Am 13.08.2013 um 06:31 hat Dong Xu Wang geschrieben:
> This patch creates 4 functions, count_opts_list, qemu_opts_append,
> qemu_opts_free and qemu_opts_print_help, they are used in following
> commits.
> 
> v16->v17:
> 1) fix indentation.
> 2) fix typo.
> 
> v15->v16:
> 1) discard double-initialization.
> 2) use pointer directly, not g_strdup.
> 
> v12->v13:
> 1) simply assert that neither argument has merge_lists set.
> 2) drop superfluous paranthesesis around p == first.
> 
> v11->v12:
> 1) renmae functions.
> 2) fix loop styles and code styles.
> 3) qemu_opts_apend will not return NULL now.
> 4) merge_lists value is from arguments in qemu_opts_append.
> 
> v6->v7:
> 1) Fix typo.
> 
> v5->v6:
> 1) allocate enough space in append_opts_list function.
> 
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> ---
>  include/qemu/option.h |  3 +++
>  util/qemu-option.c    | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 76 insertions(+)
> 
> diff --git a/include/qemu/option.h b/include/qemu/option.h
> index bbbdea3..3b514bb 100644
> --- a/include/qemu/option.h
> +++ b/include/qemu/option.h
> @@ -158,4 +158,7 @@ int qemu_opts_print(QemuOpts *opts);
>  int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
>                        int abort_on_failure);
>  
> +QemuOptsList *qemu_opts_append(QemuOptsList *first, QemuOptsList *second);
> +void qemu_opts_free(QemuOptsList *list);
> +void qemu_opts_print_help(QemuOptsList *list);
>  #endif
> diff --git a/util/qemu-option.c b/util/qemu-option.c
> index a3c3c17..2a5447c 100644
> --- a/util/qemu-option.c
> +++ b/util/qemu-option.c
> @@ -1201,3 +1201,76 @@ int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
>      loc_pop(&loc);
>      return rc;
>  }
> +
> +static size_t count_opts_list(QemuOptsList *list)
> +{
> +    size_t i;
> +
> +    for (i = 0; list && list->desc[i].name; i++) {
> +        ;
> +    }
> +
> +    return i;
> +}
> +
> +/* Create a new QemuOptsList with a desc of the merge of the first
> + * and second. It will allocate space for one new QemuOptsList plus
> + * enough space for QemuOptDesc in first and second QemuOptsList.
> + * First argument's QemuOptDesc members take precedence over second's.
> + * The result's name and implied_opt_name are not copied from them.
> + * Both merge_lists should not be set. Both lists can be NULL.
> + */
> +QemuOptsList *qemu_opts_append(QemuOptsList *first,
> +                               QemuOptsList *second)
> +{
> +    size_t num_first_opts, num_second_opts;
> +    QemuOptsList *dest = NULL;
> +    int i;
> +    int index = 0;
> +    QemuOptsList *p = first;
> +
> +    num_first_opts = count_opts_list(first);
> +    num_second_opts = count_opts_list(second);
> +
> +    dest = g_malloc0(sizeof(QemuOptsList)
> +        + (num_first_opts + num_second_opts + 1) * sizeof(QemuOptDesc));
> +
> +    dest->name = "append_opts_list";
> +    dest->implied_opt_name = NULL;
> +    assert((!first || !first->merge_lists)
> +           && (!second || !second->merge_lists));
> +    QTAILQ_INIT(&dest->head);
> +
> +    for (i = 0; p && p->desc[i].name; i++) {
> +        if (!find_desc_by_name(dest->desc, p->desc[i].name)) {
> +            dest->desc[index].name = p->desc[i].name;
> +            dest->desc[index].help = p->desc[i].help;
> +            dest->desc[index].type = p->desc[i].type;
> +            dest->desc[index].def_value_str =  p->desc[i].def_value_str;

Can be simplified as:

dest->desc[index] = p->desc[i];

> +            index++;
> +        }
> +        if (p == first && p && !p->desc[i].name) {
> +            p = second;
> +            i = 0;
> +        }

And then the loop body is small enough that you don't have to iterate
two arrays in one loop and confuse readers, but can use two separate
loops.

> +    }
> +    dest->desc[index].name = NULL;
> +    return dest;
> +}
> +
> +/* free a QemuOptsList, can accept NULL as arguments */
> +void qemu_opts_free(QemuOptsList *list)
> +{
> +    g_free(list);
> +}
> +
> +void qemu_opts_print_help(QemuOptsList *list)
> +{
> +    int i;
> +    printf("Supported options:\n");
> +    for (i = 0; list && list->desc[i].name; i++) {
> +        printf("%-16s %s\n", list->desc[i].name,
> +               list->desc[i].help ?
> +               list->desc[i].help : "No description available");

Is "No description available" a helpful string or should we just print
an empty string?

Kevin

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 04/25] qemu-option: create some QemuOpts functons
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 04/25] qemu-option: create some QemuOpts functons Dong Xu Wang
@ 2013-08-27 13:58   ` Kevin Wolf
  0 siblings, 0 replies; 39+ messages in thread
From: Kevin Wolf @ 2013-08-27 13:58 UTC (permalink / raw)
  To: Dong Xu Wang; +Cc: wdongxu, qemu-devel, stefanha

Am 13.08.2013 um 06:31 hat Dong Xu Wang geschrieben:
> These functions will be used in next commit.
> 
> qemu_opt_get_(*)_del functions are used to make sure we
> have the same behaviors as before: in block layer, after
> parsing a parameter value, parameter list will delete it
> to avoid parsing it twice.
> 
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> 
> v16->v17:
> 1) return "char *" instead of "const char*"
> 
> v13->v14:
> 1) rewrite commit message.
> 2) use def_value_str in qemu_opt_get_FOO_del() and qemu_opt_get_del().
> 3) delete redundant qemu_opt_del(opt).
> ---
>  include/qemu/option.h |  11 ++++-
>  util/qemu-option.c    | 130 ++++++++++++++++++++++++++++++++++++++++++++------
>  2 files changed, 125 insertions(+), 16 deletions(-)
> 
> diff --git a/include/qemu/option.h b/include/qemu/option.h
> index 3b514bb..64d7327 100644
> --- a/include/qemu/option.h
> +++ b/include/qemu/option.h
> @@ -108,6 +108,7 @@ struct QemuOptsList {
>  };
>  
>  const char *qemu_opt_get(QemuOpts *opts, const char *name);
> +char *qemu_opt_get_del(QemuOpts *opts, const char *name);
>  /**
>   * qemu_opt_has_help_opt:
>   * @opts: options to search for a help request
> @@ -121,14 +122,19 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name);
>   */
>  bool qemu_opt_has_help_opt(QemuOpts *opts);
>  bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
> +bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval);
>  uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
>  uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
>  int qemu_opt_unset(QemuOpts *opts, const char *name);
> +uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
> +                               uint64_t defval);
>  int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
> +int qemu_opt_replace_set(QemuOpts *opts, const char *name, const char *value);
>  void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
>                        Error **errp);
>  int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val);
>  int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val);
> +int qemu_opt_replace_set_number(QemuOpts *opts, const char *name, int64_t val);
>  typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque);
>  int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
>                       int abort_on_failure);
> @@ -145,7 +151,10 @@ const char *qemu_opts_id(QemuOpts *opts);
>  void qemu_opts_del(QemuOpts *opts);
>  void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
>  int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
> -QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int permit_abbrev);
> +int qemu_opts_do_parse_replace(QemuOpts *opts, const char *params,
> +                               const char *firstname);
> +QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
> +                          int permit_abbrev);
>  void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
>                              int permit_abbrev);
>  QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
> diff --git a/util/qemu-option.c b/util/qemu-option.c
> index 2a5447c..b939e8a 100644
> --- a/util/qemu-option.c
> +++ b/util/qemu-option.c
> @@ -523,6 +523,32 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
>      return opt ? opt->str : NULL;
>  }
>  
> +static void qemu_opt_del(QemuOpt *opt)
> +{
> +    QTAILQ_REMOVE(&opt->opts->head, opt, next);
> +    g_free((/* !const */ char*)opt->name);
> +    g_free((/* !const */ char*)opt->str);
> +    g_free(opt);
> +}
> +
> +char *qemu_opt_get_del(QemuOpts *opts, const char *name)
> +{
> +    QemuOpt *opt = qemu_opt_find(opts, name);
> +    const QemuOptDesc *desc;
> +    char *str = NULL;
> +
> +    if (!opt) {
> +        desc = find_desc_by_name(opts->list->desc, name);
> +        if (desc && desc->def_value_str) {
> +            str = g_strdup(desc->def_value_str);
> +        }
> +    } else {
> +        str = g_strdup(opt->str);
> +        qemu_opt_del(opt);
> +    }
> +    return str;
> +}

This is almost duplicating qemu_opt_get(). Can't it be a thin wrapper
around the original function?

Also, any reason to g_strdup() here when the original function returns a
reference to the existing string? This makes the interface inconsistent.

Same comments apply to qemu_opt_get_bool_del() and
qemu_opt_get_size_del().

Kevin

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 05/25] qemu-option: opt->str store digit, without suffixes
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 05/25] qemu-option: opt->str store digit, without suffixes Dong Xu Wang
@ 2013-08-27 14:01   ` Kevin Wolf
  0 siblings, 0 replies; 39+ messages in thread
From: Kevin Wolf @ 2013-08-27 14:01 UTC (permalink / raw)
  To: Dong Xu Wang; +Cc: wdongxu, qemu-devel, stefanha

Am 13.08.2013 um 06:31 hat Dong Xu Wang geschrieben:
> To produce same output while using "qemu-img create", opt->str
> should store pure digit, without suffixes.
> 
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> ---
>  util/qemu-option.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/util/qemu-option.c b/util/qemu-option.c
> index b939e8a..861929d 100644
> --- a/util/qemu-option.c
> +++ b/util/qemu-option.c
> @@ -675,6 +675,8 @@ static void qemu_opt_parse(QemuOpt *opt, Error **errp)
>          break;
>      case QEMU_OPT_SIZE:
>          parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
> +        g_free((char *)opt->str);
> +        opt->str = g_strdup(stringify(opt->value_uint));

This is wrong, stringify() is a macro at compile time. You get
"opt->value_uint" for any option here.

You're probably looking for g_strdup_printf().

Kevin

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 06/25] add interface to block
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 06/25] add interface to block Dong Xu Wang
@ 2013-08-27 14:08   ` Kevin Wolf
  0 siblings, 0 replies; 39+ messages in thread
From: Kevin Wolf @ 2013-08-27 14:08 UTC (permalink / raw)
  To: Dong Xu Wang; +Cc: wdongxu, qemu-devel, stefanha

Am 13.08.2013 um 06:31 hat Dong Xu Wang geschrieben:
> Subject: Re: [PATCH V18 06/25] add interface to block

This is _not_ a good subject line.

> To make patches easy for reviewing, each block format is
> a single patch. Add a new interface to block layer to make
> sure origin code can compile and do not change any code
> logic.
> 
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>

I believe that adding a second copy of each creation function actually
makes reviewing harder than just changing the option parsing part in it.

Kevin

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str
  2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str Dong Xu Wang
@ 2013-08-27 14:12   ` Kevin Wolf
  2013-08-27 23:13     ` Eric Blake
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Wolf @ 2013-08-27 14:12 UTC (permalink / raw)
  To: Dong Xu Wang; +Cc: wdongxu, qemu-devel, stefanha

Am 13.08.2013 um 06:32 hat Dong Xu Wang geschrieben:
> QMP command query-command-line-options shows details information of
> parameters, since added def_value_str, also output it in the QMP
> command.
> 
> v16->v17:
> 1) add "Since 1.6" tag.
> 2) rename def_str_value to "default".
> 
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> ---
>  qapi-schema.json   | 8 ++++++--
>  qmp-commands.hx    | 2 ++
>  util/qemu-config.c | 4 ++++
>  3 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/qapi-schema.json b/qapi-schema.json
> index a51f7d2..aa18d84 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3630,12 +3630,16 @@
>  #
>  # @help: #optional human readable text string, not suitable for parsing.
>  #
> -# Since 1.5
> +# @default: #optional string representation of the default used
> +#           if the option is omitted.
> +#
> +# Since 1.6

The "Since 1.6" belongs to the @default field only. The command as a
whole is still "Since 1.5".

Kevin

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str
  2013-08-27 14:12   ` Kevin Wolf
@ 2013-08-27 23:13     ` Eric Blake
  2013-08-28  8:57       ` Dong Xu Wang
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Blake @ 2013-08-27 23:13 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: wdongxu, Dong Xu Wang, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 1033 bytes --]

On 08/27/2013 08:12 AM, Kevin Wolf wrote:
> Am 13.08.2013 um 06:32 hat Dong Xu Wang geschrieben:
>> QMP command query-command-line-options shows details information of
>> parameters, since added def_value_str, also output it in the QMP
>> command.
>>
>> v16->v17:
>> 1) add "Since 1.6" tag.
>> 2) rename def_str_value to "default".

>> +++ b/qapi-schema.json
>> @@ -3630,12 +3630,16 @@
>>  #
>>  # @help: #optional human readable text string, not suitable for parsing.
>>  #
>> -# Since 1.5
>> +# @default: #optional string representation of the default used
>> +#           if the option is omitted.
>> +#
>> +# Since 1.6
> 
> The "Since 1.6" belongs to the @default field only. The command as a
> whole is still "Since 1.5".

Further, 1.6 is already released, so this should now be:

@default #optional string representation of the default used if
         the option is omitted (since 1.7).

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print
  2013-08-27 13:49   ` Kevin Wolf
@ 2013-08-28  8:55     ` Dong Xu Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-28  8:55 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: wdongxu, qemu-devel, stefanha

On 2013/8/27 21:49, Kevin Wolf wrote:
> Am 13.08.2013 um 06:31 hat Dong Xu Wang geschrieben:
>> qemu_opts_print has no user now, so can re-write the function safely.
>>
>> qemu_opts_print is used while using "qemu-img create", it
>> produces the same output as previous code.
>>
>> The behavior of this function has changed:
>>
>> 1. Print every possible option, whether a value has been set or not.
>> 2. Option descriptors may provide a default value.
>> 3. Print to stdout instead of stderr.
>>
>> Previously the behavior was to print every option that has been set.
>> Options that have not been set would be skipped.
>>
>> v17->v18:
>> 1) print opt->value.uint directly while type is QEMU_OPT_SIZE.
>>
>> v13->v14:
>> 1) fix memory leak.
>> 2) make opt_set do not accpet null value argument.
>>
>> v12->v13
>> 1) re-write commit message.
>>
>> v11->v12
>> 1) make def_value_str become the real default value string in opt_set
>> function.
>>
>> v10->v11:
>> 1) print all values that have actually been assigned while accept-any
>> cases.
>>
>> v7->v8:
>> 1) print "elements => accept any params" while opts_accepts_any() ==
>> true.
>> 2) since def_print_str is the default value if an option isn't set,
>> so rename it to def_value_str.
>>
>> Reviewed-by: Eric Blake <eblake@redhat.com>
>> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
>> ---
>
> Please put the version history after the "---" line so that git am
> removes it when applying the patch.
>
Okay.
>>   include/qemu/option.h |  3 ++-
>>   util/qemu-option.c    | 34 ++++++++++++++++++++++++++++------
>>   2 files changed, 30 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/qemu/option.h b/include/qemu/option.h
>> index 7a58e47..bbbdea3 100644
>> --- a/include/qemu/option.h
>> +++ b/include/qemu/option.h
>> @@ -96,6 +96,7 @@ typedef struct QemuOptDesc {
>>       const char *name;
>>       enum QemuOptType type;
>>       const char *help;
>> +    const char *def_value_str;
>>   } QemuOptDesc;
>>
>>   struct QemuOptsList {
>> @@ -153,7 +154,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
>>   void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
>>
>>   typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
>> -int qemu_opts_print(QemuOpts *opts, void *dummy);
>> +int qemu_opts_print(QemuOpts *opts);
>
> Should be a void function, it can only return 0 anyway.
>
Okay.
Thanks Kevin, and together with other comments, I will send a new version.
> Kevin
>
>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str
  2013-08-27 23:13     ` Eric Blake
@ 2013-08-28  8:57       ` Dong Xu Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-28  8:57 UTC (permalink / raw)
  To: Eric Blake; +Cc: Kevin Wolf, wdongxu, qemu-devel, stefanha

On 2013/8/28 7:13, Eric Blake wrote:
> On 08/27/2013 08:12 AM, Kevin Wolf wrote:
>> Am 13.08.2013 um 06:32 hat Dong Xu Wang geschrieben:
>>> QMP command query-command-line-options shows details information of
>>> parameters, since added def_value_str, also output it in the QMP
>>> command.
>>>
>>> v16->v17:
>>> 1) add "Since 1.6" tag.
>>> 2) rename def_str_value to "default".
>
>>> +++ b/qapi-schema.json
>>> @@ -3630,12 +3630,16 @@
>>>   #
>>>   # @help: #optional human readable text string, not suitable for parsing.
>>>   #
>>> -# Since 1.5
>>> +# @default: #optional string representation of the default used
>>> +#           if the option is omitted.
>>> +#
>>> +# Since 1.6
>>
>> The "Since 1.6" belongs to the @default field only. The command as a
>> whole is still "Since 1.5".
>
> Further, 1.6 is already released, so this should now be:
>
> @default #optional string representation of the default used if
>           the option is omitted (since 1.7).
Okay, the description is precise. Thanks :)
>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print Dong Xu Wang
  2013-08-27 13:49   ` Kevin Wolf
@ 2013-08-28 12:53   ` Eric Blake
  2013-08-29  1:49     ` Dong Xu Wang
  1 sibling, 1 reply; 39+ messages in thread
From: Eric Blake @ 2013-08-28 12:53 UTC (permalink / raw)
  To: Dong Xu Wang; +Cc: kwolf, wdongxu, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 1328 bytes --]

On 08/12/2013 10:31 PM, Dong Xu Wang wrote:
> qemu_opts_print has no user now, so can re-write the function safely.
> 
> qemu_opts_print is used while using "qemu-img create", it
> produces the same output as previous code.
> 
> The behavior of this function has changed:
> 
> 1. Print every possible option, whether a value has been set or not.
> 2. Option descriptors may provide a default value.
> 3. Print to stdout instead of stderr.
> 
> Previously the behavior was to print every option that has been set.
> Options that have not been set would be skipped.
> 
> v17->v18:
> 1) print opt->value.uint directly while type is QEMU_OPT_SIZE. 

When making a change to a previously-reviewed patch, unrelated to the
reviewer's comments...

> 
> Reviewed-by: Eric Blake <eblake@redhat.com>
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>

...it is probably better to drop the earlier Reviewed-by: to make sure
that the change gets properly reviewed.  Keeping a Reviewed-by makes
sense only when carrying a patch with no changes, or when the set of
changes made are trivial in nature (such as whitespace cleanups) or
explicitly mentioned as the changes desired by the reviewer.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 02/25] qemu-option: avoid duplication of default value in QemuOpts
  2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 02/25] qemu-option: avoid duplication of default value in QemuOpts Dong Xu Wang
@ 2013-08-28 12:57   ` Eric Blake
  2013-08-29  1:49     ` Dong Xu Wang
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Blake @ 2013-08-28 12:57 UTC (permalink / raw)
  To: Dong Xu Wang; +Cc: kwolf, wdongxu, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 931 bytes --]

On 08/12/2013 10:31 PM, Dong Xu Wang wrote:
> This patch moves the default value entirely to QemuOptDesc.
> 
> When getting the value of an option that hasn't been set, and
> QemuOptDesc has a default value, return that.  Else, behave as
> before.
> 
...
>    Else, return NULL.
> 
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> 
> v13->v14:
> 1) change code style.
> 2) assert errors.
> 
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> 
> Conflicts:
> 	util/qemu-option.c
> ---

Awkward.  You should never have a 'Conflicts:' section on an upstream
patch (except for maintainers resolving trivial conflicts during a merge
operation); and this is another case of needing to move your submission
changelog after the ---.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 02/25] qemu-option: avoid duplication of default value in QemuOpts
  2013-08-28 12:57   ` Eric Blake
@ 2013-08-29  1:49     ` Dong Xu Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-29  1:49 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, wdongxu, qemu-devel, stefanha

On 2013/8/28 20:57, Eric Blake wrote:
> On 08/12/2013 10:31 PM, Dong Xu Wang wrote:
>> This patch moves the default value entirely to QemuOptDesc.
>>
>> When getting the value of an option that hasn't been set, and
>> QemuOptDesc has a default value, return that.  Else, behave as
>> before.
>>
> ...
>>     Else, return NULL.
>>
>> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
>> Reviewed-by: Eric Blake <eblake@redhat.com>
>>
>> v13->v14:
>> 1) change code style.
>> 2) assert errors.
>>
>> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
>>
>> Conflicts:
>> 	util/qemu-option.c
>> ---
>
> Awkward.  You should never have a 'Conflicts:' section on an upstream
> patch (except for maintainers resolving trivial conflicts during a merge
> operation); and this is another case of needing to move your submission
> changelog after the ---.
>
Okay, thank you, Eric.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print
  2013-08-28 12:53   ` Eric Blake
@ 2013-08-29  1:49     ` Dong Xu Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Dong Xu Wang @ 2013-08-29  1:49 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, wdongxu, qemu-devel, stefanha

On 2013/8/28 20:53, Eric Blake wrote:
> On 08/12/2013 10:31 PM, Dong Xu Wang wrote:
>> qemu_opts_print has no user now, so can re-write the function safely.
>>
>> qemu_opts_print is used while using "qemu-img create", it
>> produces the same output as previous code.
>>
>> The behavior of this function has changed:
>>
>> 1. Print every possible option, whether a value has been set or not.
>> 2. Option descriptors may provide a default value.
>> 3. Print to stdout instead of stderr.
>>
>> Previously the behavior was to print every option that has been set.
>> Options that have not been set would be skipped.
>>
>> v17->v18:
>> 1) print opt->value.uint directly while type is QEMU_OPT_SIZE.
>
> When making a change to a previously-reviewed patch, unrelated to the
> reviewer's comments...
>
>>
>> Reviewed-by: Eric Blake <eblake@redhat.com>
>> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
>
> ...it is probably better to drop the earlier Reviewed-by: to make sure
> that the change gets properly reviewed.  Keeping a Reviewed-by makes
> sense only when carrying a patch with no changes, or when the set of
> changes made are trivial in nature (such as whitespace cleanups) or
> explicitly mentioned as the changes desired by the reviewer.
>
Okay, thank you, Eric.

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2013-08-29  1:50 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-13  4:31 [Qemu-devel] [PATCH V18 00/25] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 01/25] qemu-option: add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print Dong Xu Wang
2013-08-27 13:49   ` Kevin Wolf
2013-08-28  8:55     ` Dong Xu Wang
2013-08-28 12:53   ` Eric Blake
2013-08-29  1:49     ` Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 02/25] qemu-option: avoid duplication of default value in QemuOpts Dong Xu Wang
2013-08-28 12:57   ` Eric Blake
2013-08-29  1:49     ` Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 03/25] qemu-option: create four QemuOptsList related functions Dong Xu Wang
2013-08-27 13:54   ` Kevin Wolf
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 04/25] qemu-option: create some QemuOpts functons Dong Xu Wang
2013-08-27 13:58   ` Kevin Wolf
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 05/25] qemu-option: opt->str store digit, without suffixes Dong Xu Wang
2013-08-27 14:01   ` Kevin Wolf
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 06/25] add interface to block Dong Xu Wang
2013-08-27 14:08   ` Kevin Wolf
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 07/25] block: add QemuOpts support for cow.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 08/25] block: add QemuOpts support for gluster.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 09/25] block: add QemuOpts support for iscsi.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 10/25] block: add QemuOpts support for qcow.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 11/25] block: add QemuOpts support for qcow2.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 12/25] block: add QemuOpts support for qed.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 13/25] block: add QemuOpts support for raw-posix.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 14/25] block: add QemuOpts support for raw-win32.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 15/25] block: add QemuOpts support for raw.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 16/25] block: add QemuOpts support for rbd.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 17/25] block: add QemuOpts support for sheepdog.c Dong Xu Wang
2013-08-13  4:31 ` [Qemu-devel] [PATCH V18 18/25] block: add QemuOpts support for ssh.c Dong Xu Wang
2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 19/25] block: add QemuOpts support for vdi.c Dong Xu Wang
2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 20/25] block: add QemuOpts support for vmdk.c Dong Xu Wang
2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 21/25] block: add QemuOpts support for vpc.c Dong Xu Wang
2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 22/25] block: add QemuOpts support for block.c Dong Xu Wang
2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 23/25] block: clean temp code and use QemuOpts in block Dong Xu Wang
2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str Dong Xu Wang
2013-08-27 14:12   ` Kevin Wolf
2013-08-27 23:13     ` Eric Blake
2013-08-28  8:57       ` Dong Xu Wang
2013-08-13  4:32 ` [Qemu-devel] [PATCH V18 25/25] qemu-option: remove QEMUOptionParameter related functions and struct Dong Xu Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).