[libvirt] [PATCH 0/2] persistant live migration with specified XML

Live migration has a bug: specified XML doesn't used for persistant configuration. https://bugzilla.redhat.com/show_bug.cgi?id=835300 This patch-set fixes this problem. Specified XML used for both active and inactive domain XML. Hope this is what it should be. Dmitry Andreev (2): qemuMigrationCookieAddPersistent: change argument type qemu: migration: use specified XML for active and inactive confguration src/qemu/qemu_migration.c | 55 ++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 27 deletions(-) -- 1.8.3.1

It wasn't possible to add XML not assigned to a domain because virDomainObjPtr was an argument type. --- src/qemu/qemu_migration.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 38fa81c..92d2ce9 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -507,7 +507,7 @@ qemuMigrationCookieAddLockstate(qemuMigrationCookiePtr mig, static int qemuMigrationCookieAddPersistent(qemuMigrationCookiePtr mig, - virDomainObjPtr dom) + virDomainDefPtr def) { if (mig->flags & QEMU_MIGRATION_COOKIE_PERSISTENT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -515,10 +515,10 @@ qemuMigrationCookieAddPersistent(qemuMigrationCookiePtr mig, return -1; } - if (!dom->newDef) + if (!def) return 0; - mig->persistent = dom->newDef; + mig->persistent = def; mig->flags |= QEMU_MIGRATION_COOKIE_PERSISTENT; mig->flagsMandatory |= QEMU_MIGRATION_COOKIE_PERSISTENT; return 0; @@ -1367,7 +1367,7 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig, return -1; if (flags & QEMU_MIGRATION_COOKIE_PERSISTENT && - qemuMigrationCookieAddPersistent(mig, dom) < 0) + qemuMigrationCookieAddPersistent(mig, dom->newDef) < 0) return -1; if (flags & QEMU_MIGRATION_COOKIE_NETWORK && -- 1.8.3.1

Migration API allows to specify a destination domain XML. If no XML was specified the source one is used. Offline domain has only inactive XML and it is replaced by specified destination XML. Live migration allows to persist domain on a destination host. In this case both inactive and active XML should be replaced with specified XML. The problem is that specified XML only replaces an active one. https://bugzilla.redhat.com/show_bug.cgi?id=835300 This commit adds a migration cookie with specified destination XML at a migration beginning phase and sets this XML to destination domain on the next step. --- src/qemu/qemu_migration.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 92d2ce9..b24301d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3072,14 +3072,6 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver, vm->newDef && virDomainDefHasMemoryHotplug(vm->newDef))) cookieFlags |= QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG; - if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0))) - goto cleanup; - - if (qemuMigrationBakeCookie(mig, driver, vm, - cookieout, cookieoutlen, - cookieFlags) < 0) - goto cleanup; - if (flags & VIR_MIGRATE_OFFLINE) { if (flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) { @@ -3115,6 +3107,18 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver, rv = qemuDomainDefFormatLive(driver, vm->def, false, true); } + if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0))) + goto cleanup; + + if (flags & VIR_MIGRATE_PERSIST_DEST && + qemuMigrationCookieAddPersistent(mig, def ? def : vm->newDef)) + goto cleanup; + + if (qemuMigrationBakeCookie(mig, driver, vm, + cookieout, cookieoutlen, + cookieFlags) < 0) + goto cleanup; + cleanup: qemuMigrationCookieFree(mig); virObjectUnref(caps); @@ -3431,7 +3435,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, QEMU_MIGRATION_COOKIE_LOCKSTATE | QEMU_MIGRATION_COOKIE_NBD | - QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG))) + QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG | + QEMU_MIGRATION_COOKIE_PERSISTENT))) goto cleanup; if (STREQ_NULLABLE(protocol, "rdma") && @@ -3457,6 +3462,9 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, if (flags & VIR_MIGRATE_OFFLINE) goto done; + if (flags & VIR_MIGRATE_PERSIST_DEST) + vm->newDef = qemuMigrationCookieGetPersistent(mig); + if (tunnel && (pipe(dataFD) < 0 || virSetCloseExec(dataFD[1]) < 0)) { virReportSystemError(errno, "%s", @@ -3585,7 +3593,10 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, } virDomainObjEndAPI(&vm); qemuDomainEventQueue(driver, event); - qemuMigrationCookieFree(mig); + if (mig) { + virDomainDefFree(qemuMigrationCookieGetPersistent(mig)); + qemuMigrationCookieFree(mig); + } virObjectUnref(caps); virNWFilterUnlockFilterUpdates(); return ret; @@ -4546,8 +4557,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_STATS; - if (flags & VIR_MIGRATE_PERSIST_DEST) - cookieFlags |= QEMU_MIGRATION_COOKIE_PERSISTENT; + if (ret == 0 && qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, cookieFlags) < 0) { @@ -5664,13 +5674,11 @@ qemuMigrationVPAssociatePortProfiles(virDomainDefPtr def) static int qemuMigrationPersist(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuMigrationCookiePtr mig, bool ignoreSaveError) { virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virCapsPtr caps = NULL; virDomainDefPtr vmdef; - virDomainDefPtr oldDef = NULL; unsigned int oldPersist = vm->persistent; virObjectEventPtr event; int ret = -1; @@ -5679,8 +5687,6 @@ qemuMigrationPersist(virQEMUDriverPtr driver, goto cleanup; vm->persistent = 1; - oldDef = vm->newDef; - vm->newDef = qemuMigrationCookieGetPersistent(mig); if (!(vmdef = virDomainObjGetPersistentDef(caps, driver->xmlopt, vm))) goto error; @@ -5699,7 +5705,6 @@ qemuMigrationPersist(virQEMUDriverPtr driver, ret = 0; cleanup: - virDomainDefFree(oldDef); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -5707,8 +5712,6 @@ qemuMigrationPersist(virQEMUDriverPtr driver, error: virDomainDefFree(vm->newDef); vm->persistent = oldPersist; - vm->newDef = oldDef; - oldDef = NULL; goto cleanup; } @@ -5762,8 +5765,6 @@ qemuMigrationFinish(virQEMUDriverPtr driver, cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_STATS | QEMU_MIGRATION_COOKIE_NBD; - if (flags & VIR_MIGRATE_PERSIST_DEST) - cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT; if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, cookie_flags))) @@ -5771,7 +5772,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver, if (flags & VIR_MIGRATE_OFFLINE) { if (retcode == 0 && - qemuMigrationPersist(driver, vm, mig, false) == 0) + qemuMigrationPersist(driver, vm, false) == 0) dom = virGetDomain(dconn, vm->def->name, vm->def->uuid); goto endjob; } @@ -5819,7 +5820,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver, if (flags & VIR_MIGRATE_PERSIST_DEST) { - if (qemuMigrationPersist(driver, vm, mig, !v3proto) < 0) { + if (qemuMigrationPersist(driver, vm, !v3proto) < 0) { /* Hmpf. Migration was successful, but making it persistent * was not. If we report successful, then when this domain * shuts down, management tools are in for a surprise. On the -- 1.8.3.1

On Thu, Mar 10, 2016 at 11:59:29 +0300, Dmitry Andreev wrote:
Migration API allows to specify a destination domain XML. If no XML was specified the source one is used.
Offline domain has only inactive XML and it is replaced by specified destination XML.
Live migration allows to persist domain on a destination host. In this case both inactive and active XML should be replaced with specified XML. The problem is that specified XML only replaces an active one.
https://bugzilla.redhat.com/show_bug.cgi?id=835300
This commit adds a migration cookie with specified destination XML at a migration beginning phase and sets this XML to destination domain on the next step.
This is not the right way to fix the issue. Currently, we send persistent definition at the end of the Perform phase and Finish processes it at the destination. If you change this, migration between old and new libvirt (in any combination) will be broken. The patch should really only change what XML is passed to the other host. And perhaps we may need to introduce another parameter so that the persistent XML can be specified separately. I can imagine a valid case when one wants to keep the persistent XML in sync with the source host even when passing a custom active XML to the migration API. Jirka
participants (2)
-
Dmitry Andreev
-
Jiri Denemark