svn commit: r354382 - vendor-sys/illumos/dist/common/zfs vendor-sys/illumos/dist/uts/common/fs/zfs vendor-sys/illumos/dist/uts/common/fs/zfs/sys vendor-sys/illumos/dist/uts/common/sys/fs vendor/ill...
Andriy Gapon
avg at FreeBSD.org
Wed Nov 6 08:58:08 UTC 2019
Author: avg
Date: Wed Nov 6 08:58:03 2019
New Revision: 354382
URL: https://svnweb.freebsd.org/changeset/base/354382
Log:
10601 10757 Pool allocation classes
illumos/illumos-gate at 663207adb1669640c01c5ec6949ce78fd806efae
https://github.com/illumos/illumos-gate/commit/663207adb1669640c01c5ec6949ce78fd806efae
10601 Pool allocation classes
https://www.illumos.org/issues/10601
illumos port of ZoL Pool allocation classes. Includes at least these two
commits:
441709695 Pool allocation classes misplacing small file blocks
cc99f275a Pool allocation classes
10757 Add -gLp to zpool subcommands for alt vdev names
https://www.illumos.org/issues/10757
Port from ZoL of
d2f3e292d Add -gLp to zpool subcommands for alt vdev names
Note that a subsequent ZoL commit changed -p to -P
a77f29f93 Change full path subcommand flag from -p to -P
Portions contributed by: Jerry Jelinek <jerry.jelinek at joyent.com>
Portions contributed by: Håkan Johansson <f96hajo at chalmers.se>
Portions contributed by: Richard Yao <ryao at gentoo.org>
Portions contributed by: Chunwei Chen <david.chen at nutanix.com>
Portions contributed by: loli10K <ezomori.nozomu at gmail.com>
Author: Don Brady <don.brady at delphix.com>
Modified:
vendor/illumos/dist/cmd/zdb/zdb.c
vendor/illumos/dist/cmd/zpool/zpool_main.c
vendor/illumos/dist/cmd/zpool/zpool_vdev.c
vendor/illumos/dist/cmd/ztest/ztest.c
vendor/illumos/dist/lib/libzfs/common/libzfs.h
vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c
vendor/illumos/dist/lib/libzfs/common/libzfs_pool.c
vendor/illumos/dist/lib/libzpool/common/util.c
vendor/illumos/dist/man/man1m/zfs.1m
vendor/illumos/dist/man/man1m/zpool.1m
vendor/illumos/dist/man/man5/zpool-features.5
Changes in other areas also in this revision:
Modified:
vendor-sys/illumos/dist/common/zfs/zfeature_common.c
vendor-sys/illumos/dist/common/zfs/zfeature_common.h
vendor-sys/illumos/dist/common/zfs/zfs_prop.c
vendor-sys/illumos/dist/uts/common/fs/zfs/dmu.c
vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_objset.c
vendor-sys/illumos/dist/uts/common/fs/zfs/metaslab.c
vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c
vendor-sys/illumos/dist/uts/common/fs/zfs/spa_misc.c
vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu.h
vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu_objset.h
vendor-sys/illumos/dist/uts/common/fs/zfs/sys/metaslab.h
vendor-sys/illumos/dist/uts/common/fs/zfs/sys/spa.h
vendor-sys/illumos/dist/uts/common/fs/zfs/sys/spa_impl.h
vendor-sys/illumos/dist/uts/common/fs/zfs/sys/vdev.h
vendor-sys/illumos/dist/uts/common/fs/zfs/sys/vdev_impl.h
vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zio.h
vendor-sys/illumos/dist/uts/common/fs/zfs/vdev.c
vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_label.c
vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_removal.c
vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c
vendor-sys/illumos/dist/uts/common/fs/zfs/zio.c
vendor-sys/illumos/dist/uts/common/sys/fs/zfs.h
Modified: vendor/illumos/dist/cmd/zdb/zdb.c
==============================================================================
--- vendor/illumos/dist/cmd/zdb/zdb.c Wed Nov 6 08:55:23 2019 (r354381)
+++ vendor/illumos/dist/cmd/zdb/zdb.c Wed Nov 6 08:58:03 2019 (r354382)
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2017 Nexenta Systems, Inc.
* Copyright (c) 2017, 2018 Lawrence Livermore National Security, LLC.
@@ -931,13 +931,23 @@ dump_metaslab(metaslab_t *msp)
static void
print_vdev_metaslab_header(vdev_t *vd)
{
- (void) printf("\tvdev %10llu\n\t%-10s%5llu %-19s %-15s %-10s\n",
- (u_longlong_t)vd->vdev_id,
+ vdev_alloc_bias_t alloc_bias = vd->vdev_alloc_bias;
+ const char *bias_str;
+
+ bias_str = (alloc_bias == VDEV_BIAS_LOG || vd->vdev_islog) ?
+ VDEV_ALLOC_BIAS_LOG :
+ (alloc_bias == VDEV_BIAS_SPECIAL) ? VDEV_ALLOC_BIAS_SPECIAL :
+ (alloc_bias == VDEV_BIAS_DEDUP) ? VDEV_ALLOC_BIAS_DEDUP :
+ vd->vdev_islog ? "log" : "";
+
+ (void) printf("\tvdev %10llu %s\n"
+ "\t%-10s%5llu %-19s %-15s %-12s\n",
+ (u_longlong_t)vd->vdev_id, bias_str,
"metaslabs", (u_longlong_t)vd->vdev_ms_count,
"offset", "spacemap", "free");
- (void) printf("\t%15s %19s %15s %10s\n",
+ (void) printf("\t%15s %19s %15s %12s\n",
"---------------", "-------------------",
- "---------------", "-------------");
+ "---------------", "------------");
}
static void
@@ -953,7 +963,7 @@ dump_metaslab_groups(spa_t *spa)
vdev_t *tvd = rvd->vdev_child[c];
metaslab_group_t *mg = tvd->vdev_mg;
- if (mg->mg_class != mc)
+ if (mg == NULL || mg->mg_class != mc)
continue;
metaslab_group_histogram_verify(mg);
@@ -2767,6 +2777,7 @@ typedef struct zdb_blkstats {
uint64_t zb_count;
uint64_t zb_gangs;
uint64_t zb_ditto_samevdev;
+ uint64_t zb_ditto_same_ms;
uint64_t zb_psize_histogram[PSIZE_HISTO_SIZE];
} zdb_blkstats_t;
@@ -2806,6 +2817,16 @@ typedef struct zdb_cb {
uint32_t **zcb_vd_obsolete_counts;
} zdb_cb_t;
+/* test if two DVA offsets from same vdev are within the same metaslab */
+static boolean_t
+same_metaslab(spa_t *spa, uint64_t vdev, uint64_t off1, uint64_t off2)
+{
+ vdev_t *vd = vdev_lookup_top(spa, vdev);
+ uint64_t ms_shift = vd->vdev_ms_shift;
+
+ return ((off1 >> ms_shift) == (off2 >> ms_shift));
+}
+
static void
zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
dmu_object_type_t type)
@@ -2817,6 +2838,8 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const b
if (zilog && zil_bp_tree_add(zilog, bp) != 0)
return;
+ spa_config_enter(zcb->zcb_spa, SCL_CONFIG, FTAG, RW_READER);
+
for (int i = 0; i < 4; i++) {
int l = (i < 2) ? BP_GET_LEVEL(bp) : ZB_TOTAL;
int t = (i & 1) ? type : ZDB_OT_TOTAL;
@@ -2842,8 +2865,15 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const b
switch (BP_GET_NDVAS(bp)) {
case 2:
if (DVA_GET_VDEV(&bp->blk_dva[0]) ==
- DVA_GET_VDEV(&bp->blk_dva[1]))
+ DVA_GET_VDEV(&bp->blk_dva[1])) {
zb->zb_ditto_samevdev++;
+
+ if (same_metaslab(zcb->zcb_spa,
+ DVA_GET_VDEV(&bp->blk_dva[0]),
+ DVA_GET_OFFSET(&bp->blk_dva[0]),
+ DVA_GET_OFFSET(&bp->blk_dva[1])))
+ zb->zb_ditto_same_ms++;
+ }
break;
case 3:
equal = (DVA_GET_VDEV(&bp->blk_dva[0]) ==
@@ -2852,13 +2882,37 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const b
DVA_GET_VDEV(&bp->blk_dva[2])) +
(DVA_GET_VDEV(&bp->blk_dva[1]) ==
DVA_GET_VDEV(&bp->blk_dva[2]));
- if (equal != 0)
+ if (equal != 0) {
zb->zb_ditto_samevdev++;
+
+ if (DVA_GET_VDEV(&bp->blk_dva[0]) ==
+ DVA_GET_VDEV(&bp->blk_dva[1]) &&
+ same_metaslab(zcb->zcb_spa,
+ DVA_GET_VDEV(&bp->blk_dva[0]),
+ DVA_GET_OFFSET(&bp->blk_dva[0]),
+ DVA_GET_OFFSET(&bp->blk_dva[1])))
+ zb->zb_ditto_same_ms++;
+ else if (DVA_GET_VDEV(&bp->blk_dva[0]) ==
+ DVA_GET_VDEV(&bp->blk_dva[2]) &&
+ same_metaslab(zcb->zcb_spa,
+ DVA_GET_VDEV(&bp->blk_dva[0]),
+ DVA_GET_OFFSET(&bp->blk_dva[0]),
+ DVA_GET_OFFSET(&bp->blk_dva[2])))
+ zb->zb_ditto_same_ms++;
+ else if (DVA_GET_VDEV(&bp->blk_dva[1]) ==
+ DVA_GET_VDEV(&bp->blk_dva[2]) &&
+ same_metaslab(zcb->zcb_spa,
+ DVA_GET_VDEV(&bp->blk_dva[1]),
+ DVA_GET_OFFSET(&bp->blk_dva[1]),
+ DVA_GET_OFFSET(&bp->blk_dva[2])))
+ zb->zb_ditto_same_ms++;
+ }
break;
}
-
}
+ spa_config_exit(zcb->zcb_spa, SCL_CONFIG, FTAG);
+
if (BP_IS_EMBEDDED(bp)) {
zcb->zcb_embedded_blocks[BPE_GET_ETYPE(bp)]++;
zcb->zcb_embedded_histogram[BPE_GET_ETYPE(bp)]
@@ -3665,6 +3719,7 @@ dump_block_stats(spa_t *spa)
uint64_t norm_alloc, norm_space, total_alloc, total_found;
int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD;
boolean_t leaks = B_FALSE;
+ int err;
bzero(&zcb, sizeof (zcb));
(void) printf("\nTraversing all blocks %s%s%s%s%s...\n\n",
@@ -3707,8 +3762,10 @@ dump_block_stats(spa_t *spa)
flags |= TRAVERSE_PREFETCH_DATA;
zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa));
+ zcb.zcb_totalasize += metaslab_class_get_alloc(spa_special_class(spa));
+ zcb.zcb_totalasize += metaslab_class_get_alloc(spa_dedup_class(spa));
zcb.zcb_start = zcb.zcb_lastprint = gethrtime();
- zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
+ err = traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
/*
* If we've traversed the data blocks then we need to wait for those
@@ -3724,6 +3781,12 @@ dump_block_stats(spa_t *spa)
}
}
+ /*
+ * Done after zio_wait() since zcb_haderrors is modified in
+ * zdb_blkptr_done()
+ */
+ zcb.zcb_haderrors |= err;
+
if (zcb.zcb_haderrors) {
(void) printf("\nError counts:\n\n");
(void) printf("\t%5s %s\n", "errno", "count");
@@ -3745,7 +3808,10 @@ dump_block_stats(spa_t *spa)
norm_alloc = metaslab_class_get_alloc(spa_normal_class(spa));
norm_space = metaslab_class_get_space(spa_normal_class(spa));
- total_alloc = norm_alloc + metaslab_class_get_alloc(spa_log_class(spa));
+ total_alloc = norm_alloc +
+ metaslab_class_get_alloc(spa_log_class(spa)) +
+ metaslab_class_get_alloc(spa_special_class(spa)) +
+ metaslab_class_get_alloc(spa_dedup_class(spa));
total_found = tzb->zb_asize - zcb.zcb_dedup_asize +
zcb.zcb_removing_size + zcb.zcb_checkpoint_size;
@@ -3767,31 +3833,50 @@ dump_block_stats(spa_t *spa)
return (2);
(void) printf("\n");
- (void) printf("\tbp count: %10llu\n",
+ (void) printf("\t%-16s %14llu\n", "bp count:",
(u_longlong_t)tzb->zb_count);
- (void) printf("\tganged count: %10llu\n",
+ (void) printf("\t%-16s %14llu\n", "ganged count:",
(longlong_t)tzb->zb_gangs);
- (void) printf("\tbp logical: %10llu avg: %6llu\n",
+ (void) printf("\t%-16s %14llu avg: %6llu\n", "bp logical:",
(u_longlong_t)tzb->zb_lsize,
(u_longlong_t)(tzb->zb_lsize / tzb->zb_count));
- (void) printf("\tbp physical: %10llu avg:"
- " %6llu compression: %6.2f\n",
- (u_longlong_t)tzb->zb_psize,
+ (void) printf("\t%-16s %14llu avg: %6llu compression: %6.2f\n",
+ "bp physical:", (u_longlong_t)tzb->zb_psize,
(u_longlong_t)(tzb->zb_psize / tzb->zb_count),
(double)tzb->zb_lsize / tzb->zb_psize);
- (void) printf("\tbp allocated: %10llu avg:"
- " %6llu compression: %6.2f\n",
- (u_longlong_t)tzb->zb_asize,
+ (void) printf("\t%-16s %14llu avg: %6llu compression: %6.2f\n",
+ "bp allocated:", (u_longlong_t)tzb->zb_asize,
(u_longlong_t)(tzb->zb_asize / tzb->zb_count),
(double)tzb->zb_lsize / tzb->zb_asize);
- (void) printf("\tbp deduped: %10llu ref>1:"
- " %6llu deduplication: %6.2f\n",
- (u_longlong_t)zcb.zcb_dedup_asize,
+ (void) printf("\t%-16s %14llu ref>1: %6llu deduplication: %6.2f\n",
+ "bp deduped:", (u_longlong_t)zcb.zcb_dedup_asize,
(u_longlong_t)zcb.zcb_dedup_blocks,
(double)zcb.zcb_dedup_asize / tzb->zb_asize + 1.0);
- (void) printf("\tSPA allocated: %10llu used: %5.2f%%\n",
+ (void) printf("\t%-16s %14llu used: %5.2f%%\n", "Normal class:",
(u_longlong_t)norm_alloc, 100.0 * norm_alloc / norm_space);
+ if (spa_special_class(spa)->mc_rotor != NULL) {
+ uint64_t alloc = metaslab_class_get_alloc(
+ spa_special_class(spa));
+ uint64_t space = metaslab_class_get_space(
+ spa_special_class(spa));
+
+ (void) printf("\t%-16s %14llu used: %5.2f%%\n",
+ "Special class", (u_longlong_t)alloc,
+ 100.0 * alloc / space);
+ }
+
+ if (spa_dedup_class(spa)->mc_rotor != NULL) {
+ uint64_t alloc = metaslab_class_get_alloc(
+ spa_dedup_class(spa));
+ uint64_t space = metaslab_class_get_space(
+ spa_dedup_class(spa));
+
+ (void) printf("\t%-16s %14llu used: %5.2f%%\n",
+ "Dedup class", (u_longlong_t)alloc,
+ 100.0 * alloc / space);
+ }
+
for (bp_embedded_type_t i = 0; i < NUM_BP_EMBEDDED_TYPES; i++) {
if (zcb.zcb_embedded_blocks[i] == 0)
continue;
@@ -3812,6 +3897,10 @@ dump_block_stats(spa_t *spa)
if (tzb->zb_ditto_samevdev != 0) {
(void) printf("\tDittoed blocks on same vdev: %llu\n",
(longlong_t)tzb->zb_ditto_samevdev);
+ }
+ if (tzb->zb_ditto_same_ms != 0) {
+ (void) printf("\tDittoed blocks in same metaslab: %llu\n",
+ (longlong_t)tzb->zb_ditto_same_ms);
}
for (uint64_t v = 0; v < spa->spa_root_vdev->vdev_children; v++) {
Modified: vendor/illumos/dist/cmd/zpool/zpool_main.c
==============================================================================
--- vendor/illumos/dist/cmd/zpool/zpool_main.c Wed Nov 6 08:55:23 2019 (r354381)
+++ vendor/illumos/dist/cmd/zpool/zpool_main.c Wed Nov 6 08:58:03 2019 (r354382)
@@ -27,6 +27,7 @@
* Copyright 2016 Igor Kozhukhov <ikozhukhov at gmail.com>.
* Copyright 2016 Nexenta Systems, Inc.
* Copyright (c) 2017 Datto Inc.
+ * Copyright (c) 2017, Intel Corporation.
*/
#include <assert.h>
@@ -206,6 +207,8 @@ static zpool_command_t command_table[] = {
#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
+#define VDEV_ALLOC_CLASS_LOGS "logs"
+
static zpool_command_t *current_command;
static char history_str[HIS_MAX_RECORD_LEN];
static boolean_t log_history = B_TRUE;
@@ -216,7 +219,7 @@ get_usage(zpool_help_t idx)
{
switch (idx) {
case HELP_ADD:
- return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
+ return (gettext("\tadd [-fgLnP] <pool> <vdev> ...\n"));
case HELP_ATTACH:
return (gettext("\tattach [-f] <pool> <device> "
"<new-device>\n"));
@@ -248,12 +251,12 @@ get_usage(zpool_help_t idx)
"[-R root] [-F [-n]] [-t]\n"
"\t [--rewind-to-checkpoint] <pool | id> [newpool]\n"));
case HELP_IOSTAT:
- return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
- "[count]]\n"));
+ return (gettext("\tiostat [-gLPv] [-T d|u] [pool] ... "
+ "[interval [count]]\n"));
case HELP_LABELCLEAR:
return (gettext("\tlabelclear [-f] <vdev>\n"));
case HELP_LIST:
- return (gettext("\tlist [-Hp] [-o property[,...]] "
+ return (gettext("\tlist [-gHLpPv] [-o property[,...]] "
"[-T d|u] [pool] ... [interval [count]]\n"));
case HELP_OFFLINE:
return (gettext("\toffline [-t] <pool> <device> ...\n"));
@@ -271,8 +274,8 @@ get_usage(zpool_help_t idx)
case HELP_SCRUB:
return (gettext("\tscrub [-s | -p] <pool> ...\n"));
case HELP_STATUS:
- return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
- "[count]]\n"));
+ return (gettext("\tstatus [-DgLPvx] [-T d|u] [pool] ... "
+ "[interval [count]]\n"));
case HELP_UPGRADE:
return (gettext("\tupgrade\n"
"\tupgrade -v\n"
@@ -283,7 +286,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:
@@ -305,7 +308,7 @@ print_prop_cb(int prop, void *cb)
{
FILE *fp = cb;
- (void) fprintf(fp, "\t%-15s ", zpool_prop_to_name(prop));
+ (void) fprintf(fp, "\t%-19s ", zpool_prop_to_name(prop));
if (zpool_prop_readonly(prop))
(void) fprintf(fp, " NO ");
@@ -357,14 +360,14 @@ usage(boolean_t requested)
(void) fprintf(fp,
gettext("\nthe following properties are supported:\n"));
- (void) fprintf(fp, "\n\t%-15s %s %s\n\n",
+ (void) fprintf(fp, "\n\t%-19s %s %s\n\n",
"PROPERTY", "EDIT", "VALUES");
/* Iterate over all properties */
(void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
ZFS_TYPE_POOL);
- (void) fprintf(fp, "\t%-15s ", "feature at ...");
+ (void) fprintf(fp, "\t%-19s ", "feature at ...");
(void) fprintf(fp, "YES disabled | enabled | active\n");
(void) fprintf(fp, gettext("\nThe feature@ properties must be "
@@ -382,32 +385,45 @@ usage(boolean_t requested)
exit(requested ? 0 : 2);
}
-void
+/*
+ * print a pool vdev config for dry runs
+ */
+static void
print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
- boolean_t print_logs)
+ const char *match, int name_flags)
{
nvlist_t **child;
uint_t c, children;
char *vname;
+ boolean_t printed = B_FALSE;
- if (name != NULL)
- (void) printf("\t%*s%s\n", indent, "", name);
-
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
- &child, &children) != 0)
+ &child, &children) != 0) {
+ if (name != NULL)
+ (void) printf("\t%*s%s\n", indent, "", name);
return;
+ }
for (c = 0; c < children; c++) {
uint64_t is_log = B_FALSE;
+ char *class = "";
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
&is_log);
- if ((is_log && !print_logs) || (!is_log && print_logs))
+ if (is_log)
+ class = VDEV_ALLOC_BIAS_LOG;
+ (void) nvlist_lookup_string(child[c],
+ ZPOOL_CONFIG_ALLOCATION_BIAS, &class);
+ if (strcmp(match, class) != 0)
continue;
- vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
- print_vdev_tree(zhp, vname, child[c], indent + 2,
- B_FALSE);
+ if (!printed && name != NULL) {
+ (void) printf("\t%*s%s\n", indent, "", name);
+ printed = B_TRUE;
+ }
+ vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags);
+ print_vdev_tree(zhp, vname, child[c], indent + 2, "",
+ name_flags);
free(vname);
}
}
@@ -515,11 +531,14 @@ add_prop_list_default(const char *propname, char *prop
}
/*
- * zpool add [-fn] <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.
+ * -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
@@ -530,6 +549,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;
@@ -540,14 +560,23 @@ zpool_do_add(int argc, char **argv)
nvlist_t *config;
/* check options */
- while ((c = getopt(argc, argv, "fn")) != -1) {
+ while ((c = getopt(argc, argv, "fgLnP")) != -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;
+ case 'P':
+ name_flags |= VDEV_NAME_PATH;
+ break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
@@ -607,17 +636,26 @@ 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, "",
+ name_flags | VDEV_NAME_TYPE_ID);
+ print_vdev_tree(zhp, NULL, nvroot, 0, "", 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);
- } else if (num_logs(nvroot) > 0) {
- print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
- }
+ /* print other classes: 'dedup', 'special', and 'log' */
+ print_vdev_tree(zhp, "dedup", poolnvroot, 0,
+ VDEV_ALLOC_BIAS_DEDUP, name_flags);
+ print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_DEDUP,
+ name_flags);
+ print_vdev_tree(zhp, "special", poolnvroot, 0,
+ VDEV_ALLOC_BIAS_SPECIAL, name_flags);
+ print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_SPECIAL,
+ name_flags);
+
+ print_vdev_tree(zhp, "logs", poolnvroot, 0, VDEV_ALLOC_BIAS_LOG,
+ name_flags);
+ print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_LOG,
+ name_flags);
+
ret = 0;
} else {
ret = (zpool_add(zhp, nvroot) != 0);
@@ -1203,9 +1241,13 @@ 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);
- if (num_logs(nvroot) > 0)
- print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
+ print_vdev_tree(NULL, poolname, nvroot, 0, "", 0);
+ print_vdev_tree(NULL, "dedup", nvroot, 0,
+ VDEV_ALLOC_BIAS_DEDUP, 0);
+ print_vdev_tree(NULL, "special", nvroot, 0,
+ VDEV_ALLOC_BIAS_SPECIAL, 0);
+ print_vdev_tree(NULL, "logs", nvroot, 0,
+ VDEV_ALLOC_BIAS_LOG, 0);
ret = 0;
} else {
@@ -1412,13 +1454,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;
@@ -1428,7 +1472,7 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int 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;
}
@@ -1436,7 +1480,7 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int 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;
}
@@ -1444,11 +1488,10 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int 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;
}
-
return (max);
}
@@ -1497,12 +1540,24 @@ find_spare(zpool_handle_t *zhp, void *data)
return (0);
}
+typedef struct status_cbdata {
+ int cb_count;
+ int cb_name_flags;
+ int cb_namewidth;
+ boolean_t cb_allpools;
+ boolean_t cb_verbose;
+ boolean_t cb_explain;
+ boolean_t cb_first;
+ boolean_t cb_dedup_stats;
+ boolean_t cb_print_status;
+} status_cbdata_t;
+
/*
* Print out configuration state as requested by status_callback.
*/
-void
-print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
- int namewidth, int depth, boolean_t isspare)
+static void
+print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
+ nvlist_t *nv, int depth, boolean_t isspare)
{
nvlist_t **child;
uint_t c, children;
@@ -1511,7 +1566,7 @@ print_status_config(zpool_handle_t *zhp, const char *n
char rbuf[6], wbuf[6], cbuf[6];
char *vname;
uint64_t notpresent;
- spare_cbdata_t cb;
+ spare_cbdata_t spare_cb;
const char *state;
char *type;
@@ -1539,7 +1594,7 @@ print_status_config(zpool_handle_t *zhp, const char *n
state = "AVAIL";
}
- (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth,
+ (void) printf("\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth,
name, state);
if (!isspare) {
@@ -1580,17 +1635,17 @@ print_status_config(zpool_handle_t *zhp, const char *n
case VDEV_AUX_SPARED:
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
- &cb.cb_guid) == 0);
- if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
- if (strcmp(zpool_get_name(cb.cb_zhp),
+ &spare_cb.cb_guid) == 0);
+ if (zpool_iter(g_zfs, find_spare, &spare_cb) == 1) {
+ if (strcmp(zpool_get_name(spare_cb.cb_zhp),
zpool_get_name(zhp)) == 0)
(void) printf(gettext("currently in "
"use"));
else
(void) printf(gettext("in use by "
"pool '%s'"),
- zpool_get_name(cb.cb_zhp));
- zpool_close(cb.cb_zhp);
+ zpool_get_name(spare_cb.cb_zhp));
+ zpool_close(spare_cb.cb_zhp);
} else {
(void) printf(gettext("currently in use"));
}
@@ -1689,20 +1744,25 @@ print_status_config(zpool_handle_t *zhp, const char *n
&ishole);
if (islog || ishole)
continue;
- vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
- print_status_config(zhp, vname, child[c],
- namewidth, depth + 2, isspare);
+ /* Only print normal classes here */
+ if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
+ continue;
+
+ vname = zpool_vdev_name(g_zfs, zhp, child[c],
+ cb->cb_name_flags | VDEV_NAME_TYPE_ID);
+ print_status_config(zhp, cb, vname, child[c], depth + 2,
+ isspare);
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(status_cbdata_t *cb, const char *name, nvlist_t *nv,
+ int depth)
{
nvlist_t **child;
uint_t c, children;
@@ -1717,7 +1777,7 @@ print_import_config(const char *name, nvlist_t *nv, in
verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
(uint64_t **)&vs, &c) == 0);
- (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
+ (void) printf("\t%*s%-*s", depth, "", cb->cb_namewidth - depth, name);
(void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
if (vs->vs_aux != 0) {
@@ -1774,9 +1834,12 @@ print_import_config(const char *name, nvlist_t *nv, in
&is_log);
if (is_log)
continue;
+ if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
+ 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],
+ cb->cb_name_flags | VDEV_NAME_TYPE_ID);
+ print_import_config(cb, vname, child[c], depth + 2);
free(vname);
}
@@ -1784,7 +1847,8 @@ print_import_config(const char *name, nvlist_t *nv, in
&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],
+ cb->cb_name_flags);
(void) printf("\t %s\n", vname);
free(vname);
}
@@ -1794,7 +1858,8 @@ print_import_config(const char *name, nvlist_t *nv, in
&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],
+ cb->cb_name_flags);
(void) printf("\t %s\n", vname);
free(vname);
}
@@ -1802,39 +1867,62 @@ print_import_config(const char *name, nvlist_t *nv, in
}
/*
- * Print log vdevs.
- * Logs are recorded as top level vdevs in the main pool child array
- * but with "is_log" set to 1. We use either print_status_config() or
- * print_import_config() to print the top level logs then any log
- * children (eg mirrored slogs) are printed recursively - which
- * works because only the top level vdev is marked "is_log"
+ * Print specialized class vdevs.
+ *
+ * These are recorded as top level vdevs in the main pool child array
+ * but with "is_log" set to 1 or an "alloc_bias" string. We use either
+ * print_status_config() or print_import_config() to print the top level
+ * class vdevs then any of their children (eg mirrored slogs) are printed
+ * recursively - which works because only the top level vdev is marked.
*/
static void
-print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
+print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv,
+ const char *class)
{
uint_t c, children;
nvlist_t **child;
+ boolean_t printed = B_FALSE;
+ assert(zhp != NULL || !cb->cb_verbose);
+
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
&children) != 0)
return;
- (void) printf(gettext("\tlogs\n"));
-
for (c = 0; c < children; c++) {
uint64_t is_log = B_FALSE;
- char *name;
+ char *bias = NULL;
+ char *type = NULL;
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
&is_log);
- if (!is_log)
+
+ if (is_log) {
+ bias = VDEV_ALLOC_CLASS_LOGS;
+ } else {
+ (void) nvlist_lookup_string(child[c],
+ ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
+ (void) nvlist_lookup_string(child[c],
+ ZPOOL_CONFIG_TYPE, &type);
+ }
+
+ if (bias == NULL || strcmp(bias, class) != 0)
continue;
- name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
- if (verbose)
- print_status_config(zhp, name, child[c], namewidth,
- 2, B_FALSE);
+ if (!is_log && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
+ continue;
+
+ if (!printed) {
+ (void) printf("\t%s\t\n", gettext(class));
+ printed = B_TRUE;
+ }
+
+ char *name = zpool_vdev_name(g_zfs, zhp, child[c],
+ cb->cb_name_flags | VDEV_NAME_TYPE_ID);
+ if (cb->cb_print_status)
+ print_status_config(zhp, cb, name, child[c], 2,
+ B_FALSE);
else
- print_import_config(name, child[c], namewidth, 2);
+ print_import_config(cb, name, child[c], 2);
free(name);
}
}
@@ -1856,8 +1944,8 @@ show_import(nvlist_t *config)
int reason;
const char *health;
uint_t vsc;
- int namewidth;
char *comment;
+ status_cbdata_t cb = { 0 };
verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
@@ -2083,14 +2171,16 @@ show_import(nvlist_t *config)
(void) printf(gettext(" config:\n\n"));
- namewidth = max_width(NULL, nvroot, 0, 0);
- if (namewidth < 10)
- namewidth = 10;
+ cb.cb_namewidth = max_width(NULL, nvroot, 0, 0, 0);
+ if (cb.cb_namewidth < 10)
+ cb.cb_namewidth = 10;
- print_import_config(name, nvroot, namewidth, 0);
- if (num_logs(nvroot) > 0)
- print_logs(NULL, nvroot, namewidth, B_FALSE);
+ print_import_config(&cb, name, nvroot, 0);
+ print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_DEDUP);
+ print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_SPECIAL);
+ print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS);
+
if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
(void) printf(gettext("\n\tAdditional devices are known to "
"be part of this pool, though their\n\texact "
@@ -2751,8 +2841,10 @@ zpool_do_sync(int argc, char **argv)
typedef struct iostat_cbdata {
boolean_t cb_verbose;
+ int cb_name_flags;
int cb_namewidth;
int cb_iteration;
+ boolean_t cb_scripted;
zpool_list_t *cb_list;
} iostat_cbdata_t;
@@ -2788,12 +2880,20 @@ print_one_stat(uint64_t value)
(void) printf(" %5s", buf);
}
+static const char *class_name[] = {
+ VDEV_ALLOC_BIAS_DEDUP,
+ VDEV_ALLOC_BIAS_SPECIAL,
+ VDEV_ALLOC_CLASS_LOGS
+};
+
/*
* Print out all the statistics for the given vdev. This can either be the
* toplevel configuration, or called recursively. If 'name' is NULL, then this
* is a verbose output, and we don't want to display the toplevel pool stats.
+ *
+ * Returns the number of stat lines printed.
*/
-void
+static unsigned int
print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
{
@@ -2801,12 +2901,13 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name
uint_t c, children;
vdev_stat_t *oldvs, *newvs;
vdev_stat_t zerovs = { 0 };
+ char *vname;
+ int ret = 0;
uint64_t tdelta;
double scale;
- char *vname;
if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
- return;
+ return (ret);
if (oldnv != NULL) {
verify(nvlist_lookup_uint64_array(oldnv,
@@ -2854,16 +2955,19 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name
(void) printf("\n");
if (!cb->cb_verbose)
- return;
+ return (ret);
if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
&newchild, &children) != 0)
- return;
+ return (ret);
if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
&oldchild, &c) != 0)
- return;
+ return (ret);
+ /*
+ * print normal top-level devices
+ */
for (c = 0; c < children; c++) {
uint64_t ishole = B_FALSE, islog = B_FALSE;
@@ -2876,33 +2980,45 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name
if (ishole || islog)
continue;
- vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
+ if (nvlist_exists(newchild[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
+ continue;
+
+ 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);
}
/*
- * Log device section
+ * print all other top-level devices
*/
-
- if (num_logs(newnv) > 0) {
- (void) printf("%-*s - - - - - "
- "-\n", cb->cb_namewidth, "logs");
-
+ for (uint_t n = 0; n < 3; n++) {
for (c = 0; c < children; c++) {
uint64_t islog = B_FALSE;
+ char *bias = NULL;
+ char *type = NULL;
+
(void) nvlist_lookup_uint64(newchild[c],
ZPOOL_CONFIG_IS_LOG, &islog);
-
if (islog) {
- vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
- B_FALSE);
- print_vdev_stats(zhp, vname, oldnv ?
- oldchild[c] : NULL, newchild[c],
- cb, depth + 2);
- free(vname);
+ bias = VDEV_ALLOC_CLASS_LOGS;
+ } else {
+ (void) nvlist_lookup_string(newchild[c],
+ ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
+ (void) nvlist_lookup_string(newchild[c],
+ ZPOOL_CONFIG_TYPE, &type);
}
+ if (bias == NULL || strcmp(bias, class_name[n]) != 0)
+ continue;
+ if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
+ continue;
+
+ vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
+ cb->cb_name_flags);
+ ret += print_vdev_stats(zhp, vname, oldnv ?
+ oldchild[c] : NULL, newchild[c], cb, depth + 2);
+ free(vname);
}
}
@@ -2912,23 +3028,25 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name
*/
if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
&newchild, &children) != 0)
- return;
+ return (ret);
if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
&oldchild, &c) != 0)
- return;
+ return (ret);
if (children > 0) {
(void) printf("%-*s - - - - - "
"-\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);
}
}
+
+ return (ret);
}
static int
@@ -2997,7 +3115,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);
}
/*
@@ -3095,8 +3213,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
*
@@ -3115,11 +3236,23 @@ zpool_do_iostat(int argc, char **argv)
unsigned long interval = 0, count = 0;
zpool_list_t *list;
boolean_t verbose = B_FALSE;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-vendor
mailing list