mirror of https://github.com/xqemu/xqemu.git
block/gluster: using new qapi schema
this patch adds 'GlusterServer' related schema in qapi/block-core.json [Jeff: minor fix-ups of comments and formatting, per patch reviews] Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-id: 1468947453-5433-5-git-send-email-prasanna.kalever@redhat.com Signed-off-by: Jeff Cody <jcody@redhat.com>
This commit is contained in:
parent
0552ff2465
commit
7edac2ddeb
109
block/gluster.c
109
block/gluster.c
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#define GLUSTER_OPT_FILENAME "filename"
|
#define GLUSTER_OPT_FILENAME "filename"
|
||||||
#define GLUSTER_OPT_DEBUG "debug"
|
#define GLUSTER_OPT_DEBUG "debug"
|
||||||
|
#define GLUSTER_DEFAULT_PORT 24007
|
||||||
#define GLUSTER_DEBUG_DEFAULT 4
|
#define GLUSTER_DEBUG_DEFAULT 4
|
||||||
#define GLUSTER_DEBUG_MAX 9
|
#define GLUSTER_DEBUG_MAX 9
|
||||||
|
|
||||||
|
@ -40,15 +41,6 @@ typedef struct BDRVGlusterReopenState {
|
||||||
struct glfs_fd *fd;
|
struct glfs_fd *fd;
|
||||||
} BDRVGlusterReopenState;
|
} BDRVGlusterReopenState;
|
||||||
|
|
||||||
typedef struct GlusterConf {
|
|
||||||
char *host;
|
|
||||||
int port;
|
|
||||||
char *volume;
|
|
||||||
char *path;
|
|
||||||
char *transport;
|
|
||||||
int debug_level;
|
|
||||||
} GlusterConf;
|
|
||||||
|
|
||||||
|
|
||||||
static QemuOptsList qemu_gluster_create_opts = {
|
static QemuOptsList qemu_gluster_create_opts = {
|
||||||
.name = "qemu-gluster-create-opts",
|
.name = "qemu-gluster-create-opts",
|
||||||
|
@ -92,18 +84,7 @@ static QemuOptsList runtime_opts = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void qemu_gluster_gconf_free(GlusterConf *gconf)
|
static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path)
|
||||||
{
|
|
||||||
if (gconf) {
|
|
||||||
g_free(gconf->host);
|
|
||||||
g_free(gconf->volume);
|
|
||||||
g_free(gconf->path);
|
|
||||||
g_free(gconf->transport);
|
|
||||||
g_free(gconf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_volume_options(GlusterConf *gconf, char *path)
|
|
||||||
{
|
{
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
|
|
||||||
|
@ -160,8 +141,10 @@ static int parse_volume_options(GlusterConf *gconf, char *path)
|
||||||
* file=gluster+tcp://host.domain.com:24007/testvol/dir/a.img
|
* file=gluster+tcp://host.domain.com:24007/testvol/dir/a.img
|
||||||
* file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
|
* file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
|
||||||
*/
|
*/
|
||||||
static int qemu_gluster_parseuri(GlusterConf *gconf, const char *filename)
|
static int qemu_gluster_parse_uri(BlockdevOptionsGluster *gconf,
|
||||||
|
const char *filename)
|
||||||
{
|
{
|
||||||
|
GlusterServer *gsconf;
|
||||||
URI *uri;
|
URI *uri;
|
||||||
QueryParams *qp = NULL;
|
QueryParams *qp = NULL;
|
||||||
bool is_unix = false;
|
bool is_unix = false;
|
||||||
|
@ -172,16 +155,18 @@ static int qemu_gluster_parseuri(GlusterConf *gconf, const char *filename)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gconf->server = gsconf = g_new0(GlusterServer, 1);
|
||||||
|
|
||||||
/* transport */
|
/* transport */
|
||||||
if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
|
if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
|
||||||
gconf->transport = g_strdup("tcp");
|
gsconf->type = GLUSTER_TRANSPORT_TCP;
|
||||||
} else if (!strcmp(uri->scheme, "gluster+tcp")) {
|
} else if (!strcmp(uri->scheme, "gluster+tcp")) {
|
||||||
gconf->transport = g_strdup("tcp");
|
gsconf->type = GLUSTER_TRANSPORT_TCP;
|
||||||
} else if (!strcmp(uri->scheme, "gluster+unix")) {
|
} else if (!strcmp(uri->scheme, "gluster+unix")) {
|
||||||
gconf->transport = g_strdup("unix");
|
gsconf->type = GLUSTER_TRANSPORT_UNIX;
|
||||||
is_unix = true;
|
is_unix = true;
|
||||||
} else if (!strcmp(uri->scheme, "gluster+rdma")) {
|
} else if (!strcmp(uri->scheme, "gluster+rdma")) {
|
||||||
gconf->transport = g_strdup("tcp");
|
gsconf->type = GLUSTER_TRANSPORT_TCP;
|
||||||
error_report("Warning: rdma feature is not supported, falling "
|
error_report("Warning: rdma feature is not supported, falling "
|
||||||
"back to tcp");
|
"back to tcp");
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,10 +194,14 @@ static int qemu_gluster_parseuri(GlusterConf *gconf, const char *filename)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
gconf->host = g_strdup(qp->p[0].value);
|
gsconf->u.q_unix.path = g_strdup(qp->p[0].value);
|
||||||
} else {
|
} else {
|
||||||
gconf->host = g_strdup(uri->server ? uri->server : "localhost");
|
gsconf->u.tcp.host = g_strdup(uri->server ? uri->server : "localhost");
|
||||||
gconf->port = uri->port;
|
if (uri->port) {
|
||||||
|
gsconf->u.tcp.port = g_strdup_printf("%d", uri->port);
|
||||||
|
} else {
|
||||||
|
gsconf->u.tcp.port = g_strdup_printf("%d", GLUSTER_DEFAULT_PORT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -223,17 +212,18 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename,
|
static struct glfs *qemu_gluster_init(BlockdevOptionsGluster *gconf,
|
||||||
Error **errp)
|
const char *filename, Error **errp)
|
||||||
{
|
{
|
||||||
struct glfs *glfs = NULL;
|
struct glfs *glfs = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
int old_errno;
|
int old_errno;
|
||||||
|
|
||||||
ret = qemu_gluster_parseuri(gconf, filename);
|
ret = qemu_gluster_parse_uri(gconf, filename);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg(errp, "Usage: file=gluster[+transport]://[host[:port]]/"
|
error_setg(errp, "Invalid URI");
|
||||||
"volume/path[?socket=...]");
|
error_append_hint(errp, "Usage: file=gluster[+transport]://"
|
||||||
|
"[host[:port]]/volume/path[?socket=...]\n");
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -243,8 +233,16 @@ static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = glfs_set_volfile_server(glfs, gconf->transport, gconf->host,
|
if (gconf->server->type == GLUSTER_TRANSPORT_UNIX) {
|
||||||
gconf->port);
|
ret = glfs_set_volfile_server(glfs,
|
||||||
|
GlusterTransport_lookup[gconf->server->type],
|
||||||
|
gconf->server->u.q_unix.path, 0);
|
||||||
|
} else {
|
||||||
|
ret = glfs_set_volfile_server(glfs,
|
||||||
|
GlusterTransport_lookup[gconf->server->type],
|
||||||
|
gconf->server->u.tcp.host,
|
||||||
|
atoi(gconf->server->u.tcp.port));
|
||||||
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -256,15 +254,22 @@ static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename,
|
||||||
|
|
||||||
ret = glfs_init(glfs);
|
ret = glfs_init(glfs);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error_setg_errno(errp, errno,
|
if (gconf->server->type == GLUSTER_TRANSPORT_UNIX) {
|
||||||
"Gluster connection failed for host=%s port=%d "
|
error_setg(errp,
|
||||||
"volume=%s path=%s transport=%s", gconf->host,
|
"Gluster connection for volume %s, path %s failed on "
|
||||||
gconf->port, gconf->volume, gconf->path,
|
"socket %s ", gconf->volume, gconf->path,
|
||||||
gconf->transport);
|
gconf->server->u.q_unix.path);
|
||||||
|
} else {
|
||||||
|
error_setg(errp,
|
||||||
|
"Gluster connection for volume %s, path %s failed on "
|
||||||
|
"host %s and port %s ", gconf->volume, gconf->path,
|
||||||
|
gconf->server->u.tcp.host, gconf->server->u.tcp.port);
|
||||||
|
}
|
||||||
|
|
||||||
/* glfs_init sometimes doesn't set errno although docs suggest that */
|
/* glfs_init sometimes doesn't set errno although docs suggest that */
|
||||||
if (errno == 0)
|
if (errno == 0) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -352,7 +357,7 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
|
||||||
BDRVGlusterState *s = bs->opaque;
|
BDRVGlusterState *s = bs->opaque;
|
||||||
int open_flags = 0;
|
int open_flags = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
GlusterConf *gconf = g_new0(GlusterConf, 1);
|
BlockdevOptionsGluster *gconf = NULL;
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
@ -375,7 +380,9 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
|
||||||
s->debug_level = GLUSTER_DEBUG_MAX;
|
s->debug_level = GLUSTER_DEBUG_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gconf = g_new0(BlockdevOptionsGluster, 1);
|
||||||
gconf->debug_level = s->debug_level;
|
gconf->debug_level = s->debug_level;
|
||||||
|
gconf->has_debug_level = true;
|
||||||
s->glfs = qemu_gluster_init(gconf, filename, errp);
|
s->glfs = qemu_gluster_init(gconf, filename, errp);
|
||||||
if (!s->glfs) {
|
if (!s->glfs) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
|
@ -410,7 +417,7 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
qemu_opts_del(opts);
|
qemu_opts_del(opts);
|
||||||
qemu_gluster_gconf_free(gconf);
|
qapi_free_BlockdevOptionsGluster(gconf);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -429,7 +436,7 @@ static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
BDRVGlusterState *s;
|
BDRVGlusterState *s;
|
||||||
BDRVGlusterReopenState *reop_s;
|
BDRVGlusterReopenState *reop_s;
|
||||||
GlusterConf *gconf = NULL;
|
BlockdevOptionsGluster *gconf;
|
||||||
int open_flags = 0;
|
int open_flags = 0;
|
||||||
|
|
||||||
assert(state != NULL);
|
assert(state != NULL);
|
||||||
|
@ -442,9 +449,9 @@ static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
|
||||||
|
|
||||||
qemu_gluster_parse_flags(state->flags, &open_flags);
|
qemu_gluster_parse_flags(state->flags, &open_flags);
|
||||||
|
|
||||||
gconf = g_new0(GlusterConf, 1);
|
gconf = g_new0(BlockdevOptionsGluster, 1);
|
||||||
|
|
||||||
gconf->debug_level = s->debug_level;
|
gconf->debug_level = s->debug_level;
|
||||||
|
gconf->has_debug_level = true;
|
||||||
reop_s->glfs = qemu_gluster_init(gconf, state->bs->filename, errp);
|
reop_s->glfs = qemu_gluster_init(gconf, state->bs->filename, errp);
|
||||||
if (reop_s->glfs == NULL) {
|
if (reop_s->glfs == NULL) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
|
@ -470,7 +477,7 @@ static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
/* state->opaque will be freed in either the _abort or _commit */
|
/* state->opaque will be freed in either the _abort or _commit */
|
||||||
qemu_gluster_gconf_free(gconf);
|
qapi_free_BlockdevOptionsGluster(gconf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,14 +579,15 @@ static inline int qemu_gluster_zerofill(struct glfs_fd *fd, int64_t offset,
|
||||||
static int qemu_gluster_create(const char *filename,
|
static int qemu_gluster_create(const char *filename,
|
||||||
QemuOpts *opts, Error **errp)
|
QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
|
BlockdevOptionsGluster *gconf;
|
||||||
struct glfs *glfs;
|
struct glfs *glfs;
|
||||||
struct glfs_fd *fd;
|
struct glfs_fd *fd;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int prealloc = 0;
|
int prealloc = 0;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
GlusterConf *gconf = g_new0(GlusterConf, 1);
|
|
||||||
|
|
||||||
|
gconf = g_new0(BlockdevOptionsGluster, 1);
|
||||||
gconf->debug_level = qemu_opt_get_number_del(opts, GLUSTER_OPT_DEBUG,
|
gconf->debug_level = qemu_opt_get_number_del(opts, GLUSTER_OPT_DEBUG,
|
||||||
GLUSTER_DEBUG_DEFAULT);
|
GLUSTER_DEBUG_DEFAULT);
|
||||||
if (gconf->debug_level < 0) {
|
if (gconf->debug_level < 0) {
|
||||||
|
@ -587,6 +595,7 @@ static int qemu_gluster_create(const char *filename,
|
||||||
} else if (gconf->debug_level > GLUSTER_DEBUG_MAX) {
|
} else if (gconf->debug_level > GLUSTER_DEBUG_MAX) {
|
||||||
gconf->debug_level = GLUSTER_DEBUG_MAX;
|
gconf->debug_level = GLUSTER_DEBUG_MAX;
|
||||||
}
|
}
|
||||||
|
gconf->has_debug_level = true;
|
||||||
|
|
||||||
glfs = qemu_gluster_init(gconf, filename, errp);
|
glfs = qemu_gluster_init(gconf, filename, errp);
|
||||||
if (!glfs) {
|
if (!glfs) {
|
||||||
|
@ -628,7 +637,7 @@ static int qemu_gluster_create(const char *filename,
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
qemu_gluster_gconf_free(gconf);
|
qapi_free_BlockdevOptionsGluster(gconf);
|
||||||
if (glfs) {
|
if (glfs) {
|
||||||
glfs_fini(glfs);
|
glfs_fini(glfs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1666,13 +1666,14 @@
|
||||||
# @host_device, @host_cdrom: Since 2.1
|
# @host_device, @host_cdrom: Since 2.1
|
||||||
#
|
#
|
||||||
# Since: 2.0
|
# Since: 2.0
|
||||||
|
# @gluster: Since 2.7
|
||||||
##
|
##
|
||||||
{ 'enum': 'BlockdevDriver',
|
{ 'enum': 'BlockdevDriver',
|
||||||
'data': [ 'archipelago', 'blkdebug', 'blkverify', 'bochs', 'cloop',
|
'data': [ 'archipelago', 'blkdebug', 'blkverify', 'bochs', 'cloop',
|
||||||
'dmg', 'file', 'ftp', 'ftps', 'host_cdrom', 'host_device',
|
'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom',
|
||||||
'http', 'https', 'luks', 'null-aio', 'null-co', 'parallels',
|
'host_device', 'http', 'https', 'luks', 'null-aio', 'null-co',
|
||||||
'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'tftp', 'vdi', 'vhdx',
|
'parallels', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'tftp',
|
||||||
'vmdk', 'vpc', 'vvfat' ] }
|
'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @BlockdevOptionsFile
|
# @BlockdevOptionsFile
|
||||||
|
@ -2064,6 +2065,63 @@
|
||||||
'*rewrite-corrupted': 'bool',
|
'*rewrite-corrupted': 'bool',
|
||||||
'*read-pattern': 'QuorumReadPattern' } }
|
'*read-pattern': 'QuorumReadPattern' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @GlusterTransport
|
||||||
|
#
|
||||||
|
# An enumeration of Gluster transport types
|
||||||
|
#
|
||||||
|
# @tcp: TCP - Transmission Control Protocol
|
||||||
|
#
|
||||||
|
# @unix: UNIX - Unix domain socket
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'enum': 'GlusterTransport',
|
||||||
|
'data': [ 'unix', 'tcp' ] }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# @GlusterServer
|
||||||
|
#
|
||||||
|
# Captures the address of a socket
|
||||||
|
#
|
||||||
|
# Details for connecting to a gluster server
|
||||||
|
#
|
||||||
|
# @type: Transport type used for gluster connection
|
||||||
|
#
|
||||||
|
# @unix: socket file
|
||||||
|
#
|
||||||
|
# @tcp: host address and port number
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'union': 'GlusterServer',
|
||||||
|
'base': { 'type': 'GlusterTransport' },
|
||||||
|
'discriminator': 'type',
|
||||||
|
'data': { 'unix': 'UnixSocketAddress',
|
||||||
|
'tcp': 'InetSocketAddress' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevOptionsGluster
|
||||||
|
#
|
||||||
|
# Driver specific block device options for Gluster
|
||||||
|
#
|
||||||
|
# @volume: name of gluster volume where VM image resides
|
||||||
|
#
|
||||||
|
# @path: absolute path to image file in gluster volume
|
||||||
|
#
|
||||||
|
# @server: gluster server description
|
||||||
|
#
|
||||||
|
# @debug-level: #optional libgfapi log level (default '4' which is Error)
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockdevOptionsGluster',
|
||||||
|
'data': { 'volume': 'str',
|
||||||
|
'path': 'str',
|
||||||
|
'server': 'GlusterServer',
|
||||||
|
'*debug_level': 'int' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @BlockdevOptions
|
# @BlockdevOptions
|
||||||
#
|
#
|
||||||
|
@ -2111,7 +2169,7 @@
|
||||||
'file': 'BlockdevOptionsFile',
|
'file': 'BlockdevOptionsFile',
|
||||||
'ftp': 'BlockdevOptionsFile',
|
'ftp': 'BlockdevOptionsFile',
|
||||||
'ftps': 'BlockdevOptionsFile',
|
'ftps': 'BlockdevOptionsFile',
|
||||||
# TODO gluster: Wait for structured options
|
'gluster': 'BlockdevOptionsGluster',
|
||||||
'host_cdrom': 'BlockdevOptionsFile',
|
'host_cdrom': 'BlockdevOptionsFile',
|
||||||
'host_device':'BlockdevOptionsFile',
|
'host_device':'BlockdevOptionsFile',
|
||||||
'http': 'BlockdevOptionsFile',
|
'http': 'BlockdevOptionsFile',
|
||||||
|
|
Loading…
Reference in New Issue