mirror of
https://github.com/libvirt/libvirt.git
synced 2026-09-03 20:53:04 -05:00
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:
@@ -48,6 +48,10 @@
|
|||||||
# Override the default configuration which binds to all network
|
# Override the default configuration which binds to all network
|
||||||
# interfaces. This can be a numeric IPv4/6 address, or hostname
|
# 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"
|
#listen_addr = "192.168.0.1"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+26
-2
@@ -226,15 +226,29 @@ int virNetSocketNewListenTCP(const char *nodename,
|
|||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
size_t i;
|
size_t i;
|
||||||
int addrInUse = false;
|
bool addrInUse = false;
|
||||||
|
bool familyNotSupported = false;
|
||||||
|
virSocketAddr tmp_addr;
|
||||||
|
|
||||||
*retsocks = NULL;
|
*retsocks = NULL;
|
||||||
*nretsocks = 0;
|
*nretsocks = 0;
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
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);
|
int e = getaddrinfo(nodename, service, &hints, &ai);
|
||||||
if (e != 0) {
|
if (e != 0) {
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
@@ -251,6 +265,11 @@ int virNetSocketNewListenTCP(const char *nodename,
|
|||||||
|
|
||||||
if ((fd = socket(runp->ai_family, runp->ai_socktype,
|
if ((fd = socket(runp->ai_family, runp->ai_socktype,
|
||||||
runp->ai_protocol)) < 0) {
|
runp->ai_protocol)) < 0) {
|
||||||
|
if (errno == EAFNOSUPPORT) {
|
||||||
|
familyNotSupported = true;
|
||||||
|
runp = runp->ai_next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
virReportSystemError(errno, "%s", _("Unable to create socket"));
|
virReportSystemError(errno, "%s", _("Unable to create socket"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -307,6 +326,11 @@ int virNetSocketNewListenTCP(const char *nodename,
|
|||||||
fd = -1;
|
fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nsocks == 0 && familyNotSupported) {
|
||||||
|
virReportSystemError(EAFNOSUPPORT, "%s", _("Unable to bind to port"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (nsocks == 0 &&
|
if (nsocks == 0 &&
|
||||||
addrInUse) {
|
addrInUse) {
|
||||||
virReportSystemError(EADDRINUSE, "%s", _("Unable to bind to port"));
|
virReportSystemError(EADDRINUSE, "%s", _("Unable to bind to port"));
|
||||||
|
|||||||
Reference in New Issue
Block a user