[libvirt] [PATCH 2/2] cpustats: report user and sys times

Eric Blake eblake at redhat.com
Fri Mar 9 17:37:12 UTC 2012


Thanks to cgroups, providing user vs. system time of the overall
guest is easy to add to our existing API.

* include/libvirt/libvirt.h.in (VIR_DOMAIN_CPU_STATS_USERTIME)
(VIR_DOMAIN_CPU_STATS_SYSTEMTIME): New constants.
* src/util/virtypedparam.h (virTypedParameterArrayValidate)
(virTypedParameterAssign): Enforce checking the result.
* src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Fix offender.
(qemuDomainGetTotalcpuStats): Implement new parameters.
* tools/virsh.c (cmdCPUStats): Tweak output accordingly.
---
 include/libvirt/libvirt.h.in |   12 +++++++++++
 src/qemu/qemu_driver.c       |   45 ++++++++++++++++++++++++++++++++++-------
 src/util/virtypedparam.h     |    5 ++-
 tools/virsh.c                |   12 ++++++----
 4 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 66883fb..7d41642 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1332,6 +1332,18 @@ int                     virDomainGetState       (virDomainPtr domain,
  */
 #define VIR_DOMAIN_CPU_STATS_CPUTIME "cpu_time"

+/**
+ * VIR_DOMAIN_CPU_STATS_USERTIME:
+ * cpu time charged to user instructions in nanoseconds, as a ullong
+ */
+#define VIR_DOMAIN_CPU_STATS_USERTIME "user_time"
+
+/**
+ * VIR_DOMAIN_CPU_STATS_SYSTEMTIME:
+ * cpu time charged to system instructions in nanoseconds, as a ullong
+ */
+#define VIR_DOMAIN_CPU_STATS_SYSTEMTIME "system_time"
+
 int virDomainGetCPUStats(virDomainPtr domain,
                          virTypedParameterPtr params,
                          unsigned int nparams,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index be678f3..3147a9b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -101,6 +101,9 @@

 #define QEMU_NB_NUMA_PARAM 2

+#define QEMU_NB_TOTAL_CPU_STAT_PARAM 3
+#define QEMU_NB_PER_CPU_STAT_PARAM 1
+
 #if HAVE_LINUX_KVM_H
 # include <linux/kvm.h>
 #endif
@@ -12145,11 +12148,10 @@ qemuDomainGetTotalcpuStats(virCgroupPtr group,
                            int nparams)
 {
     unsigned long long cpu_time;
-    int param_idx = 0;
     int ret;

     if (nparams == 0) /* return supported number of params */
-        return 1;
+        return QEMU_NB_TOTAL_CPU_STAT_PARAM;
     /* entry 0 is cputime */
     ret = virCgroupGetCpuacctUsage(group, &cpu_time);
     if (ret < 0) {
@@ -12157,9 +12159,35 @@ qemuDomainGetTotalcpuStats(virCgroupPtr group,
         return -1;
     }

-    virTypedParameterAssign(&params[param_idx], VIR_DOMAIN_CPU_STATS_CPUTIME,
-                            VIR_TYPED_PARAM_ULLONG, cpu_time);
-    return 1;
+    if (virTypedParameterAssign(&params[0], VIR_DOMAIN_CPU_STATS_CPUTIME,
+                                VIR_TYPED_PARAM_ULLONG, cpu_time) < 0)
+        return -1;
+
+    if (nparams > 1) {
+        unsigned long long user;
+        unsigned long long sys;
+
+        ret = virCgroupGetCpuacctStat(group, &user, &sys);
+        if (ret < 0) {
+            virReportSystemError(-ret, "%s", _("unable to get cpu account"));
+            return -1;
+        }
+
+        if (virTypedParameterAssign(&params[1],
+                                    VIR_DOMAIN_CPU_STATS_USERTIME,
+                                    VIR_TYPED_PARAM_ULLONG, user) < 0)
+            return -1;
+        if (nparams > 2 &&
+            virTypedParameterAssign(&params[2],
+                                    VIR_DOMAIN_CPU_STATS_SYSTEMTIME,
+                                    VIR_TYPED_PARAM_ULLONG, sys) < 0)
+            return -1;
+
+        if (nparams > QEMU_NB_TOTAL_CPU_STAT_PARAM)
+            nparams = QEMU_NB_TOTAL_CPU_STAT_PARAM;
+    }
+
+    return nparams;
 }

 static int
@@ -12180,7 +12208,7 @@ qemuDomainGetPercpuStats(virDomainPtr domain,

     /* return the number of supported params */
     if (nparams == 0 && ncpus != 0)
-        return 1; /* only cpu_time is supported */
+        return QEMU_NB_PER_CPU_STAT_PARAM; /* only cpu_time is supported */

     /* return percpu cputime in index 0 */
     param_idx = 0;
@@ -12223,8 +12251,9 @@ qemuDomainGetPercpuStats(virDomainPtr domain,
         if (i < start_cpu)
             continue;
         ent = &params[ (i - start_cpu) * nparams + param_idx];
-        virTypedParameterAssign(ent, VIR_DOMAIN_CPU_STATS_CPUTIME,
-                                VIR_TYPED_PARAM_ULLONG, cpu_time);
+        if (virTypedParameterAssign(ent, VIR_DOMAIN_CPU_STATS_CPUTIME,
+                                    VIR_TYPED_PARAM_ULLONG, cpu_time) < 0)
+            goto cleanup;
     }
     rv = param_idx + 1;
 cleanup:
diff --git a/src/util/virtypedparam.h b/src/util/virtypedparam.h
index 52cbe78..7c513ed 100644
--- a/src/util/virtypedparam.h
+++ b/src/util/virtypedparam.h
@@ -29,9 +29,10 @@ void virTypedParameterArrayClear(virTypedParameterPtr params, int nparams);

 int virTypedParameterArrayValidate(virTypedParameterPtr params, int nparams,
                                    /* const char *name, int type ... */ ...)
-    ATTRIBUTE_SENTINEL;
+    ATTRIBUTE_SENTINEL ATTRIBUTE_RETURN_CHECK;

 int virTypedParameterAssign(virTypedParameterPtr param, const char *name,
-                            int type, /* TYPE arg */ ...);
+                            int type, /* TYPE arg */ ...)
+    ATTRIBUTE_RETURN_CHECK;

 #endif /* __VIR_TYPED_PARAM_H */
diff --git a/tools/virsh.c b/tools/virsh.c
index 9a16ef8..630b77f 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -5630,10 +5630,10 @@ cmdCPUStats(vshControl *ctl, const vshCmd *cmd)

             for (j = 0; j < nparams; j++) {
                 pos = i * nparams + j;
-                vshPrint(ctl, "\t%-10s ", params[pos].field);
+                vshPrint(ctl, "\t%-12s ", params[pos].field);
                 if (STREQ(params[pos].field, VIR_DOMAIN_CPU_STATS_CPUTIME) &&
                     params[j].type == VIR_TYPED_PARAM_ULLONG) {
-                    vshPrint(ctl, "%lld.%09lld seconds\n",
+                    vshPrint(ctl, "%9lld.%09lld seconds\n",
                              params[pos].value.ul / 1000000000,
                              params[pos].value.ul % 1000000000);
                 } else {
@@ -5671,10 +5671,12 @@ do_show_total:

     vshPrint(ctl, _("Total:\n"));
     for (i = 0; i < nparams; i++) {
-        vshPrint(ctl, "\t%-10s ", params[i].field);
-        if (STREQ(params[i].field, VIR_DOMAIN_CPU_STATS_CPUTIME) &&
+        vshPrint(ctl, "\t%-12s ", params[i].field);
+        if ((STREQ(params[i].field, VIR_DOMAIN_CPU_STATS_CPUTIME) ||
+             STREQ(params[i].field, VIR_DOMAIN_CPU_STATS_USERTIME) ||
+             STREQ(params[i].field, VIR_DOMAIN_CPU_STATS_SYSTEMTIME)) &&
             params[i].type == VIR_TYPED_PARAM_ULLONG) {
-            vshPrint(ctl, "%llu.%09llu seconds\n",
+            vshPrint(ctl, "%9lld.%09lld seconds\n",
                      params[i].value.ul / 1000000000,
                      params[i].value.ul % 1000000000);
         } else {
-- 
1.7.7.6




More information about the libvir-list mailing list