[PATCH v2 6/9] qemu: Allow NBD migration over UNIX socket

Jiri Denemark jdenemar at redhat.com
Tue Sep 1 18:32:29 UTC 2020


On Tue, Sep 01, 2020 at 16:36:57 +0200, Martin Kletzander wrote:
> Adds new typed param for migration and uses this as a UNIX socket path that
> should be used for the NBD part of migration.  And also adds virsh support.
> 
> Partially resolves: https://bugzilla.redhat.com/1638889
> 
> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
> ---
>  docs/manpages/virsh.rst          |  11 ++
>  include/libvirt/libvirt-domain.h |  13 +++
>  src/qemu/qemu_driver.c           |  33 +++++-
>  src/qemu/qemu_migration.c        | 170 ++++++++++++++++++++++++-------
>  src/qemu/qemu_migration.h        |   3 +
>  src/qemu/qemu_migration_cookie.c |   3 +-
>  tools/virsh-domain.c             |  12 +++
>  7 files changed, 205 insertions(+), 40 deletions(-)
> 
> diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
> index 8e2fb7039046..12357ea4ee86 100644
> --- a/docs/manpages/virsh.rst
> +++ b/docs/manpages/virsh.rst
> @@ -3113,6 +3113,7 @@ migrate
>        [--postcopy-bandwidth bandwidth]
>        [--parallel [--parallel-connections connections]]
>        [--bandwidth bandwidth] [--tls-destination hostname]
> +      [--disks-socket socket-path]

--disks-uri URI

>  
>  Migrate domain to another host.  Add *--live* for live migration; <--p2p>
>  for peer-2-peer migration; *--direct* for direct migration; or *--tunnelled*
> @@ -3292,6 +3293,16 @@ error if this parameter is used.
>  Optional *disks-port* sets the port that hypervisor on destination side should
>  bind to for incoming disks traffic. Currently it is supported only by QEMU.
>  
> +Optional *disks-uri* can also be specified (mutually exclusive with
> +*disks-port*) to specify what the remote hypervisor should bind/connect to when
> +migrating disks.  This can be *tcp://address:port* to specify a listen address
> +(which overrides *--listen-address* for the disk migration) and a port or
> +*unix:///path/to/socket* in case you need the disk migration to happen over a
> +UNIX socket with that specified path.  In this case you need to make sure the
> +same socket path is accessible to both source and destination hypervisors and
> +connecting to the socket on the source (after hypervisor creates it on the
> +destination) will actually connect to the destination.
> +
>  
>  migrate-compcache
>  -----------------
...
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 3636716ceea1..08b6b853de47 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
...
> @@ -11485,6 +11486,7 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn,
>      g_autofree const char **migrate_disks = NULL;
>      g_autofree char *origname = NULL;
>      g_autoptr(qemuMigrationParams) migParams = NULL;
> +    const char *nbdSocketPath = NULL;

nbdURI

>  
>      virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
>      if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
> @@ -11502,6 +11504,9 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn,
>          virTypedParamsGetString(params, nparams,
>                                  VIR_MIGRATE_PARAM_LISTEN_ADDRESS,
>                                  &listenAddress) < 0 ||
> +        virTypedParamsGetString(params, nparams,
> +                                VIR_MIGRATE_PARAM_DISKS_URI,
> +                                &nbdSocketPath) < 0 ||

nbdURI

>          virTypedParamsGetInt(params, nparams,
>                               VIR_MIGRATE_PARAM_DISKS_PORT,
>                               &nbdPort) < 0)
> @@ -11518,6 +11523,13 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn,
>                                                     QEMU_MIGRATION_DESTINATION)))
>          return -1;
>  
> +    if (nbdSocketPath && nbdPort) {

nbdURI

> +        virReportError(VIR_ERR_INVALID_ARG, "%s",
> +                       _("Both port and socket requested for disk migration "

s/socket/URI/

> +                         "while being mutually exclusive"));
> +        return -1;
> +    }
> +
>      if (flags & VIR_MIGRATE_TUNNELLED) {
>          /* this is a logical error; we never should have gotten here with
>           * VIR_MIGRATE_TUNNELLED set
> @@ -11540,7 +11552,7 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn,
>                                           uri_in, uri_out,
>                                           &def, origname, listenAddress,
>                                           nmigrate_disks, migrate_disks, nbdPort,
> -                                         migParams, flags);
> +                                         nbdSocketPath, migParams, flags);

nbdURI

>  }
>  
>  
> @@ -11682,7 +11694,7 @@ qemuDomainMigratePerform3(virDomainPtr dom,
>  
>      ret = qemuMigrationSrcPerform(driver, dom->conn, vm, xmlin, NULL,
>                                    dconnuri, uri, NULL, NULL, 0, NULL, 0,
> -                                  migParams,
> +                                  NULL, migParams,
>                                    cookiein, cookieinlen,
>                                    cookieout, cookieoutlen,
>                                    flags, dname, resource, true);
> @@ -11716,6 +11728,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
>      unsigned long long bandwidth = 0;
>      int nbdPort = 0;
>      g_autoptr(qemuMigrationParams) migParams = NULL;
> +    const char *nbdSocketPath = NULL;

nbdURI

>      int ret = -1;
>  
>      virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
> @@ -11743,11 +11756,21 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
>          virTypedParamsGetInt(params, nparams,
>                               VIR_MIGRATE_PARAM_DISKS_PORT,
>                               &nbdPort) < 0 ||
> +        virTypedParamsGetString(params, nparams,
> +                                VIR_MIGRATE_PARAM_DISKS_URI,
> +                                &nbdSocketPath) < 0 ||

nbdURI

>          virTypedParamsGetString(params, nparams,
>                                  VIR_MIGRATE_PARAM_PERSIST_XML,
>                                  &persist_xml) < 0)
>          goto cleanup;
>  
> +    if (nbdSocketPath && nbdPort) {

nbdURI

> +        virReportError(VIR_ERR_INVALID_ARG, "%s",
> +                       _("Both port and socket requested for disk migration "

s/socket/URI/

> +                         "while being mutually exclusive"));
> +        goto cleanup;
> +    }
> +
>      nmigrate_disks = virTypedParamsGetStringList(params, nparams,
>                                                   VIR_MIGRATE_PARAM_MIGRATE_DISKS,
>                                                   &migrate_disks);
> @@ -11768,7 +11791,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
>      ret = qemuMigrationSrcPerform(driver, dom->conn, vm, dom_xml, persist_xml,
>                                    dconnuri, uri, graphicsuri, listenAddress,
>                                    nmigrate_disks, migrate_disks, nbdPort,
> -                                  migParams,
> +                                  nbdSocketPath, migParams,

nbdURI

>                                    cookiein, cookieinlen, cookieout, cookieoutlen,
>                                    flags, dname, bandwidth, true);
>   cleanup:
> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index b887185d012d..7277f2f458a2 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
...
> @@ -390,8 +391,44 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
>          .port = nbdPort,
>      };
>      bool server_started = false;
> +    g_autoptr(virURI) uri = NULL;
> +
> +    /* Prefer nbdURI */
> +    if (nbdURI) {
> +        uri = virURIParse(nbdURI);
>  
> -    if (nbdPort < 0 || nbdPort > USHRT_MAX) {
> +        if (!uri)
> +            return -1;
> +
> +        if (STREQ(uri->scheme, "tcp")) {
> +            server.transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
> +            if (!uri->server || STREQ(uri->server, "")) {
> +                /* Since tcp://:<port>/ is parsed as server = NULL and port = 0
> +                 * we should rather error out instead of auto-allocating a port
> +                 * as that would be the exact opposite of what was requested. */
> +                virReportError(VIR_ERR_INVALID_ARG,
> +                               _("URI with tcp scheme did not provide a server part: %s"),
> +                               nbdURI);
> +                return -1;
> +            }
> +                server.name = (char *)uri->server;

Indentation is a bit off here.

> +            if (uri->port)
> +                server.port = uri->port;
> +        } else if (STREQ(uri->scheme, "unix")) {
> +            if (!uri->path) {
> +                virReportError(VIR_ERR_INVALID_ARG, "%s",
> +                               _("UNIX disks URI does not include path"));
> +                return -1;
> +            }
> +            server.transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
> +            server.socket = (char *)uri->path;
> +        } else {
> +            virReportError(VIR_ERR_INVALID_ARG,
> +                           _("Unsupported scheme in disks URI: %s"),
> +                           uri->scheme);
> +            return -1;
> +        }
> +    } else if (nbdPort < 0 || nbdPort > USHRT_MAX) {
>          virReportError(VIR_ERR_INVALID_ARG, "%s",
>                         _("nbd port must be in range 0-65535"));
>          return -1;
...
> diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
> index cef255598854..c1295b32fc27 100644
> --- a/src/qemu/qemu_migration_cookie.c
> +++ b/src/qemu/qemu_migration_cookie.c
> @@ -91,6 +91,7 @@ qemuMigrationCookieNBDFree(qemuMigrationCookieNBDPtr nbd)
>      while (nbd->ndisks)
>          VIR_FREE(nbd->disks[--nbd->ndisks].target);
>      VIR_FREE(nbd->disks);
> +
>      VIR_FREE(nbd);
>  }
>  
> @@ -992,7 +993,7 @@ qemuMigrationCookieNBDXMLParse(xmlXPathContextPtr ctxt)
>      if (port && virStrToLong_i(port, NULL, 10, &ret->port) < 0) {
>          virReportError(VIR_ERR_INTERNAL_ERROR,
>                         _("Malformed nbd port '%s'"),
> -                       port);
> +                           port);
>          goto error;
>      }
>  

I don't think you wanted to touch qemu_migration_cookie.c at all. You
can just drop both hunks.

...

With the small fixups

Reviewed-by: Jiri Denemark <jdenemar at redhat.com>




More information about the libvir-list mailing list