mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-31 18:15:25 +00:00
virNodeGetCPUStats: Implement virsh support
Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp>
This commit is contained in:
parent
daea15aa40
commit
7e6cb82d1c
130
tools/virsh.c
130
tools/virsh.c
@ -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},
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user