The branch main has been updated by phk:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c263dd413ca0b43b4513e6e6dd8ed64c0eb9c3aa

commit c263dd413ca0b43b4513e6e6dd8ed64c0eb9c3aa
Author:     Poul-Henning Kamp <[email protected]>
AuthorDate: 2026-06-27 11:26:18 +0000
Commit:     Poul-Henning Kamp <[email protected]>
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 ***

Reply via email to