Disk Stats

BSD - iostat

On BSD systems, iostat(8) gives stats for devices, the figures given for each device are average transaction size (KB/t), number of transactions per second (tps), and average data flow rate (MB/s). The -w wait option is used to output the figures every wait seconds, the -d option displays device statistics only (i.e. no CPU or TTY stats).

The following example illustrates the use of iostat, each device has three columns of data :

$ iostat -w 1 -d
             ad0             acd0              fd0              md0 
  KB/t tps  MB/s   KB/t tps  MB/s   KB/t tps  MB/s   KB/t tps  MB/s 
  9.09  95  0.84  18.63  35  0.63   0.00   0  0.00   0.00   0  0.00 
 11.26  89  0.98  19.00  42  0.77   0.00   0  0.00   0.00   0  0.00 
 11.59  72  0.82  19.00  40  0.73   0.00   0  0.00   0.00   0  0.00 
  6.11  36  0.21  18.06  36  0.63   0.00   0  0.00   0.00   0  0.00 
^C
$
Graphing the data is a matter of taking the third column for the device, and expressing it in relation to the highest value so far.

OpenBSD and NetBSD show stats for up to four devices at a time, FreeBSD for up to as many as will fit onto an 80 character display line (which is the same thing). FreeBSD allows for more devices to be displayed, through the -n devs option, but this is not supported by the other BSDs. However, by naming the devices on the command line, at least there is a choice of which devices to display.

The iostat command doesn't distinguish between reads and writes, so all disk activity is shown in blue on BSD systems.

Linux - /proc/stat and /proc/partitions

2.2 kernels

2.2 kernels provide stats for the first four IDE or SCSI disks in the /proc/stat file on four lines beginning with the words disk_rio, disk_wio, disk_rblk or disk_wblk. The disk_?io lines give the number of I/Os for each disk, the disk_?blk lines give the number of blocks, i.e. the amount of data transferred.

For the purposes of graphing disk activity, we choose the block figures, which give an indication of how hard the disk is being hammered. Because the figures are cumulative, we calculate the number of blocks read and written since the last time we looked, and express both figures as percentages of the highest total so far; reads are shown in blue, and writes in red.

The four figures given on each line are the counts for the first four IDE (hda, hdb, hdc and hdc) or SCSI disks (sda, sdb, sdc and sdd). SCSI disks are given preference over IDE disks, so if the system has both types of disk listed in /proc/partitions, stats are only kept for the SCSI devices, and not for IDE. Also, the entries in /proc/stat will always have four counts, regardless of whether the devices actually exist; so if the system has a single hard disk hda and a CDROM drive hdc, the hard disk will be the first count, and the CDROM drive the third, while the second and fourth counts will be zero.

The following example shows the relevant parts of /proc/partitions and /proc/stat on a Red Hat 6.2 system with a hard disk and a CDROM drive :

$ grep ' [hs]d.$' /proc/partitions 
   3     0    6342840 hda
  22     0 1073741823 hdc
$
$ egrep '^disk_(r|w)blk' /proc/stat
disk_rblk 52920 0 510 0
disk_wblk 37050 0 0 0
$
Both devices are IDE because the names start with hd. Also, there are no SCSI devices mentioned, so the stats will refer to IDE devices. The hard disk has had 52920 blocks read and 37050 blocks written, the CDROM drive has had 510 blocks read and none written (it's a readonly device).

2.4 kernels

2.4 kernels provide stats for both IDE and SCSI disks in the /proc/stat file on a line beginning with the word disk_io.

The following example shows a floppy disk and an IDE hard disk on a Red Hat 7.2 system :

$ grep disk_io /proc/stat
disk_io: (2,0):(19,19,23,0,0) (3,0):(90569,24038,417822,66531,1579164) 
$

Each disk is identified by its major and minor numbers in parentheses. The major number refers to the disk controller, and the minor number identifies the device. From my desktop machine with IDE disks and a server with SCSI disks, I have made the following assumptions :

Major   Minor   Device
20fd0
21fd1
30hda
31hdb
220hdc
221hdd
80sda
81sdb

Following the major/minor numbers, is a group of five stats, containing the number of reads, number of blocks read, number of writes, and number of blocks written, again in parentheses. The number of blocks read and written are figures three and five in each group. Figures two and four are the read and write counts, I'm not sure what figure one is.

As with 2.2 kernels, the figures are cumulative, so we calculate the differences against the last time we looked, and express both figures as percentages of the highest total difference so far. Reads are shown in blue, writes in red.

What to conclude from the disk meter

The disk meter cannot give a truly accurate picture of what the disks are doing, especially if the number and types of disks are restricted by the underlying iostat or /proc/stat. Even so, it does give a good indication of disk activity when it happens. Here are some observations I've made while developing the disk meter :
  1. The disk meter twitches every couple of seconds during normal operations; this may be down to flushing, paging, logging, or other routine system activity. On BSD, soft updates reduce this markedly (a quiet disk, I like it !).

  2. Linux does a lot of its I/O asynchronously, so disk activity is much lower. FreeBSD grinds by default, but soft updates make all the difference. On both systems, you can often do a find across the whole disk without making any noise, but grepping across all the files will slow things down again.

  3. To see the meter at its best, mount the CDROM drive, grep across all the files, and watch the meter go up and down with the drive's pitch.

  4. If the any of the above is wrong (particularly my interpretation of the Linux /proc/stat contents), please let me know so I can make corrections...