summaryrefslogtreecommitdiffstats
path: root/usr.sbin/iostat
diff options
context:
space:
mode:
authormaxim <maxim@FreeBSD.org>2006-04-16 22:23:39 +0000
committermaxim <maxim@FreeBSD.org>2006-04-16 22:23:39 +0000
commitc6cab9cc4821e37f776ac01cb7a920b0c3428238 (patch)
tree28fbbd400afef6293d7c8c9726d7b465d613fcf6 /usr.sbin/iostat
parent4a3ab050f7810df3bf3af7566f7cf491870076ce (diff)
downloadFreeBSD-src-c6cab9cc4821e37f776ac01cb7a920b0c3428238.zip
FreeBSD-src-c6cab9cc4821e37f776ac01cb7a920b0c3428238.tar.gz
o Implement Solaris-like -x flag: show extended disk statistics.
o Implement Solaris-like -z flag: omit lines for devices with no activity. o iostat.8: describe -x and -z flags, Xr devstat(3), touch .Dd. PR: mostly bin/68840, with style changes; bin/73327 Submitted by: Dan Nelson, Peter Schuller Obtained from: NetBSD (a part of man page) MFC after: 1 month
Diffstat (limited to 'usr.sbin/iostat')
-rw-r--r--usr.sbin/iostat/iostat.835
-rw-r--r--usr.sbin/iostat/iostat.c116
2 files changed, 136 insertions, 15 deletions
diff --git a/usr.sbin/iostat/iostat.8 b/usr.sbin/iostat/iostat.8
index be66c7c..8aeb833 100644
--- a/usr.sbin/iostat/iostat.8
+++ b/usr.sbin/iostat/iostat.8
@@ -60,7 +60,7 @@
.\"
.\" @(#)iostat.8 8.1 (Berkeley) 6/6/93
.\"
-.Dd December 22, 1997
+.Dd April 17, 2006
.Dt IOSTAT 8
.Os
.Sh NAME
@@ -70,7 +70,7 @@
statistics
.Sh SYNOPSIS
.Nm
-.Op Fl CdhKIoT?\&
+.Op Fl CdhKIoTxz?\&
.Op Fl c Ar count
.Op Fl M Ar core
.Op Fl n Ar devs
@@ -239,6 +239,13 @@ seconds between each display.
If no repeat
.Ar count
is specified, the default is infinity.
+.It Fl x
+Show extended disk statistics.
+Each disk is displayed on a line of its own with all available statistics.
+.It Fl z
+If
+.Fl x
+is specified, omit lines for devices with no activity.
.It Fl ?\&
Display a usage statement and exit.
.El
@@ -313,6 +320,29 @@ total number of transfers
total number of megabytes transferred
.El
.Pp
+The extended
+.Nm
+device display, with the
+.Fl x
+flag specified, shows the following statistics:
+.Pp
+.Bl -tag -width indent -compact
+.It r/s
+read operations per second
+.It w/s
+write operations per second
+.It kr/s
+kilobytes read per second
+.It kw/s
+kilobytes write per second
+.It wait
+transactions queue length
+.It svc_t
+average duration of transactions, in milliseconds
+.It %b
+% of time the device had one or more outstanding transactions
+.El
+.Pp
The old-style
.Nm
display (using
@@ -414,6 +444,7 @@ flags are given, the TTY and CPU displays will be displayed.
.Xr nfsstat 1 ,
.Xr ps 1 ,
.Xr systat 1 ,
+.Xr devstat 3 ,
.Xr gstat 8 ,
.Xr pstat 8 ,
.Xr vmstat 8
diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c
index 724756e..3abf8cc 100644
--- a/usr.sbin/iostat/iostat.c
+++ b/usr.sbin/iostat/iostat.c
@@ -137,6 +137,7 @@ struct device_selection *dev_select;
int maxshowdevs;
volatile sig_atomic_t headercount;
int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Kflag = 0;
+int xflag = 0, zflag = 0;
/* local function declarations */
static void usage(void);
@@ -156,7 +157,7 @@ usage(void)
* This isn't mentioned in the man page, or the usage statement,
* but it is supported.
*/
- fprintf(stderr, "usage: iostat [-CdhIKoT?] [-c count] [-M core]"
+ fprintf(stderr, "usage: iostat [-CdhIKoTxz?] [-c count] [-M core]"
" [-n devs] [-N system]\n"
"\t [-t type,if,pass] [-w wait] [drives]\n");
}
@@ -184,7 +185,7 @@ main(int argc, char **argv)
matches = NULL;
maxshowdevs = 3;
- while ((c = getopt(argc, argv, "c:CdhIKM:n:N:ot:Tw:?")) != -1) {
+ while ((c = getopt(argc, argv, "c:CdhIKM:n:N:ot:Tw:xz?")) != -1) {
switch(c) {
case 'c':
cflag++;
@@ -238,6 +239,12 @@ main(int argc, char **argv)
if (waittime < 1)
errx(1, "wait time is < 1");
break;
+ case 'x':
+ xflag++;
+ break;
+ case 'z':
+ zflag++;
+ break;
default:
usage();
exit(1);
@@ -270,7 +277,7 @@ main(int argc, char **argv)
* Make sure Tflag and/or Cflag are set if dflag == 0. If dflag is
* greater than 0, they may be 0 or non-zero.
*/
- if (dflag == 0) {
+ if (dflag == 0 && xflag == 0) {
Cflag = 1;
Tflag = 1;
}
@@ -547,16 +554,18 @@ main(int argc, char **argv)
last.cp_time[i] = tmp;
}
- if (Tflag > 0)
- printf("%4.0Lf%5.0Lf", cur.tk_nin / etime,
- cur.tk_nout/etime);
+ if (xflag == 0 && Tflag > 0)
+ printf("%4.0Lf%5.0Lf", cur.tk_nin / etime,
+ cur.tk_nout / etime);
devstats(hflag, etime, havelast);
- if (Cflag > 0)
- cpustats();
+ if (xflag == 0) {
+ if (Cflag > 0)
+ cpustats();
- printf("\n");
+ printf("\n");
+ }
fflush(stdout);
if (count >= 0 && --count <= 0)
@@ -584,6 +593,13 @@ phdr(void)
{
register int i;
int printed;
+
+ /*
+ * If xflag is set, we need a per-loop header, not a page header, so
+ * just return. We'll print the header in devstats().
+ */
+ if (xflag > 0)
+ return;
if (Tflag > 0)
(void)printf(" tty");
@@ -639,11 +655,30 @@ static void
devstats(int perf_select, long double etime, int havelast)
{
register int dn;
- long double transfers_per_second;
- long double kb_per_transfer, mb_per_second;
+ long double transfers_per_second, transfers_per_second_read, transfers_per_second_write;
+ long double kb_per_transfer, mb_per_second, mb_per_second_read, mb_per_second_write;
u_int64_t total_bytes, total_transfers, total_blocks;
+ long double busy_pct;
+ u_int64_t queue_len;
long double total_mb;
long double blocks_per_second, ms_per_transaction;
+ int firstline = 1;
+ char *devname;
+
+ if (xflag > 0) {
+ printf(" extended device statistics ");
+ if (Tflag > 0)
+ printf(" tty ");
+ if (Cflag > 0)
+ printf(" cpu ");
+ printf("\n");
+ printf("device r/s w/s kr/s kw/s wait svc_t %%b ");
+ if (Tflag > 0)
+ printf("tin tout ");
+ if (Cflag > 0)
+ printf("us ni sy in id ");
+ printf("\n");
+ }
for (dn = 0; dn < num_devices; dn++) {
int di;
@@ -661,9 +696,15 @@ devstats(int perf_select, long double etime, int havelast)
DSM_TOTAL_BLOCKS, &total_blocks,
DSM_KB_PER_TRANSFER, &kb_per_transfer,
DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
+ DSM_TRANSFERS_PER_SECOND_READ, &transfers_per_second_read,
+ DSM_TRANSFERS_PER_SECOND_WRITE, &transfers_per_second_write,
DSM_MB_PER_SECOND, &mb_per_second,
+ DSM_MB_PER_SECOND_READ, &mb_per_second_read,
+ DSM_MB_PER_SECOND_WRITE, &mb_per_second_write,
DSM_BLOCKS_PER_SECOND, &blocks_per_second,
DSM_MS_PER_TRANSACTION, &ms_per_transaction,
+ DSM_BUSY_PCT, &busy_pct,
+ DSM_QUEUE_LENGTH, &queue_len,
DSM_NONE) != 0)
errx(1, "%s", devstat_errbuf);
@@ -674,13 +715,47 @@ devstats(int perf_select, long double etime, int havelast)
continue;
}
- if (Kflag) {
+ if (Kflag > 0 || xflag > 0) {
int block_size = cur.dinfo->devices[di].block_size;
total_blocks = total_blocks * (block_size ?
block_size : 512) / 1024;
}
- if (oflag > 0) {
+ if (xflag > 0) {
+ asprintf(&devname, "%s%d",
+ cur.dinfo->devices[di].device_name,
+ cur.dinfo->devices[di].unit_number);
+ /*
+ * If zflag is set, skip any devices with zero I/O.
+ */
+ if (zflag == 0 || transfers_per_second_read > 0.05 ||
+ transfers_per_second_write > 0.05 ||
+ mb_per_second_read > ((long double).0005)/1024 ||
+ mb_per_second_write > ((long double).0005)/1024 ||
+ busy_pct > 0.5) {
+ printf("%-8.8s %5.1Lf %5.1Lf %7.1Lf %7.1Lf %4qu %5.1Lf %3.0Lf ",
+ devname, transfers_per_second_read,
+ transfers_per_second_write,
+ mb_per_second_read * 1024,
+ mb_per_second_write * 1024, queue_len,
+ ms_per_transaction, busy_pct);
+ if (firstline) {
+ /*
+ * If this is the first device
+ * we're printing, also print
+ * CPU or TTY stats if requested.
+ */
+ firstline = 0;
+ if (Tflag > 0)
+ printf("%4.0Lf%5.0Lf",
+ cur.tk_nin / etime,
+ cur.tk_nout / etime);
+ if (Cflag > 0)
+ cpustats();
+ }
+ printf("\n");
+ }
+ } else if (oflag > 0) {
int msdig = (ms_per_transaction < 100.0) ? 1 : 0;
if (Iflag == 0)
@@ -712,6 +787,21 @@ devstats(int perf_select, long double etime, int havelast)
}
}
}
+ if (xflag > 0 && zflag > 0 && firstline == 1 &&
+ (Tflag > 0 || Cflag > 0)) {
+ /*
+ * If zflag is set and we did not print any device
+ * lines I/O because they were all zero,
+ * print TTY/CPU stats.
+ */
+ printf("%52s","");
+ if (Tflag > 0)
+ printf("%4.0Lf%5.0Lf", cur.tk_nin / etime,
+ cur.tk_nout / etime);
+ if (Cflag > 0)
+ cpustats();
+ printf("\n");
+ }
}
static void
OpenPOWER on IntegriCloud