111 static uint_t tohdr = 1;
112
113 /*
114 * If we're in raw format, have we printed a header? We only do it
115 * once for raw but we emit it every REPRINT lines in non-raw format.
116 * This applies only for the basic header. The extended header is
117 * done only once in both formats.
118 */
119 static uint_t hdr_out;
120
121 /*
122 * Flags representing arguments from command line
123 */
124 static uint_t do_tty; /* show tty info (-t) */
125 static uint_t do_disk; /* show disk info per selected */
126 /* format (-d, -D, -e, -E, -x -X -Y) */
127 static uint_t do_cpu; /* show cpu info (-c) */
128 static uint_t do_interval; /* do intervals (-I) */
129 static int do_partitions; /* per-partition stats (-p) */
130 static int do_partitions_only; /* per-partition stats only (-P) */
131 /* no per-device stats for disks */
132 static uint_t do_conversions; /* display disks as cXtYdZ (-n) */
133 static uint_t do_megabytes; /* display data in MB/sec (-M) */
134 static uint_t do_controller; /* display controller info (-C) */
135 static uint_t do_raw; /* emit raw format (-r) */
136 static uint_t timestamp_fmt = NODATE; /* timestamp each display (-T) */
137 static uint_t do_devid; /* -E should show devid */
138
139 /*
140 * Default number of disk drives to be displayed in basic format
141 */
142 #define DEFAULT_LIMIT 4
143
144 struct iodev_filter df;
145
146 static uint_t suppress_state; /* skip state change messages */
147 static uint_t suppress_zero; /* skip zero valued lines */
148 static uint_t show_mountpts; /* show mount points */
149 static int interval; /* interval (seconds) to output */
150 static int iter; /* iterations from command line */
151
152 #define SMALL_SCRATCH_BUFLEN MAXNAMELEN
153
154 static int iodevs_nl; /* name field width */
155 #define IODEVS_NL_MIN 6 /* not too thin for "device" */
156 #define IODEVS_NL_MAX 24 /* but keep full width under 80 */
157
158 static char disk_header[132];
159 static uint_t dh_len; /* disk header length for centering */
160 static int lineout; /* data waiting to be printed? */
161
162 static struct snapshot *newss;
163 static struct snapshot *oldss;
164 static double getime; /* elapsed time */
165 static double percent; /* 100 / etime */
166
167 /*
168 * List of functions to be called which will construct the desired output
169 */
170 static format_t *formatter_list;
171 static format_t *formatter_end;
172
173 static u_longlong_t ull_delta(u_longlong_t, u_longlong_t);
174 static uint_t u32_delta(uint_t, uint_t);
175 static void setup(void (*nfunc)(void));
176 static void print_tty_hdr1(void);
208 hrtime_t start_n;
209 hrtime_t period_n;
210
211 (void) setlocale(LC_ALL, "");
212 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
213 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
214 #endif
215 (void) textdomain(TEXT_DOMAIN);
216
217 do_args(argc, argv);
218
219 /*
220 * iostat historically showed CPU changes, even though
221 * it doesn't provide much useful information
222 */
223 types |= SNAP_CPUS;
224
225 if (do_disk)
226 types |= SNAP_IODEVS;
227
228 if (do_disk && !do_partitions_only)
229 df.if_allowed_types |= IODEV_DISK;
230 if (do_disk & DISK_IOPATH_LI) {
231 df.if_allowed_types |= IODEV_IOPATH_LTI;
232 types |= SNAP_IOPATHS_LI;
233 }
234 if (do_disk & DISK_IOPATH_LTI) {
235 df.if_allowed_types |= IODEV_IOPATH_LTI;
236 types |= SNAP_IOPATHS_LTI;
237 }
238 if (do_disk & DISK_ERROR_MASK)
239 types |= SNAP_IODEV_ERRORS;
240 if (do_partitions || do_partitions_only)
241 df.if_allowed_types |= IODEV_PARTITION;
242 if (do_conversions)
243 types |= SNAP_IODEV_PRETTY;
244 if (do_devid)
245 types |= SNAP_IODEV_DEVID;
246 if (do_controller) {
247 if (!(do_disk & PRINT_VERTICAL) ||
248 (do_disk & DISK_EXTENDED_ERRORS))
249 fail(0, "-C can only be used with -e or -x.");
250 types |= SNAP_CONTROLLERS;
251 df.if_allowed_types |= IODEV_CONTROLLER;
252 }
253
254 hz = sysconf(_SC_CLK_TCK);
255
256 /*
257 * Undocumented behavior - sending a SIGCONT will result
258 * in a new header being emitted. Used only if we're not
259 * doing extended headers. This is a historical
260 * artifact.
261 */
947 "\t\t-c: report percentage of time system has spent\n"
948 "\t\t\tin user/system/dtrace/idle mode\n"
949 "\t\t-C: report disk statistics by controller\n"
950 "\t\t-d: display disk Kb/sec, transfers/sec, avg. \n"
951 "\t\t\tservice time in milliseconds \n"
952 "\t\t-D: display disk reads/sec, writes/sec, \n"
953 "\t\t\tpercentage disk utilization \n"
954 "\t\t-e: report device error summary statistics\n"
955 "\t\t-E: report extended device error statistics\n"
956 "\t\t-i: show device IDs for -E output\n"
957 "\t\t-I: report the counts in each interval,\n"
958 "\t\t\tinstead of rates, where applicable\n"
959 "\t\t-l n: Limit the number of disks to n\n"
960 "\t\t-m: Display mount points (most useful with -p)\n"
961 "\t\t-M: Display data throughput in MB/sec "
962 "instead of Kb/sec\n"
963 "\t\t-n: convert device names to cXdYtZ format\n"
964 "\t\t-p: report per-partition disk statistics\n"
965 "\t\t-P: report per-partition disk statistics only,\n"
966 "\t\t\tno per-device disk statistics\n"
967 "\t\t-r: Display data in comma separated format\n"
968 "\t\t-s: Suppress state change messages\n"
969 "\t\t-T d|u Display a timestamp in date (d) or unix "
970 "time_t (u)\n"
971 "\t\t-t: display chars read/written to terminals\n"
972 "\t\t-x: display extended disk statistics\n"
973 "\t\t-X: display I/O path statistics\n"
974 "\t\t-Y: display I/O path (I/T/L) statistics\n"
975 "\t\t-z: Suppress entries with all zero values\n");
976 exit(1);
977 }
978
979 /*ARGSUSED*/
980 static void
981 show_disk_errors(void *v1, void *v2, void *d)
982 {
983 struct iodev_snapshot *disk = (struct iodev_snapshot *)v2;
984 kstat_named_t *knp;
985 size_t col;
986 int i, len;
1065 }
1066 if ((col >= 62) || (i == 2)) {
1067 do_newline();
1068 col = 0;
1069 }
1070 }
1071 if (col > 0) {
1072 do_newline();
1073 }
1074 do_newline();
1075 }
1076
1077 void
1078 do_args(int argc, char **argv)
1079 {
1080 int c;
1081 int errflg = 0;
1082 extern char *optarg;
1083 extern int optind;
1084
1085 while ((c = getopt(argc, argv, "tdDxXYCciIpPnmMeEszrT:l:")) != EOF)
1086 switch (c) {
1087 case 't':
1088 do_tty++;
1089 break;
1090 case 'd':
1091 do_disk |= DISK_OLD;
1092 break;
1093 case 'D':
1094 do_disk |= DISK_NEW;
1095 break;
1096 case 'x':
1097 do_disk |= DISK_EXTENDED;
1098 break;
1099 case 'X':
1100 if (do_disk & DISK_IOPATH_LTI)
1101 errflg++; /* -Y already used */
1102 else
1103 do_disk |= DISK_IOPATH_LI;
1104 break;
1105 case 'Y':
1106 if (do_disk & DISK_IOPATH_LI)
1107 errflg++; /* -X already used */
1108 else
1109 do_disk |= DISK_IOPATH_LTI;
1110 break;
1111 case 'C':
1112 do_controller++;
1113 break;
1114 case 'c':
1115 do_cpu++;
1116 break;
1117 case 'I':
1118 do_interval++;
1119 break;
1120 case 'p':
1121 do_partitions++;
1122 break;
1123 case 'P':
1124 do_partitions_only++;
1125 break;
1126 case 'n':
1127 do_conversions++;
1128 break;
1129 case 'M':
1130 do_megabytes++;
1131 break;
1132 case 'e':
1133 do_disk |= DISK_ERRORS;
1134 break;
1135 case 'E':
1136 do_disk |= DISK_EXTENDED_ERRORS;
1137 break;
1138 case 'i':
1139 do_devid = 1;
1140 break;
1141 case 's':
1142 suppress_state = 1;
1143 break;
1144 case 'z':
1145 suppress_zero = 1;
|
111 static uint_t tohdr = 1;
112
113 /*
114 * If we're in raw format, have we printed a header? We only do it
115 * once for raw but we emit it every REPRINT lines in non-raw format.
116 * This applies only for the basic header. The extended header is
117 * done only once in both formats.
118 */
119 static uint_t hdr_out;
120
121 /*
122 * Flags representing arguments from command line
123 */
124 static uint_t do_tty; /* show tty info (-t) */
125 static uint_t do_disk; /* show disk info per selected */
126 /* format (-d, -D, -e, -E, -x -X -Y) */
127 static uint_t do_cpu; /* show cpu info (-c) */
128 static uint_t do_interval; /* do intervals (-I) */
129 static int do_partitions; /* per-partition stats (-p) */
130 static int do_partitions_only; /* per-partition stats only (-P) */
131 static int do_zfs;
132 static int do_zfs_only;
133 /* no per-device stats for disks */
134 static uint_t do_conversions; /* display disks as cXtYdZ (-n) */
135 static uint_t do_megabytes; /* display data in MB/sec (-M) */
136 static uint_t do_controller; /* display controller info (-C) */
137 static uint_t do_raw; /* emit raw format (-r) */
138 static uint_t timestamp_fmt = NODATE; /* timestamp each display (-T) */
139 static uint_t do_devid; /* -E should show devid */
140
141 /*
142 * Default number of disk drives to be displayed in basic format
143 */
144 #define DEFAULT_LIMIT 4
145
146 struct iodev_filter df;
147
148 static uint_t suppress_state; /* skip state change messages */
149 static uint_t suppress_zero; /* skip zero valued lines */
150 static uint_t show_mountpts; /* show mount points */
151 static int interval; /* interval (seconds) to output */
152 static int iter; /* iterations from command line */
153
154 #define SMALL_SCRATCH_BUFLEN MAXNAMELEN
155
156 static int iodevs_nl; /* name field width */
157 #define IODEVS_NL_MIN 6 /* not too thin for "device" */
158 #define IODEVS_NL_MAX 64 /* but keep full width under 80 */
159
160 static char disk_header[132];
161 static uint_t dh_len; /* disk header length for centering */
162 static int lineout; /* data waiting to be printed? */
163
164 static struct snapshot *newss;
165 static struct snapshot *oldss;
166 static double getime; /* elapsed time */
167 static double percent; /* 100 / etime */
168
169 /*
170 * List of functions to be called which will construct the desired output
171 */
172 static format_t *formatter_list;
173 static format_t *formatter_end;
174
175 static u_longlong_t ull_delta(u_longlong_t, u_longlong_t);
176 static uint_t u32_delta(uint_t, uint_t);
177 static void setup(void (*nfunc)(void));
178 static void print_tty_hdr1(void);
210 hrtime_t start_n;
211 hrtime_t period_n;
212
213 (void) setlocale(LC_ALL, "");
214 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
215 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
216 #endif
217 (void) textdomain(TEXT_DOMAIN);
218
219 do_args(argc, argv);
220
221 /*
222 * iostat historically showed CPU changes, even though
223 * it doesn't provide much useful information
224 */
225 types |= SNAP_CPUS;
226
227 if (do_disk)
228 types |= SNAP_IODEVS;
229
230 if (do_disk && !do_partitions_only && !do_zfs_only)
231 df.if_allowed_types |= IODEV_DISK;
232 if (do_disk & DISK_IOPATH_LI) {
233 df.if_allowed_types |= IODEV_IOPATH_LTI;
234 types |= SNAP_IOPATHS_LI;
235 }
236 if (do_disk & DISK_IOPATH_LTI) {
237 df.if_allowed_types |= IODEV_IOPATH_LTI;
238 types |= SNAP_IOPATHS_LTI;
239 }
240 if (do_disk & DISK_ERROR_MASK)
241 types |= SNAP_IODEV_ERRORS;
242 if (do_partitions || do_partitions_only)
243 df.if_allowed_types |= IODEV_PARTITION;
244 if (do_zfs || do_zfs_only)
245 df.if_allowed_types |= IODEV_ZFS;
246 if (do_conversions)
247 types |= SNAP_IODEV_PRETTY;
248 if (do_devid)
249 types |= SNAP_IODEV_DEVID;
250 if (do_controller) {
251 if (!(do_disk & PRINT_VERTICAL) ||
252 (do_disk & DISK_EXTENDED_ERRORS))
253 fail(0, "-C can only be used with -e or -x.");
254 types |= SNAP_CONTROLLERS;
255 df.if_allowed_types |= IODEV_CONTROLLER;
256 }
257
258 hz = sysconf(_SC_CLK_TCK);
259
260 /*
261 * Undocumented behavior - sending a SIGCONT will result
262 * in a new header being emitted. Used only if we're not
263 * doing extended headers. This is a historical
264 * artifact.
265 */
951 "\t\t-c: report percentage of time system has spent\n"
952 "\t\t\tin user/system/dtrace/idle mode\n"
953 "\t\t-C: report disk statistics by controller\n"
954 "\t\t-d: display disk Kb/sec, transfers/sec, avg. \n"
955 "\t\t\tservice time in milliseconds \n"
956 "\t\t-D: display disk reads/sec, writes/sec, \n"
957 "\t\t\tpercentage disk utilization \n"
958 "\t\t-e: report device error summary statistics\n"
959 "\t\t-E: report extended device error statistics\n"
960 "\t\t-i: show device IDs for -E output\n"
961 "\t\t-I: report the counts in each interval,\n"
962 "\t\t\tinstead of rates, where applicable\n"
963 "\t\t-l n: Limit the number of disks to n\n"
964 "\t\t-m: Display mount points (most useful with -p)\n"
965 "\t\t-M: Display data throughput in MB/sec "
966 "instead of Kb/sec\n"
967 "\t\t-n: convert device names to cXdYtZ format\n"
968 "\t\t-p: report per-partition disk statistics\n"
969 "\t\t-P: report per-partition disk statistics only,\n"
970 "\t\t\tno per-device disk statistics\n"
971 "\t\t-f: report ZFS-level statistics for ZFS pool and\n"
972 "\t\t\tindividual vdevs\n"
973 "\t\t-F: report ZFS pool and individual physical vdevs\n"
974 "\t\t\tstatistics only, no per-device statistics\n"
975 "\t\t-r: Display data in comma separated format\n"
976 "\t\t-s: Suppress state change messages\n"
977 "\t\t-T d|u Display a timestamp in date (d) or unix "
978 "time_t (u)\n"
979 "\t\t-t: display chars read/written to terminals\n"
980 "\t\t-x: display extended disk statistics\n"
981 "\t\t-X: display I/O path statistics\n"
982 "\t\t-Y: display I/O path (I/T/L) statistics\n"
983 "\t\t-z: Suppress entries with all zero values\n");
984 exit(1);
985 }
986
987 /*ARGSUSED*/
988 static void
989 show_disk_errors(void *v1, void *v2, void *d)
990 {
991 struct iodev_snapshot *disk = (struct iodev_snapshot *)v2;
992 kstat_named_t *knp;
993 size_t col;
994 int i, len;
1073 }
1074 if ((col >= 62) || (i == 2)) {
1075 do_newline();
1076 col = 0;
1077 }
1078 }
1079 if (col > 0) {
1080 do_newline();
1081 }
1082 do_newline();
1083 }
1084
1085 void
1086 do_args(int argc, char **argv)
1087 {
1088 int c;
1089 int errflg = 0;
1090 extern char *optarg;
1091 extern int optind;
1092
1093 while ((c = getopt(argc, argv, "tdDxXYCciIpPfFnmMeEszrT:l:")) != EOF)
1094 switch (c) {
1095 case 't':
1096 do_tty++;
1097 break;
1098 case 'd':
1099 do_disk |= DISK_OLD;
1100 break;
1101 case 'D':
1102 do_disk |= DISK_NEW;
1103 break;
1104 case 'x':
1105 do_disk |= DISK_EXTENDED;
1106 break;
1107 case 'X':
1108 if (do_disk & DISK_IOPATH_LTI)
1109 errflg++; /* -Y already used */
1110 else
1111 do_disk |= DISK_IOPATH_LI;
1112 break;
1113 case 'Y':
1114 if (do_disk & DISK_IOPATH_LI)
1115 errflg++; /* -X already used */
1116 else
1117 do_disk |= DISK_IOPATH_LTI;
1118 break;
1119 case 'C':
1120 do_controller++;
1121 break;
1122 case 'c':
1123 do_cpu++;
1124 break;
1125 case 'I':
1126 do_interval++;
1127 break;
1128 case 'p':
1129 do_partitions++;
1130 break;
1131 case 'P':
1132 do_partitions_only++;
1133 break;
1134 case 'f':
1135 do_zfs++;
1136 break;
1137 case 'F':
1138 do_zfs_only++;
1139 break;
1140 case 'n':
1141 do_conversions++;
1142 break;
1143 case 'M':
1144 do_megabytes++;
1145 break;
1146 case 'e':
1147 do_disk |= DISK_ERRORS;
1148 break;
1149 case 'E':
1150 do_disk |= DISK_EXTENDED_ERRORS;
1151 break;
1152 case 'i':
1153 do_devid = 1;
1154 break;
1155 case 's':
1156 suppress_state = 1;
1157 break;
1158 case 'z':
1159 suppress_zero = 1;
|