https://bugzilla.redhat.com/show_bug.cgi?id=994364
If user provides domain XML in migration we check if it doesn't break
ABI via virDomainDefCheckABIStability(). However, if the provided XML
was generated via virDomainGetXMLDesc(..., VIR_DOMAIN_XML_MIGRATABLE)
it is missing some devices, e.g. 'pci-root' controller. Hence, the ABI
stability check fails even though it is stable.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_migration.c | 41 +++++++++++++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 3a1aab7..65a09b4 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1970,6 +1970,8 @@ static char
virCapsPtr caps = NULL;
unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_LOCKSTATE;
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
+ virDomainDefPtr migratableDef = NULL;
+ char *migratableDefStr = NULL;
VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s,"
" cookieout=%p, cookieoutlen=%p, flags=%lx",
@@ -2039,7 +2041,17 @@ static char
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (!virDomainDefCheckABIStability(vm->def, def))
+ migratableDefStr = qemuDomainDefFormatLive(driver, vm->def, false, true);
+ if (!migratableDefStr)
+ goto cleanup;
+
+ if (!(migratableDef = virDomainDefParseString(migratableDefStr, caps,
+ driver->xmlopt,
+ QEMU_EXPECTED_VIRT_TYPES,
+ VIR_DOMAIN_XML_INACTIVE)))
+ goto cleanup;
+
+ if (!virDomainDefCheckABIStability(migratableDef, def))
goto cleanup;
rv = qemuDomainDefFormatLive(driver, def, false, true);
@@ -2051,6 +2063,8 @@ cleanup:
qemuMigrationCookieFree(mig);
virObjectUnref(caps);
virDomainDefFree(def);
+ virDomainDefFree(migratableDef);
+ VIR_FREE(migratableDefStr);
return rv;
}
@@ -2179,6 +2193,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
const char *listenAddr = NULL;
char *migrateFrom = NULL;
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
+ virDomainDefPtr migratableDef = NULL;
+ char *migratableDefStr = NULL;
if (virTimeMillisNow(&now) < 0)
return -1;
@@ -2213,18 +2229,16 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
/* Let migration hook filter domain XML */
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
- char *xml;
int hookret;
- if (!(xml = qemuDomainDefFormatXML(driver, *def,
- VIR_DOMAIN_XML_SECURE |
- VIR_DOMAIN_XML_MIGRATABLE)))
+ if (!(migratableDefStr = qemuDomainDefFormatXML(driver, *def,
+ VIR_DOMAIN_XML_SECURE |
+ VIR_DOMAIN_XML_MIGRATABLE)))
goto cleanup;
hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, (*def)->name,
VIR_HOOK_QEMU_OP_MIGRATE, VIR_HOOK_SUBOP_BEGIN,
- NULL, xml, &xmlout);
- VIR_FREE(xml);
+ NULL, migratableDefStr, &xmlout);
if (hookret < 0) {
goto cleanup;
@@ -2242,7 +2256,16 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
if (!newdef)
goto cleanup;
- if (!virDomainDefCheckABIStability(*def, newdef)) {
+ migratableDef = virDomainDefParseString(migratableDefStr, caps,
+ driver->xmlopt,
+ QEMU_EXPECTED_VIRT_TYPES,
+ VIR_DOMAIN_XML_INACTIVE);
+ if (!migratableDef) {
+ virDomainDefFree(newdef);
+ goto cleanup;
+ }
+
+ if (!virDomainDefCheckABIStability(migratableDef, newdef)) {
virDomainDefFree(newdef);
goto cleanup;
}
@@ -2429,6 +2452,8 @@ cleanup:
qemuDomainEventQueue(driver, event);
qemuMigrationCookieFree(mig);
virObjectUnref(caps);
+ virDomainDefFree(migratableDef);
+ VIR_FREE(migratableDefStr);
return ret;
stop:
--
1.8.1.5