[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Patch for iostat, fine-grained read/write statistics.
- To: tech_(_at_)_openbsd_(_dot_)_org
- Subject: Patch for iostat, fine-grained read/write statistics.
- From: Sven Ingebrigt Ulland <SvenI_(_dot_)_Ulland_(_at_)_iu_(_dot_)_hio_(_dot_)_no>
- Date: Sun, 24 Jul 2005 19:18:22 +0200
This patch adds two new types of statistics to iostat:
1. Number of separate read and write transfers.
2. Number of separate read and write bytes.
Here are two examples:
% iostat -x -I
wd0 cd0 fd0
rxfr wxfr rxfr wxfr rxfr wxfr
22564 6087 0 0 0 0
This shows the absolute numbers of both read and write
transfers for each device. Why is that interesting, you
might ask. The primary reason is to have more fine-grained
control over write transfers when dealing with solid state
media, e.g. Compact Flash (much used in embedded systems).
These cards are said to handle only a limited amount of
write transfers before potential failure, see
<URL:http://www.sandisk.com/pdf/oem/WPaperWearLevelv1.0.pdf>
Another example shows read and written bytes per second:
% iostat -b
wd0 cd0 fd0
rB/s wB/s rB/s wB/s rB/s wB/s
3179 2365 0 0 0 0
(On a sidenote, this was on a seemingly idle system, so I
was a bit surprised by those values. Why are the numbers
so high?)
Here's the patch:
% diff -ru usr.sbin/iostat/iostat.c myusr.sbin/iostat/iostat.c
--- usr.sbin/iostat/iostat.c Fri Apr 1 05:32:47 2005
+++ myusr.sbin/iostat/iostat.c Sun Jul 24 18:43:07 2005
@@ -109,11 +109,15 @@
#define SHOW_TTY 0x0002
#define SHOW_STATS_1 0x0004
#define SHOW_STATS_2 0x0008
+#define SHOW_XFERS 0x0010
+#define SHOW_BYTES 0x0020
#define SHOW_TOTALS 0x0080
static void cpustats(void);
static void disk_stats(double);
static void disk_stats2(double);
+static void disk_xfers(double);
+static void disk_bytes(double);
static void sigheader(int);
static void header(void);
static void usage(void);
@@ -130,8 +134,11 @@
int ch, hdrcnt;
struct timeval tv;
- while ((ch = getopt(argc, argv, "Cc:dDIM:N:Tw:")) != -1)
+ while ((ch = getopt(argc, argv, "bCc:dDIM:N:Tw:x")) != -1)
switch(ch) {
+ case 'b':
+ todo |= SHOW_BYTES;
+ break;
case 'c':
if ((reps = atoi(optarg)) <= 0)
errx(1, "repetition count <= 0.");
@@ -161,6 +168,9 @@
if ((interval = atoi(optarg)) <= 0)
errx(1, "interval <= 0.");
break;
+ case 'x':
+ todo |= SHOW_XFERS;
+ break;
case '?':
default:
usage();
@@ -168,7 +178,7 @@
argc -= optind;
argv += optind;
- if (!ISSET(todo, SHOW_CPU | SHOW_TTY | SHOW_STATS_1 | SHOW_STATS_2))
+ if (!ISSET(todo, SHOW_CPU | SHOW_TTY | SHOW_STATS_1 | SHOW_STATS_2 | SHOW_XFERS | SHOW_BYTES))
todo |= SHOW_CPU | SHOW_TTY | SHOW_STATS_1;
dkinit(0);
@@ -227,6 +237,16 @@
if (cur.dk_select[i])
(void)printf(" %13.13s ", cur.dk_name[i]);
+ if (ISSET(todo, SHOW_XFERS))
+ for (i = 0; i < dk_ndrive; i++)
+ if (cur.dk_select[i])
+ (void)printf(" %14.14s", cur.dk_name[i]);
+
+ if (ISSET(todo, SHOW_BYTES))
+ for (i = 0; i < dk_ndrive; i++)
+ if (cur.dk_select[i])
+ (void)printf(" %14.14s", cur.dk_name[i]);
+
if (ISSET(todo, SHOW_CPU))
(void)printf(" cpu");
printf("\n");
@@ -248,6 +268,22 @@
if (cur.dk_select[i])
(void)printf(" KB xfr time ");
+ if (ISSET(todo, SHOW_XFERS))
+ for (i = 0; i < dk_ndrive; i++)
+ if (cur.dk_select[i])
+ if (ISSET(todo, SHOW_TOTALS))
+ (void)printf(" rxfr wxfr");
+ else
+ (void)printf(" rxfr/s wxfr/s");
+
+ if (ISSET(todo, SHOW_BYTES))
+ for (i = 0; i < dk_ndrive; i++)
+ if (cur.dk_select[i])
+ if (ISSET(todo, SHOW_TOTALS))
+ (void)printf(" rBytes wBytes");
+ else
+ (void)printf(" rB/s wB/s");
+
if (ISSET(todo, SHOW_CPU))
(void)printf(" us ni sy in id");
printf("\n");
@@ -316,6 +352,46 @@
}
static void
+disk_xfers(double etime)
+{
+ int dn;
+ double atime;
+
+ for (dn = 0; dn < dk_ndrive; ++dn) {
+ if (!cur.dk_select[dn])
+ continue;
+
+ /* average read transfers per second. */
+ (void)printf(" %7.0f",
+ cur.dk_rxfer[dn] / etime);
+
+ /* average write transfers per second. */
+ (void)printf(" %7.0f",
+ cur.dk_wxfer[dn] / etime);
+ }
+}
+
+static void
+disk_bytes(double etime)
+{
+ int dn;
+ double atime;
+
+ for (dn = 0; dn < dk_ndrive; ++dn) {
+ if (!cur.dk_select[dn])
+ continue;
+
+ /* average read bytes per second. */
+ (void)printf(" %7.0f",
+ cur.dk_rbytes[dn] / etime);
+
+ /* average write bytes per second. */
+ (void)printf(" %7.0f",
+ cur.dk_wbytes[dn] / etime);
+ }
+}
+
+static void
cpustats(void)
{
int state;
@@ -335,7 +411,7 @@
usage(void)
{
(void)fprintf(stderr,
-"usage: iostat [-CdDIT] [-c count] [-M core] [-N system] [-w wait] [drives]\n");
+"usage: iostat [-bCdDITx] [-c count] [-M core] [-N system] [-w wait] [drives]\n");
exit(1);
}
@@ -369,6 +445,12 @@
if (ISSET(todo, SHOW_STATS_2))
disk_stats2(etime);
+
+ if (ISSET(todo, SHOW_XFERS))
+ disk_xfers(etime);
+
+ if (ISSET(todo, SHOW_BYTES))
+ disk_bytes(etime);
if (ISSET(todo, SHOW_CPU))
cpustats();
Visit your host, monkey.org