xref: /freebsd-src/usr.sbin/gstat/gstat.c (revision d471b4f71dd3b09ada5bf58912dfb1266dd47750)
154a8adabSPoul-Henning Kamp /*-
2eb8f8877SWarner Losh  * SPDX-License-Identifier: BSD-3-Clause
31de7b4b8SPedro F. Giffuni  *
454a8adabSPoul-Henning Kamp  * Copyright (c) 2003 Poul-Henning Kamp
554a8adabSPoul-Henning Kamp  * All rights reserved.
654a8adabSPoul-Henning Kamp  *
754a8adabSPoul-Henning Kamp  * Redistribution and use in source and binary forms, with or without
854a8adabSPoul-Henning Kamp  * modification, are permitted provided that the following conditions
954a8adabSPoul-Henning Kamp  * are met:
1054a8adabSPoul-Henning Kamp  * 1. Redistributions of source code must retain the above copyright
1154a8adabSPoul-Henning Kamp  *    notice, this list of conditions and the following disclaimer.
1254a8adabSPoul-Henning Kamp  * 2. Redistributions in binary form must reproduce the above copyright
1354a8adabSPoul-Henning Kamp  *    notice, this list of conditions and the following disclaimer in the
1454a8adabSPoul-Henning Kamp  *    documentation and/or other materials provided with the distribution.
1554a8adabSPoul-Henning Kamp  * 3. The names of the authors may not be used to endorse or promote
1654a8adabSPoul-Henning Kamp  *    products derived from this software without specific prior written
1754a8adabSPoul-Henning Kamp  *    permission.
1854a8adabSPoul-Henning Kamp  *
1954a8adabSPoul-Henning Kamp  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2054a8adabSPoul-Henning Kamp  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2154a8adabSPoul-Henning Kamp  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2254a8adabSPoul-Henning Kamp  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2354a8adabSPoul-Henning Kamp  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2454a8adabSPoul-Henning Kamp  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2554a8adabSPoul-Henning Kamp  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2654a8adabSPoul-Henning Kamp  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2754a8adabSPoul-Henning Kamp  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2854a8adabSPoul-Henning Kamp  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2954a8adabSPoul-Henning Kamp  * SUCH DAMAGE.
3054a8adabSPoul-Henning Kamp  */
3154a8adabSPoul-Henning Kamp 
3254a8adabSPoul-Henning Kamp 
33711385c9SSimon L. B. Nielsen #include <sys/devicestat.h>
34711385c9SSimon L. B. Nielsen #include <sys/mman.h>
35711385c9SSimon L. B. Nielsen #include <sys/resource.h>
36711385c9SSimon L. B. Nielsen #include <sys/time.h>
37711385c9SSimon L. B. Nielsen 
38711385c9SSimon L. B. Nielsen #include <curses.h>
39711385c9SSimon L. B. Nielsen #include <devstat.h>
40711385c9SSimon L. B. Nielsen #include <err.h>
41711385c9SSimon L. B. Nielsen #include <errno.h>
42711385c9SSimon L. B. Nielsen #include <fcntl.h>
43711385c9SSimon L. B. Nielsen #include <histedit.h>
44711385c9SSimon L. B. Nielsen #include <libgeom.h>
45711385c9SSimon L. B. Nielsen #include <paths.h>
46711385c9SSimon L. B. Nielsen #include <regex.h>
4754a8adabSPoul-Henning Kamp #include <stdint.h>
48711385c9SSimon L. B. Nielsen #include <stdio.h>
4954a8adabSPoul-Henning Kamp #include <stdlib.h>
5054a8adabSPoul-Henning Kamp #include <string.h>
51711385c9SSimon L. B. Nielsen #include <sysexits.h>
5254a8adabSPoul-Henning Kamp #include <unistd.h>
5354a8adabSPoul-Henning Kamp 
540b9079bfSMarcelo Araujo static int flag_a, flag_b, flag_B, flag_c, flag_C, flag_d, flag_o, flag_p,
550b9079bfSMarcelo Araujo 	   flag_s;
56c8113770SDag-Erling Smørgrav static int flag_I = 1000000;
5754a8adabSPoul-Henning Kamp 
580b9079bfSMarcelo Araujo #define HIGH_PCT_BUSY_THRESH 80
590b9079bfSMarcelo Araujo #define MEDIUM_PCT_BUSY_THRESH 50
60a0312e48SUlf Lilleengen #define PRINTMSG(...) do {						\
61712a6ae6SMarcelo Araujo 		if ((flag_b && !loop) || (flag_B))			\
62a0312e48SUlf Lilleengen 			printf(__VA_ARGS__);				\
63a0312e48SUlf Lilleengen 		else if (!flag_b)					\
64a0312e48SUlf Lilleengen 			printw(__VA_ARGS__);				\
65a0312e48SUlf Lilleengen 	} while(0)
66a0312e48SUlf Lilleengen 
67a9cce232SAlfonso Gregory static void usage(void) __dead2;
68ab42be1fSGiorgos Keramidas 
69711385c9SSimon L. B. Nielsen static const char*
70711385c9SSimon L. B. Nielsen el_prompt(void)
71711385c9SSimon L. B. Nielsen {
72711385c9SSimon L. B. Nielsen 
73711385c9SSimon L. B. Nielsen 	return ("Filter: ");
74711385c9SSimon L. B. Nielsen }
75711385c9SSimon L. B. Nielsen 
7654a8adabSPoul-Henning Kamp int
7754a8adabSPoul-Henning Kamp main(int argc, char **argv)
7854a8adabSPoul-Henning Kamp {
7954a8adabSPoul-Henning Kamp 	int error, i, quit;
800b9079bfSMarcelo Araujo 	int curx, cury, maxx, maxy, line_len, loop, max_flen, head_printed;
8154a8adabSPoul-Henning Kamp 	struct devstat *gsp, *gsq;
8254a8adabSPoul-Henning Kamp 	void *sp, *sq;
8354a8adabSPoul-Henning Kamp 	double dt;
8454a8adabSPoul-Henning Kamp 	struct timespec tp, tq;
8554a8adabSPoul-Henning Kamp 	struct gmesh gmp;
8654a8adabSPoul-Henning Kamp 	struct gprovider *pp;
87a7526044SStefan Farfeleder 	struct gconsumer *cp;
8854a8adabSPoul-Henning Kamp 	struct gident *gid;
89711385c9SSimon L. B. Nielsen 	regex_t f_re, tmp_f_re;
9054a8adabSPoul-Henning Kamp 	short cf, cb;
9154a8adabSPoul-Henning Kamp 	char *p;
92711385c9SSimon L. B. Nielsen 	char f_s[100], pf_s[100], tmp_f_s[100];
930b9079bfSMarcelo Araujo 	char ts[100], g_name[4096];
94711385c9SSimon L. B. Nielsen 	const char *line;
95712a6ae6SMarcelo Araujo 	long double ld[16];
9654a8adabSPoul-Henning Kamp 	uint64_t u64;
97711385c9SSimon L. B. Nielsen 	EditLine *el;
98711385c9SSimon L. B. Nielsen 	History *hist;
99711385c9SSimon L. B. Nielsen 	HistEvent hist_ev;
10054a8adabSPoul-Henning Kamp 
101a0312e48SUlf Lilleengen 	hist = NULL;
102a0312e48SUlf Lilleengen 	el = NULL;
103a0312e48SUlf Lilleengen 	maxx = -1;
104a0312e48SUlf Lilleengen 	curx = -1;
105a0312e48SUlf Lilleengen 	loop = 1;
10662bc2068SMaxim Konovalov 	/* Turn on batch mode if output is not tty. */
10762bc2068SMaxim Konovalov 	if (!isatty(fileno(stdout)))
10862bc2068SMaxim Konovalov 		flag_b = 1;
10962bc2068SMaxim Konovalov 
110711385c9SSimon L. B. Nielsen 	f_s[0] = '\0';
1110b9079bfSMarcelo Araujo 	while ((i = getopt(argc, argv, "abBdcCf:I:ops")) != -1) {
11254a8adabSPoul-Henning Kamp 		switch (i) {
113be75dba7SLukas Ertl 		case 'a':
114be75dba7SLukas Ertl 			flag_a = 1;
115be75dba7SLukas Ertl 			break;
116a0312e48SUlf Lilleengen 		case 'b':
117a0312e48SUlf Lilleengen 			flag_b = 1;
118a0312e48SUlf Lilleengen 			break;
119712a6ae6SMarcelo Araujo 		case 'B':
120712a6ae6SMarcelo Araujo 			flag_B = 1;
121712a6ae6SMarcelo Araujo 			flag_b = 1;
122712a6ae6SMarcelo Araujo 			break;
12354a8adabSPoul-Henning Kamp 		case 'c':
1246bf611a7SGiorgos Keramidas 			flag_c = 1;
12554a8adabSPoul-Henning Kamp 			break;
1260b9079bfSMarcelo Araujo 		case 'C':
1270b9079bfSMarcelo Araujo 			flag_C = 1;
1280b9079bfSMarcelo Araujo 			/* csv out implies repeating batch mode */
1290b9079bfSMarcelo Araujo 			flag_b = 1;
1300b9079bfSMarcelo Araujo 			flag_B = 1;
1310b9079bfSMarcelo Araujo 			head_printed = 0;
1320b9079bfSMarcelo Araujo 			break;
133fbbe961cSPoul-Henning Kamp 		case 'd':
134fbbe961cSPoul-Henning Kamp 			flag_d = 1;
135fbbe961cSPoul-Henning Kamp 			break;
136711385c9SSimon L. B. Nielsen 		case 'f':
137711385c9SSimon L. B. Nielsen 			if (strlen(optarg) > sizeof(f_s) - 1)
138711385c9SSimon L. B. Nielsen 				errx(EX_USAGE, "Filter string too long");
139711385c9SSimon L. B. Nielsen 			if (regcomp(&f_re, optarg, REG_EXTENDED) != 0)
140711385c9SSimon L. B. Nielsen 				errx(EX_USAGE,
141711385c9SSimon L. B. Nielsen 				    "Invalid filter - see re_format(7)");
1422d0fc14cSXin LI 			strlcpy(f_s, optarg, sizeof(f_s));
143711385c9SSimon L. B. Nielsen 			break;
14416f6e715SAlexander Motin 		case 'o':
14516f6e715SAlexander Motin 			flag_o = 1;
14616f6e715SAlexander Motin 			break;
14754a8adabSPoul-Henning Kamp 		case 'I':
14854a8adabSPoul-Henning Kamp 			p = NULL;
14954a8adabSPoul-Henning Kamp 			i = strtoul(optarg, &p, 0);
1504fe8c1b6SGiorgos Keramidas 			if (p == optarg || errno == EINVAL ||
1514fe8c1b6SGiorgos Keramidas 			    errno == ERANGE) {
15254a8adabSPoul-Henning Kamp 				errx(1, "Invalid argument to -I");
15354a8adabSPoul-Henning Kamp 			} else if (!strcmp(p, "s"))
15454a8adabSPoul-Henning Kamp 				i *= 1000000;
15554a8adabSPoul-Henning Kamp 			else if (!strcmp(p, "ms"))
15654a8adabSPoul-Henning Kamp 				i *= 1000;
15754a8adabSPoul-Henning Kamp 			else if (!strcmp(p, "us"))
15854a8adabSPoul-Henning Kamp 				i *= 1;
15954a8adabSPoul-Henning Kamp 			flag_I = i;
16054a8adabSPoul-Henning Kamp 			break;
161f7317857SXin LI 		case 'p':
162f7317857SXin LI 			flag_p = 1;
163f7317857SXin LI 			break;
164712a6ae6SMarcelo Araujo 		case 's':
165712a6ae6SMarcelo Araujo 			flag_s = 1;
166712a6ae6SMarcelo Araujo 			break;
16754a8adabSPoul-Henning Kamp 		case '?':
16854a8adabSPoul-Henning Kamp 		default:
169ab42be1fSGiorgos Keramidas 			usage();
17054a8adabSPoul-Henning Kamp 		}
17154a8adabSPoul-Henning Kamp 	}
17254a8adabSPoul-Henning Kamp 	argc -= optind;
17354a8adabSPoul-Henning Kamp 	argv += optind;
17454a8adabSPoul-Henning Kamp 	if (argc != 0)
175ab42be1fSGiorgos Keramidas 		usage();
17654a8adabSPoul-Henning Kamp 
17754a8adabSPoul-Henning Kamp 	i = geom_gettree(&gmp);
17854a8adabSPoul-Henning Kamp 	if (i != 0)
17954a8adabSPoul-Henning Kamp 		err(1, "geom_gettree = %d", i);
18054a8adabSPoul-Henning Kamp 	error = geom_stats_open();
18154a8adabSPoul-Henning Kamp 	if (error)
18254a8adabSPoul-Henning Kamp 		err(1, "geom_stats_open()");
18354a8adabSPoul-Henning Kamp 	sq = NULL;
18454a8adabSPoul-Henning Kamp 	sq = geom_stats_snapshot_get();
18554a8adabSPoul-Henning Kamp 	if (sq == NULL)
18654a8adabSPoul-Henning Kamp 		err(1, "geom_stats_snapshot()");
187a0312e48SUlf Lilleengen 	if (!flag_b) {
188711385c9SSimon L. B. Nielsen 		/* Setup libedit */
189711385c9SSimon L. B. Nielsen 		hist = history_init();
190711385c9SSimon L. B. Nielsen 		if (hist == NULL)
191711385c9SSimon L. B. Nielsen 			err(EX_SOFTWARE, "history_init()");
192711385c9SSimon L. B. Nielsen 		history(hist, &hist_ev, H_SETSIZE, 100);
193711385c9SSimon L. B. Nielsen 		el = el_init("gstat", stdin, stdout, stderr);
194711385c9SSimon L. B. Nielsen 		if (el == NULL)
195711385c9SSimon L. B. Nielsen 			err(EX_SOFTWARE, "el_init");
196711385c9SSimon L. B. Nielsen 		el_set(el, EL_EDITOR, "emacs");
197711385c9SSimon L. B. Nielsen 		el_set(el, EL_SIGNAL, 1);
198711385c9SSimon L. B. Nielsen 		el_set(el, EL_HIST, history, hist);
199711385c9SSimon L. B. Nielsen 		el_set(el, EL_PROMPT, el_prompt);
200711385c9SSimon L. B. Nielsen 		if (f_s[0] != '\0')
201711385c9SSimon L. B. Nielsen 			history(hist, &hist_ev, H_ENTER, f_s);
2023185f0f0SAlan Somers 		/* Setup curses */
2033185f0f0SAlan Somers 		initscr();
2043185f0f0SAlan Somers 		start_color();
2053185f0f0SAlan Somers 		use_default_colors();
2063185f0f0SAlan Somers 		pair_content(0, &cf, &cb);
2073185f0f0SAlan Somers 		init_pair(1, COLOR_GREEN, cb);
2083185f0f0SAlan Somers 		init_pair(2, COLOR_MAGENTA, cb);
2093185f0f0SAlan Somers 		init_pair(3, COLOR_RED, cb);
2103185f0f0SAlan Somers 		cbreak();
2113185f0f0SAlan Somers 		noecho();
2123185f0f0SAlan Somers 		nonl();
2133185f0f0SAlan Somers 		nodelay(stdscr, 1);
2143185f0f0SAlan Somers 		intrflush(stdscr, FALSE);
2153185f0f0SAlan Somers 		keypad(stdscr, TRUE);
216a0312e48SUlf Lilleengen 	}
21754a8adabSPoul-Henning Kamp 	geom_stats_snapshot_timestamp(sq, &tq);
21854a8adabSPoul-Henning Kamp 	for (quit = 0; !quit;) {
21954a8adabSPoul-Henning Kamp 		sp = geom_stats_snapshot_get();
22054a8adabSPoul-Henning Kamp 		if (sp == NULL)
22154a8adabSPoul-Henning Kamp 			err(1, "geom_stats_snapshot()");
22254a8adabSPoul-Henning Kamp 		geom_stats_snapshot_timestamp(sp, &tp);
22354a8adabSPoul-Henning Kamp 		dt = tp.tv_sec - tq.tv_sec;
22454a8adabSPoul-Henning Kamp 		dt += (tp.tv_nsec - tq.tv_nsec) * 1e-9;
22554a8adabSPoul-Henning Kamp 		tq = tp;
2260b9079bfSMarcelo Araujo 		if (flag_C) { /* set timestamp string */
2270b9079bfSMarcelo Araujo 			(void)strftime(ts,sizeof(ts),
2280b9079bfSMarcelo Araujo 					"%F %T",localtime(&tq.tv_sec));
2290b9079bfSMarcelo Araujo 			(void)snprintf(ts,sizeof(ts),
2300b9079bfSMarcelo Araujo 					"%s.%.9ld",ts,tq.tv_nsec);
2310b9079bfSMarcelo Araujo 		}
23254a8adabSPoul-Henning Kamp 
23354a8adabSPoul-Henning Kamp 		geom_stats_snapshot_reset(sp);
23454a8adabSPoul-Henning Kamp 		geom_stats_snapshot_reset(sq);
235712a6ae6SMarcelo Araujo 		if (!flag_b)
23654a8adabSPoul-Henning Kamp 			move(0,0);
2370b9079bfSMarcelo Araujo 		if (!flag_C)
2380b9079bfSMarcelo Araujo 			PRINTMSG("dT: %5.3fs  w: %.3fs", dt,
2390b9079bfSMarcelo Araujo 					(float)flag_I / 1000000);
2400b9079bfSMarcelo Araujo 		if (!flag_C && f_s[0] != '\0') {
241a0312e48SUlf Lilleengen 			PRINTMSG("  filter: ");
242a0312e48SUlf Lilleengen 			if (!flag_b) {
243711385c9SSimon L. B. Nielsen 				getyx(stdscr, cury, curx);
244711385c9SSimon L. B. Nielsen 				getmaxyx(stdscr, maxy, maxx);
245a0312e48SUlf Lilleengen 			}
2462d0fc14cSXin LI 			strlcpy(pf_s, f_s, sizeof(pf_s));
247711385c9SSimon L. B. Nielsen 			max_flen = maxx - curx - 1;
248711385c9SSimon L. B. Nielsen 			if ((int)strlen(f_s) > max_flen && max_flen >= 0) {
249711385c9SSimon L. B. Nielsen 				if (max_flen > 3)
250711385c9SSimon L. B. Nielsen 					pf_s[max_flen - 3] = '.';
251711385c9SSimon L. B. Nielsen 				if (max_flen > 2)
252711385c9SSimon L. B. Nielsen 					pf_s[max_flen - 2] = '.';
253711385c9SSimon L. B. Nielsen 				if (max_flen > 1)
254711385c9SSimon L. B. Nielsen 					pf_s[max_flen - 1] = '.';
255711385c9SSimon L. B. Nielsen 				pf_s[max_flen] = '\0';
256711385c9SSimon L. B. Nielsen 			}
257a0312e48SUlf Lilleengen 			PRINTMSG("%s", pf_s);
258711385c9SSimon L. B. Nielsen 		}
2590b9079bfSMarcelo Araujo 		if (!flag_C) {
260a0312e48SUlf Lilleengen 			PRINTMSG("\n");
261a0312e48SUlf Lilleengen 			PRINTMSG(" L(q)  ops/s   ");
262712a6ae6SMarcelo Araujo 			if (flag_s) {
263712a6ae6SMarcelo Araujo 				PRINTMSG(" r/s     kB   kBps   ms/r   ");
264712a6ae6SMarcelo Araujo 				PRINTMSG(" w/s     kB   kBps   ms/w   ");
265712a6ae6SMarcelo Araujo 			}
266712a6ae6SMarcelo Araujo 			else {
267a0312e48SUlf Lilleengen 				PRINTMSG(" r/s   kBps   ms/r   ");
268a0312e48SUlf Lilleengen 				PRINTMSG(" w/s   kBps   ms/w   ");
269712a6ae6SMarcelo Araujo 			}
270712a6ae6SMarcelo Araujo 			if (flag_d) {
2710b9079bfSMarcelo Araujo 				if (flag_s) {
2720b9079bfSMarcelo Araujo 					PRINTMSG(" d/s     kB   kBps");
2730b9079bfSMarcelo Araujo 					PRINTMSG("   ms/d   ");
2740b9079bfSMarcelo Araujo 				} else
275a0312e48SUlf Lilleengen 					PRINTMSG(" d/s   kBps   ms/d   ");
276712a6ae6SMarcelo Araujo 			}
27716f6e715SAlexander Motin 			if (flag_o)
27816f6e715SAlexander Motin 				PRINTMSG(" o/s   ms/o   ");
279a0312e48SUlf Lilleengen 			PRINTMSG("%%busy Name\n");
2800b9079bfSMarcelo Araujo 		} else if (flag_C && !head_printed) {
2810b9079bfSMarcelo Araujo 			PRINTMSG("timestamp,name,q-depth,total_ops/s");
2820b9079bfSMarcelo Araujo 			if (flag_s) {
2830b9079bfSMarcelo Araujo 				PRINTMSG(",read/s,read_sz-KiB");
2840b9079bfSMarcelo Araujo 				PRINTMSG(",read-KiB/s,ms/read");
2850b9079bfSMarcelo Araujo 				PRINTMSG(",write/s,write_sz-KiB");
2860b9079bfSMarcelo Araujo 				PRINTMSG(",write-KiB/s,ms/write");
2870b9079bfSMarcelo Araujo 			} else {
2880b9079bfSMarcelo Araujo 				PRINTMSG(",read/s,read-KiB/s,ms/read");
2890b9079bfSMarcelo Araujo 				PRINTMSG(",write/s,write-KiB/s,ms/write");
2900b9079bfSMarcelo Araujo 			}
2910b9079bfSMarcelo Araujo 			if (flag_d) {
2920b9079bfSMarcelo Araujo 				if (flag_s) {
2930b9079bfSMarcelo Araujo 					PRINTMSG(",delete/s,delete-sz-KiB");
2940b9079bfSMarcelo Araujo 					PRINTMSG(",delete-KiB/s,ms/delete");
2950b9079bfSMarcelo Araujo 				} else {
2960b9079bfSMarcelo Araujo 					PRINTMSG(",delete/s,delete-KiB/s");
2970b9079bfSMarcelo Araujo 					PRINTMSG(",ms/delete");
2980b9079bfSMarcelo Araujo 				}
2990b9079bfSMarcelo Araujo 			}
3000b9079bfSMarcelo Araujo 			if (flag_o)
3010b9079bfSMarcelo Araujo 				PRINTMSG(",other/s,ms/other");
3020b9079bfSMarcelo Araujo 			PRINTMSG(",%%busy\n");
3030b9079bfSMarcelo Araujo 			head_printed = 1;
3040b9079bfSMarcelo Araujo 		}
30554a8adabSPoul-Henning Kamp 		for (;;) {
30654a8adabSPoul-Henning Kamp 			gsp = geom_stats_snapshot_next(sp);
30754a8adabSPoul-Henning Kamp 			gsq = geom_stats_snapshot_next(sq);
30854a8adabSPoul-Henning Kamp 			if (gsp == NULL || gsq == NULL)
30954a8adabSPoul-Henning Kamp 				break;
31054a8adabSPoul-Henning Kamp 			if (gsp->id == NULL)
31154a8adabSPoul-Henning Kamp 				continue;
31254a8adabSPoul-Henning Kamp 			gid = geom_lookupid(&gmp, gsp->id);
31354a8adabSPoul-Henning Kamp 			if (gid == NULL) {
31454a8adabSPoul-Henning Kamp 				geom_deletetree(&gmp);
31554a8adabSPoul-Henning Kamp 				i = geom_gettree(&gmp);
31654a8adabSPoul-Henning Kamp 				if (i != 0)
31754a8adabSPoul-Henning Kamp 					err(1, "geom_gettree = %d", i);
31854a8adabSPoul-Henning Kamp 				gid = geom_lookupid(&gmp, gsp->id);
31954a8adabSPoul-Henning Kamp 			}
32054a8adabSPoul-Henning Kamp 			if (gid == NULL)
32154a8adabSPoul-Henning Kamp 				continue;
322711385c9SSimon L. B. Nielsen 			if (gid->lg_what == ISCONSUMER && !flag_c)
32354a8adabSPoul-Henning Kamp 				continue;
324f7317857SXin LI 			if (flag_p && gid->lg_what == ISPROVIDER &&
3250b9079bfSMarcelo Araujo 			   ((struct gprovider *)
3260b9079bfSMarcelo Araujo 			    (gid->lg_ptr))->lg_geom->lg_rank != 1)
327f7317857SXin LI 				continue;
328711385c9SSimon L. B. Nielsen 			/* Do not print past end of window */
329a0312e48SUlf Lilleengen 			if (!flag_b) {
330711385c9SSimon L. B. Nielsen 				getyx(stdscr, cury, curx);
331711385c9SSimon L. B. Nielsen 				if (curx > 0)
332711385c9SSimon L. B. Nielsen 					continue;
333a0312e48SUlf Lilleengen 			}
334711385c9SSimon L. B. Nielsen 			if ((gid->lg_what == ISPROVIDER
335711385c9SSimon L. B. Nielsen 			    || gid->lg_what == ISCONSUMER) && f_s[0] != '\0') {
336711385c9SSimon L. B. Nielsen 				pp = gid->lg_ptr;
337711385c9SSimon L. B. Nielsen 				if ((regexec(&f_re, pp->lg_name, 0, NULL, 0)
338711385c9SSimon L. B. Nielsen 				     != 0))
339711385c9SSimon L. B. Nielsen 				  continue;
340711385c9SSimon L. B. Nielsen 			}
34154a8adabSPoul-Henning Kamp 			if (gsp->sequence0 != gsp->sequence1) {
3420b9079bfSMarcelo Araujo 				/*
3430b9079bfSMarcelo Araujo 				 * it is ok to skip entire line silently
3440b9079bfSMarcelo Araujo 				 * for CSV output
3450b9079bfSMarcelo Araujo 				 */
3460b9079bfSMarcelo Araujo 				if (!flag_C)
347a0312e48SUlf Lilleengen 					PRINTMSG("*\n");
34854a8adabSPoul-Henning Kamp 				continue;
34954a8adabSPoul-Henning Kamp 			}
35054a8adabSPoul-Henning Kamp 			devstat_compute_statistics(gsp, gsq, dt,
35154a8adabSPoul-Henning Kamp 			    DSM_QUEUE_LENGTH, &u64,
35254a8adabSPoul-Henning Kamp 			    DSM_TRANSFERS_PER_SECOND, &ld[0],
353fbbe961cSPoul-Henning Kamp 
35454a8adabSPoul-Henning Kamp 			    DSM_TRANSFERS_PER_SECOND_READ, &ld[1],
35554a8adabSPoul-Henning Kamp 			    DSM_MB_PER_SECOND_READ, &ld[2],
35654a8adabSPoul-Henning Kamp 			    DSM_MS_PER_TRANSACTION_READ, &ld[3],
357fbbe961cSPoul-Henning Kamp 
35854a8adabSPoul-Henning Kamp 			    DSM_TRANSFERS_PER_SECOND_WRITE, &ld[4],
35954a8adabSPoul-Henning Kamp 			    DSM_MB_PER_SECOND_WRITE, &ld[5],
36054a8adabSPoul-Henning Kamp 			    DSM_MS_PER_TRANSACTION_WRITE, &ld[6],
361fbbe961cSPoul-Henning Kamp 
36254a8adabSPoul-Henning Kamp 			    DSM_BUSY_PCT, &ld[7],
36316f6e715SAlexander Motin 
364fbbe961cSPoul-Henning Kamp 			    DSM_TRANSFERS_PER_SECOND_FREE, &ld[8],
365fbbe961cSPoul-Henning Kamp 			    DSM_MB_PER_SECOND_FREE, &ld[9],
366fbbe961cSPoul-Henning Kamp 			    DSM_MS_PER_TRANSACTION_FREE, &ld[10],
36716f6e715SAlexander Motin 
36816f6e715SAlexander Motin 			    DSM_TRANSFERS_PER_SECOND_OTHER, &ld[11],
36916f6e715SAlexander Motin 			    DSM_MS_PER_TRANSACTION_OTHER, &ld[12],
37016f6e715SAlexander Motin 
371712a6ae6SMarcelo Araujo 			    DSM_KB_PER_TRANSFER_READ, &ld[13],
372712a6ae6SMarcelo Araujo 			    DSM_KB_PER_TRANSFER_WRITE, &ld[14],
373712a6ae6SMarcelo Araujo 			    DSM_KB_PER_TRANSFER_FREE, &ld[15],
374712a6ae6SMarcelo Araujo 
37554a8adabSPoul-Henning Kamp 			    DSM_NONE);
37654a8adabSPoul-Henning Kamp 
377be75dba7SLukas Ertl 			if (flag_a && ld[7] < 0.1) {
378be75dba7SLukas Ertl 				*gsq = *gsp;
379be75dba7SLukas Ertl 				continue;
380be75dba7SLukas Ertl 			}
381be75dba7SLukas Ertl 
3820b9079bfSMarcelo Araujo 			/* store name for geom device */
3830b9079bfSMarcelo Araujo 			if (gid == NULL) {
3840b9079bfSMarcelo Araujo 				(void)snprintf(g_name, sizeof(g_name), "??");
3850b9079bfSMarcelo Araujo 			} else if (gid->lg_what == ISPROVIDER) {
3860b9079bfSMarcelo Araujo 				pp = gid->lg_ptr;
3870b9079bfSMarcelo Araujo 				(void)snprintf(g_name, sizeof(g_name), "%s",
3880b9079bfSMarcelo Araujo 						pp->lg_name);
3890b9079bfSMarcelo Araujo 			} else if (gid->lg_what == ISCONSUMER) {
3900b9079bfSMarcelo Araujo 				cp = gid->lg_ptr;
3910b9079bfSMarcelo Araujo 				(void)snprintf(g_name, sizeof(g_name),
3920b9079bfSMarcelo Araujo 					"%s/%s/%s",
3930b9079bfSMarcelo Araujo 					cp->lg_geom->lg_class->lg_name,
3940b9079bfSMarcelo Araujo 				   	cp->lg_geom->lg_name,
3950b9079bfSMarcelo Araujo 				    	cp->lg_provider->lg_name);
3960b9079bfSMarcelo Araujo 			}
3970b9079bfSMarcelo Araujo 
3980b9079bfSMarcelo Araujo 			if (flag_C) {
3990b9079bfSMarcelo Araujo 				PRINTMSG("%s", ts); /* timestamp */
4000b9079bfSMarcelo Araujo 				PRINTMSG(",%s", g_name); /* print name */
4010b9079bfSMarcelo Araujo 				PRINTMSG(",%ju", (uintmax_t)u64);
4020b9079bfSMarcelo Araujo 				PRINTMSG(",%.0f", (double)ld[0]);
4030b9079bfSMarcelo Araujo 				PRINTMSG(",%.0f", (double)ld[1]);
4040b9079bfSMarcelo Araujo 				if (flag_s)
4050b9079bfSMarcelo Araujo 					PRINTMSG(",%.0f", (double)ld[13]);
4060b9079bfSMarcelo Araujo 				PRINTMSG(",%.0f", (double)ld[2] * 1024);
4070b9079bfSMarcelo Araujo 				if (ld[3] > 1e3)
4080b9079bfSMarcelo Araujo 					PRINTMSG(",%.0f", (double)ld[3]);
409*d471b4f7SMichael Zhilin 				else if (ld[3] > 1e0)
4100b9079bfSMarcelo Araujo 					PRINTMSG(",%.1f", (double)ld[3]);
411*d471b4f7SMichael Zhilin 				else
412*d471b4f7SMichael Zhilin 					PRINTMSG(",%.3f", (double)ld[3]);
4130b9079bfSMarcelo Araujo 				PRINTMSG(",%.0f", (double)ld[4]);
4140b9079bfSMarcelo Araujo 				if (flag_s)
4150b9079bfSMarcelo Araujo 					PRINTMSG(",%.0f", (double)ld[14]);
4160b9079bfSMarcelo Araujo 				PRINTMSG(",%.0f", (double)ld[5] * 1024);
4170b9079bfSMarcelo Araujo 				if (ld[6] > 1e3)
4180b9079bfSMarcelo Araujo 					PRINTMSG(",%.0f", (double)ld[6]);
419*d471b4f7SMichael Zhilin 				else if (ld[6] > 1e0)
4200b9079bfSMarcelo Araujo 					PRINTMSG(",%.1f", (double)ld[6]);
421*d471b4f7SMichael Zhilin 				else
422*d471b4f7SMichael Zhilin 					PRINTMSG(",%.3f", (double)ld[6]);
4230b9079bfSMarcelo Araujo 
4240b9079bfSMarcelo Araujo 				if (flag_d) {
4250b9079bfSMarcelo Araujo 					PRINTMSG(",%.0f", (double)ld[8]);
4260b9079bfSMarcelo Araujo 					if (flag_s)
4270b9079bfSMarcelo Araujo 						PRINTMSG(",%.0f",
4280b9079bfSMarcelo Araujo 								(double)ld[15]);
4290b9079bfSMarcelo Araujo 					PRINTMSG(",%.0f", (double)ld[9] * 1024);
4300b9079bfSMarcelo Araujo 					if (ld[10] > 1e3)
4310b9079bfSMarcelo Araujo 						PRINTMSG(",%.0f",
4320b9079bfSMarcelo Araujo 								(double)ld[10]);
433*d471b4f7SMichael Zhilin 					else if (ld[10] > 1e0)
4340b9079bfSMarcelo Araujo 						PRINTMSG(",%.1f",
4350b9079bfSMarcelo Araujo 								(double)ld[10]);
436*d471b4f7SMichael Zhilin 					else
437*d471b4f7SMichael Zhilin 						PRINTMSG(",%.3f",
438*d471b4f7SMichael Zhilin 								(double)ld[10]);
4390b9079bfSMarcelo Araujo 				}
4400b9079bfSMarcelo Araujo 
4410b9079bfSMarcelo Araujo 				if (flag_o) {
4420b9079bfSMarcelo Araujo 					PRINTMSG(",%.0f", (double)ld[11]);
4430b9079bfSMarcelo Araujo 					if (ld[12] > 1e3)
4440b9079bfSMarcelo Araujo 						PRINTMSG(",%.0f",
4450b9079bfSMarcelo Araujo 								(double)ld[12]);
446*d471b4f7SMichael Zhilin 					else if (ld[12] > 1e0)
4470b9079bfSMarcelo Araujo 						PRINTMSG(",%.1f",
4480b9079bfSMarcelo Araujo 								(double)ld[12]);
449*d471b4f7SMichael Zhilin 					else
450*d471b4f7SMichael Zhilin 						PRINTMSG(",%.3f",
451*d471b4f7SMichael Zhilin 								(double)ld[12]);
4520b9079bfSMarcelo Araujo 				}
4530b9079bfSMarcelo Araujo 				PRINTMSG(",%.1lf", (double)ld[7]);
4540b9079bfSMarcelo Araujo 			} else {
455a0312e48SUlf Lilleengen 				PRINTMSG(" %4ju", (uintmax_t)u64);
456a0312e48SUlf Lilleengen 				PRINTMSG(" %6.0f", (double)ld[0]);
457a0312e48SUlf Lilleengen 				PRINTMSG(" %6.0f", (double)ld[1]);
458712a6ae6SMarcelo Araujo 				if (flag_s)
459712a6ae6SMarcelo Araujo 					PRINTMSG(" %6.0f", (double)ld[13]);
460a0312e48SUlf Lilleengen 				PRINTMSG(" %6.0f", (double)ld[2] * 1024);
4610c5de885SPoul-Henning Kamp 				if (ld[3] > 1e3)
462a0312e48SUlf Lilleengen 					PRINTMSG(" %6.0f", (double)ld[3]);
463*d471b4f7SMichael Zhilin 				else if (ld[3] > 1e0)
464a0312e48SUlf Lilleengen 					PRINTMSG(" %6.1f", (double)ld[3]);
465*d471b4f7SMichael Zhilin 				else
466*d471b4f7SMichael Zhilin 					PRINTMSG(" %6.3f", (double)ld[3]);
467a0312e48SUlf Lilleengen 				PRINTMSG(" %6.0f", (double)ld[4]);
468712a6ae6SMarcelo Araujo 				if (flag_s)
469712a6ae6SMarcelo Araujo 					PRINTMSG(" %6.0f", (double)ld[14]);
470a0312e48SUlf Lilleengen 				PRINTMSG(" %6.0f", (double)ld[5] * 1024);
4710c5de885SPoul-Henning Kamp 				if (ld[6] > 1e3)
472a0312e48SUlf Lilleengen 					PRINTMSG(" %6.0f", (double)ld[6]);
473*d471b4f7SMichael Zhilin 				else if (ld[6] > 1e0)
474a0312e48SUlf Lilleengen 					PRINTMSG(" %6.1f", (double)ld[6]);
475*d471b4f7SMichael Zhilin 				else
476*d471b4f7SMichael Zhilin 					PRINTMSG(" %6.3f", (double)ld[6]);
47754a8adabSPoul-Henning Kamp 
478fbbe961cSPoul-Henning Kamp 				if (flag_d) {
479a0312e48SUlf Lilleengen 					PRINTMSG(" %6.0f", (double)ld[8]);
480712a6ae6SMarcelo Araujo 					if (flag_s)
4810b9079bfSMarcelo Araujo 						PRINTMSG(" %6.0f",
4820b9079bfSMarcelo Araujo 								(double)ld[15]);
4830b9079bfSMarcelo Araujo 					PRINTMSG(" %6.0f",
4840b9079bfSMarcelo Araujo 							(double)ld[9] * 1024);
4850c5de885SPoul-Henning Kamp 					if (ld[10] > 1e3)
4860b9079bfSMarcelo Araujo 						PRINTMSG(" %6.0f",
4870b9079bfSMarcelo Araujo 								(double)ld[10]);
488*d471b4f7SMichael Zhilin 					else if (ld[10] > 1e0)
4890b9079bfSMarcelo Araujo 						PRINTMSG(" %6.1f",
4900b9079bfSMarcelo Araujo 								(double)ld[10]);
491*d471b4f7SMichael Zhilin 					else
492*d471b4f7SMichael Zhilin 						PRINTMSG(" %6.3f",
493*d471b4f7SMichael Zhilin 								(double)ld[10]);
494fbbe961cSPoul-Henning Kamp 				}
495fbbe961cSPoul-Henning Kamp 
49616f6e715SAlexander Motin 				if (flag_o) {
49716f6e715SAlexander Motin 					PRINTMSG(" %6.0f", (double)ld[11]);
49816f6e715SAlexander Motin 					if (ld[12] > 1e3)
4990b9079bfSMarcelo Araujo 						PRINTMSG(" %6.0f",
5000b9079bfSMarcelo Araujo 								(double)ld[12]);
501*d471b4f7SMichael Zhilin 					else if (ld[12] > 1e0)
5020b9079bfSMarcelo Araujo 						PRINTMSG(" %6.1f",
5030b9079bfSMarcelo Araujo 								(double)ld[12]);
504*d471b4f7SMichael Zhilin 					else
505*d471b4f7SMichael Zhilin 						PRINTMSG(" %6.3f",
506*d471b4f7SMichael Zhilin 								(double)ld[12]);
50716f6e715SAlexander Motin 				}
50816f6e715SAlexander Motin 
5090b9079bfSMarcelo Araujo 				if (ld[7] > HIGH_PCT_BUSY_THRESH)
51054a8adabSPoul-Henning Kamp 					i = 3;
5110b9079bfSMarcelo Araujo 				else if (ld[7] > MEDIUM_PCT_BUSY_THRESH)
51254a8adabSPoul-Henning Kamp 					i = 2;
51354a8adabSPoul-Henning Kamp 				else
51454a8adabSPoul-Henning Kamp 					i = 1;
515a0312e48SUlf Lilleengen 				if (!flag_b)
51654a8adabSPoul-Henning Kamp 					attron(COLOR_PAIR(i));
517a0312e48SUlf Lilleengen 				PRINTMSG(" %6.1lf", (double)ld[7]);
51862bc2068SMaxim Konovalov 				if (!flag_b) {
51954a8adabSPoul-Henning Kamp 					attroff(COLOR_PAIR(i));
520a0312e48SUlf Lilleengen 					PRINTMSG("|");
52162bc2068SMaxim Konovalov 				} else
52262bc2068SMaxim Konovalov 					PRINTMSG(" ");
5230b9079bfSMarcelo Araujo 				PRINTMSG(" %s", g_name);
524a0312e48SUlf Lilleengen 				if (!flag_b)
52554a8adabSPoul-Henning Kamp 					clrtoeol();
5260b9079bfSMarcelo Araujo 			}
527a0312e48SUlf Lilleengen 			PRINTMSG("\n");
52854a8adabSPoul-Henning Kamp 			*gsq = *gsp;
52954a8adabSPoul-Henning Kamp 		}
53054a8adabSPoul-Henning Kamp 		geom_stats_snapshot_free(sp);
531a0312e48SUlf Lilleengen 		if (flag_b) {
532a0312e48SUlf Lilleengen 			/* We loop extra to make sure we get the information. */
533a0312e48SUlf Lilleengen 			if (!loop)
534a0312e48SUlf Lilleengen 				break;
535712a6ae6SMarcelo Araujo 			if (!flag_B)
536a0312e48SUlf Lilleengen 				loop = 0;
537712a6ae6SMarcelo Araujo 			else
538d065b3ebSMaxim Sobolev 				if (fflush(stdout) == EOF)
539d065b3ebSMaxim Sobolev 					goto out;
540a0312e48SUlf Lilleengen 			usleep(flag_I);
541a0312e48SUlf Lilleengen 			continue;
542a0312e48SUlf Lilleengen 		}
543711385c9SSimon L. B. Nielsen 		getyx(stdscr, cury, curx);
544711385c9SSimon L. B. Nielsen 		getmaxyx(stdscr, maxy, maxx);
54554a8adabSPoul-Henning Kamp 		clrtobot();
546711385c9SSimon L. B. Nielsen 		if (maxy - 1 <= cury)
547711385c9SSimon L. B. Nielsen 			move(maxy - 1, 0);
54854a8adabSPoul-Henning Kamp 		refresh();
54954a8adabSPoul-Henning Kamp 		usleep(flag_I);
550711385c9SSimon L. B. Nielsen 		while((i = getch()) != ERR) {
55154a8adabSPoul-Henning Kamp 			switch (i) {
55254a8adabSPoul-Henning Kamp 			case '>':
55354a8adabSPoul-Henning Kamp 				flag_I *= 2;
55454a8adabSPoul-Henning Kamp 				break;
55554a8adabSPoul-Henning Kamp 			case '<':
55654a8adabSPoul-Henning Kamp 				flag_I /= 2;
55754a8adabSPoul-Henning Kamp 				if (flag_I < 1000)
55854a8adabSPoul-Henning Kamp 					flag_I = 1000;
55954a8adabSPoul-Henning Kamp 				break;
56054a8adabSPoul-Henning Kamp 			case 'c':
56154a8adabSPoul-Henning Kamp 				flag_c = !flag_c;
56254a8adabSPoul-Henning Kamp 				break;
563711385c9SSimon L. B. Nielsen 			case 'f':
564711385c9SSimon L. B. Nielsen 				move(0,0);
565711385c9SSimon L. B. Nielsen 				clrtoeol();
566711385c9SSimon L. B. Nielsen 				refresh();
567711385c9SSimon L. B. Nielsen 				line = el_gets(el, &line_len);
568711385c9SSimon L. B. Nielsen 				if (line == NULL)
569711385c9SSimon L. B. Nielsen 					err(1, "el_gets");
570711385c9SSimon L. B. Nielsen 				if (line_len > 1)
571711385c9SSimon L. B. Nielsen 					history(hist, &hist_ev, H_ENTER, line);
5722d0fc14cSXin LI 				strlcpy(tmp_f_s, line, sizeof(f_s));
573711385c9SSimon L. B. Nielsen 				if ((p = strchr(tmp_f_s, '\n')) != NULL)
574711385c9SSimon L. B. Nielsen 					*p = '\0';
575711385c9SSimon L. B. Nielsen 				/*
5763185f0f0SAlan Somers 				 * Fix the terminal.  We messed up
577711385c9SSimon L. B. Nielsen 				 * curses idea of the screen by using
578711385c9SSimon L. B. Nielsen 				 * libedit.
579711385c9SSimon L. B. Nielsen 				 */
580711385c9SSimon L. B. Nielsen 				clear();
581711385c9SSimon L. B. Nielsen 				refresh();
5823185f0f0SAlan Somers 				cbreak();
5833185f0f0SAlan Somers 				noecho();
5843185f0f0SAlan Somers 				nonl();
585711385c9SSimon L. B. Nielsen 				if (regcomp(&tmp_f_re, tmp_f_s, REG_EXTENDED)
586711385c9SSimon L. B. Nielsen 				    != 0) {
587711385c9SSimon L. B. Nielsen 					move(0, 0);
588711385c9SSimon L. B. Nielsen 					printw("Invalid filter");
589711385c9SSimon L. B. Nielsen 					refresh();
590711385c9SSimon L. B. Nielsen 					sleep(1);
591711385c9SSimon L. B. Nielsen 				} else {
5922d0fc14cSXin LI 					strlcpy(f_s, tmp_f_s, sizeof(f_s));
593711385c9SSimon L. B. Nielsen 					f_re = tmp_f_re;
594711385c9SSimon L. B. Nielsen 				}
595711385c9SSimon L. B. Nielsen 				break;
596711385c9SSimon L. B. Nielsen 			case 'F':
597711385c9SSimon L. B. Nielsen 				f_s[0] = '\0';
598711385c9SSimon L. B. Nielsen 				break;
59954a8adabSPoul-Henning Kamp 			case 'q':
60054a8adabSPoul-Henning Kamp 				quit = 1;
60154a8adabSPoul-Henning Kamp 				break;
60254a8adabSPoul-Henning Kamp 			default:
60354a8adabSPoul-Henning Kamp 				break;
60454a8adabSPoul-Henning Kamp 			}
60554a8adabSPoul-Henning Kamp 		}
606711385c9SSimon L. B. Nielsen 	}
607d065b3ebSMaxim Sobolev out:
608a0312e48SUlf Lilleengen 	if (!flag_b) {
609711385c9SSimon L. B. Nielsen 		el_end(el);
6103185f0f0SAlan Somers 		endwin();
611a0312e48SUlf Lilleengen 	}
612711385c9SSimon L. B. Nielsen 	exit(EX_OK);
61354a8adabSPoul-Henning Kamp }
614ab42be1fSGiorgos Keramidas 
615ab42be1fSGiorgos Keramidas static void
616ab42be1fSGiorgos Keramidas usage(void)
617ab42be1fSGiorgos Keramidas {
6180b9079bfSMarcelo Araujo 	fprintf(stderr, "usage: gstat [-abBcCdps] [-f filter] [-I interval]\n");
619711385c9SSimon L. B. Nielsen 	exit(EX_USAGE);
620ab42be1fSGiorgos Keramidas         /* NOTREACHED */
621ab42be1fSGiorgos Keramidas }
622