Skip to content

Commit

Permalink
block/nbd: Store runtime option values
Browse files Browse the repository at this point in the history
Store the runtime option values in the BDRVNBDState so they can later be
used in nbd_refresh_filename() without having to directly access the
options QDict which may contain values of non-string types.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
XanClic authored and kevmw committed Aug 15, 2016
1 parent 036990d commit 03504d0
Showing 1 changed file with 61 additions and 44 deletions.
105 changes: 61 additions & 44 deletions block/nbd.c
Expand Up @@ -42,6 +42,9 @@

typedef struct BDRVNBDState {
NbdClientSession client;

/* For nbd_refresh_filename() */
char *path, *host, *port, *export, *tlscredsid;
} BDRVNBDState;

static int nbd_parse_uri(const char *filename, QDict *options)
Expand Down Expand Up @@ -188,13 +191,15 @@ static void nbd_parse_filename(const char *filename, QDict *options,
g_free(file);
}

static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, char **export,
Error **errp)
static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, Error **errp)
{
SocketAddress *saddr;

if (!qemu_opt_get(opts, "path") == !qemu_opt_get(opts, "host")) {
if (qemu_opt_get(opts, "path")) {
s->path = g_strdup(qemu_opt_get(opts, "path"));
s->host = g_strdup(qemu_opt_get(opts, "host"));

if (!s->path == !s->host) {
if (s->path) {
error_setg(errp, "path and host may not be used at the same time.");
} else {
error_setg(errp, "one of path and host must be specified.");
Expand All @@ -204,25 +209,28 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, char **export,

saddr = g_new0(SocketAddress, 1);

if (qemu_opt_get(opts, "path")) {
if (s->path) {
UnixSocketAddress *q_unix;
saddr->type = SOCKET_ADDRESS_KIND_UNIX;
q_unix = saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
q_unix->path = g_strdup(qemu_opt_get(opts, "path"));
q_unix->path = g_strdup(s->path);
} else {
InetSocketAddress *inet;

s->port = g_strdup(qemu_opt_get(opts, "port"));

saddr->type = SOCKET_ADDRESS_KIND_INET;
inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
inet->host = g_strdup(qemu_opt_get(opts, "host"));
inet->port = g_strdup(qemu_opt_get(opts, "port"));
inet->host = g_strdup(s->host);
inet->port = g_strdup(s->port);
if (!inet->port) {
inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
}
}

s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;

*export = g_strdup(qemu_opt_get(opts, "export"));
s->export = g_strdup(qemu_opt_get(opts, "export"));

return saddr;
}
Expand Down Expand Up @@ -323,10 +331,8 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
BDRVNBDState *s = bs->opaque;
QemuOpts *opts = NULL;
Error *local_err = NULL;
char *export = NULL;
QIOChannelSocket *sioc = NULL;
SocketAddress *saddr = NULL;
const char *tlscredsid;
QCryptoTLSCreds *tlscreds = NULL;
const char *hostname = NULL;
int ret = -EINVAL;
Expand All @@ -339,14 +345,14 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
}

/* Pop the config into our state object. Exit if invalid. */
saddr = nbd_config(s, opts, &export, errp);
saddr = nbd_config(s, opts, errp);
if (!saddr) {
goto error;
}

tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
if (tlscredsid) {
tlscreds = nbd_get_tls_creds(tlscredsid, errp);
s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
if (s->tlscredsid) {
tlscreds = nbd_get_tls_creds(s->tlscredsid, errp);
if (!tlscreds) {
goto error;
}
Expand All @@ -368,7 +374,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
}

/* NBD handshake */
ret = nbd_client_init(bs, sioc, export,
ret = nbd_client_init(bs, sioc, s->export,
tlscreds, hostname, errp);
error:
if (sioc) {
Expand All @@ -377,8 +383,14 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
if (tlscreds) {
object_unref(OBJECT(tlscreds));
}
if (ret < 0) {
g_free(s->path);
g_free(s->host);
g_free(s->port);
g_free(s->export);
g_free(s->tlscredsid);
}
qapi_free_SocketAddress(saddr);
g_free(export);
qemu_opts_del(opts);
return ret;
}
Expand All @@ -396,7 +408,15 @@ static void nbd_refresh_limits(BlockDriverState *bs, Error **errp)

static void nbd_close(BlockDriverState *bs)
{
BDRVNBDState *s = bs->opaque;

nbd_client_close(bs);

g_free(s->path);
g_free(s->host);
g_free(s->port);
g_free(s->export);
g_free(s->tlscredsid);
}

static int64_t nbd_getlength(BlockDriverState *bs)
Expand All @@ -419,48 +439,45 @@ static void nbd_attach_aio_context(BlockDriverState *bs,

static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
{
BDRVNBDState *s = bs->opaque;
QDict *opts = qdict_new();
const char *path = qdict_get_try_str(options, "path");
const char *host = qdict_get_try_str(options, "host");
const char *port = qdict_get_try_str(options, "port");
const char *export = qdict_get_try_str(options, "export");
const char *tlscreds = qdict_get_try_str(options, "tls-creds");

qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("nbd")));

if (path && export) {
if (s->path && s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nbd+unix:///%s?socket=%s", export, path);
} else if (path && !export) {
"nbd+unix:///%s?socket=%s", s->export, s->path);
} else if (s->path && !s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nbd+unix://?socket=%s", path);
} else if (!path && export && port) {
"nbd+unix://?socket=%s", s->path);
} else if (!s->path && s->export && s->port) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nbd://%s:%s/%s", host, port, export);
} else if (!path && export && !port) {
"nbd://%s:%s/%s", s->host, s->port, s->export);
} else if (!s->path && s->export && !s->port) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nbd://%s/%s", host, export);
} else if (!path && !export && port) {
"nbd://%s/%s", s->host, s->export);
} else if (!s->path && !s->export && s->port) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nbd://%s:%s", host, port);
} else if (!path && !export && !port) {
"nbd://%s:%s", s->host, s->port);
} else if (!s->path && !s->export && !s->port) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nbd://%s", host);
"nbd://%s", s->host);
}

if (path) {
qdict_put_obj(opts, "path", QOBJECT(qstring_from_str(path)));
} else if (port) {
qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(host)));
qdict_put_obj(opts, "port", QOBJECT(qstring_from_str(port)));
if (s->path) {
qdict_put_obj(opts, "path", QOBJECT(qstring_from_str(s->path)));
} else if (s->port) {
qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(s->host)));
qdict_put_obj(opts, "port", QOBJECT(qstring_from_str(s->port)));
} else {
qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(host)));
qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(s->host)));
}
if (export) {
qdict_put_obj(opts, "export", QOBJECT(qstring_from_str(export)));
if (s->export) {
qdict_put_obj(opts, "export", QOBJECT(qstring_from_str(s->export)));
}
if (tlscreds) {
qdict_put_obj(opts, "tls-creds", QOBJECT(qstring_from_str(tlscreds)));
if (s->tlscredsid) {
qdict_put_obj(opts, "tls-creds",
QOBJECT(qstring_from_str(s->tlscredsid)));
}

bs->full_open_options = opts;
Expand Down

0 comments on commit 03504d0

Please sign in to comment.