summaryrefslogtreecommitdiffstats
path: root/cddl/contrib/dtracetoolkit/iopattern
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/contrib/dtracetoolkit/iopattern')
-rwxr-xr-xcddl/contrib/dtracetoolkit/iopattern277
1 files changed, 277 insertions, 0 deletions
diff --git a/cddl/contrib/dtracetoolkit/iopattern b/cddl/contrib/dtracetoolkit/iopattern
new file mode 100755
index 0000000..e825f9f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/iopattern
@@ -0,0 +1,277 @@
+#!/usr/bin/ksh
+#
+# iopattern - print disk I/O pattern.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This prints details on the I/O access pattern for the disks, such as
+# percentage of events that were of a random or sequential nature.
+# By default totals for all disks are printed.
+#
+# $Id: iopattern 65 2007-10-04 11:09:40Z brendan $
+#
+# USAGE: iopattern [-v] [-d device] [-f filename] [-m mount_point]
+# [interval [count]]
+#
+# -v # print timestamp, string
+# -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,
+# iopattern # default output, 1 second intervals
+# iopattern 10 # 10 second samples
+# iopattern 5 12 # print 12 x 5 second samples
+# iopattern -m / # snoop events on filesystem / only
+#
+# FIELDS:
+# %RAN percentage of events of a random nature
+# %SEQ percentage of events of a sequential nature
+# COUNT number of I/O events
+# MIN minimum I/O event size
+# MAX maximum I/O event size
+# AVG average I/O event size
+# KR total kilobytes read during sample
+# KW total kilobytes written during sample
+# DEVICE device name
+# MOUNT mount point
+# FILE filename
+# TIME timestamp, string
+#
+# NOTES:
+#
+# An event is considered random when the heads seek. This program prints
+# the percentage of events that are random. The size of the seek is not
+# measured - it's either random or not.
+#
+# SEE ALSO: iosnoop, iotop
+#
+# IDEA: Ryan Matteson
+#
+# COPYRIGHT: Copyright (c) 2005 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]
+#
+# 25-Jul-2005 Brendan Gregg Created this.
+# 25-Jul-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_device=0; opt_file=0; opt_mount=0; opt_time=0
+filter=0; device=.; filename=.; mount=.; interval=1; count=-1
+
+### process options
+while getopts d:f:hm:v name
+do
+ case $name in
+ d) opt_device=1; device=$OPTARG ;;
+ f) opt_file=1; filename=$OPTARG ;;
+ m) opt_mount=1; mount=$OPTARG ;;
+ v) opt_time=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: iopattern [-v] [-d device] [-f filename] [-m mount_point]
+ [interval [count]]
+
+ -v # print timestamp
+ -d device # instance name to snoop
+ -f filename # snoop this file only
+ -m mount_point # this FS only
+ eg,
+ iopattern # default output, 1 second samples
+ iopattern 10 # 10 second samples
+ iopattern 5 12 # print 12 x 5 second samples
+ iopattern -m / # snoop events on filesystem / only
+ 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
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_time = '$opt_time';
+ 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'";
+
+ #pragma D option quiet
+
+ int last_loc[string];
+
+ /*
+ * Program start
+ */
+ dtrace:::BEGIN
+ {
+ /* starting values */
+ diskcnt = 0;
+ diskmin = 0;
+ diskmax = 0;
+ diskran = 0;
+ diskr = 0;
+ diskw = 0;
+ counts = COUNTER;
+ secs = INTERVAL;
+ LINES = 20;
+ line = 0;
+ last_event[""] = 0;
+ }
+
+ /*
+ * Print header
+ */
+ profile:::tick-1sec
+ /line <= 0 /
+ {
+ /* print optional headers */
+ OPT_time ? printf("%-20s ", "TIME") : 1;
+ OPT_device ? printf("%-9s ", "DEVICE") : 1;
+ OPT_mount ? printf("%-12s ", "MOUNT") : 1;
+ OPT_file ? printf("%-12s ", "FILE") : 1;
+
+ /* print header */
+ printf("%4s %4s %6s %6s %6s %6s %6s %6s\n",
+ "%RAN", "%SEQ", "COUNT", "MIN", "MAX", "AVG", "KR", "KW");
+
+ line = LINES;
+ }
+
+ /*
+ * Check event is being traced
+ */
+ io:genunix::done
+ {
+ /* default is to trace unless filtering */
+ self->ok = FILTER ? 0 : 1;
+
+ /* check each filter */
+ (OPT_device == 1 && DEVICE == args[1]->dev_statname)? self->ok = 1 : 1;
+ (OPT_file == 1 && FILENAME == args[2]->fi_pathname) ? self->ok = 1 : 1;
+ (OPT_mount == 1 && MOUNT == args[2]->fi_mount) ? self->ok = 1 : 1;
+ }
+
+ /*
+ * Process and Print completion
+ */
+ io:genunix::done
+ /self->ok/
+ {
+ /*
+ * Save details
+ */
+ this->loc = args[0]->b_blkno * 512;
+ this->pre = last_loc[args[1]->dev_statname];
+ diskr += args[0]->b_flags & B_READ ? args[0]->b_bcount : 0;
+ diskw += args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount;
+ diskran += this->pre == this->loc ? 0 : 1;
+ diskcnt++;
+ diskmin = diskmin == 0 ? args[0]->b_bcount :
+ (diskmin > args[0]->b_bcount ? args[0]->b_bcount : diskmin);
+ diskmax = diskmax < args[0]->b_bcount ? args[0]->b_bcount : diskmax;
+
+ /* save disk location */
+ last_loc[args[1]->dev_statname] = this->loc + args[0]->b_bcount;
+
+ /* cleanup */
+ self->ok = 0;
+ }
+
+ /*
+ * Timer
+ */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /*
+ * Print Output
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* calculate diskavg */
+ diskavg = diskcnt > 0 ? (diskr + diskw) / diskcnt : 0;
+
+ /* convert counters to Kbytes */
+ diskr /= 1024;
+ diskw /= 1024;
+
+ /* convert to percentages */
+ diskran = diskcnt == 0 ? 0 : (diskran * 100) / diskcnt;
+ diskseq = diskcnt == 0 ? 0 : 100 - diskran;
+
+ /* print optional fields */
+ OPT_time ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_device ? printf("%-9s ", DEVICE) : 1;
+ OPT_mount ? printf("%-12s ", MOUNT) : 1;
+ OPT_file ? printf("%-12s ", FILENAME) : 1;
+
+ /* print data */
+ printf("%4d %4d %6d %6d %6d %6d %6d %6d\n",
+ diskran, diskseq, diskcnt, diskmin, diskmax, diskavg,
+ diskr, diskw);
+
+ /* clear data */
+ diskmin = 0;
+ diskmax = 0;
+ diskcnt = 0;
+ diskran = 0;
+ diskr = 0;
+ diskw = 0;
+
+ secs = INTERVAL;
+ counts--;
+ line--;
+ }
+
+ /*
+ * End of program
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+'
OpenPOWER on IntegriCloud