From nobody Sat Feb 7 08:28:29 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) client-ip=207.211.31.81; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [207.211.31.81]) by mx.zohomail.com with SMTPS id 158073383170045.81990138185199; Mon, 3 Feb 2020 04:43:51 -0800 (PST) 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-387-UF1cRtQNNEiektH4iiA5RQ-1; Mon, 03 Feb 2020 07:43:48 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 879111021868; Mon, 3 Feb 2020 12:43: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 4939190770; Mon, 3 Feb 2020 12:43:42 +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 F2E9F8174A; Mon, 3 Feb 2020 12:43:41 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 013ChfUV006078 for ; Mon, 3 Feb 2020 07:43:41 -0500 Received: by smtp.corp.redhat.com (Postfix) id 2D7E765F6A; Mon, 3 Feb 2020 12:43:41 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-57.ams2.redhat.com [10.36.112.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id EDAC4672C6; Mon, 3 Feb 2020 12:43:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1580733830; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc: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=+lA6GuM+JBkk4lwTK8MRHirRZwL4ZG4ui7z8MgDJJQU=; b=Z8p3gFD5iBrzvLqI1Hs4CguSE5I+JV7Sb10FcuZmBh3UiILmqBAVNjy45gXBXpHh6WhQ0R dVtA2m0lnM0OXtUsaoZvI840ywsAJjv5cT5kJeDCnlshZihCtJAeUCJsEo7OVkj4z390zS 5xCUWRRXhLO/TAk6YuJ6vtAzIMLlFhg= From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Subject: [libvirt PATCH 3/6] Add local migration support in QEMU Migration framework Date: Mon, 3 Feb 2020 12:43:30 +0000 Message-Id: <20200203124333.1925908-4-berrange@redhat.com> In-Reply-To: <20200203124333.1925908-1-berrange@redhat.com> References: <20200203124333.1925908-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Shaju Abraham 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.13 X-MC-Unique: UF1cRtQNNEiektH4iiA5RQ-1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" From: Shaju Abraham The local migration is selected by the option 'local' in virsh migrate command. Once 'local' is specified in the command line, the migration framework needs to follow the local migration path. Use the passed flag to selectively bypass the checks that otherwise prevents the local migration in QEMU migration framework. Signed-off-by: Shaju Abraham --- src/qemu/qemu_migration.c | 46 +++++++----- src/qemu/qemu_migration.h | 1 + src/qemu/qemu_migration_cookie.c | 121 ++++++++++++++++--------------- src/qemu/qemu_migration_cookie.h | 2 + src/qemu/qemu_process.c | 3 +- src/qemu/qemu_process.h | 2 + 6 files changed, 98 insertions(+), 77 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d7814208a2..d22daeac9c 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2334,15 +2334,30 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, bool tunnel =3D !!st; char *xmlout =3D NULL; unsigned int cookieFlags; - unsigned int startFlags; + unsigned int startFlags =3D 0; + unsigned int eatCookieFlags; qemuProcessIncomingDefPtr incoming =3D NULL; bool taint_hook =3D false; bool stopProcess =3D false; bool relabel =3D false; int rv; char *tlsAlias =3D NULL; + unsigned long list_flags =3D VIR_DOMAIN_OBJ_LIST_ADD_LIVE | + VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE; + eatCookieFlags =3D QEMU_MIGRATION_COOKIE_LOCKSTATE | + QEMU_MIGRATION_COOKIE_NBD | + QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG | + QEMU_MIGRATION_COOKIE_CPU_HOTPLUG | + QEMU_MIGRATION_COOKIE_CPU | + QEMU_MIGRATION_COOKIE_ALLOW_REBOOT | + QEMU_MIGRATION_COOKIE_CAPS; =20 virNWFilterReadLockFilterUpdates(); + if (flags & VIR_MIGRATE_LOCAL) { + list_flags |=3D VIR_DOMAIN_OBJ_LIST_ADD_LIVE_LOCAL; + eatCookieFlags |=3D QEMU_MIGRATION_COOKIE_LOCAL_MIGRATION; + startFlags |=3D VIR_QEMU_PROCESS_START_LOCAL_MIG; + } =20 if (flags & VIR_MIGRATE_OFFLINE) { if (flags & (VIR_MIGRATE_NON_SHARED_DISK | @@ -2439,19 +2454,12 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, * point in having the domain in the list at that point. */ if (!(mig =3D qemuMigrationEatCookie(driver, *def, origname, NULL, cookiein, cookieinlen, - QEMU_MIGRATION_COOKIE_LOCKSTATE | - QEMU_MIGRATION_COOKIE_NBD | - QEMU_MIGRATION_COOKIE_MEMORY_HOTPLU= G | - QEMU_MIGRATION_COOKIE_CPU_HOTPLUG | - QEMU_MIGRATION_COOKIE_CPU | - QEMU_MIGRATION_COOKIE_ALLOW_REBOOT | - QEMU_MIGRATION_COOKIE_CAPS))) + eatCookieFlags))) goto cleanup; =20 if (!(vm =3D virDomainObjListAdd(driver->domains, *def, driver->xmlopt, - VIR_DOMAIN_OBJ_LIST_ADD_LIVE | - VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, + list_flags, NULL))) goto cleanup; *def =3D NULL; @@ -2494,9 +2502,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, _("cannot create pipe for tunnelled migration= ")); goto stopjob; } - - startFlags =3D VIR_QEMU_PROCESS_START_AUTODESTROY; - + startFlags |=3D VIR_QEMU_PROCESS_START_AUTODESTROY; if (qemuProcessInit(driver, vm, mig->cpu, QEMU_ASYNC_JOB_MIGRATION_IN, true, startFlags) < 0) goto stopjob; @@ -2938,6 +2944,7 @@ qemuMigrationSrcConfirmPhase(virQEMUDriverPtr driver, qemuMigrationCookiePtr mig; virObjectEventPtr event; int rv =3D -1; + unsigned int cookieFlags =3D 0; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); qemuDomainObjPrivatePtr priv =3D vm->privateData; qemuDomainJobInfoPtr jobInfo =3D NULL; @@ -2948,15 +2955,16 @@ qemuMigrationSrcConfirmPhase(virQEMUDriverPtr drive= r, flags, retcode); =20 virCheckFlags(QEMU_MIGRATION_FLAGS, -1); - + cookieFlags =3D QEMU_MIGRATION_COOKIE_STATS; + if (flags & VIR_MIGRATE_LOCAL) + cookieFlags |=3D QEMU_MIGRATION_COOKIE_LOCAL_MIGRATION; qemuMigrationJobSetPhase(driver, vm, retcode =3D=3D 0 ? QEMU_MIGRATION_PHASE_CONFIRM3 : QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED); =20 if (!(mig =3D qemuMigrationEatCookie(driver, vm->def, priv->origname, = priv, - cookiein, cookieinlen, - QEMU_MIGRATION_COOKIE_STATS))) + cookiein, cookieinlen, cookieFlags)= )) goto cleanup; =20 if (retcode =3D=3D 0) @@ -3420,7 +3428,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, cookieout, cookieoutlen, flags, resource, spec, spec->destType, spec->fwdType, dconn, NULLSTR(graphicsuri), nmigrate_disks, migrate_disks); - + if (flags & VIR_MIGRATE_LOCAL) + cookieFlags |=3D QEMU_MIGRATION_COOKIE_LOCAL_MIGRATION; if (flags & VIR_MIGRATE_NON_SHARED_DISK) { migrate_flags |=3D QEMU_MONITOR_MIGRATE_NON_SHARED_DISK; cookieFlags |=3D QEMU_MIGRATION_COOKIE_NBD; @@ -4955,6 +4964,9 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver, * even though VIR_MIGRATE_PERSIST_DEST was not used. */ cookie_flags |=3D QEMU_MIGRATION_COOKIE_PERSISTENT; =20 + if (flags & VIR_MIGRATE_LOCAL) + cookie_flags |=3D QEMU_MIGRATION_COOKIE_LOCAL_MIGRATION; + if (!(mig =3D qemuMigrationEatCookie(driver, vm->def, priv->origname, = priv, cookiein, cookieinlen, cookie_flags= ))) goto endjob; diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index b6f88d3fd9..2cb4bb9023 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -59,6 +59,7 @@ VIR_MIGRATE_POSTCOPY | \ VIR_MIGRATE_TLS | \ VIR_MIGRATE_PARALLEL | \ + VIR_MIGRATE_LOCAL |\ 0) =20 /* All supported migration parameters and their types. */ diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_coo= kie.c index 299bf17c9e..18544dbaac 100644 --- a/src/qemu/qemu_migration_cookie.c +++ b/src/qemu/qemu_migration_cookie.c @@ -51,6 +51,7 @@ VIR_ENUM_IMPL(qemuMigrationCookieFlag, "cpu", "allowReboot", "capabilities", + "local-migration", ); =20 =20 @@ -1199,69 +1200,71 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr = mig, =20 /* We don't store the uuid, name, hostname, or hostuuid * values. We just compare them to local data to do some - * sanity checking on migration operation + * sanity checking on migration operation. In case of Local + * Migration bypass the checks. We know that we are migrating + * to the same host and the name and UUID will be existing in + * the host. */ =20 /* Extract domain name */ - if (!(tmp =3D virXPathString("string(./name[1])", ctxt))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("missing name element in migration data")); - goto error; - } - if (STRNEQ(tmp, mig->name)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Incoming cookie data had unexpected name %s vs %= s"), - tmp, mig->name); - goto error; - } - VIR_FREE(tmp); - - /* Extract domain uuid */ - tmp =3D virXPathString("string(./uuid[1])", ctxt); - if (!tmp) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("missing uuid element in migration data")); - goto error; - } - virUUIDFormat(mig->uuid, uuidstr); - if (STRNEQ(tmp, uuidstr)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Incoming cookie data had unexpected UUID %s vs %= s"), - tmp, uuidstr); - goto error; - } - VIR_FREE(tmp); - - /* Check & forbid "localhost" migration */ - if (!(mig->remoteHostname =3D virXPathString("string(./hostname[1])", = ctxt))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("missing hostname element in migration data= ")); - goto error; - } - if (STREQ(mig->remoteHostname, mig->localHostname)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Attempt to migrate guest to the same host %s"), - mig->remoteHostname); - goto error; - } - - if (!(tmp =3D virXPathString("string(./hostuuid[1])", ctxt))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("missing hostuuid element in migration data= ")); - goto error; - } - if (virUUIDParse(tmp, mig->remoteHostuuid) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("malformed hostuuid element in migration da= ta")); - goto error; - } - if (memcmp(mig->remoteHostuuid, mig->localHostuuid, VIR_UUID_BUFLEN) = =3D=3D 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Attempt to migrate guest to the same host %s"), - tmp); - goto error; + if (!(flags & QEMU_MIGRATION_COOKIE_LOCAL_MIGRATION)) { + if (!(tmp =3D virXPathString("string(./name[1])", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing name element in migration data= ")); + goto error; + } + if (STRNEQ(tmp, mig->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Incoming cookie data had unexpected name %s = vs %s"), + tmp, mig->name); + goto error; + } + VIR_FREE(tmp); + /* Extract domain uuid */ + tmp =3D virXPathString("string(./uuid[1])", ctxt); + if (!tmp) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing uuid element in migration data= ")); + goto error; + } + virUUIDFormat(mig->uuid, uuidstr); + if (STRNEQ(tmp, uuidstr)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Incoming cookie data had unexpected UUID %s = vs %s"), + tmp, uuidstr); + goto error; + } + VIR_FREE(tmp); + /* Check & forbid "localhost" migration */ + if (!(mig->remoteHostname =3D virXPathString("string(./hostname[1]= )", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing hostname element in migration = data")); + goto error; + } + if (STREQ(mig->remoteHostname, mig->localHostname)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Attempt to migrate guest to the same host %s= "), + mig->remoteHostname); + goto error; + } + if (!(tmp =3D virXPathString("string(./hostuuid[1])", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing hostuuid element in migration = data")); + goto error; + } + if (virUUIDParse(tmp, mig->remoteHostuuid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("malformed hostuuid element in migratio= n data")); + goto error; + } + if (memcmp(mig->remoteHostuuid, mig->localHostuuid, VIR_UUID_BUFLE= N) =3D=3D 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Attempt to migrate guest to the same host %s= "), + tmp); + goto error; + } + VIR_FREE(tmp); } - VIR_FREE(tmp); =20 /* Check to ensure all mandatory features from XML are also * present in 'flags' */ diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_coo= kie.h index 20e1ed60ca..7574672fd6 100644 --- a/src/qemu/qemu_migration_cookie.h +++ b/src/qemu/qemu_migration_cookie.h @@ -33,6 +33,7 @@ typedef enum { QEMU_MIGRATION_COOKIE_FLAG_CPU, QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT, QEMU_MIGRATION_COOKIE_FLAG_CAPS, + QEMU_MIGRATION_COOKIE_FLAG_LOCAL_MIGRATION, =20 QEMU_MIGRATION_COOKIE_FLAG_LAST } qemuMigrationCookieFlags; @@ -51,6 +52,7 @@ typedef enum { QEMU_MIGRATION_COOKIE_CPU =3D (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU), QEMU_MIGRATION_COOKIE_ALLOW_REBOOT =3D (1 << QEMU_MIGRATION_COOKIE_FLA= G_ALLOW_REBOOT), QEMU_MIGRATION_COOKIE_CAPS =3D (1 << QEMU_MIGRATION_COOKIE_FLAG_CAPS), + QEMU_MIGRATION_COOKIE_LOCAL_MIGRATION =3D (1 << QEMU_MIGRATION_COOKIE_= FLAG_LOCAL_MIGRATION), } qemuMigrationCookieFeatures; =20 typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 57a60c568a..df0884a233 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6679,7 +6679,8 @@ qemuProcessLaunch(virConnectPtr conn, VIR_QEMU_PROCESS_START_PAUSED | VIR_QEMU_PROCESS_START_AUTODESTROY | VIR_QEMU_PROCESS_START_NEW | - VIR_QEMU_PROCESS_START_GEN_VMID, -1); + VIR_QEMU_PROCESS_START_GEN_VMID | + VIR_QEMU_PROCESS_START_LOCAL_MIG, -1); =20 cfg =3D virQEMUDriverGetConfig(driver); =20 diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 9af9f967fd..7aa67158b0 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -81,6 +81,8 @@ typedef enum { VIR_QEMU_PROCESS_START_GEN_VMID =3D 1 << 5, /* Generate a new VMID= */ VIR_QEMU_PROCESS_START_STANDALONE =3D 1 << 6, /* Require CLI args to= be usable standalone, ie no FD passing and = the like */ + VIR_QEMU_PROCESS_START_LOCAL_MIG =3D 1 << 7, /* internal, new VM is= starting + for Local Migration */ } qemuProcessStartFlags; =20 int qemuProcessStart(virConnectPtr conn, --=20 2.24.1