提交 7e6cb82d 编写于 作者: M Minoru Usui 提交者: Eric Blake

virNodeGetCPUStats: Implement virsh support

Signed-off-by: NMinoru Usui <usui@mxm.nes.nec.co.jp>
上级 daea15aa
...@@ -3713,6 +3713,135 @@ cmdNodeinfo(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) ...@@ -3713,6 +3713,135 @@ cmdNodeinfo(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
return true; 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 * "capabilities" command
*/ */
...@@ -11393,6 +11522,7 @@ static const vshCmdDef hostAndHypervisorCmds[] = { ...@@ -11393,6 +11522,7 @@ static const vshCmdDef hostAndHypervisorCmds[] = {
VSH_CMD_FLAG_NOCONNECT}, VSH_CMD_FLAG_NOCONNECT},
{"freecell", cmdFreecell, opts_freecell, info_freecell, 0}, {"freecell", cmdFreecell, opts_freecell, info_freecell, 0},
{"hostname", cmdHostname, NULL, info_hostname, 0}, {"hostname", cmdHostname, NULL, info_hostname, 0},
{"nodecpustats", cmdNodeCPUStats, opts_node_cpustats, info_nodecpustats, 0},
{"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo, 0}, {"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo, 0},
{"qemu-monitor-command", cmdQemuMonitorCommand, opts_qemu_monitor_command, {"qemu-monitor-command", cmdQemuMonitorCommand, opts_qemu_monitor_command,
info_qemu_monitor_command, 0}, info_qemu_monitor_command, 0},
......
...@@ -239,6 +239,13 @@ and size of the physical memory. The output corresponds to virNodeInfo ...@@ -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 structure. Specifically, the "CPU socket(s)" field means number of CPU
sockets per NUMA cell. 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> =item B<capabilities>
Print an XML document describing the capabilities of the hypervisor Print an XML document describing the capabilities of the hypervisor
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册