[libvirt] [PATCH 5/5 V5] cpu-accts command shows cpu accounting information of a domain.

Lai Jiangshan laijs at cn.fujitsu.com
Thu Feb 9 10:43:09 UTC 2012


From: KAMEZAWA Hiroyuki <kamezawa.hiroyu at jp.fujitsu.com>

Total:
	cpu_time        15.8
CPU0:
	cpu_time        8.6
CPU1:
	cpu_time        3.5
CPU2:
	cpu_time        2.4
CPU3:
	cpu_time        1.3
---
 tools/virsh.c   |  116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/virsh.pod |    5 ++
 2 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 66ba61c..e9d2f86 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -5385,6 +5385,121 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
 }
 
 /*
+ * "cputime" command
+ */
+static const vshCmdInfo info_cpu_accts[] = {
+    {"help", N_("show domain cpu accounting information")},
+    {"desc", N_("Returns information about the domain's cpu accounting")},
+    {NULL, NULL},
+};
+
+static const vshCmdOptDef opts_cpu_accts[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+    {NULL, 0, 0, NULL},
+};
+
+static bool
+cmdCPUAccts(vshControl *ctl, const vshCmd *cmd)
+{
+    virDomainPtr dom;
+    virTypedParameterPtr params = NULL;
+    bool ret = true;
+    int i, j, pos, cpu, nparams;
+    int max_id;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+        return false;
+
+    /* get max cpu id on the node */
+    max_id = virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0);
+    if (max_id < 0) {
+        vshPrint(ctl, "max id %d\n", max_id);
+        goto cleanup;
+    }
+    /* get supported num of parameter for total statistics */
+    nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0);
+    if (nparams < 0)
+        goto cleanup;
+
+    if (VIR_ALLOC_N(params, nparams)) {
+        virReportOOMError();
+        goto cleanup;
+    }
+    /* passing start_cpu == -1 gives us domain's total status */
+    nparams = virDomainGetCPUStats(dom, params, nparams, -1, 1, 0);
+    if (nparams < 0)
+        goto cleanup;
+
+    vshPrint(ctl, "Total:\n");
+    for (i = 0; i < nparams; i++) {
+        vshPrint(ctl, "\t%-15s ", params[i].field);
+        switch (params[i].type) {
+        case VIR_TYPED_PARAM_ULLONG:
+            /* Now all UULONG param is used for time accounting in ns */
+            vshPrint(ctl, "%.1lf\n",
+                     params[i].value.ul / 1000000000.0);
+            break;
+        default:
+            vshError(ctl, "%s", _("API mismatch?"));
+            goto cleanup;
+        }
+    }
+    VIR_FREE(params);
+    /* get percpu information */
+    nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0);
+    if (nparams < 0)
+        goto cleanup;
+
+    cpu = 0;
+    while (cpu <= max_id) {
+        int ncpus = 128;
+
+        if (cpu + ncpus - 1 > max_id) /* id starts from 0. */
+            ncpus = max_id + 1 - cpu;
+
+        if (VIR_ALLOC_N(params, nparams * ncpus)) {
+            virReportOOMError();
+            goto cleanup;
+        }
+
+        if (virDomainGetCPUStats(dom, params, nparams, cpu, ncpus, 0) < 0)
+            goto cleanup;
+
+        for (i = 0; i < ncpus; i++) {
+            if (params[i * nparams].type == 0)
+                continue;
+            vshPrint(ctl, "CPU%d:\n", cpu + i);
+
+            for (j = 0; j < nparams; j++) {
+                pos = i * nparams + j;
+                if (params[pos].type == 0)
+                    continue;
+                vshPrint(ctl, "\t%-15s ", params[pos].field);
+                switch(params[j].type) {
+                case VIR_TYPED_PARAM_ULLONG:
+                    vshPrint(ctl, "%.1lf\n",
+                        params[pos].value.ul / 1000000000.0);
+                    break;
+                default:
+                    vshError(ctl, "%s", _("API mismatch?"));
+                    goto cleanup;
+                }
+            }
+        }
+        cpu += ncpus;
+        /* Note: If we handle string type, it should be freed */
+        VIR_FREE(params);
+    }
+cleanup:
+    VIR_FREE(params);
+    virDomainFree(dom);
+    return ret;
+}
+
+/*
  * "inject-nmi" command
  */
 static const vshCmdInfo info_inject_nmi[] = {
@@ -16441,6 +16556,7 @@ static const vshCmdDef domManagementCmds[] = {
 #endif
     {"cpu-baseline", cmdCPUBaseline, opts_cpu_baseline, info_cpu_baseline, 0},
     {"cpu-compare", cmdCPUCompare, opts_cpu_compare, info_cpu_compare, 0},
+    {"cpu-accts", cmdCPUAccts, opts_cpu_accts, info_cpu_accts, 0},
     {"create", cmdCreate, opts_create, info_create, 0},
     {"define", cmdDefine, opts_define, info_define, 0},
     {"desc", cmdDesc, opts_desc, info_desc, 0},
diff --git a/tools/virsh.pod b/tools/virsh.pod
index bd79b4c..2b2f70b 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -762,6 +762,11 @@ Provide the maximum number of virtual CPUs supported for a guest VM on
 this connection.  If provided, the I<type> parameter must be a valid
 type attribute for the <domain> element of XML.
 
+=item B<cpu-accts> I<domain>
+
+Provide cpu accounting information of a domain. The domain should
+be running.
+
 =item B<migrate> [I<--live>] [I<--direct>] [I<--p2p> [I<--tunnelled>]]
 [I<--persistent>] [I<--undefinesource>] [I<--suspend>] [I<--copy-storage-all>]
 [I<--copy-storage-inc>] [I<--change-protection>] [I<--verbose>]
-- 
1.7.4.4




More information about the libvir-list mailing list