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@xxxxxxxxxx> > --- > 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@xxxxxxxxxx>