[PATCH] qemu: Provide virDomainGetCPUStats() implementation for session connection

Martin Kletzander mkletzan at redhat.com
Tue Jan 17 14:15:49 UTC 2023


On Tue, Jan 17, 2023 at 01:44:44PM +0100, Michal Privoznik wrote:
>We have virDomainGetCPUStats() API which offers querying
>statistics on host CPU usage by given guest. And it works in two
>modes: getting overall stats (@start_cpu == -1, @ncpus == 1) or
>getting per host CPU usage.
>
>For the QEMU driver it is implemented by looking into values
>stored in corresponding cpuacct CGroup controller. Well, this
>works for system instances, where libvirt has permissions to
>create CGroups and place QEMU process into them. But it does not
>fly for session connection, where no CGroups are set up.
>
>Fortunately, we can do something similar to v8.8.0-rc1~95 and use
>virProcessGetStatInfo() to fill the overall stats. Unfortunately,
>I haven't found any source of per host CPU usage, so we just
>continue throwing an error in that case.
>

Looks ok, but there's one thing that's bothering me a bit.  On non-Linux
platforms this API would start to work and returning zeros.  Could that
be fixed somehow in a nice fashion or should I treat that as a non-issue?

>Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
>---
> src/qemu/qemu_driver.c | 52 ++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 50 insertions(+), 2 deletions(-)
>
>diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>index d6879175fe..a570057ecf 100644
>--- a/src/qemu/qemu_driver.c
>+++ b/src/qemu/qemu_driver.c
>@@ -16009,6 +16009,50 @@ qemuDomainGetMetadata(virDomainPtr dom,
>     return ret;
> }
>
>+#define QEMU_CPU_STATS_PROC_TOTAL 3
>+
>+static int
>+qemuDomainGetCPUStatsProc(virDomainObj *vm,
>+                          virTypedParameterPtr params,
>+                          unsigned int nparams)
>+{
>+    unsigned long long cpuTime = 0;
>+    unsigned long long userTime = 0;
>+    unsigned long long sysTime = 0;
>+
>+    if (nparams == 0) {
>+        /* return supported number of params */
>+        return QEMU_CPU_STATS_PROC_TOTAL;
>+    }
>+
>+    if (virProcessGetStatInfo(&cpuTime, &userTime, &sysTime,
>+                              NULL, NULL, vm->pid, 0) < 0) {
>+        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
>+                       _("cannot read cputime for domain"));
>+        return -1;
>+    }
>+
>+    if (virTypedParameterAssign(&params[0], VIR_DOMAIN_CPU_STATS_CPUTIME,
>+                                VIR_TYPED_PARAM_ULLONG, cpuTime) < 0)
>+        return -1;
>+
>+    if (nparams > 1 &&
>+        virTypedParameterAssign(&params[1], VIR_DOMAIN_CPU_STATS_USERTIME,
>+                                VIR_TYPED_PARAM_ULLONG, userTime) < 0)
>+        return -1;
>+
>+    if (nparams > 2 &&
>+        virTypedParameterAssign(&params[2], VIR_DOMAIN_CPU_STATS_SYSTEMTIME,
>+                                VIR_TYPED_PARAM_ULLONG, sysTime) < 0)
>+        return -1;
>+
>+    if (nparams > 3)
>+        nparams = 3;
>+
>+    return nparams;
>+}
>+
>+#undef QEMU_CPU_STATS_PROC_TOTAL
>
> static int
> qemuDomainGetCPUStats(virDomainPtr domain,
>@@ -16037,8 +16081,12 @@ qemuDomainGetCPUStats(virDomainPtr domain,
>         goto cleanup;
>
>     if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUACCT)) {
>-        virReportError(VIR_ERR_OPERATION_INVALID,
>-                       "%s", _("cgroup CPUACCT controller is not mounted"));
>+        if (start_cpu == -1) {
>+            ret = qemuDomainGetCPUStatsProc(vm, params, nparams);
>+        } else {
>+            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
>+                           _("cgroup CPUACCT controller is not mounted"));
>+        }
>         goto cleanup;
>     }
>
>-- 
>2.38.2
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20230117/d813dfc4/attachment.sig>


More information about the libvir-list mailing list