From 8fccfa8e17d30b4dae82f0cd33346f39b79f4822 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Damian=20Wojs=C5=82aw?= Date: Wed, 23 Jan 2019 22:29:49 +0100 Subject: [PATCH] zpool iostat should print headers when terminal fills MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Giuseppe Di Natale Reviewed-by: George Melikov Reviewed-by: Brian Behlendorf Reviewed-by: Tony Hutter Signed-off-by: Damian Wojsław Closes #8235 Closes #8262 --- cmd/zpool/zpool_main.c | 36 ++++++++++++++++++++++++++++++++---- man/man8/zpool.8 | 12 +++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index b96aaf3b7..733af559b 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -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] \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); /* diff --git a/man/man8/zpool.8 b/man/man8/zpool.8 index 8f35ca0ee..28517e475 100644 --- a/man/man8/zpool.8 +++ b/man/man8/zpool.8 @@ -123,7 +123,7 @@ .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 -- 2.39.5