diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 437f83c2a81e..00fc8af6f5a0 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -3440,6 +3440,8 @@ print_header(list_cbdata_t *cb) boolean_t first = B_TRUE; boolean_t right_justify; + color_start(ANSI_BOLD); + for (; pl != NULL; pl = pl->pl_next) { if (!first) { (void) printf(" "); @@ -3466,9 +3468,31 @@ print_header(list_cbdata_t *cb) (void) printf("%-*s", (int)pl->pl_width, header); } + color_end(); + (void) printf("\n"); } +/* + * Decides on the color that the avail value should be printed in. + * > 80% used = yellow + * > 90% used = red + */ +static const char * +zfs_list_avail_color(zfs_handle_t *zhp) +{ + uint64_t used = zfs_prop_get_int(zhp, ZFS_PROP_USED); + uint64_t avail = zfs_prop_get_int(zhp, ZFS_PROP_AVAILABLE); + int percentage = (int)((double)avail / MAX(avail + used, 1) * 100); + + if (percentage > 20) + return (NULL); + else if (percentage > 10) + return (ANSI_YELLOW); + else + return (ANSI_RED); +} + /* * Given a dataset and a list of fields, print out all the properties according * to the described layout. @@ -3531,6 +3555,9 @@ print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb) right_justify = B_FALSE; } + if (pl->pl_prop == ZFS_PROP_AVAILABLE) + color_start(zfs_list_avail_color(zhp)); + /* * If this is being called in scripted mode, or if this is the * last column and it is left-justified, don't include a width @@ -3542,6 +3569,9 @@ print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb) (void) printf("%*s", (int)pl->pl_width, propstr); else (void) printf("%-*s", (int)pl->pl_width, propstr); + + if (pl->pl_prop == ZFS_PROP_AVAILABLE) + color_end(); } (void) putchar('\n'); diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index d2614411df3f..ad377228298c 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -4220,6 +4220,8 @@ print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width, unsigned int namewidth; const char *title; + color_start(ANSI_BOLD); + if (cb->cb_flags & IOS_ANYHISTO_M) { title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]; } else if (cb->cb_vdevs.cb_names_count) { @@ -4253,6 +4255,8 @@ print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width, if (cb->vcdl != NULL) print_cmd_columns(cb->vcdl, 1); + color_end(); + printf("\n"); } @@ -4262,6 +4266,35 @@ print_iostat_header(iostat_cbdata_t *cb) print_iostat_header_impl(cb, 0, NULL); } +/* + * Prints a size string (i.e. 120M) with the suffix ("M") colored + * by order of magnitude. Uses column_size to add padding. + */ +static void +print_stat_color(char *statbuf, unsigned int column_size) +{ + fputs(" ", stdout); + if (*statbuf == '0') { + color_start(ANSI_GRAY); + fputc('0', stdout); + column_size--; + } else { + for (; *statbuf; statbuf++) { + if (*statbuf == 'K') color_start(ANSI_GREEN); + else if (*statbuf == 'M') color_start(ANSI_YELLOW); + else if (*statbuf == 'G') color_start(ANSI_RED); + else if (*statbuf == 'T') color_start(ANSI_BOLD_BLUE); + else if (*statbuf == 'P') color_start(ANSI_MAGENTA); + else if (*statbuf == 'E') color_start(ANSI_CYAN); + fputc(*statbuf, stdout); + if (--column_size <= 0) + break; + } + } + color_end(); + for (; column_size > 0; column_size--) + fputc(' ', stdout); +} /* * Display a single statistic. @@ -4277,7 +4310,7 @@ print_one_stat(uint64_t value, enum zfs_nicenum_format format, if (scripted) printf("\t%s", buf); else - printf(" %*s", column_size, buf); + print_stat_color(buf, column_size); } /* diff --git a/include/libzutil.h b/include/libzutil.h index 948ac08cd772..465e463f0c1f 100644 --- a/include/libzutil.h +++ b/include/libzutil.h @@ -169,10 +169,16 @@ struct zfs_cmd; /* * List of colors to use */ +#define ANSI_BLACK "\033[0;30m" #define ANSI_RED "\033[0;31m" #define ANSI_GREEN "\033[0;32m" #define ANSI_YELLOW "\033[0;33m" #define ANSI_BLUE "\033[0;34m" +#define ANSI_BOLD_BLUE "\033[1;34m" /* light blue */ +#define ANSI_MAGENTA "\033[0;35m" +#define ANSI_CYAN "\033[0;36m" +#define ANSI_GRAY "\033[0;37m" + #define ANSI_RESET "\033[0m" #define ANSI_BOLD "\033[1m" diff --git a/lib/libzfs/libzfs_diff.c b/lib/libzfs/libzfs_diff.c index 1330e7c3052a..da2b26ef99ce 100644 --- a/lib/libzfs/libzfs_diff.c +++ b/lib/libzfs/libzfs_diff.c @@ -55,10 +55,10 @@ #define ZDIFF_REMOVED '-' #define ZDIFF_RENAMED "R" -#define ZDIFF_ADDED_COLOR ANSI_GREEN +#define ZDIFF_ADDED_COLOR ANSI_GREEN #define ZDIFF_MODIFIED_COLOR ANSI_YELLOW -#define ZDIFF_REMOVED_COLOR ANSI_RED -#define ZDIFF_RENAMED_COLOR ANSI_BLUE +#define ZDIFF_REMOVED_COLOR ANSI_RED +#define ZDIFF_RENAMED_COLOR ANSI_BOLD_BLUE /* * Given a {dsname, object id}, get the object path diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index 2507bfecdc9b..ad5343a080c3 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -2011,10 +2011,11 @@ use_color(void) } /* - * color_start() and color_end() are used for when you want to colorize a block - * of text. For example: + * The functions color_start() and color_end() are used for when you want + * to colorize a block of text. * - * color_start(ANSI_RED_FG) + * For example: + * color_start(ANSI_RED) * printf("hello"); * printf("world"); * color_end(); @@ -2022,7 +2023,7 @@ use_color(void) void color_start(const char *color) { - if (use_color()) { + if (color && use_color()) { fputs(color, stdout); fflush(stdout); } @@ -2038,7 +2039,9 @@ color_end(void) } -/* printf() with a color. If color is NULL, then do a normal printf. */ +/* + * printf() with a color. If color is NULL, then do a normal printf. + */ int printf_color(const char *color, const char *format, ...) { diff --git a/man/man8/zfs.8 b/man/man8/zfs.8 index d12377f9b4f2..dd578cb74aac 100644 --- a/man/man8/zfs.8 +++ b/man/man8/zfs.8 @@ -740,6 +740,8 @@ command will be undone if the share is ever unshared (like via a reboot). .It Sy ZFS_COLOR Use ANSI color in .Nm zfs Cm diff +and +.Nm zfs Cm list output. .It Sy ZFS_MOUNT_HELPER Cause diff --git a/man/man8/zpool.8 b/man/man8/zpool.8 index 48e4eb3c557b..e8eadffa6fcf 100644 --- a/man/man8/zpool.8 +++ b/man/man8/zpool.8 @@ -445,6 +445,8 @@ to dump core on exit for the purposes of running .It Sy ZFS_COLOR Use ANSI color in .Nm zpool Cm status +and +.Nm zpool Cm iostat output. .It Sy ZPOOL_IMPORT_PATH The search path for devices or files to use with the pool.