On Tue, Oct 15, 2013 at 04:24:14AM +0000, Wangyufei (A) wrote:
> >From f56b290eab36bbb7a9ac53778a55638d473504d1 Mon Sep 17 00:00:00 2001
> From: WangYufei <james.wangyu...@huawei.com>
> Date: Fri, 11 Oct 2013 11:27:13 +0800
> Subject: [PATCH] qemu_migrate: Fix assign the same port when migrating 
> concurrently
> 
> 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.

In future please line wrap your commit messages at ~70 characters.

> Signed-off-by: WangYufei <james.wangyu...@huawei.com>
> ---
>  src/qemu/qemu_command.h   |    3 +++
>  src/qemu/qemu_conf.h      |    6 +++---
>  src/qemu/qemu_domain.h    |    1 +
>  src/qemu/qemu_driver.c    |    6 ++++++
>  src/qemu/qemu_migration.c |   28 +++++++++++++++++++++-------
>  5 files changed, 34 insertions(+), 10 deletions(-)
> 
> diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
> index 2e2acfb..3277ba4 100644
> --- a/src/qemu/qemu_command.h
> +++ b/src/qemu/qemu_command.h
> @@ -51,6 +51,9 @@
>  # define QEMU_WEBSOCKET_PORT_MIN  5700
>  # define QEMU_WEBSOCKET_PORT_MAX  65535
>  
> +# define QEMU_MIGRATION_PORT_MIN 49152
> +# define QEMU_MIGRATION_PORT_MAX 49215
> +
>  typedef struct _qemuBuildCommandLineCallbacks qemuBuildCommandLineCallbacks;
>  typedef qemuBuildCommandLineCallbacks *qemuBuildCommandLineCallbacksPtr;
>  struct _qemuBuildCommandLineCallbacks {
> diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
> index da29a2a..3176085 100644
> --- a/src/qemu/qemu_conf.h
> +++ b/src/qemu/qemu_conf.h
> @@ -221,6 +221,9 @@ struct _virQEMUDriver {
>      /* Immutable pointer, self-locking APIs */
>      virPortAllocatorPtr webSocketPorts;
>  
> +    /* Immutable pointer, self-locking APIs */
> +    virPortAllocatorPtr migrationPorts;
> +
>      /* Immutable pointer, lockless APIs*/
>      virSysinfoDefPtr hostsysinfo;
>  
> @@ -242,9 +245,6 @@ struct _qemuDomainCmdlineDef {
>      char **env_value;
>  };
>  
> -/* Port numbers used for KVM migration. */
> -# define QEMUD_MIGRATION_FIRST_PORT 49152
> -# define QEMUD_MIGRATION_NUM_PORTS 64
>  
>  
>  void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def);
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 21f116c..16c55a6 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -160,6 +160,7 @@ struct _qemuDomainObjPrivate {
>      unsigned long migMaxBandwidth;
>      char *origname;
>      int nbdPort; /* Port used for migration with NBD */
> +    int migrationPort;
>  
>      virChrdevsPtr devs;
>  
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index cfdbb9a..c08a73c 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -687,6 +687,11 @@ qemuStateInitialize(bool privileged,
>                               cfg->webSocketPortMax)) == NULL)
>          goto error;
>  
> +    if ((qemu_driver->migrationPorts =
> +         virPortAllocatorNew(QEMU_MIGRATION_PORT_MIN,
> +                             QEMU_MIGRATION_PORT_MAX)) == NULL)
> +        goto error;
> +
>      if (qemuSecurityInit(qemu_driver) < 0)
>          goto error;
>  
> @@ -993,6 +998,7 @@ qemuStateCleanup(void) {
>      virObjectUnref(qemu_driver->domains);
>      virObjectUnref(qemu_driver->remotePorts);
>      virObjectUnref(qemu_driver->webSocketPorts);
> +    virObjectUnref(qemu_driver->migrationPorts);
>  
>      virObjectUnref(qemu_driver->xmlopt);
>  
> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index 3a1aab7..93ae237 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
> @@ -2147,6 +2147,9 @@ qemuMigrationPrepareCleanup(virQEMUDriverPtr driver,
>                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);
> @@ -2297,6 +2300,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
>  
>      *def = NULL;
>      priv = vm->privateData;
> +    priv->migrationPort = port;
>      if (VIR_STRDUP(priv->origname, origname) < 0)
>          goto cleanup;
>  
> @@ -2415,6 +2419,11 @@ cleanup:
>      VIR_FREE(xmlout);
>      VIR_FORCE_CLOSE(dataFD[0]);
>      VIR_FORCE_CLOSE(dataFD[1]);
> +    if (ret < 0) {
> +        virPortAllocatorRelease(driver->migrationPorts, port);
> +        if (priv)
> +            priv->migrationPort = 0;
> +    }
>      if (vm) {
>          if (ret >= 0 || vm->persistent)
>              virObjectUnlock(vm);
> @@ -2493,7 +2502,6 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
>                             const char *origname,
>                             unsigned long flags)
>  {
> -    static int port = 0;
>      int this_port;
>      char *hostname = NULL;
>      const char *p;
> @@ -2521,8 +2529,9 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
>       * 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,
> +                                    (unsigned short *)&this_port) < 0)
> +            goto cleanup;

Just declare 'this_port' to be an 'unsigned short' instead of casting
it everywhere.


ACK if you fix that.

As a followup, it might be desirable to make the migration port range
be configurable via /etc/libvirt/qemu.conf, in the same way that we
have the VNC/SPICE port range configurable.


Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|

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

Reply via email to