From 00f93eb12547bbd7314394e23faf72695972efcf Mon Sep 17 00:00:00 2001 Message-Id: <00f93eb12547bbd7314394e23faf72695972efcf@dist-git> From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Tue, 24 Jun 2014 16:02:37 +0200 Subject: [PATCH] Don't use AI_ADDRCONFIG when binding to wildcard addresses https://bugzilla.redhat.com/show_bug.cgi?id=1112692 With parallel boot, network addresses might not yet be assigned [1], but binding to wildcard addresses should work. For non-wildcard addresses, ADDRCONFIG is still used. Document this in libvirtd.conf. [1] http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ (cherry picked from commit 819ca36e2b65a0a34263547161a98cec497780c8) Signed-off-by: Jiri Denemark --- daemon/libvirtd.conf | 4 ++++ src/rpc/virnetsocket.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf index 5353927..e518ae5 100644 --- a/daemon/libvirtd.conf +++ b/daemon/libvirtd.conf @@ -48,6 +48,10 @@ # Override the default configuration which binds to all network # interfaces. This can be a numeric IPv4/6 address, or hostname # +# If the libvirtd service is started in parallel with network +# startup (e.g. with systemd), binding to addresses other than +# the wildcards (0.0.0.0/::) might not be available yet. +# #listen_addr = "192.168.0.1" diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index fcd41ca..85fedb0 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -224,15 +224,29 @@ int virNetSocketNewListenTCP(const char *nodename, struct addrinfo hints; int fd = -1; size_t i; - int addrInUse = false; + bool addrInUse = false; + bool familyNotSupported = false; + virSocketAddr tmp_addr; *retsocks = NULL; *nretsocks = 0; memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; + /* Don't use ADDRCONFIG for binding to the wildcard address. + * Just catch the error returned by socket() if the system has + * no IPv6 support. + * + * This allows libvirtd to be started in parallel with the network + * startup in most cases. + */ + if (nodename && + !(virSocketAddrParse(&tmp_addr, nodename, AF_UNSPEC) > 0 && + virSocketAddrIsWildcard(&tmp_addr))) + hints.ai_flags |= AI_ADDRCONFIG; + int e = getaddrinfo(nodename, service, &hints, &ai); if (e != 0) { virReportError(VIR_ERR_SYSTEM_ERROR, @@ -249,6 +263,11 @@ int virNetSocketNewListenTCP(const char *nodename, if ((fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol)) < 0) { + if (errno == EAFNOSUPPORT) { + familyNotSupported = true; + runp = runp->ai_next; + continue; + } virReportSystemError(errno, "%s", _("Unable to create socket")); goto error; } @@ -306,6 +325,11 @@ int virNetSocketNewListenTCP(const char *nodename, fd = -1; } + if (nsocks == 0 && familyNotSupported) { + virReportSystemError(EAFNOSUPPORT, "%s", _("Unable to bind to port")); + goto error; + } + if (nsocks == 0 && addrInUse) { virReportSystemError(EADDRINUSE, "%s", _("Unable to bind to port")); -- 2.0.0