|
|
735c6b |
From ec03aa23ac417797f9b53d51b6f999f5e966f9d7 Mon Sep 17 00:00:00 2001
|
|
|
735c6b |
Message-Id: <ec03aa23ac417797f9b53d51b6f999f5e966f9d7@dist-git>
|
|
|
735c6b |
From: Michal Privoznik <mprivozn@redhat.com>
|
|
|
735c6b |
Date: Mon, 16 Jan 2023 12:46:09 +0100
|
|
|
735c6b |
Subject: [PATCH] qemu: Provide virDomainGetCPUStats() implementation for
|
|
|
735c6b |
session connection
|
|
|
735c6b |
|
|
|
735c6b |
We have virDomainGetCPUStats() API which offers querying
|
|
|
735c6b |
statistics on host CPU usage by given guest. And it works in two
|
|
|
735c6b |
modes: getting overall stats (@start_cpu == -1, @ncpus == 1) or
|
|
|
735c6b |
getting per host CPU usage.
|
|
|
735c6b |
|
|
|
735c6b |
For the QEMU driver it is implemented by looking into values
|
|
|
735c6b |
stored in corresponding cpuacct CGroup controller. Well, this
|
|
|
735c6b |
works for system instances, where libvirt has permissions to
|
|
|
735c6b |
create CGroups and place QEMU process into them. But it does not
|
|
|
735c6b |
fly for session connection, where no CGroups are set up.
|
|
|
735c6b |
|
|
|
735c6b |
Fortunately, we can do something similar to v8.8.0-rc1~95 and use
|
|
|
735c6b |
virProcessGetStatInfo() to fill the overall stats. Unfortunately,
|
|
|
735c6b |
I haven't found any source of per host CPU usage, so we just
|
|
|
735c6b |
continue throwing an error in that case.
|
|
|
735c6b |
|
|
|
735c6b |
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
|
735c6b |
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
735c6b |
(cherry picked from commit 8865c42771600a40eddf40663f73b458423059a4)
|
|
|
735c6b |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2148266
|
|
|
735c6b |
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
|
735c6b |
---
|
|
|
735c6b |
src/qemu/qemu_driver.c | 52 ++++++++++++++++++++++++++++++++++++++++--
|
|
|
735c6b |
1 file changed, 50 insertions(+), 2 deletions(-)
|
|
|
735c6b |
|
|
|
735c6b |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
735c6b |
index c576c601ad..0603af6a35 100644
|
|
|
735c6b |
--- a/src/qemu/qemu_driver.c
|
|
|
735c6b |
+++ b/src/qemu/qemu_driver.c
|
|
|
735c6b |
@@ -16009,6 +16009,50 @@ qemuDomainGetMetadata(virDomainPtr dom,
|
|
|
735c6b |
return ret;
|
|
|
735c6b |
}
|
|
|
735c6b |
|
|
|
735c6b |
+#define QEMU_CPU_STATS_PROC_TOTAL 3
|
|
|
735c6b |
+
|
|
|
735c6b |
+static int
|
|
|
735c6b |
+qemuDomainGetCPUStatsProc(virDomainObj *vm,
|
|
|
735c6b |
+ virTypedParameterPtr params,
|
|
|
735c6b |
+ unsigned int nparams)
|
|
|
735c6b |
+{
|
|
|
735c6b |
+ unsigned long long cpuTime = 0;
|
|
|
735c6b |
+ unsigned long long userTime = 0;
|
|
|
735c6b |
+ unsigned long long sysTime = 0;
|
|
|
735c6b |
+
|
|
|
735c6b |
+ if (nparams == 0) {
|
|
|
735c6b |
+ /* return supported number of params */
|
|
|
735c6b |
+ return QEMU_CPU_STATS_PROC_TOTAL;
|
|
|
735c6b |
+ }
|
|
|
735c6b |
+
|
|
|
735c6b |
+ if (virProcessGetStatInfo(&cpuTime, &userTime, &sysTime,
|
|
|
735c6b |
+ NULL, NULL, vm->pid, 0) < 0) {
|
|
|
735c6b |
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
735c6b |
+ _("cannot read cputime for domain"));
|
|
|
735c6b |
+ return -1;
|
|
|
735c6b |
+ }
|
|
|
735c6b |
+
|
|
|
735c6b |
+ if (virTypedParameterAssign(¶ms[0], VIR_DOMAIN_CPU_STATS_CPUTIME,
|
|
|
735c6b |
+ VIR_TYPED_PARAM_ULLONG, cpuTime) < 0)
|
|
|
735c6b |
+ return -1;
|
|
|
735c6b |
+
|
|
|
735c6b |
+ if (nparams > 1 &&
|
|
|
735c6b |
+ virTypedParameterAssign(¶ms[1], VIR_DOMAIN_CPU_STATS_USERTIME,
|
|
|
735c6b |
+ VIR_TYPED_PARAM_ULLONG, userTime) < 0)
|
|
|
735c6b |
+ return -1;
|
|
|
735c6b |
+
|
|
|
735c6b |
+ if (nparams > 2 &&
|
|
|
735c6b |
+ virTypedParameterAssign(¶ms[2], VIR_DOMAIN_CPU_STATS_SYSTEMTIME,
|
|
|
735c6b |
+ VIR_TYPED_PARAM_ULLONG, sysTime) < 0)
|
|
|
735c6b |
+ return -1;
|
|
|
735c6b |
+
|
|
|
735c6b |
+ if (nparams > 3)
|
|
|
735c6b |
+ nparams = 3;
|
|
|
735c6b |
+
|
|
|
735c6b |
+ return nparams;
|
|
|
735c6b |
+}
|
|
|
735c6b |
+
|
|
|
735c6b |
+#undef QEMU_CPU_STATS_PROC_TOTAL
|
|
|
735c6b |
|
|
|
735c6b |
static int
|
|
|
735c6b |
qemuDomainGetCPUStats(virDomainPtr domain,
|
|
|
735c6b |
@@ -16037,8 +16081,12 @@ qemuDomainGetCPUStats(virDomainPtr domain,
|
|
|
735c6b |
goto cleanup;
|
|
|
735c6b |
|
|
|
735c6b |
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUACCT)) {
|
|
|
735c6b |
- virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
735c6b |
- "%s", _("cgroup CPUACCT controller is not mounted"));
|
|
|
735c6b |
+ if (start_cpu == -1) {
|
|
|
735c6b |
+ ret = qemuDomainGetCPUStatsProc(vm, params, nparams);
|
|
|
735c6b |
+ } else {
|
|
|
735c6b |
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
735c6b |
+ _("cgroup CPUACCT controller is not mounted"));
|
|
|
735c6b |
+ }
|
|
|
735c6b |
goto cleanup;
|
|
|
735c6b |
}
|
|
|
735c6b |
|
|
|
735c6b |
--
|
|
|
735c6b |
2.39.1
|
|
|
735c6b |
|