From nobody Sun Feb 8 13:48:22 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1598971093; cv=none; d=zohomail.com; s=zohoarc; b=etFKmd9mq8Fte0bkIAgLLuBb5P2C8AxRUyXBzW6VdLz8/aNcdB93jtXvN8aE5gpnCBPhiq3Yj/HzTFRf6AJpjJL8O0Cce+eyJnytUW/NbcaGPRBBLyqPYL5fvrl58JcanHoyWrRQxkqXDpH+oSv4bwEzFcIOO0OwDVL8KYSsGc0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1598971093; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=zuC5lJhtkG/E6oN1mEN74rrkSOgCDHnPpfqnHuFMAEo=; b=avFA8tuhjY9GkZRTbnjkCVvHHkqPpE1dVVf7IZAm5n6JWWYznKRw7XPX/tPOFn17GgkIauz511CzMQX6FA7kQwoXh7JmmWeLgraNVQUrPcBEil7AfLdws+3P2vpXky5KufRHVSxu1r9Uy2eiFgbhpBz4LWMFvzo0Yf1/+ybbc18= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1598971093168701.7925761991249; Tue, 1 Sep 2020 07:38:13 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-521-0X8LvPWmOQCJFuWE_FZjYg-1; Tue, 01 Sep 2020 10:37:49 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 12D131DDF5; Tue, 1 Sep 2020 14:37:42 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E51EC5D9CC; Tue, 1 Sep 2020 14:37:41 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B54277A31E; Tue, 1 Sep 2020 14:37:41 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 081EbCnh016619 for ; Tue, 1 Sep 2020 10:37:12 -0400 Received: by smtp.corp.redhat.com (Postfix) id 4F0EB7EB8F; Tue, 1 Sep 2020 14:37:12 +0000 (UTC) Received: from wheatley.localdomain (unknown [10.40.195.43]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3570B7EB87 for ; Tue, 1 Sep 2020 14:37:11 +0000 (UTC) Received: from wheatley.redhat.com (wheatley.k8r.cz [127.0.0.1]) by wheatley.localdomain (Postfix) with ESMTP id 7AF347E0084 for ; Tue, 1 Sep 2020 16:37:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1598971092; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=zuC5lJhtkG/E6oN1mEN74rrkSOgCDHnPpfqnHuFMAEo=; b=DcCYhX3QUZlMGUU7PcqrhNSnHCGJUPY01QW0uQQjo3PjQolqtKk09vmM0SYua4xa/SolNo Dc6CWskuiG3blXZIdPhfvJvrHHeqaB40iKzw3/RIs8k4BMCyK6XBhp2QfAGqOaekGphDau V1WuCqkLlz3LecYYtKPfnP4SAJQb+Vk= X-MC-Unique: 0X8LvPWmOQCJFuWE_FZjYg-1 From: Martin Kletzander To: libvir-list@redhat.com Subject: [PATCH v2 6/9] qemu: Allow NBD migration over UNIX socket Date: Tue, 1 Sep 2020 16:36:57 +0200 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Jiri Denemark --- 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] =20 Migrate domain to another host. Add *--live* for live migration; <--p2p> for peer-2-peer migration; *--direct* for direct migration; or *--tunnelle= d* @@ -3292,6 +3293,16 @@ error if this parameter is used. Optional *disks-port* sets the port that hypervisor on destination side sh= ould bind to for incoming disks traffic. Currently it is supported only by QEMU. =20 +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 add= ress +(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 ove= r 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. + =20 migrate-compcache ----------------- diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.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" =20 +/** + * 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 conn= ect + * 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 i= f 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 =3D 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); =20 cleanup: @@ -11289,6 +11289,7 @@ qemuDomainMigratePerform(virDomainPtr dom, */ ret =3D 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); } =20 static int @@ -11485,6 +11486,7 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, g_autofree const char **migrate_disks =3D NULL; g_autofree char *origname =3D NULL; g_autoptr(qemuMigrationParams) migParams =3D NULL; + const char *nbdSocketPath =3D NULL; =20 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 dcon= n, QEMU_MIGRATION_DESTINAT= ION))) return -1; =20 + if (nbdSocketPath && nbdPort) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Both port and socket requested for disk migratio= n " + "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, nb= dPort, - migParams, flags); + nbdSocketPath, migParams, flags); } =20 =20 @@ -11682,7 +11694,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, =20 ret =3D 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 =3D 0; int nbdPort =3D 0; g_autoptr(qemuMigrationParams) migParams =3D NULL; + const char *nbdSocketPath =3D NULL; int ret =3D -1; =20 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; =20 + if (nbdSocketPath && nbdPort) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Both port and socket requested for disk migratio= n " + "while being mutually exclusive")); + goto cleanup; + } + nmigrate_disks =3D virTypedParamsGetStringList(params, nparams, VIR_MIGRATE_PARAM_MIGRATE= _DISKS, &migrate_disks); @@ -11768,7 +11791,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, ret =3D qemuMigrationSrcPerform(driver, dom->conn, vm, dom_xml, persis= t_xml, dconnuri, uri, graphicsuri, listenAddres= s, nmigrate_disks, migrate_disks, nbdPort, - migParams, + nbdSocketPath, migParams, cookiein, cookieinlen, cookieout, cookie= outlen, 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 =3D -1; @@ -390,8 +391,44 @@ qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver, .port =3D nbdPort, }; bool server_started =3D false; + g_autoptr(virURI) uri =3D NULL; + + /* Prefer nbdURI */ + if (nbdURI) { + uri =3D virURIParse(nbdURI); =20 - if (nbdPort < 0 || nbdPort > USHRT_MAX) { + if (!uri) + return -1; + + if (STREQ(uri->scheme, "tcp")) { + server.transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; + if (!uri->server || STREQ(uri->server, "")) { + /* Since tcp://:/ is parsed as server =3D NULL and p= ort =3D 0 + * we should rather error out instead of auto-allocating a= port + * as that would be the exact opposite of what was request= ed. */ + virReportError(VIR_ERR_INVALID_ARG, + _("URI with tcp scheme did not provide a se= rver part: %s"), + nbdURI); + return -1; + } + server.name =3D (char *)uri->server; + if (uri->port) + server.port =3D 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 =3D VIR_STORAGE_NET_HOST_TRANS_UNIX; + server.socket =3D (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 =3D diskAlias; } =20 - if (!server_started) { + if (!server_started && + server.transport =3D=3D 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; } =20 - priv->nbdPort =3D server.port; + if (server.transport =3D=3D VIR_STORAGE_NET_HOST_TRANS_TCP) + priv->nbdPort =3D server.port; =20 ret =3D 0; =20 @@ -793,6 +832,7 @@ static virStorageSourcePtr qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(virDomainDiskDefPtr di= sk, const char *host, int port, + const char *socket, const char *tlsAlias) { g_autoptr(virStorageSource) copysrc =3D NULL; @@ -813,9 +853,14 @@ qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(vi= rDomainDiskDefPtr disk, copysrc->hosts =3D g_new0(virStorageNetHostDef, 1); =20 copysrc->nhosts =3D 1; - copysrc->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; - copysrc->hosts->port =3D port; - copysrc->hosts->name =3D g_strdup(host); + if (socket) { + copysrc->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_UNIX; + copysrc->hosts->socket =3D g_strdup(socket); + } else { + copysrc->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; + copysrc->hosts->port =3D port; + copysrc->hosts->name =3D g_strdup(host); + } =20 copysrc->tlsAlias =3D g_strdup(tlsAlias); =20 @@ -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, =20 VIR_DEBUG("starting blockdev mirror for disk=3D%s to host=3D%s", disk-= >dst, host); =20 - if (!(copysrc =3D qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(= disk, host, port, tlsAlias))) + if (!(copysrc =3D qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(= disk, host, port, socket, tlsAlias))) return -1; =20 /* Migration via blockdev-mirror was supported sooner than the auto-re= ad-only @@ -885,13 +931,17 @@ qemuMigrationSrcNBDStorageCopyDriveMirror(virQEMUDriv= erPtr 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 =3D NULL; int mon_ret; =20 - if (strchr(host, ':')) { + if (socket) { + nbd_dest =3D g_strdup_printf("nbd+unix:///%s?socket=3D%s", + diskAlias, socket); + } else if (strchr(host, ':')) { nbd_dest =3D g_strdup_printf("nbd:[%s]:%d:exportname=3D%s", host, = port, diskAlias); } else { @@ -920,6 +970,7 @@ qemuMigrationSrcNBDStorageCopyOne(virQEMUDriverPtr driv= er, 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 d= river, rc =3D qemuMigrationSrcNBDStorageCopyBlockdev(driver, vm, disk, jobname, sourcename, persistjob, - host, port, + host, port, socket, mirror_speed, mirror_shallow, tlsAlias); } else { rc =3D qemuMigrationSrcNBDStorageCopyDriveMirror(driver, vm, diskA= lias, - host, port, + host, port, socket, mirror_speed, mirror_shallow); } @@ -1014,6 +1065,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr drive= r, const char **migrate_disks, virConnectPtr dconn, const char *tlsAlias, + const char *nbdURI, unsigned int flags) { qemuDomainObjPrivatePtr priv =3D vm->privateData; @@ -1023,6 +1075,8 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr drive= r, bool mirror_shallow =3D *migrate_flags & QEMU_MONITOR_MIGRATE_NON_SHAR= ED_INC; int rv; g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(driver); + g_autoptr(virURI) uri =3D NULL; + const char *socket =3D NULL; =20 VIR_DEBUG("Starting drive mirrors for domain %s", vm->def->name); =20 @@ -1038,6 +1092,33 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driv= er, port =3D mig->nbd->port; mig->nbd->port =3D 0; =20 + if (nbdURI) { + uri =3D virURIParse(nbdURI); + if (!uri) + return -1; + + if (STREQ(uri->scheme, "tcp")) { + if (uri->server && STRNEQ(uri->server, "")) + host =3D (char *)uri->server; + if (uri->port) + port =3D 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 =3D 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 =3D 0; i < vm->def->ndisks; i++) { virDomainDiskDefPtr disk =3D vm->def->disks[i]; =20 @@ -1046,6 +1127,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr drive= r, continue; =20 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, =20 if (qemuMigrationDstStartNBDServer(driver, vm, incoming->address, nmigrate_disks, migrate_disks, - nbdPort, nbdTLSAlias) < 0) { + nbdPort, nbdURI, + nbdTLSAlias) < 0) { goto stopjob; } cookieFlags |=3D QEMU_MIGRATION_COOKIE_NBD; @@ -2785,7 +2869,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, return qemuMigrationDstPrepareAny(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, def, origna= me, st, NULL, 0, false, NULL, 0, NULL, 0, - migParams, flags); + NULL, migParams, flags); } =20 =20 @@ -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 driv= er, VIR_DEBUG("driver=3D%p, dconn=3D%p, cookiein=3D%s, cookieinlen=3D%d, " "cookieout=3D%p, cookieoutlen=3D%p, uri_in=3D%s, uri_out=3D%= p, " "def=3D%p, origname=3D%s, listenAddress=3D%s, " - "nmigrate_disks=3D%zu, migrate_disks=3D%p, nbdPort=3D%d, fla= gs=3D0x%lx", + "nmigrate_disks=3D%zu, migrate_disks=3D%p, nbdPort=3D%d, " + "nbdURI=3D%s, flags=3D0x%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); =20 *uri_out =3D NULL; =20 @@ -2947,7 +3034,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, NULL, uri ? uri->scheme : "tcp", port, autoPort, listenAddress, nmigrate_disks, migrate_disks, nbdPor= t, - migParams, flags); + nbdURI, migParams, flags); cleanup: if (ret !=3D 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 =3D -1; unsigned int migrate_flags =3D 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 =3D vm->privateData; g_autoptr(virURI) uribits =3D NULL; @@ -3908,7 +3998,7 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver, ret =3D qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookiei= nlen, cookieout, cookieoutlen, flags, resource, &spec, dconn, graphicsuri, nmigrate_disks, migrate_disks, - migParams); + migParams, nbdURI); =20 if (spec.destType =3D=3D MIGRATION_DEST_FD) VIR_FORCE_CLOSE(spec.dest.fd.qemu); @@ -3971,7 +4061,7 @@ qemuMigrationSrcPerformTunnel(virQEMUDriverPtr driver, ret =3D qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookiei= nlen, cookieout, cookieoutlen, flags, resource, &s= pec, dconn, graphicsuri, nmigrate_disks, migrate_= disks, - migParams); + migParams, NULL); =20 cleanup: VIR_FORCE_CLOSE(spec.dest.fd.qemu); @@ -4078,7 +4168,7 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr dr= iver, cookie, cookielen, NULL, NULL, /* No out cookie w= ith v2 migration */ flags, resource, dconn, NULL, = 0, NULL, - migParams); + migParams, NULL); =20 /* Perform failed. Make sure Finish doesn't overwrite the error */ if (ret < 0) @@ -4142,6 +4232,7 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr dr= iver, 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 d= river, VIR_MIGRATE_PARAM_DISKS_PORT, nbdPort) < 0) goto cleanup; + if (nbdURI && + virTypedParamsAddString(¶ms, &nparams, &maxparams, + VIR_MIGRATE_PARAM_DISKS_URI, + nbdURI) < 0) + goto cleanup; =20 if (qemuMigrationParamsDump(migParams, ¶ms, &nparams, &maxparams, &flags) < 0) @@ -4323,7 +4419,7 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr dr= iver, &cookieout, &cookieoutlen, flags, bandwidth, dconn, graph= icsuri, nmigrate_disks, migrate_disks, - migParams); + migParams, nbdURI); } =20 /* Perform failed. Make sure Finish doesn't overwrite the error */ @@ -4498,6 +4594,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr dri= ver, 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 d= river, =20 VIR_DEBUG("driver=3D%p, sconn=3D%p, vm=3D%p, xmlin=3D%s, dconnuri=3D%s= , uri=3D%s, " "graphicsuri=3D%s, listenAddress=3D%s, nmigrate_disks=3D%zu,= " - "migrate_disks=3D%p, nbdPort=3D%d, flags=3D0x%lx, dname=3D%s= , " - "resource=3D%lu", + "migrate_disks=3D%p, nbdPort=3D%d, nbdURI=3D%s, flags=3D0x%l= x, " + "dname=3D%s, resource=3D%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); =20 if (flags & VIR_MIGRATE_TUNNELLED && uri) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", @@ -4618,7 +4715,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr dri= ver, ret =3D qemuMigrationSrcPerformPeer2Peer3(driver, sconn, dconn, dc= onnuri, vm, xmlin, persist_xml, dname, uri, g= raphicsuri, listenAddress, nmigrate_di= sks, migrate_disks, - nbdPort, migParams, resour= ce, + nbdPort, nbdURI, migParams= , resource, useParams, flags); } else { ret =3D 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 =3D qemuMigrationSrcPerformPeer2Peer(driver, conn, vm, xmlin, = persist_xml, dconnuri, uri, graphicsuri,= listenAddress, nmigrate_disks, migrate_dis= ks, nbdPort, + nbdURI, migParams, flags, dname, re= source, &v3proto); } else { @@ -4699,7 +4798,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, ret =3D 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 =3D vm->privateData; qemuDomainJobPrivatePtr jobPriv =3D priv->job.privateData; @@ -4787,7 +4887,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, ret =3D qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, co= okiein, cookieinlen, cookieout, cookieoutlen, flags, resource, NULL, graphicsuri, - nmigrate_disks, migrate_disks, mig= Params); + nmigrate_disks, migrate_disks, mig= Params, nbdURI); =20 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=3D%p, conn=3D%p, vm=3D%p, xmlin=3D%s, dconnuri=3D%s,= " "uri=3D%s, graphicsuri=3D%s, listenAddress=3D%s, " "nmigrate_disks=3D%zu, migrate_disks=3D%p, nbdPort=3D%d, " + "nbdURI=3D%s, " "cookiein=3D%s, cookieinlen=3D%d, cookieout=3D%p, cookieoutl= en=3D%p, " "flags=3D0x%lx, dname=3D%s, resource=3D%lu, v3proto=3D%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); =20 @@ -4859,7 +4961,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist= _xml, dconnuri, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, n= bdPort, - 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, per= sist_xml, NULL, uri, graphicsuri, listenAddr= ess, nmigrate_disks, migrate_disk= s, nbdPort, - migParams, + nbdURI, migParams, cookiein, cookieinlen, cookieout, cookieoutlen, fla= gs, 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 =20 =20 @@ -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); =20 @@ -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_coo= kie.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); } =20 @@ -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; } =20 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[] =3D { .type =3D VSH_OT_INT, .help =3D N_("port to use by target server for incoming disks migrati= on") }, + {.name =3D "disks-uri", + .type =3D VSH_OT_STRING, + .help =3D N_("URI to use for disks migration (overrides --disks-port)= ") + }, {.name =3D "comp-methods", .type =3D VSH_OT_STRING, .help =3D 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; =20 + if (vshCommandOptStringReq(ctl, cmd, "disks-uri", &opt) < 0) + goto out; + if (opt && + virTypedParamsAddString(¶ms, &nparams, &maxparams, + VIR_MIGRATE_PARAM_DISKS_URI, + opt) < 0) + goto save_error; + if (vshCommandOptStringReq(ctl, cmd, "dname", &opt) < 0) goto out; if (opt && --=20 2.28.0