mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
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:
parent
a1db79fd73
commit
923565aa7e
@ -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:
|
||||
|
@ -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 = ¶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,
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user