summaryrefslogtreecommitdiffstats
path: root/cddl/contrib/dtracetoolkit/Zones/zvmstat
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/contrib/dtracetoolkit/Zones/zvmstat')
-rwxr-xr-xcddl/contrib/dtracetoolkit/Zones/zvmstat277
1 files changed, 277 insertions, 0 deletions
diff --git a/cddl/contrib/dtracetoolkit/Zones/zvmstat b/cddl/contrib/dtracetoolkit/Zones/zvmstat
new file mode 100755
index 0000000..e49f89c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Zones/zvmstat
@@ -0,0 +1,277 @@
+#!/usr/bin/ksh
+#
+# zvmstat - print vmstat style info per Zone.
+# This uses DTrace (Solaris 10 3/05).
+#
+# This program must be run from the global zone as root.
+#
+# $Id: zvmstat 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: zvmstat [-ht] [interval [count]]
+#
+# zvmstat # default output
+# -t # print times
+# eg,
+# zvmstat 1 # print every 1 second
+# zvmstat 10 5 # print 5 x 10 second samples
+# zvmstat -t 5 # print every 5 seconds with time
+#
+#
+# FIELDS:
+# re page reclaims
+# mf minor faults
+# fr pages freed
+# sr scan rate
+# epi executable pages paged in
+# epo executable pages paged out
+# epf executable pages freed
+# api anonymous pages paged in
+# apo anonymous pages paged out
+# apf anonymous pages freed
+# fpi filesystem pages paged in
+# fpo filesystem pages paged out
+# fpf filesystem pages freed
+#
+# NOTES:
+# - Zone status should really be provided by Kstat, which currently
+# provides system wide values, per CPU and per processor set, but not per
+# zone. DTrace can fill this role in the meantime until Kstat supports zones.
+# - First output does not contain summary since boot.
+#
+# SEE ALSO: prstat -Z
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# BUGS:
+# - First output may not contain all zones due to how loops are achieved.
+# Check for newer versions.
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 11-May-2005 Brendan Gregg Created this.
+# 26-Jul-2005 " " Improved code.
+# 08-Jan-2006 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_time=0; interval=1; counts=1
+
+### process options
+while getopts ht name
+do
+ case $name in
+ t) opt_time=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: zvmstat [-ht] [interval [count]]
+ zvmstat # default output
+ -t # print times
+ eg,
+ zvmstat 1 # print every 1 second
+ zvmstat 10 5 # print 5 x 10 second samples
+ zvmstat -t 5 # print every 5 seconds with time
+ END
+ exit 1
+ esac
+done
+shift $(( OPTIND - 1 ))
+
+### option logic
+if (( "0$1" > 0 )); then
+ interval=$1; counts=-1; shift
+fi
+if (( "0$1" > 0 )); then
+ counts=$1; shift
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+dtrace -n '
+ #pragma D option quiet
+ #pragma D option destructive
+ #pragma D option switchrate=10
+
+ /*
+ * Command line arguments
+ */
+ inline int OPT_time = '$opt_time';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$counts';
+
+ /*
+ * Initialise variables
+ */
+ dtrace:::BEGIN
+ {
+ secs = INTERVAL;
+ counts = COUNTER;
+ zonemax = 0;
+ listing = 1;
+ re[""] = 0; pi[""] = 0; po[""] = 0;
+ mf[""] = 0; sr[""] = 0; fr[""] = 0;
+ epi[""] = 0; epo[""] = 0; epf[""] = 0;
+ api[""] = 0; apo[""] = 0; apf[""] = 0;
+ fpi[""] = 0; fpo[""] = 0; fpf[""] = 0;
+ }
+
+ /*
+ * Build zonelist array
+ *
+ * Here we want the output of a command to be saved into an array
+ * inside dtrace. This is done by running the command, sending the
+ * output to /dev/null, and by probing its write syscalls from dtrace.
+ *
+ * This is an example of a "scraper".
+ */
+
+ /*
+ * List zones
+ */
+ dtrace:::BEGIN
+ {
+ /* run zoneadm */
+ system("/usr/sbin/zoneadm list > /dev/null; echo END > /dev/null");
+ }
+
+ /*
+ * Scrape zone listing
+ */
+ syscall::write:entry
+ /listing && (execname == "zoneadm") &&
+ (curthread->t_procp->p_parent->p_ppid == $pid)/
+ {
+ /* read zoneadm output */
+ zonelist[zonemax] = stringof(copyin(arg1, arg2 - 1));
+
+ /* increment max number of zones */
+ zonemax++;
+ }
+
+ /*
+ * Finish scraping zones
+ */
+ syscall::write:entry
+ /listing && (execname == "sh") && (ppid == $pid)/
+ {
+ /*
+ * this end tag lets us know our zonelist has finished.
+ * thanks A. Packer.
+ */
+ listing = stringof(copyin(arg1, arg2 - 1)) == "END" ? 0 : 1;
+ }
+
+ /*
+ * Record vminfo counters
+ */
+ vminfo:::pgrec { re[zonename] += arg0; }
+ vminfo:::as_fault { mf[zonename] += arg0; }
+ vminfo:::scan { sr[zonename] += arg0; }
+ vminfo:::execpgin { epi[zonename] += arg0; }
+ vminfo:::execpgout { epo[zonename] += arg0; }
+ vminfo:::execfree { epf[zonename] += arg0; fr[zonename] += arg0; }
+ vminfo:::anonpgin { api[zonename] += arg0; }
+ vminfo:::anonpgout { apo[zonename] += arg0; }
+ vminfo:::anonfree { apf[zonename] += arg0; fr[zonename] += arg0; }
+ vminfo:::fspgin { fpi[zonename] += arg0; }
+ vminfo:::fspgout { fpo[zonename] += arg0; }
+ vminfo:::fsfree { fpf[zonename] += arg0; fr[zonename] += arg0; }
+
+ /*
+ * Timer
+ */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /*
+ * Check for exit
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /*
+ * Print header line
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* set counters */
+ secs = INTERVAL;
+ counts--;
+ zonei = 0;
+
+ /* print time */
+ OPT_time ? printf("\n%Y,\n",walltimestamp) : 1;
+
+ /* print output line */
+ printf("%10s %4s %5s %4s %5s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
+ "ZONE", "re", "mf", "fr", "sr", "epi", "epo", "epf", "api", "apo",
+ "apf", "fpi", "fpo", "fpf");
+
+ /* ensure zone writes are triggered */
+ printf(" \b");
+ }
+
+ /*
+ * Print zone status line
+ *
+ * This is a fairly interesting function in that it loops over the keys in
+ * an associative array and prints out the values. DTrace cant really do
+ * loops, and generally doesnt need to. We "cheat" by generating writes
+ * in the above probe which in turn trigger the probe below which
+ * contains the contents of each loop. Dont do this at home! We are
+ * supposed to use aggreagations instead, wherever possible.
+ *
+ * This is an example of a "feedback loop".
+ */
+ syscall::write:return
+ /pid == $pid && zonei < zonemax/
+ {
+ /* fetch zonename */
+ self->zone = zonelist[zonei];
+
+ /* print output */
+ printf("%10s %4d %5d %4d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n",
+ self->zone, re[self->zone], mf[self->zone], fr[self->zone],
+ sr[self->zone], epi[self->zone], epo[self->zone],
+ epf[self->zone], api[self->zone], apo[self->zone],
+ apf[self->zone], fpi[self->zone], fpo[self->zone],
+ fpf[self->zone]);
+
+ /* clear values */
+ re[self->zone] = 0; mf[self->zone] = 0; fr[self->zone] = 0;
+ sr[self->zone] = 0; epi[self->zone] = 0; epo[self->zone] = 0;
+ epf[self->zone] = 0; api[self->zone] = 0; apo[self->zone] = 0;
+ apf[self->zone] = 0; fpi[self->zone] = 0; fpo[self->zone] = 0;
+ fpf[self->zone] = 0;
+ self->zone = 0;
+
+ /* go to next zone */
+ zonei++;
+ }
+'
+
OpenPOWER on IntegriCloud