summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-10-16 19:57:24 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-10-16 19:57:24 +0000
commit1ed814385623c8b66a0b33d4100f0d7d7f404e41 (patch)
tree65655ef19c2e4ea752fb435f08138973cc840568 /usr.sbin
parent36f1355a25c3c5f41f9c1e4b588c8bc1efc46da9 (diff)
Add domain utilisation to status display.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/ldomctl/ldomctl.c88
1 files changed, 74 insertions, 14 deletions
diff --git a/usr.sbin/ldomctl/ldomctl.c b/usr.sbin/ldomctl/ldomctl.c
index cfa0d8fb1f9..9870a1e14c4 100644
--- a/usr.sbin/ldomctl/ldomctl.c
+++ b/usr.sbin/ldomctl/ldomctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldomctl.c,v 1.3 2012/10/15 20:28:50 kettenis Exp $ */
+/* $OpenBSD: ldomctl.c,v 1.4 2012/10/16 19:57:23 kettenis Exp $ */
/*
* Copyright (c) 2012 Mark Kettenis
@@ -94,6 +94,14 @@ struct hvctl_rs_guest_softstate {
char soft_state_str[SOFT_STATE_SIZE];
};
+struct hvctl_rs_guest_util {
+ uint64_t lifespan;
+ uint64_t wallclock_delta;
+ uint64_t active_delta;
+ uint64_t stopped_cycles;
+ uint64_t yielded_cycles;
+};
+
struct hvctl_msg {
struct hvctl_header hdr;
union {
@@ -114,6 +122,7 @@ struct hvctl_msg {
#define HVCTL_INFO_GUEST_STATE 0
#define HVCTL_INFO_GUEST_SOFT_STATE 1
+#define HVCTL_INFO_GUEST_UTILISATION 3
struct command {
const char *cmd_name;
@@ -126,6 +135,8 @@ struct guest {
const char *name;
uint64_t gid;
+ int num_cpus;
+
TAILQ_ENTRY(guest) link;
};
@@ -272,6 +283,7 @@ void
add_guest(struct md_node *node)
{
struct guest *guest;
+ struct md_prop *prop;
guest = xmalloc (sizeof(*guest));
@@ -280,6 +292,15 @@ add_guest(struct md_node *node)
if (!md_get_prop_val(hvmd, node, "gid", &guest->gid))
goto free;
+ guest->num_cpus = 0;
+ TAILQ_FOREACH(prop, &node->prop_list, link) {
+ if (prop->tag == MD_PROP_ARC &&
+ strcmp(prop->name->str, "fwd") == 0) {
+ if (strcmp(prop->d.arc.node->name->str, "cpu") == 0)
+ guest->num_cpus++;
+ }
+ }
+
TAILQ_INSERT_TAIL(&guests, guest, link);
free:
free(guest);
@@ -355,12 +376,14 @@ guest_status(int argc, char **argv)
{
struct hvctl_msg msg;
ssize_t nbytes;
- struct hvctl_rs_guest_state *state;
- struct hvctl_rs_guest_softstate *softstate;
+ struct hvctl_rs_guest_state state;
+ struct hvctl_rs_guest_softstate softstate;
+ struct hvctl_rs_guest_util util;
struct guest *guest;
uint64_t gid = -1;
+ uint64_t total_cycles, yielded_cycles;
+ double utilisation = 0.0;
const char *state_str;
- const char *soft_state_str;
char buf[64];
if (argc < 1 || argc > 2)
@@ -390,11 +413,13 @@ guest_status(int argc, char **argv)
if (nbytes != sizeof(msg))
err(1, "read");
- state = (void *)msg.msg.resstat.data;
- switch (state->state) {
+ memcpy(&state, msg.msg.resstat.data, sizeof(state));
+ switch (state.state) {
case GUEST_STATE_STOPPED:
state_str = "stopped";
- soft_state_str = "";
+ break;
+ case GUEST_STATE_RESETTING:
+ state_str = "resetting";
break;
case GUEST_STATE_NORMAL:
state_str = "running";
@@ -414,22 +439,57 @@ guest_status(int argc, char **argv)
if (nbytes != sizeof(msg))
err(1, "read");
- softstate = (void *)msg.msg.resstat.data;
- soft_state_str = softstate->soft_state_str;
+ memcpy(&softstate, msg.msg.resstat.data,
+ sizeof(softstate));
+
+ bzero(&msg, sizeof(msg));
+ msg.hdr.op = HVCTL_OP_GET_RES_STAT;
+ msg.hdr.seq = seq++;
+ msg.msg.resstat.res = HVCTL_RES_GUEST;
+ msg.msg.resstat.resid = guest->gid;
+ msg.msg.resstat.infoid = HVCTL_INFO_GUEST_UTILISATION;
+ nbytes = write(fd, &msg, sizeof(msg));
+ if (nbytes != sizeof(msg))
+ err(1, "write");
+
+ bzero(&msg, sizeof(msg));
+ nbytes = read(fd, &msg, sizeof(msg));
+ if (nbytes != sizeof(msg))
+ err(1, "read");
+
+ memcpy(&util, msg.msg.resstat.data, sizeof(util));
+
+ total_cycles = util.active_delta * guest->num_cpus
+ - util.stopped_cycles;
+ yielded_cycles = util.yielded_cycles;
+ if (yielded_cycles <= total_cycles)
+ utilisation = (100.0 * (total_cycles
+ - yielded_cycles)) / total_cycles;
+ else
+ utilisation = 0.0;
+
+ break;
+ case GUEST_STATE_SUSPENDED:
+ state_str = "suspended";
+ break;
+ case GUEST_STATE_EXITING:
+ state_str = "exiting";
break;
case GUEST_STATE_UNCONFIGURED:
state_str = "unconfigured";
- soft_state_str = "";
break;
default:
snprintf(buf, sizeof(buf), "unknown (%lld)",
- state->state);
+ state.state);
state_str = buf;
- soft_state_str = "";
break;
}
- printf("%-16s %-16s %-32s\n", guest->name, state_str,
- soft_state_str);
+ if (state.state != GUEST_STATE_NORMAL)
+ printf("%-16s %-16s\n", guest->name, state_str);
+ else
+ printf("%-16s %-16s %-32s %3.0f%%\n", guest->name,
+ state_str, softstate.soft_state_str,
+ utilisation);
}
}