]> xenbits.xensource.com Git - libvirt.git/commitdiff
virsh: implement new command to support perf
authorQiaowei Ren <qiaowei.ren@intel.com>
Mon, 28 Mar 2016 13:30:32 +0000 (21:30 +0800)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 29 Mar 2016 12:13:05 +0000 (13:13 +0100)
This patch add new perf command to enable/disable perf event
for a guest domain.

Signed-off-by: Qiaowei Ren <qiaowei.ren@intel.com>
Message-id: 1459171833-26416-8-git-send-email-qiaowei.ren@intel.com

tools/virsh-domain.c
tools/virsh.pod

index 17be5b4815592a273e0cc30f22341f8532a84654..cecab63b381d7592d928f80a2d0ae0bf16c74638 100644 (file)
@@ -8505,6 +8505,128 @@ cmdMemtune(vshControl *ctl, const vshCmd *cmd)
     goto cleanup;
 }
 
+/*
+ * "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 = "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, &ntok)))
+        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", &enable) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "disable", &disable) < 0)
+        return false;
+
+    if (enable && virshParseEventStr(ctl, enable, true,
+                                     &params, &nparams, &maxparams) < 0)
+        goto cleanup;
+
+    if (disable && virshParseEventStr(ctl, disable, false,
+                                      &params, &nparams, &maxparams) < 0)
+        goto cleanup;
+
+    if (nparams == 0) {
+        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;
+
+ error:
+    vshError(ctl, "%s", _("Unable to enable/disable perf events"));
+    goto cleanup;
+}
+
+
 /*
  * "numatune" command
  */
@@ -13070,6 +13192,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,
index 2c13e04981ff4a90b29206fce86ba6a619dacd34..d0bd6a05e72e9e330bfb1f82ba758b2f9fa76c2f 100644 (file)
@@ -2136,6 +2136,26 @@ 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<--enable> B<eventName>]
+[I<--disable> B<eventName>]
+
+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 context-switches, minor-faults, etc.. Now dozens of events
+from different sources can be supported by perf.
+
+Currently only QEMU/KVM supports I<--enable> and I<--disable>.
+B<eventName> is a string listing one or more events, in the format
+of name|name|name. Only "cmt" event is supported presently. CMT is
+a PQos (Platform Qos) feature to monitor the usage of cache by
+applications running on the platform.
+
 =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>]