1235368Sgnn#!/usr/bin/sh 2235368Sgnn# 3235368Sgnn# dvmstat - vmstat by PID/name/command. 4235368Sgnn# Written using DTrace (Solaris 10 3/05). 5235368Sgnn# 6235368Sgnn# This program provides vmstat like data for one particular PID, a 7235368Sgnn# process name, or when running a command. It prints statistics 8235368Sgnn# every second. 9235368Sgnn# 10235368Sgnn# $Id: dvmstat 3 2007-08-01 10:50:08Z brendan $ 11235368Sgnn# 12235368Sgnn# USAGE: dvmstat { -p PID | -n name | command } 13235368Sgnn# eg, 14235368Sgnn# dvmstat -p 1871 # examine PID 1871 15235368Sgnn# dvmstat -n tar # examine processes called "tar" 16235368Sgnn# dvmstat df -h # run and examine "df -h" 17235368Sgnn# 18235368Sgnn# FIELDS: 19235368Sgnn# re page reclaims Kbytes 20235368Sgnn# maj major faults Kbytes 21235368Sgnn# mf minor faults Kbytes 22235368Sgnn# fr page frees Kbytes 23235368Sgnn# epi executable page ins Kbytes 24235368Sgnn# epo executable page out Kbytes 25235368Sgnn# api anonymous page ins Kbytes 26235368Sgnn# apo anonymous page outs Kbytes 27235368Sgnn# fpi filesystem page ins Kbytes 28235368Sgnn# fpo filesystem page outs Kbytes 29235368Sgnn# sy system calls number 30235368Sgnn# 31235368Sgnn# SEE ALSO: vmstat(1M) 32235368Sgnn# 33235368Sgnn# NOTES: 34235368Sgnn# 35235368Sgnn# When using dvmstat to run a command - if the command takes some time 36235368Sgnn# to execute, dvmstat will print output every second. If the command runs 37235368Sgnn# in less than a second, then the only one line of output will be printed. 38235368Sgnn# 39235368Sgnn# COPYRIGHT: Copyright (c) 2005 Brendan Gregg. 40235368Sgnn# 41235368Sgnn# CDDL HEADER START 42235368Sgnn# 43235368Sgnn# The contents of this file are subject to the terms of the 44235368Sgnn# Common Development and Distribution License, Version 1.0 only 45235368Sgnn# (the "License"). You may not use this file except in compliance 46235368Sgnn# with the License. 47235368Sgnn# 48235368Sgnn# You can obtain a copy of the license at Docs/cddl1.txt 49235368Sgnn# or http://www.opensolaris.org/os/licensing. 50235368Sgnn# See the License for the specific language governing permissions 51235368Sgnn# and limitations under the License. 52235368Sgnn# 53235368Sgnn# CDDL HEADER END 54235368Sgnn# 55235368Sgnn# Author: Brendan Gregg [Sydney, Australia] 56235368Sgnn# 57235368Sgnn# 12-Jun-2005 Brendan Gregg Created this. 58235368Sgnn# 08-Jan-2006 " " Last update. 59235368Sgnn# 60235368Sgnn 61235368Sgnn############################## 62235368Sgnn# --- Process Arguments --- 63235368Sgnn# 64235368Sgnn 65235368Sgnn### Default variables 66235368Sgnnopt_pid=0; opt_name=0; pid=0; pname="."; opt_command=0; command="" 67235368Sgnn 68235368Sgnn### Process options 69235368Sgnnwhile getopts hn:p: name 70235368Sgnndo 71235368Sgnn case $name in 72235368Sgnn p) opt_pid=1; pid=$OPTARG ;; 73235368Sgnn n) opt_name=1; pname=$OPTARG ;; 74235368Sgnn h|?) cat <<-END >&2 75235368Sgnn USAGE: dvmstat [-h] { -p PID | -n name | command } 76235368Sgnn -p PID # examine this PID 77235368Sgnn -n name # examine this process name 78235368Sgnn eg, 79235368Sgnn dvmstat -p 1871 # examine PID 1871 80235368Sgnn dvmstat -n tar # examine processes called "tar" 81235368Sgnn dvmstat df -h # run and examine "df -h" 82235368Sgnn END 83235368Sgnn exit 1 84235368Sgnn esac 85235368Sgnndone 86235368Sgnnshift `expr $OPTIND - 1` 87235368Sgnn 88235368Sgnn 89235368Sgnn### Option logic 90235368Sgnnif [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then 91235368Sgnn opt_command=1 92235368Sgnn if [ "$*" = "" ]; then 93235368Sgnn $0 -h 94235368Sgnn exit 95235368Sgnn fi 96235368Sgnn command="$*" 97235368Sgnnfi 98235368Sgnn 99235368Sgnn 100235368Sgnn################################# 101235368Sgnn# --- Main Program, DTrace --- 102235368Sgnn# 103235368Sgnndtrace=' 104235368Sgnn #pragma D option quiet 105235368Sgnn 106235368Sgnn /* 107235368Sgnn * Command line arguments 108235368Sgnn */ 109235368Sgnn inline int OPT_pid = '$opt_pid'; 110235368Sgnn inline int OPT_name = '$opt_name'; 111235368Sgnn inline int OPT_command = '$opt_command'; 112235368Sgnn inline int PID = '$pid'; 113235368Sgnn inline string NAME = "'$pname'"; 114235368Sgnn inline string COMMAND = "'$command'"; 115235368Sgnn inline int SCREEN = 21; 116235368Sgnn 117235368Sgnn /* 118235368Sgnn * Initialise variables 119235368Sgnn */ 120235368Sgnn dtrace:::BEGIN 121235368Sgnn { 122235368Sgnn epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0; 123235368Sgnn re = 0; mf = 0; maj = 0; fr = 0; sy = 0; 124235368Sgnn lines = SCREEN + 1; 125235368Sgnn header = 0; 126235368Sgnn } 127235368Sgnn 128235368Sgnn /* 129235368Sgnn * Print header 130235368Sgnn */ 131235368Sgnn dtrace:::BEGIN, 132235368Sgnn dtrace:::END, 133235368Sgnn profile:::tick-1sec 134235368Sgnn /(OPT_command && probename == "END") || 135235368Sgnn (!(OPT_command && probename == "BEGIN") && lines++ > SCREEN)/ 136235368Sgnn { 137235368Sgnn printf("%6s %5s %5s %4s %4s %4s %4s %4s %4s %4s %6s\n", 138235368Sgnn "re", "maj", "mf", "fr", "epi", "epo", "api", "apo", 139235368Sgnn "fpi", "fpo", "sy"); 140235368Sgnn lines = 0; 141235368Sgnn } 142235368Sgnn 143235368Sgnn /* 144235368Sgnn * Probe events 145235368Sgnn * 146235368Sgnn * this intentionally does not use an associative array for storing data, 147235368Sgnn * for reasons of performance. 148235368Sgnn */ 149235368Sgnn 150235368Sgnn vminfo:::execpgin 151235368Sgnn /(OPT_pid && pid == PID) || 152235368Sgnn (OPT_name && execname == NAME) || 153235368Sgnn (OPT_command && pid == $target)/ 154235368Sgnn { epi += arg0; } 155235368Sgnn 156235368Sgnn vminfo:::execpgout 157235368Sgnn /(OPT_pid && pid == PID) || 158235368Sgnn (OPT_name && execname == NAME) || 159235368Sgnn (OPT_command && pid == $target)/ 160235368Sgnn { epo += arg0; } 161235368Sgnn 162235368Sgnn vminfo:::anonpgin 163235368Sgnn /(OPT_pid && pid == PID) || 164235368Sgnn (OPT_name && execname == NAME) || 165235368Sgnn (OPT_command && pid == $target)/ 166235368Sgnn { api += arg0; } 167235368Sgnn 168235368Sgnn vminfo:::anonpgout 169235368Sgnn /(OPT_pid && pid == PID) || 170235368Sgnn (OPT_name && execname == NAME) || 171235368Sgnn (OPT_command && pid == $target)/ 172235368Sgnn { apo += arg0; } 173235368Sgnn 174235368Sgnn vminfo:::fspgin 175235368Sgnn /(OPT_pid && pid == PID) || 176235368Sgnn (OPT_name && execname == NAME) || 177235368Sgnn (OPT_command && pid == $target)/ 178235368Sgnn { fpi += arg0; } 179235368Sgnn 180235368Sgnn vminfo:::fspgout 181235368Sgnn /(OPT_pid && pid == PID) || 182235368Sgnn (OPT_name && execname == NAME) || 183235368Sgnn (OPT_command && pid == $target)/ 184235368Sgnn { fpo += arg0; } 185235368Sgnn 186235368Sgnn vminfo:::pgrec 187235368Sgnn /(OPT_pid && pid == PID) || 188235368Sgnn (OPT_name && execname == NAME) || 189235368Sgnn (OPT_command && pid == $target)/ 190235368Sgnn { re += arg0; } 191235368Sgnn 192235368Sgnn vminfo:::as_fault 193235368Sgnn /(OPT_pid && pid == PID) || 194235368Sgnn (OPT_name && execname == NAME) || 195235368Sgnn (OPT_command && pid == $target)/ 196235368Sgnn { mf += arg0; } 197235368Sgnn 198235368Sgnn vminfo:::maj_fault 199235368Sgnn /(OPT_pid && pid == PID) || 200235368Sgnn (OPT_name && execname == NAME) || 201235368Sgnn (OPT_command && pid == $target)/ 202235368Sgnn { maj += arg0; } 203235368Sgnn 204235368Sgnn vminfo:::dfree 205235368Sgnn /(OPT_pid && pid == PID) || 206235368Sgnn (OPT_name && execname == NAME) || 207235368Sgnn (OPT_command && pid == $target)/ 208235368Sgnn { fr += arg0; } 209235368Sgnn 210235368Sgnn syscall:::entry 211235368Sgnn /(OPT_pid && pid == PID) || 212235368Sgnn (OPT_name && execname == NAME) || 213235368Sgnn (OPT_command && pid == $target)/ 214235368Sgnn { sy++; } 215235368Sgnn 216235368Sgnn /* 217235368Sgnn * Print output line 218235368Sgnn */ 219235368Sgnn profile:::tick-1sec, 220235368Sgnn dtrace:::END 221235368Sgnn { 222235368Sgnn /* convert to Kbytes */ 223235368Sgnn re *= `_pagesize / 1024; 224235368Sgnn maj *= `_pagesize / 1024; 225235368Sgnn mf *= `_pagesize / 1024; 226235368Sgnn fr *= `_pagesize / 1024; 227235368Sgnn epi *= `_pagesize / 1024; 228235368Sgnn epo *= `_pagesize / 1024; 229235368Sgnn api *= `_pagesize / 1024; 230235368Sgnn apo *= `_pagesize / 1024; 231235368Sgnn fpi *= `_pagesize / 1024; 232235368Sgnn fpo *= `_pagesize / 1024; 233235368Sgnn 234235368Sgnn /* print line */ 235235368Sgnn printf("%6d %5d %5d %4d %4d %4d %4d %4d %4d %4d %6d\n", 236235368Sgnn re, maj, mf, fr, epi, epo, api, apo, fpi, fpo, sy); 237235368Sgnn 238235368Sgnn /* clear counters */ 239235368Sgnn epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0; 240235368Sgnn re = 0; mf = 0; maj = 0; fr = 0; sy = 0; 241235368Sgnn } 242235368Sgnn' 243235368Sgnn 244235368Sgnn### Run DTrace 245235368Sgnnif [ $opt_command -eq 1 ]; then 246235368Sgnn /usr/sbin/dtrace -n "$dtrace" -x evaltime=exec -c "$command" >&2 247235368Sgnnelse 248235368Sgnn /usr/sbin/dtrace -n "$dtrace" >&2 249235368Sgnnfi 250235368Sgnn 251