From nobody Mon Dec 15 23:01:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 149682474227487.68968405949954; Wed, 7 Jun 2017 01:39:02 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C2889804F2; Wed, 7 Jun 2017 08:39:00 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A0D6A7E64D; Wed, 7 Jun 2017 08:39:00 +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 3FD661869FE6; Wed, 7 Jun 2017 08:38:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v578brQR004872 for ; Wed, 7 Jun 2017 04:37:53 -0400 Received: by smtp.corp.redhat.com (Postfix) id 22B087D517; Wed, 7 Jun 2017 08:37:53 +0000 (UTC) Received: from virval.usersys.redhat.com (dhcp129-92.brq.redhat.com [10.34.129.92]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C652960467 for ; Wed, 7 Jun 2017 08:37:52 +0000 (UTC) Received: by virval.usersys.redhat.com (Postfix, from userid 500) id A224710193F; Wed, 7 Jun 2017 10:37:46 +0200 (CEST) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C2889804F2 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com C2889804F2 From: Jiri Denemark To: libvir-list@redhat.com Date: Wed, 7 Jun 2017 10:37:45 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: Mail-Followup-To: libvir-list@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 20/20] qemu: Use updated CPU when starting QEMU if possible 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: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 07 Jun 2017 08:39:01 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" If QEMU is new enough and we have the live updated CPU definition in either save or migration cookie, we can use it to enforce ABI. The original guest CPU from domain XML will be stored in private data. Signed-off-by: Jiri Denemark Reviewed-by: Pavel Hrdina --- Notes: Version 2: - no change src/qemu/qemu_domain.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 5 +++++ src/qemu/qemu_driver.c | 30 ++++++++++++++++++++++++------ src/qemu/qemu_migration.c | 2 +- src/qemu/qemu_process.c | 24 ++++++++++++++++++++++-- src/qemu/qemu_process.h | 2 ++ 6 files changed, 94 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ec43d06d7..2aa3aaa47 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -9240,3 +9240,43 @@ virSaveCookieCallbacks virQEMUDriverDomainSaveCookie= =3D { .parse =3D qemuDomainSaveCookieParse, .format =3D qemuDomainSaveCookieFormat, }; + + +/** + * qemuDomainUpdateCPU: + * @vm: domain which is being started + * @cpu: CPU updated when the domain was running previously (before migrat= ion, + * snapshot, or save) + * @origCPU: where to store the original CPU from vm->def in case @cpu was + * used instead + * + * Replace the CPU definition with the updated one when QEMU is new enough= to + * allow us to check extra features it is about to enable or disable when + * starting a domain. The original CPU is stored in @origCPU. + * + * Returns 0 on success, -1 on error. + */ +int +qemuDomainUpdateCPU(virDomainObjPtr vm, + virCPUDefPtr cpu, + virCPUDefPtr *origCPU) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + + *origCPU =3D NULL; + + if (!cpu || !vm->def->cpu || + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSIO= N) || + virCPUDefIsEqual(vm->def->cpu, cpu, false)) + return 0; + + if (!(cpu =3D virCPUDefCopy(cpu))) + return -1; + + VIR_DEBUG("Replacing CPU def with the updated one"); + + *origCPU =3D vm->def->cpu; + vm->def->cpu =3D cpu; + + return 0; +} diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 44c466cb7..ef3a33076 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -919,4 +919,9 @@ char *qemuDomainDiskBackingStoreGetName(virDomainDiskDe= fPtr disk, virStorageSourcePtr qemuDomainGetStorageSourceByDevstr(const char *devstr, virDomainDefPtr def= ); =20 +int +qemuDomainUpdateCPU(virDomainObjPtr vm, + virCPUDefPtr cpu, + virCPUDefPtr *origCPU); + #endif /* __QEMU_DOMAIN_H__ */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5766ece80..12bafd636 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1779,7 +1779,7 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr= conn, goto cleanup; } =20 - if (qemuProcessStart(conn, driver, vm, QEMU_ASYNC_JOB_START, + if (qemuProcessStart(conn, driver, vm, NULL, QEMU_ASYNC_JOB_START, NULL, -1, NULL, NULL, VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags) < 0) { @@ -6506,8 +6506,8 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, } } =20 - if (qemuProcessStart(conn, driver, vm, asyncJob, - "stdio", *fd, path, NULL, + if (qemuProcessStart(conn, driver, vm, cookie ? cookie->cpu : NULL, + asyncJob, "stdio", *fd, path, NULL, VIR_NETDEV_VPORT_PROFILE_OP_RESTORE, VIR_QEMU_PROCESS_START_PAUSED) =3D=3D 0) restored =3D true; @@ -7124,7 +7124,7 @@ qemuDomainObjStart(virConnectPtr conn, } } =20 - ret =3D qemuProcessStart(conn, driver, vm, asyncJob, + ret =3D qemuProcessStart(conn, driver, vm, NULL, asyncJob, NULL, -1, NULL, NULL, VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags= ); virDomainAuditStart(vm, "booted", ret >=3D 0); @@ -15294,6 +15294,8 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr sna= pshot, virCapsPtr caps =3D NULL; bool was_running =3D false; bool was_stopped =3D false; + qemuDomainSaveCookiePtr cookie; + virCPUDefPtr origCPU =3D NULL; =20 virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING | VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED | @@ -15399,6 +15401,8 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr sna= pshot, goto endjob; } =20 + cookie =3D (qemuDomainSaveCookiePtr) snap->def->cookie; + switch ((virDomainState) snap->def->state) { case VIR_DOMAIN_RUNNING: case VIR_DOMAIN_PAUSED: @@ -15410,6 +15414,15 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr sn= apshot, * to have finer control. */ if (virDomainObjIsActive(vm)) { /* Transitions 5, 6, 8, 9 */ + /* Replace the CPU in config and put the original one in priv + * once we're done. + */ + if (cookie && cookie->cpu && config->cpu) { + origCPU =3D config->cpu; + if (!(config->cpu =3D virCPUDefCopy(cookie->cpu))) + goto endjob; + } + /* Check for ABI compatibility. We need to do this check again= st * the migratable XML or it will always fail otherwise */ if (config && @@ -15469,8 +15482,11 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr sn= apshot, * failed loadvm attempt? */ goto endjob; } - if (config) + if (config) { virDomainObjAssignDef(vm, config, false, NULL); + virCPUDefFree(priv->origCPU); + VIR_STEAL_PTR(priv->origCPU, origCPU); + } } else { /* Transitions 2, 3 */ load: @@ -15479,6 +15495,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr sna= pshot, virDomainObjAssignDef(vm, config, false, NULL); =20 rc =3D qemuProcessStart(snapshot->domain->conn, driver, vm, + cookie ? cookie->cpu : NULL, QEMU_ASYNC_JOB_START, NULL, -1, NULL, sn= ap, VIR_NETDEV_VPORT_PROFILE_OP_CREATE, VIR_QEMU_PROCESS_START_PAUSED); @@ -15572,7 +15589,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr sna= pshot, start_flags |=3D paused ? VIR_QEMU_PROCESS_START_PAUSED : 0; =20 qemuDomainEventQueue(driver, event); - rc =3D qemuProcessStart(snapshot->domain->conn, driver, vm, + rc =3D qemuProcessStart(snapshot->domain->conn, driver, vm, NU= LL, QEMU_ASYNC_JOB_START, NULL, -1, NULL, NU= LL, VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags); @@ -15644,6 +15661,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr sna= pshot, virObjectUnref(caps); virObjectUnref(cfg); virNWFilterUnlockFilterUpdates(); + virCPUDefFree(origCPU); =20 return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 134c76c5e..505e61e5f 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2681,7 +2681,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, goto stopjob; } =20 - if (qemuProcessInit(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, + if (qemuProcessInit(driver, vm, mig->cpu, QEMU_ASYNC_JOB_MIGRATION_IN, true, VIR_QEMU_PROCESS_START_AUTODESTROY) < 0) goto stopjob; stopProcess =3D true; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index c06349474..4a66f0d5d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3946,6 +3946,13 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr drive= r, if (qemuProcessVerifyCPUFeatures(def, cpu) < 0) goto cleanup; =20 + /* Don't update the CPU if we already did so when starting a domain + * during migration, restore or snapshot revert. */ + if (priv->origCPU) { + ret =3D 0; + goto cleanup; + } + if (!(orig =3D virCPUDefCopy(def->cpu))) goto cleanup; =20 @@ -4864,6 +4871,7 @@ qemuProcessStartValidate(virQEMUDriverPtr driver, int qemuProcessInit(virQEMUDriverPtr driver, virDomainObjPtr vm, + virCPUDefPtr updatedCPU, qemuDomainAsyncJob asyncJob, bool migration, unsigned int flags) @@ -4872,6 +4880,7 @@ qemuProcessInit(virQEMUDriverPtr driver, virCapsPtr caps =3D NULL; qemuDomainObjPrivatePtr priv =3D vm->privateData; int stopFlags; + virCPUDefPtr origCPU =3D NULL; int ret =3D -1; =20 VIR_DEBUG("vm=3D%p name=3D%s id=3D%d migration=3D%d", @@ -4896,6 +4905,9 @@ qemuProcessInit(virQEMUDriverPtr driver, vm->def->os.machine)= )) goto cleanup; =20 + if (qemuDomainUpdateCPU(vm, updatedCPU, &origCPU) < 0) + goto cleanup; + if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) = < 0) goto cleanup; =20 @@ -4928,11 +4940,14 @@ qemuProcessInit(virQEMUDriverPtr driver, =20 if (qemuDomainSetPrivatePaths(driver, vm) < 0) goto stop; + + VIR_STEAL_PTR(priv->origCPU, origCPU); } =20 ret =3D 0; =20 cleanup: + virCPUDefFree(origCPU); virObjectUnref(cfg); virObjectUnref(caps); return ret; @@ -5963,6 +5978,7 @@ int qemuProcessStart(virConnectPtr conn, virQEMUDriverPtr driver, virDomainObjPtr vm, + virCPUDefPtr updatedCPU, qemuDomainAsyncJob asyncJob, const char *migrateFrom, int migrateFd, @@ -5993,7 +6009,8 @@ qemuProcessStart(virConnectPtr conn, if (!migrateFrom && !snapshot) flags |=3D VIR_QEMU_PROCESS_START_NEW; =20 - if (qemuProcessInit(driver, vm, asyncJob, !!migrateFrom, flags) < 0) + if (qemuProcessInit(driver, vm, updatedCPU, + asyncJob, !!migrateFrom, flags) < 0) goto cleanup; =20 if (migrateFrom) { @@ -6072,7 +6089,8 @@ qemuProcessCreatePretendCmd(virConnectPtr conn, flags |=3D VIR_QEMU_PROCESS_START_PRETEND; flags |=3D VIR_QEMU_PROCESS_START_NEW; =20 - if (qemuProcessInit(driver, vm, QEMU_ASYNC_JOB_NONE, !!migrateURI, fla= gs) < 0) + if (qemuProcessInit(driver, vm, NULL, QEMU_ASYNC_JOB_NONE, + !!migrateURI, flags) < 0) goto cleanup; =20 if (qemuProcessPrepareDomain(conn, driver, vm, flags) < 0) @@ -6476,6 +6494,8 @@ void qemuProcessStop(virQEMUDriverPtr driver, =20 /* clean up migration data */ VIR_FREE(priv->migTLSAlias); + virCPUDefFree(priv->origCPU); + priv->origCPU =3D NULL; =20 /* clear previously used namespaces */ virBitmapFree(priv->namespaces); diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 830d8cef8..c38310b47 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -75,6 +75,7 @@ typedef enum { int qemuProcessStart(virConnectPtr conn, virQEMUDriverPtr driver, virDomainObjPtr vm, + virCPUDefPtr updatedCPU, qemuDomainAsyncJob asyncJob, const char *migrateFrom, int stdin_fd, @@ -93,6 +94,7 @@ virCommandPtr qemuProcessCreatePretendCmd(virConnectPtr c= onn, =20 int qemuProcessInit(virQEMUDriverPtr driver, virDomainObjPtr vm, + virCPUDefPtr updatedCPU, qemuDomainAsyncJob asyncJob, bool migration, unsigned int flags); --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list