[libvirt] [PATCH] qemu: add host per cpu info to all domain stats

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Wed Feb 1 06:47:20 UTC 2017


Info provided in virDomainGetCPUStats is now missed in all
domain stats. This patch removes this discrepancy.

Output example:

  cpu.count=2
  cpu.0.time=536163399467
  cpu.1.time=453846564946
  cpu.0.vtime=530053197220
  cpu.1.vtime=446078894510
---
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_driver.c   | 71 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/util/vircgroup.c     |  2 +-
 src/util/vircgroup.h     |  5 ++++
 4 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a2866a3..40f284c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1343,6 +1343,7 @@ virCgroupGetMemoryUsage;
 virCgroupGetMemSwapHardLimit;
 virCgroupGetMemSwapUsage;
 virCgroupGetPercpuStats;
+virCgroupGetPercpuVcpuSum;
 virCgroupHasController;
 virCgroupHasEmptyTasks;
 virCgroupKill;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 16b435a..61ae60e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18768,7 +18768,16 @@ qemuDomainGetStatsCpu(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
     unsigned long long cpu_time = 0;
     unsigned long long user_time = 0;
     unsigned long long sys_time = 0;
+    unsigned long long *sum_cpu_time = NULL;
+    virBitmapPtr cpumap = NULL;
+    virBitmapPtr guestvcpus = NULL;
+    char *buf = NULL;
+    char *pos;
+    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
+    int ncpu;
     int err = 0;
+    int ret = -1;
+    size_t i;
 
     if (!priv->cgroup)
         return 0;
@@ -18795,7 +18804,67 @@ qemuDomainGetStatsCpu(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
                                         sys_time) < 0)
         return -1;
 
-    return 0;
+    if ((cpumap = virHostCPUGetPresentBitmap())) {
+        ncpu = virBitmapSize(cpumap);
+
+        if (virTypedParamsAddULLong(&record->params,
+                                    &record->nparams,
+                                    maxparams,
+                                    "cpu.count",
+                                    ncpu) < 0)
+            goto cleanup;
+
+        if (!virCgroupGetCpuacctPercpuUsage(priv->cgroup, &buf)) {
+            pos = buf;
+            for (i = 0; i < ncpu; i++) {
+                unsigned long long time = 0;
+
+                if (virBitmapIsBitSet(cpumap, i) &&
+                    virStrToLong_ull(pos, &pos, 10, &time) < 0) {
+                    VIR_WARN("cpuacct parse error");
+                    continue;
+                }
+
+                snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                         "cpu.%zu.time", i);
+                if (virTypedParamsAddULLong(&record->params,
+                                            &record->nparams,
+                                            maxparams,
+                                            param_name,
+                                            time) < 0)
+                    goto cleanup;
+            }
+        }
+
+        if (qemuDomainHasVcpuPids(dom) &&
+            (guestvcpus = virDomainDefGetOnlineVcpumap(dom->def)) &&
+            !VIR_ALLOC_N(sum_cpu_time, ncpu) &&
+            !virCgroupGetPercpuVcpuSum(priv->cgroup, guestvcpus,
+                                            sum_cpu_time, ncpu, cpumap)) {
+            for (i = 0; i < ncpu; i++) {
+                snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                         "cpu.%zu.vtime", i);
+                if (virTypedParamsAddULLong(&record->params,
+                                            &record->nparams,
+                                            maxparams,
+                                            param_name,
+                                            sum_cpu_time[i]) < 0)
+                    goto cleanup;
+            }
+        }
+    }
+
+    ret = 0;
+
+ cleanup:
+    if (!ret && virGetLastError())
+        virResetLastError();
+    virBitmapFree(cpumap);
+    virBitmapFree(guestvcpus);
+    VIR_FREE(sum_cpu_time);
+    VIR_FREE(buf);
+
+    return ret;
 }
 
 static int
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 5aa1db5..0b36609 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -3122,7 +3122,7 @@ virCgroupDenyDevicePath(virCgroupPtr group,
  *   s2 = t02 + t12
  *   s3 = t03 + t13
  */
-static int
+int
 virCgroupGetPercpuVcpuSum(virCgroupPtr group,
                           virBitmapPtr guestvcpus,
                           unsigned long long *sum_cpu_time,
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index 2de1bf2..5f71618 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -297,4 +297,9 @@ int virCgroupSetOwner(virCgroupPtr cgroup,
 int virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller);
 
 bool virCgroupControllerAvailable(int controller);
+int virCgroupGetPercpuVcpuSum(virCgroupPtr group,
+                              virBitmapPtr guestvcpus,
+                              unsigned long long *sum_cpu_time,
+                              size_t nsum,
+                              virBitmapPtr cpumap);
 #endif /* __VIR_CGROUP_H__ */
-- 
1.8.3.1




More information about the libvir-list mailing list