From 923565aa7efcc05764ef6ba4160f334dbd6a614e Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Tue, 13 Mar 2018 16:08:49 +0100 Subject: [PATCH] qemu: Properly reset migration params when libvirtd restarts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Ján Tomko --- 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 3d2520d452..ce810607fc 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, "\n"); + virBufferAdjustIndent(buf, 2); + + for (i = 0; i < QEMU_MIGRATION_PARAM_LAST; i++) { + pv = &migParams->params[i]; + + if (!pv->set) + continue; + + virBufferAsprintf(buf, "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, "\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; +} + + 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, -- GitLab