Gordon Marler writes:
> When using DTrace to track I/Os to disks under the
sd/ssd driver, it's easy enough to get the major/minor
device number of the disk being targeted for I/O:
>
> fbt:ssd:ssdstrategy:entry,
> fbt:sd:sdstrategy:entry
> {
> io_start[(struct buf *)arg0] = timestamp;
> }
>
> fbt:ssd:ssdintr:entry,
> fbt:sd:sdintr:entry
> / io_start[(this->buf = (struct buf *)((struct
scsi_pkt *)arg0)->pkt_private)]
> != 0 /
> {
> this->un = ((struct sd_xbuf *)
this->buf->b_private)->xb_un;
> this->major = getmajor(this->buf->b_edev);
> this->minor = getminor(this->buf->b_edev);
>
> max_ms[this->major, this->minor] =
> max((timestamp - io_start[this->buf])/1000000);
/* convert ns to ms */
>
> io_start[this->buf] = 0;
> }
>
> We can even get device names in the form of 'ssdXXX',
which unfortunately aren't that helpful.
>
> How can we map major/minor numbers or device names to
their /dev/[r]dsk/... symlinks in DTrace? That would make
the output more intuitive, at least to us.
>
> Gordon Marler
> gmarler gmarler.com
>
>
> --
> This message posted from opensolaris.org
> _______________________________________________
> dtrace-discuss mailing list
> dtrace-discuss opensolaris.org
Here is an example script where I got this working :
#!/usr/bin/ksh
#
# iolat - print avg latency and distribution of each disk
#
# This scripts prints average latency of each disk over the
length of the
# run. With -d, results includes an lquantization of the
result. Scripts
# runs until interrupted. Results are in usec (actually nsec
>>10).
#
# If you get "DIF program exceeds maximum program
size"
# Try : echo dtrace_dof_maxsize/Z1000000 | mdb -kw
#
opt_dist=0; min=0; max=50000; bin=5000;
### process options
while getopts dh name
do
case $name in
d) opt_dist=1 ;;
h|?) cat <<-END >&2
USAGE: iolat [-d [min max bucket]]
-d # report per disk latency
distribution.
min max bucket # arguments to dtrace
lquantize in usec.
# Default : 0, 5000, 500.
END
exit 1
esac
done
shift $(( $OPTIND - 1 ))
### option logic
if [[ ! "$1" == "" ]]; then
min=$1; shift
fi
if [[ ! "$1" == "" ]]; then
max=$1; shift
fi
if [[ ! "$1" == "" ]]; then
bin=$1; shift
fi
#Build a string to be parsed by dtrace
#Contains entry of the form
# disks[major, minor] = "c0t0d0s0";
#
disks_arr_string=`/bin/ls -1lL /dev/dsk/* 2>/dev/null |
/usr/bin/nawk -F'[ ,t/]*' '{print "disks[" $5
", " $6 "] = "" $12
"";"}'`
if [[ $opt_dist == 1 ]]; then
quantize_gather=" d[this->disk] =
lquantize(this->lat, $min, $max, $bin);"
quantize_print="printf("nnLatency
Distribution:nn"); printa("%20s % 10dn", d);"
else
quantize_gather=""
quantize_print=""
fi
script_str='
BEGIN {
'$disks_arr_string';
printf("Ctrl-C to terminate and get
resultsn");
}
io:::start{
started[args[0]->b_edev, args[0]->b_blkno] =
timestamp;
}
io:::done
/started[args[0]->b_edev, args[0]->b_blkno] != 0/
{
this->major = args[1]->dev_major;
this->minor = args[1]->dev_minor;
this->disk = (disks[this->major, this->minor] ==
"" ? "unknown" : disks[this->major,
this->minor]);
this->lat = (timestamp - started[args[0]->b_edev,
args[0]->b_blkno])>>10;
a[this->disk] = avg(this->lat); /* First is
sort key */
b[this->disk] = count();
c[this->disk] = sum(args[0]->b_bcount);
'$quantize_gather'
started[args[0]->b_edev, args[0]->b_blkno] = 0;
}
END {
printf("%20s %10s %10s %10sn",
"Disk", "Avg Lat(us)", "IO
cnt", "Bytes");
printf("%20s %10s %10s %10sn",
"----", "----------",
"------", "-----");
printa("%20s % 10d % 10d % 10dn", a, b, c);
'$quantize_print'
}
'
/usr/bin/pfexec /usr/sbin/dtrace -qn
"$script_str"
_______________________________________________
dtrace-discuss mailing list
dtrace-discuss opensolaris.org
|