nbd: convert to use the QAPI SocketAddress object

The nbd block driver currently uses a QemuOpts object
when setting up sockets. Switch it over to use the
QAPI SocketAddress object instead.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1442411543-28513-2-git-send-email-berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Daniel P. Berrange 2015-09-16 14:52:22 +01:00 committed by Paolo Bonzini
parent 8a47d575df
commit 7a5ed43764

View File

@ -43,7 +43,6 @@
typedef struct BDRVNBDState { typedef struct BDRVNBDState {
NbdClientSession client; NbdClientSession client;
QemuOpts *socket_opts;
} BDRVNBDState; } BDRVNBDState;
static int nbd_parse_uri(const char *filename, QDict *options) static int nbd_parse_uri(const char *filename, QDict *options)
@ -190,10 +189,10 @@ out:
g_free(file); g_free(file);
} }
static void nbd_config(BDRVNBDState *s, QDict *options, char **export, static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export,
Error **errp) Error **errp)
{ {
Error *local_err = NULL; SocketAddress *saddr;
if (qdict_haskey(options, "path") == qdict_haskey(options, "host")) { if (qdict_haskey(options, "path") == qdict_haskey(options, "host")) {
if (qdict_haskey(options, "path")) { if (qdict_haskey(options, "path")) {
@ -201,28 +200,37 @@ static void nbd_config(BDRVNBDState *s, QDict *options, char **export,
} else { } else {
error_setg(errp, "one of path and host must be specified."); error_setg(errp, "one of path and host must be specified.");
} }
return; return NULL;
} }
s->client.is_unix = qdict_haskey(options, "path"); saddr = g_new0(SocketAddress, 1);
s->socket_opts = qemu_opts_create(&socket_optslist, NULL, 0,
&error_abort);
qemu_opts_absorb_qdict(s->socket_opts, options, &local_err); if (qdict_haskey(options, "path")) {
if (local_err) { saddr->kind = SOCKET_ADDRESS_KIND_UNIX;
error_propagate(errp, local_err); saddr->q_unix = g_new0(UnixSocketAddress, 1);
return; saddr->q_unix->path = g_strdup(qdict_get_str(options, "path"));
qdict_del(options, "path");
} else {
saddr->kind = SOCKET_ADDRESS_KIND_INET;
saddr->inet = g_new0(InetSocketAddress, 1);
saddr->inet->host = g_strdup(qdict_get_str(options, "host"));
if (!qdict_get_try_str(options, "port")) {
saddr->inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
} else {
saddr->inet->port = g_strdup(qdict_get_str(options, "port"));
}
qdict_del(options, "host");
qdict_del(options, "port");
} }
if (!qemu_opt_get(s->socket_opts, "port")) { s->client.is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
qemu_opt_set_number(s->socket_opts, "port", NBD_DEFAULT_PORT,
&error_abort);
}
*export = g_strdup(qdict_get_try_str(options, "export")); *export = g_strdup(qdict_get_try_str(options, "export"));
if (*export) { if (*export) {
qdict_del(options, "export"); qdict_del(options, "export");
} }
return saddr;
} }
NbdClientSession *nbd_get_client_session(BlockDriverState *bs) NbdClientSession *nbd_get_client_session(BlockDriverState *bs)
@ -231,26 +239,24 @@ NbdClientSession *nbd_get_client_session(BlockDriverState *bs)
return &s->client; return &s->client;
} }
static int nbd_establish_connection(BlockDriverState *bs, Error **errp) static int nbd_establish_connection(BlockDriverState *bs,
SocketAddress *saddr,
Error **errp)
{ {
BDRVNBDState *s = bs->opaque; BDRVNBDState *s = bs->opaque;
int sock; int sock;
if (s->client.is_unix) { sock = socket_connect(saddr, errp, NULL, NULL);
sock = unix_connect_opts(s->socket_opts, errp, NULL, NULL);
} else {
sock = inet_connect_opts(s->socket_opts, errp, NULL, NULL);
if (sock >= 0) {
socket_set_nodelay(sock);
}
}
/* Failed to establish connection */
if (sock < 0) { if (sock < 0) {
logout("Failed to establish connection to NBD server\n"); logout("Failed to establish connection to NBD server\n");
return -EIO; return -EIO;
} }
if (!s->client.is_unix) {
socket_set_nodelay(sock);
}
return sock; return sock;
} }
@ -260,19 +266,19 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
BDRVNBDState *s = bs->opaque; BDRVNBDState *s = bs->opaque;
char *export = NULL; char *export = NULL;
int result, sock; int result, sock;
Error *local_err = NULL; SocketAddress *saddr;
/* Pop the config into our state object. Exit if invalid. */ /* Pop the config into our state object. Exit if invalid. */
nbd_config(s, options, &export, &local_err); saddr = nbd_config(s, options, &export, errp);
if (local_err) { if (!saddr) {
error_propagate(errp, local_err);
return -EINVAL; return -EINVAL;
} }
/* establish TCP connection, return error if it fails /* establish TCP connection, return error if it fails
* TODO: Configurable retry-until-timeout behaviour. * TODO: Configurable retry-until-timeout behaviour.
*/ */
sock = nbd_establish_connection(bs, errp); sock = nbd_establish_connection(bs, saddr, errp);
qapi_free_SocketAddress(saddr);
if (sock < 0) { if (sock < 0) {
g_free(export); g_free(export);
return sock; return sock;
@ -315,9 +321,6 @@ static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num,
static void nbd_close(BlockDriverState *bs) static void nbd_close(BlockDriverState *bs)
{ {
BDRVNBDState *s = bs->opaque;
qemu_opts_del(s->socket_opts);
nbd_client_close(bs); nbd_client_close(bs);
} }