qemu: Properly reset migration params when libvirtd restarts

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Jiri Denemark 2018-03-13 16:08:49 +01:00
parent a1db79fd73
commit 923565aa7e
3 changed files with 162 additions and 0 deletions

View File

@ -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:

View File

@ -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,

View File

@ -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,