]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Convert QEMU driver over to use virPortAllocator APIs
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 9 Jan 2013 15:28:58 +0000 (15:28 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 16 Jan 2013 11:02:58 +0000 (11:02 +0000)
Replace the current QEMU driver code for managing port
reservations with the new virPortAllocator APIs.

src/qemu/qemu_conf.h
src/qemu/qemu_driver.c
src/qemu/qemu_process.c

index 965eff7148df7c0a3c488da93fff8c519199f873..6009118c4664f5c843669e2b6ec6319ac5f5be9d 100644 (file)
@@ -39,7 +39,7 @@
 # include "virusb.h"
 # include "cpu_conf.h"
 # include "driver.h"
-# include "virbitmap.h"
+# include "virportallocator.h"
 # include "vircommand.h"
 # include "virthreadpool.h"
 # include "locking/lock_manager.h"
@@ -150,7 +150,7 @@ struct _virQEMUDriver {
 
     virHashTablePtr sharedDisks;
 
-    virBitmapPtr reservedRemotePorts;
+    virPortAllocatorPtr remotePorts;
 
     virSysinfoDefPtr hostsysinfo;
 
index 630ff414aa2f7a0ee565978fa6991f7bfaed7888..8c39864cc62286b265d25780c8d19b2780dc6b0f 100644 (file)
@@ -809,9 +809,10 @@ qemuStartup(bool privileged,
     /* Allocate bitmap for remote display port reservations. We cannot
      * do this before the config is loaded properly, since the port
      * numbers are configurable now */
-    if ((qemu_driver->reservedRemotePorts =
-         virBitmapNew(qemu_driver->remotePortMax - qemu_driver->remotePortMin)) == NULL)
-        goto out_of_memory;
+    if ((qemu_driver->remotePorts =
+         virPortAllocatorNew(qemu_driver->remotePortMin,
+                             qemu_driver->remotePortMax)) == NULL)
+        goto error;
 
     /* We should always at least have the 'nop' manager, so
      * NULLs here are a fatal error
@@ -1104,7 +1105,7 @@ qemuShutdown(void) {
     qemuCapsCacheFree(qemu_driver->capsCache);
 
     virDomainObjListDeinit(&qemu_driver->domains);
-    virBitmapFree(qemu_driver->reservedRemotePorts);
+    virObjectUnref(qemu_driver->remotePorts);
 
     virSysinfoDefFree(qemu_driver->hostsysinfo);
 
index 6c16f3b31d5f724133ff7584256bc20a8d94b24b..2f0821518337d8ef349973fe1c59721900cb79da 100644 (file)
@@ -2604,73 +2604,6 @@ qemuProcessInitPCIAddresses(virQEMUDriverPtr driver,
 }
 
 
-static int qemuProcessNextFreePort(virQEMUDriverPtr driver,
-                                   int startPort)
-{
-    int i;
-
-    for (i = startPort ; i < driver->remotePortMax; i++) {
-        int fd;
-        int reuse = 1;
-        struct sockaddr_in addr;
-        bool used = false;
-
-        if (virBitmapGetBit(driver->reservedRemotePorts,
-                            i - driver->remotePortMin, &used) < 0)
-            VIR_DEBUG("virBitmapGetBit failed on bit %d", i - driver->remotePortMin);
-
-        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)
-            return -1;
-
-        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse)) < 0) {
-            VIR_FORCE_CLOSE(fd);
-            break;
-        }
-
-        if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
-            /* Not in use, lets grab it */
-            VIR_FORCE_CLOSE(fd);
-            /* Add port to bitmap of reserved ports */
-            if (virBitmapSetBit(driver->reservedRemotePorts,
-                                i - driver->remotePortMin) < 0) {
-                VIR_DEBUG("virBitmapSetBit failed on bit %d",
-                          i - driver->remotePortMin);
-            }
-            return i;
-        }
-        VIR_FORCE_CLOSE(fd);
-
-        if (errno == EADDRINUSE) {
-            /* In use, try next */
-            continue;
-        }
-        /* Some other bad failure, get out.. */
-        break;
-    }
-    return -1;
-}
-
-
-static void
-qemuProcessReturnPort(virQEMUDriverPtr driver,
-                      int port)
-{
-    if (port < driver->remotePortMin)
-        return;
-
-    if (virBitmapClearBit(driver->reservedRemotePorts,
-                          port - driver->remotePortMin) < 0)
-        VIR_DEBUG("Could not mark port %d as unused", port);
-}
-
-
 static int
 qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
                                 virDomainChrDefPtr dev,
@@ -3665,20 +3598,18 @@ int qemuProcessStart(virConnectPtr conn,
         if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
             !graphics->data.vnc.socket &&
             graphics->data.vnc.autoport) {
-            int port = qemuProcessNextFreePort(driver, driver->remotePortMin);
-            if (port < 0) {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               "%s", _("Unable to find an unused port for VNC"));
+            unsigned short port;
+            if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0)
                 goto cleanup;
-            }
             graphics->data.vnc.port = port;
         } else if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
-            int port = -1;
+            unsigned short port = 0;
             if (graphics->data.spice.autoport ||
                 graphics->data.spice.port == -1) {
-                port = qemuProcessNextFreePort(driver, driver->remotePortMin);
+                if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0)
+                    goto cleanup;
 
-                if (port < 0) {
+                if (port == 0) {
                     virReportError(VIR_ERR_INTERNAL_ERROR,
                                    "%s", _("Unable to find an unused port for SPICE"));
                     goto cleanup;
@@ -3689,12 +3620,14 @@ int qemuProcessStart(virConnectPtr conn,
             if (driver->spiceTLS &&
                 (graphics->data.spice.autoport ||
                  graphics->data.spice.tlsPort == -1)) {
-                int tlsPort = qemuProcessNextFreePort(driver,
-                                                      graphics->data.spice.port + 1);
-                if (tlsPort < 0) {
+                unsigned short tlsPort;
+                if (virPortAllocatorAcquire(driver->remotePorts, &tlsPort) < 0)
+                    goto cleanup;
+
+                if (tlsPort == 0) {
                     virReportError(VIR_ERR_INTERNAL_ERROR,
                                    "%s", _("Unable to find an unused port for SPICE TLS"));
-                    qemuProcessReturnPort(driver, port);
+                    virPortAllocatorRelease(driver->remotePorts, port);
                     goto cleanup;
                 }
 
@@ -4363,12 +4296,15 @@ retry:
         virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
         if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
             graphics->data.vnc.autoport) {
-            qemuProcessReturnPort(driver, graphics->data.vnc.port);
+            ignore_value(virPortAllocatorRelease(driver->remotePorts,
+                                                 graphics->data.vnc.port));
         }
         if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
             graphics->data.spice.autoport) {
-            qemuProcessReturnPort(driver, graphics->data.spice.port);
-            qemuProcessReturnPort(driver, graphics->data.spice.tlsPort);
+            ignore_value(virPortAllocatorRelease(driver->remotePorts,
+                                                 graphics->data.spice.port));
+            ignore_value(virPortAllocatorRelease(driver->remotePorts,
+                                                 graphics->data.spice.tlsPort));
         }
     }