Date: Sat, 27 Jun 2026 11:28:44 +0000
From: Poul-Henning Kamp <phk@FreeBSD.org>
To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject: git: c263dd413ca0 - main - gstat: Refactor and polish. Added option for {kB/MB/GB} per second.
Message-ID: <6a3fb3ec.3bd82.7e120966@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by phk: URL: https://cgit.FreeBSD.org/src/commit/?id=c263dd413ca0b43b4513e6e6dd8ed64c0eb9c3aa commit c263dd413ca0b43b4513e6e6dd8ed64c0eb9c3aa Author: Poul-Henning Kamp <phk@FreeBSD.org> AuthorDate: 2026-06-27 11:26:18 +0000 Commit: Poul-Henning Kamp <phk@FreeBSD.org> CommitDate: 2026-06-27 11:28:33 +0000 gstat: Refactor and polish. Added option for {kB/MB/GB} per second. --- usr.sbin/gstat/gstat.8 | 24 +- usr.sbin/gstat/gstat.c | 770 ++++++++++++++++++++++++++----------------------- 2 files changed, 437 insertions(+), 357 deletions(-) diff --git a/usr.sbin/gstat/gstat.8 b/usr.sbin/gstat/gstat.8 index e882aa75b8d7..602376d5fd0d 100644 --- a/usr.sbin/gstat/gstat.8 +++ b/usr.sbin/gstat/gstat.8 @@ -78,6 +78,12 @@ Only devices with the names matching will be displayed. The format of the regular expression is described in .Xr re_format 7 . +.It Fl g +Show Gigabytes +.It Fl k +Show kilobytes +.It Fl m +Show Megabytes .It Fl I Ar interval Refresh the .Nm @@ -96,7 +102,7 @@ Enable display of statistics for other operations .It Fl p Only display physical providers (those with rank of 1). .It Fl s -Enable blocks' size statistics. +Enable average block size. .El .Sh INTERACTIVE COMMANDS These commands are currently recognized if @@ -107,17 +113,33 @@ is not running in batch mode: Halve the update interval. .It Ic > Double the update interval. +.It Ic 1 +Set update interval to one second .It Ic c Toggle display of .Xr geom 4 consumers. +.It Ic d +Toggle display BIO_DELETE .It Ic f Display only devices with the names matching regular expression filter (prompt for filter). .It Ic F Remove device filter. +.It Ic g +Show gigabytes. +.It Ic k +Show kilobytes. +.It Ic m +Show megabytes. +.It Ic o +Toggle display other (BIO_FLUSH) operations. +.It Ic p +Toggle display other only primary providers. .It Ic q Quit +.It Ic s +Toggle average block size. .Nm . .El .Sh EXIT STATUS diff --git a/usr.sbin/gstat/gstat.c b/usr.sbin/gstat/gstat.c index c650f7120a40..11616d263272 100644 --- a/usr.sbin/gstat/gstat.c +++ b/usr.sbin/gstat/gstat.c @@ -44,6 +44,7 @@ #include <libgeom.h> #include <paths.h> #include <regex.h> +#include <stdarg.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -51,20 +52,190 @@ #include <sysexits.h> #include <unistd.h> +#define HIGH_PCT_BUSY_THRESH 80 +#define MEDIUM_PCT_BUSY_THRESH 50 + static int flag_a, flag_b, flag_B, flag_c, flag_C, flag_d, flag_o, flag_p, flag_s; static int flag_I = 1000000; -#define HIGH_PCT_BUSY_THRESH 80 -#define MEDIUM_PCT_BUSY_THRESH 50 -#define PRINTMSG(...) do { \ - if ((flag_b && !loop) || (flag_B)) \ - printf(__VA_ARGS__); \ - else if (!flag_b) \ - printw(__VA_ARGS__); \ - } while(0) +static int quit; +static int max_flen; +static History *hist; +static EditLine *el; +static HistEvent hist_ev; +static regex_t f_re; +static char pf_s[100]; +static char f_s[100]; +static uintmax_t loop; +static double dt; +static double byte_scale = 1024; +static const char *byte_unit = "k"; + +struct kstat { + long double transfers_per_second; + long double mb_per_second; + long double ms_per_transaction; + long double kb_per_transfer; +}; + +static void __dead2 +usage(void) +{ + fprintf(stderr, + "usage: gstat [-abBcCdgkmops] [-f filter] [-I interval]\n"); + exit(EX_USAGE); + /* NOTREACHED */ +} + +static void +use_kb(void) +{ + byte_scale = 1024; + byte_unit = "k"; +} + +static void +use_mb(void) +{ + byte_scale = 1; + byte_unit = "M"; +} + +static void +use_gb(void) +{ + byte_scale = 1.0/1024; + byte_unit = "G"; +} + +static void +printer(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (flag_B || (flag_b && loop == 2)) + vprintf(fmt, ap); + if (!flag_b) + vw_printw(stdscr, fmt, ap); + va_end(ap); +} -static void usage(void) __dead2; +static void +text_fld_header(const char *k) +{ + if (flag_s) + printer(" %s/s kB %sBps ms/%s ", k, byte_unit, k); + else + printer(" %s/s %sBps ms/%s ", k, byte_unit, k); +} + +static void +text_header(void) +{ + int curx = 0, cury = 0; + int maxx = 0, maxy = 0; + + if (!flag_b) + move(0,0); + printer("dT: %5.3fs w: %.3fs", dt, + (float)flag_I / 1000000); + if (f_s[0] != '\0') { + printer(" filter: "); + if (!flag_b) { + getyx(stdscr, cury, curx); + (void)cury; + getmaxyx(stdscr, maxy, maxx); + (void)maxy; + } + strlcpy(pf_s, f_s, sizeof(pf_s)); + max_flen = maxx - curx - 1; + if ((int)strlen(f_s) > max_flen && max_flen >= 0) { + if (max_flen > 3) + pf_s[max_flen - 3] = '.'; + if (max_flen > 2) + pf_s[max_flen - 2] = '.'; + if (max_flen > 1) + pf_s[max_flen - 1] = '.'; + pf_s[max_flen] = '\0'; + } + printer("%s", pf_s); + } + + if (!flag_b) + clrtoeol(); + printer("\n"); + + printer(" L(q) ops/s "); + text_fld_header("r"); + text_fld_header("w"); + if (flag_d) + text_fld_header("d"); + if (flag_o) + printer(" o/s ms/o "); + printer("%%busy Name"); + if (!flag_b) + clrtoeol(); + printer("\n"); +} + +static void +print_kstat_text(const struct kstat *ks, int other) +{ + printer(" %6.0f", (double)ks->transfers_per_second); + if (flag_s && !other) + printer(" %6.0f", (double)ks->kb_per_transfer); + if (!other) + printer(" %6.0f", (double)ks->mb_per_second * byte_scale); + if (ks->ms_per_transaction < 100) + printer(" %6.3f", (double)ks->ms_per_transaction); + else if (ks->ms_per_transaction < 1000) + printer(" %6.2f", (double)ks->ms_per_transaction); + else if (ks->ms_per_transaction < 10000) + printer(" %6.1f", (double)ks->ms_per_transaction); + else + printer(" %6.0f", (double)ks->ms_per_transaction); +} + +static void +print_head_csv(void) +{ + + printf("timestamp,name,q-depth,total_ops/s"); + if (flag_s) { + printf(",read/s,read_sz-KiB"); + printf(",read-KiB/s,ms/read"); + printf(",write/s,write_sz-KiB"); + printf(",write-KiB/s,ms/write"); + } else { + printf(",read/s,read-KiB/s,ms/read"); + printf(",write/s,write-KiB/s,ms/write"); + } + if (flag_d) { + if (flag_s) { + printf(",delete/s,delete-sz-KiB"); + printf(",delete-KiB/s,ms/delete"); + } else { + printf(",delete/s,delete-KiB/s"); + printf(",ms/delete"); + } + } + if (flag_o) + printf(",other/s,ms/other"); + printf(",%%busy\n"); +} + +static void +print_kstat_csv(const struct kstat *ks, int other) +{ + + printf(",%.0f", (double)ks->transfers_per_second); + if (flag_s && !other) + printf(",%.0f", (double)ks->kb_per_transfer); + if (!other) + printf(",%.0f", (double)ks->mb_per_second * 1024); + printf(",%.3f", (double)ks->ms_per_transaction); +} static const char* el_prompt(void) @@ -73,42 +244,167 @@ el_prompt(void) return ("Filter: "); } +static void +setup_interactive(void) +{ + short cf, cb; + + /* Setup libedit */ + hist = history_init(); + if (hist == NULL) + err(EX_SOFTWARE, "history_init()"); + history(hist, &hist_ev, H_SETSIZE, 100); + el = el_init("gstat", stdin, stdout, stderr); + if (el == NULL) + err(EX_SOFTWARE, "el_init"); + el_set(el, EL_EDITOR, "emacs"); + el_set(el, EL_SIGNAL, 1); + el_set(el, EL_HIST, history, hist); + el_set(el, EL_PROMPT, el_prompt); + if (f_s[0] != '\0') + history(hist, &hist_ev, H_ENTER, f_s); + /* Setup curses */ + initscr(); + start_color(); + use_default_colors(); + pair_content(0, &cf, &cb); + init_pair(1, COLOR_GREEN, cb); + init_pair(2, COLOR_MAGENTA, cb); + init_pair(3, COLOR_RED, cb); + cbreak(); + noecho(); + nonl(); + nodelay(stdscr, 1); + intrflush(stdscr, FALSE); + keypad(stdscr, TRUE); +} + +static int +poll_input(void) +{ + int i, line_len; + char *p; + const char *line; + char tmp_f_s[100]; + regex_t tmp_f_re; + + i = getch(); + if (i == ERR) + return (0); + switch (i) { + case '>': + flag_I *= 2; + break; + case '<': + flag_I /= 2; + if (flag_I < 1000) + flag_I = 1000; + break; + case '1': + flag_I = 1000000; + break; + case 'c': + flag_c = !flag_c; + break; + case 'd': + flag_d = !flag_d; + break; + case 'o': + flag_o = !flag_o; + break; + case 'f': + move(0,0); + clrtoeol(); + refresh(); + line = el_gets(el, &line_len); + if (line == NULL) + err(1, "el_gets"); + if (line_len > 1) + history(hist, &hist_ev, H_ENTER, line); + strlcpy(tmp_f_s, line, sizeof(f_s)); + if ((p = strchr(tmp_f_s, '\n')) != NULL) + *p = '\0'; + /* + * Fix the terminal. We messed up + * curses idea of the screen by using + * libedit. + */ + clear(); + refresh(); + cbreak(); + noecho(); + nonl(); + if (regcomp(&tmp_f_re, tmp_f_s, REG_EXTENDED) + != 0) { + move(0, 0); + printw("Invalid filter"); + refresh(); + sleep(1); + } else { + strlcpy(f_s, tmp_f_s, sizeof(f_s)); + f_re = tmp_f_re; + } + break; + case 'F': + f_s[0] = '\0'; + break; + case 'g': + case 'G': + use_gb(); + break; + case 'k': + case 'K': + use_kb(); + break; + case 'm': + case 'M': + use_mb(); + break; + case 'q': + quit = 1; + break; + case 'p': + flag_p = !flag_p; + break; + case 's': + flag_s = !flag_s; + break; + default: + break; + } + return (1); +} + int main(int argc, char **argv) { - int error, i, quit; - int curx, cury, maxx, maxy, line_len, loop, max_flen, head_printed; + int error, i; + int curx, cury, maxx, maxy; struct devstat *gsp, *gsq; void *sp, *sq; - double dt; struct timespec tp, tq; struct gmesh gmp; struct gprovider *pp; struct gconsumer *cp; struct gident *gid; - regex_t f_re, tmp_f_re; - short cf, cb; char *p; - char f_s[100], pf_s[100], tmp_f_s[100]; char ts[100], g_name[4096]; - const char *line; - long double ld[16]; - uint64_t u64; - EditLine *el; - History *hist; - HistEvent hist_ev; + long double xfer_per_sec, busy_pct; + struct kstat krd, kwr, kfree, kother; + uint64_t queue_len; + memset(&kother, 0, sizeof kother); hist = NULL; el = NULL; maxx = -1; curx = -1; - loop = 1; + loop = 0; /* Turn on batch mode if output is not tty. */ if (!isatty(fileno(stdout))) flag_b = 1; f_s[0] = '\0'; - while ((i = getopt(argc, argv, "abBdcCf:I:ops")) != -1) { + while ((i = getopt(argc, argv, "abBcdCf:gI:kmops")) != -1) { switch (i) { case 'a': flag_a = 1; @@ -128,7 +424,6 @@ main(int argc, char **argv) /* csv out implies repeating batch mode */ flag_b = 1; flag_B = 1; - head_printed = 0; break; case 'd': flag_d = 1; @@ -141,6 +436,9 @@ main(int argc, char **argv) "Invalid filter - see re_format(7)"); strlcpy(f_s, optarg, sizeof(f_s)); break; + case 'g': + use_gb(); + break; case 'I': p = NULL; i = strtoul(optarg, &p, 0); @@ -155,6 +453,12 @@ main(int argc, char **argv) i *= 1; flag_I = i; break; + case 'k': + use_kb(); + break; + case 'm': + use_mb(); + break; case 'o': flag_o = 1; break; @@ -180,42 +484,16 @@ main(int argc, char **argv) error = geom_stats_open(); if (error) err(1, "geom_stats_open()"); - sq = NULL; sq = geom_stats_snapshot_get(); if (sq == NULL) err(1, "geom_stats_snapshot()"); - if (!flag_b) { - /* Setup libedit */ - hist = history_init(); - if (hist == NULL) - err(EX_SOFTWARE, "history_init()"); - history(hist, &hist_ev, H_SETSIZE, 100); - el = el_init("gstat", stdin, stdout, stderr); - if (el == NULL) - err(EX_SOFTWARE, "el_init"); - el_set(el, EL_EDITOR, "emacs"); - el_set(el, EL_SIGNAL, 1); - el_set(el, EL_HIST, history, hist); - el_set(el, EL_PROMPT, el_prompt); - if (f_s[0] != '\0') - history(hist, &hist_ev, H_ENTER, f_s); - /* Setup curses */ - initscr(); - start_color(); - use_default_colors(); - pair_content(0, &cf, &cb); - init_pair(1, COLOR_GREEN, cb); - init_pair(2, COLOR_MAGENTA, cb); - init_pair(3, COLOR_RED, cb); - cbreak(); - noecho(); - nonl(); - nodelay(stdscr, 1); - intrflush(stdscr, FALSE); - keypad(stdscr, TRUE); - } + if (!flag_b) + setup_interactive(); + if (flag_C) + print_head_csv(); geom_stats_snapshot_timestamp(sq, &tq); for (quit = 0; !quit;) { + loop += 1; sp = geom_stats_snapshot_get(); if (sp == NULL) err(1, "geom_stats_snapshot()"); @@ -229,79 +507,11 @@ main(int argc, char **argv) (void)snprintf(ts,sizeof(ts), "%s.%.9ld",ts,tq.tv_nsec); } - + if (loop > 1 && !flag_C) + text_header(); + geom_stats_snapshot_reset(sp); geom_stats_snapshot_reset(sq); - if (!flag_b) - move(0,0); - if (!flag_C) - PRINTMSG("dT: %5.3fs w: %.3fs", dt, - (float)flag_I / 1000000); - if (!flag_C && f_s[0] != '\0') { - PRINTMSG(" filter: "); - if (!flag_b) { - getyx(stdscr, cury, curx); - getmaxyx(stdscr, maxy, maxx); - } - strlcpy(pf_s, f_s, sizeof(pf_s)); - max_flen = maxx - curx - 1; - if ((int)strlen(f_s) > max_flen && max_flen >= 0) { - if (max_flen > 3) - pf_s[max_flen - 3] = '.'; - if (max_flen > 2) - pf_s[max_flen - 2] = '.'; - if (max_flen > 1) - pf_s[max_flen - 1] = '.'; - pf_s[max_flen] = '\0'; - } - PRINTMSG("%s", pf_s); - } - if (!flag_C) { - PRINTMSG("\n"); - PRINTMSG(" L(q) ops/s "); - if (flag_s) { - PRINTMSG(" r/s kB kBps ms/r "); - PRINTMSG(" w/s kB kBps ms/w "); - } - else { - PRINTMSG(" r/s kBps ms/r "); - PRINTMSG(" w/s kBps ms/w "); - } - if (flag_d) { - if (flag_s) { - PRINTMSG(" d/s kB kBps"); - PRINTMSG(" ms/d "); - } else - PRINTMSG(" d/s kBps ms/d "); - } - if (flag_o) - PRINTMSG(" o/s ms/o "); - PRINTMSG("%%busy Name\n"); - } else if (flag_C && !head_printed) { - PRINTMSG("timestamp,name,q-depth,total_ops/s"); - if (flag_s) { - PRINTMSG(",read/s,read_sz-KiB"); - PRINTMSG(",read-KiB/s,ms/read"); - PRINTMSG(",write/s,write_sz-KiB"); - PRINTMSG(",write-KiB/s,ms/write"); - } else { - PRINTMSG(",read/s,read-KiB/s,ms/read"); - PRINTMSG(",write/s,write-KiB/s,ms/write"); - } - if (flag_d) { - if (flag_s) { - PRINTMSG(",delete/s,delete-sz-KiB"); - PRINTMSG(",delete-KiB/s,ms/delete"); - } else { - PRINTMSG(",delete/s,delete-KiB/s"); - PRINTMSG(",ms/delete"); - } - } - if (flag_o) - PRINTMSG(",other/s,ms/other"); - PRINTMSG(",%%busy\n"); - head_printed = 1; - } for (;;) { gsp = geom_stats_snapshot_next(sp); gsq = geom_stats_snapshot_next(sq); @@ -339,50 +549,48 @@ main(int argc, char **argv) continue; } if (gsp->sequence0 != gsp->sequence1) { - /* + /* * it is ok to skip entire line silently * for CSV output */ if (!flag_C) - PRINTMSG("*\n"); + printer("*\n"); continue; } - devstat_compute_statistics(gsp, gsq, dt, - DSM_QUEUE_LENGTH, &u64, - DSM_TRANSFERS_PER_SECOND, &ld[0], - - DSM_TRANSFERS_PER_SECOND_READ, &ld[1], - DSM_MB_PER_SECOND_READ, &ld[2], - DSM_MS_PER_TRANSACTION_READ, &ld[3], - DSM_TRANSFERS_PER_SECOND_WRITE, &ld[4], - DSM_MB_PER_SECOND_WRITE, &ld[5], - DSM_MS_PER_TRANSACTION_WRITE, &ld[6], +#define CONVENIENCE(oper, kst) \ + DSM_TRANSFERS_PER_SECOND_##oper, &kst.transfers_per_second, \ + DSM_MB_PER_SECOND_##oper, &kst.mb_per_second, \ + DSM_MS_PER_TRANSACTION_##oper, &kst.ms_per_transaction, \ + DSM_KB_PER_TRANSFER_##oper, &kst.kb_per_transfer, - DSM_BUSY_PCT, &ld[7], + devstat_compute_statistics(gsp, gsq, dt, + DSM_QUEUE_LENGTH, &queue_len, + DSM_TRANSFERS_PER_SECOND, &xfer_per_sec, - DSM_TRANSFERS_PER_SECOND_FREE, &ld[8], - DSM_MB_PER_SECOND_FREE, &ld[9], - DSM_MS_PER_TRANSACTION_FREE, &ld[10], + CONVENIENCE(READ, krd) + CONVENIENCE(WRITE, kwr) + CONVENIENCE(FREE, kfree) - DSM_TRANSFERS_PER_SECOND_OTHER, &ld[11], - DSM_MS_PER_TRANSACTION_OTHER, &ld[12], + DSM_BUSY_PCT, &busy_pct, - DSM_KB_PER_TRANSFER_READ, &ld[13], - DSM_KB_PER_TRANSFER_WRITE, &ld[14], - DSM_KB_PER_TRANSFER_FREE, &ld[15], + DSM_TRANSFERS_PER_SECOND_OTHER, + &kother.transfers_per_second, + DSM_MS_PER_TRANSACTION_OTHER, + &kother.ms_per_transaction, DSM_NONE); - if (flag_a && ld[7] < 0.1) { - *gsq = *gsp; + *gsq = *gsp; + if (loop == 1) + continue; + + if (flag_a && busy_pct < 0.1) { continue; } /* store name for geom device */ - if (gid == NULL) { - (void)snprintf(g_name, sizeof(g_name), "??"); - } else if (gid->lg_what == ISPROVIDER) { + if (gid->lg_what == ISPROVIDER) { pp = gid->lg_ptr; (void)snprintf(g_name, sizeof(g_name), "%s", pp->lg_name); @@ -391,231 +599,81 @@ main(int argc, char **argv) (void)snprintf(g_name, sizeof(g_name), "%s/%s/%s", cp->lg_geom->lg_class->lg_name, - cp->lg_geom->lg_name, - cp->lg_provider->lg_name); + cp->lg_geom->lg_name, + cp->lg_provider->lg_name); } - - if (flag_C) { - PRINTMSG("%s", ts); /* timestamp */ - PRINTMSG(",%s", g_name); /* print name */ - PRINTMSG(",%ju", (uintmax_t)u64); - PRINTMSG(",%.0f", (double)ld[0]); - PRINTMSG(",%.0f", (double)ld[1]); - if (flag_s) - PRINTMSG(",%.0f", (double)ld[13]); - PRINTMSG(",%.0f", (double)ld[2] * 1024); - if (ld[3] > 1e3) - PRINTMSG(",%.0f", (double)ld[3]); - else if (ld[3] > 1e0) - PRINTMSG(",%.1f", (double)ld[3]); - else - PRINTMSG(",%.3f", (double)ld[3]); - PRINTMSG(",%.0f", (double)ld[4]); - if (flag_s) - PRINTMSG(",%.0f", (double)ld[14]); - PRINTMSG(",%.0f", (double)ld[5] * 1024); - if (ld[6] > 1e3) - PRINTMSG(",%.0f", (double)ld[6]); - else if (ld[6] > 1e0) - PRINTMSG(",%.1f", (double)ld[6]); - else - PRINTMSG(",%.3f", (double)ld[6]); - - if (flag_d) { - PRINTMSG(",%.0f", (double)ld[8]); - if (flag_s) - PRINTMSG(",%.0f", - (double)ld[15]); - PRINTMSG(",%.0f", (double)ld[9] * 1024); - if (ld[10] > 1e3) - PRINTMSG(",%.0f", - (double)ld[10]); - else if (ld[10] > 1e0) - PRINTMSG(",%.1f", - (double)ld[10]); - else - PRINTMSG(",%.3f", - (double)ld[10]); - } - if (flag_o) { - PRINTMSG(",%.0f", (double)ld[11]); - if (ld[12] > 1e3) - PRINTMSG(",%.0f", - (double)ld[12]); - else if (ld[12] > 1e0) - PRINTMSG(",%.1f", - (double)ld[12]); - else - PRINTMSG(",%.3f", - (double)ld[12]); - } - PRINTMSG(",%.1lf", (double)ld[7]); + if (flag_C) { + printf("%s", ts); /* timestamp */ + printf(",%s", g_name); /* print name */ + printf(",%ju", (uintmax_t)queue_len); + printf(",%.0f", (double)xfer_per_sec); + print_kstat_csv(&krd, 0); + print_kstat_csv(&kwr, 0); + if (flag_d) + print_kstat_csv(&kfree, 0); + if (flag_o) + print_kstat_csv(&kother, 1); + printf(",%.1lf\n", (double)busy_pct); } else { - PRINTMSG(" %4ju", (uintmax_t)u64); - PRINTMSG(" %6.0f", (double)ld[0]); - PRINTMSG(" %6.0f", (double)ld[1]); - if (flag_s) - PRINTMSG(" %6.0f", (double)ld[13]); - PRINTMSG(" %6.0f", (double)ld[2] * 1024); - if (ld[3] > 1e3) - PRINTMSG(" %6.0f", (double)ld[3]); - else if (ld[3] > 1e0) - PRINTMSG(" %6.1f", (double)ld[3]); - else - PRINTMSG(" %6.3f", (double)ld[3]); - PRINTMSG(" %6.0f", (double)ld[4]); - if (flag_s) - PRINTMSG(" %6.0f", (double)ld[14]); - PRINTMSG(" %6.0f", (double)ld[5] * 1024); - if (ld[6] > 1e3) - PRINTMSG(" %6.0f", (double)ld[6]); - else if (ld[6] > 1e0) - PRINTMSG(" %6.1f", (double)ld[6]); - else - PRINTMSG(" %6.3f", (double)ld[6]); - - if (flag_d) { - PRINTMSG(" %6.0f", (double)ld[8]); - if (flag_s) - PRINTMSG(" %6.0f", - (double)ld[15]); - PRINTMSG(" %6.0f", - (double)ld[9] * 1024); - if (ld[10] > 1e3) - PRINTMSG(" %6.0f", - (double)ld[10]); - else if (ld[10] > 1e0) - PRINTMSG(" %6.1f", - (double)ld[10]); - else - PRINTMSG(" %6.3f", - (double)ld[10]); - } + printer(" %4ju", (uintmax_t)queue_len); + printer(" %6.0f", (double)xfer_per_sec); - if (flag_o) { - PRINTMSG(" %6.0f", (double)ld[11]); - if (ld[12] > 1e3) - PRINTMSG(" %6.0f", - (double)ld[12]); - else if (ld[12] > 1e0) - PRINTMSG(" %6.1f", - (double)ld[12]); + print_kstat_text(&krd, 0); + print_kstat_text(&kwr, 0); + if (flag_d) + print_kstat_text(&kfree, 0); + if (flag_o) + print_kstat_text(&kother, 1); + if (!flag_b) { + if (busy_pct > HIGH_PCT_BUSY_THRESH) + i = 3; + else if (busy_pct > MEDIUM_PCT_BUSY_THRESH) + i = 2; else - PRINTMSG(" %6.3f", - (double)ld[12]); + i = 1; + attron(COLOR_PAIR(i)); } - - if (ld[7] > HIGH_PCT_BUSY_THRESH) - i = 3; - else if (ld[7] > MEDIUM_PCT_BUSY_THRESH) - i = 2; - else - i = 1; + printer(" %6.1lf", (double)busy_pct); if (!flag_b) - attron(COLOR_PAIR(i)); - PRINTMSG(" %6.1lf", (double)ld[7]); - if (!flag_b) { attroff(COLOR_PAIR(i)); - PRINTMSG("|"); - } else - PRINTMSG(" "); - PRINTMSG(" %s", g_name); + + printer(" %s", g_name); if (!flag_b) clrtoeol(); + printer("\n"); } - PRINTMSG("\n"); - *gsq = *gsp; } geom_stats_snapshot_free(sp); - if (flag_b) { - /* We loop extra to make sure we get the information. */ - if (!loop) + if (flag_b || flag_C) { + if (!flag_B && !flag_C && loop == 2) break; - if (!flag_B) - loop = 0; - else - if (fflush(stdout) == EOF) - goto out; - usleep(flag_I); - continue; - } - getyx(stdscr, cury, curx); - getmaxyx(stdscr, maxy, maxx); - clrtobot(); - if (maxy - 1 <= cury) - move(maxy - 1, 0); - refresh(); - usleep(flag_I); - while((i = getch()) != ERR) { - switch (i) { - case '>': - flag_I *= 2; - break; - case '<': - flag_I /= 2; - if (flag_I < 1000) - flag_I = 1000; - break; - case 'c': - flag_c = !flag_c; - break; - case 'f': - move(0,0); - clrtoeol(); - refresh(); - line = el_gets(el, &line_len); - if (line == NULL) - err(1, "el_gets"); - if (line_len > 1) - history(hist, &hist_ev, H_ENTER, line); - strlcpy(tmp_f_s, line, sizeof(f_s)); - if ((p = strchr(tmp_f_s, '\n')) != NULL) - *p = '\0'; - /* - * Fix the terminal. We messed up - * curses idea of the screen by using - * libedit. - */ - clear(); - refresh(); - cbreak(); - noecho(); - nonl(); - if (regcomp(&tmp_f_re, tmp_f_s, REG_EXTENDED) - != 0) { - move(0, 0); - printw("Invalid filter"); - refresh(); - sleep(1); - } else { - strlcpy(f_s, tmp_f_s, sizeof(f_s)); - f_re = tmp_f_re; - } - break; - case 'F': - f_s[0] = '\0'; - break; - case 'q': - quit = 1; - break; - default: + if (fflush(stdout) == EOF) break; + usleep(flag_I); + } else { + getyx(stdscr, cury, curx); + getmaxyx(stdscr, maxy, maxx); + clrtobot(); + if (maxy - 1 <= cury) + move(maxy - 1, 0); + refresh(); + + int di = flag_I; + while (di > 0) { + int dii = di; + if (dii > 100000) + dii = 100000; + usleep(dii); + di -= dii; + if (poll_input()) + break; } } } -out: if (!flag_b) { el_end(el); endwin(); } exit(EX_OK); } - -static void *** 6 LINES SKIPPED ***home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a3fb3ec.3bd82.7e120966>
