]> git.proxmox.com Git - mirror_zfs.git/commitdiff
zpool iostat should print headers when terminal fills
authorDamian Wojsław <damian@wojslaw.pl>
Wed, 23 Jan 2019 21:29:49 +0000 (22:29 +0100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 23 Jan 2019 21:29:49 +0000 (13:29 -0800)
When `zpool iostat` fills the terminal the headers should be
printed again.  `zpool iostat -n` can be used to suppress this.

If the command is not attached to a tty, headers will not be
printed so as to not break existing scripts.

Reviewed-by: Joshua M. Clulow <josh@sysmgr.org>
Reviewed-by: Giuseppe Di Natale <guss80@gmail.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Damian Wojsław <damian@wojslaw.pl>
Closes #8235
Closes #8262

cmd/zpool/zpool_main.c
man/man8/zpool.8

index b96aaf3b7dcf4cd5c4be751d15a8aa5965b10f7a..733af559b88cac91fa3ff0985b57f1fd58e0593d 100644 (file)
@@ -345,7 +345,7 @@ get_usage(zpool_help_t idx)
                return (gettext("\tiostat [[[-c [script1,script2,...]"
                    "[-lq]]|[-rw]] [-T d | u] [-ghHLpPvy]\n"
                    "\t    [[pool ...]|[pool vdev ...]|[vdev ...]]"
-                   " [interval [count]]\n"));
+                   " [[-n] interval [count]]\n"));
        case HELP_LABELCLEAR:
                return (gettext("\tlabelclear [-f] <vdev>\n"));
        case HELP_LIST:
@@ -4917,6 +4917,7 @@ get_namewidth_iostat(zpool_handle_t *zhp, void *data)
  *     -w      Display latency histograms
  *     -r      Display request size histogram
  *     -T      Display a timestamp in date(1) or Unix format
+ *     -n      Only print headers once
  *
  * This command can be tricky because we want to be able to deal with pool
  * creation/destruction as well as vdev configuration changes.  The bulk of this
@@ -4932,6 +4933,8 @@ zpool_do_iostat(int argc, char **argv)
        int npools;
        float interval = 0;
        unsigned long count = 0;
+       struct winsize win;
+       int winheight = 24;
        zpool_list_t *list;
        boolean_t verbose = B_FALSE;
        boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE;
@@ -4940,6 +4943,7 @@ zpool_do_iostat(int argc, char **argv)
        boolean_t guid = B_FALSE;
        boolean_t follow_links = B_FALSE;
        boolean_t full_name = B_FALSE;
+       boolean_t headers_once = B_FALSE;
        iostat_cbdata_t cb = { 0 };
        char *cmd = NULL;
 
@@ -4950,7 +4954,7 @@ zpool_do_iostat(int argc, char **argv)
        uint64_t unsupported_flags;
 
        /* check options */
-       while ((c = getopt(argc, argv, "c:gLPT:vyhplqrwH")) != -1) {
+       while ((c = getopt(argc, argv, "c:gLPT:vyhplqrwnH")) != -1) {
                switch (c) {
                case 'c':
                        if (cmd != NULL) {
@@ -5013,6 +5017,9 @@ zpool_do_iostat(int argc, char **argv)
                case 'y':
                        omit_since_boot = B_TRUE;
                        break;
+               case 'n':
+                       headers_once = B_TRUE;
+                       break;
                case 'h':
                        usage(B_FALSE);
                        break;
@@ -5214,6 +5221,26 @@ zpool_do_iostat(int argc, char **argv)
                                cb.vcdl = NULL;
                        }
 
+                       /*
+                        * Are we connected to TTY? If not, headers_once
+                        * should be true, to avoid breaking scripts.
+                        */
+                       if (isatty(fileno(stdout)) == 0)
+                               headers_once = B_TRUE;
+
+                       /*
+                        * Check terminal size so we can print headers
+                        * even when terminal window has its height
+                        * changed.
+                        */
+                       if (headers_once == B_FALSE) {
+                               if (ioctl(1, TIOCGWINSZ, &win) != -1 &&
+                                   win.ws_row > 0)
+                                       winheight = win.ws_row;
+                               else
+                                       headers_once = B_TRUE;
+                       }
+
                        /*
                         * If it's the first time and we're not skipping it,
                         * or either skip or verbose mode, print the header.
@@ -5222,7 +5249,9 @@ zpool_do_iostat(int argc, char **argv)
                         * every vdev, so skip this for histograms.
                         */
                        if (((++cb.cb_iteration == 1 && !skip) ||
-                           (skip != verbose)) &&
+                           (skip != verbose) ||
+                           (!headers_once &&
+                           (cb.cb_iteration % winheight) == 0)) &&
                            (!(cb.cb_flags & IOS_ANYHISTO_M)) &&
                            !cb.cb_scripted)
                                print_iostat_header(&cb);
@@ -5232,7 +5261,6 @@ zpool_do_iostat(int argc, char **argv)
                                continue;
                        }
 
-
                        pool_list_iter(list, B_FALSE, print_iostat, &cb);
 
                        /*
index 8f35ca0ee7ce03bc6de2cedcd1c38095da260d0e..28517e4757695a751e6cf6e102a523b5af2b57ed 100644 (file)
 .Cm iostat
 .Op Oo Oo Fl c Ar SCRIPT Oc Oo Fl lq Oc Oc Ns | Ns Fl rw
 .Op Fl T Sy u Ns | Ns Sy d
-.Op Fl ghHLpPvy
+.Op Fl ghHLnpPvy
 .Oo Oo Ar pool Ns ... Oc Ns | Ns Oo Ar pool vdev Ns ... Oc Ns | Ns Oo Ar vdev Ns ... Oc Oc
 .Op Ar interval Op Ar count
 .Nm
@@ -1631,7 +1631,7 @@ with no flags on the relevant target devices.
 .Cm iostat
 .Op Oo Oo Fl c Ar SCRIPT Oc Oo Fl lq Oc Oc Ns | Ns Fl rw
 .Op Fl T Sy u Ns | Ns Sy d
-.Op Fl ghHLpPvy
+.Op Fl ghHLnpPvy
 .Oo Oo Ar pool Ns ... Oc Ns | Ns Oo Ar pool vdev Ns ... Oc Ns | Ns Oo Ar vdev Ns ... Oc Oc
 .Op Ar interval Op Ar count
 .Xc
@@ -1643,7 +1643,10 @@ When given an
 .Ar interval ,
 the statistics are printed every
 .Ar interval
-seconds until ^C is pressed. If count is specified, the command exits
+seconds until ^C is pressed. If 
+.Fl n
+flag is specified the headers are displayed only once, otherwise they are 
+displayed periodically. If count is specified, the command exits
 after count reports are printed. The first report printed is always
 the statistics since boot regardless of whether
 .Ar interval
@@ -1735,6 +1738,8 @@ Display real paths for vdevs resolving all symbolic links. This can
 be used to look up the current block device name regardless of the
 .Pa /dev/disk/
 path used to open it.
+.It Fl n
+Print headers only once when passed
 .It Fl p
 Display numbers in parsable (exact) values. Time values are in
 nanoseconds.
@@ -1760,6 +1765,7 @@ pool, in addition to the pool-wide statistics.
 Omit statistics since boot.
 Normally the first line of output reports the statistics since boot.
 This option suppresses that first line of output.
+.Ar interval
 .It Fl w
 Display latency histograms:
 .Pp