#!/usr/bin/stap global devices, reads, writes /* data collection: SCSI disk */ %(kernel_v<"2.6.24" %? probe module("sd_mod").function("sd_init_command") !, kernel.function("sd_init_command") { device=kernel_string($SCpnt->request->rq_disk->disk_name) sector_size=$SCpnt->device->sector_size nr_sectors=$SCpnt->request->nr_sectors devices[device] = 1 %(kernel_v>="2.6.19" %? if ($SCpnt->request->cmd_flags & 1) %: if ($SCpnt->request->flags & 1) %) writes[device] <<< nr_sectors * sector_size else reads[device] <<< nr_sectors * sector_size } %: function get_sector_size:long (data:long) { return @cast(data, "scsi_device", "kernel<scsi/scsi_device.h>")->sector_size } %(kernel_v>="2.6.31" %? %{ #include <linux/blkdev.h> %} function get_nr_sectors:long(rq:long) %{ /* pure */ THIS->__retvalue = blk_rq_sectors((const struct request *)(long)THIS->rq); %} %) probe module("sd_mod").function("sd_prep_fn") !, kernel.function("sd_prep_fn") { device=kernel_string($rq->rq_disk->disk_name) sector_size=get_sector_size($q->queuedata) %(kernel_v>="2.6.31" %? nr_sectors=get_nr_sectors($rq) %: nr_sectors=$rq->nr_sectors %) devices[device] = 1 if ($rq->cmd_flags & 1) writes[device] <<< nr_sectors * sector_size else reads[device] <<< nr_sectors * sector_size } %) /* data collection: SCSI tape */ probe module("st").function("st_do_scsi") !, kernel.function("st_do_scsi") { device=kernel_string($STp->disk->disk_name) devices[device] = 1 if ($direction) writes[device] <<< $bytes else reads[device] <<< $bytes } /* reporting */ global blksize=512 global hdrcount probe timer.s($1) { if ((hdrcount++ % 10) == 0) printf("%9s %9s %9s %9s %9s %9s\n", "Device:","tps","blk_read/s","blk_wrtn/s","blk_read","blk_wrtn") foreach (dev in devices) { rdcount=@count(reads[dev]) wrcount=@count(writes[dev]) tps=(rdcount+wrcount)*100/$1 rdblkcount=rdcount ? @sum(reads[dev])/blksize : 0 wrblkcount=wrcount ? @sum(writes[dev])/blksize : 0 rdblkrate=rdblkcount*100/$1 wrblkrate=wrblkcount*100/$1 printf("%9s %6d.%02d %6d.%02d %6d.%02d %9d %9d\n", dev, tps/100,tps%100, rdblkrate/100,rdblkrate%100, wrblkrate/100,wrblkrate%100, rdblkcount, wrblkcount) } printf ("\n") delete devices delete reads delete writes }