#define DISKSTATS "/proc/diskstats"
通过访问DISKSTATS虚拟文件,获取当期的IO读写的数据,然后统计
void read_diskstats_stat(int curr)
{
FILE *fp;
char line[256], dev_name[MAX_NAME_LEN];
char *dm_name;
struct io_stats sdev;
int i;
unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks;
unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios;
unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec;
char *ioc_dname;
unsigned int major, minor;
/* Every I/O device entry is potentially unregistered */
set_entries_unregistered(iodev_nr, st_hdr_iodev);
if ((fp = fopen(DISKSTATS, "r")) == NULL)
return;
while (fgets(line, sizeof(line), fp) != NULL) {
/* major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq */
i = sscanf(line, "%u %u %s %lu %lu %lu %lu %lu %lu %lu %u %u %u %u",
&major, &minor, dev_name,
&rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios, &rd_ticks_or_wr_sec,
&wr_ios, &wr_merges, &wr_sec, &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks);
if (i == 14) {
/* Device or partition */
if (!dlist_idx && !DISPLAY_PARTITIONS(flags) &&
!is_device(dev_name, ACCEPT_VIRTUAL_DEVICES))
continue;
sdev.rd_ios = rd_ios;
sdev.rd_merges = rd_merges_or_rd_sec;
sdev.rd_sectors = rd_sec_or_wr_ios;
sdev.rd_ticks = (unsigned int) rd_ticks_or_wr_sec;
sdev.wr_ios = wr_ios;
sdev.wr_merges = wr_merges;
sdev.wr_sectors = wr_sec;
sdev.wr_ticks = wr_ticks;
sdev.ios_pgr = ios_pgr;
sdev.tot_ticks = tot_ticks;
sdev.rq_ticks = rq_ticks;
}
else if (i == 7) {
/* Partition without extended statistics */
if (DISPLAY_EXTENDED(flags) ||
(!dlist_idx && !DISPLAY_PARTITIONS(flags)))
continue;
sdev.rd_ios = rd_ios;
sdev.rd_sectors = rd_merges_or_rd_sec;
sdev.wr_ios = rd_sec_or_wr_ios;
sdev.wr_sectors = rd_ticks_or_wr_sec;
}
else
/* Unknown entry: Ignore it */
continue;
if ((ioc_dname = ioc_name(major, minor)) != NULL) {
if (strcmp(dev_name, ioc_dname) && strcmp(ioc_dname, K_NODEV)) {
/*
* No match: Use name generated from sysstat.ioconf data
* (if different from "nodev") works around known issues
* with EMC PowerPath.
*/
strncpy(dev_name, ioc_dname, MAX_NAME_LEN);
}
}
if ((DISPLAY_DEVMAP_NAME(flags)) && (major == dm_major)) {
/*
* If the device is a device mapper device, try to get its
* assigned name of its logical device.
*/
dm_name = transform_devmapname(major, minor);
if (dm_name) {
strncpy(dev_name, dm_name, MAX_NAME_LEN);
}
}
save_stats(dev_name, curr, &sdev, iodev_nr, st_hdr_iodev);
}
fclose(fp);
/* Free structures corresponding to unregistered devices */
free_unregistered_entries(iodev_nr, st_hdr_iodev);
}
iostat的核心描述