conf: Fix perf event parser

The parser was totaly broken. Fix it by rewriting it. Add tests so that
it doesn't happen.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1346723
This commit is contained in:
Peter Krempa 2016-06-15 16:33:20 +02:00
parent c22dad33c2
commit 23690e1d74
3 changed files with 43 additions and 28 deletions

View File

@ -13056,57 +13056,48 @@ virDomainPMStateParseXML(xmlXPathContextPtr ctxt,
static int
virDomainPerfEventDefParseXML(virDomainPerfDefPtr perf,
xmlNodePtr node,
xmlXPathContextPtr ctxt)
xmlNodePtr node)
{
char *name = NULL;
char *enabled = NULL;
int enabled_type;
int name_type;
int event;
int ret = -1;
xmlNodePtr oldnode = ctxt->node;
ctxt->node = node;
if (!(name = virXPathString("string(./@name)", ctxt))) {
virReportError(VIR_ERR_CONF_SYNTAX, "%s",
_("missing name for event"));
if (!(name = virXMLPropString(node, "name"))) {
virReportError(VIR_ERR_XML_ERROR, "%s", _("missing perf event name"));
goto cleanup;
}
if ((name_type = virPerfEventTypeFromString(name)) < 0) {
virReportError(VIR_ERR_CONF_SYNTAX,
_("%s is not a supported event name"), name);
if ((event = virPerfEventTypeFromString(name)) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("'unsupported perf event '%s'"), name);
goto cleanup;
}
if (!(enabled = virXPathString("string(./@enabled)", ctxt))) {
virReportError(VIR_ERR_CONF_SYNTAX,
_("missing state for cipher named %s"), name);
if (perf->events[event] != VIR_TRISTATE_BOOL_ABSENT) {
virReportError(VIR_ERR_XML_ERROR,
_("perf event '%s' was already specified"), name);
goto cleanup;
}
if ((enabled_type = virTristateBoolTypeFromString(enabled)) < 0) {
virReportError(VIR_ERR_CONF_SYNTAX,
_("%s is not a supported enabled state"), enabled);
if (!(enabled = virXMLPropString(node, "enabled"))) {
virReportError(VIR_ERR_XML_ERROR,
_("missing state of perf event '%s'"), name);
goto cleanup;
}
if (perf->events[VIR_PERF_EVENT_CMT] != VIR_TRISTATE_BOOL_ABSENT) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("A domain definition can have no more than "
"one event node with name %s"),
virTristateBoolTypeToString(name_type));
if ((perf->events[event] = virTristateBoolTypeFromString(enabled)) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("invalid state '%s' of perf event '%s'"),
enabled, name);
goto cleanup;
}
perf->events[VIR_PERF_EVENT_CMT] = enabled_type;
ret = 0;
cleanup:
VIR_FREE(name);
VIR_FREE(enabled);
ctxt->node = oldnode;
return ret;
}
@ -13126,7 +13117,7 @@ virDomainPerfDefParseXML(virDomainDefPtr def,
goto cleanup;
for (i = 0; i < n; i++) {
if (virDomainPerfEventDefParseXML(def->perf, nodes[i], ctxt) < 0)
if (virDomainPerfEventDefParseXML(def->perf, nodes[i]) < 0)
goto cleanup;
}

View File

@ -0,0 +1,22 @@
<domain type='qemu'>
<name>foo</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<perf>
<event name='cmt' enabled='yes'/>
<event name='mbmt' enabled='no'/>
<event name='mbml' enabled='yes'/>
</perf>
<devices>
</devices>
</domain>

View File

@ -95,6 +95,8 @@ mymain(void)
DO_TEST_FULL("name-slash-parse", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST("perf");
virObjectUnref(caps);
virObjectUnref(xmlopt);