aboutsummaryrefslogtreecommitdiff
path: root/Disk/iopending
diff options
context:
space:
mode:
Diffstat (limited to 'Disk/iopending')
-rwxr-xr-xDisk/iopending261
1 files changed, 261 insertions, 0 deletions
diff --git a/Disk/iopending b/Disk/iopending
new file mode 100755
index 000000000000..ef9d4da7a625
--- /dev/null
+++ b/Disk/iopending
@@ -0,0 +1,261 @@
+#!/usr/bin/ksh
+#
+# iopending - Print a plot for the number of pending disk I/O events.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This is measuring disk events that have made it past system caches.
+# By plotting a distribution graph of the number of pending events, the
+# "serialness" or "parallelness" of disk behaviour can be distinguished.
+#
+# $Id: iopending 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: iopending [-c] [-d device] [-f filename]
+# [-m mount_point] [interval [count]]
+#
+# -c # clear the screen
+# -d device # instance name to snoop (eg, dad0)
+# -f filename # full pathname of file to snoop
+# -m mount_point # this FS only (will skip raw events)
+# eg,
+# iopending # default output, 5 second intervals
+# iopending 1 # 1 second samples
+# iopending -c # clear the screen
+# iopending 5 12 # print 12 x 5 second samples
+#
+# FIELDS:
+# value number of pending events, 0 == idle
+# count number of samples @ 1000 Hz
+# load 1 min load average
+# disk_r total disk read Kbytes for sample
+# disk_w total disk write Kbytes for sample
+#
+# SEE ALSO: iosnoop, iotop
+#
+# IDEA: Dr Rex di Bona (Sydney, Australia)
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 01-Nov-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_device=0; opt_file=0; opt_mount=0; opt_clear=0;
+opt_def=1; filter=0; device=.; filename=.; mount=.
+interval=5; count=-1
+
+### process options
+while getopts cd:f:hm: name
+do
+ case $name in
+ c) opt_clear=1 ;;
+ d) opt_device=1; device=$OPTARG ;;
+ f) opt_file=1; filename=$OPTARG ;;
+ m) opt_mount=1; mount=$OPTARG ;;
+ h|?) cat <<-END >&2
+ USAGE: iopending [-c] [-d device] [-f filename]
+ [-m mount_point] [interval [count]]
+
+ -c # clear the screen
+ -d device # instance name to snoop
+ -f filename # snoop this file only
+ -m mount_point # this FS only
+ eg,
+ iopending # default output, 5 second samples
+ iopending 1 # 1 second samples
+ iopending -m / # snoop events on filesystem / only
+ iopending 5 12 # print 12 x 5 second samples
+ END
+ exit 1
+ esac
+done
+
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if [[ "$1" > 0 ]]; then
+ interval=$1; shift
+fi
+if [[ "$1" > 0 ]]; then
+ count=$1; shift
+fi
+if (( opt_device || opt_mount || opt_file )); then
+ filter=1
+fi
+if (( opt_clear )); then
+ clearstr=`clear`
+else
+ clearstr=.
+fi
+
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_def = '$opt_def';
+ inline int OPT_clear = '$opt_clear';
+ inline int OPT_device = '$opt_device';
+ inline int OPT_mount = '$opt_mount';
+ inline int OPT_file = '$opt_file';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline int FILTER = '$filter';
+ inline string DEVICE = "'$device'";
+ inline string FILENAME = "'$filename'";
+ inline string MOUNT = "'$mount'";
+ inline string CLEAR = "'$clearstr'";
+
+ inline int MAX_PENDING = 32; /* max pending value */
+
+ #pragma D option quiet
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ /* starting values */
+ counts = COUNTER;
+ secs = INTERVAL;
+ disk_r = 0;
+ disk_w = 0;
+ pending = 0;
+
+ printf("Tracing... Please wait.\n");
+ }
+
+ /*
+ * Check event is being traced
+ */
+ io:genunix::start,
+ io:genunix::done
+ {
+ /* default is to trace unless filtering, */
+ this->ok = FILTER ? 0 : 1;
+
+ /* check each filter, */
+ (OPT_device == 1 && DEVICE == args[1]->dev_statname)? this->ok = 1 : 1;
+ (OPT_file == 1 && FILENAME == args[2]->fi_pathname) ? this->ok = 1 : 1;
+ (OPT_mount == 1 && MOUNT == args[2]->fi_mount) ? this->ok = 1 : 1;
+ }
+
+ /*
+ * Store entry details
+ */
+ io:genunix::start
+ /this->ok/
+ {
+ /* track bytes */
+ disk_r += args[0]->b_flags & B_READ ? args[0]->b_bcount : 0;
+ disk_w += args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount;
+
+ /* increase event pending count */
+ pending++;
+ }
+
+ /*
+ * Process and Print completion
+ */
+ io:genunix::done
+ /this->ok/
+ {
+ /* decrease event pending count */
+ pending--;
+ }
+
+ /*
+ * Prevent pending from underflowing
+ * this can happen if this program is started during disk events.
+ */
+ io:genunix::done
+ /pending < 0/
+ {
+ pending = 0;
+ }
+
+ /*
+ * Timer
+ */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ profile:::profile-1000hz
+ {
+ @out = lquantize(pending, 0, MAX_PENDING, 1);
+ }
+
+ /*
+ * Print Report
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* fetch 1 min load average */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+ /* convert counters to Kbytes */
+ disk_r /= 1024;
+ disk_w /= 1024;
+
+ /* print status */
+ OPT_clear ? printf("%s", CLEAR) : 1;
+ printf("%Y, load: %d.%02d, disk_r: %6d KB, disk_w: %6d KB",
+ walltimestamp, this->load1a, this->load1b, disk_r, disk_w);
+
+ /* print output */
+ printa(@out);
+
+ /* clear data */
+ trunc(@out);
+ disk_r = 0;
+ disk_w = 0;
+ secs = INTERVAL;
+ counts--;
+ }
+
+ /*
+ * End of program
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /*
+ * Cleanup for Ctrl-C
+ */
+ dtrace:::END
+ {
+ trunc(@out);
+ }
+'