gluster: Support .bdrv_co_create
This adds the .bdrv_co_create driver callback to gluster, which enables image creation over QMP. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
3766ef579c
commit
ab8bda76a0
131
block/gluster.c
131
block/gluster.c
@ -655,7 +655,9 @@ out:
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct glfs *qemu_gluster_init(BlockdevOptionsGluster *gconf,
|
/* Converts options given in @filename and the @options QDict into the QAPI
|
||||||
|
* object @gconf. */
|
||||||
|
static int qemu_gluster_parse(BlockdevOptionsGluster *gconf,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
QDict *options, Error **errp)
|
QDict *options, Error **errp)
|
||||||
{
|
{
|
||||||
@ -668,8 +670,7 @@ static struct glfs *qemu_gluster_init(BlockdevOptionsGluster *gconf,
|
|||||||
"[host[:port]]volume/path[?socket=...]"
|
"[host[:port]]volume/path[?socket=...]"
|
||||||
"[,file.debug=N]"
|
"[,file.debug=N]"
|
||||||
"[,file.logfile=/path/filename.log]\n");
|
"[,file.logfile=/path/filename.log]\n");
|
||||||
errno = -ret;
|
return ret;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = qemu_gluster_parse_json(gconf, options, errp);
|
ret = qemu_gluster_parse_json(gconf, options, errp);
|
||||||
@ -685,10 +686,23 @@ static struct glfs *qemu_gluster_init(BlockdevOptionsGluster *gconf,
|
|||||||
"file.server.1.transport=unix,"
|
"file.server.1.transport=unix,"
|
||||||
"file.server.1.socket=/var/run/glusterd.socket ..."
|
"file.server.1.socket=/var/run/glusterd.socket ..."
|
||||||
"\n");
|
"\n");
|
||||||
errno = -ret;
|
return ret;
|
||||||
return NULL;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
return qemu_gluster_glfs_init(gconf, errp);
|
||||||
@ -1021,20 +1035,72 @@ static int qemu_gluster_do_truncate(struct glfs_fd *fd, int64_t offset,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qemu_gluster_co_create(BlockdevCreateOptions *options,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
BlockdevCreateOptionsGluster *opts = &options->u.gluster;
|
||||||
|
struct glfs *glfs;
|
||||||
|
struct glfs_fd *fd = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
assert(options->driver == BLOCKDEV_DRIVER_GLUSTER);
|
||||||
|
|
||||||
|
glfs = qemu_gluster_glfs_init(opts->location, errp);
|
||||||
|
if (!glfs) {
|
||||||
|
ret = -errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = qemu_gluster_do_truncate(fd, opts->size, opts->preallocation, errp);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (fd) {
|
||||||
|
if (glfs_close(fd) != 0 && ret == 0) {
|
||||||
|
ret = -errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glfs_clear_preopened(glfs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int coroutine_fn qemu_gluster_co_create_opts(const char *filename,
|
static int coroutine_fn qemu_gluster_co_create_opts(const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
BlockdevCreateOptions *options;
|
||||||
|
BlockdevCreateOptionsGluster *gopts;
|
||||||
BlockdevOptionsGluster *gconf;
|
BlockdevOptionsGluster *gconf;
|
||||||
struct glfs *glfs;
|
|
||||||
struct glfs_fd *fd = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
PreallocMode prealloc;
|
|
||||||
int64_t total_size = 0;
|
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
Error *local_err = 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);
|
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,
|
gconf->debug = qemu_opt_get_number_del(opts, GLUSTER_OPT_DEBUG,
|
||||||
GLUSTER_DEBUG_DEFAULT);
|
GLUSTER_DEBUG_DEFAULT);
|
||||||
if (gconf->debug < 0) {
|
if (gconf->debug < 0) {
|
||||||
@ -1050,42 +1116,19 @@ static int coroutine_fn qemu_gluster_co_create_opts(const char *filename,
|
|||||||
}
|
}
|
||||||
gconf->has_logfile = true;
|
gconf->has_logfile = true;
|
||||||
|
|
||||||
glfs = qemu_gluster_init(gconf, filename, NULL, errp);
|
ret = qemu_gluster_parse(gconf, filename, NULL, errp);
|
||||||
if (!glfs) {
|
if (ret < 0) {
|
||||||
ret = -errno;
|
goto fail;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
|
ret = qemu_gluster_co_create(options, errp);
|
||||||
BDRV_SECTOR_SIZE);
|
if (ret < 0) {
|
||||||
|
goto fail;
|
||||||
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,
|
ret = 0;
|
||||||
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR);
|
fail:
|
||||||
if (!fd) {
|
qapi_free_BlockdevCreateOptions(options);
|
||||||
ret = -errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = qemu_gluster_do_truncate(fd, total_size, prealloc, errp);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (fd) {
|
|
||||||
if (glfs_close(fd) != 0 && ret == 0) {
|
|
||||||
ret = -errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qapi_free_BlockdevOptionsGluster(gconf);
|
|
||||||
glfs_clear_preopened(glfs);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,6 +1479,7 @@ static BlockDriver bdrv_gluster = {
|
|||||||
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
|
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
|
||||||
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
|
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
|
||||||
.bdrv_close = qemu_gluster_close,
|
.bdrv_close = qemu_gluster_close,
|
||||||
|
.bdrv_co_create = qemu_gluster_co_create,
|
||||||
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
||||||
.bdrv_getlength = qemu_gluster_getlength,
|
.bdrv_getlength = qemu_gluster_getlength,
|
||||||
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
||||||
@ -1464,6 +1508,7 @@ static BlockDriver bdrv_gluster_tcp = {
|
|||||||
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
|
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
|
||||||
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
|
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
|
||||||
.bdrv_close = qemu_gluster_close,
|
.bdrv_close = qemu_gluster_close,
|
||||||
|
.bdrv_co_create = qemu_gluster_co_create,
|
||||||
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
||||||
.bdrv_getlength = qemu_gluster_getlength,
|
.bdrv_getlength = qemu_gluster_getlength,
|
||||||
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
||||||
@ -1492,6 +1537,7 @@ static BlockDriver bdrv_gluster_unix = {
|
|||||||
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
|
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
|
||||||
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
|
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
|
||||||
.bdrv_close = qemu_gluster_close,
|
.bdrv_close = qemu_gluster_close,
|
||||||
|
.bdrv_co_create = qemu_gluster_co_create,
|
||||||
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
||||||
.bdrv_getlength = qemu_gluster_getlength,
|
.bdrv_getlength = qemu_gluster_getlength,
|
||||||
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
||||||
@ -1526,6 +1572,7 @@ static BlockDriver bdrv_gluster_rdma = {
|
|||||||
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
|
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
|
||||||
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
|
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
|
||||||
.bdrv_close = qemu_gluster_close,
|
.bdrv_close = qemu_gluster_close,
|
||||||
|
.bdrv_co_create = qemu_gluster_co_create,
|
||||||
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
||||||
.bdrv_getlength = qemu_gluster_getlength,
|
.bdrv_getlength = qemu_gluster_getlength,
|
||||||
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
||||||
|
@ -3376,6 +3376,22 @@
|
|||||||
'*preallocation': 'PreallocMode',
|
'*preallocation': 'PreallocMode',
|
||||||
'*nocow': 'bool' } }
|
'*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:
|
# @BlockdevQcow2Version:
|
||||||
#
|
#
|
||||||
@ -3450,7 +3466,7 @@
|
|||||||
'file': 'BlockdevCreateOptionsFile',
|
'file': 'BlockdevCreateOptionsFile',
|
||||||
'ftp': 'BlockdevCreateNotSupported',
|
'ftp': 'BlockdevCreateNotSupported',
|
||||||
'ftps': 'BlockdevCreateNotSupported',
|
'ftps': 'BlockdevCreateNotSupported',
|
||||||
'gluster': 'BlockdevCreateNotSupported',
|
'gluster': 'BlockdevCreateOptionsGluster',
|
||||||
'host_cdrom': 'BlockdevCreateNotSupported',
|
'host_cdrom': 'BlockdevCreateNotSupported',
|
||||||
'host_device': 'BlockdevCreateNotSupported',
|
'host_device': 'BlockdevCreateNotSupported',
|
||||||
'http': 'BlockdevCreateNotSupported',
|
'http': 'BlockdevCreateNotSupported',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user