]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Properly reset migration params when libvirtd restarts
authorJiri Denemark <jdenemar@redhat.com>
Tue, 13 Mar 2018 15:08:49 +0000 (16:08 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 17 Apr 2018 08:46:23 +0000 (10:46 +0200)
To be able to restore all migration parameters when libvirtd is
restarting during an active migration job, we need to store the original
values of all parameters (stored in priv->job.migParams) in the status
XML.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_domain.c
src/qemu/qemu_migration_params.c
src/qemu/qemu_migration_params.h

index 3d2520d4526ef5fbb1b8c8f11451d487b1b0c511..ce810607fcf1bac6f15cdc86d23cb1824876d516 100644 (file)
@@ -32,6 +32,7 @@
 #include "qemu_parse_command.h"
 #include "qemu_capabilities.h"
 #include "qemu_migration.h"
+#include "qemu_migration_params.h"
 #include "qemu_security.h"
 #include "viralloc.h"
 #include "virlog.h"
@@ -2099,6 +2100,9 @@ qemuDomainObjPrivateXMLFormatJob(virBufferPtr buf,
         }
     }
 
+    if (priv->job.migParams)
+        qemuMigrationParamsFormat(&childBuf, priv->job.migParams);
+
     return virXMLFormatElement(buf, "job", &attrBuf, &childBuf);
 }
 
@@ -2398,6 +2402,9 @@ qemuDomainObjPrivateXMLParseJob(virDomainObjPtr vm,
     }
     VIR_FREE(nodes);
 
+    if (qemuMigrationParamsParse(ctxt, &priv->job.migParams) < 0)
+        goto cleanup;
+
     ret = 0;
 
  cleanup:
index 78ded83ee9283e9569a8b04580be319a0cffb345..8af6d8ad0e2b2d15a63149f20feb10ab4c7bd0bd 100644 (file)
@@ -1103,6 +1103,151 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver,
 }
 
 
+void
+qemuMigrationParamsFormat(virBufferPtr buf,
+                          qemuMigrationParamsPtr migParams)
+{
+    qemuMigrationParamValuePtr pv;
+    size_t i;
+
+    virBufferAddLit(buf, "<migParams>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < QEMU_MIGRATION_PARAM_LAST; i++) {
+        pv = &migParams->params[i];
+
+        if (!pv->set)
+            continue;
+
+        virBufferAsprintf(buf, "<param name='%s' ",
+                          qemuMigrationParamTypeToString(i));
+
+        switch (qemuMigrationParamTypes[i]) {
+        case QEMU_MIGRATION_PARAM_TYPE_INT:
+            virBufferAsprintf(buf, "value='%d'", pv->value.i);
+            break;
+
+        case QEMU_MIGRATION_PARAM_TYPE_ULL:
+            virBufferAsprintf(buf, "value='%llu'", pv->value.ull);
+            break;
+
+        case QEMU_MIGRATION_PARAM_TYPE_BOOL:
+            virBufferAsprintf(buf, "value='%s'", pv->value.b ? "yes" : "no");
+            break;
+
+        case QEMU_MIGRATION_PARAM_TYPE_STRING:
+            virBufferEscapeString(buf, "value='%s'", pv->value.s);
+            break;
+        }
+
+        virBufferAddLit(buf, "/>\n");
+    }
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</migParams>\n");
+}
+
+
+int
+qemuMigrationParamsParse(xmlXPathContextPtr ctxt,
+                         qemuMigrationParamsPtr *migParams)
+{
+    qemuMigrationParamsPtr params = NULL;
+    qemuMigrationParamValuePtr pv;
+    xmlNodePtr *nodes = NULL;
+    char *name = NULL;
+    char *value = NULL;
+    int param;
+    size_t i;
+    int rc;
+    int n;
+    int ret = -1;
+
+    *migParams = NULL;
+
+    if ((rc = virXPathBoolean("boolean(./migParams)", ctxt)) < 0)
+        goto cleanup;
+
+    if (rc == 0) {
+        ret = 0;
+        goto cleanup;
+    }
+
+    if ((n = virXPathNodeSet("./migParams[1]/param", ctxt, &nodes)) < 0)
+        return -1;
+
+    if (!(params = qemuMigrationParamsNew()))
+        goto cleanup;
+
+    for (i = 0; i < n; i++) {
+        if (!(name = virXMLPropString(nodes[i], "name"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("missing migration parameter name"));
+            goto cleanup;
+        }
+
+        if ((param = qemuMigrationParamTypeFromString(name)) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unknown migration parameter '%s'"), name);
+            goto cleanup;
+        }
+        pv = &params->params[param];
+
+        if (!(value = virXMLPropString(nodes[i], "value"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("missing value for migration parameter '%s'"),
+                           name);
+            goto cleanup;
+        }
+
+        rc = 0;
+        switch (qemuMigrationParamTypes[param]) {
+        case QEMU_MIGRATION_PARAM_TYPE_INT:
+            rc = virStrToLong_i(value, NULL, 10, &pv->value.i);
+            break;
+
+        case QEMU_MIGRATION_PARAM_TYPE_ULL:
+            rc = virStrToLong_ullp(value, NULL, 10, &pv->value.ull);
+            break;
+
+        case QEMU_MIGRATION_PARAM_TYPE_BOOL:
+            if (STREQ(value, "yes"))
+                pv->value.b = true;
+            else if (STREQ(value, "no"))
+                pv->value.b = false;
+            else
+                rc = -1;
+            break;
+
+        case QEMU_MIGRATION_PARAM_TYPE_STRING:
+            VIR_STEAL_PTR(pv->value.s, value);
+            break;
+        }
+
+        if (rc < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("invalid value '%s' for migration parameter '%s'"),
+                           value, name);
+            goto cleanup;
+        }
+
+        pv->set = true;
+        VIR_FREE(name);
+        VIR_FREE(value);
+    }
+
+    VIR_STEAL_PTR(*migParams, params);
+    ret = 0;
+
+ cleanup:
+    qemuMigrationParamsFree(params);
+    VIR_FREE(nodes);
+    VIR_FREE(name);
+    VIR_FREE(value);
+    return ret;
+}
+
+
 int
 qemuMigrationCapsCheck(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
index 6950eca8ef207df051d926df3a656bee78aedd0d..99dde0ad3cddfe0ff6208eedaa340170ee4eb1be 100644 (file)
@@ -24,6 +24,8 @@
 
 # include "internal.h"
 
+# include "virbuffer.h"
+# include "virxml.h"
 # include "qemu_monitor.h"
 # include "qemu_conf.h"
 
@@ -133,6 +135,14 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver,
                          int asyncJob,
                          qemuMigrationParamsPtr origParams);
 
+void
+qemuMigrationParamsFormat(virBufferPtr buf,
+                          qemuMigrationParamsPtr migParams);
+
+int
+qemuMigrationParamsParse(xmlXPathContextPtr ctxt,
+                         qemuMigrationParamsPtr *migParams);
+
 int
 qemuMigrationCapsCheck(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,