[libvirt] [PATCH v2 63/73] qemu: Properly reset migration params when libvirtd restarts

Jiri Denemark jdenemar at redhat.com
Wed Apr 11 14:41:53 UTC 2018


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 at redhat.com>
---
 src/qemu/qemu_domain.c           |   7 ++
 src/qemu/qemu_migration_params.c | 145 +++++++++++++++++++++++++++++++
 src/qemu/qemu_migration_params.h |  10 +++
 3 files changed, 162 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 03ad8d35c0..e3f58e45cb 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -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:
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index 78ded83ee9..8af6d8ad0e 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -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,
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index 6950eca8ef..99dde0ad3c 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -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,
-- 
2.17.0




More information about the libvir-list mailing list