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

Qiaowei Ren qiaowei.ren at intel.com
Tue Nov 17 08:00:48 UTC 2015


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 at intel.com>
---
 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(&params, &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




More information about the libvir-list mailing list