Now that we have @flags we can support changing perf events just
in active or inactive configuration regardless of the other.
Previously, calling virDomainSetPerfEvents set events in both
active and inactive configuration at once. Even though we allow
users to set perf events that are to be enabled once domain is
started up. The virDomainGetPerfEvents API was flawed too. It
returned just runtime info.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 76 +++++++++++++++++++++++++++++++++++---------------
tools/virsh-domain.c | 14 ++++++++++
tools/virsh.pod | 8 ++++++
3 files changed, 75 insertions(+), 23 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index cbd520b..56120ff 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10054,7 +10054,8 @@ 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)
return -1;
@@ -10071,31 +10072,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,28 +10119,50 @@ qemuDomainGetPerfEvents(virDomainPtr dom,
int *nparams,
unsigned int flags)
{
- size_t i;
+ virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm = NULL;
qemuDomainObjPrivatePtr priv;
- int ret = -1;
+ virDomainDefPtr persistentDef;
virTypedParameterPtr par = NULL;
+ virCapsPtr caps = 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);
+
+ /* We don't return strings, and thus trivially support this flag. */
+ flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup;
- priv = vm->privateData;
-
if (virDomainGetPerfEventsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
+ if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt, vm, &flags,
+ &persistentDef) < 0)
+ 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 = persistentDef->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) {
+ perf_enabled) < 0) {
virTypedParamsFree(par, npar);
goto cleanup;
}
@@ -10145,6 +10174,7 @@ qemuDomainGetPerfEvents(virDomainPtr dom,
cleanup:
virDomainObjEndAPI(&vm);
+ virObjectUnref(caps);
return ret;
}
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 2dbb890..5865308 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}
};
@@ -8607,6 +8610,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 a9915b0..d2cc5b2 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<perf> I<domain> [I<--enable> B<eventSpec>]
[I<--disable> B<eventSpec>]
+[[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<blkiotune> I<domain> [I<--weight> B<weight>]
[I<--device-weights> B<device-weights>]
[I<--device-read-iops-sec> B<device-read-iops-sec>]
--
2.7.3