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

Martin Kletzander mkletzan at redhat.com
Tue Aug 25 05:47:12 UTC 2020


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          |   8 +++
 include/libvirt/libvirt-domain.h |  12 ++++
 src/qemu/qemu_domain.h           |   1 +
 src/qemu/qemu_driver.c           |  33 ++++++++--
 src/qemu/qemu_migration.c        | 110 ++++++++++++++++++++++---------
 src/qemu/qemu_migration.h        |   3 +
 src/qemu/qemu_migration_cookie.c |  22 +++++--
 src/qemu/qemu_migration_cookie.h |   1 +
 tools/virsh-domain.c             |  12 ++++
 9 files changed, 160 insertions(+), 42 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 9187037a5615..75f475eea6ad 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]
 
 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,13 @@ 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-socket* path can also be specified (mutually exclusive with
+*disks-port*) 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/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 8b9d9c110c19..b6c6b402b9b6 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -981,6 +981,18 @@ typedef enum {
  */
 # define VIR_MIGRATE_PARAM_DISKS_PORT    "disks_port"
 
+/**
+ * VIR_MIGRATE_PARAM_DISKS_SOCKET:
+ *
+ * virDomainMigrate* params field: path of a UNIX socket that destination server
+ * should use for incoming disks migration. Type is VIR_TYPED_PARAM_STRING. If
+ * omitted, migration will proceed over network (default). At the moment this is
+ * only supported by the QEMU driver.  This is only usable if the management
+ * application makes sure that socket created with this name on the destination
+ * will be reachable from the source under the same exact path.
+ */
+# define VIR_MIGRATE_PARAM_DISKS_SOCKET    "disks_socket"
+
 /**
  * VIR_MIGRATE_PARAM_COMPRESSION:
  *
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index adba79aded54..71a644ca6b95 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -166,6 +166,7 @@ struct _qemuDomainObjPrivate {
     unsigned long migMaxBandwidth;
     char *origname;
     int nbdPort; /* Port used for migration with NBD */
+    char *nbdSocketPath; /* Port used for migration with NBD */
     unsigned short migrationPort;
     int preMigrationState;
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3636716ceea1..74b0348ccc4c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11233,7 +11233,7 @@ qemuDomainMigratePrepare2(virConnectPtr dconn,
     ret = qemuMigrationDstPrepareDirect(driver, dconn,
                                         NULL, 0, NULL, NULL, /* No cookies */
                                         uri_in, uri_out,
-                                        &def, origname, NULL, 0, NULL, 0,
+                                        &def, origname, NULL, 0, NULL, 0, NULL,
                                         migParams, flags);
 
  cleanup:
@@ -11289,6 +11289,7 @@ qemuDomainMigratePerform(virDomainPtr dom,
      */
     ret = qemuMigrationSrcPerform(driver, dom->conn, vm, NULL,
                                   NULL, dconnuri, uri, NULL, NULL, 0, NULL, 0,
+                                  NULL,
                                   migParams, cookie, cookielen,
                                   NULL, NULL, /* No output cookies in v2 */
                                   flags, dname, resource, false);
@@ -11459,7 +11460,7 @@ qemuDomainMigratePrepare3(virConnectPtr dconn,
                                          cookieout, cookieoutlen,
                                          uri_in, uri_out,
                                          &def, origname, NULL, 0, NULL, 0,
-                                         migParams, flags);
+                                         NULL, migParams, flags);
 }
 
 static int
@@ -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;
 
     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_SOCKET,
+                                &nbdSocketPath) < 0 ||
         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) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Both port and socket requested for disk migration "
+                         "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);
 }
 
 
@@ -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;
     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_SOCKET,
+                                &nbdSocketPath) < 0 ||
         virTypedParamsGetString(params, nparams,
                                 VIR_MIGRATE_PARAM_PERSIST_XML,
                                 &persist_xml) < 0)
         goto cleanup;
 
+    if (nbdSocketPath && nbdPort) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Both port and socket requested for disk migration "
+                         "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,
                                   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..3f4690f8fb72 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -379,6 +379,7 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
                                size_t nmigrate_disks,
                                const char **migrate_disks,
                                int nbdPort,
+                               const char *nbdSocketPath,
                                const char *tls_alias)
 {
     int ret = -1;
@@ -386,7 +387,7 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
     size_t i;
     virStorageNetHostDef server = {
         .name = (char *)listenAddr, /* cast away const */
-        .transport = VIR_STORAGE_NET_HOST_TRANS_TCP,
+        .transport = VIR_STORAGE_NET_HOST_TRANS_UNIX,
         .port = nbdPort,
     };
     bool server_started = false;
@@ -397,6 +398,13 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
         return -1;
     }
 
+    /* Prefer nbdSocketPath as there is no way to indicate we do not want to
+     * listen on a port */
+    if (nbdSocketPath) {
+        server.socket = (char *)nbdSocketPath;
+        server.transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
+    }
+
     for (i = 0; i < vm->def->ndisks; i++) {
         virDomainDiskDefPtr disk = vm->def->disks[i];
         g_autofree char *diskAlias = NULL;
@@ -425,7 +433,7 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
             devicename = diskAlias;
         }
 
-        if (!server_started) {
+        if (!server_started && !nbdSocketPath) {
             if (server.port) {
                 if (virPortAllocatorSetUsed(server.port) < 0)
                     goto cleanup;
@@ -453,7 +461,10 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
-    priv->nbdPort = server.port;
+    if (nbdSocketPath)
+        priv->nbdSocketPath = g_strdup(server.socket);
+    else
+        priv->nbdPort = server.port;
 
     ret = 0;
 
@@ -793,6 +804,7 @@ static virStorageSourcePtr
 qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(virDomainDiskDefPtr disk,
                                                     const char *host,
                                                     int port,
+                                                    const char *socket,
                                                     const char *tlsAlias)
 {
     g_autoptr(virStorageSource) copysrc = NULL;
@@ -813,9 +825,14 @@ qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(virDomainDiskDefPtr disk,
     copysrc->hosts = g_new0(virStorageNetHostDef, 1);
 
     copysrc->nhosts = 1;
-    copysrc->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
-    copysrc->hosts->port = port;
-    copysrc->hosts->name = g_strdup(host);
+    if (socket) {
+        copysrc->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
+        copysrc->hosts->socket = g_strdup(socket);
+    } else {
+        copysrc->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+        copysrc->hosts->port = port;
+        copysrc->hosts->name = g_strdup(host);
+    }
 
     copysrc->tlsAlias = g_strdup(tlsAlias);
 
@@ -835,6 +852,7 @@ qemuMigrationSrcNBDStorageCopyBlockdev(virQEMUDriverPtr driver,
                                        bool persistjob,
                                        const char *host,
                                        int port,
+                                       const char *socket,
                                        unsigned long long mirror_speed,
                                        unsigned int mirror_shallow,
                                        const char *tlsAlias)
@@ -846,7 +864,7 @@ qemuMigrationSrcNBDStorageCopyBlockdev(virQEMUDriverPtr driver,
 
     VIR_DEBUG("starting blockdev mirror for disk=%s to host=%s", disk->dst, host);
 
-    if (!(copysrc = qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(disk, host, port, tlsAlias)))
+    if (!(copysrc = qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(disk, host, port, socket, tlsAlias)))
         return -1;
 
     /* Migration via blockdev-mirror was supported sooner than the auto-read-only
@@ -885,13 +903,17 @@ qemuMigrationSrcNBDStorageCopyDriveMirror(virQEMUDriverPtr driver,
                                           const char *diskAlias,
                                           const char *host,
                                           int port,
+                                          const char *socket,
                                           unsigned long long mirror_speed,
                                           bool mirror_shallow)
 {
     g_autofree char *nbd_dest = NULL;
     int mon_ret;
 
-    if (strchr(host, ':')) {
+    if (socket) {
+        nbd_dest = g_strdup_printf("nbd+unix:///%s?socket=%s",
+                                   diskAlias, socket);
+    } else if (strchr(host, ':')) {
         nbd_dest = g_strdup_printf("nbd:[%s]:%d:exportname=%s", host, port,
                                    diskAlias);
     } else {
@@ -920,6 +942,7 @@ qemuMigrationSrcNBDStorageCopyOne(virQEMUDriverPtr driver,
                                   virDomainDiskDefPtr disk,
                                   const char *host,
                                   int port,
+                                  const char *socket,
                                   unsigned long long mirror_speed,
                                   bool mirror_shallow,
                                   const char *tlsAlias,
@@ -958,13 +981,13 @@ qemuMigrationSrcNBDStorageCopyOne(virQEMUDriverPtr driver,
         rc = qemuMigrationSrcNBDStorageCopyBlockdev(driver, vm,
                                                     disk, jobname,
                                                     sourcename, persistjob,
-                                                    host, port,
+                                                    host, port, socket,
                                                     mirror_speed,
                                                     mirror_shallow,
                                                     tlsAlias);
     } else {
         rc = qemuMigrationSrcNBDStorageCopyDriveMirror(driver, vm, diskAlias,
-                                                       host, port,
+                                                       host, port, socket,
                                                        mirror_speed,
                                                        mirror_shallow);
     }
@@ -1014,6 +1037,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
                                const char **migrate_disks,
                                virConnectPtr dconn,
                                const char *tlsAlias,
+                               const char *socket,
                                unsigned int flags)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -1038,6 +1062,9 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
     port = mig->nbd->port;
     mig->nbd->port = 0;
 
+    if (qemuSecurityDomainSetPathLabel(driver, vm, socket, false) < 0)
+        return -1;
+
     for (i = 0; i < vm->def->ndisks; i++) {
         virDomainDiskDefPtr disk = vm->def->disks[i];
 
@@ -1046,6 +1073,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
             continue;
 
         if (qemuMigrationSrcNBDStorageCopyOne(driver, vm, disk, host, port,
+                                              socket,
                                               mirror_speed, mirror_shallow,
                                               tlsAlias, flags) < 0)
             return -1;
@@ -2329,6 +2357,8 @@ qemuMigrationDstPrepare(virDomainObjPtr vm,
 
     if (tunnel) {
         migrateFrom = g_strdup("stdio");
+    } else if (g_strcmp0(protocol, "unix") == 0) {
+        migrateFrom = g_strdup_printf("%s:%s", protocol, listenAddress);
     } else {
         bool encloseAddress = false;
         bool hostIPv6Capable = false;
@@ -2397,6 +2427,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
                            size_t nmigrate_disks,
                            const char **migrate_disks,
                            int nbdPort,
+                           const char *nbdSocketPath,
                            qemuMigrationParamsPtr migParams,
                            unsigned long flags)
 {
@@ -2650,7 +2681,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
 
         if (qemuMigrationDstStartNBDServer(driver, vm, incoming->address,
                                            nmigrate_disks, migrate_disks,
-                                           nbdPort, nbdTLSAlias) < 0) {
+                                           nbdPort, nbdSocketPath,
+                                           nbdTLSAlias) < 0) {
             goto stopjob;
         }
         cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
@@ -2785,7 +2817,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver,
     return qemuMigrationDstPrepareAny(driver, dconn, cookiein, cookieinlen,
                                       cookieout, cookieoutlen, def, origname,
                                       st, NULL, 0, false, NULL, 0, NULL, 0,
-                                      migParams, flags);
+                                      NULL, migParams, flags);
 }
 
 
@@ -2826,6 +2858,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver,
                               size_t nmigrate_disks,
                               const char **migrate_disks,
                               int nbdPort,
+                              const char *nbdSocketPath,
                               qemuMigrationParamsPtr migParams,
                               unsigned long flags)
 {
@@ -2840,11 +2873,13 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver,
     VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, "
               "cookieout=%p, cookieoutlen=%p, uri_in=%s, uri_out=%p, "
               "def=%p, origname=%s, listenAddress=%s, "
-              "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, flags=0x%lx",
+              "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, "
+              "nbdSocketPath=%s, flags=0x%lx",
               driver, dconn, NULLSTR(cookiein), cookieinlen,
               cookieout, cookieoutlen, NULLSTR(uri_in), uri_out,
               *def, origname, NULLSTR(listenAddress),
-              nmigrate_disks, migrate_disks, nbdPort, flags);
+              nmigrate_disks, migrate_disks, nbdPort, NULLSTR(nbdSocketPath),
+              flags);
 
     *uri_out = NULL;
 
@@ -2947,7 +2982,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver,
                                      NULL, uri ? uri->scheme : "tcp",
                                      port, autoPort, listenAddress,
                                      nmigrate_disks, migrate_disks, nbdPort,
-                                     migParams, flags);
+                                     nbdSocketPath, migParams, flags);
  cleanup:
     if (ret != 0) {
         VIR_FREE(*uri_out);
@@ -3482,7 +3517,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
                     const char *graphicsuri,
                     size_t nmigrate_disks,
                     const char **migrate_disks,
-                    qemuMigrationParamsPtr migParams)
+                    qemuMigrationParamsPtr migParams,
+                    const char *nbdSocketPath)
 {
     int ret = -1;
     unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND;
@@ -3614,7 +3650,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
                                                &migrate_flags,
                                                nmigrate_disks,
                                                migrate_disks,
-                                               dconn, tlsAlias, flags) < 0) {
+                                               dconn, tlsAlias,
+                                               nbdSocketPath, flags) < 0) {
                 goto error;
             }
         } else {
@@ -3854,7 +3891,8 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver,
                               const char *graphicsuri,
                               size_t nmigrate_disks,
                               const char **migrate_disks,
-                              qemuMigrationParamsPtr migParams)
+                              qemuMigrationParamsPtr migParams,
+                              const char *nbdSocketPath)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     g_autoptr(virURI) uribits = NULL;
@@ -3908,7 +3946,7 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver,
     ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen, cookieout,
                               cookieoutlen, flags, resource, &spec, dconn,
                               graphicsuri, nmigrate_disks, migrate_disks,
-                              migParams);
+                              migParams, nbdSocketPath);
 
     if (spec.destType == MIGRATION_DEST_FD)
         VIR_FORCE_CLOSE(spec.dest.fd.qemu);
@@ -3971,7 +4009,7 @@ qemuMigrationSrcPerformTunnel(virQEMUDriverPtr driver,
     ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen,
                               cookieout, cookieoutlen, flags, resource, &spec,
                               dconn, graphicsuri, nmigrate_disks, migrate_disks,
-                              migParams);
+                              migParams, NULL);
 
  cleanup:
     VIR_FORCE_CLOSE(spec.dest.fd.qemu);
@@ -4078,7 +4116,7 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver,
                                             cookie, cookielen,
                                             NULL, NULL, /* No out cookie with v2 migration */
                                             flags, resource, dconn, NULL, 0, NULL,
-                                            migParams);
+                                            migParams, NULL);
 
     /* Perform failed. Make sure Finish doesn't overwrite the error */
     if (ret < 0)
@@ -4142,6 +4180,7 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
                                   size_t nmigrate_disks,
                                   const char **migrate_disks,
                                   int nbdPort,
+                                  const char *nbdSocketPath,
                                   qemuMigrationParamsPtr migParams,
                                   unsigned long long bandwidth,
                                   bool useParams,
@@ -4226,6 +4265,11 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
                                  VIR_MIGRATE_PARAM_DISKS_PORT,
                                  nbdPort) < 0)
             goto cleanup;
+        if (nbdSocketPath &&
+            virTypedParamsAddString(&params, &nparams, &maxparams,
+                                    VIR_MIGRATE_PARAM_DISKS_SOCKET,
+                                    nbdSocketPath) < 0)
+            goto cleanup;
 
         if (qemuMigrationParamsDump(migParams, &params, &nparams,
                                     &maxparams, &flags) < 0)
@@ -4323,7 +4367,7 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
                                             &cookieout, &cookieoutlen,
                                             flags, bandwidth, dconn, graphicsuri,
                                             nmigrate_disks, migrate_disks,
-                                            migParams);
+                                            migParams, nbdSocketPath);
     }
 
     /* Perform failed. Make sure Finish doesn't overwrite the error */
@@ -4498,6 +4542,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
                                  size_t nmigrate_disks,
                                  const char **migrate_disks,
                                  int nbdPort,
+                                 const char *nbdSocketPath,
                                  qemuMigrationParamsPtr migParams,
                                  unsigned long flags,
                                  const char *dname,
@@ -4618,7 +4663,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
         ret = qemuMigrationSrcPerformPeer2Peer3(driver, sconn, dconn, dconnuri, vm, xmlin,
                                                 persist_xml, dname, uri, graphicsuri,
                                                 listenAddress, nmigrate_disks, migrate_disks,
-                                                nbdPort, migParams, resource,
+                                                nbdPort, nbdSocketPath, migParams, resource,
                                                 useParams, flags);
     } else {
         ret = qemuMigrationSrcPerformPeer2Peer2(driver, sconn, dconn, vm,
@@ -4654,6 +4699,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver,
                            size_t nmigrate_disks,
                            const char **migrate_disks,
                            int nbdPort,
+                           const char *nbdSocketPath,
                            qemuMigrationParamsPtr migParams,
                            const char *cookiein,
                            int cookieinlen,
@@ -4692,6 +4738,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver,
         ret = qemuMigrationSrcPerformPeer2Peer(driver, conn, vm, xmlin, persist_xml,
                                                dconnuri, uri, graphicsuri, listenAddress,
                                                nmigrate_disks, migrate_disks, nbdPort,
+                                               nbdSocketPath,
                                                migParams, flags, dname, resource,
                                                &v3proto);
     } else {
@@ -4699,7 +4746,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver,
         ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen,
                                             cookieout, cookieoutlen,
                                             flags, resource, NULL, NULL, 0, NULL,
-                                            migParams);
+                                            migParams, nbdSocketPath);
     }
     if (ret < 0)
         goto endjob;
@@ -4765,7 +4812,8 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver,
                              char **cookieout,
                              int *cookieoutlen,
                              unsigned long flags,
-                             unsigned long resource)
+                             unsigned long resource,
+                             const char *nbdSocketPath)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
@@ -4787,7 +4835,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver,
     ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen,
                                         cookieout, cookieoutlen,
                                         flags, resource, NULL, graphicsuri,
-                                        nmigrate_disks, migrate_disks, migParams);
+                                        nmigrate_disks, migrate_disks, migParams, nbdSocketPath);
 
     if (ret < 0) {
         qemuMigrationSrcRestoreDomainState(driver, vm);
@@ -4828,6 +4876,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
                         size_t nmigrate_disks,
                         const char **migrate_disks,
                         int nbdPort,
+                        const char *nbdSocketPath,
                         qemuMigrationParamsPtr migParams,
                         const char *cookiein,
                         int cookieinlen,
@@ -4841,11 +4890,12 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
     VIR_DEBUG("driver=%p, conn=%p, vm=%p, xmlin=%s, dconnuri=%s, "
               "uri=%s, graphicsuri=%s, listenAddress=%s, "
               "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, "
+              "nbdSocketPath=%s, "
               "cookiein=%s, cookieinlen=%d, cookieout=%p, cookieoutlen=%p, "
               "flags=0x%lx, dname=%s, resource=%lu, v3proto=%d",
               driver, conn, vm, NULLSTR(xmlin), NULLSTR(dconnuri),
               NULLSTR(uri), NULLSTR(graphicsuri), NULLSTR(listenAddress),
-              nmigrate_disks, migrate_disks, nbdPort,
+              nmigrate_disks, migrate_disks, nbdPort, NULLSTR(nbdSocketPath),
               NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen,
               flags, NULLSTR(dname), resource, v3proto);
 
@@ -4859,7 +4909,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
         return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist_xml, dconnuri, uri,
                                           graphicsuri, listenAddress,
                                           nmigrate_disks, migrate_disks, nbdPort,
-                                          migParams,
+                                          nbdSocketPath, migParams,
                                           cookiein, cookieinlen,
                                           cookieout, cookieoutlen,
                                           flags, dname, resource, v3proto);
@@ -4877,12 +4927,12 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
                                                 migParams,
                                                 cookiein, cookieinlen,
                                                 cookieout, cookieoutlen,
-                                                flags, resource);
+                                                flags, resource, nbdSocketPath);
         } else {
             return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist_xml, NULL,
                                               uri, graphicsuri, listenAddress,
                                               nmigrate_disks, migrate_disks, nbdPort,
-                                              migParams,
+                                              nbdSocketPath, migParams,
                                               cookiein, cookieinlen,
                                               cookieout, cookieoutlen, flags,
                                               dname, resource, v3proto);
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index b6f88d3fd9ea..f195bda3e367 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -84,6 +84,7 @@
     VIR_MIGRATE_PARAM_BANDWIDTH_POSTCOPY, VIR_TYPED_PARAM_ULLONG, \
     VIR_MIGRATE_PARAM_PARALLEL_CONNECTIONS, VIR_TYPED_PARAM_INT, \
     VIR_MIGRATE_PARAM_TLS_DESTINATION, VIR_TYPED_PARAM_STRING, \
+    VIR_MIGRATE_PARAM_DISKS_SOCKET,     VIR_TYPED_PARAM_STRING, \
     NULL
 
 
@@ -149,6 +150,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver,
                               size_t nmigrate_disks,
                               const char **migrate_disks,
                               int nbdPort,
+                              const char *nbdSocketPath,
                               qemuMigrationParamsPtr migParams,
                               unsigned long flags);
 
@@ -165,6 +167,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
                         size_t nmigrate_disks,
                         const char **migrate_disks,
                         int nbdPort,
+                        const char *nbdSocketPath,
                         qemuMigrationParamsPtr migParams,
                         const char *cookiein,
                         int cookieinlen,
diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
index 81b557e0a8b4..23511bed67d5 100644
--- a/src/qemu/qemu_migration_cookie.c
+++ b/src/qemu/qemu_migration_cookie.c
@@ -91,6 +91,8 @@ qemuMigrationCookieNBDFree(qemuMigrationCookieNBDPtr nbd)
     while (nbd->ndisks)
         VIR_FREE(nbd->disks[--nbd->ndisks].target);
     VIR_FREE(nbd->disks);
+
+    VIR_FREE(nbd->socketPath);
     VIR_FREE(nbd);
 }
 
@@ -464,7 +466,10 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
 
     mig->nbd = g_new0(qemuMigrationCookieNBD, 1);
 
-    mig->nbd->port = priv->nbdPort;
+    if (priv->nbdSocketPath)
+        mig->nbd->socketPath = priv->nbdSocketPath;
+    else
+        mig->nbd->port = priv->nbdPort;
     mig->flags |= QEMU_MIGRATION_COOKIE_NBD;
 
     if (vm->def->ndisks == 0)
@@ -988,12 +993,15 @@ qemuMigrationCookieNBDXMLParse(xmlXPathContextPtr ctxt)
     if (VIR_ALLOC(ret) < 0)
         goto error;
 
-    port = virXPathString("string(./nbd/@port)", ctxt);
-    if (port && virStrToLong_i(port, NULL, 10, &ret->port) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Malformed nbd port '%s'"),
-                       port);
-        goto error;
+    ret->socketPath = virXPathString("string(./nbd/@socketPath)", ctxt);
+    if (!ret->socketPath) {
+        port = virXPathString("string(./nbd/@port)", ctxt);
+        if (port && virStrToLong_i(port, NULL, 10, &ret->port) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Malformed nbd port '%s'"),
+                           port);
+            goto error;
+        }
     }
 
     /* Now check if source sent a list of disks to prealloc. We might be
diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_cookie.h
index 95e7edb89914..90a320a69c0c 100644
--- a/src/qemu/qemu_migration_cookie.h
+++ b/src/qemu/qemu_migration_cookie.h
@@ -93,6 +93,7 @@ typedef struct _qemuMigrationCookieNBD qemuMigrationCookieNBD;
 typedef qemuMigrationCookieNBD *qemuMigrationCookieNBDPtr;
 struct _qemuMigrationCookieNBD {
     int port; /* on which port does NBD server listen for incoming data */
+    char *socketPath;
 
     size_t ndisks;  /* Number of items in @disk array */
     struct qemuMigrationCookieNBDDisk *disks;
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index c606900a9268..20b8ab9837fd 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -10639,6 +10639,10 @@ static const vshCmdOptDef opts_migrate[] = {
      .type = VSH_OT_INT,
      .help = N_("port to use by target server for incoming disks migration")
     },
+    {.name = "disks-socket",
+     .type = VSH_OT_STRING,
+     .help = N_("UNIX socket path to use for disks migration")
+    },
     {.name = "comp-methods",
      .type = VSH_OT_STRING,
      .help = N_("comma separated list of compression methods to be used")
@@ -10758,6 +10762,14 @@ doMigrate(void *opaque)
                              VIR_MIGRATE_PARAM_DISKS_PORT, intOpt) < 0)
         goto save_error;
 
+    if (vshCommandOptStringReq(ctl, cmd, "disks-socket", &opt) < 0)
+        goto out;
+    if (opt &&
+        virTypedParamsAddString(&params, &nparams, &maxparams,
+                                VIR_MIGRATE_PARAM_DISKS_SOCKET,
+                                opt) < 0)
+        goto save_error;
+
     if (vshCommandOptStringReq(ctl, cmd, "dname", &opt) < 0)
         goto out;
     if (opt &&
-- 
2.28.0




More information about the libvir-list mailing list