From 9281d9a8d447e8b066cc600f1dcca7775920f01e Mon Sep 17 00:00:00 2001 Message-Id: <9281d9a8d447e8b066cc600f1dcca7775920f01e@dist-git> From: Jiri Denemark Date: Fri, 19 May 2017 15:20:31 +0200 Subject: [PATCH] qemu: Report the original CPU in migratable xml The destination host may not be able to start a domain using the live updated CPU definition because either libvirt or QEMU may not be new enough. Thus we need to send the original guest CPU definition. Signed-off-by: Jiri Denemark Reviewed-by: Pavel Hrdina (cherry picked from commit 356a2161e293eaab57448a8e68f489e0841efe19) https://bugzilla.redhat.com/show_bug.cgi?id=1441662 Signed-off-by: Jiri Denemark --- src/qemu/qemu_domain.c | 61 ++++++++++++++++++++++++++++++++++++++--------- src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 13 ++++++---- src/qemu/qemu_migration.c | 5 ++-- 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 89fd9f9abc..514b56b33c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4175,11 +4175,13 @@ qemuDomainDefCopy(virQEMUDriverPtr driver, return ret; } -int -qemuDomainDefFormatBuf(virQEMUDriverPtr driver, - virDomainDefPtr def, - unsigned int flags, - virBuffer *buf) + +static int +qemuDomainDefFormatBufInternal(virQEMUDriverPtr driver, + virDomainDefPtr def, + virCPUDefPtr origCPU, + unsigned int flags, + virBuffer *buf) { int ret = -1; virDomainDefPtr copy = NULL; @@ -4300,6 +4302,16 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver, if (qemuDomainChrDefDropDefaultPath(def->channels[i], driver) < 0) goto cleanup; } + + /* Replace the CPU definition updated according to QEMU with the one + * used for starting the domain. The updated def will be sent + * separately for backward compatibility. + */ + if (origCPU) { + virCPUDefFree(def->cpu); + if (!(def->cpu = virCPUDefCopy(origCPU))) + goto cleanup; + } } format: @@ -4313,13 +4325,26 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver, return ret; } -char *qemuDomainDefFormatXML(virQEMUDriverPtr driver, - virDomainDefPtr def, - unsigned int flags) + +int +qemuDomainDefFormatBuf(virQEMUDriverPtr driver, + virDomainDefPtr def, + unsigned int flags, + virBufferPtr buf) +{ + return qemuDomainDefFormatBufInternal(driver, def, NULL, flags, buf); +} + + +static char * +qemuDomainDefFormatXMLInternal(virQEMUDriverPtr driver, + virDomainDefPtr def, + virCPUDefPtr origCPU, + unsigned int flags) { virBuffer buf = VIR_BUFFER_INITIALIZER; - if (qemuDomainDefFormatBuf(driver, def, flags, &buf) < 0) { + if (qemuDomainDefFormatBufInternal(driver, def, origCPU, flags, &buf) < 0) { virBufferFreeAndReset(&buf); return NULL; } @@ -4333,26 +4358,40 @@ char *qemuDomainDefFormatXML(virQEMUDriverPtr driver, return virBufferContentAndReset(&buf); } + +char * +qemuDomainDefFormatXML(virQEMUDriverPtr driver, + virDomainDefPtr def, + unsigned int flags) +{ + return qemuDomainDefFormatXMLInternal(driver, def, NULL, flags); +} + + char *qemuDomainFormatXML(virQEMUDriverPtr driver, virDomainObjPtr vm, unsigned int flags) { virDomainDefPtr def; + qemuDomainObjPrivatePtr priv = vm->privateData; + virCPUDefPtr origCPU = NULL; if ((flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef) { def = vm->newDef; } else { def = vm->def; + origCPU = priv->origCPU; if (virDomainObjIsActive(vm)) flags &= ~VIR_DOMAIN_XML_UPDATE_CPU; } - return qemuDomainDefFormatXML(driver, def, flags); + return qemuDomainDefFormatXMLInternal(driver, def, origCPU, flags); } char * qemuDomainDefFormatLive(virQEMUDriverPtr driver, virDomainDefPtr def, + virCPUDefPtr origCPU, bool inactive, bool compatible) { @@ -4363,7 +4402,7 @@ qemuDomainDefFormatLive(virQEMUDriverPtr driver, if (compatible) flags |= VIR_DOMAIN_XML_MIGRATABLE; - return qemuDomainDefFormatXML(driver, def, flags); + return qemuDomainDefFormatXMLInternal(driver, def, origCPU, flags); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 0c5dad60e1..9567458849 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -515,6 +515,7 @@ char *qemuDomainFormatXML(virQEMUDriverPtr driver, char *qemuDomainDefFormatLive(virQEMUDriverPtr driver, virDomainDefPtr def, + virCPUDefPtr origCPU, bool inactive, bool compatible); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index dbb1ea9475..f5c5c302be 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3330,9 +3330,9 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom, virDomainDefFree(def); goto endjob; } - xml = qemuDomainDefFormatLive(driver, def, true, true); + xml = qemuDomainDefFormatLive(driver, def, NULL, true, true); } else { - xml = qemuDomainDefFormatLive(driver, vm->def, true, true); + xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU, true, true); } if (!xml) { virReportError(VIR_ERR_OPERATION_FAILED, @@ -14512,7 +14512,8 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn, "snapshot", false)) < 0) goto cleanup; - if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)) || + if (!(xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU, + true, true)) || !(snap->def->cookie = (virObjectPtr) qemuDomainSaveCookieNew(vm))) goto cleanup; @@ -14623,6 +14624,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, bool align_match = true; virQEMUDriverConfigPtr cfg = NULL; virCapsPtr caps = NULL; + qemuDomainObjPrivatePtr priv; virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE | VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT | @@ -14740,6 +14742,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE); + priv = vm->privateData; + if (redefine) { if (virDomainSnapshotRedefinePrep(domain, vm, &def, &snap, driver->xmlopt, @@ -14748,7 +14752,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, } else { /* Easiest way to clone inactive portion of vm->def is via * conversion in and back out of xml. */ - if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)) || + if (!(xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU, + true, true)) || !(def->dom = virDomainDefParseString(xml, caps, driver->xmlopt, NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE | VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE))) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 5bf9bd10f7..ec5af7a612 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2028,9 +2028,10 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver, if (!qemuDomainDefCheckABIStability(driver, vm->def, def)) goto cleanup; - rv = qemuDomainDefFormatLive(driver, def, false, true); + rv = qemuDomainDefFormatLive(driver, def, NULL, false, true); } else { - rv = qemuDomainDefFormatLive(driver, vm->def, false, true); + rv = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU, + false, true); } cleanup: -- 2.13.1