VIR_FREE(def->keywrap);
+ VIR_FREE(def->perf);
+
if (def->namespaceData && def->ns.free)
(def->ns.free)(def->namespaceData);
}
+static int
+virDomainPerfEventDefParseXML(virDomainPerfDefPtr perf,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt)
+{
+ char *name = NULL;
+ char *enabled = NULL;
+ int enabled_type;
+ int name_type;
+ 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"));
+ goto cleanup;
+ }
+
+ if ((name_type = virPerfEventTypeFromString(name)) < 0) {
+ virReportError(VIR_ERR_CONF_SYNTAX,
+ _("%s is not a supported event name"), name);
+ goto cleanup;
+ }
+
+ if (!(enabled = virXPathString("string(./@enabled)", ctxt))) {
+ virReportError(VIR_ERR_CONF_SYNTAX,
+ _("missing state for cipher named %s"), name);
+ goto cleanup;
+ }
+
+ if ((enabled_type = virTristateBoolTypeFromString(enabled)) < 0) {
+ virReportError(VIR_ERR_CONF_SYNTAX,
+ _("%s is not a supported enabled state"), enabled);
+ 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));
+
+ goto cleanup;
+ }
+ perf->events[VIR_PERF_EVENT_CMT] = enabled_type;
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(name);
+ VIR_FREE(enabled);
+ ctxt->node = oldnode;
+ return ret;
+}
+
+static int
+virDomainPerfDefParseXML(virDomainDefPtr def,
+ xmlXPathContextPtr ctxt)
+{
+ size_t i;
+ int ret = -1;
+ xmlNodePtr *nodes = NULL;
+ int n;
+
+ if ((n = virXPathNodeSet("./perf/event", ctxt, &nodes)) < 0)
+ return n;
+
+ if (VIR_ALLOC(def->perf) < 0)
+ goto cleanup;
+
+ for (i = 0; i < n; i++) {
+ if (virDomainPerfEventDefParseXML(def->perf, nodes[i], ctxt) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ if (ret < 0)
+ VIR_FREE(def->perf);
+ VIR_FREE(nodes);
+ return ret;
+}
+
static int
virDomainMemorySourceDefParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
&def->pm.s4) < 0)
goto error;
+ if (virDomainPerfDefParseXML(def, ctxt) < 0)
+ goto error;
+
if ((tmp = virXPathString("string(./clock/@offset)", ctxt)) &&
(def->clock.offset = virDomainClockOffsetTypeFromString(tmp)) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
virBufferAddLit(buf, "</keywrap>\n");
}
+static void
+virDomainPerfDefFormat(virBufferPtr buf, virDomainPerfDefPtr perf)
+{
+ size_t i;
+ bool wantPerf = false;
+
+ for (i = 0; i < VIR_PERF_EVENT_LAST; i++) {
+ if (perf->events[i])
+ wantPerf = true;
+ }
+ if (!wantPerf)
+ return;
+
+ virBufferAddLit(buf, "<perf>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ for (i = 0; i < VIR_PERF_EVENT_LAST; i++) {
+ if (perf->events[i])
+ virBufferAsprintf(buf, "<event name='%s' enabled='%s'/>\n",
+ virPerfEventTypeToString(i),
+ virTristateBoolTypeToString(perf->events[i]));
+ }
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</perf>\n");
+}
+
static bool
virDomainDefHasCapabilitiesFeatures(virDomainDefPtr def)
{
virBufferAddLit(buf, "</pm>\n");
}
+ if (def->perf)
+ virDomainPerfDefFormat(buf, def->perf);
+
virBufferAddLit(buf, "<devices>\n");
virBufferAdjustIndent(buf, 2);
# include "virseclabel.h"
# include "virprocess.h"
# include "virgic.h"
+# include "virperf.h"
/* forward declarations of all device types, required by
* virDomainDeviceDef
int s4;
};
+typedef struct _virDomainPerfDef virDomainPerfDef;
+typedef virDomainPerfDef *virDomainPerfDefPtr;
+struct _virDomainPerfDef {
+ /* These options are of type enum virTristateBool */
+ int events[VIR_PERF_EVENT_LAST];
+};
+
typedef struct _virDomainKeyWrapDef virDomainKeyWrapDef;
typedef virDomainKeyWrapDef *virDomainKeyWrapDefPtr;
struct _virDomainKeyWrapDef {
virDomainPowerManagement pm;
+ virDomainPerfDefPtr perf;
+
virDomainOSDef os;
char *emulator;
/* These three options are of type virTristateSwitch,
virTypedParameterPtr params,
int nparams)
{
+ virQEMUDriverPtr driver = dom->conn->privateData;
size_t i;
virDomainObjPtr vm = NULL;
+ virQEMUDriverConfigPtr cfg = NULL;
qemuDomainObjPrivatePtr priv;
+ virDomainDefPtr def;
+ virDomainDefPtr persistentDef;
+ unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
int ret = -1;
virPerfEventType type;
bool enabled;
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
+ cfg = virQEMUDriverGetConfig(driver);
priv = vm->privateData;
if (virDomainSetPerfEventsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
+ if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0)
+ goto cleanup;
+
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
enabled = params->value.b;
goto cleanup;
if (enabled && virPerfEventEnable(priv->perf, type, vm->pid))
goto cleanup;
+
+ if (def) {
+ def->perf->events[type] = enabled ?
+ VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
+
+ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
+ goto cleanup;
+ }
+
+ if (persistentDef) {
+ persistentDef->perf->events[type] = enabled ?
+ VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
+
+ if (virDomainSaveConfig(cfg->configDir, driver->caps, persistentDef) < 0)
+ goto cleanup;
+ }
}
ret = 0;
cleanup:
virDomainObjEndAPI(&vm);
+ virObjectUnref(cfg);
return ret;
}