Don't use AI_ADDRCONFIG when binding to wildcard addresses

https://bugzilla.redhat.com/show_bug.cgi?id=1098659

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/
This commit is contained in:
Ján Tomko 2014-05-29 11:21:25 +02:00
parent 25a5df16a6
commit 819ca36e2b
2 changed files with 30 additions and 2 deletions

View File

@ -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"

View File

@ -226,15 +226,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,
@ -251,6 +265,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;
}
@ -307,6 +326,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"));