[PATCH 1/2] Split out bind() from virPortAllocatorAcquire

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---
 src/util/virportallocator.c | 72 ++++++++++++++++++++++++++++-----------------
 1 file changed, 45 insertions(+), 27 deletions(-)

diff --git a/src/util/virportallocator.c b/src/util/virportallocator.c
index 42e1f28..1922ea6 100644
--- a/src/util/virportallocator.c
+++ b/src/util/virportallocator.c
@@ -98,19 +98,59 @@ virPortAllocatorPtr virPortAllocatorNew(const char *name,
     return pa;
 }
 
+static int virPortAllocatorBindToPort(bool *used,
+                                      unsigned short port)
+{
+    struct sockaddr_in addr = {
+        .sin_family = AF_INET,
+        .sin_port = htons(port),
+        .sin_addr.s_addr = htonl(INADDR_ANY)
+    };
+    int reuse = 1;
+    int ret = -1;
+    int fd = -1;
+
+    *used = false;
+
+    fd = socket(PF_INET, SOCK_STREAM, 0);
+    if (fd < 0) {
+        virReportSystemError(errno, "%s", _("Unable to open test socket"));
+        goto cleanup;
+    }
+
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse,
+                   sizeof(reuse)) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("Unable to set socket reuse addr flag"));
+        goto cleanup;
+    }
+
+    if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+        if (errno == EADDRINUSE) {
+            *used = true;
+            ret = 0;
+        } else {
+            virReportSystemError(errno, _("Unable to bind to port %d"), port);
+        }
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FORCE_CLOSE(fd);
+    return ret;
+}
+
 int virPortAllocatorAcquire(virPortAllocatorPtr pa,
                             unsigned short *port)
 {
     int ret = -1;
     size_t i;
-    int fd = -1;
 
     *port = 0;
     virObjectLock(pa);
 
     for (i = pa->start; i <= pa->end && !*port; i++) {
-        int reuse = 1;
-        struct sockaddr_in addr;
         bool used = false;
 
         if (virBitmapGetBit(pa->bitmap,
@@ -123,31 +163,10 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa,
         if (used)
             continue;
 
-        addr.sin_family = AF_INET;
-        addr.sin_port = htons(i);
-        addr.sin_addr.s_addr = htonl(INADDR_ANY);
-        fd = socket(PF_INET, SOCK_STREAM, 0);
-        if (fd < 0) {
-            virReportSystemError(errno, "%s",
-                                 _("Unable to open test socket"));
+        if (virPortAllocatorBindToPort(&used, i) < 0)
             goto cleanup;
-        }
-
-        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse)) < 0) {
-            virReportSystemError(errno, "%s",
-                                 _("Unable to set socket reuse addr flag"));
-            goto cleanup;
-        }
 
-        if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
-            if (errno != EADDRINUSE) {
-                virReportSystemError(errno,
-                                     _("Unable to bind to port %zu"), i);
-                goto cleanup;
-            }
-            /* In use, try next */
-            VIR_FORCE_CLOSE(fd);
-        } else {
+        if (!used) {
             /* Add port to bitmap of reserved ports */
             if (virBitmapSetBit(pa->bitmap,
                                 i - pa->start) < 0) {
@@ -167,7 +186,6 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa,
     }
 cleanup:
     virObjectUnlock(pa);
-    VIR_FORCE_CLOSE(fd);
     return ret;
 }
 
-- 
1.8.1.5

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]