[libvirt] [PATCH] Don't use AI_ADDRCONFIG when binding to wildcard addresses

Ján Tomko jtomko at redhat.com
Thu May 29 09:32:13 UTC 2014


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/
---
 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 aeba11d..e5856d4 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 a7e1783..87b39f2 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -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"));
-- 
1.8.3.2




More information about the libvir-list mailing list