qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 14/27] gluster: Support .bdrv_co_create


From: Kevin Wolf
Subject: [Qemu-devel] [PATCH 14/27] gluster: Support .bdrv_co_create
Date: Thu, 8 Feb 2018 20:23:15 +0100

This adds the .bdrv_co_create driver callback to gluster, which enables
image creation over QMP.

Signed-off-by: Kevin Wolf <address@hidden>
---
 qapi/block-core.json |  18 ++++++-
 block/gluster.c      | 149 +++++++++++++++++++++++++++++++++------------------
 2 files changed, 115 insertions(+), 52 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 6f3461c751..5b4cd6bd12 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3356,6 +3356,22 @@
             '*nocow':           'bool' } }
 
 ##
+# @BlockdevCreateOptionsGluster:
+#
+# Driver specific image creation options for gluster.
+#
+# @location         Where to store the new image file
+# @size             Size of the virtual disk in bytes
+# @preallocation    Preallocation mode for the new image (default: off)
+#
+# Since: 2.12
+##
+{ 'struct': 'BlockdevCreateOptionsGluster',
+  'data': { 'location':         'BlockdevOptionsGluster',
+            'size':             'size',
+            '*preallocation':   'PreallocMode' } }
+
+##
 # @BlockdevQcow2Version:
 #
 # @v2:  The original QCOW2 format as introduced in qemu 0.10 (version 2)
@@ -3429,7 +3445,7 @@
       'file':           'BlockdevCreateOptionsFile',
       'ftp':            'BlockdevCreateNotSupported',
       'ftps':           'BlockdevCreateNotSupported',
-      'gluster':        'BlockdevCreateNotSupported',
+      'gluster':        'BlockdevCreateOptionsGluster',
       'host_cdrom':     'BlockdevCreateNotSupported',
       'host_device':    'BlockdevCreateNotSupported',
       'http':           'BlockdevCreateNotSupported',
diff --git a/block/gluster.c b/block/gluster.c
index 0f4265a3a4..b7e2b7fa2b 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -652,9 +652,11 @@ out:
     return -errno;
 }
 
-static struct glfs *qemu_gluster_init(BlockdevOptionsGluster *gconf,
-                                      const char *filename,
-                                      QDict *options, Error **errp)
+/* Converts options given in @filename and the @options QDict into the QAPI
+ * object @gconf. */
+static int qemu_gluster_parse(BlockdevOptionsGluster *gconf,
+                              const char *filename,
+                              QDict *options, Error **errp)
 {
     int ret;
     if (filename) {
@@ -665,8 +667,7 @@ static struct glfs 
*qemu_gluster_init(BlockdevOptionsGluster *gconf,
                                     "[host[:port]]volume/path[?socket=...]"
                                     "[,file.debug=N]"
                                     "[,file.logfile=/path/filename.log]\n");
-            errno = -ret;
-            return NULL;
+            return ret;
         }
     } else {
         ret = qemu_gluster_parse_json(gconf, options, errp);
@@ -682,10 +683,23 @@ static struct glfs 
*qemu_gluster_init(BlockdevOptionsGluster *gconf,
                              "file.server.1.transport=unix,"
                              "file.server.1.socket=/var/run/glusterd.socket 
..."
                              "\n");
-            errno = -ret;
-            return NULL;
+            return ret;
         }
+    }
+
+    return 0;
+}
+
+static struct glfs *qemu_gluster_init(BlockdevOptionsGluster *gconf,
+                                      const char *filename,
+                                      QDict *options, Error **errp)
+{
+    int ret;
 
+    ret = qemu_gluster_parse(gconf, filename, options, errp);
+    if (ret < 0) {
+        errno = -ret;
+        return NULL;
     }
 
     return qemu_gluster_glfs_init(gconf, errp);
@@ -962,64 +976,33 @@ static coroutine_fn int 
qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs,
 }
 #endif
 
-static int qemu_gluster_create(const char *filename,
-                               QemuOpts *opts, Error **errp)
+static int qemu_gluster_co_create(BlockdevCreateOptions *options,
+                                  Error **errp)
 {
-    BlockdevOptionsGluster *gconf;
+    BlockdevCreateOptionsGluster *opts = &options->u.gluster;
     struct glfs *glfs;
     struct glfs_fd *fd;
     int ret = 0;
-    PreallocMode prealloc;
-    int64_t total_size = 0;
-    char *tmp = NULL;
-    Error *local_err = NULL;
-
-    gconf = g_new0(BlockdevOptionsGluster, 1);
-    gconf->debug = qemu_opt_get_number_del(opts, GLUSTER_OPT_DEBUG,
-                                           GLUSTER_DEBUG_DEFAULT);
-    if (gconf->debug < 0) {
-        gconf->debug = 0;
-    } else if (gconf->debug > GLUSTER_DEBUG_MAX) {
-        gconf->debug = GLUSTER_DEBUG_MAX;
-    }
-    gconf->has_debug = true;
 
-    gconf->logfile = qemu_opt_get_del(opts, GLUSTER_OPT_LOGFILE);
-    if (!gconf->logfile) {
-        gconf->logfile = g_strdup(GLUSTER_LOGFILE_DEFAULT);
-    }
-    gconf->has_logfile = true;
+    assert(options->driver == BLOCKDEV_DRIVER_GLUSTER);
 
-    glfs = qemu_gluster_init(gconf, filename, NULL, errp);
+    glfs = qemu_gluster_glfs_init(opts->location, errp);
     if (!glfs) {
         ret = -errno;
         goto out;
     }
 
-    total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-                          BDRV_SECTOR_SIZE);
-
-    tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
-    prealloc = qapi_enum_parse(&PreallocMode_lookup, tmp, PREALLOC_MODE_OFF,
-                               &local_err);
-    g_free(tmp);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        ret = -EINVAL;
-        goto out;
-    }
-
-    fd = glfs_creat(glfs, gconf->path,
+    fd = glfs_creat(glfs, opts->location->path,
                     O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | 
S_IWUSR);
     if (!fd) {
         ret = -errno;
         goto out;
     }
 
-    switch (prealloc) {
+    switch (opts->preallocation) {
 #ifdef CONFIG_GLUSTERFS_FALLOCATE
     case PREALLOC_MODE_FALLOC:
-        if (glfs_fallocate(fd, 0, 0, total_size)) {
+        if (glfs_fallocate(fd, 0, 0, opts->size)) {
             error_setg(errp, "Could not preallocate data for the new file");
             ret = -errno;
         }
@@ -1027,8 +1010,8 @@ static int qemu_gluster_create(const char *filename,
 #endif /* CONFIG_GLUSTERFS_FALLOCATE */
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
     case PREALLOC_MODE_FULL:
-        if (!glfs_ftruncate(fd, total_size)) {
-            if (glfs_zerofill(fd, 0, total_size)) {
+        if (!glfs_ftruncate(fd, opts->size)) {
+            if (glfs_zerofill(fd, 0, opts->size)) {
                 error_setg(errp, "Could not zerofill the new file");
                 ret = -errno;
             }
@@ -1039,7 +1022,7 @@ static int qemu_gluster_create(const char *filename,
         break;
 #endif /* CONFIG_GLUSTERFS_ZEROFILL */
     case PREALLOC_MODE_OFF:
-        if (glfs_ftruncate(fd, total_size) != 0) {
+        if (glfs_ftruncate(fd, opts->size) != 0) {
             ret = -errno;
             error_setg(errp, "Could not resize file");
         }
@@ -1047,7 +1030,7 @@ static int qemu_gluster_create(const char *filename,
     default:
         ret = -EINVAL;
         error_setg(errp, "Unsupported preallocation mode: %s",
-                   PreallocMode_str(prealloc));
+                   PreallocMode_str(opts->preallocation));
         break;
     }
 
@@ -1055,11 +1038,71 @@ static int qemu_gluster_create(const char *filename,
         ret = -errno;
     }
 out:
-    qapi_free_BlockdevOptionsGluster(gconf);
     glfs_clear_preopened(glfs);
     return ret;
 }
 
+static int qemu_gluster_create(const char *filename,
+                               QemuOpts *opts, Error **errp)
+{
+    BlockdevCreateOptions *options;
+    BlockdevCreateOptionsGluster *gopts;
+    BlockdevOptionsGluster *gconf;
+    char *tmp = NULL;
+    Error *local_err = NULL;
+    int ret;
+
+    options = g_new0(BlockdevCreateOptions, 1);
+    options->driver = BLOCKDEV_DRIVER_GLUSTER;
+    gopts = &options->u.gluster;
+
+    gconf = g_new0(BlockdevOptionsGluster, 1);
+    gopts->location = gconf;
+
+    gopts->size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+                           BDRV_SECTOR_SIZE);
+
+    tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+    gopts->preallocation = qapi_enum_parse(&PreallocMode_lookup, tmp,
+                                           PREALLOC_MODE_OFF, &local_err);
+    g_free(tmp);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        ret = -EINVAL;
+        goto fail;
+    }
+
+    gconf->debug = qemu_opt_get_number_del(opts, GLUSTER_OPT_DEBUG,
+                                           GLUSTER_DEBUG_DEFAULT);
+    if (gconf->debug < 0) {
+        gconf->debug = 0;
+    } else if (gconf->debug > GLUSTER_DEBUG_MAX) {
+        gconf->debug = GLUSTER_DEBUG_MAX;
+    }
+    gconf->has_debug = true;
+
+    gconf->logfile = qemu_opt_get_del(opts, GLUSTER_OPT_LOGFILE);
+    if (!gconf->logfile) {
+        gconf->logfile = g_strdup(GLUSTER_LOGFILE_DEFAULT);
+    }
+    gconf->has_logfile = true;
+
+    ret = qemu_gluster_parse(gconf, filename, NULL, errp);
+    if (ret < 0) {
+        goto fail;
+    }
+
+    ret = qemu_gluster_co_create(options, errp);
+    if (ret < 0) {
+        goto fail;
+    }
+
+    ret = 0;
+fail:
+    qapi_free_BlockdevCreateOptions(options);
+    return ret;
+}
+
 static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
                                            int64_t sector_num, int nb_sectors,
                                            QEMUIOVector *qiov, int write)
@@ -1425,6 +1468,7 @@ static BlockDriver bdrv_gluster = {
     .bdrv_reopen_abort            = qemu_gluster_reopen_abort,
     .bdrv_close                   = qemu_gluster_close,
     .bdrv_create                  = qemu_gluster_create,
+    .bdrv_co_create               = qemu_gluster_co_create,
     .bdrv_getlength               = qemu_gluster_getlength,
     .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
     .bdrv_truncate                = qemu_gluster_truncate,
@@ -1453,6 +1497,7 @@ static BlockDriver bdrv_gluster_tcp = {
     .bdrv_reopen_abort            = qemu_gluster_reopen_abort,
     .bdrv_close                   = qemu_gluster_close,
     .bdrv_create                  = qemu_gluster_create,
+    .bdrv_co_create               = qemu_gluster_co_create,
     .bdrv_getlength               = qemu_gluster_getlength,
     .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
     .bdrv_truncate                = qemu_gluster_truncate,
@@ -1481,6 +1526,7 @@ static BlockDriver bdrv_gluster_unix = {
     .bdrv_reopen_abort            = qemu_gluster_reopen_abort,
     .bdrv_close                   = qemu_gluster_close,
     .bdrv_create                  = qemu_gluster_create,
+    .bdrv_co_create               = qemu_gluster_co_create,
     .bdrv_getlength               = qemu_gluster_getlength,
     .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
     .bdrv_truncate                = qemu_gluster_truncate,
@@ -1515,6 +1561,7 @@ static BlockDriver bdrv_gluster_rdma = {
     .bdrv_reopen_abort            = qemu_gluster_reopen_abort,
     .bdrv_close                   = qemu_gluster_close,
     .bdrv_create                  = qemu_gluster_create,
+    .bdrv_co_create               = qemu_gluster_co_create,
     .bdrv_getlength               = qemu_gluster_getlength,
     .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
     .bdrv_truncate                = qemu_gluster_truncate,
-- 
2.13.6




reply via email to

[Prev in Thread] Current Thread [Next in Thread]