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 <jdene...@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 55b88e35e0..cef08343ea 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 6f3555bc63..dd2a91cac3 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -985,3 +985,148 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver,
         virFreeError(err);
     }
 }
+
+
+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' ",
+                          qemuMigrationParamTypeList[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;
+}
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index 1540d72acb..8116f3f59f 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"
 
@@ -116,4 +118,12 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver,
                          int asyncJob,
                          qemuMigrationParamsPtr origParams);
 
+void
+qemuMigrationParamsFormat(virBufferPtr buf,
+                          qemuMigrationParamsPtr migParams);
+
+int
+qemuMigrationParamsParse(xmlXPathContextPtr ctxt,
+                         qemuMigrationParamsPtr *migParams);
+
 #endif /* __QEMU_MIGRATION_PARAMS_H__ */
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to