summaryrefslogtreecommitdiffstats
path: root/usr.sbin/iostat/iostat.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/iostat/iostat.c')
-rw-r--r--usr.sbin/iostat/iostat.c116
1 files changed, 103 insertions, 13 deletions
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