Skip to content

Commit

Permalink
Fix 'zpool list -v' alignment
Browse files Browse the repository at this point in the history
The verbose output of 'zpool list' was not correctly aligned due
to differences in the vdev name lengths.  Minimally update the
code the correct the alignment using the same strategy employed
by 'zpool status'.

Missing dashes were added for the empty defaults columns, and
the vdev state is now printed for all vdevs.

The ALTROOT properly was removed from the default output to get
close to staying within an 80 character width.  At least for
short vdev names.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
  • Loading branch information
behlendorf committed Nov 21, 2018
1 parent 8005ca4 commit f7b518c
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 54 deletions.
159 changes: 106 additions & 53 deletions cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4266,34 +4266,25 @@ get_columns(void)
return (columns);
}

int
get_namewidth(zpool_handle_t *zhp, void *data)
static int
get_namewidth(zpool_handle_t *zhp, int *width, int flags, boolean_t verbose)
{
iostat_cbdata_t *cb = data;
nvlist_t *config, *nvroot;
int columns;
int tmp_width = *width;

if ((config = zpool_get_config(zhp, NULL)) != NULL) {
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
unsigned int poolname_len = strlen(zpool_get_name(zhp));
if (!cb->cb_verbose)
cb->cb_namewidth = MAX(poolname_len, cb->cb_namewidth);
else
cb->cb_namewidth = MAX(poolname_len,
max_width(zhp, nvroot, 0, cb->cb_namewidth,
cb->cb_name_flags));
if (verbose == B_FALSE) {
tmp_width = MAX(poolname_len, tmp_width);
} else {
tmp_width = MAX(poolname_len,
max_width(zhp, nvroot, 0, tmp_width, flags));
}
}
/*
* The width must be at least 10, but may be as large as the
* column width - 42 so that we can still fit in one line.
*/
columns = get_columns();

if (cb->cb_namewidth < 10)
cb->cb_namewidth = 10;
if (cb->cb_namewidth > columns - 42)
cb->cb_namewidth = columns - 42;
*width = tmp_width;

return (0);
}
Expand Down Expand Up @@ -4712,6 +4703,32 @@ print_zpool_script_list(char *subcommand)
free(sp);
}

static int
get_namewidth_iostat(zpool_handle_t *zhp, void *data)
{
iostat_cbdata_t *cb = data;
int error, width = cb->cb_namewidth;

error = get_namewidth(zhp, &width, cb->cb_name_flags, cb->cb_verbose);
if (error)
return (error);

/*
* The width must be at least 10, but may be as large as the
* column width - 42 so that we can still fit in one line.
*/
int columns = get_columns();

if (width < 10)
width = 10;
if (width > columns - 42)
width = columns - 42;

cb->cb_namewidth = width;

return (0);
}

/*
* zpool iostat [[-c [script1,script2,...]] [-lq]|[-rw]] [-ghHLpPvy] [-n name]
* [-T d|u] [[ pool ...]|[pool vdev ...]|[vdev ...]]
Expand Down Expand Up @@ -5013,8 +5030,8 @@ zpool_do_iostat(int argc, char **argv)
* for the pool / device name column across all pools.
*/
cb.cb_namewidth = 0;
(void) pool_list_iter(list, B_FALSE, get_namewidth,
&cb);
(void) pool_list_iter(list, B_FALSE,
get_namewidth_iostat, &cb);

if (timestamp_fmt != NODATE)
print_timestamp(timestamp_fmt);
Expand Down Expand Up @@ -5225,8 +5242,8 @@ print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
}

static void
print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
boolean_t valid, enum zfs_nicenum_format format)
print_one_column(zpool_prop_t prop, uint64_t value, const char *str,
boolean_t scripted, boolean_t valid, enum zfs_nicenum_format format)
{
char propval[64];
boolean_t fixed;
Expand All @@ -5235,6 +5252,7 @@ print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
switch (prop) {
case ZPOOL_PROP_EXPANDSZ:
case ZPOOL_PROP_CHECKPOINT:
case ZPOOL_PROP_DEDUPRATIO:
if (value == 0)
(void) strlcpy(propval, "-", sizeof (propval));
else
Expand Down Expand Up @@ -5262,6 +5280,10 @@ print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
value < 1000 ? "%1.2f%%" : value < 10000 ?
"%2.1f%%" : "%3.0f%%", value / 100.0);
break;
case ZPOOL_PROP_HEALTH:
strlcpy(propval, str, sizeof (propval));
width = strlen(propval);
break;
default:
zfs_nicenum_format(value, propval, sizeof (propval), format);
}
Expand All @@ -5281,15 +5303,16 @@ print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
*/
void
print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
list_cbdata_t *cb, int depth)
list_cbdata_t *cb, int depth, boolean_t isspare)
{
nvlist_t **child;
vdev_stat_t *vs;
uint_t c, children;
char *vname;
boolean_t scripted = cb->cb_scripted;
uint64_t islog = B_FALSE;
char *dashes = "%-*s - - - - - -\n";
char *dashes = "%-*s - - - - "
"- - - - -\n";

verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
(uint64_t **)&vs, &c) == 0);
Expand All @@ -5298,6 +5321,7 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
boolean_t toplevel = (vs->vs_space != 0);
uint64_t cap;
enum zfs_nicenum_format format;
const char *state;

if (cb->cb_literal)
format = ZFS_NICENUM_RAW;
Expand All @@ -5321,24 +5345,35 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
* 'toplevel' boolean value is passed to the print_one_column()
* to indicate that the value is valid.
*/
print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted,
print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, NULL, scripted,
toplevel, format);
print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted,
toplevel, format);
print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL,
scripted, toplevel, format);
print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
NULL, scripted, toplevel, format);
print_one_column(ZPOOL_PROP_CHECKPOINT,
vs->vs_checkpoint_space, scripted, toplevel, format);
print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted,
B_TRUE, format);
vs->vs_checkpoint_space, NULL, scripted, toplevel, format);
print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, NULL,
scripted, B_TRUE, format);
print_one_column(ZPOOL_PROP_FRAGMENTATION,
vs->vs_fragmentation, scripted,
vs->vs_fragmentation, NULL, scripted,
(vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel),
format);
cap = (vs->vs_space == 0) ? 0 :
(vs->vs_alloc * 10000 / vs->vs_space);
print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel,
format);
print_one_column(ZPOOL_PROP_CAPACITY, cap, NULL,
scripted, toplevel, format);
print_one_column(ZPOOL_PROP_DEDUPRATIO, 0, NULL,
scripted, toplevel, format);
state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
if (isspare) {
if (vs->vs_aux == VDEV_AUX_SPARED)
state = "INUSE";
else if (vs->vs_state == VDEV_STATE_HEALTHY)
state = "AVAIL";
}
print_one_column(ZPOOL_PROP_HEALTH, 0, state, scripted,
1, format);
(void) printf("\n");
}

Expand All @@ -5363,7 +5398,7 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,

vname = zpool_vdev_name(g_zfs, zhp, child[c],
cb->cb_name_flags);
print_list_stats(zhp, vname, child[c], cb, depth + 2);
print_list_stats(zhp, vname, child[c], cb, depth + 2, B_FALSE);
free(vname);
}

Expand Down Expand Up @@ -5397,7 +5432,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
}
vname = zpool_vdev_name(g_zfs, zhp, child[c],
cb->cb_name_flags);
print_list_stats(zhp, vname, child[c], cb, depth + 2);
print_list_stats(zhp, vname, child[c], cb, depth + 2,
B_FALSE);
free(vname);
}
}
Expand All @@ -5409,7 +5445,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
for (c = 0; c < children; c++) {
vname = zpool_vdev_name(g_zfs, zhp, child[c],
cb->cb_name_flags);
print_list_stats(zhp, vname, child[c], cb, depth + 2);
print_list_stats(zhp, vname, child[c], cb, depth + 2,
B_FALSE);
free(vname);
}
}
Expand All @@ -5421,7 +5458,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
for (c = 0; c < children; c++) {
vname = zpool_vdev_name(g_zfs, zhp, child[c],
cb->cb_name_flags);
print_list_stats(zhp, vname, child[c], cb, depth + 2);
print_list_stats(zhp, vname, child[c], cb, depth + 2,
B_TRUE);
free(vname);
}
}
Expand All @@ -5434,26 +5472,38 @@ int
list_callback(zpool_handle_t *zhp, void *data)
{
list_cbdata_t *cbp = data;
nvlist_t *config;
nvlist_t *nvroot;

config = zpool_get_config(zhp, NULL);
print_pool(zhp, cbp);

if (cbp->cb_verbose) {
config = zpool_get_config(zhp, NULL);
nvlist_t *config, *nvroot;

config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
print_list_stats(zhp, NULL, nvroot, cbp, 0, B_FALSE);
}

if (cbp->cb_verbose)
cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0,
cbp->cb_name_flags);
return (0);
}

print_pool(zhp, cbp);
static int
get_namewidth_list(zpool_handle_t *zhp, void *data)
{
list_cbdata_t *cb = data;
int error, width = cb->cb_namewidth;

if (cbp->cb_verbose)
print_list_stats(zhp, NULL, nvroot, cbp, 0);
error = get_namewidth(zhp, &width, cb->cb_name_flags, cb->cb_verbose);
if (error)
return (error);

/*
* The width must be at least 9, but may be as large as needed.
*/
if (width < 9)
width = 9;

cb->cb_namewidth = width;

return (0);
}
Expand All @@ -5466,9 +5516,9 @@ list_callback(zpool_handle_t *zhp, void *data)
* by a single tab.
* -L Follow links when resolving vdev path name.
* -o List of properties to display. Defaults to
* "name,size,allocated,free,expandsize,fragmentation,capacity,"
* "dedupratio,health,altroot"
* -p Display values in parsable (exact) format.
* "name,size,allocated,free,fragmentation,capacity,"
* "dedupratio,health"
* -p Display values in parsable (exact) format.
* -P Display full path for vdev name.
* -T Display a timestamp in date(1) or Unix format
*
Expand All @@ -5483,7 +5533,7 @@ zpool_do_list(int argc, char **argv)
list_cbdata_t cb = { 0 };
static char default_props[] =
"name,size,allocated,free,checkpoint,expandsize,fragmentation,"
"capacity,dedupratio,health,altroot";
"capacity,dedupratio,health";
char *props = default_props;
float interval = 0;
unsigned long count = 0;
Expand Down Expand Up @@ -5546,6 +5596,9 @@ zpool_do_list(int argc, char **argv)
if (pool_list_count(list) == 0)
break;

cb.cb_namewidth = 0;
(void) pool_list_iter(list, B_FALSE, get_namewidth_list, &cb);

if (timestamp_fmt != NODATE)
print_timestamp(timestamp_fmt);

Expand Down
2 changes: 1 addition & 1 deletion man/man8/zpool.8
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ See the
section for a list of valid properties.
The default list is
.Cm name , size , allocated , free , checkpoint, expandsize , fragmentation ,
.Cm capacity , dedupratio , health , altroot .
.Cm capacity , dedupratio , health .
.It Fl L
Display real paths for vdevs resolving all symbolic links. This can
be used to look up the current block device name regardless of the
Expand Down

0 comments on commit f7b518c

Please sign in to comment.