# 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"
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,
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;
}
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"));