81
80
fprintf(stderr, _("Usage: %s [ options ] [ <interval> [ <count> ] ]\n"),
84
fprintf(stderr, _("Options are:\n"
85
"[ -c ] [ -d ] [ -N ] [ -n ] [ -h ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ -z ]\n"
83
fprintf(stderr, _("Options are:\n"
84
"[ -c ] [ -d ] [ -N ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ -z ]\n"
85
"[ <device> [...] | ALL ] [ -p [ <device> [,...] | ALL ] ] [ --debuginfo ]\n"));
87
fprintf(stderr, _("Options are:\n"
88
"[ -c ] [ -d ] [ -N ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ -z ]\n"
86
89
"[ <device> [...] | ALL ] [ -p [ <device> [,...] | ALL ] ]\n"));
91
95
***************************************************************************
96
* Set disk output unit. Unit will be kB/s unless POSIXLY_CORRECT
97
* environment variable has been set, in which case the output will be
98
* expressed in blocks/s.
99
***************************************************************************
101
void set_disk_output_unit(void)
105
if (DISPLAY_KILOBYTES(flags) || DISPLAY_MEGABYTES(flags))
108
/* Check POSIXLY_CORRECT environment variable */
109
if ((e = getenv(ENV_POSIXLY_CORRECT)) == NULL) {
110
/* Variable not set: Unit is kB/s and not blocks/s */
111
flags |= I_D_KILOBYTES;
116
***************************************************************************
92
117
* SIGALRM signal handler.
459
398
if (i < ioln_nr) {
460
399
st_hdr_ioln_i = st_hdr_ioln + i;
461
400
st_hdr_ioln_i->active = TRUE;
462
if (st_hdr_ioln == st_hdr_iodev) {
463
st_iodev_i = st_iodev[curr] + i;
464
*st_iodev_i = *((struct io_stats *) st_io);
467
st_ionfs_i = st_ionfs[curr] + i;
468
*st_ionfs_i = *((struct io_nfs_stats *) st_io);
401
st_iodev_i = st_iodev[curr] + i;
402
*st_iodev_i = *((struct io_stats *) st_io);
472
* else it was a new device or NFS directory
405
* else it was a new device
473
406
* but there was no free structure to store it.
478
411
***************************************************************************
479
* Read stats from /proc/stat file...
480
* Used to get disk stats if /sys not available.
483
* @curr Index in array for current sample statistics.
484
***************************************************************************
486
void read_proc_stat(int curr)
491
unsigned long v_tmp[4];
492
unsigned int v_major, v_index;
493
struct io_stats *st_iodev_tmp[4];
496
* Prepare pointers on the 4 disk structures in case we have a
497
* /proc/stat file with "disk_rblk", etc. entries.
499
for (i = 0; i < 4; i++) {
500
st_iodev_tmp[i] = st_iodev[curr] + i;
503
if ((fp = fopen(STAT, "r")) == NULL) {
504
fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
508
while (fgets(line, 8192, fp) != NULL) {
510
if (!strncmp(line, "disk_rblk ", 10)) {
512
* Read the number of blocks read from disk.
513
* A block is of indeterminate size.
514
* The size may vary depending on the device type.
516
sscanf(line + 10, "%lu %lu %lu %lu",
517
&v_tmp[0], &v_tmp[1], &v_tmp[2], &v_tmp[3]);
519
st_iodev_tmp[0]->dk_drive_rblk = v_tmp[0];
520
st_iodev_tmp[1]->dk_drive_rblk = v_tmp[1];
521
st_iodev_tmp[2]->dk_drive_rblk = v_tmp[2];
522
st_iodev_tmp[3]->dk_drive_rblk = v_tmp[3];
525
else if (!strncmp(line, "disk_wblk ", 10)) {
526
/* Read the number of blocks written to disk */
527
sscanf(line + 10, "%lu %lu %lu %lu",
528
&v_tmp[0], &v_tmp[1], &v_tmp[2], &v_tmp[3]);
530
st_iodev_tmp[0]->dk_drive_wblk = v_tmp[0];
531
st_iodev_tmp[1]->dk_drive_wblk = v_tmp[1];
532
st_iodev_tmp[2]->dk_drive_wblk = v_tmp[2];
533
st_iodev_tmp[3]->dk_drive_wblk = v_tmp[3];
536
else if (!strncmp(line, "disk ", 5)) {
537
/* Read the number of I/O done since the last reboot */
538
sscanf(line + 5, "%lu %lu %lu %lu",
539
&v_tmp[0], &v_tmp[1], &v_tmp[2], &v_tmp[3]);
541
st_iodev_tmp[0]->dk_drive = v_tmp[0];
542
st_iodev_tmp[1]->dk_drive = v_tmp[1];
543
st_iodev_tmp[2]->dk_drive = v_tmp[2];
544
st_iodev_tmp[3]->dk_drive = v_tmp[3];
547
else if (!strncmp(line, "disk_io: ", 9)) {
548
struct io_stats sdev;
549
char dev_name[MAX_NAME_LEN];
553
/* Every disk_io entry is potentially unregistered */
554
set_entries_inactive(iodev_nr, st_hdr_iodev);
556
/* Read disks I/O statistics (for 2.4 kernels) */
557
while (pos < strlen(line) - 1) {
558
/* Beware: a CR is already included in the line */
559
sscanf(line + pos, "(%u,%u):(%lu,%*u,%lu,%*u,%lu) ",
560
&v_major, &v_index, &v_tmp[0], &v_tmp[1], &v_tmp[2]);
562
sprintf(dev_name, "dev%d-%d", v_major, v_index);
563
sdev.dk_drive = v_tmp[0];
564
sdev.dk_drive_rblk = v_tmp[1];
565
sdev.dk_drive_wblk = v_tmp[2];
566
save_stats(dev_name, curr, &sdev, iodev_nr, st_hdr_iodev);
568
pos += strcspn(line + pos, " ") + 1;
571
/* Free structures corresponding to unregistered disks */
572
free_inactive_entries(iodev_nr, st_hdr_iodev);
580
***************************************************************************
581
412
* Read sysfs stat for current block device or partition.
871
702
***************************************************************************
872
* Read stats from /proc/partitions.
875
* @curr Index in array for current sample statistics.
876
***************************************************************************
878
void read_ppartitions_stat(int curr)
881
char line[256], dev_name[MAX_NAME_LEN];
882
struct io_stats sdev;
883
unsigned long rd_ios, rd_merges, rd_ticks, wr_ios, wr_merges, wr_ticks;
884
unsigned long ios_pgr, tot_ticks, rq_ticks;
885
unsigned long long rd_sec, wr_sec;
886
char *ioc_dname, *dm_name;
887
unsigned int major, minor;
889
/* Every I/O device entry is potentially unregistered */
890
set_entries_inactive(iodev_nr, st_hdr_iodev);
892
if ((fp = fopen(PPARTITIONS, "r")) == NULL)
895
while (fgets(line, 256, fp) != NULL) {
896
/* major minor #blocks name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq */
897
if (sscanf(line, "%u %u %*u %s %lu %lu %llu %lu %lu %lu %llu"
899
&major, &minor, dev_name,
900
&rd_ios, &rd_merges, &rd_sec, &rd_ticks, &wr_ios, &wr_merges,
901
&wr_sec, &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks) == 14) {
902
/* Device or partition */
903
sdev.rd_ios = rd_ios; sdev.rd_merges = rd_merges;
904
sdev.rd_sectors = rd_sec; sdev.rd_ticks = rd_ticks;
905
sdev.wr_ios = wr_ios; sdev.wr_merges = wr_merges;
906
sdev.wr_sectors = wr_sec; sdev.wr_ticks = wr_ticks;
907
sdev.ios_pgr = ios_pgr; sdev.tot_ticks = tot_ticks;
908
sdev.rq_ticks = rq_ticks;
911
/* Unknown entry: Ignore it */
914
if ((ioc_dname = ioc_name(major, minor)) != NULL) {
915
if (strcmp(dev_name, ioc_dname) && strcmp(ioc_dname, K_NODEV)) {
916
/* Compensate for EMC PowerPath driver bug */
917
strncpy(dev_name, ioc_dname, MAX_NAME_LEN);
921
if ((DISPLAY_DEVMAP_NAME(flags)) && (major == DEVMAP_MAJOR)) {
922
/* Get device mapper logical name */
923
dm_name = transform_devmapname(major, minor);
925
strcpy(dev_name, dm_name);
929
save_stats(dev_name, curr, &sdev, iodev_nr, st_hdr_iodev);
933
/* Free structures corresponding to unregistered devices */
934
free_inactive_entries(iodev_nr, st_hdr_iodev);
938
***************************************************************************
939
* Read NFS-mount directories stats from /proc/self/mountstats.
942
* @curr Index in array for current sample statistics.
943
***************************************************************************
945
void read_nfs_stat(int curr)
951
char nfs_name[MAX_NAME_LEN];
952
char mount[10], on[10], prefix[10], aux[32];
954
struct io_nfs_stats snfs;
957
/* Every I/O NFS entry is potentially unregistered */
958
set_entries_inactive(ionfs_nr, st_hdr_ionfs);
960
if ((fp = fopen(NFSMOUNTSTATS, "r")) == NULL)
963
sprintf(aux, "%%%ds %%10s %%10s",
964
MAX_NAME_LEN < 200 ? MAX_NAME_LEN : 200);
966
while (fgets(line, 256, fp) != NULL) {
968
/* read NFS directory name */
969
if (!strncmp(line, "device", 6)) {
971
sscanf(line + 6, aux, nfs_name, mount, on);
972
if ((!strncmp(mount, "mounted", 7)) && (!strncmp(on, "on", 2))) {
977
sscanf(line, "%10s", prefix);
978
if (sw && (!strncmp(prefix, "bytes:", 6))) {
979
/* Read the stats for the last NFS-mounted directory */
980
sscanf(strstr(line, "bytes:") + 6, "%llu %llu %llu %llu %llu %llu",
981
&snfs.rd_normal_bytes, &snfs.wr_normal_bytes,
982
&snfs.rd_direct_bytes, &snfs.wr_direct_bytes,
983
&snfs.rd_server_bytes, &snfs.wr_server_bytes);
987
if ((sw == 2) && (!strncmp(prefix, "xprt:", 5))) {
989
* Read extended statistic for the last NFS-mounted directory
990
* - number of sent rpc requests.
992
xprt_line = (strstr(line, "xprt:") + 6);
993
/* udp, tcp or rdma data */
994
if (!strncmp(xprt_line, "udp", 3)) {
995
/* port bind_count sends recvs (bad_xids req_u bklog_u) */
996
sscanf(strstr(xprt_line, "udp") + 4, "%*u %*u %lu",
999
if (!strncmp(xprt_line, "tcp", 3)) {
1001
* port bind_counter connect_count connect_time idle_time
1002
* sends recvs (bad_xids req_u bklog_u)
1004
sscanf(strstr(xprt_line, "tcp") + 4,
1005
"%*u %*u %*u %*u %*d %lu",
1008
if (!strncmp(xprt_line,"rdma", 4)) {
1010
* 0(port) bind_count connect_count connect_time idle_time
1011
* sends recvs (bad_xids req_u bklog_u...)
1013
sscanf(strstr(xprt_line, "rdma") + 5,
1014
"%*u %*u %*u %*u %*d %lu",
1020
if ((sw == 3) && (!strncmp(prefix, "per-op", 6))) {
1023
fgets(line, 256, fp);
1024
sscanf(line, "%15s %lu", operation, &v1);
1025
if (!strncmp(operation, "READ:", 5)) {
1028
else if (!strncmp(operation, "WRITE:", 6)) {
1030
save_stats(nfs_name, curr, &snfs, ionfs_nr, st_hdr_ionfs);
1039
/* Free structures corresponding to unregistered devices */
1040
free_inactive_entries(ionfs_nr, st_hdr_ionfs);
1044
***************************************************************************
1045
703
* Display CPU utilization.
1231
869
printf("%-13s", shi->name);
1233
if (HAS_SYSFS(flags) ||
1234
HAS_DISKSTATS(flags) || HAS_PPARTITIONS(flags)) {
1235
/* Print stats coming from /sys or /proc/{diskstats,partitions} */
1236
rd_sec = ioi->rd_sectors - ioj->rd_sectors;
1237
if ((ioi->rd_sectors < ioj->rd_sectors) && (ioj->rd_sectors <= 0xffffffff)) {
1238
rd_sec &= 0xffffffff;
1240
wr_sec = ioi->wr_sectors - ioj->wr_sectors;
1241
if ((ioi->wr_sectors < ioj->wr_sectors) && (ioj->wr_sectors <= 0xffffffff)) {
1242
wr_sec &= 0xffffffff;
1245
printf(" %8.2f %12.2f %12.2f %10llu %10llu\n",
1246
S_VALUE(ioj->rd_ios + ioj->wr_ios, ioi->rd_ios + ioi->wr_ios, itv),
1247
ll_s_value(ioj->rd_sectors, ioi->rd_sectors, itv) / fctr,
1248
ll_s_value(ioj->wr_sectors, ioi->wr_sectors, itv) / fctr,
1249
(unsigned long long) rd_sec / fctr,
1250
(unsigned long long) wr_sec / fctr);
1253
/* Print stats coming from /proc/stat */
1254
printf(" %8.2f %12.2f %12.2f %10lu %10lu\n",
1255
S_VALUE(ioj->dk_drive, ioi->dk_drive, itv),
1256
S_VALUE(ioj->dk_drive_rblk, ioi->dk_drive_rblk, itv) / fctr,
1257
S_VALUE(ioj->dk_drive_wblk, ioi->dk_drive_wblk, itv) / fctr,
1258
(ioi->dk_drive_rblk - ioj->dk_drive_rblk) / fctr,
1259
(ioi->dk_drive_wblk - ioj->dk_drive_wblk) / fctr);
1265
***************************************************************************
1266
* Write NFS stats read from /proc/self/mountstats.
1269
* @curr Index in array for current sample statistics.
1270
* @itv Interval of time.
1271
* @fctr Conversion factor.
1272
* @shi Structures describing the NFS filesystems.
1273
* @ioi Current sample statistics.
1274
* @ioj Previous sample statistics.
1275
***************************************************************************
1277
void write_nfs_stat(int curr, unsigned long long itv, int fctr,
1278
struct io_hdr_stats *shi, struct io_nfs_stats *ioni,
1279
struct io_nfs_stats *ionj)
1281
if (DISPLAY_HUMAN_READ(flags)) {
1282
printf("%-22s\n%23s", shi->name, "");
1285
printf("%-22s ", shi->name);
1287
printf("%12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %9.2f %9.2f %9.2f\n",
1288
S_VALUE(ionj->rd_normal_bytes, ioni->rd_normal_bytes, itv) / fctr,
1289
S_VALUE(ionj->wr_normal_bytes, ioni->wr_normal_bytes, itv) / fctr,
1290
S_VALUE(ionj->rd_direct_bytes, ioni->rd_direct_bytes, itv) / fctr,
1291
S_VALUE(ionj->wr_direct_bytes, ioni->wr_direct_bytes, itv) / fctr,
1292
S_VALUE(ionj->rd_server_bytes, ioni->rd_server_bytes, itv) / fctr,
1293
S_VALUE(ionj->wr_server_bytes, ioni->wr_server_bytes, itv) / fctr,
1294
S_VALUE(ionj->rpc_sends, ioni->rpc_sends, itv),
1295
S_VALUE(ionj->nfs_rops, ioni->nfs_rops, itv),
1296
S_VALUE(ionj->nfs_wops, ioni->nfs_wops, itv));
871
/* Print stats coming from /sys or /proc/diskstats */
872
rd_sec = ioi->rd_sectors - ioj->rd_sectors;
873
if ((ioi->rd_sectors < ioj->rd_sectors) && (ioj->rd_sectors <= 0xffffffff)) {
874
rd_sec &= 0xffffffff;
876
wr_sec = ioi->wr_sectors - ioj->wr_sectors;
877
if ((ioi->wr_sectors < ioj->wr_sectors) && (ioj->wr_sectors <= 0xffffffff)) {
878
wr_sec &= 0xffffffff;
881
printf(" %8.2f %12.2f %12.2f %10llu %10llu\n",
882
S_VALUE(ioj->rd_ios + ioj->wr_ios, ioi->rd_ios + ioi->wr_ios, itv),
883
ll_s_value(ioj->rd_sectors, ioi->rd_sectors, itv) / fctr,
884
ll_s_value(ioj->wr_sectors, ioi->wr_sectors, itv) / fctr,
885
(unsigned long long) rd_sec / fctr,
886
(unsigned long long) wr_sec / fctr);
1379
987
ioj = st_iodev[!curr] + i;
1381
989
if (!DISPLAY_UNFILTERED(flags)) {
1382
if (HAS_OLD_KERNEL(flags) ||
1383
HAS_PLAIN_KERNEL24(flags)) {
1388
if (!ioi->rd_ios && !ioi->wr_ios)
990
if (!ioi->rd_ios && !ioi->wr_ios)
1393
994
if (DISPLAY_ZERO_OMIT(flags)) {
1394
if (HAS_OLD_KERNEL(flags) ||
1395
HAS_PLAIN_KERNEL24(flags)) {
1396
if (ioi->dk_drive == ioj->dk_drive)
1397
/* No activity: Ignore it */
1401
if ((ioi->rd_ios == ioj->rd_ios) &&
1402
(ioi->wr_ios == ioj->wr_ios))
1403
/* No activity: Ignore it */
995
if ((ioi->rd_ios == ioj->rd_ios) &&
996
(ioi->wr_ios == ioj->wr_ios))
997
/* No activity: Ignore it */
1001
if (DISPLAY_DEBUG(flags)) {
1003
fprintf(stderr, "name=%s itv=%llu fctr=%d ioi{ rd_sectors=%llu "
1004
"wr_sectors=%llu rd_ios=%lu rd_merges=%lu rd_ticks=%lu "
1005
"wr_ios=%lu wr_merges=%lu wr_ticks=%lu ios_pgr=%lu tot_ticks=%lu "
1006
"rq_ticks=%lu dk_drive=%lu dk_drive_rblk=%lu dk_drive_wblk=%lu }\n",
1408
1028
if (DISPLAY_EXTENDED(flags)) {
1409
1029
write_ext_stat(curr, itv, fctr, shi, ioi, ioj);