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] "
"[-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"));
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"
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:
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;
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);
}
}
}
/*
- * 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
{
boolean_t force = B_FALSE;
boolean_t dryrun = B_FALSE;
+ int name_flags = 0;
int c;
nvlist_t *nvroot;
char *poolname;
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;
(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);
"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 */
(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);
}
(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);
}
(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 {
* 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;
&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;
}
&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;
}
&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);
}
/*
* 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;
&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;
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);
}
&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);
}
&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);
}
* 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;
&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);
}
}
(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 "
typedef struct iostat_cbdata {
boolean_t cb_verbose;
+ int cb_name_flags;
int cb_namewidth;
int cb_iteration;
zpool_list_t *cb_list;
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);
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);
"-\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);
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);
}
/*
}
/*
- * 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
*
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;
*/
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;
typedef struct list_cbdata {
boolean_t cb_verbose;
+ int cb_name_flags;
int cb_namewidth;
boolean_t cb_scripted;
zprop_list_t *cb_proplist;
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);
}
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);
}
/* 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);
}
/* 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);
}
}
/*
- * 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
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;
}
/*
- * 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
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(
mntopts = optarg;
}
break;
+ case 'p':
+ flags.name_flags |= VDEV_NAME_PATH;
+ break;
case ':':
(void) fprintf(stderr, gettext("missing argument for "
"'%c' option\n"), optopt);
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);
}
typedef struct status_cbdata {
int cb_count;
+ int cb_name_flags;
boolean_t cb_allpools;
boolean_t cb_verbose;
boolean_t cb_explain;
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;
(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;
(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);
}
}
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;
(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) {
}
/*
- * 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)
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;
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"device '%s' contains an EFI label and "
"cannot be used on root pools."),
- zpool_vdev_name(hdl, NULL, spares[s],
- B_FALSE));
+ zpool_vdev_name(hdl, NULL, spares[s], 0));
return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
}
}
return;
for (c = 0; c < children; c++) {
- vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE);
+ vname = zpool_vdev_name(hdl, NULL, child[c], VDEV_NAME_TYPE_ID);
print_vdev_tree(hdl, vname, child[c], indent + 2);
free(vname);
}
verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
- if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
+ if ((newname = zpool_vdev_name(NULL, NULL, child[0], 0)) == NULL)
return (-1);
/*
for (mc = 0; mc < mchildren; mc++) {
uint_t sc;
char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
- mchild[mc], B_FALSE);
+ mchild[mc], 0);
for (sc = 0; sc < schildren; sc++) {
char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
- schild[sc], B_FALSE);
+ schild[sc], 0);
boolean_t result = (strcmp(mpath, spath) == 0);
free(spath);
*/
char *
zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
- boolean_t verbose)
+ int name_flags)
{
- char *path, *devid, *type;
+ char *path, *devid, *type, *env;
uint64_t value;
char buf[PATH_BUF_LEN];
char tmpbuf[PATH_BUF_LEN];
vdev_stat_t *vs;
uint_t vsc;
- if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
- &value) == 0) {
- verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
- &value) == 0);
- (void) snprintf(buf, sizeof (buf), "%llu",
- (u_longlong_t)value);
+ env = getenv("ZPOOL_VDEV_NAME_PATH");
+ if (env && (strtoul(env, NULL, 0) > 0 ||
+ !strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2)))
+ name_flags |= VDEV_NAME_PATH;
+
+ env = getenv("ZPOOL_VDEV_NAME_GUID");
+ if (env && (strtoul(env, NULL, 0) > 0 ||
+ !strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2)))
+ name_flags |= VDEV_NAME_GUID;
+
+ env = getenv("ZPOOL_VDEV_NAME_FOLLOW_LINKS");
+ if (env && (strtoul(env, NULL, 0) > 0 ||
+ !strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2)))
+ name_flags |= VDEV_NAME_FOLLOW_LINKS;
+
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 ||
+ name_flags & VDEV_NAME_GUID) {
+ nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value);
+ (void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)value);
path = buf;
} else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
/*
devid_str_free(newdevid);
}
+ if (name_flags & VDEV_NAME_FOLLOW_LINKS) {
+ char *rp = realpath(path, NULL);
+ if (rp) {
+ strlcpy(buf, rp, sizeof (buf));
+ path = buf;
+ free(rp);
+ }
+ }
+
/*
* For a block device only use the name.
*/
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
- if (strcmp(type, VDEV_TYPE_DISK) == 0) {
+ if ((strcmp(type, VDEV_TYPE_DISK) == 0) &&
+ !(name_flags & VDEV_NAME_PATH)) {
path = strrchr(path, '/');
path++;
}
/*
* Remove the partition from the path it this is a whole disk.
*/
- if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
- &value) == 0 && value) {
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &value)
+ == 0 && value && !(name_flags & VDEV_NAME_PATH)) {
return (strip_partition(hdl, path));
}
} else {
* We identify each top-level vdev by using a <type-id>
* naming convention.
*/
- if (verbose) {
+ if (name_flags & VDEV_NAME_TYPE_ID) {
uint64_t id;
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,