3 # iopending - Print a plot for the number of pending disk I/O events.
4 # Written using DTrace (Solaris 10 3/05).
6 # This is measuring disk events that have made it past system caches.
7 # By plotting a distribution graph of the number of pending events, the
8 # "serialness" or "parallelness" of disk behaviour can be distinguished.
10 # $Id: iopending 3 2007-08-01 10:50:08Z brendan $
12 # USAGE: iopending [-c] [-d device] [-f filename]
13 # [-m mount_point] [interval [count]]
15 # -c # clear the screen
16 # -d device # instance name to snoop (eg, dad0)
17 # -f filename # full pathname of file to snoop
18 # -m mount_point # this FS only (will skip raw events)
20 # iopending # default output, 5 second intervals
21 # iopending 1 # 1 second samples
22 # iopending -c # clear the screen
23 # iopending 5 12 # print 12 x 5 second samples
26 # value number of pending events, 0 == idle
27 # count number of samples @ 1000 Hz
28 # load 1 min load average
29 # disk_r total disk read Kbytes for sample
30 # disk_w total disk write Kbytes for sample
32 # SEE ALSO: iosnoop, iotop
34 # IDEA: Dr Rex di Bona (Sydney, Australia)
36 # COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
40 # The contents of this file are subject to the terms of the
41 # Common Development and Distribution License, Version 1.0 only
42 # (the "License"). You may not use this file except in compliance
45 # You can obtain a copy of the license at Docs/cddl1.txt
46 # or http://www.opensolaris.org/os/licensing.
47 # See the License for the specific language governing permissions
48 # and limitations under the License.
52 # Author: Brendan Gregg [Sydney, Australia]
54 # 01-Nov-2005 Brendan Gregg Created this.
55 # 20-Apr-2006 " " Last update.
59 ##############################
60 # --- Process Arguments ---
64 opt_device=0; opt_file=0; opt_mount=0; opt_clear=0;
65 opt_def=1; filter=0; device=.; filename=.; mount=.
69 while getopts cd:f:hm: name
73 d) opt_device=1; device=$OPTARG ;;
74 f) opt_file=1; filename=$OPTARG ;;
75 m) opt_mount=1; mount=$OPTARG ;;
77 USAGE: iopending [-c] [-d device] [-f filename]
78 [-m mount_point] [interval [count]]
81 -d device # instance name to snoop
82 -f filename # snoop this file only
83 -m mount_point # this FS only
85 iopending # default output, 5 second samples
86 iopending 1 # 1 second samples
87 iopending -m / # snoop events on filesystem / only
88 iopending 5 12 # print 12 x 5 second samples
94 shift $(( $OPTIND - 1 ))
97 if [[ "$1" > 0 ]]; then
100 if [[ "$1" > 0 ]]; then
103 if (( opt_device || opt_mount || opt_file )); then
106 if (( opt_clear )); then
114 #################################
115 # --- Main Program, DTrace ---
117 /usr/sbin/dtrace -n '
119 * Command line arguments
121 inline int OPT_def = '$opt_def';
122 inline int OPT_clear = '$opt_clear';
123 inline int OPT_device = '$opt_device';
124 inline int OPT_mount = '$opt_mount';
125 inline int OPT_file = '$opt_file';
126 inline int INTERVAL = '$interval';
127 inline int COUNTER = '$count';
128 inline int FILTER = '$filter';
129 inline string DEVICE = "'$device'";
130 inline string FILENAME = "'$filename'";
131 inline string MOUNT = "'$mount'";
132 inline string CLEAR = "'$clearstr'";
134 inline int MAX_PENDING = 32; /* max pending value */
136 #pragma D option quiet
143 /* starting values */
150 printf("Tracing... Please wait.\n");
154 * Check event is being traced
159 /* default is to trace unless filtering, */
160 this->ok = FILTER ? 0 : 1;
162 /* check each filter, */
163 (OPT_device == 1 && DEVICE == args[1]->dev_statname)? this->ok = 1 : 1;
164 (OPT_file == 1 && FILENAME == args[2]->fi_pathname) ? this->ok = 1 : 1;
165 (OPT_mount == 1 && MOUNT == args[2]->fi_mount) ? this->ok = 1 : 1;
169 * Store entry details
175 disk_r += args[0]->b_flags & B_READ ? args[0]->b_bcount : 0;
176 disk_w += args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount;
178 /* increase event pending count */
183 * Process and Print completion
188 /* decrease event pending count */
193 * Prevent pending from underflowing
194 * this can happen if this program is started during disk events.
210 profile:::profile-1000hz
212 @out = lquantize(pending, 0, MAX_PENDING, 1);
221 /* fetch 1 min load average */
222 this->load1a = `hp_avenrun[0] / 65536;
223 this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
225 /* convert counters to Kbytes */
230 OPT_clear ? printf("%s", CLEAR) : 1;
231 printf("%Y, load: %d.%02d, disk_r: %6d KB, disk_w: %6d KB",
232 walltimestamp, this->load1a, this->load1b, disk_r, disk_w);