#!/bin/bash
opt_device=0; opt_file=0; opt_mount=0; opt_time=0
filter=0; device=.; filename=.; mount=.; interval=1; count=-1
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 -d device -f filename -m mount_point eg,
iopattern iopattern 10 iopattern 5 12 iopattern -m / END
exit 1
esac
done
shift $(( $OPTIND - 1 ))
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
/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"'";
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:::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:::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);
}
'