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