qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3] vdi: Implement .bdrv_co_create
@ 2018-03-12 16:55 Max Reitz
  2018-03-12 16:55 ` [Qemu-devel] [PATCH 1/3] vdi: Pull option parsing from vdi_co_create Max Reitz
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Max Reitz @ 2018-03-12 16:55 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Max Reitz, Stefan Weil, Kevin Wolf, Eric Blake

I think cluster-size should not be exposed in QAPI (yet), but Kevin's
patch does that, while I had these patches lying around, so here is my
proposal.


Max Reitz (3):
  vdi: Pull option parsing from vdi_co_create
  vdi: Move file creation to vdi_co_create_opts
  vdi: Implement .bdrv_co_create

 qapi/block-core.json |  20 +++++++-
 block/vdi.c          | 139 +++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 132 insertions(+), 27 deletions(-)

-- 
2.14.3

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

* [Qemu-devel] [PATCH 1/3] vdi: Pull option parsing from vdi_co_create
  2018-03-12 16:55 [Qemu-devel] [PATCH 0/3] vdi: Implement .bdrv_co_create Max Reitz
@ 2018-03-12 16:55 ` Max Reitz
  2018-03-12 16:55 ` [Qemu-devel] [PATCH 2/3] vdi: Move file creation to vdi_co_create_opts Max Reitz
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Max Reitz @ 2018-03-12 16:55 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Max Reitz, Stefan Weil, Kevin Wolf, Eric Blake

In preparation of QAPI-fying VDI image creation, we have to create a
BlockdevCreateOptionsVdi type which is received by a (future)
vdi_co_create().

vdi_co_create_opts() now converts the QemuOpts object into such a
BlockdevCreateOptionsVdi object.  The protocol-layer file is still
created in vdi_co_do_create() (and BlockdevCreateOptionsVdi.file is set
to an empty string), but that will be addressed by a follow-up patch.

Note that cluster-size is not part of the QAPI schema because it is not
supported by default.

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 qapi/block-core.json | 18 +++++++++++
 block/vdi.c          | 91 ++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 95 insertions(+), 14 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 524d51567a..e7110c9a47 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3606,6 +3606,24 @@
   'data': { 'location':         'BlockdevOptionsSsh',
             'size':             'size' } }
 
+##
+# @BlockdevCreateOptionsVdi:
+#
+# Driver specific image creation options for VDI.
+#
+# @file             Node to create the image format on
+# @size             Size of the virtual disk in bytes
+# @static           Whether to create a statically (true) or
+#                   dynamically (false) allocated image
+#                   (default: false, i.e. dynamic)
+#
+# Since: 2.12
+##
+{ 'struct': 'BlockdevCreateOptionsVdi',
+  'data': { 'file':             'BlockdevRef',
+            'size':             'size',
+            '*static':          'bool' } }
+
 ##
 # @BlockdevCreateNotSupported:
 #
diff --git a/block/vdi.c b/block/vdi.c
index 2b5ddd0666..0c8f8204ce 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -51,6 +51,9 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qapi-visit-block-core.h"
 #include "block/block_int.h"
 #include "sysemu/block-backend.h"
 #include "qemu/module.h"
@@ -140,6 +143,8 @@
 #define VDI_DISK_SIZE_MAX        ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
                                   (uint64_t)DEFAULT_CLUSTER_SIZE)
 
+static QemuOptsList vdi_create_opts;
+
 typedef struct {
     char text[0x40];
     uint32_t signature;
@@ -716,13 +721,14 @@ nonallocating_write:
     return ret;
 }
 
-static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
-                                           Error **errp)
+static int coroutine_fn vdi_co_do_create(const char *filename,
+                                         QemuOpts *file_opts,
+                                         BlockdevCreateOptionsVdi *vdi_opts,
+                                         size_t block_size, Error **errp)
 {
     int ret = 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;
@@ -735,18 +741,25 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
     logout("\n");
 
     /* Read out options. */
-    bytes = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-                     BDRV_SECTOR_SIZE);
-#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)) {
+    bytes = vdi_opts->size;
+    if (vdi_opts->q_static) {
         image_type = VDI_TYPE_STATIC;
     }
+#ifndef CONFIG_VDI_STATIC_IMAGE
+    if (image_type == VDI_TYPE_STATIC) {
+        ret = -ENOTSUP;
+        error_setg(errp, "Statically allocated images cannot be created in "
+                   "this build");
+        goto exit;
+    }
+#endif
+#ifndef CONFIG_VDI_BLOCK_SIZE
+    if (block_size != DEFAULT_CLUSTER_SIZE) {
+        ret = -ENOTSUP;
+        error_setg(errp,
+                   "A non-default cluster size is not supported in this build");
+        goto exit;
+    }
 #endif
 
     if (bytes > VDI_DISK_SIZE_MAX) {
@@ -757,7 +770,7 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
         goto exit;
     }
 
-    ret = bdrv_create_file(filename, opts, &local_err);
+    ret = bdrv_create_file(filename, file_opts, &local_err);
     if (ret < 0) {
         error_propagate(errp, local_err);
         goto exit;
@@ -847,6 +860,56 @@ exit:
     return ret;
 }
 
+static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
+                                           Error **errp)
+{
+    QDict *qdict = NULL;
+    BlockdevCreateOptionsVdi *create_options = NULL;
+    uint64_t block_size = DEFAULT_CLUSTER_SIZE;
+    Visitor *v;
+    Error *local_err = NULL;
+    int ret;
+
+    /* Since CONFIG_VDI_BLOCK_SIZE is disabled by default,
+     * cluster-size is not part of the QAPI schema; therefore we have
+     * to parse it before creating the QAPI object. */
+#if defined(CONFIG_VDI_BLOCK_SIZE)
+    block_size = qemu_opt_get_size_del(opts,
+                                       BLOCK_OPT_CLUSTER_SIZE,
+                                       DEFAULT_CLUSTER_SIZE);
+    if (block_size < BDRV_SECTOR_SIZE || block_size > UINT32_MAX ||
+        !is_power_of_2(block_size))
+    {
+        error_setg(errp, "Invalid cluster size");
+        ret = -EINVAL;
+        goto done;
+    }
+#endif
+
+    qdict = qemu_opts_to_qdict_filtered(opts, NULL, &vdi_create_opts, true);
+
+    qdict_put_str(qdict, "file", ""); /* FIXME */
+
+    /* Get the QAPI object */
+    v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+    visit_type_BlockdevCreateOptionsVdi(v, NULL, &create_options, &local_err);
+    visit_free(v);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    create_options->size = ROUND_UP(create_options->size, BDRV_SECTOR_SIZE);
+
+    ret = vdi_co_do_create(filename, opts, create_options, block_size, errp);
+done:
+    QDECREF(qdict);
+    qapi_free_BlockdevCreateOptionsVdi(create_options);
+    return ret;
+}
+
 static void vdi_close(BlockDriverState *bs)
 {
     BDRVVdiState *s = bs->opaque;
-- 
2.14.3

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

* [Qemu-devel] [PATCH 2/3] vdi: Move file creation to vdi_co_create_opts
  2018-03-12 16:55 [Qemu-devel] [PATCH 0/3] vdi: Implement .bdrv_co_create Max Reitz
  2018-03-12 16:55 ` [Qemu-devel] [PATCH 1/3] vdi: Pull option parsing from vdi_co_create Max Reitz
@ 2018-03-12 16:55 ` Max Reitz
  2018-03-12 16:55 ` [Qemu-devel] [PATCH 3/3] vdi: Implement .bdrv_co_create Max Reitz
  2018-03-13 10:22 ` [Qemu-devel] [PATCH 0/3] " Kevin Wolf
  3 siblings, 0 replies; 5+ messages in thread
From: Max Reitz @ 2018-03-12 16:55 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Max Reitz, Stefan Weil, Kevin Wolf, Eric Blake

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block/vdi.c | 46 ++++++++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/block/vdi.c b/block/vdi.c
index 0c8f8204ce..2a39b0ac98 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -721,9 +721,7 @@ nonallocating_write:
     return ret;
 }
 
-static int coroutine_fn vdi_co_do_create(const char *filename,
-                                         QemuOpts *file_opts,
-                                         BlockdevCreateOptionsVdi *vdi_opts,
+static int coroutine_fn vdi_co_do_create(BlockdevCreateOptionsVdi *vdi_opts,
                                          size_t block_size, Error **errp)
 {
     int ret = 0;
@@ -734,7 +732,7 @@ static int coroutine_fn vdi_co_do_create(const char *filename,
     size_t i;
     size_t bmap_size;
     int64_t offset = 0;
-    Error *local_err = NULL;
+    BlockDriverState *bs_file = NULL;
     BlockBackend *blk = NULL;
     uint32_t *bmap = NULL;
 
@@ -770,18 +768,15 @@ static int coroutine_fn vdi_co_do_create(const char *filename,
         goto exit;
     }
 
-    ret = bdrv_create_file(filename, file_opts, &local_err);
-    if (ret < 0) {
-        error_propagate(errp, local_err);
+    bs_file = bdrv_open_blockdev_ref(vdi_opts->file, errp);
+    if (!bs_file) {
+        ret = -EIO;
         goto exit;
     }
 
-    blk = blk_new_open(filename, NULL, NULL,
-                       BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
-                       &local_err);
-    if (blk == NULL) {
-        error_propagate(errp, local_err);
-        ret = -EIO;
+    blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
+    ret = blk_insert_bs(blk, bs_file, errp);
+    if (ret < 0) {
         goto exit;
     }
 
@@ -818,7 +813,7 @@ static int coroutine_fn vdi_co_do_create(const char *filename,
     vdi_header_to_le(&header);
     ret = blk_pwrite(blk, offset, &header, sizeof(header), 0);
     if (ret < 0) {
-        error_setg(errp, "Error writing header to %s", filename);
+        error_setg(errp, "Error writing header");
         goto exit;
     }
     offset += sizeof(header);
@@ -839,7 +834,7 @@ static int coroutine_fn vdi_co_do_create(const char *filename,
         }
         ret = blk_pwrite(blk, offset, bmap, bmap_size, 0);
         if (ret < 0) {
-            error_setg(errp, "Error writing bmap to %s", filename);
+            error_setg(errp, "Error writing bmap");
             goto exit;
         }
         offset += bmap_size;
@@ -849,13 +844,14 @@ static int coroutine_fn vdi_co_do_create(const char *filename,
         ret = blk_truncate(blk, offset + blocks * block_size,
                            PREALLOC_MODE_OFF, errp);
         if (ret < 0) {
-            error_prepend(errp, "Failed to statically allocate %s", filename);
+            error_prepend(errp, "Failed to statically allocate file");
             goto exit;
         }
     }
 
 exit:
     blk_unref(blk);
+    bdrv_unref(bs_file);
     g_free(bmap);
     return ret;
 }
@@ -865,6 +861,7 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
 {
     QDict *qdict = NULL;
     BlockdevCreateOptionsVdi *create_options = NULL;
+    BlockDriverState *bs_file = NULL;
     uint64_t block_size = DEFAULT_CLUSTER_SIZE;
     Visitor *v;
     Error *local_err = NULL;
@@ -888,7 +885,19 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
 
     qdict = qemu_opts_to_qdict_filtered(opts, NULL, &vdi_create_opts, true);
 
-    qdict_put_str(qdict, "file", ""); /* FIXME */
+    ret = bdrv_create_file(filename, opts, errp);
+    if (ret < 0) {
+        goto done;
+    }
+
+    bs_file = bdrv_open(filename, NULL, NULL,
+                        BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
+    if (!bs_file) {
+        ret = -EIO;
+        goto done;
+    }
+
+    qdict_put_str(qdict, "file", bs_file->node_name);
 
     /* Get the QAPI object */
     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
@@ -903,10 +912,11 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
 
     create_options->size = ROUND_UP(create_options->size, BDRV_SECTOR_SIZE);
 
-    ret = vdi_co_do_create(filename, opts, create_options, block_size, errp);
+    ret = vdi_co_do_create(create_options, block_size, errp);
 done:
     QDECREF(qdict);
     qapi_free_BlockdevCreateOptionsVdi(create_options);
+    bdrv_unref(bs_file);
     return ret;
 }
 
-- 
2.14.3

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

* [Qemu-devel] [PATCH 3/3] vdi: Implement .bdrv_co_create
  2018-03-12 16:55 [Qemu-devel] [PATCH 0/3] vdi: Implement .bdrv_co_create Max Reitz
  2018-03-12 16:55 ` [Qemu-devel] [PATCH 1/3] vdi: Pull option parsing from vdi_co_create Max Reitz
  2018-03-12 16:55 ` [Qemu-devel] [PATCH 2/3] vdi: Move file creation to vdi_co_create_opts Max Reitz
@ 2018-03-12 16:55 ` Max Reitz
  2018-03-13 10:22 ` [Qemu-devel] [PATCH 0/3] " Kevin Wolf
  3 siblings, 0 replies; 5+ messages in thread
From: Max Reitz @ 2018-03-12 16:55 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Max Reitz, Stefan Weil, Kevin Wolf, Eric Blake

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 qapi/block-core.json |  2 +-
 block/vdi.c          | 24 +++++++++++++++++++-----
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index e7110c9a47..5c3186fe4f 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3678,7 +3678,7 @@
       'sheepdog':       'BlockdevCreateOptionsSheepdog',
       'ssh':            'BlockdevCreateOptionsSsh',
       'throttle':       'BlockdevCreateNotSupported',
-      'vdi':            'BlockdevCreateNotSupported',
+      'vdi':            'BlockdevCreateOptionsVdi',
       'vhdx':           'BlockdevCreateNotSupported',
       'vmdk':           'BlockdevCreateNotSupported',
       'vpc':            'BlockdevCreateNotSupported',
diff --git a/block/vdi.c b/block/vdi.c
index 2a39b0ac98..8132e3adfe 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -721,9 +721,10 @@ nonallocating_write:
     return ret;
 }
 
-static int coroutine_fn vdi_co_do_create(BlockdevCreateOptionsVdi *vdi_opts,
+static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
                                          size_t block_size, Error **errp)
 {
+    BlockdevCreateOptionsVdi *vdi_opts;
     int ret = 0;
     uint64_t bytes = 0;
     uint32_t blocks;
@@ -736,6 +737,9 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptionsVdi *vdi_opts,
     BlockBackend *blk = NULL;
     uint32_t *bmap = NULL;
 
+    assert(create_options->driver == BLOCKDEV_DRIVER_VDI);
+    vdi_opts = &create_options->u.vdi;
+
     logout("\n");
 
     /* Read out options. */
@@ -856,11 +860,17 @@ exit:
     return ret;
 }
 
+static int coroutine_fn vdi_co_create(BlockdevCreateOptions *create_options,
+                                      Error **errp)
+{
+    return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp);
+}
+
 static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
                                            Error **errp)
 {
     QDict *qdict = NULL;
-    BlockdevCreateOptionsVdi *create_options = NULL;
+    BlockdevCreateOptions *create_options = NULL;
     BlockDriverState *bs_file = NULL;
     uint64_t block_size = DEFAULT_CLUSTER_SIZE;
     Visitor *v;
@@ -897,11 +907,12 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
         goto done;
     }
 
+    qdict_put_str(qdict, "driver", "vdi");
     qdict_put_str(qdict, "file", bs_file->node_name);
 
     /* Get the QAPI object */
     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
-    visit_type_BlockdevCreateOptionsVdi(v, NULL, &create_options, &local_err);
+    visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
     visit_free(v);
 
     if (local_err) {
@@ -910,12 +921,14 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
         goto done;
     }
 
-    create_options->size = ROUND_UP(create_options->size, BDRV_SECTOR_SIZE);
+    assert(create_options->driver == BLOCKDEV_DRIVER_VDI);
+    create_options->u.vdi.size = ROUND_UP(create_options->u.vdi.size,
+                                          BDRV_SECTOR_SIZE);
 
     ret = vdi_co_do_create(create_options, block_size, errp);
 done:
     QDECREF(qdict);
-    qapi_free_BlockdevCreateOptionsVdi(create_options);
+    qapi_free_BlockdevCreateOptions(create_options);
     bdrv_unref(bs_file);
     return ret;
 }
@@ -969,6 +982,7 @@ static BlockDriver bdrv_vdi = {
     .bdrv_reopen_prepare = vdi_reopen_prepare,
     .bdrv_child_perm          = bdrv_format_default_perms,
     .bdrv_co_create_opts = vdi_co_create_opts,
+    .bdrv_co_create      = vdi_co_create,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_co_block_status = vdi_co_block_status,
     .bdrv_make_empty = vdi_make_empty,
-- 
2.14.3

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

* Re: [Qemu-devel] [PATCH 0/3] vdi: Implement .bdrv_co_create
  2018-03-12 16:55 [Qemu-devel] [PATCH 0/3] vdi: Implement .bdrv_co_create Max Reitz
                   ` (2 preceding siblings ...)
  2018-03-12 16:55 ` [Qemu-devel] [PATCH 3/3] vdi: Implement .bdrv_co_create Max Reitz
@ 2018-03-13 10:22 ` Kevin Wolf
  3 siblings, 0 replies; 5+ messages in thread
From: Kevin Wolf @ 2018-03-13 10:22 UTC (permalink / raw)
  To: Max Reitz; +Cc: qemu-block, qemu-devel, Stefan Weil, Eric Blake

Am 12.03.2018 um 17:55 hat Max Reitz geschrieben:
> I think cluster-size should not be exposed in QAPI (yet), but Kevin's
> patch does that, while I had these patches lying around, so here is my
> proposal.

Thanks, applied to the block branch.

Kevin

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

end of thread, other threads:[~2018-03-13 10:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-12 16:55 [Qemu-devel] [PATCH 0/3] vdi: Implement .bdrv_co_create Max Reitz
2018-03-12 16:55 ` [Qemu-devel] [PATCH 1/3] vdi: Pull option parsing from vdi_co_create Max Reitz
2018-03-12 16:55 ` [Qemu-devel] [PATCH 2/3] vdi: Move file creation to vdi_co_create_opts Max Reitz
2018-03-12 16:55 ` [Qemu-devel] [PATCH 3/3] vdi: Implement .bdrv_co_create Max Reitz
2018-03-13 10:22 ` [Qemu-devel] [PATCH 0/3] " Kevin Wolf

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).