diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2015-09-01 14:46:50 +0100 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2015-10-20 14:21:45 +0100 |
commit | 0983f5e6af76d5df8c6346cbdfff9d8305fb6da0 (patch) | |
tree | 622d1e1beb3f0bb934742a6bd04e4096cfa07cb3 | |
parent | 2a8e21c7c8dcb7d235cfd256be36b7e8f9f3fcb3 (diff) | |
download | qemu-0983f5e6af76d5df8c6346cbdfff9d8305fb6da0.zip qemu-0983f5e6af76d5df8c6346cbdfff9d8305fb6da0.tar.gz qemu-0983f5e6af76d5df8c6346cbdfff9d8305fb6da0.tar.bz2 |
sockets: allow port to be NULL when listening on IP address
If the port in the SocketAddress struct is NULL, it can allow
the kernel to automatically select a free port. This is useful
in particular in unit tests to avoid a race trying to find a
free port to run a test case on.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-rw-r--r-- | qapi-schema.json | 6 | ||||
-rw-r--r-- | util/qemu-sockets.c | 18 |
2 files changed, 17 insertions, 7 deletions
diff --git a/qapi-schema.json b/qapi-schema.json index 702b7b5..f60be29 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2614,7 +2614,9 @@ # # @host: host part of the address # -# @port: port part of the address, or lowest port if @to is present +# @port: port part of the address, or lowest port if @to is present. +# Kernel selects a free port if omitted for listener addresses. +# #optional # # @to: highest port to try # @@ -2629,7 +2631,7 @@ { 'struct': 'InetSocketAddress', 'data': { 'host': 'str', - 'port': 'str', + '*port': 'str', '*to': 'uint16', '*ipv4': 'bool', '*ipv6': 'bool' } } diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 3338452..9142917 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -128,12 +128,15 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp) ai.ai_family = PF_UNSPEC; ai.ai_socktype = SOCK_STREAM; - if ((qemu_opt_get(opts, "host") == NULL) || - (qemu_opt_get(opts, "port") == NULL)) { - error_setg(errp, "host and/or port not specified"); + if ((qemu_opt_get(opts, "host") == NULL)) { + error_setg(errp, "host not specified"); return -1; } - pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port")); + if (qemu_opt_get(opts, "port") != NULL) { + pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port")); + } else { + port[0] = '\0'; + } addr = qemu_opt_get(opts, "host"); to = qemu_opt_get_number(opts, "to", 0); @@ -145,6 +148,10 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp) /* lookup */ if (port_offset) { unsigned long long baseport; + if (strlen(port) == 0) { + error_setg(errp, "port not specified"); + return -1; + } if (parse_uint_full(port, &baseport, 10) < 0) { error_setg(errp, "can't convert to a number: %s", port); return -1; @@ -156,7 +163,8 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp) } snprintf(port, sizeof(port), "%d", (int)baseport + port_offset); } - rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res); + rc = getaddrinfo(strlen(addr) ? addr : NULL, + strlen(port) ? port : NULL, &ai, &res); if (rc != 0) { error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, gai_strerror(rc)); |