[libvirt] [PATCH] qemu: Transfer inactive XML among cookie

Michal Privoznik mprivozn at redhat.com
Thu Sep 15 14:04:03 UTC 2011


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.
---
 src/qemu/qemu_migration.c |   91 ++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index d9f8d93..bc98708 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -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)
@@ -354,10 +379,12 @@ static void qemuMigrationCookieGraphicsXMLFormat(virBufferPtr buf,
 
 
 static void qemuMigrationCookieXMLFormat(virBufferPtr buf,
-                                         qemuMigrationCookiePtr mig)
+                                         qemuMigrationCookiePtr mig,
+                                         struct qemud_driver *driver)
 {
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     char hostuuidstr[VIR_UUID_STRING_BUFLEN];
+    char *domXML;
     int i;
 
     virUUIDFormat(mig->uuid, uuidstr);
@@ -388,15 +415,25 @@ static void qemuMigrationCookieXMLFormat(virBufferPtr buf,
         virBufferAddLit(buf, "  </lockstate>\n");
     }
 
+    if ((mig->flags & QEMU_MIGRATION_COOKIE_PERSISTENT) &&
+        mig->persistent) {
+        domXML = qemuDomainDefFormatXML(driver, mig->persistent,
+                                        VIR_DOMAIN_XML_INACTIVE |
+                                        VIR_DOMAIN_XML_SECURE);
+        virBufferAdd(buf, domXML, -1);
+        VIR_FREE(domXML);
+    }
+
     virBufferAddLit(buf, "</qemu-migration>\n");
 }
 
 
-static char *qemuMigrationCookieXMLFormatStr(qemuMigrationCookiePtr mig)
+static char *qemuMigrationCookieXMLFormatStr(qemuMigrationCookiePtr mig,
+                                             struct qemud_driver *driver)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    qemuMigrationCookieXMLFormat(&buf, mig);
+    qemuMigrationCookieXMLFormat(&buf, mig, driver);
 
     if (virBufferError(&buf)) {
         virReportOOMError();
@@ -460,6 +497,8 @@ error:
 
 static int
 qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
+                            struct qemud_driver *driver,
+                            xmlDocPtr doc,
                             xmlXPathContextPtr ctxt,
                             unsigned int flags)
 {
@@ -583,6 +622,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 +652,7 @@ error:
 
 static int
 qemuMigrationCookieXMLParseStr(qemuMigrationCookiePtr mig,
+                               struct qemud_driver *driver,
                                const char *xml,
                                unsigned int flags)
 {
@@ -606,7 +665,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,7 +696,11 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
         qemuMigrationCookieAddLockstate(mig, driver, dom) < 0)
         return -1;
 
-    if (!(*cookieout = qemuMigrationCookieXMLFormatStr(mig)))
+    if (flags & QEMU_MIGRATION_COOKIE_PERSISTENT &&
+        qemuMigrationCookieAddPersistent(mig, dom) < 0)
+        return -1;
+
+    if (!(*cookieout = qemuMigrationCookieXMLFormatStr(mig, driver)))
         return -1;
 
     *cookieoutlen = strlen(*cookieout) + 1;
@@ -672,6 +735,7 @@ qemuMigrationEatCookie(struct qemud_driver *driver,
 
     if (cookiein && cookieinlen &&
         qemuMigrationCookieXMLParseStr(mig,
+                                       driver,
                                        cookiein,
                                        flags) < 0)
         goto error;
@@ -1575,7 +1639,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 +2542,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 +2556,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 +2580,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
-- 
1.7.3.4




More information about the libvir-list mailing list