Add per host cpu info provided in virDomainGetCPUStats to the
stats provided in virConnectGetAllDomainStats. Namely:
"cpu.count" - number of host cpus
"cpu.<num>.time" - total cpu time spent for this domain in nanoseconds
"cpu.<num>.vtime" - time spent in virtual cpu threads for this domain
in nanoseconds
---
docs/news.xml | 9 ++++++
include/libvirt/libvirt-domain.h | 1 +
src/libvirt-domain.c | 7 +++++
src/qemu/qemu_driver.c | 64 ++++++++++++++++++++++++++++++++++++++++
tools/virsh-domain-monitor.c | 7 +++++
tools/virsh.pod | 11 +++++--
6 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/docs/news.xml b/docs/news.xml
index f408293..6e40c33 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -42,6 +42,15 @@
Allow setting MTU size for some types of domain interface.
</description>
</change>
+ <change>
+ <summary>
+ Show per host cpu stats in all domain stats
+ </summary>
+ <description>
+ Show stats provided in virDomainGetCPUStats in all domain stats
+ as well.
+ </description>
+ </change>
</section>
<section title="Bug fixes">
<change>
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index e303140..2691ebe 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2020,6 +2020,7 @@ typedef enum {
VIR_DOMAIN_STATS_INTERFACE = (1 << 4), /* return domain interfaces info */
VIR_DOMAIN_STATS_BLOCK = (1 << 5), /* return domain block info */
VIR_DOMAIN_STATS_PERF = (1 << 6), /* return domain perf event info */
+ VIR_DOMAIN_STATS_PER_CPU = (1 << 7), /* return domain per host CPU info */
} virDomainStatsTypes;
typedef enum {
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 5b3e842..3726938 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11126,6 +11126,13 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
* "cpu.system" - system cpu time spent in nanoseconds as unsigned long
* long.
*
+ * VIR_DOMAIN_STATS_PER_CPU:
+ * Return per host CPU statistics
+ * "cpu.count" - number of host cpus
+ * "cpu.<num>.time" - total cpu time spent for this domain in
nanoseconds
+ * "cpu.<num>.vtime" - time spent in virtual cpu threads for this
domain
+ * in nanoseconds
+ *
* VIR_DOMAIN_STATS_BALLOON:
* Return memory balloon device information.
* The typed parameter keys are in this format:
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 088f55e..d457a71 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18806,6 +18806,69 @@ qemuDomainGetStatsCpu(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
}
static int
+qemuDomainGetStatsPerCpu(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
+ virDomainObjPtr dom,
+ virDomainStatsRecordPtr record,
+ int *maxparams,
+ unsigned int privflags ATTRIBUTE_UNUSED)
+{
+ qemuDomainObjPrivatePtr priv = dom->privateData;
+ virCgroupCpuStats stats = {0};
+ virBitmapPtr guestvcpus = NULL;
+ char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
+ int ncpus;
+ size_t i;
+ int ret = -1;
+
+ if (qemuDomainHasVcpuPids(dom))
+ guestvcpus = virDomainDefGetOnlineVcpumap(dom->def);
+
+ ncpus = virCgroupGetCpuStats(priv->cgroup, guestvcpus, &stats);
+
+ if (ncpus > 0) {
+ if (virTypedParamsAddUInt(&record->params,
+ &record->nparams,
+ maxparams,
+ "cpu.count",
+ ncpus) < 0)
+ goto cleanup;
+
+ for (i = 0; i < ncpus; i++) {
+ snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+ "cpu.%zu.time", i);
+ if (virTypedParamsAddULLong(&record->params,
+ &record->nparams,
+ maxparams,
+ param_name,
+ stats.time[i]) < 0)
+ goto cleanup;
+
+
+ if (stats.vtime) {
+ snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+ "cpu.%zu.vtime", i);
+ if (virTypedParamsAddULLong(&record->params,
+ &record->nparams,
+ maxparams,
+ param_name,
+ stats.vtime[i]) < 0)
+ goto cleanup;
+ }
+ }
+ }
+
+ ret = 0;
+
+ cleanup:
+ if (!ret && virGetLastError())
+ virResetLastError();
+ virBitmapFree(guestvcpus);
+ virCgroupCpuStatsFree(&stats);
+
+ return ret;
+}
+
+static int
qemuDomainGetStatsBalloon(virQEMUDriverPtr driver,
virDomainObjPtr dom,
virDomainStatsRecordPtr record,
@@ -19381,6 +19444,7 @@ struct qemuDomainGetStatsWorker {
static struct qemuDomainGetStatsWorker qemuDomainGetStatsWorkers[] = {
{ qemuDomainGetStatsState, VIR_DOMAIN_STATS_STATE, false },
{ qemuDomainGetStatsCpu, VIR_DOMAIN_STATS_CPU_TOTAL, false },
+ { qemuDomainGetStatsPerCpu, VIR_DOMAIN_STATS_PER_CPU, false },
{ qemuDomainGetStatsBalloon, VIR_DOMAIN_STATS_BALLOON, true },
{ qemuDomainGetStatsVcpu, VIR_DOMAIN_STATS_VCPU, true },
{ qemuDomainGetStatsInterface, VIR_DOMAIN_STATS_INTERFACE, false },
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 77aa272..7707a96 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -1953,6 +1953,10 @@ static const vshCmdOptDef opts_domstats[] = {
.type = VSH_OT_BOOL,
.help = N_("report domain physical cpu usage"),
},
+ {.name = "per-cpu",
+ .type = VSH_OT_BOOL,
+ .help = N_("report domain per physical cpu usage"),
+ },
{.name = "balloon",
.type = VSH_OT_BOOL,
.help = N_("report domain balloon statistics"),
@@ -2072,6 +2076,9 @@ cmdDomstats(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "cpu-total"))
stats |= VIR_DOMAIN_STATS_CPU_TOTAL;
+ if (vshCommandOptBool(cmd, "per-cpu"))
+ stats |= VIR_DOMAIN_STATS_PER_CPU;
+
if (vshCommandOptBool(cmd, "balloon"))
stats |= VIR_DOMAIN_STATS_BALLOON;
diff --git a/tools/virsh.pod b/tools/virsh.pod
index a470409..c10a4ee 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -860,8 +860,9 @@ I<snapshot-create> for disk snapshots) will accept either
target
or unique source names printed by this command.
=item B<domstats> [I<--raw>] [I<--enforce>] [I<--backing>]
[I<--state>]
-[I<--cpu-total>] [I<--balloon>] [I<--vcpu>] [I<--interface>]
[I<--block>]
-[I<--perf>] [[I<--list-active>] [I<--list-inactive>]
[I<--list-persistent>]
+[I<--cpu-total>] [I<--per-cpu>] [I<--balloon>] [I<--vcpu>]
[I<--interface>]
+[I<--block>] [I<--perf>]
+[[I<--list-active>] [I<--list-inactive>] [I<--list-persistent>]
[I<--list-transient>] [I<--list-running>] [I<--list-paused>]
[I<--list-shutoff>] [I<--list-other>]] | [I<domain> ...]
@@ -894,6 +895,12 @@ I<--cpu-total> returns:
"cpu.user" - user cpu time spent in nanoseconds,
"cpu.system" - system cpu time spent in nanoseconds
+I<--per-cpu> returns:
+"cpu.count" - number of host cpus,
+"cpu.<num>.time" - total cpu time spent for this domain in nanoseconds,
+"cpu.<num>.vtime" - time spent in virtual cpu threads for this domain
+in nanoseconds.
+
I<--balloon> returns:
"balloon.current" - the memory in kiB currently used,
"balloon.maximum" - the maximum memory in kiB allowed,
--
1.8.3.1