changeset 10933:7bba9f719ba5

4636888 iostat doesn't display correct output if -z and -e option are used together
author jose borrego <Jose.Borrego@Sun.COM>
date Mon, 02 Nov 2009 15:57:35 -0700
parents 522e54a523c2
children e209937a4f19
files usr/src/cmd/stat/iostat/iostat.c
diffstat 1 files changed, 43 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/stat/iostat/iostat.c	Mon Nov 02 14:47:18 2009 -0800
+++ b/usr/src/cmd/stat/iostat/iostat.c	Mon Nov 02 15:57:35 2009 -0700
@@ -64,6 +64,8 @@
 
 #define	REPRINT 19
 
+#define	NUMBER_OF_ERR_COUNTERS	3
+
 /*
  * It's really a pseudo-gigabyte. We use 1000000000 bytes so that the disk
  * labels don't look bad. 1GB is really 1073741824 bytes.
@@ -558,6 +560,8 @@
 static void
 show_disk(void *v1, void *v2, void *data)
 {
+	uint32_t err_counters[NUMBER_OF_ERR_COUNTERS];
+	boolean_t display_err_counters = do_disk & DISK_ERRORS;
 	struct iodev_snapshot *old = (struct iodev_snapshot *)v1;
 	struct iodev_snapshot *new = (struct iodev_snapshot *)v2;
 	int *count = (int *)data;
@@ -572,7 +576,6 @@
 	uint64_t w_delta;
 	uint64_t r_delta;
 	int doit = 1;
-	int i;
 	uint_t toterrs;
 	char *fstr;
 
@@ -779,6 +782,30 @@
 		}
 	}
 
+	/*
+	 * The error counters are read first (if asked for and if they are
+	 * available).
+	 */
+	bzero(err_counters, sizeof (err_counters));
+	toterrs = 0;
+	if (display_err_counters && (new->is_errors.ks_data != NULL)) {
+		kstat_named_t	*knp;
+		int		i;
+
+		knp = KSTAT_NAMED_PTR(&new->is_errors);
+		for (i = 0; i < NUMBER_OF_ERR_COUNTERS; i++) {
+			switch (knp[i].data_type) {
+				case KSTAT_DATA_ULONG:
+				case KSTAT_DATA_ULONGLONG:
+					err_counters[i] = knp[i].value.ui32;
+					toterrs += knp[i].value.ui32;
+					break;
+				default:
+					break;
+			}
+		}
+	}
+
 	switch (do_disk & DISK_IO_MASK) {
 	case DISK_OLD:
 		if (do_raw == 0)
@@ -798,8 +825,10 @@
 		if (suppress_zero) {
 			if (fzero(rps) && fzero(wps) && fzero(krps) &&
 			    fzero(kwps) && fzero(avw) && fzero(avr) &&
-			    fzero(serv) && fzero(w_pct) && fzero(r_pct)) {
+			    fzero(serv) && fzero(w_pct) && fzero(r_pct) &&
+			    (toterrs == 0)) {
 				doit = 0;
+				display_err_counters = B_FALSE;
 			} else if (do_conversions == 0) {
 				if (do_raw == 0) {
 					push_out("%-*.*s",
@@ -837,52 +866,22 @@
 		break;
 	}
 
-	if (do_disk & DISK_ERRORS) {
-		if ((do_disk == DISK_ERRORS)) {
-			if (do_raw == 0)
+	if (display_err_counters) {
+		char	*efstr;
+		int	i;
+
+		if (do_raw == 0) {
+			if (do_disk == DISK_ERRORS)
 				push_out(two_blanks);
+			efstr = "%3u ";
+		} else {
+			efstr = "%u";
 		}
 
-		if (new->is_errors.ks_data) {
-			kstat_named_t *knp;
-			char *efstr;
+		for (i = 0; i < NUMBER_OF_ERR_COUNTERS; i++)
+			push_out(efstr, err_counters[i]);
 
-			if (do_raw == 0)
-				efstr = "%3u ";
-			else
-				efstr = "%u";
-			toterrs = 0;
-			knp = KSTAT_NAMED_PTR(&new->is_errors);
-			for (i = 0; i < 3; i++) {
-				switch (knp[i].data_type) {
-					case KSTAT_DATA_ULONG:
-						push_out(efstr,
-						    knp[i].value.ui32);
-						toterrs += knp[i].value.ui32;
-						break;
-					case KSTAT_DATA_ULONGLONG:
-						/*
-						 * We're only set up to
-						 * write out the low
-						 * order 32-bits so
-						 * just grab that.
-						 */
-						push_out(efstr,
-						    knp[i].value.ui32);
-						toterrs += knp[i].value.ui32;
-						break;
-					default:
-						break;
-				}
-			}
-			push_out(efstr, toterrs);
-		} else {
-			if (do_raw == 0)
-				push_out("  0   0   0   0 ");
-			else
-				push_out("0,0,0,0");
-		}
-
+		push_out(efstr, toterrs);
 	}
 
 	if (suppress_zero == 0 || doit == 1) {