Re: [libvirt] [PATCH 7/8] virsh: implement new command to support perf

2016-01-28 Thread Daniel P. Berrange
On Thu, Dec 10, 2015 at 08:34:37PM +0800, Qiaowei Ren wrote:
> This patch add new perf command to enable/disable perf event
> for a guest domain.
> 
> Signed-off-by: Qiaowei Ren 
> ---
>  tools/virsh-domain.c | 128 
> +++
>  tools/virsh.pod  |  20 
>  2 files changed, 148 insertions(+)

ACK


Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 7/8] virsh: implement new command to support perf

2015-12-13 Thread Qiaowei Ren
This patch add new perf command to enable/disable perf event
for a guest domain.

Signed-off-by: Qiaowei Ren 
---
 tools/virsh-domain.c | 128 +++
 tools/virsh.pod  |  20 
 2 files changed, 148 insertions(+)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index b7e7606..cef68f5 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -,6 +,128 @@ 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 ")
+},
+{.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 = "enable",
+ .type = VSH_OT_STRING,
+ .help = N_("perf events which will be enabled")
+},
+{.name = "disable",
+ .type = VSH_OT_STRING,
+ .help = N_("perf events which will be disabled")
+},
+{.name = NULL}
+};
+
+static int
+virshParseEventStr(vshControl *ctl,
+   const char *event,
+   bool state,
+   virTypedParameterPtr *params,
+   int *nparams,
+   int *maxparams)
+{
+char **tok = NULL;
+size_t i, ntok;
+int ret = -1;
+
+if (!(tok = virStringSplitCount(event, "|", 0, )))
+return -1;
+
+if (ntok > VIR_PERF_EVENT_LAST) {
+vshError(ctl, _("event string '%s' has too many fields"), event);
+goto cleanup;
+}
+
+for(i = 0; i < ntok; i++) {
+if ((*tok[i] != '\0') &&
+virTypedParamsAddBoolean(params, nparams,
+ maxparams, tok[i], state) < 0)
+goto cleanup;
+}
+
+ret = 0;
+ cleanup:
+virStringFreeList(tok);
+return ret;
+}
+
+static bool
+cmdPerf(vshControl *ctl, const vshCmd *cmd)
+{
+virDomainPtr dom;
+int nparams = 0;
+int maxparams = 0;
+size_t i;
+virTypedParameterPtr params = NULL;
+bool ret = false;
+const char *enable = NULL, *disable = NULL;
+
+if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
+return false;
+
+if (vshCommandOptStringReq(ctl, cmd, "enable", ) < 0 ||
+vshCommandOptStringReq(ctl, cmd, "disable", ) < 0)
+return false;
+
+if (enable && virshParseEventStr(ctl, enable, true,
+ , , ) < 0)
+goto cleanup;
+
+if (disable && virshParseEventStr(ctl, disable, false,
+  , , ) < 0)
+   goto cleanup;
+
+if (nparams == 0) {
+if (virDomainGetPerfEvents(dom, , ) != 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;
+
+ error:
+vshError(ctl, "%s", _("Unable to enable/disable perf events"));
+goto cleanup;
+}
+
+
+/*
  * "numatune" command
  */
 static const vshCmdInfo info_numatune[] = {
@@ -13406,6 +13528,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 21ae4a3..bfc7e63 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -2113,6 +2113,26 @@ The guaranteed minimum memory allocation for the guest.
 
 Specifying -1 as a value for these limits is interpreted as unlimited.
 
+=item B I [I<--enable> B]
+[I<--disable> B]
+
+Get the current perf events setting or enable/disable specific perf
+event for a guest domain.
+
+Perf is a performance analyzing tool in Linux, and it can instrument
+CPU performance counters, tracepoints, kprobes, and uprobes (dynamic
+tracing). Perf supports a list of measurable events, and can measure
+events coming from different sources. For instance, some event are
+pure kernel counters, in this case they are called software events,
+including