<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from rtf -->
<style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<font face="Calibri" size="2"><span style="font-size:10.5pt;">
<div align="left" style="text-align:justify;">From f56b290eab36bbb7a9ac53778a55638d473504d1 Mon Sep 17 00:00:00 2001</div>
<div align="left" style="text-align:justify;">From: WangYufei <james.wangyufei@huawei.com></div>
<div align="left" style="text-align:justify;">Date: Fri, 11 Oct 2013 11:27:13 +0800</div>
<div align="left" style="text-align:justify;">Subject: [PATCH] qemu_migrate: Fix assign the same port when migrating concurrently</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">When we migrate vms concurrently, there's a chance that libvirtd on destination assign the same port for different migrations, which will lead to migration failed during migration prepare phase on destination. So
we use virPortAllocator here to solve the problem.</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">Signed-off-by: WangYufei <james.wangyufei@huawei.com></div>
<div align="left" style="text-align:justify;">---</div>
<div align="left" style="text-align:justify;"> src/qemu/qemu_command.h   |    3 +++</div>
<div align="left" style="text-align:justify;"> src/qemu/qemu_conf.h      |    6 +++---</div>
<div align="left" style="text-align:justify;"> src/qemu/qemu_domain.h    |    1 +</div>
<div align="left" style="text-align:justify;"> src/qemu/qemu_driver.c    |    6 ++++++</div>
<div align="left" style="text-align:justify;"> src/qemu/qemu_migration.c |   28 +++++++++++++++++++++-------</div>
<div align="left" style="text-align:justify;"> 5 files changed, 34 insertions(+), 10 deletions(-)</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h</div>
<div align="left" style="text-align:justify;">index 2e2acfb..3277ba4 100644</div>
<div align="left" style="text-align:justify;">--- a/src/qemu/qemu_command.h</div>
<div align="left" style="text-align:justify;">+++ b/src/qemu/qemu_command.h</div>
<div align="left" style="text-align:justify;">@@ -51,6 +51,9 @@</div>
<div align="left" style="text-align:justify;"> # define QEMU_WEBSOCKET_PORT_MIN  5700</div>
<div align="left" style="text-align:justify;"> # define QEMU_WEBSOCKET_PORT_MAX  65535</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">+# define QEMU_MIGRATION_PORT_MIN 49152</div>
<div align="left" style="text-align:justify;">+# define QEMU_MIGRATION_PORT_MAX 49215</div>
<div align="left" style="text-align:justify;">+</div>
<div align="left" style="text-align:justify;"> typedef struct _qemuBuildCommandLineCallbacks qemuBuildCommandLineCallbacks;</div>
<div align="left" style="text-align:justify;"> typedef qemuBuildCommandLineCallbacks *qemuBuildCommandLineCallbacksPtr;</div>
<div align="left" style="text-align:justify;"> struct _qemuBuildCommandLineCallbacks {</div>
<div align="left" style="text-align:justify;">diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h</div>
<div align="left" style="text-align:justify;">index da29a2a..3176085 100644</div>
<div align="left" style="text-align:justify;">--- a/src/qemu/qemu_conf.h</div>
<div align="left" style="text-align:justify;">+++ b/src/qemu/qemu_conf.h</div>
<div align="left" style="text-align:justify;">@@ -221,6 +221,9 @@ struct _virQEMUDriver {</div>
<div align="left" style="text-align:justify;">     /* Immutable pointer, self-locking APIs */</div>
<div align="left" style="text-align:justify;">     virPortAllocatorPtr webSocketPorts;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">+    /* Immutable pointer, self-locking APIs */</div>
<div align="left" style="text-align:justify;">+    virPortAllocatorPtr migrationPorts;</div>
<div align="left" style="text-align:justify;">+</div>
<div align="left" style="text-align:justify;">     /* Immutable pointer, lockless APIs*/</div>
<div align="left" style="text-align:justify;">     virSysinfoDefPtr hostsysinfo;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">@@ -242,9 +245,6 @@ struct _qemuDomainCmdlineDef {</div>
<div align="left" style="text-align:justify;">     char **env_value;</div>
<div align="left" style="text-align:justify;"> };</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">-/* Port numbers used for KVM migration. */</div>
<div align="left" style="text-align:justify;">-# define QEMUD_MIGRATION_FIRST_PORT 49152</div>
<div align="left" style="text-align:justify;">-# define QEMUD_MIGRATION_NUM_PORTS 64</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;"> void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def);</div>
<div align="left" style="text-align:justify;">diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h</div>
<div align="left" style="text-align:justify;">index 21f116c..16c55a6 100644</div>
<div align="left" style="text-align:justify;">--- a/src/qemu/qemu_domain.h</div>
<div align="left" style="text-align:justify;">+++ b/src/qemu/qemu_domain.h</div>
<div align="left" style="text-align:justify;">@@ -160,6 +160,7 @@ struct _qemuDomainObjPrivate {</div>
<div align="left" style="text-align:justify;">     unsigned long migMaxBandwidth;</div>
<div align="left" style="text-align:justify;">     char *origname;</div>
<div align="left" style="text-align:justify;">     int nbdPort; /* Port used for migration with NBD */</div>
<div align="left" style="text-align:justify;">+    int migrationPort;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">     virChrdevsPtr devs;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c</div>
<div align="left" style="text-align:justify;">index cfdbb9a..c08a73c 100644</div>
<div align="left" style="text-align:justify;">--- a/src/qemu/qemu_driver.c</div>
<div align="left" style="text-align:justify;">+++ b/src/qemu/qemu_driver.c</div>
<div align="left" style="text-align:justify;">@@ -687,6 +687,11 @@ qemuStateInitialize(bool privileged,</div>
<div align="left" style="text-align:justify;">                              cfg->webSocketPortMax)) == NULL)</div>
<div align="left" style="text-align:justify;">         goto error;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">+    if ((qemu_driver->migrationPorts =</div>
<div align="left" style="text-align:justify;">+         virPortAllocatorNew(QEMU_MIGRATION_PORT_MIN,</div>
<div align="left" style="text-align:justify;">+                             QEMU_MIGRATION_PORT_MAX)) == NULL)</div>
<div align="left" style="text-align:justify;">+        goto error;</div>
<div align="left" style="text-align:justify;">+</div>
<div align="left" style="text-align:justify;">     if (qemuSecurityInit(qemu_driver) < 0)</div>
<div align="left" style="text-align:justify;">         goto error;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">@@ -993,6 +998,7 @@ qemuStateCleanup(void) {</div>
<div align="left" style="text-align:justify;">     virObjectUnref(qemu_driver->domains);</div>
<div align="left" style="text-align:justify;">     virObjectUnref(qemu_driver->remotePorts);</div>
<div align="left" style="text-align:justify;">     virObjectUnref(qemu_driver->webSocketPorts);</div>
<div align="left" style="text-align:justify;">+    virObjectUnref(qemu_driver->migrationPorts);</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">     virObjectUnref(qemu_driver->xmlopt);</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c</div>
<div align="left" style="text-align:justify;">index 3a1aab7..93ae237 100644</div>
<div align="left" style="text-align:justify;">--- a/src/qemu/qemu_migration.c</div>
<div align="left" style="text-align:justify;">+++ b/src/qemu/qemu_migration.c</div>
<div align="left" style="text-align:justify;">@@ -2147,6 +2147,9 @@ qemuMigrationPrepareCleanup(virQEMUDriverPtr driver,</div>
<div align="left" style="text-align:justify;">               qemuDomainJobTypeToString(priv->job.active),</div>
<div align="left" style="text-align:justify;">               qemuDomainAsyncJobTypeToString(priv->job.asyncJob));</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">+    virPortAllocatorRelease(driver->migrationPorts, priv->migrationPort);</div>
<div align="left" style="text-align:justify;">+    priv->migrationPort = 0;</div>
<div align="left" style="text-align:justify;">+</div>
<div align="left" style="text-align:justify;">     if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN))</div>
<div align="left" style="text-align:justify;">         return;</div>
<div align="left" style="text-align:justify;">     qemuDomainObjDiscardAsyncJob(driver, vm);</div>
<div align="left" style="text-align:justify;">@@ -2297,6 +2300,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">     *def = NULL;</div>
<div align="left" style="text-align:justify;">     priv = vm->privateData;</div>
<div align="left" style="text-align:justify;">+    priv->migrationPort = port;</div>
<div align="left" style="text-align:justify;">     if (VIR_STRDUP(priv->origname, origname) < 0)</div>
<div align="left" style="text-align:justify;">         goto cleanup;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">@@ -2415,6 +2419,11 @@ cleanup:</div>
<div align="left" style="text-align:justify;">     VIR_FREE(xmlout);</div>
<div align="left" style="text-align:justify;">     VIR_FORCE_CLOSE(dataFD[0]);</div>
<div align="left" style="text-align:justify;">     VIR_FORCE_CLOSE(dataFD[1]);</div>
<div align="left" style="text-align:justify;">+    if (ret < 0) {</div>
<div align="left" style="text-align:justify;">+        virPortAllocatorRelease(driver->migrationPorts, port);</div>
<div align="left" style="text-align:justify;">+        if (priv)</div>
<div align="left" style="text-align:justify;">+            priv->migrationPort = 0;</div>
<div align="left" style="text-align:justify;">+    }</div>
<div align="left" style="text-align:justify;">     if (vm) {</div>
<div align="left" style="text-align:justify;">         if (ret >= 0 || vm->persistent)</div>
<div align="left" style="text-align:justify;">             virObjectUnlock(vm);</div>
<div align="left" style="text-align:justify;">@@ -2493,7 +2502,6 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,</div>
<div align="left" style="text-align:justify;">                            const char *origname,</div>
<div align="left" style="text-align:justify;">                            unsigned long flags)</div>
<div align="left" style="text-align:justify;"> {</div>
<div align="left" style="text-align:justify;">-    static int port = 0;</div>
<div align="left" style="text-align:justify;">     int this_port;</div>
<div align="left" style="text-align:justify;">     char *hostname = NULL;</div>
<div align="left" style="text-align:justify;">     const char *p;</div>
<div align="left" style="text-align:justify;">@@ -2521,8 +2529,9 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,</div>
<div align="left" style="text-align:justify;">      * to be a correct hostname which refers to the target machine).</div>
<div align="left" style="text-align:justify;">      */</div>
<div align="left" style="text-align:justify;">     if (uri_in == NULL) {</div>
<div align="left" style="text-align:justify;">-        this_port = QEMUD_MIGRATION_FIRST_PORT + port++;</div>
<div align="left" style="text-align:justify;">-        if (port == QEMUD_MIGRATION_NUM_PORTS) port = 0;</div>
<div align="left" style="text-align:justify;">+        if (virPortAllocatorAcquire(driver->migrationPorts,</div>
<div align="left" style="text-align:justify;">+                                    (unsigned short *)&this_port) < 0)</div>
<div align="left" style="text-align:justify;">+            goto cleanup;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">         /* Get hostname */</div>
<div align="left" style="text-align:justify;">         if ((hostname = virGetHostname()) == NULL)</div>
<div align="left" style="text-align:justify;">@@ -2578,9 +2587,9 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">         if (uri->port == 0) {</div>
<div align="left" style="text-align:justify;">             /* Generate a port */</div>
<div align="left" style="text-align:justify;">-            this_port = QEMUD_MIGRATION_FIRST_PORT + port++;</div>
<div align="left" style="text-align:justify;">-            if (port == QEMUD_MIGRATION_NUM_PORTS)</div>
<div align="left" style="text-align:justify;">-                port = 0;</div>
<div align="left" style="text-align:justify;">+            if (virPortAllocatorAcquire(driver->migrationPorts,</div>
<div align="left" style="text-align:justify;">+                                        (unsigned short *)&this_port) < 0)</div>
<div align="left" style="text-align:justify;">+                goto cleanup;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">             /* Caller frees */</div>
<div align="left" style="text-align:justify;">             if (virAsprintf(uri_out, "%s:%d", uri_in, this_port) < 0)</div>
<div align="left" style="text-align:justify;">@@ -2600,8 +2609,11 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,</div>
<div align="left" style="text-align:justify;"> cleanup:</div>
<div align="left" style="text-align:justify;">     virURIFree(uri);</div>
<div align="left" style="text-align:justify;">     VIR_FREE(hostname);</div>
<div align="left" style="text-align:justify;">-    if (ret != 0)</div>
<div align="left" style="text-align:justify;">+    if (ret != 0) {</div>
<div align="left" style="text-align:justify;">         VIR_FREE(*uri_out);</div>
<div align="left" style="text-align:justify;">+        virPortAllocatorRelease(driver->migrationPorts,</div>
<div align="left" style="text-align:justify;">+                                (unsigned short)this_port);</div>
<div align="left" style="text-align:justify;">+    }</div>
<div align="left" style="text-align:justify;">     return ret;</div>
<div align="left" style="text-align:justify;"> }</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">@@ -4370,6 +4382,8 @@ qemuMigrationFinish(virQEMUDriverPtr driver,</div>
<div align="left" style="text-align:justify;">         }</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">         qemuMigrationStopNBDServer(driver, vm, mig);</div>
<div align="left" style="text-align:justify;">+        virPortAllocatorRelease(driver->migrationPorts, priv->migrationPort);</div>
<div align="left" style="text-align:justify;">+        priv->migrationPort = 0;</div>
<div align="left" style="text-align:justify;"> </div>
<div align="left" style="text-align:justify;">         if (flags & VIR_MIGRATE_PERSIST_DEST) {</div>
<div align="left" style="text-align:justify;">             virDomainDefPtr vmdef;</div>
<div align="left" style="text-align:justify;">-- </div>
<div align="left" style="text-align:justify;">1.7.3.1.msysgit.0</div>
<div align="left" style="text-align:justify;"><font face="Times New Roman"> </font></div>
<div>Best Regards,</div>
<div>-WangYufei</div>
<div align="left" style="text-align:justify;"><font face="Times New Roman"> </font></div>
<div align="left" style="text-align:justify;"><font face="Times New Roman"> </font></div>
<div align="left" style="text-align:justify;"><font face="Times New Roman"> </font></div>
</span></font>
</body>
</html>