Add -gLp to zpool subcommands for alt vdev names

The following options have been added to the zpool add, iostat,
list, status, and split subcommands.  The default behavior was
not modified, from zfs(8).

  -g    Display vdev GUIDs  instead  of  the  normal  short
        device  names.  These GUIDs can be used in-place of
        device   names   for    the    zpool    detach/off‐
        line/remove/replace commands.

  -L    Display real paths for vdevs resolving all symbolic
        links. This can be used to lookup the current block
        device  name regardless of the /dev/disk/ path used
        to open it.

  -p    Display  full  paths  for vdevs instead of only the
        last component of the path.  This can  be  used  in
        conjunction with the -L flag.

This behavior may also be enabled using the following environment
variables.

  ZPOOL_VDEV_NAME_GUID
  ZPOOL_VDEV_NAME_FOLLOW_LINKS
  ZPOOL_VDEV_NAME_PATH

This change is based on worked originally started by Richard Yao
to add a -g option.  Then extended by @ilovezfs to add a -L option
for openzfsonosx.  Those changes have been merged, re-factored,
a -p option added and extended to all relevant zpool subcommands.

Original-patch-by: Richard Yao <ryao@gentoo.org>
Extended-by: ilovezfs <ilovezfs@icloud.com>
Extended-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: ilovezfs <ilovezfs@icloud.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2011
Closes #4341
This commit is contained in:
Richard Yao
2013-12-29 13:40:46 -05:00
committed by Brian Behlendorf
parent e79a6bacc6
commit d2f3e292dc
4 changed files with 407 additions and 104 deletions
+169 -73
View File
@@ -207,7 +207,7 @@ static const char *
get_usage(zpool_help_t idx) {
switch (idx) {
case HELP_ADD:
return (gettext("\tadd [-fn] [-o property=value] "
return (gettext("\tadd [-fgLnp] [-o property=value] "
"<pool> <vdev> ...\n"));
case HELP_ATTACH:
return (gettext("\tattach [-f] [-o property=value] "
@@ -237,12 +237,12 @@ get_usage(zpool_help_t idx) {
"[-R root] [-F [-n]]\n"
"\t <pool | id> [newpool]\n"));
case HELP_IOSTAT:
return (gettext("\tiostat [-v] [-T d|u] [-y] [pool] ... "
return (gettext("\tiostat [-gLpvy] [-T d|u] [pool] ... "
"[interval [count]]\n"));
case HELP_LABELCLEAR:
return (gettext("\tlabelclear [-f] <vdev>\n"));
case HELP_LIST:
return (gettext("\tlist [-Hv] [-o property[,...]] "
return (gettext("\tlist [-gHLpv] [-o property[,...]] "
"[-T d|u] [pool] ... [interval [count]]\n"));
case HELP_OFFLINE:
return (gettext("\toffline [-t] <pool> <device> ...\n"));
@@ -258,8 +258,8 @@ get_usage(zpool_help_t idx) {
case HELP_SCRUB:
return (gettext("\tscrub [-s] <pool> ...\n"));
case HELP_STATUS:
return (gettext("\tstatus [-vxD] [-T d|u] [pool] ... [interval "
"[count]]\n"));
return (gettext("\tstatus [-gLpvxD] [-T d|u] [pool] ... "
"[interval [count]]\n"));
case HELP_UPGRADE:
return (gettext("\tupgrade\n"
"\tupgrade -v\n"
@@ -272,7 +272,7 @@ get_usage(zpool_help_t idx) {
case HELP_SET:
return (gettext("\tset <property=value> <pool> \n"));
case HELP_SPLIT:
return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
return (gettext("\tsplit [-gLnp] [-R altroot] [-o mntopts]\n"
"\t [-o property=value] <pool> <newpool> "
"[<device> ...]\n"));
case HELP_REGUID:
@@ -371,7 +371,7 @@ usage(boolean_t requested)
void
print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
boolean_t print_logs)
boolean_t print_logs, int name_flags)
{
nvlist_t **child;
uint_t c, children;
@@ -392,9 +392,9 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
if ((is_log && !print_logs) || (!is_log && print_logs))
continue;
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags);
print_vdev_tree(zhp, vname, child[c], indent + 2,
B_FALSE);
B_FALSE, name_flags);
free(vname);
}
}
@@ -502,12 +502,15 @@ add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
}
/*
* zpool add [-fn] [-o property=value] <pool> <vdev> ...
* zpool add [-fgLnp] [-o property=value] <pool> <vdev> ...
*
* -f Force addition of devices, even if they appear in use
* -g Display guid for individual vdev name.
* -L Follow links when resolving vdev path name.
* -n Do not add the devices, but display the resulting layout if
* they were to be added.
* -o Set property=value.
* -p Display full path for vdev name.
*
* Adds the given vdevs to 'pool'. As with create, the bulk of this work is
* handled by get_vdev_spec(), which constructs the nvlist needed to pass to
@@ -518,6 +521,7 @@ zpool_do_add(int argc, char **argv)
{
boolean_t force = B_FALSE;
boolean_t dryrun = B_FALSE;
int name_flags = 0;
int c;
nvlist_t *nvroot;
char *poolname;
@@ -528,11 +532,17 @@ zpool_do_add(int argc, char **argv)
char *propval;
/* check options */
while ((c = getopt(argc, argv, "fno:")) != -1) {
while ((c = getopt(argc, argv, "fgLno:p")) != -1) {
switch (c) {
case 'f':
force = B_TRUE;
break;
case 'g':
name_flags |= VDEV_NAME_GUID;
break;
case 'L':
name_flags |= VDEV_NAME_FOLLOW_LINKS;
break;
case 'n':
dryrun = B_TRUE;
break;
@@ -549,6 +559,9 @@ zpool_do_add(int argc, char **argv)
(add_prop_list(optarg, propval, &props, B_TRUE)))
usage(B_FALSE);
break;
case 'p':
name_flags |= VDEV_NAME_PATH;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
@@ -606,15 +619,19 @@ zpool_do_add(int argc, char **argv)
"configuration:\n"), zpool_get_name(zhp));
/* print original main pool and new tree */
print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE,
name_flags);
print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE, name_flags);
/* Do the same for the logs */
if (num_logs(poolnvroot) > 0) {
print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE,
name_flags);
print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE,
name_flags);
} else if (num_logs(nvroot) > 0) {
print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE,
name_flags);
}
/* Do the same for the caches */
@@ -624,7 +641,7 @@ zpool_do_add(int argc, char **argv)
(void) printf(gettext("\tcache\n"));
for (c = 0; c < l2children; c++) {
vname = zpool_vdev_name(g_zfs, NULL,
l2child[c], B_FALSE);
l2child[c], name_flags);
(void) printf("\t %s\n", vname);
free(vname);
}
@@ -635,7 +652,7 @@ zpool_do_add(int argc, char **argv)
(void) printf(gettext("\tcache\n"));
for (c = 0; c < l2children; c++) {
vname = zpool_vdev_name(g_zfs, NULL,
l2child[c], B_FALSE);
l2child[c], name_flags);
(void) printf("\t %s\n", vname);
free(vname);
}
@@ -1082,9 +1099,9 @@ zpool_do_create(int argc, char **argv)
(void) printf(gettext("would create '%s' with the "
"following layout:\n\n"), poolname);
print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE, 0);
if (num_logs(nvroot) > 0)
print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE, 0);
ret = 0;
} else {
@@ -1311,13 +1328,15 @@ zpool_do_export(int argc, char **argv)
* name column.
*/
static int
max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max,
int name_flags)
{
char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE);
char *name;
nvlist_t **child;
uint_t c, children;
int ret;
name = zpool_vdev_name(g_zfs, zhp, nv, name_flags | VDEV_NAME_TYPE_ID);
if (strlen(name) + depth > max)
max = strlen(name) + depth;
@@ -1327,7 +1346,7 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
&child, &children) == 0) {
for (c = 0; c < children; c++)
if ((ret = max_width(zhp, child[c], depth + 2,
max)) > max)
max, name_flags)) > max)
max = ret;
}
@@ -1335,7 +1354,7 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
&child, &children) == 0) {
for (c = 0; c < children; c++)
if ((ret = max_width(zhp, child[c], depth + 2,
max)) > max)
max, name_flags)) > max)
max = ret;
}
@@ -1343,11 +1362,10 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
&child, &children) == 0) {
for (c = 0; c < children; c++)
if ((ret = max_width(zhp, child[c], depth + 2,
max)) > max)
max, name_flags)) > max)
max = ret;
}
return (max);
}
@@ -1399,9 +1417,9 @@ find_spare(zpool_handle_t *zhp, void *data)
/*
* Print out configuration state as requested by status_callback.
*/
void
static void
print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
int namewidth, int depth, boolean_t isspare)
int namewidth, int depth, boolean_t isspare, int name_flags)
{
nvlist_t **child;
uint_t c, children;
@@ -1537,20 +1555,21 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
&ishole);
if (islog || ishole)
continue;
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
vname = zpool_vdev_name(g_zfs, zhp, child[c],
name_flags | VDEV_NAME_TYPE_ID);
print_status_config(zhp, vname, child[c],
namewidth, depth + 2, isspare);
namewidth, depth + 2, isspare, name_flags);
free(vname);
}
}
/*
* Print the configuration of an exported pool. Iterate over all vdevs in the
* pool, printing out the name and status for each one.
*/
void
print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
static void
print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
int name_flags)
{
nvlist_t **child;
uint_t c, children;
@@ -1615,8 +1634,10 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
if (is_log)
continue;
vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
print_import_config(vname, child[c], namewidth, depth + 2);
vname = zpool_vdev_name(g_zfs, NULL, child[c],
name_flags | VDEV_NAME_TYPE_ID);
print_import_config(vname, child[c], namewidth, depth + 2,
name_flags);
free(vname);
}
@@ -1624,7 +1645,8 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
&child, &children) == 0) {
(void) printf(gettext("\tcache\n"));
for (c = 0; c < children; c++) {
vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
vname = zpool_vdev_name(g_zfs, NULL, child[c],
name_flags);
(void) printf("\t %s\n", vname);
free(vname);
}
@@ -1634,7 +1656,8 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
&child, &children) == 0) {
(void) printf(gettext("\tspares\n"));
for (c = 0; c < children; c++) {
vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
vname = zpool_vdev_name(g_zfs, NULL, child[c],
name_flags);
(void) printf("\t %s\n", vname);
free(vname);
}
@@ -1650,7 +1673,8 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
* works because only the top level vdev is marked "is_log"
*/
static void
print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose,
int name_flags)
{
uint_t c, children;
nvlist_t **child;
@@ -1669,12 +1693,14 @@ print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
&is_log);
if (!is_log)
continue;
name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
name = zpool_vdev_name(g_zfs, zhp, child[c],
name_flags | VDEV_NAME_TYPE_ID);
if (verbose)
print_status_config(zhp, name, child[c], namewidth,
2, B_FALSE);
2, B_FALSE, name_flags);
else
print_import_config(name, child[c], namewidth, 2);
print_import_config(name, child[c], namewidth, 2,
name_flags);
free(name);
}
}
@@ -1923,13 +1949,13 @@ show_import(nvlist_t *config)
(void) printf(gettext(" config:\n\n"));
namewidth = max_width(NULL, nvroot, 0, 0);
namewidth = max_width(NULL, nvroot, 0, 0, 0);
if (namewidth < 10)
namewidth = 10;
print_import_config(name, nvroot, namewidth, 0);
print_import_config(name, nvroot, namewidth, 0, 0);
if (num_logs(nvroot) > 0)
print_logs(NULL, nvroot, namewidth, B_FALSE);
print_logs(NULL, nvroot, namewidth, B_FALSE, 0);
if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
(void) printf(gettext("\n\tAdditional devices are known to "
@@ -2438,6 +2464,7 @@ error:
typedef struct iostat_cbdata {
boolean_t cb_verbose;
int cb_name_flags;
int cb_namewidth;
int cb_iteration;
zpool_list_t *cb_list;
@@ -2560,7 +2587,8 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
if (ishole || islog)
continue;
vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
cb->cb_name_flags);
print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
newchild[c], cb, depth + 2);
free(vname);
@@ -2581,7 +2609,7 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
if (islog) {
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
B_FALSE);
cb->cb_name_flags);
print_vdev_stats(zhp, vname, oldnv ?
oldchild[c] : NULL, newchild[c],
cb, depth + 2);
@@ -2607,7 +2635,7 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
"-\n", cb->cb_namewidth, "cache");
for (c = 0; c < children; c++) {
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
B_FALSE);
cb->cb_name_flags);
print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
newchild[c], cb, depth + 2);
free(vname);
@@ -2700,7 +2728,7 @@ get_namewidth(zpool_handle_t *zhp, void *data)
cb->cb_namewidth = strlen(zpool_get_name(zhp));
else
cb->cb_namewidth = max_width(zhp, nvroot, 0,
cb->cb_namewidth);
cb->cb_namewidth, cb->cb_name_flags);
}
/*
@@ -2800,8 +2828,11 @@ get_timestamp_arg(char c)
}
/*
* zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
* zpool iostat [-gLpv] [-T d|u] [pool] ... [interval [count]]
*
* -g Display guid for individual vdev name.
* -L Follow links when resolving vdev path name.
* -p Display full path for vdev name.
* -v Display statistics for individual vdevs
* -T Display a timestamp in date(1) or Unix format
*
@@ -2821,11 +2852,23 @@ zpool_do_iostat(int argc, char **argv)
zpool_list_t *list;
boolean_t verbose = B_FALSE;
boolean_t omit_since_boot = B_FALSE;
iostat_cbdata_t cb;
boolean_t guid = B_FALSE;
boolean_t follow_links = B_FALSE;
boolean_t full_name = B_FALSE;
iostat_cbdata_t cb = { 0 };
/* check options */
while ((c = getopt(argc, argv, "T:vy")) != -1) {
while ((c = getopt(argc, argv, "gLpT:vy")) != -1) {
switch (c) {
case 'g':
guid = B_TRUE;
break;
case 'L':
follow_links = B_TRUE;
break;
case 'p':
full_name = B_TRUE;
break;
case 'T':
get_timestamp_arg(*optarg);
break;
@@ -2870,6 +2913,12 @@ zpool_do_iostat(int argc, char **argv)
*/
cb.cb_list = list;
cb.cb_verbose = verbose;
if (guid)
cb.cb_name_flags |= VDEV_NAME_GUID;
if (follow_links)
cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
if (full_name)
cb.cb_name_flags |= VDEV_NAME_PATH;
cb.cb_iteration = 0;
cb.cb_namewidth = 0;
@@ -2953,6 +3002,7 @@ zpool_do_iostat(int argc, char **argv)
typedef struct list_cbdata {
boolean_t cb_verbose;
int cb_name_flags;
int cb_namewidth;
boolean_t cb_scripted;
zprop_list_t *cb_proplist;
@@ -3187,7 +3237,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
continue;
}
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
vname = zpool_vdev_name(g_zfs, zhp, child[c],
cb->cb_name_flags);
print_list_stats(zhp, vname, child[c], cb, depth + 2);
free(vname);
}
@@ -3199,7 +3250,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
&islog) != 0 || !islog)
continue;
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
vname = zpool_vdev_name(g_zfs, zhp, child[c],
cb->cb_name_flags);
print_list_stats(zhp, vname, child[c], cb, depth + 2);
free(vname);
}
@@ -3210,7 +3262,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf(dashes, cb->cb_namewidth, "cache");
for (c = 0; c < children; c++) {
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
vname = zpool_vdev_name(g_zfs, zhp, child[c],
cb->cb_name_flags);
print_list_stats(zhp, vname, child[c], cb, depth + 2);
free(vname);
}
@@ -3221,7 +3274,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf(dashes, cb->cb_namewidth, "spare");
for (c = 0; c < children; c++) {
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
vname = zpool_vdev_name(g_zfs, zhp, child[c],
cb->cb_name_flags);
print_list_stats(zhp, vname, child[c], cb, depth + 2);
free(vname);
}
@@ -3253,13 +3307,16 @@ list_callback(zpool_handle_t *zhp, void *data)
}
/*
* zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
* zpool list [-gHLp] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
*
* -g Display guid for individual vdev name.
* -H Scripted mode. Don't display headers, and separate properties
* 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 full path for vdev name.
* -T Display a timestamp in date(1) or Unix format
*
* List all pools in the system, whether or not they're healthy. Output space
@@ -3280,14 +3337,23 @@ zpool_do_list(int argc, char **argv)
boolean_t first = B_TRUE;
/* check options */
while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
while ((c = getopt(argc, argv, ":gHLo:pT:v")) != -1) {
switch (c) {
case 'g':
cb.cb_name_flags |= VDEV_NAME_GUID;
break;
case 'H':
cb.cb_scripted = B_TRUE;
break;
case 'L':
cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
break;
case 'o':
props = optarg;
break;
case 'p':
cb.cb_name_flags |= VDEV_NAME_PATH;
break;
case 'T':
get_timestamp_arg(*optarg);
break;
@@ -3543,13 +3609,16 @@ zpool_do_detach(int argc, char **argv)
}
/*
* zpool split [-n] [-o prop=val] ...
* zpool split [-gLnp] [-o prop=val] ...
* [-o mntopt] ...
* [-R altroot] <pool> <newpool> [<device> ...]
*
* -g Display guid for individual vdev name.
* -L Follow links when resolving vdev path name.
* -n Do not split the pool, but display the resulting layout if
* it were to be split.
* -o Set property=value, or set mount options.
* -p Display full path for vdev name.
* -R Mount the split-off pool under an alternate root.
*
* Splits the named pool and gives it the new pool name. Devices to be split
@@ -3573,10 +3642,17 @@ zpool_do_split(int argc, char **argv)
flags.dryrun = B_FALSE;
flags.import = B_FALSE;
flags.name_flags = 0;
/* check options */
while ((c = getopt(argc, argv, ":R:no:")) != -1) {
while ((c = getopt(argc, argv, ":gLR:no:p")) != -1) {
switch (c) {
case 'g':
flags.name_flags |= VDEV_NAME_GUID;
break;
case 'L':
flags.name_flags |= VDEV_NAME_FOLLOW_LINKS;
break;
case 'R':
flags.import = B_TRUE;
if (add_prop_list(
@@ -3604,6 +3680,9 @@ zpool_do_split(int argc, char **argv)
mntopts = optarg;
}
break;
case 'p':
flags.name_flags |= VDEV_NAME_PATH;
break;
case ':':
(void) fprintf(stderr, gettext("missing argument for "
"'%c' option\n"), optopt);
@@ -3651,7 +3730,8 @@ zpool_do_split(int argc, char **argv)
if (flags.dryrun) {
(void) printf(gettext("would create '%s' with the "
"following layout:\n\n"), newpool);
print_vdev_tree(NULL, newpool, config, 0, B_FALSE);
print_vdev_tree(NULL, newpool, config, 0, B_FALSE,
flags.name_flags);
}
nvlist_free(config);
}
@@ -4057,6 +4137,7 @@ zpool_do_scrub(int argc, char **argv)
typedef struct status_cbdata {
int cb_count;
int cb_name_flags;
boolean_t cb_allpools;
boolean_t cb_verbose;
boolean_t cb_explain;
@@ -4213,7 +4294,7 @@ print_error_log(zpool_handle_t *zhp)
static void
print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
int namewidth)
int namewidth, int name_flags)
{
uint_t i;
char *name;
@@ -4224,16 +4305,16 @@ print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
(void) printf(gettext("\tspares\n"));
for (i = 0; i < nspares; i++) {
name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
name = zpool_vdev_name(g_zfs, zhp, spares[i], name_flags);
print_status_config(zhp, name, spares[i],
namewidth, 2, B_TRUE);
namewidth, 2, B_TRUE, name_flags);
free(name);
}
}
static void
print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
int namewidth)
int namewidth, int name_flags)
{
uint_t i;
char *name;
@@ -4244,9 +4325,9 @@ print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
(void) printf(gettext("\tcache\n"));
for (i = 0; i < nl2cache; i++) {
name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
name = zpool_vdev_name(g_zfs, zhp, l2cache[i], name_flags);
print_status_config(zhp, name, l2cache[i],
namewidth, 2, B_FALSE);
namewidth, 2, B_FALSE, name_flags);
free(name);
}
}
@@ -4588,7 +4669,7 @@ status_callback(zpool_handle_t *zhp, void *data)
ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
print_scan_status(ps);
namewidth = max_width(zhp, nvroot, 0, 0);
namewidth = max_width(zhp, nvroot, 0, 0, cbp->cb_name_flags);
if (namewidth < 10)
namewidth = 10;
@@ -4596,17 +4677,20 @@ status_callback(zpool_handle_t *zhp, void *data)
(void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
"NAME", "STATE", "READ", "WRITE", "CKSUM");
print_status_config(zhp, zpool_get_name(zhp), nvroot,
namewidth, 0, B_FALSE);
namewidth, 0, B_FALSE, cbp->cb_name_flags);
if (num_logs(nvroot) > 0)
print_logs(zhp, nvroot, namewidth, B_TRUE);
print_logs(zhp, nvroot, namewidth, B_TRUE,
cbp->cb_name_flags);
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
&l2cache, &nl2cache) == 0)
print_l2cache(zhp, l2cache, nl2cache, namewidth);
print_l2cache(zhp, l2cache, nl2cache, namewidth,
cbp->cb_name_flags);
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
&spares, &nspares) == 0)
print_spares(zhp, spares, nspares, namewidth);
print_spares(zhp, spares, nspares, namewidth,
cbp->cb_name_flags);
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
&nerr) == 0) {
@@ -4654,8 +4738,11 @@ status_callback(zpool_handle_t *zhp, void *data)
}
/*
* zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
* zpool status [-gLpvx] [-T d|u] [pool] ... [interval [count]]
*
* -g Display guid for individual vdev name.
* -L Follow links when resolving vdev path name.
* -p Display full path for vdev name.
* -v Display complete error logs
* -x Display only pools with potential problems
* -D Display dedup status (undocumented)
@@ -4672,8 +4759,17 @@ zpool_do_status(int argc, char **argv)
status_cbdata_t cb = { 0 };
/* check options */
while ((c = getopt(argc, argv, "vxDT:")) != -1) {
while ((c = getopt(argc, argv, "gLpvxDT:")) != -1) {
switch (c) {
case 'g':
cb.cb_name_flags |= VDEV_NAME_GUID;
break;
case 'L':
cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
break;
case 'p':
cb.cb_name_flags |= VDEV_NAME_PATH;
break;
case 'v':
cb.cb_verbose = B_TRUE;
break;