qemuDomainJobTypeToString(priv->job.active),
qemuDomainAsyncJobTypeToString(priv->job.asyncJob));
+ virPortAllocatorRelease(driver->migrationPorts, priv->migrationPort);
+ priv->migrationPort = 0;
+
if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN))
return;
qemuDomainObjDiscardAsyncJob(driver, vm);
virDomainDefPtr *def,
const char *origname,
virStreamPtr st,
- unsigned int port,
+ unsigned short port,
+ bool autoPort,
const char *listenAddress,
unsigned long flags)
{
goto cleanup;
}
+ if (autoPort)
+ priv->migrationPort = port;
ret = 0;
cleanup:
ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
cookieout, cookieoutlen, def, origname,
- st, 0, NULL, flags);
+ st, 0, false, NULL, flags);
return ret;
}
const char *listenAddress,
unsigned long flags)
{
- static int port = 0;
- int this_port;
+ unsigned short port = 0;
+ bool autoPort = true;
char *hostname = NULL;
const char *p;
char *uri_str = NULL;
* to be a correct hostname which refers to the target machine).
*/
if (uri_in == NULL) {
- this_port = QEMUD_MIGRATION_FIRST_PORT + port++;
- if (port == QEMUD_MIGRATION_NUM_PORTS) port = 0;
+ if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0) {
+ goto cleanup;
+ } else if (!port) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No migration port available within the "
+ "configured range"));
+ goto cleanup;
+ }
- /* Get hostname */
if ((hostname = virGetHostname()) == NULL)
goto cleanup;
* new targets accept both syntaxes though.
*/
/* Caller frees */
- if (virAsprintf(uri_out, "tcp:%s:%d", hostname, this_port) < 0)
+ if (virAsprintf(uri_out, "tcp:%s:%d", hostname, port) < 0)
goto cleanup;
} else {
/* Check the URI starts with "tcp:". We will escape the
}
if (uri->port == 0) {
- /* Generate a port */
- this_port = QEMUD_MIGRATION_FIRST_PORT + port++;
- if (port == QEMUD_MIGRATION_NUM_PORTS)
- port = 0;
+ if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0) {
+ goto cleanup;
+ } else if (!port) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No migration port available within the "
+ "configured range"));
+ goto cleanup;
+ }
/* Caller frees */
- if (virAsprintf(uri_out, "%s:%d", uri_in, this_port) < 0)
+ if (virAsprintf(uri_out, "%s:%d", uri_in, port) < 0)
goto cleanup;
} else {
- this_port = uri->port;
+ port = uri->port;
+ autoPort = false;
}
}
ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
cookieout, cookieoutlen, def, origname,
- NULL, this_port, listenAddress, flags);
+ NULL, port, autoPort, listenAddress, flags);
cleanup:
virURIFree(uri);
VIR_FREE(hostname);
- if (ret != 0)
+ if (ret != 0) {
VIR_FREE(*uri_out);
+ if (autoPort)
+ virPortAllocatorRelease(driver->migrationPorts, port);
+ }
return ret;
}
}
qemuMigrationStopNBDServer(driver, vm, mig);
+ virPortAllocatorRelease(driver->migrationPorts, priv->migrationPort);
+ priv->migrationPort = 0;
if (flags & VIR_MIGRATE_PERSIST_DEST) {
virDomainDefPtr vmdef;