virNodeGetCPUStats: Implement virsh support

Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp>
This commit is contained in:
Minoru Usui 2011-06-07 10:02:13 +09:00 committed by Eric Blake
parent daea15aa40
commit 7e6cb82d1c
2 changed files with 137 additions and 0 deletions

View File

@ -3713,6 +3713,135 @@ cmdNodeinfo(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
return true;
}
/*
* "nodecpustats" command
*/
static const vshCmdInfo info_nodecpustats[] = {
{"help", N_("Prints cpu stats of the node.")},
{"desc", N_("Returns cpu stats of the node.")},
{NULL, NULL}
};
static const vshCmdOptDef opts_node_cpustats[] = {
{"cpu", VSH_OT_INT, 0, N_("prints specified cpu statistics only.")},
{"percent", VSH_OT_BOOL, 0, N_("prints by percentage during 1 second.")},
{NULL, 0, 0, NULL}
};
static bool
cmdNodeCPUStats(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
{
int i, j;
bool flag_utilization = false;
bool flag_percent = vshCommandOptBool(cmd, "percent");
int cpuNum = VIR_CPU_STATS_ALL_CPUS;
virCPUStatsPtr 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 util;
} cpu_stats[2];
double user_time, sys_time, idle_time, iowait_time, total_time;
double usage;
if (!vshConnectionUsability(ctl, ctl->conn))
return false;
if (vshCommandOptInt(cmd, "cpu", &cpuNum) < 0) {
vshError(ctl, "%s", _("Invalid value of cpuNum"));
return false;
}
if (virNodeGetCPUStats(ctl->conn, cpuNum, NULL, &nparams, 0) != 0) {
vshError(ctl, "%s",
_("Unable to get number of cpu stats"));
return false;
}
if (nparams == 0) {
/* nothing to output */
return true;
}
memset(cpu_stats, 0, sizeof(cpu_stats));
params = vshCalloc(ctl, nparams, sizeof(*params));
i = 0;
do {
if (virNodeGetCPUStats(ctl->conn, cpuNum, params, &nparams, 0) != 0) {
vshError(ctl, "%s", _("Unable to get node cpu stats"));
goto cleanup;
}
for (j = 0; j < nparams; j++) {
unsigned long long value = params[j].value;
if (STREQ(params[j].field, VIR_CPU_STATS_KERNEL)) {
cpu_stats[i].sys = value;
} else if (STREQ(params[j].field, VIR_CPU_STATS_USER)) {
cpu_stats[i].user = value;
} else if (STREQ(params[j].field, VIR_CPU_STATS_IDLE)) {
cpu_stats[i].idle = value;
} else if (STREQ(params[j].field, VIR_CPU_STATS_IOWAIT)) {
cpu_stats[i].iowait = value;
} else if (STREQ(params[j].field, VIR_CPU_STATS_UTILIZATION)) {
cpu_stats[i].util = value;
flag_utilization = true;
}
}
if (flag_utilization || !flag_percent)
break;
i++;
sleep(1);
} while (i < 2);
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);
}
} else {
if (flag_utilization) {
usage = cpu_stats[0].util;
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;
total_time = user_time + sys_time + idle_time + iowait_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);
}
}
ret = true;
cleanup:
VIR_FREE(params);
return ret;
}
/*
* "capabilities" command
*/
@ -11393,6 +11522,7 @@ static const vshCmdDef hostAndHypervisorCmds[] = {
VSH_CMD_FLAG_NOCONNECT},
{"freecell", cmdFreecell, opts_freecell, info_freecell, 0},
{"hostname", cmdHostname, NULL, info_hostname, 0},
{"nodecpustats", cmdNodeCPUStats, opts_node_cpustats, info_nodecpustats, 0},
{"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo, 0},
{"qemu-monitor-command", cmdQemuMonitorCommand, opts_qemu_monitor_command,
info_qemu_monitor_command, 0},

View File

@ -239,6 +239,13 @@ and size of the physical memory. The output corresponds to virNodeInfo
structure. Specifically, the "CPU socket(s)" field means number of CPU
sockets per NUMA cell.
=item B<nodecpustats> optional I<cpu> I<--percent>
Returns cpu stats of the node.
If I<cpu> is specified, this will prints specified cpu statistics only.
If I<--percent> is specified, this will prints percentage of each kind of cpu
statistics during 1 second.
=item B<capabilities>
Print an XML document describing the capabilities of the hypervisor