[libvirt] [PATCH v2 2/2] virsh: report only filled values in 'nodecpustats'

Roman Bogorodskiy bogorodskiy at gmail.com
Sun Jan 19 18:24:04 UTC 2014


  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};
> +    virHashTablePtr cpu_stats[2];
>  
>      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)) {
> -                cpu_stats[i].util = value;
> +                virHashAddEntry(cpu_stats[i], "usage:", value);
>                  flag_utilization = true;
>              }
>          }
> @@ -405,46 +407,68 @@ cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd)
>  
>      if (!flag_percent) {
>          if (!flag_utilization) {
> -            vshPrint(ctl, "%-15s %20llu\n", _("user:"), cpu_stats[0].user);
> -            vshPrint(ctl, "%-15s %20llu\n", _("system:"), cpu_stats[0].sys);
> -            vshPrint(ctl, "%-15s %20llu\n", _("idle:"), cpu_stats[0].idle);
> -            vshPrint(ctl, "%-15s %20llu\n", _("iowait:"), cpu_stats[0].iowait);
> -            vshPrint(ctl, "%-15s %20llu\n", _("intr:"), cpu_stats[0].intr);
> +            for (k = 0; fields[k] != NULL; k++) {
> +                unsigned long long *value = virHashLookup(cpu_stats[0], fields[k]);
> +
> +                if (value)
> +                    vshPrint(ctl, "%-15s %20llu\n", _(fields[k]), *value);
> +            }
>          }
>      } else {
>          if (flag_utilization) {
> -            usage = cpu_stats[0].util;
> +            double *usage = virHashLookup(cpu_stats[0], "usage:");
>  
> -            vshPrint(ctl, "%-15s %5.1lf%%\n", _("usage:"), usage);
> -            vshPrint(ctl, "%-15s %5.1lf%%\n", _("idle:"), 100 - usage);
> +            vshPrint(ctl, "%-15s %5.1lf%%\n", _("usage:"), *usage);
> +            vshPrint(ctl, "%-15s %5.1lf%%\n", _("idle:"), 100 - *usage);
>          } else {
> -            user_time   = cpu_stats[1].user   - cpu_stats[0].user;
> -            sys_time    = cpu_stats[1].sys    - cpu_stats[0].sys;
> -            idle_time   = cpu_stats[1].idle   - cpu_stats[0].idle;
> -            iowait_time = cpu_stats[1].iowait - cpu_stats[0].iowait;
> -            intr_time   = cpu_stats[1].intr   - cpu_stats[0].intr;
> -            total_time  = user_time + sys_time + idle_time + iowait_time + intr_time;
> -
> -            usage = (user_time + sys_time) / total_time * 100;
> -
> -            vshPrint(ctl, "%-15s %5.1lf%%\n",
> -                     _("usage:"), usage);
> -            vshPrint(ctl, "%-15s %5.1lf%%\n",
> -                     _("user:"), user_time / total_time * 100);
> -            vshPrint(ctl, "%-15s %5.1lf%%\n",
> -                     _("system:"), sys_time  / total_time * 100);
> -            vshPrint(ctl, "%-15s %5.1lf%%\n",
> -                     _("idle:"), idle_time     / total_time * 100);
> -            vshPrint(ctl, "%-15s %5.1lf%%\n",
> -                     _("iowait:"), iowait_time   / total_time * 100);
> -            vshPrint(ctl, "%-15s %5.1lf%%\n",
> -                     _("intr:"), intr_time         / total_time * 100);
> +            virHashTablePtr diff;
> +            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]);
> +
> +                if (!oldval || !newval)
> +                    continue;
> +
> +                if (VIR_ALLOC(value_diff) < 0)
> +                    goto cleanup;
> +
> +                *value_diff = *newval - *oldval;
> +                virHashAddEntry(diff, fields[k], value_diff);
> +                total_time += *value_diff;
> +            }
> +
> +            for (k = 0; fields[k] != NULL; k++) {
> +                double *value = virHashLookup(diff, fields[k]);
> +
> +                if (!value)
> +                    continue;
> +
> +                vshPrint(ctl, "%-15s %5.1lf%%\n",
> +                         _(fields[k]), *value / total_time * 100);
> +
> +                if (STREQ("idle:", fields[k]))
> +                    usage = (total_time - *value) / total_time * 100;
> +            }
> +
> +            if (usage != -1)
> +                vshPrint(ctl, "%-15s %5.1lf%%\n",
> +                         _("usage:"), usage);
This needs 
           virHashFree(diff);

I'll wait for other comments before updating the patch.
>          }
>      }
>  
>      ret = true;
>  
>    cleanup:
> +    for (i = 0; i < 2; i++)
> +        virHashFree(cpu_stats[i]);
>      VIR_FREE(params);
>      return ret;
>  }
> -- 
> 1.8.4.3
> 

Roman Bogorodskiy




More information about the libvir-list mailing list