[libvirt PATCH 8/9] qemu: Allow migration over UNIX socket

Jiri Denemark jdenemar at redhat.com
Tue Aug 25 15:53:32 UTC 2020


On Tue, Aug 25, 2020 at 07:47:14 +0200, Martin Kletzander wrote:
> This allows:
> 
>  a) migration without access to network
> 
>  b) complete control of the migration stream
> 
>  c) easy migration between containerised libvirt daemons on the same host
> 
> Resolves: https://bugzilla.redhat.com/1638889
> 
> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
> ---
>  docs/manpages/virsh.rst   |  17 ++++-
>  docs/migration.html.in    |  33 ++++++++++
>  src/qemu/qemu_migration.c | 128 +++++++++++++++++++++++++++-----------
>  3 files changed, 139 insertions(+), 39 deletions(-)
> 
> diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
> index cbb3c18deb30..82f7c9f77488 100644
> --- a/docs/manpages/virsh.rst
> +++ b/docs/manpages/virsh.rst
> @@ -3237,12 +3237,12 @@ has different semantics:
>  
>  In a special circumstance where you require a complete control of the connection
>  and/or libvirt does not have network access to the remote side you can use a
> -unix transport in the URI and specify a socket path in the query, for example
> +UNIX transport in the URI and specify a socket path in the query, for example
>  with the qemu driver you could use this:
>  
>  .. code-block::
>  
> -      qemu+unix://?socket=/path/to/socket
> +      qemu+unix:///system?socket=/path/to/socket
>  
>  When *migrateuri* is not specified, libvirt will automatically determine the
>  hypervisor specific URI.  Some hypervisors, including QEMU, have an optional

This hunk looks like it should go into the previous patch 7/9 (peer2peer
migration: allow connecting to local sockets).

> @@ -3270,6 +3270,14 @@ There are a few scenarios where specifying *migrateuri* may help:
>    might be specified to choose a specific port number outside the default range in
>    order to comply with local firewall policies.
>  
> +* The *desturi* uses UNIX transport method.  In this advanced case libvirt
> +  should not guess a *migrateuri* and it should be specified using
> +  UNIX socket path URI:
> +
> +.. code-block::
> +
> +      unix://?socket=/path/to/socket
> +
>  See `https://libvirt.org/migration.html#uris <https://libvirt.org/migration.html#uris>`_ for more details on
>  migration URIs.
>  
> @@ -3296,7 +3304,10 @@ specific parameters separated by '&'. Currently recognized parameters are
>  Optional *listen-address* sets the listen address that hypervisor on the
>  destination side should bind to for incoming migration. Both IPv4 and IPv6
>  addresses are accepted as well as hostnames (the resolving is done on
> -destination). Some hypervisors do not support this feature and will return an
> +destination).  In niche scenarios you can also use UNIX socket to make the
> +hypervisor connection over UNIX socket in which case you must make sure the
> +source can connect to the destination using the socket path provided by you.
> +Some hypervisors do not support specifying the listen address and will return an
>  error if this parameter is used.
>  
>  Optional *disks-port* sets the port that hypervisor on destination side should
> diff --git a/docs/migration.html.in b/docs/migration.html.in
> index e95ee9de6f1b..9c8417674b22 100644
> --- a/docs/migration.html.in
> +++ b/docs/migration.html.in
> @@ -201,6 +201,9 @@
>          numbers. In the latter case the management application may wish
>          to choose a specific port number outside the default range in order
>          to comply with local firewall policies.</li>
> +      <li>The second URI uses UNIX transport method.  In this advanced case
> +        libvirt should not guess a *migrateuri* and it should be specified using
> +        UNIX socket path URI: <code>unix://?socket=/path/to/socket</code>.</li>
>      </ol>
>  
>      <h2><a id="config">Configuration file handling</a></h2>
> @@ -628,5 +631,35 @@ virsh migrate --p2p --tunnelled web1 qemu+ssh://desthost/system qemu+ssh://10.0.
>        Supported by QEMU driver
>      </p>
>  
> +
> +    <h3><a id="scenariounixsocket">Migration using only UNIX sockets</a></h3>
> +
> +    <p>
> +      In a niche scenarion where libvirt daemon does not have access to the

s/scenarion/scenario/

or

s/a // and s/scenarion/scenarios/

> +      network (e.g. running in a restricted container on a host that has
> +      accessible network), when a management application wants to have complete
> +      control over the transfer or when migrating between two containers on the
> +      same host all the communication can be done using UNIX sockets.  This
> +      includes connecting to non-standard socket path for the destination
> +      daemon, using UNIX sockets for hypervisor's communication or for the NBD
> +      data transfer.  All of that can be used with both peer2peer and direct
> +      migration options.
> +    </p>
> +
> +    <p>
> +      Example using <code>/tmp/migdir</code> as a directory representing the
> +      same path visible from both libvirt daemons.  That can be achieved by
> +      bind-mounting the same directory to different containers running separate
> +      daemons or forwarding connections to these sockets manually
> +      (using <code>socat</code>, <code>netcat</code> or a custom piece of
> +      software):
> +    <pre>
> +virsh migrate web1 [--p2p] --copy-storage-all 'qemu+unix:///system?socket=/tmp/migdir/test-sock-driver' 'unix://?socket=/tmp/migdir/test-sock-qemu' [--listen-address /tmp/migdir/test-sock-qemu] --disks-socket /tmp/migdir/test-sock-nbd
> +    </pre>
> +
> +    <p>
> +      Supported by QEMU driver
> +    </p>
> +
>    </body>
>  </html>
> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index 3f4690f8fb72..1158d152869c 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
...
> @@ -3931,16 +3969,34 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver,
>          }
>      }
>  
> -    /* RDMA and multi-fd migration requires QEMU to connect to the destination
> -     * itself.
> -     */
> -    if (STREQ(uribits->scheme, "rdma") || (flags & VIR_MIGRATE_PARALLEL))
> -        spec.destType = MIGRATION_DEST_HOST;
> -    else
> -        spec.destType = MIGRATION_DEST_CONNECT_HOST;
> -    spec.dest.host.protocol = uribits->scheme;
> -    spec.dest.host.name = uribits->server;
> -    spec.dest.host.port = uribits->port;
> +    if (STREQ(uribits->scheme, "unix")) {
> +        if (flags & VIR_MIGRATE_TLS) {
> +            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
> +                           _("Migration over UNIX socket with TLS is not supported"));
> +            return -1;
> +        }
> +        if (flags & VIR_MIGRATE_PARALLEL) {
> +            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
> +                           _("Parallel migration over UNIX socket is not supported"));
> +            return -1;
> +        }

Is there a reason for not supporting TLS and multi-fd with unix sockets?
>From libvirt's POV this should be fairly trivial (can be a follow-up
patch, though): introduce MIGRATION_DEST_SOCKET in addition to
MIGRATION_DEST_CONNECT_SOCKET and use it to instruct QEMU to connect
using unix: URI (unless this support was removed from QEMU).

> +
> +        spec.destType = MIGRATION_DEST_CONNECT_SOCKET;
> +        spec.dest.socket.path = virURIGetParam(uribits, "socket");
> +    } else {
> +        /* RDMA and multi-fd migration requires QEMU to connect to the destination
> +         * itself.
> +         */
> +        if (STREQ(uribits->scheme, "rdma") || (flags & VIR_MIGRATE_PARALLEL))
> +            spec.destType = MIGRATION_DEST_HOST;
> +        else
> +            spec.destType = MIGRATION_DEST_CONNECT_HOST;
> +
> +        spec.dest.host.protocol = uribits->scheme;
> +        spec.dest.host.name = uribits->server;
> +        spec.dest.host.port = uribits->port;
> +    }
> +
>      spec.fwdType = MIGRATION_FWD_DIRECT;
>  
>      ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen, cookieout,

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




More information about the libvir-list mailing list