1235368Sgnn#!/usr/bin/sh 2235368Sgnn# 3235368Sgnn# xvmstat - extended vmstat demo in DTrace. 4235368Sgnn# Written using DTrace (Solaris 10 3/05). 5235368Sgnn# 6235368Sgnn# This has been written to demonstrate fetching similar data as vmstat 7235368Sgnn# from DTrace, with a few extra fields. 8235368Sgnn# 9235368Sgnn# $Id: xvmstat 3 2007-08-01 10:50:08Z brendan $ 10235368Sgnn# 11235368Sgnn# USAGE: xvmstat [interval [count]] 12235368Sgnn# 13235368Sgnn# FIELDS: 14235368Sgnn# w swapped out LWPs number 15235368Sgnn# swap virtual memory free Mbytes 16235368Sgnn# free free RAM Mbytes 17235368Sgnn# re page reclaims pages/sec 18235368Sgnn# maj major faults pages/sec 19235368Sgnn# mf minor faults pages/sec 20235368Sgnn# cow copy-on-write faults pages/sec 21235368Sgnn# pro protection faults pages/sec 22235368Sgnn# sr scan rate pages/sec 23235368Sgnn# epi executable page ins pages/sec 24235368Sgnn# epo executable page outs pages/sec 25235368Sgnn# epf executable frees pages/sec 26235368Sgnn# api anonymous page ins pages/sec 27235368Sgnn# apo anonymous page outs pages/sec 28235368Sgnn# apf anonymous frees pages/sec 29235368Sgnn# fpi filesystem page ins pages/sec 30235368Sgnn# fpo filesystem page outs pages/sec 31235368Sgnn# fpf filesystem frees pages/sec 32235368Sgnn# 33235368Sgnn# NOTES: 34235368Sgnn# - Most of the statistics are in units of pages, unlike the 35235368Sgnn# original vmstat command which sometimes uses kilobytes. 36235368Sgnn# - As this program does not use Kstat, there is no summary since boot line. 37235368Sgnn# - Free RAM is both free free + cache free. 38235368Sgnn# 39235368Sgnn# SEE ALSO: vmstat(1M) 40235368Sgnn# 41235368Sgnn# COPYRIGHT: Copyright (c) 2005 Brendan Gregg. 42235368Sgnn# 43235368Sgnn# CDDL HEADER START 44235368Sgnn# 45235368Sgnn# The contents of this file are subject to the terms of the 46235368Sgnn# Common Development and Distribution License, Version 1.0 only 47235368Sgnn# (the "License"). You may not use this file except in compliance 48235368Sgnn# with the License. 49235368Sgnn# 50235368Sgnn# You can obtain a copy of the license at Docs/cddl1.txt 51235368Sgnn# or http://www.opensolaris.org/os/licensing. 52235368Sgnn# See the License for the specific language governing permissions 53235368Sgnn# and limitations under the License. 54235368Sgnn# 55235368Sgnn# CDDL HEADER END 56235368Sgnn# 57235368Sgnn# 12-Jun-2005 Brendan Gregg Created this. 58235368Sgnn# 01-Mar-2006 " " Last update. 59235368Sgnn# 60235368Sgnn 61235368Sgnn############################## 62235368Sgnn# --- Process Arguments --- 63235368Sgnn# 64235368Sgnn 65235368Sgnn### default values 66235368Sgnninterval=1; count=-1 67235368Sgnn 68235368Sgnn### check arguments 69235368Sgnnif [ "$1" = "-h" -o "$1" = "--help" ]; then 70235368Sgnn cat <<-END >&2 71235368Sgnn USAGE: xvmstat [interval [count]] 72235368Sgnn xvmstat # 1 second samples, infinite 73235368Sgnn eg, 74235368Sgnn xvmstat 1 # print every 1 second 75235368Sgnn xvmstat 5 6 # print every 5 seconds, 6 times 76235368Sgnn END 77235368Sgnn exit 1 78235368Sgnnfi 79235368Sgnn 80235368Sgnn### argument logic 81235368Sgnnif [ "$1" -gt 0 ]; then 82235368Sgnn interval=$1; count=-1; shift 83235368Sgnnfi 84235368Sgnnif [ "$1" -gt 0 ]; then 85235368Sgnn count=$1; shift 86235368Sgnnfi 87235368Sgnnif [ $interval -eq 0 ]; then 88235368Sgnn interval=1 89235368Sgnnfi 90235368Sgnn 91235368Sgnn 92235368Sgnn################################# 93235368Sgnn# --- Main Program, DTrace --- 94235368Sgnn# 95235368Sgnn/usr/sbin/dtrace -n ' 96235368Sgnn #pragma D option quiet 97235368Sgnn 98235368Sgnn /* 99235368Sgnn * Command line arguments 100235368Sgnn */ 101235368Sgnn inline int INTERVAL = '$interval'; 102235368Sgnn inline int COUNTER = '$count'; 103235368Sgnn inline int SCREEN = 21; 104235368Sgnn 105235368Sgnn /* 106235368Sgnn * Initialise variables 107235368Sgnn */ 108235368Sgnn dtrace:::BEGIN 109235368Sgnn { 110235368Sgnn re = 0; sr = 0; mf = 0; maj = 0; cow = 0; pro = 0; 111235368Sgnn epi = 0; epo = 0; epf = 0; api = 0; apo = 0; apf = 0; 112235368Sgnn fpi = 0; fpo = 0; fpf = 0; 113235368Sgnn lines = SCREEN + 1; 114235368Sgnn counts = COUNTER; 115235368Sgnn secs = INTERVAL; 116235368Sgnn first = 1; 117235368Sgnn } 118235368Sgnn 119235368Sgnn profile:::tick-1sec 120235368Sgnn { 121235368Sgnn secs--; 122235368Sgnn } 123235368Sgnn 124235368Sgnn /* 125235368Sgnn * Print header 126235368Sgnn */ 127235368Sgnn dtrace:::BEGIN, 128235368Sgnn profile:::tick-1sec 129235368Sgnn /first || (secs == 0 && lines > SCREEN)/ 130235368Sgnn { 131235368Sgnn printf("%2s %6s %5s %5s %3s %4s %3s %3s %3s ", 132235368Sgnn "w", "swap", "free", "re", "maj", "mf", "cow", "pro", "sr"); 133235368Sgnn printf("%3s %3s %3s %3s %3s %3s %3s %3s %3s\n", 134235368Sgnn "epi", "epo", "epf", "api", "apo", "apf", "fpi", "fpo", "fpf"); 135235368Sgnn lines = 0; 136235368Sgnn first = 0; 137235368Sgnn } 138235368Sgnn 139235368Sgnn /* 140235368Sgnn * Probe events 141235368Sgnn */ 142235368Sgnn vminfo:::pgrec { re += arg0; } 143235368Sgnn vminfo:::scan { sr += arg0; } 144235368Sgnn vminfo:::as_fault { mf += arg0; } 145235368Sgnn vminfo:::execpgin { epi += arg0; } 146235368Sgnn vminfo:::execpgout { epo += arg0; } 147235368Sgnn vminfo:::execfree { epf += arg0; } 148235368Sgnn vminfo:::anonpgin { api += arg0; } 149235368Sgnn vminfo:::anonpgout { apo += arg0; } 150235368Sgnn vminfo:::anonfree { apf += arg0; } 151235368Sgnn vminfo:::fspgin { fpi += arg0; } 152235368Sgnn vminfo:::fspgout { fpo += arg0; } 153235368Sgnn vminfo:::fsfree { fpf += arg0; } 154235368Sgnn vminfo:::maj_fault { maj += arg0; } 155235368Sgnn vminfo:::cow_fault { cow += arg0; } 156235368Sgnn vminfo:::prot_fault { pro += arg0; } 157235368Sgnn 158235368Sgnn /* 159235368Sgnn * Print output line 160235368Sgnn */ 161235368Sgnn profile:::tick-1sec 162235368Sgnn /secs == 0/ 163235368Sgnn { 164235368Sgnn /* fetch free mem */ 165235368Sgnn this->free = `freemem; 166235368Sgnn 167235368Sgnn /* 168235368Sgnn * fetch free swap 169235368Sgnn * 170235368Sgnn * free swap is described in /usr/include/vm/anon.h as, 171235368Sgnn * MAX(ani_max - ani_resv, 0) + (availrmem - swapfs_minfree) 172235368Sgnn */ 173235368Sgnn this->ani_max = `k_anoninfo.ani_max; 174235368Sgnn this->ani_resv = `k_anoninfo.ani_phys_resv + `k_anoninfo.ani_mem_resv; 175235368Sgnn this->swap = (this->ani_max - this->ani_resv > 0 ? 176235368Sgnn this->ani_max - this->ani_resv : 0) + `availrmem - `swapfs_minfree; 177235368Sgnn 178235368Sgnn /* fetch w */ 179235368Sgnn this->w = `nswapped; 180235368Sgnn 181235368Sgnn /* convert to Mbytes */ 182235368Sgnn this->swap *= `_pagesize; this->swap /= 1048576; 183235368Sgnn this->free *= `_pagesize; this->free /= 1048576; 184235368Sgnn 185235368Sgnn /* convert to per second values */ 186235368Sgnn re /= INTERVAL; maj /= INTERVAL; mf /= INTERVAL; 187235368Sgnn cow /= INTERVAL; pro /= INTERVAL; sr /= INTERVAL; 188235368Sgnn epi /= INTERVAL; epo /= INTERVAL; epf /= INTERVAL; 189235368Sgnn api /= INTERVAL; apo /= INTERVAL; apf /= INTERVAL; 190235368Sgnn fpi /= INTERVAL; fpo /= INTERVAL; fpf /= INTERVAL; 191235368Sgnn 192235368Sgnn /* print line */ 193235368Sgnn printf("%2d %6d %5d %5d %3d %4d %3d %3d %3d ", 194235368Sgnn this->w, this->swap, this->free, re, maj, mf, cow, pro, sr); 195235368Sgnn printf("%3d %3d %3d %3d %3d %3d %3d %3d %3d\n", 196235368Sgnn epi, epo, epf, api, apo, apf, fpi, fpo, fpf); 197235368Sgnn 198235368Sgnn /* clear counters */ 199235368Sgnn re = 0; sr = 0; mf = 0; maj = 0; cow = 0; pro = 0; 200235368Sgnn epi = 0; epo = 0; epf = 0; api = 0; apo = 0; apf = 0; 201235368Sgnn fpi = 0; fpo = 0; fpf = 0; 202235368Sgnn 203235368Sgnn /* process counts */ 204235368Sgnn secs = INTERVAL; 205235368Sgnn counts--; 206235368Sgnn lines++; 207235368Sgnn } 208235368Sgnn 209235368Sgnn /* 210235368Sgnn * End 211235368Sgnn */ 212235368Sgnn profile:::tick-1sec 213235368Sgnn /counts == 0/ 214235368Sgnn { 215235368Sgnn exit(0); 216235368Sgnn } 217235368Sgnn' 218