diff options
author | Richard Yao <[email protected]> | 2013-12-29 13:40:46 -0500 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2016-02-25 11:58:39 -0800 |
commit | d2f3e292dccab23e47ade3c67677a10f353b9e85 (patch) | |
tree | 89ffd386e9a11e4464386a4141ce1cca978a6c05 /cmd | |
parent | e79a6bacc6666233e109513b614d19d9d7742820 (diff) |
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 <[email protected]>
Extended-by: ilovezfs <[email protected]>
Extended-by: Brian Behlendorf <[email protected]>
Signed-off-by: ilovezfs <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #2011
Closes #4341
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/zpool/zpool_main.c | 242 |
1 files changed, 169 insertions, 73 deletions
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 9bf28c29f..420e95730 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -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; |