From e62be8888a83aa0ab7f50eeb954deb2ec4e7201d Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 15 Mar 2013 17:14:24 +0100 Subject: qemu-socket: Make socket_optslist public Allow other users to create the QemuOpts needed for inet_connect_opts(). Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- util/qemu-sockets.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'util') diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 83e4e08e85..39717d0a5b 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -33,10 +33,10 @@ static const int on=1, off=0; -/* used temporarely until all users are converted to QemuOpts */ -static QemuOptsList dummy_opts = { - .name = "dummy", - .head = QTAILQ_HEAD_INITIALIZER(dummy_opts.head), +/* used temporarily until all users are converted to QemuOpts */ +QemuOptsList socket_optslist = { + .name = "socket", + .head = QTAILQ_HEAD_INITIALIZER(socket_optslist.head), .desc = { { .name = "path", @@ -583,7 +583,7 @@ int inet_listen(const char *str, char *ostr, int olen, addr = inet_parse(str, errp); if (addr != NULL) { - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); inet_addr_to_opts(opts, addr); qapi_free_InetSocketAddress(addr); sock = inet_listen_opts(opts, port_offset, errp); @@ -656,7 +656,7 @@ int inet_nonblocking_connect(const char *str, addr = inet_parse(str, errp); if (addr != NULL) { - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); inet_addr_to_opts(opts, addr); qapi_free_InetSocketAddress(addr); sock = inet_connect_opts(opts, errp, callback, opaque); @@ -799,7 +799,7 @@ int unix_listen(const char *str, char *ostr, int olen, Error **errp) char *path, *optstr; int sock, len; - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); optstr = strchr(str, ','); if (optstr) { @@ -827,7 +827,7 @@ int unix_connect(const char *path, Error **errp) QemuOpts *opts; int sock; - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); qemu_opt_set(opts, "path", path); sock = unix_connect_opts(opts, errp, NULL, NULL); qemu_opts_del(opts); @@ -844,7 +844,7 @@ int unix_nonblocking_connect(const char *path, g_assert(callback != NULL); - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); qemu_opt_set(opts, "path", path); sock = unix_connect_opts(opts, errp, callback, opaque); qemu_opts_del(opts); @@ -895,7 +895,7 @@ int socket_connect(SocketAddress *addr, Error **errp, QemuOpts *opts; int fd; - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); switch (addr->kind) { case SOCKET_ADDRESS_KIND_INET: inet_addr_to_opts(opts, addr->inet); @@ -926,7 +926,7 @@ int socket_listen(SocketAddress *addr, Error **errp) QemuOpts *opts; int fd; - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); switch (addr->kind) { case SOCKET_ADDRESS_KIND_INET: inet_addr_to_opts(opts, addr->inet); @@ -954,7 +954,7 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp) QemuOpts *opts; int fd; - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); switch (remote->kind) { case SOCKET_ADDRESS_KIND_INET: qemu_opt_set(opts, "host", remote->inet->host); -- cgit v1.2.3 From f17c90bed11a6e277614b5a5d16434004f24d572 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 15 Mar 2013 11:55:29 +0100 Subject: nbd: Keep hostname and port separate The NBD block supports an URL syntax, for which a URL parser returns separate hostname and port fields. It also supports the traditional qemu syntax encoded in a filename. Until now, after parsing the URL to get each piece of information, a new string is built to be fed to socket functions. Instead of building a string in the URL case that is immediately parsed again, parse the string in both cases and use the QemuOpts interface to qemu-sockets.c. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block/nbd.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- include/block/nbd.h | 2 ++ include/qemu/sockets.h | 1 + nbd.c | 12 ++++++++++++ util/qemu-sockets.c | 6 +++--- 5 files changed, 58 insertions(+), 12 deletions(-) (limited to 'util') diff --git a/block/nbd.c b/block/nbd.c index 0473908996..ecbc892f19 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -66,7 +66,10 @@ typedef struct BDRVNBDState { struct nbd_reply reply; int is_unix; - char *host_spec; + char *unix_path; + + InetSocketAddress *inet_addr; + char *export_name; /* An NBD server may export several devices */ } BDRVNBDState; @@ -112,7 +115,7 @@ static int nbd_parse_uri(BDRVNBDState *s, const char *filename) ret = -EINVAL; goto out; } - s->host_spec = g_strdup(qp->p[0].value); + s->unix_path = g_strdup(qp->p[0].value); } else { /* nbd[+tcp]://host:port/export */ if (!uri->server) { @@ -122,7 +125,12 @@ static int nbd_parse_uri(BDRVNBDState *s, const char *filename) if (!uri->port) { uri->port = NBD_DEFAULT_PORT; } - s->host_spec = g_strdup_printf("%s:%d", uri->server, uri->port); + + s->inet_addr = g_new0(InetSocketAddress, 1); + *s->inet_addr = (InetSocketAddress) { + .host = g_strdup(uri->server), + .port = g_strdup_printf("%d", uri->port), + }; } out: @@ -140,6 +148,7 @@ static int nbd_config(BDRVNBDState *s, const char *filename) const char *host_spec; const char *unixpath; int err = -EINVAL; + Error *local_err = NULL; if (strstr(filename, "://")) { return nbd_parse_uri(s, filename); @@ -165,10 +174,15 @@ static int nbd_config(BDRVNBDState *s, const char *filename) /* are we a UNIX or TCP socket? */ if (strstart(host_spec, "unix:", &unixpath)) { s->is_unix = true; - s->host_spec = g_strdup(unixpath); + s->unix_path = g_strdup(unixpath); } else { s->is_unix = false; - s->host_spec = g_strdup(host_spec); + s->inet_addr = inet_parse(host_spec, &local_err); + if (local_err != NULL) { + qerror_report_err(local_err); + error_free(local_err); + goto out; + } } err = 0; @@ -177,7 +191,8 @@ out: g_free(file); if (err != 0) { g_free(s->export_name); - g_free(s->host_spec); + g_free(s->unix_path); + qapi_free_InetSocketAddress(s->inet_addr); } return err; } @@ -328,9 +343,24 @@ static int nbd_establish_connection(BlockDriverState *bs) size_t blocksize; if (s->is_unix) { - sock = unix_socket_outgoing(s->host_spec); + sock = unix_socket_outgoing(s->unix_path); } else { - sock = tcp_socket_outgoing_spec(s->host_spec); + QemuOpts *opts = qemu_opts_create_nofail(&socket_optslist); + + qemu_opt_set(opts, "host", s->inet_addr->host); + qemu_opt_set(opts, "port", s->inet_addr->port); + if (s->inet_addr->has_to) { + qemu_opt_set_number(opts, "to", s->inet_addr->to); + } + if (s->inet_addr->has_ipv4) { + qemu_opt_set_number(opts, "ipv4", s->inet_addr->ipv4); + } + if (s->inet_addr->has_ipv6) { + qemu_opt_set_number(opts, "ipv6", s->inet_addr->ipv6); + } + + sock = tcp_socket_outgoing_opts(opts); + qemu_opts_del(opts); } /* Failed to establish connection */ @@ -550,7 +580,8 @@ static void nbd_close(BlockDriverState *bs) { BDRVNBDState *s = bs->opaque; g_free(s->export_name); - g_free(s->host_spec); + g_free(s->unix_path); + qapi_free_InetSocketAddress(s->inet_addr); nbd_teardown_connection(bs); } diff --git a/include/block/nbd.h b/include/block/nbd.h index 344f05b794..9b52d50fb1 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -22,6 +22,7 @@ #include #include "qemu-common.h" +#include "qemu/option.h" struct nbd_request { uint32_t magic; @@ -64,6 +65,7 @@ int tcp_socket_outgoing(const char *address, uint16_t port); int tcp_socket_incoming(const char *address, uint16_t port); int tcp_socket_outgoing_spec(const char *address_and_port); int tcp_socket_incoming_spec(const char *address_and_port); +int tcp_socket_outgoing_opts(QemuOpts *opts); int unix_socket_outgoing(const char *path); int unix_socket_incoming(const char *path); diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 21846f9886..d225f6dd74 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -47,6 +47,7 @@ int recv_all(int fd, void *buf, int len1, bool single_read); */ typedef void NonBlockingConnectHandler(int fd, void *opaque); +InetSocketAddress *inet_parse(const char *str, Error **errp); int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp); int inet_listen(const char *str, char *ostr, int olen, int socktype, int port_offset, Error **errp); diff --git a/nbd.c b/nbd.c index 0698a023ad..97879ca204 100644 --- a/nbd.c +++ b/nbd.c @@ -218,6 +218,18 @@ int tcp_socket_outgoing_spec(const char *address_and_port) return fd; } +int tcp_socket_outgoing_opts(QemuOpts *opts) +{ + Error *local_err = NULL; + int fd = inet_connect_opts(opts, &local_err, NULL, NULL); + if (local_err != NULL) { + qerror_report_err(local_err); + error_free(local_err); + } + + return fd; +} + int tcp_socket_incoming(const char *address, uint16_t port) { char address_and_port[128]; diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 39717d0a5b..dc7524d829 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -485,7 +485,7 @@ err: } /* compatibility wrapper */ -static InetSocketAddress *inet_parse(const char *str, Error **errp) +InetSocketAddress *inet_parse(const char *str, Error **errp) { InetSocketAddress *addr; const char *optstr, *h; @@ -555,7 +555,7 @@ fail: return NULL; } -static void inet_addr_to_opts(QemuOpts *opts, InetSocketAddress *addr) +static void inet_addr_to_opts(QemuOpts *opts, const InetSocketAddress *addr) { bool ipv4 = addr->ipv4 || !addr->has_ipv4; bool ipv6 = addr->ipv6 || !addr->has_ipv6; @@ -622,7 +622,7 @@ int inet_connect(const char *str, Error **errp) addr = inet_parse(str, errp); if (addr != NULL) { - opts = qemu_opts_create_nofail(&dummy_opts); + opts = qemu_opts_create_nofail(&socket_optslist); inet_addr_to_opts(opts, addr); qapi_free_InetSocketAddress(addr); sock = inet_connect_opts(opts, errp, NULL, NULL); -- cgit v1.2.3