diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cbd520b52c..c80f1dae36 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10054,9 +10054,12 @@ qemuDomainSetPerfEvents(virDomainPtr dom, virPerfEventType type; bool enabled; - virCheckFlags(0, -1); + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); - if (virTypedParamsValidate(params, nparams, VIR_PERF_PARAMETERS) < 0) + if (virTypedParamsValidate(params, nparams, + VIR_PERF_PARAM_CMT, VIR_TYPED_PARAM_BOOLEAN, + NULL) < 0) return -1; if (!(vm = qemuDomObjFromDomain(dom))) @@ -10071,31 +10074,37 @@ qemuDomainSetPerfEvents(virDomainPtr dom, if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0) goto cleanup; - for (i = 0; i < nparams; i++) { - virTypedParameterPtr param = ¶ms[i]; - enabled = params->value.b; - type = virPerfEventTypeFromString(param->field); + if (def) { + for (i = 0; i < nparams; i++) { + virTypedParameterPtr param = ¶ms[i]; + enabled = params->value.b; + type = virPerfEventTypeFromString(param->field); - if (!enabled && virPerfEventDisable(priv->perf, type)) - goto cleanup; - if (enabled && virPerfEventEnable(priv->perf, type, vm->pid)) - goto cleanup; + if (!enabled && virPerfEventDisable(priv->perf, type)) + 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) { + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) + goto cleanup; + } + + if (persistentDef) { + for (i = 0; i < nparams; i++) { + virTypedParameterPtr param = ¶ms[i]; + enabled = params->value.b; + type = virPerfEventTypeFromString(param->field); + persistentDef->perf->events[type] = enabled ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO; - - if (virDomainSaveConfig(cfg->configDir, driver->caps, persistentDef) < 0) - goto cleanup; } + + if (virDomainSaveConfig(cfg->configDir, driver->caps, persistentDef) < 0) + goto cleanup; } ret = 0; @@ -10112,39 +10121,53 @@ qemuDomainGetPerfEvents(virDomainPtr dom, int *nparams, unsigned int flags) { - size_t i; virDomainObjPtr vm = NULL; qemuDomainObjPrivatePtr priv; - int ret = -1; + virDomainDefPtr def; virTypedParameterPtr par = NULL; int maxpar = 0; int npar = 0; + size_t i; + int ret = -1; - virCheckFlags(0, -1); + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG | + VIR_TYPED_PARAM_STRING_OKAY, -1); if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; - priv = vm->privateData; - if (virDomainGetPerfEventsEnsureACL(dom->conn, vm->def) < 0) goto cleanup; + if (!(def = virDomainObjGetOneDef(vm, flags))) + goto cleanup; + + priv = vm->privateData; + for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { + bool perf_enabled; + + if (flags & VIR_DOMAIN_AFFECT_CONFIG) + perf_enabled = def->perf->events[i] == VIR_TRISTATE_BOOL_YES; + else + perf_enabled = virPerfEventIsEnabled(priv->perf, i); + if (virTypedParamsAddBoolean(&par, &npar, &maxpar, virPerfEventTypeToString(i), - virPerfEventIsEnabled(priv->perf, i)) < 0) { - virTypedParamsFree(par, npar); + perf_enabled) < 0) goto cleanup; - } } *params = par; *nparams = npar; + par = NULL; + npar = 0; ret = 0; cleanup: virDomainObjEndAPI(&vm); + virTypedParamsFree(par, npar); return ret; } diff --git a/src/util/virperf.h b/src/util/virperf.h index 4c36b78f3d..8ec87530b9 100644 --- a/src/util/virperf.h +++ b/src/util/virperf.h @@ -32,10 +32,6 @@ typedef enum { VIR_ENUM_DECL(virPerfEvent); -# define VIR_PERF_PARAMETERS \ - VIR_PERF_PARAM_CMT, VIR_TYPED_PARAM_BOOLEAN, \ - NULL - struct virPerf; typedef struct virPerf *virPerfPtr; diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index f3aa1bb592..d0d2dd08d9 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -8560,6 +8560,9 @@ static const vshCmdOptDef opts_perf[] = { .type = VSH_OT_STRING, .help = N_("perf events which will be disabled") }, + VIRSH_COMMON_OPT_DOMAIN_CONFIG, + VIRSH_COMMON_OPT_DOMAIN_LIVE, + VIRSH_COMMON_OPT_DOMAIN_CURRENT, {.name = NULL} }; @@ -8601,6 +8604,17 @@ cmdPerf(vshControl *ctl, const vshCmd *cmd) bool ret = false; const char *enable = NULL, *disable = NULL; unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT; + bool current = vshCommandOptBool(cmd, "current"); + bool config = vshCommandOptBool(cmd, "config"); + bool live = vshCommandOptBool(cmd, "live"); + + VSH_EXCLUSIVE_OPTIONS_VAR(current, live); + VSH_EXCLUSIVE_OPTIONS_VAR(current, config); + + if (config) + flags |= VIR_DOMAIN_AFFECT_CONFIG; + if (live) + flags |= VIR_DOMAIN_AFFECT_LIVE; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; diff --git a/tools/virsh.pod b/tools/virsh.pod index a9915b09f4..d2cc5b2946 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2146,6 +2146,7 @@ Specifying -1 as a value for these limits is interpreted as unlimited. =item B I [I<--enable> B] [I<--disable> B] +[[I<--config>] [I<--live>] | [I<--current>]] Get the current perf events setting or enable/disable specific perf events for a guest domain. @@ -2165,6 +2166,13 @@ separated by commas. However, just "cmt" event is supported presently. CMT is a PQos (Platform Qos) feature to monitor the usage of cache by applications running on the platform. +If I<--live> is specified, affect a running guest. +If I<--config> is specified, affect the next boot of a persistent guest. +If I<--current> is specified, affect the current guest state. +Both I<--live> and I<--config> flags may be given, but I<--current> is +exclusive. If no flag is specified, behavior is different depending +on hypervisor. + =item B I [I<--weight> B] [I<--device-weights> B] [I<--device-read-iops-sec> B]