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
					
				
							
								
								
									
										135
									
								
								block/gluster.c
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								block/gluster.c
									
									
									
									
									
								
							@ -655,9 +655,11 @@ 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
 | 
				
			||||||
                                      const char *filename,
 | 
					 * object @gconf. */
 | 
				
			||||||
                                      QDict *options, Error **errp)
 | 
					static int qemu_gluster_parse(BlockdevOptionsGluster *gconf,
 | 
				
			||||||
 | 
					                              const char *filename,
 | 
				
			||||||
 | 
					                              QDict *options, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    if (filename) {
 | 
					    if (filename) {
 | 
				
			||||||
@ -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