3 # iopattern - print disk I/O pattern.
4 # Written using DTrace (Solaris 10 3/05).
6 # This prints details on the I/O access pattern for the disks, such as
7 # percentage of events that were of a random or sequential nature.
8 # By default totals for all disks are printed.
10 # $Id: iopattern 65 2007-10-04 11:09:40Z brendan $
12 # USAGE: iopattern [-v] [-d device] [-f filename] [-m mount_point]
15 # -v # print timestamp, string
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 # iopattern # default output, 1 second intervals
21 # iopattern 10 # 10 second samples
22 # iopattern 5 12 # print 12 x 5 second samples
23 # iopattern -m / # snoop events on filesystem / only
26 # %RAN percentage of events of a random nature
27 # %SEQ percentage of events of a sequential nature
28 # COUNT number of I/O events
29 # MIN minimum I/O event size
30 # MAX maximum I/O event size
31 # AVG average I/O event size
32 # KR total kilobytes read during sample
33 # KW total kilobytes written during sample
37 # TIME timestamp, string
41 # An event is considered random when the heads seek. This program prints
42 # the percentage of events that are random. The size of the seek is not
43 # measured - it's either random or not.
45 # SEE ALSO: iosnoop, iotop
49 # COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
53 # The contents of this file are subject to the terms of the
54 # Common Development and Distribution License, Version 1.0 only
55 # (the "License"). You may not use this file except in compliance
58 # You can obtain a copy of the license at Docs/cddl1.txt
59 # or http://www.opensolaris.org/os/licensing.
60 # See the License for the specific language governing permissions
61 # and limitations under the License.
65 # Author: Brendan Gregg [Sydney, Australia]
67 # 25-Jul-2005 Brendan Gregg Created this.
68 # 25-Jul-2005 " " Last update.
72 ##############################
73 # --- Process Arguments ---
77 opt_device=0; opt_file=0; opt_mount=0; opt_time=0
78 filter=0; device=.; filename=.; mount=.; interval=1; count=-1
81 while getopts d:f:hm:v name
84 d) opt_device=1; device=$OPTARG ;;
85 f) opt_file=1; filename=$OPTARG ;;
86 m) opt_mount=1; mount=$OPTARG ;;
89 USAGE: iopattern [-v] [-d device] [-f filename] [-m mount_point]
93 -d device # instance name to snoop
94 -f filename # snoop this file only
95 -m mount_point # this FS only
97 iopattern # default output, 1 second samples
98 iopattern 10 # 10 second samples
99 iopattern 5 12 # print 12 x 5 second samples
100 iopattern -m / # snoop events on filesystem / only
106 shift $(( $OPTIND - 1 ))
109 if [[ "$1" > 0 ]]; then
112 if [[ "$1" > 0 ]]; then
115 if (( opt_device || opt_mount || opt_file )); then
120 #################################
121 # --- Main Program, DTrace ---
123 /usr/sbin/dtrace -n '
125 * Command line arguments
127 inline int OPT_time = '$opt_time';
128 inline int OPT_device = '$opt_device';
129 inline int OPT_mount = '$opt_mount';
130 inline int OPT_file = '$opt_file';
131 inline int INTERVAL = '$interval';
132 inline int COUNTER = '$count';
133 inline int FILTER = '$filter';
134 inline string DEVICE = "'$device'";
135 inline string FILENAME = "'$filename'";
136 inline string MOUNT = "'$mount'";
138 #pragma D option quiet
140 int last_loc[string];
147 /* starting values */
167 /* print optional headers */
168 OPT_time ? printf("%-20s ", "TIME") : 1;
169 OPT_device ? printf("%-9s ", "DEVICE") : 1;
170 OPT_mount ? printf("%-12s ", "MOUNT") : 1;
171 OPT_file ? printf("%-12s ", "FILE") : 1;
174 printf("%4s %4s %6s %6s %6s %6s %6s %6s\n",
175 "%RAN", "%SEQ", "COUNT", "MIN", "MAX", "AVG", "KR", "KW");
181 * Check event is being traced
185 /* default is to trace unless filtering */
186 self->ok = FILTER ? 0 : 1;
188 /* check each filter */
189 (OPT_device == 1 && DEVICE == args[1]->dev_statname)? self->ok = 1 : 1;
190 (OPT_file == 1 && FILENAME == args[2]->fi_pathname) ? self->ok = 1 : 1;
191 (OPT_mount == 1 && MOUNT == args[2]->fi_mount) ? self->ok = 1 : 1;
195 * Process and Print completion
203 this->loc = args[0]->b_blkno * 512;
204 this->pre = last_loc[args[1]->dev_statname];
205 diskr += args[0]->b_flags & B_READ ? args[0]->b_bcount : 0;
206 diskw += args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount;
207 diskran += this->pre == this->loc ? 0 : 1;
209 diskmin = diskmin == 0 ? args[0]->b_bcount :
210 (diskmin > args[0]->b_bcount ? args[0]->b_bcount : diskmin);
211 diskmax = diskmax < args[0]->b_bcount ? args[0]->b_bcount : diskmax;
213 /* save disk location */
214 last_loc[args[1]->dev_statname] = this->loc + args[0]->b_bcount;
234 /* calculate diskavg */
235 diskavg = diskcnt > 0 ? (diskr + diskw) / diskcnt : 0;
237 /* convert counters to Kbytes */
241 /* convert to percentages */
242 diskran = diskcnt == 0 ? 0 : (diskran * 100) / diskcnt;
243 diskseq = diskcnt == 0 ? 0 : 100 - diskran;
245 /* print optional fields */
246 OPT_time ? printf("%-20Y ", walltimestamp) : 1;
247 OPT_device ? printf("%-9s ", DEVICE) : 1;
248 OPT_mount ? printf("%-12s ", MOUNT) : 1;
249 OPT_file ? printf("%-12s ", FILENAME) : 1;
252 printf("%4d %4d %6d %6d %6d %6d %6d %6d\n",
253 diskran, diskseq, diskcnt, diskmin, diskmax, diskavg,