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(a)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 = ¶ms->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