[libvirt] [PATCH v2 5/6] qemu: migration: selective block device migration

Michal Privoznik mprivozn at redhat.com
Mon May 25 14:58:51 UTC 2015


On 21.05.2015 13:07, Pavel Boldin wrote:
> Implement a `migrate_disks' parameters for the QEMU driver. This multi-
> value parameter can be used to explicitly specify what block devices
> are to be migrated using the NBD server. Tunnelled migration using NBD
> is to be done.
> 
> Signed-off-by: Pavel Boldin <pboldin at mirantis.com>
> ---
>  include/libvirt/libvirt-domain.h |   9 ++
>  src/qemu/qemu_driver.c           |  66 ++++++++++-----
>  src/qemu/qemu_migration.c        | 174 +++++++++++++++++++++++++--------------
>  src/qemu/qemu_migration.h        |  23 ++++--
>  4 files changed, 183 insertions(+), 89 deletions(-)
> 
> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
> index 0f465b9..6b48923 100644
> --- a/include/libvirt/libvirt-domain.h
> +++ b/include/libvirt/libvirt-domain.h
> @@ -748,6 +748,15 @@ typedef enum {
>   */
>  # define VIR_MIGRATE_PARAM_LISTEN_ADDRESS    "listen_address"
>  
> +/**
> + * VIR_MIGRATE_PARAM_MIGRATE_DISKS:
> + *
> + * virDomainMigrate* params multiple field: The multiple values that list
> + * the block devices to be migrated. At the moment this is only supported
> + * by the QEMU driver but not for the tunnelled migration.
> + */
> +# define VIR_MIGRATE_PARAM_MIGRATE_DISKS    "migrate_disks"
> +
>  /* Domain migration. */
>  virDomainPtr virDomainMigrate (virDomainPtr domain, virConnectPtr dconn,
>                                 unsigned long flags, const char *dname,
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 2668011..77b7d9d 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -12472,7 +12472,7 @@ qemuDomainMigratePrepare2(virConnectPtr dconn,
>      ret = qemuMigrationPrepareDirect(driver, dconn,
>                                       NULL, 0, NULL, NULL, /* No cookies */
>                                       uri_in, uri_out,
> -                                     &def, origname, NULL, flags);
> +                                     &def, origname, NULL, flags, NULL);
>  
>   cleanup:
>      VIR_FREE(origname);
> @@ -12525,7 +12525,7 @@ qemuDomainMigratePerform(virDomainPtr dom,
>       * Consume any cookie we were able to decode though
>       */
>      ret = qemuMigrationPerform(driver, dom->conn, vm,
> -                               NULL, dconnuri, uri, NULL, NULL,
> +                               NULL, dconnuri, uri, NULL, NULL, NULL,
>                                 cookie, cookielen,
>                                 NULL, NULL, /* No output cookies in v2 */
>                                 flags, dname, resource, false);
> @@ -12602,7 +12602,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
>      }
>  
>      return qemuMigrationBegin(domain->conn, vm, xmlin, dname,
> -                              cookieout, cookieoutlen, flags);
> +                              cookieout, cookieoutlen, flags, NULL);
>  }
>  
>  static char *
> @@ -12615,11 +12615,13 @@ qemuDomainMigrateBegin3Params(virDomainPtr domain,
>  {
>      const char *xmlin = NULL;
>      const char *dname = NULL;
> +    const char **migrate_disks = NULL;
> +    char *ret = NULL;
>      virDomainObjPtr vm;
>  
>      virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
>      if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
> -        return NULL;
> +        goto cleanup;
>  
>      if (virTypedParamsGetString(params, nparams,
>                                  VIR_MIGRATE_PARAM_DEST_XML,
> @@ -12627,18 +12629,26 @@ qemuDomainMigrateBegin3Params(virDomainPtr domain,
>          virTypedParamsGetString(params, nparams,
>                                  VIR_MIGRATE_PARAM_DEST_NAME,
>                                  &dname) < 0)
> -        return NULL;
> +        goto cleanup;
> +
> +    migrate_disks = virTypedParamsPickStrings(params, nparams,
> +                                              VIR_MIGRATE_PARAM_MIGRATE_DISKS,
> +                                              NULL);

Since this function looks slightly different now, this patch needs to be
changed too. Mostly, where @migrate_disks is parsed, new variable (say
@nmigrate_disks) describing the array length needs to be passed too.

>  
>      if (!(vm = qemuDomObjFromDomain(domain)))
> -        return NULL;
> +        goto cleanup;
>  
>      if (virDomainMigrateBegin3ParamsEnsureACL(domain->conn, vm->def) < 0) {
>          virDomainObjEndAPI(&vm);
> -        return NULL;
> +        goto cleanup;
>      }
>  
> -    return qemuMigrationBegin(domain->conn, vm, xmlin, dname,
> -                              cookieout, cookieoutlen, flags);
> +    ret = qemuMigrationBegin(domain->conn, vm, xmlin, dname,
> +                             cookieout, cookieoutlen, flags, migrate_disks);
> +
> + cleanup:
> +    VIR_FREE(migrate_disks);
> +    return ret;
>  }
>  
>  

> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index 8fe1cfb..708d1aa 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
> @@ -1579,12 +1579,32 @@ qemuMigrationPrecreateDisk(virConnectPtr conn,
>      return ret;
>  }
>  
> +static int

This should return bool rather than int.

> +qemuMigrateDisk(virDomainDiskDefPtr const disk, const char **migrate_disks)
> +{
> +    size_t i;
> +    /* Check if the disk alias is in the list */
> +    if (disk->info.alias && migrate_disks) {
> +        for (i = 0; migrate_disks[i]; i++) {
> +            if (STREQ(disk->info.alias, migrate_disks[i]))
> +                return 1;
> +        }
> +        return 0;
> +    }
> +
> +    /* Default is to migrate only non-shared non-readonly disks
> +     * with source */
> +    return !disk->src->shared && !disk->src->readonly &&
> +           virDomainDiskGetSource(disk);
> +}
> +
>  

> @@ -4577,6 +4614,11 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
>                                      VIR_MIGRATE_PARAM_LISTEN_ADDRESS,
>                                      listenAddress) < 0)
>              goto cleanup;
> +        if (migrate_disks &&
> +            virTypedParamsAddStringList(&params, &nparams, &maxparams,
> +                                        VIR_MIGRATE_PARAM_MIGRATE_DISKS,
> +                                        migrate_disks) < 0)
> +            goto cleanup;

Since @migrate_disks is no longer a NULL terminated array (but hey, we
have @nmigrate_disks) this must be turned into a for() loop.

>      }
>  
>      if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)

Otherwise looking good.

Michal




More information about the libvir-list mailing list