qemu: Transfer inactive XML among cookie

If a domain has inactive XML we want to transfer it to destination
when migrating with VIR_MIGRATE_PERSIST_DEST. In order to harm
the migration protocol as least as possible, a optional cookie was
chosen.
This commit is contained in:
Michal Privoznik 2011-09-15 15:13:11 +02:00
parent 508de7eedb
commit c42e1c3947

View File

@ -64,6 +64,7 @@ VIR_ENUM_IMPL(qemuMigrationJobPhase, QEMU_MIGRATION_PHASE_LAST,
enum qemuMigrationCookieFlags {
QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS,
QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
QEMU_MIGRATION_COOKIE_FLAG_LAST
};
@ -71,11 +72,12 @@ enum qemuMigrationCookieFlags {
VIR_ENUM_DECL(qemuMigrationCookieFlag);
VIR_ENUM_IMPL(qemuMigrationCookieFlag,
QEMU_MIGRATION_COOKIE_FLAG_LAST,
"graphics", "lockstate");
"graphics", "lockstate", "persistent");
enum qemuMigrationCookieFeatures {
QEMU_MIGRATION_COOKIE_GRAPHICS = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
QEMU_MIGRATION_COOKIE_LOCKSTATE = (1 << QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE),
QEMU_MIGRATION_COOKIE_PERSISTENT = (1 << QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT),
};
typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
@ -110,6 +112,9 @@ struct _qemuMigrationCookie {
/* If (flags & QEMU_MIGRATION_COOKIE_GRAPHICS) */
qemuMigrationCookieGraphicsPtr graphics;
/* If (flags & QEMU_MIGRATION_COOKIE_PERSISTENT) */
virDomainDefPtr persistent;
};
static void qemuMigrationCookieGraphicsFree(qemuMigrationCookieGraphicsPtr grap)
@ -334,6 +339,26 @@ qemuMigrationCookieAddLockstate(qemuMigrationCookiePtr mig,
}
static int
qemuMigrationCookieAddPersistent(qemuMigrationCookiePtr mig,
virDomainObjPtr dom)
{
if (mig->flags & QEMU_MIGRATION_COOKIE_PERSISTENT) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Migration persistent data already present"));
return -1;
}
if (!dom->newDef)
return 0;
mig->persistent = dom->newDef;
mig->flags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
mig->flagsMandatory |= QEMU_MIGRATION_COOKIE_PERSISTENT;
return 0;
}
static void qemuMigrationCookieGraphicsXMLFormat(virBufferPtr buf,
qemuMigrationCookieGraphicsPtr grap)
@ -358,6 +383,7 @@ static void qemuMigrationCookieXMLFormat(virBufferPtr buf,
{
char uuidstr[VIR_UUID_STRING_BUFLEN];
char hostuuidstr[VIR_UUID_STRING_BUFLEN];
char *domXML;
int i;
virUUIDFormat(mig->uuid, uuidstr);
@ -388,6 +414,15 @@ static void qemuMigrationCookieXMLFormat(virBufferPtr buf,
virBufferAddLit(buf, " </lockstate>\n");
}
if ((mig->flags & QEMU_MIGRATION_COOKIE_PERSISTENT) &&
mig->persistent) {
domXML = virDomainDefFormat(mig->persistent,
VIR_DOMAIN_XML_INACTIVE |
VIR_DOMAIN_XML_SECURE);
virBufferAdd(buf, domXML, -1);
VIR_FREE(domXML);
}
virBufferAddLit(buf, "</qemu-migration>\n");
}
@ -460,6 +495,8 @@ error:
static int
qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
struct qemud_driver *driver,
xmlDocPtr doc,
xmlXPathContextPtr ctxt,
unsigned int flags)
{
@ -583,6 +620,25 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
VIR_FREE(mig->lockState);
}
if ((flags & QEMU_MIGRATION_COOKIE_PERSISTENT) &&
virXPathBoolean("count(./domain) > 0", ctxt)) {
if ((n = virXPathNodeSet("./domain", ctxt, &nodes)) > 1) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Too many domain elements in "
"migration cookie: %d"),
n);
goto error;
}
mig->persistent = virDomainDefParseNode(driver->caps, doc, nodes[0],
-1, VIR_DOMAIN_XML_INACTIVE);
if (!mig->persistent) {
/* virDomainDefParseNode already reported
* an error for us */
goto error;
}
VIR_FREE(nodes);
}
return 0;
error:
@ -594,6 +650,7 @@ error:
static int
qemuMigrationCookieXMLParseStr(qemuMigrationCookiePtr mig,
struct qemud_driver *driver,
const char *xml,
unsigned int flags)
{
@ -606,7 +663,7 @@ qemuMigrationCookieXMLParseStr(qemuMigrationCookiePtr mig,
if (!(doc = virXMLParseStringCtxt(xml, _("(qemu_migration_cookie)"), &ctxt)))
goto cleanup;
ret = qemuMigrationCookieXMLParse(mig, ctxt, flags);
ret = qemuMigrationCookieXMLParse(mig, driver, doc, ctxt, flags);
cleanup:
xmlXPathFreeContext(ctxt);
@ -637,6 +694,10 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
qemuMigrationCookieAddLockstate(mig, driver, dom) < 0)
return -1;
if (flags & QEMU_MIGRATION_COOKIE_PERSISTENT &&
qemuMigrationCookieAddPersistent(mig, dom) < 0)
return -1;
if (!(*cookieout = qemuMigrationCookieXMLFormatStr(mig)))
return -1;
@ -672,6 +733,7 @@ qemuMigrationEatCookie(struct qemud_driver *driver,
if (cookiein && cookieinlen &&
qemuMigrationCookieXMLParseStr(mig,
driver,
cookiein,
flags) < 0)
goto error;
@ -1575,7 +1637,8 @@ cleanup:
}
if (ret == 0 &&
qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, 0) < 0)
qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen,
QEMU_MIGRATION_COOKIE_PERSISTENT ) < 0)
VIR_WARN("Unable to encode migration cookie");
qemuMigrationCookieFree(mig);
@ -2477,6 +2540,7 @@ qemuMigrationFinish(struct qemud_driver *driver,
int newVM = 1;
qemuMigrationCookiePtr mig = NULL;
virErrorPtr orig_err = NULL;
int cookie_flags = 0;
VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, flags=%lx, retcode=%d",
@ -2490,7 +2554,11 @@ qemuMigrationFinish(struct qemud_driver *driver,
v3proto ? QEMU_MIGRATION_PHASE_FINISH3
: QEMU_MIGRATION_PHASE_FINISH2);
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, 0)))
if (flags & VIR_MIGRATE_PERSIST_DEST)
cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein,
cookieinlen, cookie_flags)))
goto endjob;
/* Did the migration go as planned? If yes, return the domain
@ -2510,7 +2578,10 @@ qemuMigrationFinish(struct qemud_driver *driver,
if (vm->persistent)
newVM = 0;
vm->persistent = 1;
vmdef = virDomainObjGetPersistentDef(driver->caps, vm);
if (mig->persistent)
vm->newDef = vmdef = mig->persistent;
else
vmdef = virDomainObjGetPersistentDef(driver->caps, vm);
if (virDomainSaveConfig(driver->configDir, vmdef) < 0) {
/* Hmpf. Migration was successful, but making it persistent
* was not. If we report successful, then when this domain