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(a)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(¶ms, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_DISKS_SOCKET,
+ nbdSocketPath) < 0)
+ goto cleanup;
if (qemuMigrationParamsDump(migParams, ¶ms, &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(¶ms, &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