On 01/19/2014 06:55 PM, Roman Bogorodskiy wrote:
A set of fields for CPU stats could vary on different platforms,
for example, FreeBSD doesn't report 'iowait'.
Make virsh print out only the fields that were actually filled.
---
tools/virsh-host.c | 118 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 71 insertions(+), 47 deletions(-)
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index ac41177..8c1218e 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -34,6 +34,7 @@
#include "internal.h"
#include "virbuffer.h"
#include "viralloc.h"
+#include "virhash.h"
#include "virsh-domain.h"
#include "virxml.h"
#include "virtypedparam.h"
@@ -335,23 +336,15 @@ static const vshCmdOptDef opts_node_cpustats[] = {
static bool
cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd)
{
- size_t i, j;
+ size_t i, j, k;
bool flag_utilization = false;
bool flag_percent = vshCommandOptBool(cmd, "percent");
int cpuNum = VIR_NODE_CPU_STATS_ALL_CPUS;
virNodeCPUStatsPtr params;
int nparams = 0;
bool ret = false;
- struct cpu_stats {
- unsigned long long user;
- unsigned long long sys;
- unsigned long long idle;
- unsigned long long iowait;
- unsigned long long intr;
- unsigned long long util;
- } cpu_stats[2];
- double user_time, sys_time, idle_time, iowait_time, intr_time, total_time;
- double usage;
+ const char *fields[] = {"user:", "system:", "idle:",
"iowait:", "intr:", NULL};
Maybe creating an enum with VIR_ENUM_DECL/VIR_ENUM_IMPL would make the code
easier to read? (You could use the FromString/ToString functions and an array
of bools to tell missing/zero fields apart instead of NULL pointers)
+ virHashTablePtr cpu_stats[2];
This should be initialized to NULLs.
if (vshCommandOptInt(cmd, "cpu", &cpuNum) < 0) {
vshError(ctl, "%s", _("Invalid value of cpuNum"));
@@ -372,6 +365,10 @@ cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd)
params = vshCalloc(ctl, nparams, sizeof(*params));
for (i = 0; i < 2; i++) {
+ cpu_stats[i] = virHashCreate(0, (virHashDataFree) free);
+ if (cpu_stats[i] == NULL)
+ goto cleanup;
+
if (i > 0)
sleep(1);
@@ -381,20 +378,25 @@ cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd)
}
for (j = 0; j < nparams; j++) {
- unsigned long long value = params[j].value;
+ unsigned long long *value;
+
+ if (VIR_ALLOC(value) < 0)
+ goto cleanup;
+
+ *value = params[j].value;
if (STREQ(params[j].field, VIR_NODE_CPU_STATS_KERNEL)) {
- cpu_stats[i].sys = value;
+ virHashAddEntry(cpu_stats[i], "system:", value);
} else if (STREQ(params[j].field, VIR_NODE_CPU_STATS_USER)) {
- cpu_stats[i].user = value;
+ virHashAddEntry(cpu_stats[i], "user:", value);
} else if (STREQ(params[j].field, VIR_NODE_CPU_STATS_IDLE)) {
- cpu_stats[i].idle = value;
+ virHashAddEntry(cpu_stats[i], "idle:", value);
} else if (STREQ(params[j].field, VIR_NODE_CPU_STATS_IOWAIT)) {
- cpu_stats[i].iowait = value;
+ virHashAddEntry(cpu_stats[i], "iowait:", value);
} else if (STREQ(params[j].field, VIR_NODE_CPU_STATS_INTR)) {
- cpu_stats[i].intr = value;
+ virHashAddEntry(cpu_stats[i], "intr:", value);
} else if (STREQ(params[j].field, VIR_NODE_CPU_STATS_UTILIZATION)) {
Hmm, did libvirtd ever fill out the 'usage' field? I can't find it in git
history.
- cpu_stats[i].util = value;
+ virHashAddEntry(cpu_stats[i], "usage:", value);
flag_utilization = true;
}
}
@@ -405,46 +407,68 @@ cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd)
+ virHashTablePtr diff;
This should be declared at
the start of the function, so you can free it in
the cleanup label.
+ double total_time = 0;
+ double usage = -1;
+
+ diff = virHashCreate(0, (virHashDataFree) free);
+ if (diff == NULL)
+ goto cleanup;
+
+ for (k = 0; fields[k] != NULL; k++) {
+ double *value_diff;
+ unsigned long long *oldval = virHashLookup(cpu_stats[0], fields[k]);
+ unsigned long long *newval = virHashLookup(cpu_stats[1], fields[k]);
+
Jan