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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list