This patch add new perf command to enable/disable perf event for a guest domain. For example: $ virsh perf domain --cmt 1 // enable CMT perf event for domain $ virsh perf domain --cmt 0 // disable CMT perf event for domain $ virsh perf domain // list the state (enabled or disabled) of all supported perf event for domain Signed-off-by: Qiaowei Ren <qiaowei.ren@xxxxxxxxx> --- tools/virsh-domain.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 8 +++ 2 files changed, 147 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index bd00785..e17747e 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -8890,6 +8890,139 @@ cmdMemtune(vshControl *ctl, const vshCmd *cmd) } /* + * "perf" command + */ +static const vshCmdInfo info_perf[] = { + {.name = "help", + .data = N_("Get or set perf event") + }, + {.name = "desc", + .data = N_("Get or set the current perf events for a guest" + " domain.\n" + " To get the perf events list use following command: \n\n" + " virsh # perf <domain>") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_perf[] = { + {.name = "domain", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("domain name, id or uuid") + }, + {.name = "cmt", + .type = VSH_OT_INT, + .help = N_("CMT event, as integer (default 0, disable)") + }, + {.name = NULL} +}; + +static int +virshPerfGetEventEnabled(vshControl *ctl, const vshCmd *cmd, + const char *name, bool *value) +{ + int ret, tmp; + const char *str; + char *end; + + ret = vshCommandOptString(ctl, cmd, name, &str); + if (ret <= 0) + return ret; + if (virStrToLong_i(str, &end, 0, &tmp) < 0) + return -1; + if (tmp == 1) { + *value = true; + ret = 1; + } else if (tmp == 0) { + *value = false; + ret = 1; + } else { + ret = -1; + } + + return ret; +} + +static bool +cmdPerf(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool tmpVal; + int nparams = 0; + int maxparams = 0; + int rc; + size_t i; + virTypedParameterPtr params = NULL; + bool ret = false; + + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + return false; + +#define PARSE_PERF_PARAM(NAME, FIELD) \ + if ((rc = virshPerfGetEventEnabled(ctl, cmd, NAME, &tmpVal)) < 0) { \ + vshError(ctl, _("Unable to parse boolean parameter %s"), NAME); \ + goto cleanup; \ + } \ + if (rc == 1) { \ + if (virTypedParamsAddBoolean(¶ms, &nparams, &maxparams, \ + FIELD, tmpVal) < 0) \ + goto save_error; \ + } \ + + + PARSE_PERF_PARAM("cmt", VIR_DOMAIN_PERF_CMT); + +#undef PARSE_PERF_PARAM + + if (nparams == 0) { + /* get the number of perf events */ + if (virDomainGetPerfEvents(dom, NULL, &nparams) != 0) { + vshError(ctl, "%s", + _("Unable to get number of perf events")); + goto cleanup; + } + + if (nparams == 0) { + /* nothing to output */ + ret = true; + goto cleanup; + } + + params = vshCalloc(ctl, nparams, sizeof(*params)); + if (virDomainGetPerfEvents(dom, params, &nparams) != 0) { + vshError(ctl, "%s", _("Unable to get perf events")); + goto cleanup; + } + for (i = 0; i < nparams; i++) { + if (params[i].type == VIR_TYPED_PARAM_BOOLEAN && + params[i].value.b) { + vshPrint(ctl, "%-15s: %s\n", params[i].field, _("enabled")); + } else { + vshPrint(ctl, "%-15s: %s\n", params[i].field, _("disabled")); + } + } + } else { + if (virDomainSetPerfEvents(dom, params, nparams) != 0) + goto error; + } + + ret = true; + + cleanup: + virTypedParamsFree(params, nparams); + virDomainFree(dom); + return ret; + + save_error: + vshSaveLibvirtError(); + error: + vshError(ctl, "%s", _("Unable to enable/disable perf events")); + goto cleanup; +} + + +/* * "numatune" command */ static const vshCmdInfo info_numatune[] = { @@ -13368,6 +13501,12 @@ const vshCmdDef domManagementCmds[] = { .info = info_memtune, .flags = 0 }, + {.name = "perf", + .handler = cmdPerf, + .opts = opts_perf, + .info = info_perf, + .flags = 0 + }, {.name = "metadata", .handler = cmdMetadata, .opts = opts_metadata, diff --git a/tools/virsh.pod b/tools/virsh.pod index 935d017..c674b58 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2116,6 +2116,14 @@ The guaranteed minimum memory allocation for the guest. Specifying -1 as a value for these limits is interpreted as unlimited. +=item B<perf> I<domain> [I<--cmt> B<enable-disable>] + +Get the current perf events setting or enable/disable specific perf +event for a guest domain. Currently only QEMU/KVM supports I<--cmt>. + +B<enable-disable> may be 0 or 1. 0 means cmt perf event will be +disabled, and 1 means cmt perf event will be enabled. + =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>] -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list