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