1N/A# zvmstat - print vmstat style info per Zone. 1N/A# This uses DTrace (Solaris 10 3/05). 1N/A# This program must be run from the global zone as root. 1N/A# $Id: zvmstat 3 2007-08-01 10:50:08Z brendan $ 1N/A# USAGE: zvmstat [-ht] [interval [count]] 1N/A# zvmstat # default output 1N/A# zvmstat 1 # print every 1 second 1N/A# zvmstat 10 5 # print 5 x 10 second samples 1N/A# zvmstat -t 5 # print every 5 seconds with time 1N/A# epi executable pages paged in 1N/A# epo executable pages paged out 1N/A# epf executable pages freed 1N/A# api anonymous pages paged in 1N/A# apo anonymous pages paged out 1N/A# apf anonymous pages freed 1N/A# fpi filesystem pages paged in 1N/A# fpo filesystem pages paged out 1N/A# fpf filesystem pages freed 1N/A# - Zone status should really be provided by Kstat, which currently 1N/A# provides system wide values, per CPU and per processor set, but not per 1N/A# zone. DTrace can fill this role in the meantime until Kstat supports zones. 1N/A# - First output does not contain summary since boot. 1N/A# SEE ALSO: prstat -Z 1N/A# COPYRIGHT: Copyright (c) 2005 Brendan Gregg. 1N/A# The contents of this file are subject to the terms of the 1N/A# Common Development and Distribution License, Version 1.0 only 1N/A# (the "License"). You may not use this file except in compliance 1N/A# See the License for the specific language governing permissions 1N/A# and limitations under the License. 1N/A# - First output may not contain all zones due to how loops are achieved. 1N/A# Check for newer versions. 1N/A# Author: Brendan Gregg [Sydney, Australia] 1N/A# 11-May-2005 Brendan Gregg Created this. 1N/A# 26-Jul-2005 " " Improved code. 1N/A# 08-Jan-2006 " " Last update. 1N/A############################## 1N/A# --- Process Arguments --- 1N/A### default variables 1N/A USAGE: zvmstat [-ht] [interval [count]] 1N/A zvmstat # default output 1N/A zvmstat 1 # print every 1 second 1N/A zvmstat 10 5 # print 5 x 10 second samples 1N/A zvmstat -t 5 # print every 5 seconds with time 1N/Ashift $(( OPTIND - 1 )) 1N/Aif (( "0$1" > 0 )); then 1N/A interval=$1; counts=-1; shift 1N/Aif (( "0$1" > 0 )); then 1N/A################################# 1N/A# --- Main Program, DTrace --- 1N/A #pragma D option quiet 1N/A #pragma D option destructive 1N/A #pragma D option switchrate=10 1N/A * Command line arguments 1N/A inline int OPT_time = '$opt_time'; 1N/A inline int INTERVAL = '$interval'; 1N/A inline int COUNTER = '$counts'; 1N/A * Initialise variables 1N/A re[""] = 0; pi[""] = 0; po[""] = 0; 1N/A mf[""] = 0; sr[""] = 0; fr[""] = 0; 1N/A epi[""] = 0; epo[""] = 0; epf[""] = 0; 1N/A api[""] = 0; apo[""] = 0; apf[""] = 0; 1N/A fpi[""] = 0; fpo[""] = 0; fpf[""] = 0; 1N/A * Build zonelist array 1N/A * Here we want the output of a command to be saved into an array 1N/A * inside dtrace. This is done by running the command, sending the 1N/A * output to /dev/null, and by probing its write syscalls from dtrace. 1N/A * This is an example of a "scraper". 1N/A system("/usr/sbin/zoneadm list > /dev/null; echo END > /dev/null"); 1N/A * Scrape zone listing 1N/A syscall::write:entry 1N/A /listing && (execname == "zoneadm") && 1N/A (curthread->t_procp->p_parent->p_ppid == $pid)/ 1N/A /* read zoneadm output */ 1N/A zonelist[zonemax] = stringof(copyin(arg1, arg2 - 1)); 1N/A /* increment max number of zones */ 1N/A * Finish scraping zones 1N/A syscall::write:entry 1N/A /listing && (execname == "sh") && (ppid == $pid)/ 1N/A * this end tag lets us know our zonelist has finished. 1N/A listing = stringof(copyin(arg1, arg2 - 1)) == "END" ? 0 : 1; 1N/A * Record vminfo counters 1N/A vminfo:::pgrec { re[zonename] += arg0; } 1N/A vminfo:::as_fault { mf[zonename] += arg0; } 1N/A vminfo:::scan { sr[zonename] += arg0; } 1N/A vminfo:::execpgin { epi[zonename] += arg0; } 1N/A vminfo:::execpgout { epo[zonename] += arg0; } 1N/A vminfo:::execfree { epf[zonename] += arg0; fr[zonename] += arg0; } 1N/A vminfo:::anonpgin { api[zonename] += arg0; } 1N/A vminfo:::anonpgout { apo[zonename] += arg0; } 1N/A vminfo:::anonfree { apf[zonename] += arg0; fr[zonename] += arg0; } 1N/A vminfo:::fspgin { fpi[zonename] += arg0; } 1N/A vminfo:::fspgout { fpo[zonename] += arg0; } 1N/A vminfo:::fsfree { fpf[zonename] += arg0; fr[zonename] += arg0; } 1N/A OPT_time ? printf("\n%Y,\n",walltimestamp) : 1; 1N/A /* print output line */ 1N/A printf("%10s %4s %5s %4s %5s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n", 1N/A "ZONE", "re", "mf", "fr", "sr", "epi", "epo", "epf", "api", "apo", 1N/A "apf", "fpi", "fpo", "fpf"); 1N/A /* ensure zone writes are triggered */ 1N/A * Print zone status line 1N/A * This is a fairly interesting function in that it loops over the keys in 1N/A * an associative array and prints out the values. DTrace cant really do 1N/A * loops, and generally doesnt need to. We "cheat" by generating writes 1N/A * in the above probe which in turn trigger the probe below which 1N/A * contains the contents of each loop. Dont do this at home! We are 1N/A * supposed to use aggreagations instead, wherever possible. 1N/A * This is an example of a "feedback loop". 1N/A syscall::write:return 1N/A /pid == $pid && zonei < zonemax/ 1N/A /* fetch zonename */ 1N/A self->zone = zonelist[zonei]; 1N/A printf("%10s %4d %5d %4d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n", 1N/A self->zone, re[self->zone], mf[self->zone], fr[self->zone], 1N/A sr[self->zone], epi[self->zone], epo[self->zone], 1N/A epf[self->zone], api[self->zone], apo[self->zone], 1N/A apf[self->zone], fpi[self->zone], fpo[self->zone], 1N/A re[self->zone] = 0; mf[self->zone] = 0; fr[self->zone] = 0; 1N/A sr[self->zone] = 0; epi[self->zone] = 0; epo[self->zone] = 0; 1N/A epf[self->zone] = 0; api[self->zone] = 0; apo[self->zone] = 0; 1N/A apf[self->zone] = 0; fpi[self->zone] = 0; fpo[self->zone] = 0; 1N/A fpf[self->zone] = 0; 1N/A /* go to next zone */