#include "block/block_int.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
+#include "qapi/util.h"
#include "qemu/uri.h"
#include "qemu/error-report.h"
+#include "qemu/cutils.h"
#define GLUSTER_OPT_FILENAME "filename"
#define GLUSTER_OPT_VOLUME "volume"
struct glfs_fd *fd;
char *logfile;
bool supports_seek_data;
- int debug_level;
+ int debug;
} BDRVGlusterState;
typedef struct BDRVGlusterReopenState {
{
.name = GLUSTER_OPT_TYPE,
.type = QEMU_OPT_STRING,
- .help = "tcp|unix",
+ .help = "inet|unix",
},
{ /* end of list */ }
},
},
};
-static QemuOptsList runtime_tcp_opts = {
- .name = "gluster_tcp",
- .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
+static QemuOptsList runtime_inet_opts = {
+ .name = "gluster_inet",
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_inet_opts.head),
.desc = {
{
.name = GLUSTER_OPT_TYPE,
.type = QEMU_OPT_STRING,
- .help = "tcp|unix",
+ .help = "inet|unix",
},
{
.name = GLUSTER_OPT_HOST,
},
{
.name = GLUSTER_OPT_PORT,
- .type = QEMU_OPT_NUMBER,
+ .type = QEMU_OPT_STRING,
.help = "port number on which glusterd is listening (default 24007)",
},
{
static void glfs_clear_preopened(glfs_t *fs)
{
ListElement *entry = NULL;
+ ListElement *next;
if (fs == NULL) {
return;
}
- QLIST_FOREACH(entry, &glfs_list, list) {
+ QLIST_FOREACH_SAFE(entry, &glfs_list, list, next) {
if (entry->saved.fs == fs) {
if (--entry->saved.ref) {
return;
static int qemu_gluster_parse_uri(BlockdevOptionsGluster *gconf,
const char *filename)
{
- GlusterServer *gsconf;
+ SocketAddressFlat *gsconf;
URI *uri;
QueryParams *qp = NULL;
bool is_unix = false;
return -EINVAL;
}
- gconf->server = g_new0(GlusterServerList, 1);
- gconf->server->value = gsconf = g_new0(GlusterServer, 1);
+ gconf->server = g_new0(SocketAddressFlatList, 1);
+ gconf->server->value = gsconf = g_new0(SocketAddressFlat, 1);
/* transport */
if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
- gsconf->type = GLUSTER_TRANSPORT_TCP;
+ gsconf->type = SOCKET_ADDRESS_FLAT_TYPE_INET;
} else if (!strcmp(uri->scheme, "gluster+tcp")) {
- gsconf->type = GLUSTER_TRANSPORT_TCP;
+ gsconf->type = SOCKET_ADDRESS_FLAT_TYPE_INET;
} else if (!strcmp(uri->scheme, "gluster+unix")) {
- gsconf->type = GLUSTER_TRANSPORT_UNIX;
+ gsconf->type = SOCKET_ADDRESS_FLAT_TYPE_UNIX;
is_unix = true;
} else if (!strcmp(uri->scheme, "gluster+rdma")) {
- gsconf->type = GLUSTER_TRANSPORT_TCP;
+ gsconf->type = SOCKET_ADDRESS_FLAT_TYPE_INET;
error_report("Warning: rdma feature is not supported, falling "
"back to tcp");
} else {
}
gsconf->u.q_unix.path = g_strdup(qp->p[0].value);
} else {
- gsconf->u.tcp.host = g_strdup(uri->server ? uri->server : "localhost");
+ gsconf->u.inet.host = g_strdup(uri->server ? uri->server : "localhost");
if (uri->port) {
- gsconf->u.tcp.port = g_strdup_printf("%d", uri->port);
+ gsconf->u.inet.port = g_strdup_printf("%d", uri->port);
} else {
- gsconf->u.tcp.port = g_strdup_printf("%d", GLUSTER_DEFAULT_PORT);
+ gsconf->u.inet.port = g_strdup_printf("%d", GLUSTER_DEFAULT_PORT);
}
}
struct glfs *glfs;
int ret;
int old_errno;
- GlusterServerList *server;
+ SocketAddressFlatList *server;
+ unsigned long long port;
glfs = glfs_find_preopened(gconf->volume);
if (glfs) {
glfs_set_preopened(gconf->volume, glfs);
for (server = gconf->server; server; server = server->next) {
- if (server->value->type == GLUSTER_TRANSPORT_UNIX) {
- ret = glfs_set_volfile_server(glfs,
- GlusterTransport_lookup[server->value->type],
+ if (server->value->type == SOCKET_ADDRESS_FLAT_TYPE_UNIX) {
+ ret = glfs_set_volfile_server(glfs, "unix",
server->value->u.q_unix.path, 0);
} else {
- ret = glfs_set_volfile_server(glfs,
- GlusterTransport_lookup[server->value->type],
- server->value->u.tcp.host,
- atoi(server->value->u.tcp.port));
+ if (parse_uint_full(server->value->u.inet.port, &port, 10) < 0 ||
+ port > 65535) {
+ error_setg(errp, "'%s' is not a valid port number",
+ server->value->u.inet.port);
+ errno = EINVAL;
+ goto out;
+ }
+ ret = glfs_set_volfile_server(glfs, "tcp",
+ server->value->u.inet.host,
+ (int)port);
}
if (ret < 0) {
}
}
- ret = glfs_set_logging(glfs, gconf->logfile, gconf->debug_level);
+ ret = glfs_set_logging(glfs, gconf->logfile, gconf->debug);
if (ret < 0) {
goto out;
}
error_setg(errp, "Gluster connection for volume %s, path %s failed"
" to connect", gconf->volume, gconf->path);
for (server = gconf->server; server; server = server->next) {
- if (server->value->type == GLUSTER_TRANSPORT_UNIX) {
+ if (server->value->type == SOCKET_ADDRESS_FLAT_TYPE_UNIX) {
error_append_hint(errp, "hint: failed on socket %s ",
server->value->u.q_unix.path);
} else {
error_append_hint(errp, "hint: failed on host %s and port %s ",
- server->value->u.tcp.host,
- server->value->u.tcp.port);
+ server->value->u.inet.host,
+ server->value->u.inet.port);
}
}
return NULL;
}
-static int qapi_enum_parse(const char *opt)
-{
- int i;
-
- if (!opt) {
- return GLUSTER_TRANSPORT__MAX;
- }
-
- for (i = 0; i < GLUSTER_TRANSPORT__MAX; i++) {
- if (!strcmp(opt, GlusterTransport_lookup[i])) {
- return i;
- }
- }
-
- return i;
-}
-
/*
* Convert the json formatted command line into qapi.
*/
QDict *options, Error **errp)
{
QemuOpts *opts;
- GlusterServer *gsconf;
- GlusterServerList *curr = NULL;
+ SocketAddressFlat *gsconf = NULL;
+ SocketAddressFlatList *curr = NULL;
QDict *backing_options = NULL;
Error *local_err = NULL;
char *str = NULL;
}
ptr = qemu_opt_get(opts, GLUSTER_OPT_TYPE);
- gsconf = g_new0(GlusterServer, 1);
- gsconf->type = qapi_enum_parse(ptr);
if (!ptr) {
error_setg(&local_err, QERR_MISSING_PARAMETER, GLUSTER_OPT_TYPE);
error_append_hint(&local_err, GERR_INDEX_HINT, i);
goto out;
}
- if (gsconf->type == GLUSTER_TRANSPORT__MAX) {
- error_setg(&local_err, QERR_INVALID_PARAMETER_VALUE,
- GLUSTER_OPT_TYPE, "tcp or unix");
+ gsconf = g_new0(SocketAddressFlat, 1);
+ if (!strcmp(ptr, "tcp")) {
+ ptr = "inet"; /* accept legacy "tcp" */
+ }
+ gsconf->type = qapi_enum_parse(SocketAddressFlatType_lookup, ptr,
+ SOCKET_ADDRESS_FLAT_TYPE__MAX, -1,
+ &local_err);
+ if (local_err) {
+ error_append_hint(&local_err,
+ "Parameter '%s' may be 'inet' or 'unix'\n",
+ GLUSTER_OPT_TYPE);
error_append_hint(&local_err, GERR_INDEX_HINT, i);
goto out;
}
qemu_opts_del(opts);
- if (gsconf->type == GLUSTER_TRANSPORT_TCP) {
- /* create opts info from runtime_tcp_opts list */
- opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);
+ if (gsconf->type == SOCKET_ADDRESS_FLAT_TYPE_INET) {
+ /* create opts info from runtime_inet_opts list */
+ opts = qemu_opts_create(&runtime_inet_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, backing_options, &local_err);
if (local_err) {
goto out;
error_append_hint(&local_err, GERR_INDEX_HINT, i);
goto out;
}
- gsconf->u.tcp.host = g_strdup(ptr);
+ gsconf->u.inet.host = g_strdup(ptr);
ptr = qemu_opt_get(opts, GLUSTER_OPT_PORT);
if (!ptr) {
error_setg(&local_err, QERR_MISSING_PARAMETER,
error_append_hint(&local_err, GERR_INDEX_HINT, i);
goto out;
}
- gsconf->u.tcp.port = g_strdup(ptr);
+ gsconf->u.inet.port = g_strdup(ptr);
/* defend for unsupported fields in InetSocketAddress,
* i.e. @ipv4, @ipv6 and @to
*/
ptr = qemu_opt_get(opts, GLUSTER_OPT_TO);
if (ptr) {
- gsconf->u.tcp.has_to = true;
+ gsconf->u.inet.has_to = true;
}
ptr = qemu_opt_get(opts, GLUSTER_OPT_IPV4);
if (ptr) {
- gsconf->u.tcp.has_ipv4 = true;
+ gsconf->u.inet.has_ipv4 = true;
}
ptr = qemu_opt_get(opts, GLUSTER_OPT_IPV6);
if (ptr) {
- gsconf->u.tcp.has_ipv6 = true;
+ gsconf->u.inet.has_ipv6 = true;
}
- if (gsconf->u.tcp.has_to) {
+ if (gsconf->u.inet.has_to) {
error_setg(&local_err, "Parameter 'to' not supported");
goto out;
}
- if (gsconf->u.tcp.has_ipv4 || gsconf->u.tcp.has_ipv6) {
+ if (gsconf->u.inet.has_ipv4 || gsconf->u.inet.has_ipv6) {
error_setg(&local_err, "Parameters 'ipv4/ipv6' not supported");
goto out;
}
}
if (gconf->server == NULL) {
- gconf->server = g_new0(GlusterServerList, 1);
+ gconf->server = g_new0(SocketAddressFlatList, 1);
gconf->server->value = gsconf;
curr = gconf->server;
} else {
- curr->next = g_new0(GlusterServerList, 1);
+ curr->next = g_new0(SocketAddressFlatList, 1);
curr->next->value = gsconf;
curr = curr->next;
}
+ gsconf = NULL;
- qdict_del(backing_options, str);
+ QDECREF(backing_options);
+ backing_options = NULL;
g_free(str);
str = NULL;
}
out:
error_propagate(errp, local_err);
+ qapi_free_SocketAddressFlat(gsconf);
qemu_opts_del(opts);
- if (str) {
- qdict_del(backing_options, str);
- g_free(str);
- }
+ g_free(str);
+ QDECREF(backing_options);
errno = EINVAL;
return -errno;
}
"file.volume=testvol,file.path=/path/a.qcow2"
"[,file.debug=9]"
"[,file.logfile=/path/filename.log],"
- "file.server.0.type=tcp,"
+ "file.server.0.type=inet,"
"file.server.0.host=1.2.3.4,"
"file.server.0.port=24007,"
"file.server.1.transport=unix,"
return qemu_gluster_glfs_init(gconf, errp);
}
-static void qemu_gluster_complete_aio(void *opaque)
-{
- GlusterAIOCB *acb = (GlusterAIOCB *)opaque;
-
- qemu_coroutine_enter(acb->coroutine);
-}
-
/*
* AIO callback routine called from GlusterFS thread.
*/
acb->ret = -EIO; /* Partial read/write - fail it */
}
- aio_bh_schedule_oneshot(acb->aio_context, qemu_gluster_complete_aio, acb);
+ aio_co_schedule(acb->aio_context, acb->coroutine);
}
static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags)
filename = qemu_opt_get(opts, GLUSTER_OPT_FILENAME);
- s->debug_level = qemu_opt_get_number(opts, GLUSTER_OPT_DEBUG,
- GLUSTER_DEBUG_DEFAULT);
- if (s->debug_level < 0) {
- s->debug_level = 0;
- } else if (s->debug_level > GLUSTER_DEBUG_MAX) {
- s->debug_level = GLUSTER_DEBUG_MAX;
+ s->debug = qemu_opt_get_number(opts, GLUSTER_OPT_DEBUG,
+ GLUSTER_DEBUG_DEFAULT);
+ if (s->debug < 0) {
+ s->debug = 0;
+ } else if (s->debug > GLUSTER_DEBUG_MAX) {
+ s->debug = GLUSTER_DEBUG_MAX;
}
gconf = g_new0(BlockdevOptionsGluster, 1);
- gconf->debug_level = s->debug_level;
- gconf->has_debug_level = true;
+ gconf->debug = s->debug;
+ gconf->has_debug = true;
logfile = qemu_opt_get(opts, GLUSTER_OPT_LOGFILE);
s->logfile = g_strdup(logfile ? logfile : GLUSTER_LOGFILE_DEFAULT);
qemu_gluster_parse_flags(state->flags, &open_flags);
gconf = g_new0(BlockdevOptionsGluster, 1);
- gconf->debug_level = s->debug_level;
- gconf->has_debug_level = true;
+ gconf->debug = s->debug;
+ gconf->has_debug = true;
gconf->logfile = g_strdup(s->logfile);
gconf->has_logfile = true;
reop_s->glfs = qemu_gluster_init(gconf, state->bs->filename, NULL, errp);
char *tmp = NULL;
gconf = g_new0(BlockdevOptionsGluster, 1);
- gconf->debug_level = qemu_opt_get_number_del(opts, GLUSTER_OPT_DEBUG,
- GLUSTER_DEBUG_DEFAULT);
- if (gconf->debug_level < 0) {
- gconf->debug_level = 0;
- } else if (gconf->debug_level > GLUSTER_DEBUG_MAX) {
- gconf->debug_level = GLUSTER_DEBUG_MAX;
+ 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_level = true;
+ gconf->has_debug = true;
gconf->logfile = qemu_opt_get_del(opts, GLUSTER_OPT_LOGFILE);
if (!gconf->logfile) {
* If @start is in a trailing hole or beyond EOF, return -ENXIO.
* If we can't find out, return a negative errno other than -ENXIO.
*
- * (Shamefully copied from raw-posix.c, only miniscule adaptions.)
+ * (Shamefully copied from file-posix.c, only miniscule adaptions.)
*/
static int find_allocation(BlockDriverState *bs, off_t start,
off_t *data, off_t *hole)
* 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
* beyond the end of the disk image it will be clamped.
*
- * (Based on raw_co_get_block_status() from raw-posix.c.)
+ * (Based on raw_co_get_block_status() from file-posix.c.)
*/
static int64_t coroutine_fn qemu_gluster_co_get_block_status(
BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,