1N/A#!/usr/bin/sh
1N/A#
1N/A# dvmstat - vmstat by PID/name/command.
1N/A# Written using DTrace (Solaris 10 3/05).
1N/A#
1N/A# This program provides vmstat like data for one particular PID, a
1N/A# process name, or when running a command. It prints statistics
1N/A# every second.
1N/A#
1N/A# $Id: dvmstat 3 2007-08-01 10:50:08Z brendan $
1N/A#
1N/A# USAGE: dvmstat { -p PID | -n name | command }
1N/A# eg,
1N/A# dvmstat -p 1871 # examine PID 1871
1N/A# dvmstat -n tar # examine processes called "tar"
1N/A# dvmstat df -h # run and examine "df -h"
1N/A#
1N/A# FIELDS:
1N/A# re page reclaims Kbytes
1N/A# maj major faults Kbytes
1N/A# mf minor faults Kbytes
1N/A# fr page frees Kbytes
1N/A# epi executable page ins Kbytes
1N/A# epo executable page out Kbytes
1N/A# api anonymous page ins Kbytes
1N/A# apo anonymous page outs Kbytes
1N/A# fpi filesystem page ins Kbytes
1N/A# fpo filesystem page outs Kbytes
1N/A# sy system calls number
1N/A#
1N/A# SEE ALSO: vmstat(1M)
1N/A#
1N/A# NOTES:
1N/A#
1N/A# When using dvmstat to run a command - if the command takes some time
1N/A# to execute, dvmstat will print output every second. If the command runs
1N/A# in less than a second, then the only one line of output will be printed.
1N/A#
1N/A# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
1N/A#
1N/A# CDDL HEADER START
1N/A#
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# with the License.
1N/A#
1N/A# You can obtain a copy of the license at Docs/cddl1.txt
1N/A# or http://www.opensolaris.org/os/licensing.
1N/A# See the License for the specific language governing permissions
1N/A# and limitations under the License.
1N/A#
1N/A# CDDL HEADER END
1N/A#
1N/A# Author: Brendan Gregg [Sydney, Australia]
1N/A#
1N/A# 12-Jun-2005 Brendan Gregg Created this.
1N/A# 08-Jan-2006 " " Last update.
1N/A#
1N/A
1N/A##############################
1N/A# --- Process Arguments ---
1N/A#
1N/A
1N/A### Default variables
1N/Aopt_pid=0; opt_name=0; pid=0; pname="."; opt_command=0; command=""
1N/A
1N/A### Process options
1N/Awhile getopts hn:p: name
1N/Ado
1N/A case $name in
1N/A p) opt_pid=1; pid=$OPTARG ;;
1N/A n) opt_name=1; pname=$OPTARG ;;
1N/A h|?) cat <<-END >&2
1N/A USAGE: dvmstat [-h] { -p PID | -n name | command }
1N/A -p PID # examine this PID
1N/A -n name # examine this process name
1N/A eg,
1N/A dvmstat -p 1871 # examine PID 1871
1N/A dvmstat -n tar # examine processes called "tar"
1N/A dvmstat df -h # run and examine "df -h"
1N/A END
1N/A exit 1
1N/A esac
1N/Adone
1N/Ashift `expr $OPTIND - 1`
1N/A
1N/A
1N/A### Option logic
1N/Aif [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then
1N/A opt_command=1
1N/A if [ "$*" = "" ]; then
1N/A $0 -h
1N/A exit
1N/A fi
1N/A command="$*"
1N/Afi
1N/A
1N/A
1N/A#################################
1N/A# --- Main Program, DTrace ---
1N/A#
1N/Adtrace='
1N/A #pragma D option quiet
1N/A
1N/A /*
1N/A * Command line arguments
1N/A */
1N/A inline int OPT_pid = '$opt_pid';
1N/A inline int OPT_name = '$opt_name';
1N/A inline int OPT_command = '$opt_command';
1N/A inline int PID = '$pid';
1N/A inline string NAME = "'$pname'";
1N/A inline string COMMAND = "'$command'";
1N/A inline int SCREEN = 21;
1N/A
1N/A /*
1N/A * Initialise variables
1N/A */
1N/A dtrace:::BEGIN
1N/A {
1N/A epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0;
1N/A re = 0; mf = 0; maj = 0; fr = 0; sy = 0;
1N/A lines = SCREEN + 1;
1N/A header = 0;
1N/A }
1N/A
1N/A /*
1N/A * Print header
1N/A */
1N/A dtrace:::BEGIN,
1N/A dtrace:::END,
1N/A profile:::tick-1sec
1N/A /(OPT_command && probename == "END") ||
1N/A (!(OPT_command && probename == "BEGIN") && lines++ > SCREEN)/
1N/A {
1N/A printf("%6s %5s %5s %4s %4s %4s %4s %4s %4s %4s %6s\n",
1N/A "re", "maj", "mf", "fr", "epi", "epo", "api", "apo",
1N/A "fpi", "fpo", "sy");
1N/A lines = 0;
1N/A }
1N/A
1N/A /*
1N/A * Probe events
1N/A *
1N/A * this intentionally does not use an associative array for storing data,
1N/A * for reasons of performance.
1N/A */
1N/A
1N/A vminfo:::execpgin
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { epi += arg0; }
1N/A
1N/A vminfo:::execpgout
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { epo += arg0; }
1N/A
1N/A vminfo:::anonpgin
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { api += arg0; }
1N/A
1N/A vminfo:::anonpgout
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { apo += arg0; }
1N/A
1N/A vminfo:::fspgin
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { fpi += arg0; }
1N/A
1N/A vminfo:::fspgout
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { fpo += arg0; }
1N/A
1N/A vminfo:::pgrec
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { re += arg0; }
1N/A
1N/A vminfo:::as_fault
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { mf += arg0; }
1N/A
1N/A vminfo:::maj_fault
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { maj += arg0; }
1N/A
1N/A vminfo:::dfree
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { fr += arg0; }
1N/A
1N/A syscall:::entry
1N/A /(OPT_pid && pid == PID) ||
1N/A (OPT_name && execname == NAME) ||
1N/A (OPT_command && pid == $target)/
1N/A { sy++; }
1N/A
1N/A /*
1N/A * Print output line
1N/A */
1N/A profile:::tick-1sec,
1N/A dtrace:::END
1N/A {
1N/A /* convert to Kbytes */
1N/A re *= `_pagesize / 1024;
1N/A maj *= `_pagesize / 1024;
1N/A mf *= `_pagesize / 1024;
1N/A fr *= `_pagesize / 1024;
1N/A epi *= `_pagesize / 1024;
1N/A epo *= `_pagesize / 1024;
1N/A api *= `_pagesize / 1024;
1N/A apo *= `_pagesize / 1024;
1N/A fpi *= `_pagesize / 1024;
1N/A fpo *= `_pagesize / 1024;
1N/A
1N/A /* print line */
1N/A printf("%6d %5d %5d %4d %4d %4d %4d %4d %4d %4d %6d\n",
1N/A re, maj, mf, fr, epi, epo, api, apo, fpi, fpo, sy);
1N/A
1N/A /* clear counters */
1N/A epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0;
1N/A re = 0; mf = 0; maj = 0; fr = 0; sy = 0;
1N/A }
1N/A'
1N/A
1N/A### Run DTrace
1N/Aif [ $opt_command -eq 1 ]; then
1N/A /usr/sbin/dtrace -n "$dtrace" -x evaltime=exec -c "$command" >&2
1N/Aelse
1N/A /usr/sbin/dtrace -n "$dtrace" >&2
1N/Afi
1N/A