[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 14/27] gluster: Support .bdrv_co_create
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [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
- Re: [Qemu-block] [PATCH 10/27] qcow2: Use visitor for options in qcow2_create(), (continued)
- [Qemu-block] [PATCH 13/27] file-win32: Support .bdrv_co_create, Kevin Wolf, 2018/02/08
- [Qemu-block] [PATCH 12/27] file-posix: Support .bdrv_co_create, Kevin Wolf, 2018/02/08
- [Qemu-block] [PATCH 14/27] gluster: Support .bdrv_co_create,
Kevin Wolf <=
- [Qemu-block] [PATCH 15/27] rbd: Support .bdrv_co_create, Kevin Wolf, 2018/02/08
- [Qemu-block] [PATCH 16/27] nfs: Use QAPI options in nfs_client_open(), Kevin Wolf, 2018/02/08
- [Qemu-block] [PATCH 17/27] nfs: Support .bdrv_co_create, Kevin Wolf, 2018/02/08
- [Qemu-block] [PATCH 19/27] sheepdog: Support .bdrv_co_create, Kevin Wolf, 2018/02/08
- [Qemu-block] [PATCH 18/27] sheepdog: QAPIfy "redundacy" create option, Kevin Wolf, 2018/02/08