3 # zvmstat - print vmstat style info per Zone.
4 # This uses DTrace (Solaris 10 3/05).
6 # This program must be run from the global zone as root.
8 # $Id: zvmstat 3 2007-08-01 10:50:08Z brendan $
10 # USAGE: zvmstat [-ht] [interval [count]]
12 # zvmstat # default output
15 # zvmstat 1 # print every 1 second
16 # zvmstat 10 5 # print 5 x 10 second samples
17 # zvmstat -t 5 # print every 5 seconds with time
25 # epi executable pages paged in
26 # epo executable pages paged out
27 # epf executable pages freed
28 # api anonymous pages paged in
29 # apo anonymous pages paged out
30 # apf anonymous pages freed
31 # fpi filesystem pages paged in
32 # fpo filesystem pages paged out
33 # fpf filesystem pages freed
36 # - Zone status should really be provided by Kstat, which currently
37 # provides system wide values, per CPU and per processor set, but not per
38 # zone. DTrace can fill this role in the meantime until Kstat supports zones.
39 # - First output does not contain summary since boot.
43 # COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
47 # The contents of this file are subject to the terms of the
48 # Common Development and Distribution License, Version 1.0 only
49 # (the "License"). You may not use this file except in compliance
52 # You can obtain a copy of the license at Docs/cddl1.txt
53 # or http://www.opensolaris.org/os/licensing.
54 # See the License for the specific language governing permissions
55 # and limitations under the License.
60 # - First output may not contain all zones due to how loops are achieved.
61 # Check for newer versions.
63 # Author: Brendan Gregg [Sydney, Australia]
65 # 11-May-2005 Brendan Gregg Created this.
66 # 26-Jul-2005 " " Improved code.
67 # 08-Jan-2006 " " Last update.
71 ##############################
72 # --- Process Arguments ---
76 opt_time=0; interval=1; counts=1
84 USAGE: zvmstat [-ht] [interval [count]]
85 zvmstat # default output
88 zvmstat 1 # print every 1 second
89 zvmstat 10 5 # print 5 x 10 second samples
90 zvmstat -t 5 # print every 5 seconds with time
95 shift $(( OPTIND - 1 ))
98 if (( "0$1" > 0 )); then
99 interval=$1; counts=-1; shift
101 if (( "0$1" > 0 )); then
106 #################################
107 # --- Main Program, DTrace ---
110 #pragma D option quiet
111 #pragma D option destructive
112 #pragma D option switchrate=10
115 * Command line arguments
117 inline int OPT_time = '$opt_time';
118 inline int INTERVAL = '$interval';
119 inline int COUNTER = '$counts';
122 * Initialise variables
130 re[""] = 0; pi[""] = 0; po[""] = 0;
131 mf[""] = 0; sr[""] = 0; fr[""] = 0;
132 epi[""] = 0; epo[""] = 0; epf[""] = 0;
133 api[""] = 0; apo[""] = 0; apf[""] = 0;
134 fpi[""] = 0; fpo[""] = 0; fpf[""] = 0;
138 * Build zonelist array
140 * Here we want the output of a command to be saved into an array
141 * inside dtrace. This is done by running the command, sending the
142 * output to /dev/null, and by probing its write syscalls from dtrace.
144 * This is an example of a "scraper".
153 system("/usr/sbin/zoneadm list > /dev/null; echo END > /dev/null");
157 * Scrape zone listing
160 /listing && (execname == "zoneadm") &&
161 (curthread->t_procp->p_parent->p_ppid == $pid)/
163 /* read zoneadm output */
164 zonelist[zonemax] = stringof(copyin(arg1, arg2 - 1));
166 /* increment max number of zones */
171 * Finish scraping zones
174 /listing && (execname == "sh") && (ppid == $pid)/
177 * this end tag lets us know our zonelist has finished.
180 listing = stringof(copyin(arg1, arg2 - 1)) == "END" ? 0 : 1;
184 * Record vminfo counters
186 vminfo:::pgrec { re[zonename] += arg0; }
187 vminfo:::as_fault { mf[zonename] += arg0; }
188 vminfo:::scan { sr[zonename] += arg0; }
189 vminfo:::execpgin { epi[zonename] += arg0; }
190 vminfo:::execpgout { epo[zonename] += arg0; }
191 vminfo:::execfree { epf[zonename] += arg0; fr[zonename] += arg0; }
192 vminfo:::anonpgin { api[zonename] += arg0; }
193 vminfo:::anonpgout { apo[zonename] += arg0; }
194 vminfo:::anonfree { apf[zonename] += arg0; fr[zonename] += arg0; }
195 vminfo:::fspgin { fpi[zonename] += arg0; }
196 vminfo:::fspgout { fpo[zonename] += arg0; }
197 vminfo:::fsfree { fpf[zonename] += arg0; fr[zonename] += arg0; }
228 OPT_time ? printf("\n%Y,\n",walltimestamp) : 1;
230 /* print output line */
231 printf("%10s %4s %5s %4s %5s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
232 "ZONE", "re", "mf", "fr", "sr", "epi", "epo", "epf", "api", "apo",
233 "apf", "fpi", "fpo", "fpf");
235 /* ensure zone writes are triggered */
240 * Print zone status line
242 * This is a fairly interesting function in that it loops over the keys in
243 * an associative array and prints out the values. DTrace cant really do
244 * loops, and generally doesnt need to. We "cheat" by generating writes
245 * in the above probe which in turn trigger the probe below which
246 * contains the contents of each loop. Dont do this at home! We are
247 * supposed to use aggreagations instead, wherever possible.
249 * This is an example of a "feedback loop".
251 syscall::write:return
252 /pid == $pid && zonei < zonemax/
255 self->zone = zonelist[zonei];
258 printf("%10s %4d %5d %4d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n",
259 self->zone, re[self->zone], mf[self->zone], fr[self->zone],
260 sr[self->zone], epi[self->zone], epo[self->zone],
261 epf[self->zone], api[self->zone], apo[self->zone],
262 apf[self->zone], fpi[self->zone], fpo[self->zone],
266 re[self->zone] = 0; mf[self->zone] = 0; fr[self->zone] = 0;
267 sr[self->zone] = 0; epi[self->zone] = 0; epo[self->zone] = 0;
268 epf[self->zone] = 0; api[self->zone] = 0; apo[self->zone] = 0;
269 apf[self->zone] = 0; fpi[self->zone] = 0; fpo[self->zone] = 0;
273 /* go to next zone */