Home | History | Annotate | Line # | Download | only in Bin
      1 #!/usr/bin/sh
      2 #
      3 # dvmstat - vmstat by PID/name/command.
      4 #           Written using DTrace (Solaris 10 3/05).
      5 #
      6 # This program provides vmstat like data for one particular PID, a 
      7 # process name, or when running a command. It prints statistics
      8 # every second.
      9 #
     10 # $Id: dvmstat,v 1.1.1.1 2015/09/30 22:01:07 christos Exp $
     11 #
     12 # USAGE:	dvmstat { -p PID | -n name | command }
     13 #  eg,
     14 #		dvmstat -p 1871       # examine PID 1871
     15 #		dvmstat -n tar        # examine processes called "tar"
     16 #		dvmstat df -h         # run and examine "df -h"
     17 #
     18 # FIELDS: 
     19 #		re	page reclaims		Kbytes
     20 #		maj	major faults		Kbytes
     21 #		mf	minor faults		Kbytes
     22 #		fr	page frees		Kbytes
     23 #		epi	executable page ins	Kbytes
     24 #		epo	executable page out	Kbytes
     25 #		api	anonymous page ins	Kbytes
     26 #		apo	anonymous page outs	Kbytes
     27 #		fpi	filesystem page ins	Kbytes
     28 #		fpo	filesystem page outs	Kbytes
     29 #		sy	system calls		number
     30 #
     31 # SEE ALSO:	vmstat(1M)
     32 #
     33 # NOTES:
     34 #
     35 # When using dvmstat to run a command - if the command takes some time
     36 # to execute, dvmstat will print output every second. If the command runs
     37 # in less than a second, then the only one line of output will be printed.
     38 #
     39 # COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
     40 #
     41 # CDDL HEADER START
     42 #
     43 #  The contents of this file are subject to the terms of the
     44 #  Common Development and Distribution License, Version 1.0 only
     45 #  (the "License").  You may not use this file except in compliance
     46 #  with the License.
     47 #
     48 #  You can obtain a copy of the license at Docs/cddl1.txt
     49 #  or http://www.opensolaris.org/os/licensing.
     50 #  See the License for the specific language governing permissions
     51 #  and limitations under the License.
     52 #
     53 # CDDL HEADER END
     54 #
     55 # Author: Brendan Gregg  [Sydney, Australia]
     56 #
     57 # 12-Jun-2005	Brendan Gregg	Created this.
     58 # 08-Jan-2006	   "      "	Last update.
     59 # 
     60 
     61 ##############################
     62 # --- Process Arguments ---
     63 #
     64 
     65 ### Default variables
     66 opt_pid=0; opt_name=0; pid=0; pname="."; opt_command=0; command=""
     67 
     68 ### Process options
     69 while getopts hn:p: name
     70 do
     71         case $name in
     72         p)      opt_pid=1; pid=$OPTARG ;;
     73         n)      opt_name=1; pname=$OPTARG ;;
     74         h|?)    cat <<-END >&2
     75 		USAGE: dvmstat [-h] { -p PID | -n name | command }
     76 		           -p PID          # examine this PID
     77 		           -n name         # examine this process name
     78 		  eg,
     79 		       dvmstat -p 1871     # examine PID 1871
     80 		       dvmstat -n tar      # examine processes called "tar"
     81 		       dvmstat df -h       # run and examine "df -h"
     82 		END
     83                 exit 1
     84         esac
     85 done
     86 shift `expr $OPTIND - 1`
     87 
     88 
     89 ### Option logic
     90 if [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then
     91         opt_command=1
     92         if [ "$*" = "" ]; then
     93                 $0 -h
     94                 exit
     95         fi
     96         command="$*"
     97 fi
     98 
     99 
    100 #################################
    101 # --- Main Program, DTrace ---
    102 #
    103 dtrace='
    104  #pragma D option quiet
    105 
    106  /*
    107   * Command line arguments
    108   */
    109  inline int OPT_pid      = '$opt_pid';
    110  inline int OPT_name     = '$opt_name';
    111  inline int OPT_command  = '$opt_command';
    112  inline int PID          = '$pid';
    113  inline string NAME      = "'$pname'";
    114  inline string COMMAND   = "'$command'";
    115  inline int SCREEN       = 21;
    116 
    117  /*
    118   * Initialise variables
    119   */
    120  dtrace:::BEGIN
    121  {
    122 	epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0;
    123 	re = 0; mf = 0; maj = 0; fr = 0; sy = 0;
    124 	lines = SCREEN + 1;
    125 	header = 0;
    126  }
    127 
    128  /*
    129   * Print header
    130   */
    131  dtrace:::BEGIN,
    132  dtrace:::END,
    133  profile:::tick-1sec
    134  /(OPT_command && probename == "END") || 
    135   (!(OPT_command && probename == "BEGIN") && lines++ > SCREEN)/
    136  {
    137 	printf("%6s %5s %5s %4s %4s %4s %4s %4s %4s %4s %6s\n",
    138 	    "re", "maj", "mf", "fr", "epi", "epo", "api", "apo", 
    139 	    "fpi", "fpo", "sy");
    140 	lines = 0;
    141  }
    142 
    143  /*
    144   * Probe events
    145   *
    146   * this intentionally does not use an associative array for storing data,
    147   * for reasons of performance.
    148   */
    149 
    150  vminfo:::execpgin
    151  /(OPT_pid && pid == PID) ||
    152   (OPT_name && execname == NAME) ||
    153   (OPT_command && pid == $target)/
    154  { epi += arg0; }
    155 
    156  vminfo:::execpgout
    157  /(OPT_pid && pid == PID) ||
    158   (OPT_name && execname == NAME) ||
    159   (OPT_command && pid == $target)/
    160  { epo += arg0; }
    161 
    162  vminfo:::anonpgin
    163  /(OPT_pid && pid == PID) ||
    164   (OPT_name && execname == NAME) ||
    165   (OPT_command && pid == $target)/
    166  { api += arg0; }
    167 
    168  vminfo:::anonpgout
    169  /(OPT_pid && pid == PID) ||
    170   (OPT_name && execname == NAME) ||
    171   (OPT_command && pid == $target)/
    172  { apo += arg0; }
    173 
    174  vminfo:::fspgin
    175  /(OPT_pid && pid == PID) ||
    176   (OPT_name && execname == NAME) ||
    177   (OPT_command && pid == $target)/
    178  { fpi += arg0; }
    179 
    180  vminfo:::fspgout
    181  /(OPT_pid && pid == PID) ||
    182   (OPT_name && execname == NAME) ||
    183   (OPT_command && pid == $target)/
    184  { fpo += arg0; }
    185 
    186  vminfo:::pgrec
    187  /(OPT_pid && pid == PID) ||
    188   (OPT_name && execname == NAME) ||
    189   (OPT_command && pid == $target)/
    190  { re += arg0; }
    191 
    192  vminfo:::as_fault
    193  /(OPT_pid && pid == PID) ||
    194   (OPT_name && execname == NAME) ||
    195   (OPT_command && pid == $target)/
    196  { mf += arg0; }
    197 
    198  vminfo:::maj_fault
    199  /(OPT_pid && pid == PID) ||
    200   (OPT_name && execname == NAME) ||
    201   (OPT_command && pid == $target)/
    202  { maj += arg0; }
    203 
    204  vminfo:::dfree
    205  /(OPT_pid && pid == PID) ||
    206   (OPT_name && execname == NAME) ||
    207   (OPT_command && pid == $target)/
    208  { fr += arg0; }
    209 
    210  syscall:::entry
    211  /(OPT_pid && pid == PID) ||
    212   (OPT_name && execname == NAME) ||
    213   (OPT_command && pid == $target)/
    214  { sy++; }
    215 
    216  /* 
    217   * Print output line
    218   */
    219  profile:::tick-1sec,
    220  dtrace:::END
    221  {
    222 	/* convert to Kbytes */
    223 	re  *= `_pagesize / 1024;
    224 	maj *= `_pagesize / 1024;
    225 	mf  *= `_pagesize / 1024;
    226 	fr  *= `_pagesize / 1024;
    227 	epi *= `_pagesize / 1024;
    228 	epo *= `_pagesize / 1024;
    229 	api *= `_pagesize / 1024;
    230 	apo *= `_pagesize / 1024;
    231 	fpi *= `_pagesize / 1024;
    232 	fpo *= `_pagesize / 1024;
    233 
    234 	/* print line */
    235 	printf("%6d %5d %5d %4d %4d %4d %4d %4d %4d %4d %6d\n",
    236 	    re, maj, mf, fr, epi, epo, api, apo, fpi, fpo, sy);
    237 
    238 	/* clear counters */
    239 	epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0;
    240 	re = 0; mf = 0; maj = 0; fr = 0; sy = 0;
    241  }
    242 '
    243 
    244 ### Run DTrace
    245 if [ $opt_command -eq 1 ]; then
    246         /usr/sbin/dtrace -n "$dtrace" -x evaltime=exec -c "$command" >&2
    247 else
    248         /usr/sbin/dtrace -n "$dtrace" >&2
    249 fi
    250 
    251