File libxl-release-mig-port.patch of Package libvirt.18121

libxl: fix leaking of allocated migration ports

Although the migration port is immediately released in the
finish phase of migration, it was never set in the domain
private object when allocated in the prepare phase. So
libxlDomainMigrationFinish() always released a 0-initialized
migrationPort, leaking any allocated port. After enough
migrations to exhaust the migration port pool, migration would
fail with

error: internal error: Unable to find an unused port in range
       'migration' (49152-49216)

Fix it by setting libxlDomainObjPrivate->migrationPort to the
port allocated in the prepare phase. While at it, also fix
leaking an allocated port if the prepare phase fails.

Index: libvirt-2.0.0/src/libxl/libxl_migration.c
===================================================================
--- libvirt-2.0.0.orig/src/libxl/libxl_migration.c
+++ libvirt-2.0.0/src/libxl/libxl_migration.c
@@ -509,6 +509,7 @@ libxlDomainMigrationPrepare(virConnectPt
     libxlDriverPrivatePtr driver = dconn->privateData;
     libxlMigrationCookiePtr mig = NULL;
     virDomainObjPtr vm = NULL;
+    libxlDomainObjPrivatePtr priv;
     char *hostname = NULL;
     unsigned short port;
     char portstr[100];
@@ -537,6 +538,7 @@ libxlDomainMigrationPrepare(virConnectPt
                                    NULL)))
         goto error;
     *def = NULL;
+    priv = vm->privateData;
 
     /*
      * Unless an error is encountered in this function, the job will
@@ -560,6 +562,7 @@ libxlDomainMigrationPrepare(virConnectPt
         if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
             goto endjob;
 
+        priv->migrationPort = port;
         if (virAsprintf(uri_out, "tcp://%s:%d", hostname, port) < 0)
             goto endjob;
     } else {
@@ -594,6 +597,7 @@ libxlDomainMigrationPrepare(virConnectPt
             if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
                 goto endjob;
 
+            priv->migrationPort = port;
         } else {
             port = uri->port;
         }
@@ -659,6 +663,10 @@ libxlDomainMigrationPrepare(virConnectPt
     }
     VIR_FREE(socks);
     virObjectUnref(args);
+    if (priv) {
+        virPortAllocatorRelease(driver->migrationPorts, priv->migrationPort);
+        priv->migrationPort = 0;
+    }
 
     /* Remove virDomainObj from domain list */
     if (vm) {
openSUSE Build Service is sponsored by