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

Martin Kletzander mkletzan at redhat.com
Tue Sep 1 14:36:57 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          |  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]
 
 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/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 8b9d9c110c19..77f9116675af 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -981,6 +981,19 @@ typedef enum {
  */
 # define VIR_MIGRATE_PARAM_DISKS_PORT    "disks_port"
 
+/**
+ * VIR_MIGRATE_PARAM_DISKS_URI:
+ *
+ * virDomainMigrate* params field: URI used for incoming disks migration. Type
+ * is VIR_TYPED_PARAM_STRING. Only schemes "tcp" and "unix" are accepted. TCP
+ * URI can currently only provide a server and port to listen on (and connect
+ * to), UNIX URI may only provide a path component for a UNIX socket. This is
+ * currently only supported by the QEMU driver.  UNIX URI 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_URI    "disks_uri"
+
 /**
  * VIR_MIGRATE_PARAM_COMPRESSION:
  *
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
@@ -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_URI,
+                                &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_URI,
+                                &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..7277f2f458a2 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 *nbdURI,
                                const char *tls_alias)
 {
     int ret = -1;
@@ -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;
+            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;
@@ -425,7 +462,8 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
             devicename = diskAlias;
         }
 
-        if (!server_started) {
+        if (!server_started &&
+            server.transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
             if (server.port) {
                 if (virPortAllocatorSetUsed(server.port) < 0)
                     goto cleanup;
@@ -453,7 +491,8 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
-    priv->nbdPort = server.port;
+    if (server.transport == VIR_STORAGE_NET_HOST_TRANS_TCP)
+        priv->nbdPort = server.port;
 
     ret = 0;
 
@@ -793,6 +832,7 @@ static virStorageSourcePtr
 qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(virDomainDiskDefPtr disk,
                                                     const char *host,
                                                     int port,
+                                                    const char *socket,
                                                     const char *tlsAlias)
 {
     g_autoptr(virStorageSource) copysrc = NULL;
@@ -813,9 +853,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 +880,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 +892,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 +931,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 +970,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 +1009,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 +1065,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
                                const char **migrate_disks,
                                virConnectPtr dconn,
                                const char *tlsAlias,
+                               const char *nbdURI,
                                unsigned int flags)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -1023,6 +1075,8 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
     bool mirror_shallow = *migrate_flags & QEMU_MONITOR_MIGRATE_NON_SHARED_INC;
     int rv;
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+    g_autoptr(virURI) uri = NULL;
+    const char *socket = NULL;
 
     VIR_DEBUG("Starting drive mirrors for domain %s", vm->def->name);
 
@@ -1038,6 +1092,33 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
     port = mig->nbd->port;
     mig->nbd->port = 0;
 
+    if (nbdURI) {
+        uri = virURIParse(nbdURI);
+        if (!uri)
+            return -1;
+
+        if (STREQ(uri->scheme, "tcp")) {
+            if (uri->server && STRNEQ(uri->server, ""))
+                host = (char *)uri->server;
+            if (uri->port)
+                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;
+            }
+            socket = uri->path;
+
+            if (qemuSecurityDomainSetPathLabel(driver, vm, socket, false) < 0)
+                return -1;
+        } else {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("Unsupported scheme in disks URI: %s"),
+                           uri->scheme);
+        }
+    }
+
     for (i = 0; i < vm->def->ndisks; i++) {
         virDomainDiskDefPtr disk = vm->def->disks[i];
 
@@ -1046,6 +1127,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
             continue;
 
         if (qemuMigrationSrcNBDStorageCopyOne(driver, vm, disk, host, port,
+                                              socket,
                                               mirror_speed, mirror_shallow,
                                               tlsAlias, flags) < 0)
             return -1;
@@ -2397,6 +2479,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
                            size_t nmigrate_disks,
                            const char **migrate_disks,
                            int nbdPort,
+                           const char *nbdURI,
                            qemuMigrationParamsPtr migParams,
                            unsigned long flags)
 {
@@ -2650,7 +2733,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
 
         if (qemuMigrationDstStartNBDServer(driver, vm, incoming->address,
                                            nmigrate_disks, migrate_disks,
-                                           nbdPort, nbdTLSAlias) < 0) {
+                                           nbdPort, nbdURI,
+                                           nbdTLSAlias) < 0) {
             goto stopjob;
         }
         cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
@@ -2785,7 +2869,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 +2910,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver,
                               size_t nmigrate_disks,
                               const char **migrate_disks,
                               int nbdPort,
+                              const char *nbdURI,
                               qemuMigrationParamsPtr migParams,
                               unsigned long flags)
 {
@@ -2840,11 +2925,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, "
+              "nbdURI=%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(nbdURI),
+              flags);
 
     *uri_out = NULL;
 
@@ -2947,7 +3034,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver,
                                      NULL, uri ? uri->scheme : "tcp",
                                      port, autoPort, listenAddress,
                                      nmigrate_disks, migrate_disks, nbdPort,
-                                     migParams, flags);
+                                     nbdURI, migParams, flags);
  cleanup:
     if (ret != 0) {
         VIR_FREE(*uri_out);
@@ -3482,7 +3569,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
                     const char *graphicsuri,
                     size_t nmigrate_disks,
                     const char **migrate_disks,
-                    qemuMigrationParamsPtr migParams)
+                    qemuMigrationParamsPtr migParams,
+                    const char *nbdURI)
 {
     int ret = -1;
     unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND;
@@ -3614,7 +3702,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
                                                &migrate_flags,
                                                nmigrate_disks,
                                                migrate_disks,
-                                               dconn, tlsAlias, flags) < 0) {
+                                               dconn, tlsAlias,
+                                               nbdURI, flags) < 0) {
                 goto error;
             }
         } else {
@@ -3854,7 +3943,8 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver,
                               const char *graphicsuri,
                               size_t nmigrate_disks,
                               const char **migrate_disks,
-                              qemuMigrationParamsPtr migParams)
+                              qemuMigrationParamsPtr migParams,
+                              const char *nbdURI)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     g_autoptr(virURI) uribits = NULL;
@@ -3908,7 +3998,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, nbdURI);
 
     if (spec.destType == MIGRATION_DEST_FD)
         VIR_FORCE_CLOSE(spec.dest.fd.qemu);
@@ -3971,7 +4061,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 +4168,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 +4232,7 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
                                   size_t nmigrate_disks,
                                   const char **migrate_disks,
                                   int nbdPort,
+                                  const char *nbdURI,
                                   qemuMigrationParamsPtr migParams,
                                   unsigned long long bandwidth,
                                   bool useParams,
@@ -4226,6 +4317,11 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
                                  VIR_MIGRATE_PARAM_DISKS_PORT,
                                  nbdPort) < 0)
             goto cleanup;
+        if (nbdURI &&
+            virTypedParamsAddString(&params, &nparams, &maxparams,
+                                    VIR_MIGRATE_PARAM_DISKS_URI,
+                                    nbdURI) < 0)
+            goto cleanup;
 
         if (qemuMigrationParamsDump(migParams, &params, &nparams,
                                     &maxparams, &flags) < 0)
@@ -4323,7 +4419,7 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
                                             &cookieout, &cookieoutlen,
                                             flags, bandwidth, dconn, graphicsuri,
                                             nmigrate_disks, migrate_disks,
-                                            migParams);
+                                            migParams, nbdURI);
     }
 
     /* Perform failed. Make sure Finish doesn't overwrite the error */
@@ -4498,6 +4594,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
                                  size_t nmigrate_disks,
                                  const char **migrate_disks,
                                  int nbdPort,
+                                 const char *nbdURI,
                                  qemuMigrationParamsPtr migParams,
                                  unsigned long flags,
                                  const char *dname,
@@ -4515,12 +4612,12 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
 
     VIR_DEBUG("driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, uri=%s, "
               "graphicsuri=%s, listenAddress=%s, nmigrate_disks=%zu, "
-              "migrate_disks=%p, nbdPort=%d, flags=0x%lx, dname=%s, "
-              "resource=%lu",
+              "migrate_disks=%p, nbdPort=%d, nbdURI=%s, flags=0x%lx, "
+              "dname=%s, resource=%lu",
               driver, sconn, vm, NULLSTR(xmlin), NULLSTR(dconnuri),
               NULLSTR(uri), NULLSTR(graphicsuri), NULLSTR(listenAddress),
-              nmigrate_disks, migrate_disks, nbdPort, flags, NULLSTR(dname),
-              resource);
+              nmigrate_disks, migrate_disks, nbdPort, NULLSTR(nbdURI),
+              flags, NULLSTR(dname), resource);
 
     if (flags & VIR_MIGRATE_TUNNELLED && uri) {
         virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
@@ -4618,7 +4715,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, nbdURI, migParams, resource,
                                                 useParams, flags);
     } else {
         ret = qemuMigrationSrcPerformPeer2Peer2(driver, sconn, dconn, vm,
@@ -4654,6 +4751,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver,
                            size_t nmigrate_disks,
                            const char **migrate_disks,
                            int nbdPort,
+                           const char *nbdURI,
                            qemuMigrationParamsPtr migParams,
                            const char *cookiein,
                            int cookieinlen,
@@ -4692,6 +4790,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver,
         ret = qemuMigrationSrcPerformPeer2Peer(driver, conn, vm, xmlin, persist_xml,
                                                dconnuri, uri, graphicsuri, listenAddress,
                                                nmigrate_disks, migrate_disks, nbdPort,
+                                               nbdURI,
                                                migParams, flags, dname, resource,
                                                &v3proto);
     } else {
@@ -4699,7 +4798,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver,
         ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen,
                                             cookieout, cookieoutlen,
                                             flags, resource, NULL, NULL, 0, NULL,
-                                            migParams);
+                                            migParams, nbdURI);
     }
     if (ret < 0)
         goto endjob;
@@ -4765,7 +4864,8 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver,
                              char **cookieout,
                              int *cookieoutlen,
                              unsigned long flags,
-                             unsigned long resource)
+                             unsigned long resource,
+                             const char *nbdURI)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
@@ -4787,7 +4887,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, nbdURI);
 
     if (ret < 0) {
         qemuMigrationSrcRestoreDomainState(driver, vm);
@@ -4828,6 +4928,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
                         size_t nmigrate_disks,
                         const char **migrate_disks,
                         int nbdPort,
+                        const char *nbdURI,
                         qemuMigrationParamsPtr migParams,
                         const char *cookiein,
                         int cookieinlen,
@@ -4841,11 +4942,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, "
+              "nbdURI=%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(nbdURI),
               NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen,
               flags, NULLSTR(dname), resource, v3proto);
 
@@ -4859,7 +4961,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
         return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist_xml, dconnuri, uri,
                                           graphicsuri, listenAddress,
                                           nmigrate_disks, migrate_disks, nbdPort,
-                                          migParams,
+                                          nbdURI, migParams,
                                           cookiein, cookieinlen,
                                           cookieout, cookieoutlen,
                                           flags, dname, resource, v3proto);
@@ -4877,12 +4979,12 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
                                                 migParams,
                                                 cookiein, cookieinlen,
                                                 cookieout, cookieoutlen,
-                                                flags, resource);
+                                                flags, resource, nbdURI);
         } else {
             return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist_xml, NULL,
                                               uri, graphicsuri, listenAddress,
                                               nmigrate_disks, migrate_disks, nbdPort,
-                                              migParams,
+                                              nbdURI, 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..fd9eb7cab0cd 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_URI,     VIR_TYPED_PARAM_STRING, \
     NULL
 
 
@@ -149,6 +150,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver,
                               size_t nmigrate_disks,
                               const char **migrate_disks,
                               int nbdPort,
+                              const char *nbdURI,
                               qemuMigrationParamsPtr migParams,
                               unsigned long flags);
 
@@ -165,6 +167,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
                         size_t nmigrate_disks,
                         const char **migrate_disks,
                         int nbdPort,
+                        const char *nbdURI,
                         qemuMigrationParamsPtr migParams,
                         const char *cookiein,
                         int cookieinlen,
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;
     }
 
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 8a4a0d172dc9..31597ee46972 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -10643,6 +10643,10 @@ static const vshCmdOptDef opts_migrate[] = {
      .type = VSH_OT_INT,
      .help = N_("port to use by target server for incoming disks migration")
     },
+    {.name = "disks-uri",
+     .type = VSH_OT_STRING,
+     .help = N_("URI to use for disks migration (overrides --disks-port)")
+    },
     {.name = "comp-methods",
      .type = VSH_OT_STRING,
      .help = N_("comma separated list of compression methods to be used")
@@ -10762,6 +10766,14 @@ doMigrate(void *opaque)
                              VIR_MIGRATE_PARAM_DISKS_PORT, intOpt) < 0)
         goto save_error;
 
+    if (vshCommandOptStringReq(ctl, cmd, "disks-uri", &opt) < 0)
+        goto out;
+    if (opt &&
+        virTypedParamsAddString(&params, &nparams, &maxparams,
+                                VIR_MIGRATE_PARAM_DISKS_URI,
+                                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