aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/cmd')
-rw-r--r--sys/contrib/openzfs/cmd/raidz_test/raidz_test.c1
-rw-r--r--sys/contrib/openzfs/cmd/zdb/zdb.c222
-rw-r--r--sys/contrib/openzfs/cmd/zfs/zfs_main.c46
-rw-r--r--sys/contrib/openzfs/cmd/zfs/zfs_project.c36
-rw-r--r--sys/contrib/openzfs/cmd/zhack.c135
-rw-r--r--sys/contrib/openzfs/cmd/zinject/zinject.c81
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_iter.c118
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_main.c643
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_util.h3
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_vdev.c98
-rw-r--r--sys/contrib/openzfs/cmd/zstream/zstream_redup.c4
-rw-r--r--sys/contrib/openzfs/cmd/ztest.c57
12 files changed, 945 insertions, 499 deletions
diff --git a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c
index cf3e123c6090..4839e909e4f7 100644
--- a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c
+++ b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c
@@ -33,6 +33,7 @@
#include <sys/vdev_raidz_impl.h>
#include <assert.h>
#include <stdio.h>
+#include <libzpool.h>
#include "raidz_test.h"
static int *rand_data;
diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c
index 70096b809656..09e144f66c68 100644
--- a/sys/contrib/openzfs/cmd/zdb/zdb.c
+++ b/sys/contrib/openzfs/cmd/zdb/zdb.c
@@ -89,6 +89,7 @@
#include <sys/zstd/zstd.h>
#include <sys/backtrace.h>
+#include <libzpool.h>
#include <libnvpair.h>
#include <libzutil.h>
#include <libzfs_core.h>
@@ -106,11 +107,15 @@ extern boolean_t spa_mode_readable_spacemaps;
extern uint_t zfs_reconstruct_indirect_combinations_max;
extern uint_t zfs_btree_verify_intensity;
+enum {
+ ARG_ALLOCATED = 256,
+ ARG_BLOCK_BIN_MODE,
+ ARG_BLOCK_CLASSES,
+};
+
static const char cmdname[] = "zdb";
uint8_t dump_opt[512];
-#define ALLOCATED_OPT 256
-
typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
static uint64_t *zopt_metaslab = NULL;
@@ -131,6 +136,20 @@ static objset_t *os;
static boolean_t kernel_init_done;
static boolean_t corruption_found = B_FALSE;
+static enum {
+ BIN_AUTO = 0,
+ BIN_PSIZE,
+ BIN_LSIZE,
+ BIN_ASIZE,
+} block_bin_mode = BIN_AUTO;
+
+static enum {
+ CLASS_NORMAL = 1 << 1,
+ CLASS_SPECIAL = 1 << 2,
+ CLASS_DEDUP = 1 << 3,
+ CLASS_OTHER = 1 << 4,
+} block_classes = 0;
+
static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *,
boolean_t);
static void mos_obj_refd(uint64_t);
@@ -385,7 +404,7 @@ verify_livelist_allocs(metaslab_verify_t *mv, uint64_t txg,
sublivelist_verify_block_t svb = {{{0}}};
DVA_SET_VDEV(&svb.svb_dva, mv->mv_vdid);
DVA_SET_OFFSET(&svb.svb_dva, offset);
- DVA_SET_ASIZE(&svb.svb_dva, size);
+ DVA_SET_ASIZE(&svb.svb_dva, 0);
zfs_btree_index_t where;
uint64_t end_offset = offset + size;
@@ -749,6 +768,12 @@ usage(void)
(void) fprintf(stderr, " Options to control amount of output:\n");
(void) fprintf(stderr, " -b --block-stats "
"block statistics\n");
+ (void) fprintf(stderr, " --bin=(lsize|psize|asize) "
+ "bin blocks based on this size in all three columns\n");
+ (void) fprintf(stderr,
+ " --class=(normal|special|dedup|other)[,...]\n"
+ " only consider blocks from "
+ "these allocation classes\n");
(void) fprintf(stderr, " -B --backup "
"backup stream\n");
(void) fprintf(stderr, " -c --checksum "
@@ -1694,7 +1719,7 @@ dump_metaslab(metaslab_t *msp)
(u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start,
(u_longlong_t)space_map_object(sm), freebuf);
- if (dump_opt[ALLOCATED_OPT] ||
+ if (dump_opt[ARG_ALLOCATED] ||
(dump_opt['m'] > 2 && !dump_opt['L'])) {
mutex_enter(&msp->ms_lock);
VERIFY0(metaslab_load(msp));
@@ -1705,7 +1730,7 @@ dump_metaslab(metaslab_t *msp)
dump_metaslab_stats(msp);
}
- if (dump_opt[ALLOCATED_OPT]) {
+ if (dump_opt[ARG_ALLOCATED]) {
uint64_t off = msp->ms_start;
zfs_range_tree_walk(msp->ms_allocatable, dump_allocated,
&off);
@@ -1726,7 +1751,7 @@ dump_metaslab(metaslab_t *msp)
SPACE_MAP_HISTOGRAM_SIZE, sm->sm_shift);
}
- if (dump_opt[ALLOCATED_OPT] ||
+ if (dump_opt[ARG_ALLOCATED] ||
(dump_opt['m'] > 2 && !dump_opt['L'])) {
metaslab_unload(msp);
mutex_exit(&msp->ms_lock);
@@ -3301,6 +3326,7 @@ zdb_derive_key(dsl_dir_t *dd, uint8_t *key_out)
uint64_t keyformat, salt, iters;
int i;
unsigned char c;
+ FILE *f;
VERIFY0(zap_lookup(dd->dd_pool->dp_meta_objset, dd->dd_crypto_obj,
zfs_prop_to_name(ZFS_PROP_KEYFORMAT), sizeof (uint64_t),
@@ -3333,6 +3359,25 @@ zdb_derive_key(dsl_dir_t *dd, uint8_t *key_out)
break;
+ case ZFS_KEYFORMAT_RAW:
+ if ((f = fopen(key_material, "r")) == NULL)
+ return (B_FALSE);
+
+ if (fread(key_out, 1, WRAPPING_KEY_LEN, f) !=
+ WRAPPING_KEY_LEN) {
+ (void) fclose(f);
+ return (B_FALSE);
+ }
+
+ /* Check the key length */
+ if (fgetc(f) != EOF) {
+ (void) fclose(f);
+ return (B_FALSE);
+ }
+
+ (void) fclose(f);
+ break;
+
default:
fatal("no support for key format %u\n",
(unsigned int) keyformat);
@@ -5794,6 +5839,34 @@ dump_size_histograms(zdb_cb_t *zcb)
(void) printf("\nBlock Size Histogram\n");
+ switch (block_bin_mode) {
+ case BIN_PSIZE:
+ printf("(note: all categories are binned by %s)\n", "psize");
+ break;
+ case BIN_LSIZE:
+ printf("(note: all categories are binned by %s)\n", "lsize");
+ break;
+ case BIN_ASIZE:
+ printf("(note: all categories are binned by %s)\n", "asize");
+ break;
+ default:
+ printf("(note: all categories are binned separately)\n");
+ break;
+ }
+ if (block_classes != 0) {
+ char buf[256] = "";
+ if (block_classes & CLASS_NORMAL)
+ strlcat(buf, "\"normal\", ", sizeof (buf));
+ if (block_classes & CLASS_SPECIAL)
+ strlcat(buf, "\"special\", ", sizeof (buf));
+ if (block_classes & CLASS_DEDUP)
+ strlcat(buf, "\"dedup\", ", sizeof (buf));
+ if (block_classes & CLASS_OTHER)
+ strlcat(buf, "\"other\", ", sizeof (buf));
+ buf[strlen(buf)-2] = '\0';
+ printf("(note: only blocks in these classes are counted: %s)\n",
+ buf);
+ }
/*
* Print the first line titles
*/
@@ -6142,29 +6215,85 @@ skipped:
[BPE_GET_PSIZE(bp)]++;
return;
}
+
+ if (block_classes != 0) {
+ spa_config_enter(zcb->zcb_spa, SCL_CONFIG, FTAG, RW_READER);
+
+ uint64_t vdev = DVA_GET_VDEV(&bp->blk_dva[0]);
+ uint64_t offset = DVA_GET_OFFSET(&bp->blk_dva[0]);
+ vdev_t *vd = vdev_lookup_top(zcb->zcb_spa, vdev);
+ ASSERT(vd != NULL);
+ metaslab_t *ms = vd->vdev_ms[offset >> vd->vdev_ms_shift];
+ ASSERT(ms != NULL);
+ metaslab_group_t *mg = ms->ms_group;
+ ASSERT(mg != NULL);
+ metaslab_class_t *mc = mg->mg_class;
+ ASSERT(mc != NULL);
+
+ spa_config_exit(zcb->zcb_spa, SCL_CONFIG, FTAG);
+
+ int class;
+ if (mc == spa_normal_class(zcb->zcb_spa)) {
+ class = CLASS_NORMAL;
+ } else if (mc == spa_special_class(zcb->zcb_spa)) {
+ class = CLASS_SPECIAL;
+ } else if (mc == spa_dedup_class(zcb->zcb_spa)) {
+ class = CLASS_DEDUP;
+ } else {
+ class = CLASS_OTHER;
+ }
+
+ if (!(block_classes & class)) {
+ goto hist_skipped;
+ }
+ }
+
/*
* The binning histogram bins by powers of two up to
* SPA_MAXBLOCKSIZE rather than creating bins for
* every possible blocksize found in the pool.
*/
- int bin = highbit64(BP_GET_PSIZE(bp)) - 1;
+ int bin;
+
+ /*
+ * Binning strategy: each bin includes blocks up to and including
+ * the given size (excluding blocks that fit into the previous bin).
+ * This way, the "4K" bin includes blocks within the (2K; 4K] range.
+ */
+#define BIN(size) (highbit64((size) - 1))
+
+ switch (block_bin_mode) {
+ case BIN_PSIZE: bin = BIN(BP_GET_PSIZE(bp)); break;
+ case BIN_LSIZE: bin = BIN(BP_GET_LSIZE(bp)); break;
+ case BIN_ASIZE: bin = BIN(BP_GET_ASIZE(bp)); break;
+ case BIN_AUTO: break;
+ default: PANIC("bad block_bin_mode"); abort();
+ }
+
+ if (block_bin_mode == BIN_AUTO)
+ bin = BIN(BP_GET_PSIZE(bp));
zcb->zcb_psize_count[bin]++;
zcb->zcb_psize_len[bin] += BP_GET_PSIZE(bp);
zcb->zcb_psize_total += BP_GET_PSIZE(bp);
- bin = highbit64(BP_GET_LSIZE(bp)) - 1;
+ if (block_bin_mode == BIN_AUTO)
+ bin = BIN(BP_GET_LSIZE(bp));
zcb->zcb_lsize_count[bin]++;
zcb->zcb_lsize_len[bin] += BP_GET_LSIZE(bp);
zcb->zcb_lsize_total += BP_GET_LSIZE(bp);
- bin = highbit64(BP_GET_ASIZE(bp)) - 1;
+ if (block_bin_mode == BIN_AUTO)
+ bin = BIN(BP_GET_ASIZE(bp));
zcb->zcb_asize_count[bin]++;
zcb->zcb_asize_len[bin] += BP_GET_ASIZE(bp);
zcb->zcb_asize_total += BP_GET_ASIZE(bp);
+#undef BIN
+
+hist_skipped:
if (!do_claim)
return;
@@ -7771,11 +7900,11 @@ zdb_set_skip_mmp(char *target)
* Disable the activity check to allow examination of
* active pools.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if ((spa = spa_lookup(target)) != NULL) {
spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
#define BOGUS_SUFFIX "_CHECKPOINTED_UNIVERSE"
@@ -9406,7 +9535,11 @@ main(int argc, char **argv)
{"livelist", no_argument, NULL, 'y'},
{"zstd-headers", no_argument, NULL, 'Z'},
{"allocated-map", no_argument, NULL,
- ALLOCATED_OPT},
+ ARG_ALLOCATED},
+ {"bin", required_argument, NULL,
+ ARG_BLOCK_BIN_MODE},
+ {"class", required_argument, NULL,
+ ARG_BLOCK_CLASSES},
{0, 0, 0, 0}
};
@@ -9437,7 +9570,7 @@ main(int argc, char **argv)
case 'u':
case 'y':
case 'Z':
- case ALLOCATED_OPT:
+ case ARG_ALLOCATED:
dump_opt[c]++;
dump_all = 0;
break;
@@ -9520,6 +9653,59 @@ main(int argc, char **argv)
case 'x':
vn_dumpdir = optarg;
break;
+ case ARG_BLOCK_BIN_MODE:
+ if (strcmp(optarg, "lsize") == 0) {
+ block_bin_mode = BIN_LSIZE;
+ } else if (strcmp(optarg, "psize") == 0) {
+ block_bin_mode = BIN_PSIZE;
+ } else if (strcmp(optarg, "asize") == 0) {
+ block_bin_mode = BIN_ASIZE;
+ } else {
+ (void) fprintf(stderr,
+ "--bin=\"%s\" must be one of \"lsize\", "
+ "\"psize\" or \"asize\"\n", optarg);
+ usage();
+ }
+ break;
+
+ case ARG_BLOCK_CLASSES: {
+ char *buf = strdup(optarg), *tok = buf, *next,
+ *save = NULL;
+
+ while ((next = strtok_r(tok, ",", &save)) != NULL) {
+ tok = NULL;
+
+ if (strcmp(next, "normal") == 0) {
+ block_classes |= CLASS_NORMAL;
+ } else if (strcmp(next, "special") == 0) {
+ block_classes |= CLASS_SPECIAL;
+ } else if (strcmp(next, "dedup") == 0) {
+ block_classes |= CLASS_DEDUP;
+ } else if (strcmp(next, "other") == 0) {
+ block_classes |= CLASS_OTHER;
+ } else {
+ (void) fprintf(stderr,
+ "--class=\"%s\" must be a "
+ "comma-separated list of either "
+ "\"normal\", \"special\", "
+ "\"asize\" or \"other\"; "
+ "got \"%s\"\n",
+ optarg, next);
+ usage();
+ }
+ }
+
+ if (block_classes == 0) {
+ (void) fprintf(stderr,
+ "--class= must be a comma-separated "
+ "list of either \"normal\", \"special\", "
+ "\"asize\" or \"other\"; got empty\n");
+ usage();
+ }
+
+ free(buf);
+ break;
+ }
default:
usage();
break;
@@ -9562,6 +9748,9 @@ main(int argc, char **argv)
*/
spa_mode_readable_spacemaps = B_TRUE;
+ libspl_set_assert_ok((dump_opt['A'] == 1) || (dump_opt['A'] > 2));
+ zfs_recover = (dump_opt['A'] > 1);
+
if (dump_all)
verbose = MAX(verbose, 1);
@@ -9572,9 +9761,6 @@ main(int argc, char **argv)
dump_opt[c] += verbose;
}
- libspl_set_assert_ok((dump_opt['A'] == 1) || (dump_opt['A'] > 2));
- zfs_recover = (dump_opt['A'] > 1);
-
argc -= optind;
argv += optind;
if (argc < 2 && dump_opt['R'])
@@ -9837,13 +10023,13 @@ main(int argc, char **argv)
* try opening the pool after clearing the
* log state.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if ((spa = spa_lookup(target)) != NULL &&
spa->spa_log_state == SPA_LOG_MISSING) {
spa->spa_log_state = SPA_LOG_CLEAR;
error = 0;
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
if (!error) {
error = spa_open_rewind(target, &spa,
diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_main.c b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
index f7a627a2fee6..ccdd5ffef8e6 100644
--- a/sys/contrib/openzfs/cmd/zfs/zfs_main.c
+++ b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
@@ -914,7 +914,11 @@ zfs_do_clone(int argc, char **argv)
log_history = B_FALSE;
}
- ret = zfs_mount_and_share(g_zfs, argv[1], ZFS_TYPE_DATASET);
+ /*
+ * Dataset cloned successfully, mount/share failures are
+ * non-fatal.
+ */
+ (void) zfs_mount_and_share(g_zfs, argv[1], ZFS_TYPE_DATASET);
}
zfs_close(zhp);
@@ -930,19 +934,15 @@ usage:
}
/*
- * Return a default volblocksize for the pool which always uses more than
- * half of the data sectors. This primarily applies to dRAID which always
- * writes full stripe widths.
+ * Calculate the minimum allocation size based on the top-level vdevs.
*/
static uint64_t
-default_volblocksize(zpool_handle_t *zhp, nvlist_t *props)
+calculate_volblocksize(nvlist_t *config)
{
- uint64_t volblocksize, asize = SPA_MINBLOCKSIZE;
+ uint64_t asize = SPA_MINBLOCKSIZE;
nvlist_t *tree, **vdevs;
uint_t nvdevs;
- nvlist_t *config = zpool_get_config(zhp, NULL);
-
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree) != 0 ||
nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN,
&vdevs, &nvdevs) != 0) {
@@ -973,6 +973,24 @@ default_volblocksize(zpool_handle_t *zhp, nvlist_t *props)
}
}
+ return (asize);
+}
+
+/*
+ * Return a default volblocksize for the pool which always uses more than
+ * half of the data sectors. This primarily applies to dRAID which always
+ * writes full stripe widths.
+ */
+static uint64_t
+default_volblocksize(zpool_handle_t *zhp, nvlist_t *props)
+{
+ uint64_t volblocksize, asize = SPA_MINBLOCKSIZE;
+
+ nvlist_t *config = zpool_get_config(zhp, NULL);
+
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_MAX_ALLOC, &asize) != 0)
+ asize = calculate_volblocksize(config);
+
/*
* Calculate the target volblocksize such that more than half
* of the asize is used. The following table is for 4k sectors.
@@ -1319,7 +1337,9 @@ zfs_do_create(int argc, char **argv)
goto error;
}
- ret = zfs_mount_and_share(g_zfs, argv[0], ZFS_TYPE_DATASET);
+ /* Dataset created successfully, mount/share failures are non-fatal */
+ ret = 0;
+ (void) zfs_mount_and_share(g_zfs, argv[0], ZFS_TYPE_DATASET);
error:
nvlist_free(props);
return (ret);
@@ -6864,17 +6884,17 @@ print_holds(boolean_t scripted, int nwidth, int tagwidth, nvlist_t *nvl,
if (scripted) {
if (parsable) {
- (void) printf("%s\t%s\t%ld\n", zname,
- tagname, (unsigned long)time);
+ (void) printf("%s\t%s\t%lld\n", zname,
+ tagname, (long long)time);
} else {
(void) printf("%s\t%s\t%s\n", zname,
tagname, tsbuf);
}
} else {
if (parsable) {
- (void) printf("%-*s %-*s %ld\n",
+ (void) printf("%-*s %-*s %lld\n",
nwidth, zname, tagwidth,
- tagname, (unsigned long)time);
+ tagname, (long long)time);
} else {
(void) printf("%-*s %-*s %s\n",
nwidth, zname, tagwidth,
diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_project.c b/sys/contrib/openzfs/cmd/zfs/zfs_project.c
index fbf5e6cbdc68..8925e6672bef 100644
--- a/sys/contrib/openzfs/cmd/zfs/zfs_project.c
+++ b/sys/contrib/openzfs/cmd/zfs/zfs_project.c
@@ -145,11 +145,11 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
switch (zpc->zpc_op) {
case ZFS_PROJECT_OP_LIST:
(void) printf("%5u %c %s\n", fsx.fsx_projid,
- (fsx.fsx_xflags & ZFS_PROJINHERIT_FL) ? 'P' : '-', name);
+ (fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) ? 'P' : '-', name);
goto out;
case ZFS_PROJECT_OP_CHECK:
if (fsx.fsx_projid == zpc->zpc_expected_projid &&
- fsx.fsx_xflags & ZFS_PROJINHERIT_FL)
+ fsx.fsx_xflags & FS_XFLAG_PROJINHERIT)
goto out;
if (!zpc->zpc_newline) {
@@ -164,29 +164,30 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
"(%u/%u)\n", name, fsx.fsx_projid,
(uint32_t)zpc->zpc_expected_projid);
- if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL))
+ if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT))
(void) printf("%s - project inherit flag is not set\n",
name);
goto out;
case ZFS_PROJECT_OP_CLEAR:
- if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL) &&
+ if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) &&
(zpc->zpc_keep_projid ||
fsx.fsx_projid == ZFS_DEFAULT_PROJID))
goto out;
- fsx.fsx_xflags &= ~ZFS_PROJINHERIT_FL;
+ fsx.fsx_xflags &= ~FS_XFLAG_PROJINHERIT;
if (!zpc->zpc_keep_projid)
fsx.fsx_projid = ZFS_DEFAULT_PROJID;
break;
case ZFS_PROJECT_OP_SET:
if (fsx.fsx_projid == zpc->zpc_expected_projid &&
- (!zpc->zpc_set_flag || fsx.fsx_xflags & ZFS_PROJINHERIT_FL))
+ (!zpc->zpc_set_flag ||
+ fsx.fsx_xflags & FS_XFLAG_PROJINHERIT))
goto out;
fsx.fsx_projid = zpc->zpc_expected_projid;
if (zpc->zpc_set_flag)
- fsx.fsx_xflags |= ZFS_PROJINHERIT_FL;
+ fsx.fsx_xflags |= FS_XFLAG_PROJINHERIT;
break;
default:
ASSERT(0);
@@ -194,11 +195,30 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
}
ret = ioctl(fd, ZFS_IOC_FSSETXATTR, &fsx);
- if (ret)
+ if (ret) {
(void) fprintf(stderr,
gettext("failed to set xattr for %s: %s\n"),
name, strerror(errno));
+ if (errno == ENOTSUP) {
+ char *kver = zfs_version_kernel();
+ /*
+ * Special case: a module/userspace version mismatch can
+ * return ENOTSUP due to us fixing the XFLAGs bits in
+ * #17884. In that case give a hint to the user that
+ * they should take action to make the versions match.
+ */
+ if (strcmp(kver, ZFS_META_ALIAS) != 0) {
+ fprintf(stderr,
+ gettext("Warning: The zfs module version "
+ "(%s) and userspace\nversion (%s) do not "
+ "match up. This may be the\ncause of the "
+ "\"Operation not supported\" error.\n"),
+ kver, ZFS_META_ALIAS);
+ }
+ }
+ }
+
out:
close(fd);
return (ret);
diff --git a/sys/contrib/openzfs/cmd/zhack.c b/sys/contrib/openzfs/cmd/zhack.c
index edf9dfa2cece..536e3880718c 100644
--- a/sys/contrib/openzfs/cmd/zhack.c
+++ b/sys/contrib/openzfs/cmd/zhack.c
@@ -55,6 +55,7 @@
#include <zfeature_common.h>
#include <libzutil.h>
#include <sys/metaslab_impl.h>
+#include <libzpool.h>
static importargs_t g_importargs;
static char *g_pool;
@@ -714,6 +715,23 @@ zhack_repair_read_label(const int fd, vdev_label_t *vl,
return (0);
}
+static int
+zhack_repair_get_byteswap(const zio_eck_t *vdev_eck, const int l, int *byteswap)
+{
+ if (vdev_eck->zec_magic == ZEC_MAGIC) {
+ *byteswap = B_FALSE;
+ } else if (vdev_eck->zec_magic == BSWAP_64((uint64_t)ZEC_MAGIC)) {
+ *byteswap = B_TRUE;
+ } else {
+ (void) fprintf(stderr, "error: label %d: "
+ "Expected the nvlist checksum magic number but instead got "
+ "0x%" PRIx64 "\n",
+ l, vdev_eck->zec_magic);
+ return (1);
+ }
+ return (0);
+}
+
static void
zhack_repair_calc_cksum(const int byteswap, void *data, const uint64_t offset,
const uint64_t abdsize, zio_eck_t *eck, zio_cksum_t *cksum)
@@ -740,33 +758,10 @@ zhack_repair_calc_cksum(const int byteswap, void *data, const uint64_t offset,
}
static int
-zhack_repair_check_label(uberblock_t *ub, const int l, const char **cfg_keys,
- const size_t cfg_keys_len, nvlist_t *cfg, nvlist_t *vdev_tree_cfg,
- uint64_t *ashift)
+zhack_repair_get_ashift(nvlist_t *cfg, const int l, uint64_t *ashift)
{
int err;
-
- if (ub->ub_txg != 0) {
- (void) fprintf(stderr,
- "error: label %d: UB TXG of 0 expected, but got %"
- PRIu64 "\n",
- l, ub->ub_txg);
- (void) fprintf(stderr, "It would appear the device was not "
- "properly removed.\n");
- return (1);
- }
-
- for (int i = 0; i < cfg_keys_len; i++) {
- uint64_t val;
- err = nvlist_lookup_uint64(cfg, cfg_keys[i], &val);
- if (err) {
- (void) fprintf(stderr,
- "error: label %d, %d: "
- "cannot find nvlist key %s\n",
- l, i, cfg_keys[i]);
- return (err);
- }
- }
+ nvlist_t *vdev_tree_cfg;
err = nvlist_lookup_nvlist(cfg,
ZPOOL_CONFIG_VDEV_TREE, &vdev_tree_cfg);
@@ -790,7 +785,7 @@ zhack_repair_check_label(uberblock_t *ub, const int l, const char **cfg_keys,
(void) fprintf(stderr,
"error: label %d: nvlist key %s is zero\n",
l, ZPOOL_CONFIG_ASHIFT);
- return (err);
+ return (1);
}
return (0);
@@ -805,30 +800,35 @@ zhack_repair_undetach(uberblock_t *ub, nvlist_t *cfg, const int l)
*/
if (BP_GET_LOGICAL_BIRTH(&ub->ub_rootbp) != 0) {
const uint64_t txg = BP_GET_LOGICAL_BIRTH(&ub->ub_rootbp);
+ int err;
+
ub->ub_txg = txg;
- if (nvlist_remove_all(cfg, ZPOOL_CONFIG_CREATE_TXG) != 0) {
+ err = nvlist_remove_all(cfg, ZPOOL_CONFIG_CREATE_TXG);
+ if (err) {
(void) fprintf(stderr,
"error: label %d: "
"Failed to remove pool creation TXG\n",
l);
- return (1);
+ return (err);
}
- if (nvlist_remove_all(cfg, ZPOOL_CONFIG_POOL_TXG) != 0) {
+ err = nvlist_remove_all(cfg, ZPOOL_CONFIG_POOL_TXG);
+ if (err) {
(void) fprintf(stderr,
"error: label %d: Failed to remove pool TXG to "
"be replaced.\n",
l);
- return (1);
+ return (err);
}
- if (nvlist_add_uint64(cfg, ZPOOL_CONFIG_POOL_TXG, txg) != 0) {
+ err = nvlist_add_uint64(cfg, ZPOOL_CONFIG_POOL_TXG, txg);
+ if (err) {
(void) fprintf(stderr,
"error: label %d: "
"Failed to add pool TXG of %" PRIu64 "\n",
l, txg);
- return (1);
+ return (err);
}
}
@@ -922,6 +922,7 @@ zhack_repair_test_cksum(const int byteswap, void *vdev_data,
BSWAP_64(ZEC_MAGIC) : ZEC_MAGIC;
const uint64_t actual_magic = vdev_eck->zec_magic;
int err = 0;
+
if (actual_magic != expected_magic) {
(void) fprintf(stderr, "error: label %d: "
"Expected "
@@ -943,6 +944,36 @@ zhack_repair_test_cksum(const int byteswap, void *vdev_data,
return (err);
}
+static int
+zhack_repair_unpack_cfg(vdev_label_t *vl, const int l, nvlist_t **cfg)
+{
+ const char *cfg_keys[] = { ZPOOL_CONFIG_VERSION,
+ ZPOOL_CONFIG_POOL_STATE, ZPOOL_CONFIG_GUID };
+ int err;
+
+ err = nvlist_unpack(vl->vl_vdev_phys.vp_nvlist,
+ VDEV_PHYS_SIZE - sizeof (zio_eck_t), cfg, 0);
+ if (err) {
+ (void) fprintf(stderr,
+ "error: cannot unpack nvlist label %d\n", l);
+ return (err);
+ }
+
+ for (int i = 0; i < ARRAY_SIZE(cfg_keys); i++) {
+ uint64_t val;
+ err = nvlist_lookup_uint64(*cfg, cfg_keys[i], &val);
+ if (err) {
+ (void) fprintf(stderr,
+ "error: label %d, %d: "
+ "cannot find nvlist key %s\n",
+ l, i, cfg_keys[i]);
+ return (err);
+ }
+ }
+
+ return (0);
+}
+
static void
zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
vdev_label_t *vl, const uint64_t label_offset, const int l,
@@ -956,10 +987,7 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
(zio_eck_t *)((char *)(vdev_data) + VDEV_PHYS_SIZE) - 1;
const uint64_t vdev_phys_offset =
label_offset + offsetof(vdev_label_t, vl_vdev_phys);
- const char *cfg_keys[] = { ZPOOL_CONFIG_VERSION,
- ZPOOL_CONFIG_POOL_STATE, ZPOOL_CONFIG_GUID };
nvlist_t *cfg;
- nvlist_t *vdev_tree_cfg = NULL;
uint64_t ashift;
int byteswap;
@@ -967,18 +995,9 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
if (err)
return;
- if (vdev_eck->zec_magic == 0) {
- (void) fprintf(stderr, "error: label %d: "
- "Expected the nvlist checksum magic number to not be zero"
- "\n",
- l);
- (void) fprintf(stderr, "There should already be a checksum "
- "for the label.\n");
+ err = zhack_repair_get_byteswap(vdev_eck, l, &byteswap);
+ if (err)
return;
- }
-
- byteswap =
- (vdev_eck->zec_magic == BSWAP_64((uint64_t)ZEC_MAGIC));
if (byteswap) {
byteswap_uint64_array(&vdev_eck->zec_cksum,
@@ -994,16 +1013,7 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
return;
}
- err = nvlist_unpack(vl->vl_vdev_phys.vp_nvlist,
- VDEV_PHYS_SIZE - sizeof (zio_eck_t), &cfg, 0);
- if (err) {
- (void) fprintf(stderr,
- "error: cannot unpack nvlist label %d\n", l);
- return;
- }
-
- err = zhack_repair_check_label(ub,
- l, cfg_keys, ARRAY_SIZE(cfg_keys), cfg, vdev_tree_cfg, &ashift);
+ err = zhack_repair_unpack_cfg(vl, l, &cfg);
if (err)
return;
@@ -1011,6 +1021,19 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
char *buf;
size_t buflen;
+ if (ub->ub_txg != 0) {
+ (void) fprintf(stderr,
+ "error: label %d: UB TXG of 0 expected, but got %"
+ PRIu64 "\n", l, ub->ub_txg);
+ (void) fprintf(stderr, "It would appear the device was "
+ "not properly detached.\n");
+ return;
+ }
+
+ err = zhack_repair_get_ashift(cfg, l, &ashift);
+ if (err)
+ return;
+
err = zhack_repair_undetach(ub, cfg, l);
if (err)
return;
diff --git a/sys/contrib/openzfs/cmd/zinject/zinject.c b/sys/contrib/openzfs/cmd/zinject/zinject.c
index 113797c878b9..c2f646f2567d 100644
--- a/sys/contrib/openzfs/cmd/zinject/zinject.c
+++ b/sys/contrib/openzfs/cmd/zinject/zinject.c
@@ -107,6 +107,8 @@
* zinject
* zinject <-a | -u pool>
* zinject -c <id|all>
+ * zinject -E <delay> [-a] [-m] [-f freq] [-l level] [-r range]
+ * [-T iotype] [-t type object | -b bookmark pool]
* zinject [-q] <-t type> [-f freq] [-u] [-a] [-m] [-e errno] [-l level]
* [-r range] <object>
* zinject [-f freq] [-a] [-m] [-u] -b objset:object:level:start:end pool
@@ -132,14 +134,18 @@
* The '-f' flag controls the frequency of errors injected, expressed as a
* real number percentage between 0.0001 and 100. The default is 100.
*
- * The this form is responsible for actually injecting the handler into the
+ * The <object> form is responsible for actually injecting the handler into the
* framework. It takes the arguments described above, translates them to the
* internal tuple using libzpool, and then issues an ioctl() to register the
* handler.
*
- * The final form can target a specific bookmark, regardless of whether a
+ * The '-b' option can target a specific bookmark, regardless of whether a
* human-readable interface has been designed. It allows developers to specify
* a particular block by number.
+ *
+ * The '-E' option injects pipeline ready stage delays for the given object or
+ * bookmark. The delay is specified in milliseconds, and it supports I/O type
+ * and range filters.
*/
#include <errno.h>
@@ -346,6 +352,13 @@ usage(void)
"\t\tsuch that the operation takes a minimum of supplied seconds\n"
"\t\tto complete.\n"
"\n"
+ "\tzinject -E <delay> [-a] [-m] [-f freq] [-l level] [-r range]\n"
+ "\t\t[-T iotype] [-t type object | -b bookmark pool]\n"
+ "\n"
+ "\t\tInject pipeline ready stage delays for the given object path\n"
+ "\t\t(data or dnode) or raw bookmark. The delay is specified in\n"
+ "\t\tmilliseconds.\n"
+ "\n"
"\tzinject -I [-s <seconds> | -g <txgs>] pool\n"
"\t\tCause the pool to stop writing blocks yet not\n"
"\t\treport errors for a duration. Simulates buggy hardware\n"
@@ -724,12 +737,15 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
if (quiet) {
(void) printf("%llu\n", (u_longlong_t)zc.zc_guid);
} else {
+ boolean_t show_object = B_FALSE;
+ boolean_t show_iotype = B_FALSE;
(void) printf("Added handler %llu with the following "
"properties:\n", (u_longlong_t)zc.zc_guid);
(void) printf(" pool: %s\n", pool);
if (record->zi_guid) {
(void) printf(" vdev: %llx\n",
(u_longlong_t)record->zi_guid);
+ show_iotype = B_TRUE;
} else if (record->zi_func[0] != '\0') {
(void) printf(" panic function: %s\n",
record->zi_func);
@@ -742,7 +758,18 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
} else if (record->zi_timer > 0) {
(void) printf(" timer: %lld ms\n",
(u_longlong_t)NSEC2MSEC(record->zi_timer));
+ if (record->zi_cmd == ZINJECT_DELAY_READY) {
+ show_object = B_TRUE;
+ show_iotype = B_TRUE;
+ }
} else {
+ show_object = B_TRUE;
+ }
+ if (show_iotype) {
+ (void) printf("iotype: %s\n",
+ iotype_to_str(record->zi_iotype));
+ }
+ if (show_object) {
(void) printf("objset: %llu\n",
(u_longlong_t)record->zi_objset);
(void) printf("object: %llu\n",
@@ -910,6 +937,7 @@ main(int argc, char **argv)
int ret;
int flags = 0;
uint32_t dvas = 0;
+ hrtime_t ready_delay = -1;
if ((g_zfs = libzfs_init()) == NULL) {
(void) fprintf(stderr, "%s\n", libzfs_error_init(errno));
@@ -940,7 +968,7 @@ main(int argc, char **argv)
}
while ((c = getopt(argc, argv,
- ":aA:b:C:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:P:")) != -1) {
+ ":aA:b:C:d:D:E:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:P:")) != -1) {
switch (c) {
case 'a':
flags |= ZINJECT_FLUSH_ARC;
@@ -1113,6 +1141,18 @@ main(int argc, char **argv)
case 'u':
flags |= ZINJECT_UNLOAD_SPA;
break;
+ case 'E':
+ ready_delay = MSEC2NSEC(strtol(optarg, &end, 10));
+ if (ready_delay <= 0 || *end != '\0') {
+ (void) fprintf(stderr, "invalid delay '%s': "
+ "must be a positive duration\n", optarg);
+ usage();
+ libzfs_fini(g_zfs);
+ return (1);
+ }
+ record.zi_cmd = ZINJECT_DELAY_READY;
+ record.zi_timer = ready_delay;
+ break;
case 'L':
if ((label = name_to_type(optarg)) == TYPE_INVAL &&
!LABEL_TYPE(type)) {
@@ -1150,7 +1190,7 @@ main(int argc, char **argv)
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED ||
- record.zi_freq > 0 || dvas != 0) {
+ record.zi_freq > 0 || dvas != 0 || ready_delay >= 0) {
(void) fprintf(stderr, "cancel (-c) incompatible with "
"any other options\n");
usage();
@@ -1186,7 +1226,7 @@ main(int argc, char **argv)
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED ||
- dvas != 0) {
+ dvas != 0 || ready_delay >= 0) {
(void) fprintf(stderr, "device (-d) incompatible with "
"data error injection\n");
usage();
@@ -1276,13 +1316,23 @@ main(int argc, char **argv)
return (1);
}
- record.zi_cmd = ZINJECT_DATA_FAULT;
+ if (record.zi_cmd == ZINJECT_UNINITIALIZED) {
+ record.zi_cmd = ZINJECT_DATA_FAULT;
+ if (!error)
+ error = EIO;
+ } else if (error != 0) {
+ (void) fprintf(stderr, "error type -e incompatible "
+ "with delay injection\n");
+ libzfs_fini(g_zfs);
+ return (1);
+ } else {
+ record.zi_iotype = io_type;
+ }
+
if (translate_raw(raw, &record) != 0) {
libzfs_fini(g_zfs);
return (1);
}
- if (!error)
- error = EIO;
} else if (record.zi_cmd == ZINJECT_PANIC) {
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0 || device != NULL || record.zi_freq > 0 ||
@@ -1410,6 +1460,13 @@ main(int argc, char **argv)
record.zi_dvas = dvas;
}
+ if (record.zi_cmd != ZINJECT_UNINITIALIZED && error != 0) {
+ (void) fprintf(stderr, "error type -e incompatible "
+ "with delay injection\n");
+ libzfs_fini(g_zfs);
+ return (1);
+ }
+
if (error == EACCES) {
if (type != TYPE_DATA) {
(void) fprintf(stderr, "decryption errors "
@@ -1425,8 +1482,12 @@ main(int argc, char **argv)
* not found.
*/
error = ECKSUM;
- } else {
+ } else if (record.zi_cmd == ZINJECT_UNINITIALIZED) {
record.zi_cmd = ZINJECT_DATA_FAULT;
+ if (!error)
+ error = EIO;
+ } else {
+ record.zi_iotype = io_type;
}
if (translate_record(type, argv[0], range, level, &record, pool,
@@ -1434,8 +1495,6 @@ main(int argc, char **argv)
libzfs_fini(g_zfs);
return (1);
}
- if (!error)
- error = EIO;
}
/*
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_iter.c b/sys/contrib/openzfs/cmd/zpool/zpool_iter.c
index 2eec9a95e24c..fef602736705 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_iter.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_iter.c
@@ -26,6 +26,7 @@
/*
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
+ * Copyright (c) 2025, Klara, Inc.
*/
#include <libintl.h>
@@ -52,7 +53,7 @@
typedef struct zpool_node {
zpool_handle_t *zn_handle;
uu_avl_node_t zn_avlnode;
- int zn_mark;
+ hrtime_t zn_last_refresh;
} zpool_node_t;
struct zpool_list {
@@ -62,6 +63,7 @@ struct zpool_list {
uu_avl_pool_t *zl_pool;
zprop_list_t **zl_proplist;
zfs_type_t zl_type;
+ hrtime_t zl_last_refresh;
};
static int
@@ -81,26 +83,30 @@ zpool_compare(const void *larg, const void *rarg, void *unused)
* of known pools.
*/
static int
-add_pool(zpool_handle_t *zhp, void *data)
+add_pool(zpool_handle_t *zhp, zpool_list_t *zlp)
{
- zpool_list_t *zlp = data;
- zpool_node_t *node = safe_malloc(sizeof (zpool_node_t));
+ zpool_node_t *node, *new = safe_malloc(sizeof (zpool_node_t));
uu_avl_index_t idx;
- node->zn_handle = zhp;
- uu_avl_node_init(node, &node->zn_avlnode, zlp->zl_pool);
- if (uu_avl_find(zlp->zl_avl, node, NULL, &idx) == NULL) {
+ new->zn_handle = zhp;
+ uu_avl_node_init(new, &new->zn_avlnode, zlp->zl_pool);
+
+ node = uu_avl_find(zlp->zl_avl, new, NULL, &idx);
+ if (node == NULL) {
if (zlp->zl_proplist &&
zpool_expand_proplist(zhp, zlp->zl_proplist,
zlp->zl_type, zlp->zl_literal) != 0) {
zpool_close(zhp);
- free(node);
+ free(new);
return (-1);
}
- uu_avl_insert(zlp->zl_avl, node, idx);
+ new->zn_last_refresh = zlp->zl_last_refresh;
+ uu_avl_insert(zlp->zl_avl, new, idx);
} else {
+ zpool_refresh_stats_from_handle(node->zn_handle, zhp);
+ node->zn_last_refresh = zlp->zl_last_refresh;
zpool_close(zhp);
- free(node);
+ free(new);
return (-1);
}
@@ -108,6 +114,18 @@ add_pool(zpool_handle_t *zhp, void *data)
}
/*
+ * add_pool(), but always returns 0. This allows zpool_iter() to continue
+ * even if a pool exists in the tree, or we fail to get the properties for
+ * a new one.
+ */
+static int
+add_pool_cb(zpool_handle_t *zhp, void *data)
+{
+ (void) add_pool(zhp, data);
+ return (0);
+}
+
+/*
* Create a list of pools based on the given arguments. If we're given no
* arguments, then iterate over all pools in the system and add them to the AVL
* tree. Otherwise, add only those pool explicitly specified on the command
@@ -135,9 +153,10 @@ pool_list_get(int argc, char **argv, zprop_list_t **proplist, zfs_type_t type,
zlp->zl_type = type;
zlp->zl_literal = literal;
+ zlp->zl_last_refresh = gethrtime();
if (argc == 0) {
- (void) zpool_iter(g_zfs, add_pool, zlp);
+ (void) zpool_iter(g_zfs, add_pool_cb, zlp);
zlp->zl_findall = B_TRUE;
} else {
int i;
@@ -159,15 +178,61 @@ pool_list_get(int argc, char **argv, zprop_list_t **proplist, zfs_type_t type,
}
/*
- * Search for any new pools, adding them to the list. We only add pools when no
- * options were given on the command line. Otherwise, we keep the list fixed as
- * those that were explicitly specified.
+ * Refresh the state of all pools on the list. Additionally, if no options were
+ * given on the command line, add any new pools and remove any that are no
+ * longer available.
*/
-void
-pool_list_update(zpool_list_t *zlp)
+int
+pool_list_refresh(zpool_list_t *zlp)
{
- if (zlp->zl_findall)
- (void) zpool_iter(g_zfs, add_pool, zlp);
+ zlp->zl_last_refresh = gethrtime();
+
+ if (!zlp->zl_findall) {
+ /*
+ * This list is a fixed list of pools, so we must not add
+ * or remove any. Just walk over them and refresh their
+ * state.
+ */
+ int navail = 0;
+ for (zpool_node_t *node = uu_avl_first(zlp->zl_avl);
+ node != NULL; node = uu_avl_next(zlp->zl_avl, node)) {
+ boolean_t missing;
+ zpool_refresh_stats(node->zn_handle, &missing);
+ navail += !missing;
+ node->zn_last_refresh = zlp->zl_last_refresh;
+ }
+ return (navail);
+ }
+
+ /* Search for any new pools and add them to the list. */
+ (void) zpool_iter(g_zfs, add_pool_cb, zlp);
+
+ /* Walk the list of existing pools, and update or remove them. */
+ zpool_node_t *node, *next;
+ for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next) {
+ next = uu_avl_next(zlp->zl_avl, node);
+
+ /*
+ * Skip any that were refreshed and are online; they were added
+ * by zpool_iter() and are already up to date.
+ */
+ if (node->zn_last_refresh == zlp->zl_last_refresh &&
+ zpool_get_state(node->zn_handle) != POOL_STATE_UNAVAIL)
+ continue;
+
+ /* Refresh and remove if necessary. */
+ boolean_t missing;
+ zpool_refresh_stats(node->zn_handle, &missing);
+ if (missing) {
+ uu_avl_remove(zlp->zl_avl, node);
+ zpool_close(node->zn_handle);
+ free(node);
+ } else {
+ node->zn_last_refresh = zlp->zl_last_refresh;
+ }
+ }
+
+ return (uu_avl_numnodes(zlp->zl_avl));
}
/*
@@ -191,23 +256,6 @@ pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func,
}
/*
- * Remove the given pool from the list. When running iostat, we want to remove
- * those pools that no longer exist.
- */
-void
-pool_list_remove(zpool_list_t *zlp, zpool_handle_t *zhp)
-{
- zpool_node_t search, *node;
-
- search.zn_handle = zhp;
- if ((node = uu_avl_find(zlp->zl_avl, &search, NULL, NULL)) != NULL) {
- uu_avl_remove(zlp->zl_avl, node);
- zpool_close(node->zn_handle);
- free(node);
- }
-}
-
-/*
* Free all the handles associated with this list.
*/
void
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
index 237e558da65b..b0e05aa2776a 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
@@ -33,7 +33,7 @@
* Copyright (c) 2017, Intel Corporation.
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
* Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
- * Copyright (c) 2021, 2023, Klara Inc.
+ * Copyright (c) 2021, 2023, 2025, Klara, Inc.
* Copyright (c) 2021, 2025 Hewlett Packard Enterprise Development LP.
*/
@@ -43,6 +43,7 @@
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
+#include <inttypes.h>
#include <libgen.h>
#include <libintl.h>
#include <libuutil.h>
@@ -51,6 +52,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#include <thread_pool.h>
#include <time.h>
#include <unistd.h>
@@ -456,7 +458,7 @@ get_usage(zpool_help_t idx)
"<pool> <vdev> ...\n"));
case HELP_ATTACH:
return (gettext("\tattach [-fsw] [-o property=value] "
- "<pool> <device> <new-device>\n"));
+ "<pool> <vdev> <new-device>\n"));
case HELP_CLEAR:
return (gettext("\tclear [[--power]|[-nF]] <pool> [device]\n"));
case HELP_CREATE:
@@ -494,8 +496,7 @@ get_usage(zpool_help_t idx)
"[--json-int, --json-pool-key-guid]] ...\n"
"\t [-T d|u] [pool] [interval [count]]\n"));
case HELP_PREFETCH:
- return (gettext("\tprefetch -t <type> [<type opts>] <pool>\n"
- "\t -t ddt <pool>\n"));
+ return (gettext("\tprefetch [-t <type>] <pool>\n"));
case HELP_OFFLINE:
return (gettext("\toffline [--power]|[[-f][-t]] <pool> "
"<device> ...\n"));
@@ -635,7 +636,7 @@ zpool_power_on_and_disk_wait(zpool_handle_t *zhp, char *vdev)
if (rc != 0)
return (rc);
- zpool_disk_wait(vdev_name_to_path(zhp, vdev));
+ (void) zpool_disk_wait(vdev_name_to_path(zhp, vdev));
return (0);
}
@@ -665,7 +666,7 @@ zpool_power_on_pool_and_wait_for_devices(zpool_handle_t *zhp)
*/
FOR_EACH_REAL_LEAF_VDEV(zhp, nv) {
path = fnvlist_lookup_string(nv, ZPOOL_CONFIG_PATH);
- zpool_disk_wait(path);
+ (void) zpool_disk_wait(path);
}
return (0);
@@ -848,7 +849,6 @@ zpool_do_initialize(int argc, char **argv)
if (argc < 1 && !initialize_all) {
(void) fprintf(stderr, gettext("missing pool name argument\n"));
usage(B_FALSE);
- return (-1);
}
if (wait && (cmd_type != POOL_INITIALIZE_START)) {
@@ -1039,9 +1039,10 @@ nice_num_str_nvlist(nvlist_t *item, const char *key, uint64_t value,
boolean_t literal, boolean_t as_int, int format)
{
char buf[256];
+
if (literal) {
if (!as_int)
- snprintf(buf, 256, "%llu", (u_longlong_t)value);
+ (void) snprintf(buf, 256, "%llu", (u_longlong_t)value);
} else {
switch (format) {
case ZFS_NICENUM_1024:
@@ -1087,7 +1088,7 @@ zpool_json_schema(int maj_v, int min_v)
nvlist_t *sch = fnvlist_alloc();
nvlist_t *ov = fnvlist_alloc();
- snprintf(cmd, MAX_CMD_LEN, "zpool %s", current_command->name);
+ (void) snprintf(cmd, MAX_CMD_LEN, "zpool %s", current_command->name);
fnvlist_add_string(ov, "command", cmd);
fnvlist_add_uint32(ov, "vers_major", maj_v);
fnvlist_add_uint32(ov, "vers_minor", min_v);
@@ -1118,12 +1119,12 @@ fill_pool_info(nvlist_t *list, zpool_handle_t *zhp, boolean_t addtype,
} else {
char value[ZFS_MAXPROPLEN];
if (guid) {
- snprintf(value, ZFS_MAXPROPLEN, "%llu",
+ (void) snprintf(value, ZFS_MAXPROPLEN, "%llu",
(u_longlong_t)guid);
fnvlist_add_string(list, ZPOOL_CONFIG_POOL_GUID, value);
}
if (txg) {
- snprintf(value, ZFS_MAXPROPLEN, "%llu",
+ (void) snprintf(value, ZFS_MAXPROPLEN, "%llu",
(u_longlong_t)txg);
fnvlist_add_string(list, ZPOOL_CONFIG_POOL_TXG, value);
}
@@ -1182,7 +1183,7 @@ fill_vdev_info(nvlist_t *list, zpool_handle_t *zhp, char *name,
fnvlist_add_uint64(list, "guid", guid);
} else {
char buf[ZFS_MAXPROPLEN];
- snprintf(buf, ZFS_MAXPROPLEN, "%llu",
+ (void) snprintf(buf, ZFS_MAXPROPLEN, "%llu",
(u_longlong_t)guid);
fnvlist_add_string(list, "guid", buf);
}
@@ -1764,7 +1765,7 @@ vdev_is_active(char *vdev_path)
return (1); /* cant open O_EXCL - disk is active */
}
- close(fd);
+ (void) close(fd);
return (0); /* disk is inactive in the pool */
}
@@ -2415,12 +2416,12 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
* So we serialize access here for 'zpool export -a' parallel case.
*/
if (cb->tpool != NULL)
- pthread_mutex_lock(&cb->mnttab_lock);
+ (void) pthread_mutex_lock(&cb->mnttab_lock);
int retval = zpool_disable_datasets(zhp, cb->force);
if (cb->tpool != NULL)
- pthread_mutex_unlock(&cb->mnttab_lock);
+ (void) pthread_mutex_unlock(&cb->mnttab_lock);
if (retval)
return (1);
@@ -2533,7 +2534,7 @@ zpool_do_export(int argc, char **argv)
cb.tpool = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
0, NULL);
- pthread_mutex_init(&cb.mnttab_lock, NULL);
+ (void) pthread_mutex_init(&cb.mnttab_lock, NULL);
/* Asynchronously call zpool_export_one using thread pool */
ret = for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
@@ -2651,7 +2652,7 @@ zpool_nvlist_cmd(vdev_cmd_data_list_t *vcdl, const char *pool, const char *path,
for (j = data->cols_cnt; j < data->lines_cnt; j++) {
if (data->lines[j]) {
- snprintf(tmp, 256, "extra_%d", k++);
+ (void) snprintf(tmp, 256, "extra_%d", k++);
fnvlist_add_string(item, tmp,
data->lines[j]);
}
@@ -2697,17 +2698,17 @@ zpool_print_cmd(vdev_cmd_data_list_t *vcdl, const char *pool, const char *path)
printf("%*s", vcdl->uniq_cols_width[j], val);
if (j < vcdl->uniq_cols_cnt - 1)
- fputs(" ", stdout);
+ (void) fputs(" ", stdout);
}
/* Print out any values that aren't in a column at the end */
for (j = data->cols_cnt; j < data->lines_cnt; j++) {
/* Did we have any columns? If so print a spacer. */
if (vcdl->uniq_cols_cnt > 0)
- fputs(" ", stdout);
+ (void) fputs(" ", stdout);
val = data->lines[j];
- fputs(val ?: "", stdout);
+ (void) fputs(val ?: "", stdout);
}
break;
}
@@ -2920,7 +2921,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
return;
}
- printf_color(health_str_to_color(state),
+ (void) printf_color(health_str_to_color(state),
"\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth,
name, state);
@@ -2938,26 +2939,26 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
scolor = ANSI_BLUE;
if (cb->cb_literal) {
- fputc(' ', stdout);
- printf_color(rcolor, "%5llu",
+ (void) fputc(' ', stdout);
+ (void) printf_color(rcolor, "%5llu",
(u_longlong_t)vs->vs_read_errors);
- fputc(' ', stdout);
- printf_color(wcolor, "%5llu",
+ (void) fputc(' ', stdout);
+ (void) printf_color(wcolor, "%5llu",
(u_longlong_t)vs->vs_write_errors);
- fputc(' ', stdout);
- printf_color(ccolor, "%5llu",
+ (void) fputc(' ', stdout);
+ (void) printf_color(ccolor, "%5llu",
(u_longlong_t)vs->vs_checksum_errors);
} else {
zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
zfs_nicenum(vs->vs_checksum_errors, cbuf,
sizeof (cbuf));
- fputc(' ', stdout);
- printf_color(rcolor, "%5s", rbuf);
- fputc(' ', stdout);
- printf_color(wcolor, "%5s", wbuf);
- fputc(' ', stdout);
- printf_color(ccolor, "%5s", cbuf);
+ (void) fputc(' ', stdout);
+ (void) printf_color(rcolor, "%5s", rbuf);
+ (void) fputc(' ', stdout);
+ (void) printf_color(wcolor, "%5s", wbuf);
+ (void) fputc(' ', stdout);
+ (void) printf_color(ccolor, "%5s", cbuf);
}
if (cb->cb_print_slow_ios) {
if (children == 0) {
@@ -2965,14 +2966,14 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
zfs_nicenum(vs->vs_slow_ios, rbuf,
sizeof (rbuf));
} else {
- snprintf(rbuf, sizeof (rbuf), "-");
+ (void) snprintf(rbuf, sizeof (rbuf), "-");
}
if (cb->cb_literal)
- printf_color(scolor, " %5llu",
+ (void) printf_color(scolor, " %5llu",
(u_longlong_t)vs->vs_slow_ios);
else
- printf_color(scolor, " %5s", rbuf);
+ (void) printf_color(scolor, " %5s", rbuf);
}
if (cb->cb_print_power) {
if (children == 0) {
@@ -2981,7 +2982,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
fnvlist_lookup_string(nv,
ZPOOL_CONFIG_PATH))) {
case 0:
- printf_color(ANSI_RED, " %5s",
+ (void) printf_color(ANSI_RED, " %5s",
gettext("off"));
break;
case 1:
@@ -3427,70 +3428,70 @@ show_import(nvlist_t *config, boolean_t report_error)
if (reason != ZPOOL_STATUS_OK) {
(void) printf("%s", indent);
- printf_color(ANSI_BOLD, gettext("status: "));
+ (void) printf_color(ANSI_BOLD, gettext("status: "));
}
switch (reason) {
case ZPOOL_STATUS_MISSING_DEV_R:
case ZPOOL_STATUS_MISSING_DEV_NR:
case ZPOOL_STATUS_BAD_GUID_SUM:
- printf_color(ANSI_YELLOW, gettext("One or more devices are "
- "missing from the system.\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("One or more devices "
+ "are missing from the system.\n"));
break;
case ZPOOL_STATUS_CORRUPT_LABEL_R:
case ZPOOL_STATUS_CORRUPT_LABEL_NR:
- printf_color(ANSI_YELLOW, gettext("One or more devices "
+ (void) printf_color(ANSI_YELLOW, gettext("One or more devices "
"contains corrupted data.\n"));
break;
case ZPOOL_STATUS_CORRUPT_DATA:
- printf_color(ANSI_YELLOW, gettext("The pool data is "
+ (void) printf_color(ANSI_YELLOW, gettext("The pool data is "
"corrupted.\n"));
break;
case ZPOOL_STATUS_OFFLINE_DEV:
- printf_color(ANSI_YELLOW, gettext("One or more devices "
+ (void) printf_color(ANSI_YELLOW, gettext("One or more devices "
"are offlined.\n"));
break;
case ZPOOL_STATUS_CORRUPT_POOL:
- printf_color(ANSI_YELLOW, gettext("The pool metadata is "
+ (void) printf_color(ANSI_YELLOW, gettext("The pool metadata is "
"corrupted.\n"));
break;
case ZPOOL_STATUS_VERSION_OLDER:
- printf_color(ANSI_YELLOW, gettext("The pool is formatted using "
- "a legacy on-disk version.\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("The pool is "
+ "formatted using a legacy on-disk version.\n"));
break;
case ZPOOL_STATUS_VERSION_NEWER:
- printf_color(ANSI_YELLOW, gettext("The pool is formatted using "
- "an incompatible version.\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("The pool is "
+ "formatted using an incompatible version.\n"));
break;
case ZPOOL_STATUS_FEAT_DISABLED:
- printf_color(ANSI_YELLOW, gettext("Some supported "
+ (void) printf_color(ANSI_YELLOW, gettext("Some supported "
"features are not enabled on the pool.\n"
"\t%s(Note that they may be intentionally disabled if the\n"
"\t%s'compatibility' property is set.)\n"), indent, indent);
break;
case ZPOOL_STATUS_COMPATIBILITY_ERR:
- printf_color(ANSI_YELLOW, gettext("Error reading or parsing "
- "the file(s) indicated by the 'compatibility'\n"
+ (void) printf_color(ANSI_YELLOW, gettext("Error reading or "
+ "parsing the file(s) indicated by the 'compatibility'\n"
"\t%sproperty.\n"), indent);
break;
case ZPOOL_STATUS_INCOMPATIBLE_FEAT:
- printf_color(ANSI_YELLOW, gettext("One or more features "
+ (void) printf_color(ANSI_YELLOW, gettext("One or more features "
"are enabled on the pool despite not being\n"
"\t%srequested by the 'compatibility' property.\n"),
indent);
break;
case ZPOOL_STATUS_UNSUP_FEAT_READ:
- printf_color(ANSI_YELLOW, gettext("The pool uses the following "
- "feature(s) not supported on this system:\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("The pool uses the "
+ "following feature(s) not supported on this system:\n"));
color_start(ANSI_YELLOW);
zpool_collect_unsup_feat(config, buf, 2048);
(void) printf("%s", buf);
@@ -3498,7 +3499,7 @@ show_import(nvlist_t *config, boolean_t report_error)
break;
case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
- printf_color(ANSI_YELLOW, gettext("The pool can only be "
+ (void) printf_color(ANSI_YELLOW, gettext("The pool can only be "
"accessed in read-only mode on this system. It\n"
"\t%scannot be accessed in read-write mode because it uses "
"the following\n"
@@ -3511,47 +3512,48 @@ show_import(nvlist_t *config, boolean_t report_error)
break;
case ZPOOL_STATUS_HOSTID_ACTIVE:
- printf_color(ANSI_YELLOW, gettext("The pool is currently "
- "imported by another system.\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("The pool is "
+ "currently imported by another system.\n"));
break;
case ZPOOL_STATUS_HOSTID_REQUIRED:
- printf_color(ANSI_YELLOW, gettext("The pool has the "
+ (void) printf_color(ANSI_YELLOW, gettext("The pool has the "
"multihost property on. It cannot\n"
"\t%sbe safely imported when the system hostid is not "
"set.\n"), indent);
break;
case ZPOOL_STATUS_HOSTID_MISMATCH:
- printf_color(ANSI_YELLOW, gettext("The pool was last accessed "
- "by another system.\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("The pool was last "
+ "accessed by another system.\n"));
break;
case ZPOOL_STATUS_FAULTED_DEV_R:
case ZPOOL_STATUS_FAULTED_DEV_NR:
- printf_color(ANSI_YELLOW, gettext("One or more devices are "
- "faulted.\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("One or more devices "
+ "are faulted.\n"));
break;
case ZPOOL_STATUS_BAD_LOG:
- printf_color(ANSI_YELLOW, gettext("An intent log record cannot "
- "be read.\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("An intent log record "
+ "cannot be read.\n"));
break;
case ZPOOL_STATUS_RESILVERING:
case ZPOOL_STATUS_REBUILDING:
- printf_color(ANSI_YELLOW, gettext("One or more devices were "
- "being resilvered.\n"));
+ (void) printf_color(ANSI_YELLOW, gettext("One or more devices "
+ "were being resilvered.\n"));
break;
case ZPOOL_STATUS_ERRATA:
- printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"),
+ (void) printf_color(ANSI_YELLOW,
+ gettext("Errata #%d detected.\n"),
errata);
break;
case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
- printf_color(ANSI_YELLOW, gettext("One or more devices are "
- "configured to use a non-native block size.\n"
+ (void) printf_color(ANSI_YELLOW, gettext("One or more devices "
+ "are configured to use a non-native block size.\n"
"\t%sExpect reduced performance.\n"), indent);
break;
@@ -4200,7 +4202,7 @@ zpool_do_checkpoint(int argc, char **argv)
#define CHECKPOINT_OPT 1024
/*
- * zpool prefetch <type> [<type opts>] <pool>
+ * zpool prefetch [-t <type>] <pool>
*
* Prefetchs a particular type of data in the specified pool.
*/
@@ -4245,20 +4247,27 @@ zpool_do_prefetch(int argc, char **argv)
poolname = argv[0];
- argc--;
- argv++;
-
- if (strcmp(typestr, "ddt") == 0) {
- type = ZPOOL_PREFETCH_DDT;
- } else {
- (void) fprintf(stderr, gettext("unsupported prefetch type\n"));
- usage(B_FALSE);
- }
-
if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
return (1);
- err = zpool_prefetch(zhp, type);
+ if (typestr == NULL) {
+ /* Prefetch all types */
+ err = zpool_prefetch(zhp, ZPOOL_PREFETCH_DDT);
+ if (err == 0)
+ err = zpool_prefetch(zhp, ZPOOL_PREFETCH_BRT);
+ } else {
+ if (strcmp(typestr, "ddt") == 0) {
+ type = ZPOOL_PREFETCH_DDT;
+ } else if (strcmp(typestr, "brt") == 0) {
+ type = ZPOOL_PREFETCH_BRT;
+ } else {
+ (void) fprintf(stderr,
+ gettext("unsupported prefetch type\n"));
+ zpool_close(zhp);
+ usage(B_FALSE);
+ }
+ err = zpool_prefetch(zhp, type);
+ }
zpool_close(zhp);
@@ -4916,7 +4925,8 @@ print_cmd_columns(vdev_cmd_data_list_t *vcdl, int use_dashes)
for (j = 0; j < vcdl->uniq_cols_width[i]; j++)
printf("-");
} else {
- printf_color(ANSI_BOLD, "%*s", vcdl->uniq_cols_width[i],
+ (void) printf_color(ANSI_BOLD, "%*s",
+ vcdl->uniq_cols_width[i],
vcdl->uniq_cols[i]);
}
}
@@ -5067,15 +5077,15 @@ print_iostat_header(iostat_cbdata_t *cb)
static void
print_stat_color(const char *statbuf, unsigned int column_size)
{
- fputs(" ", stdout);
+ (void) fputs(" ", stdout);
size_t len = strlen(statbuf);
while (len < column_size) {
- fputc(' ', stdout);
+ (void) fputc(' ', stdout);
column_size--;
}
if (*statbuf == '0') {
color_start(ANSI_GRAY);
- fputc('0', stdout);
+ (void) fputc('0', stdout);
} else {
for (; *statbuf; statbuf++) {
if (*statbuf == 'K') color_start(ANSI_GREEN);
@@ -5084,7 +5094,7 @@ print_stat_color(const char *statbuf, unsigned int column_size)
else if (*statbuf == 'T') color_start(ANSI_BOLD_BLUE);
else if (*statbuf == 'P') color_start(ANSI_MAGENTA);
else if (*statbuf == 'E') color_start(ANSI_CYAN);
- fputc(*statbuf, stdout);
+ (void) fputc(*statbuf, stdout);
if (--column_size <= 0)
break;
}
@@ -5761,24 +5771,6 @@ children:
return (ret);
}
-static int
-refresh_iostat(zpool_handle_t *zhp, void *data)
-{
- iostat_cbdata_t *cb = data;
- boolean_t missing;
-
- /*
- * If the pool has disappeared, remove it from the list and continue.
- */
- if (zpool_refresh_stats(zhp, &missing) != 0)
- return (-1);
-
- if (missing)
- pool_list_remove(cb->cb_list, zhp);
-
- return (0);
-}
-
/*
* Callback to print out the iostats for the given pool.
*/
@@ -6010,7 +6002,7 @@ get_stat_flags(zpool_list_t *list)
* get_stat_flags_cb() will lop off bits from "mask" until only the
* flags that are supported on all pools remain.
*/
- pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask);
+ (void) pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask);
return (mask);
}
@@ -6259,7 +6251,7 @@ print_zpool_dir_scripts(char *dirpath)
print_zpool_script_help(ent->d_name,
fullpath);
}
- closedir(dir);
+ (void) closedir(dir);
}
}
@@ -6359,15 +6351,14 @@ get_namewidth_iostat(zpool_handle_t *zhp, void *data)
* This command can be tricky because we want to be able to deal with pool
* creation/destruction as well as vdev configuration changes. The bulk of this
* processing is handled by the pool_list_* routines in zpool_iter.c. We rely
- * on pool_list_update() to detect the addition of new pools. Configuration
- * changes are all handled within libzfs.
+ * on pool_list_refresh() to detect the addition and removal of pools.
+ * Configuration changes are all handled within libzfs.
*/
int
zpool_do_iostat(int argc, char **argv)
{
int c;
int ret;
- int npools;
float interval = 0;
unsigned long count = 0;
zpool_list_t *list;
@@ -6520,7 +6511,6 @@ zpool_do_iostat(int argc, char **argv)
argv[0], &cb.cb_vdevs);
fprintf(stderr, "\n");
usage(B_FALSE);
- return (1);
}
} else {
/*
@@ -6563,7 +6553,6 @@ zpool_do_iostat(int argc, char **argv)
(void) fprintf(stderr,
gettext("[-r|-w] isn't allowed with [-c|-l|-q]\n"));
usage(B_FALSE);
- return (1);
}
if (l_histo && rq_histo) {
@@ -6571,7 +6560,6 @@ zpool_do_iostat(int argc, char **argv)
(void) fprintf(stderr,
gettext("Only one of [-r|-w] can be passed at a time\n"));
usage(B_FALSE);
- return (1);
}
/*
@@ -6618,10 +6606,24 @@ zpool_do_iostat(int argc, char **argv)
return (1);
}
+ int last_npools = 0;
for (;;) {
- if ((npools = pool_list_count(list)) == 0)
+ /*
+ * Refresh all pools in list, adding or removing pools as
+ * necessary.
+ */
+ int npools = pool_list_refresh(list);
+ if (npools == 0) {
(void) fprintf(stderr, gettext("no pools available\n"));
- else {
+ } else {
+ /*
+ * If the list of pools has changed since last time
+ * around, reset the iteration count to force the
+ * header to be redisplayed.
+ */
+ if (last_npools != npools)
+ cb.cb_iteration = 0;
+
/*
* If this is the first iteration and -y was supplied
* we skip any printing.
@@ -6630,15 +6632,6 @@ zpool_do_iostat(int argc, char **argv)
cb.cb_iteration == 0);
/*
- * Refresh all statistics. This is done as an
- * explicit step before calculating the maximum name
- * width, so that any * configuration changes are
- * properly accounted for.
- */
- (void) pool_list_iter(list, B_FALSE, refresh_iostat,
- &cb);
-
- /*
* Iterate over all pools to determine the maximum width
* for the pool / device name column across all pools.
*/
@@ -6691,10 +6684,11 @@ zpool_do_iostat(int argc, char **argv)
if (skip) {
(void) fflush(stdout);
(void) fsleep(interval);
+ last_npools = npools;
continue;
}
- pool_list_iter(list, B_FALSE, print_iostat, &cb);
+ (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
/*
* If there's more than one pool, and we're not in
@@ -6728,6 +6722,8 @@ zpool_do_iostat(int argc, char **argv)
(void) fflush(stdout);
(void) fsleep(interval);
+
+ last_npools = npools;
}
pool_list_free(list);
@@ -6907,7 +6903,7 @@ collect_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
uint64_t guid = fnvlist_lookup_uint64(
zpool_get_config(zhp, NULL),
ZPOOL_CONFIG_POOL_GUID);
- snprintf(pool_guid, 256, "%llu",
+ (void) snprintf(pool_guid, 256, "%llu",
(u_longlong_t)guid);
fnvlist_add_nvlist(d, pool_guid, item);
} else {
@@ -6974,8 +6970,8 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
(void) strlcpy(propval, "-", sizeof (propval));
if (json) {
- zprop_nvlist_one_property(zpool_prop_to_name(prop), propval,
- ZPROP_SRC_NONE, NULL, NULL, nvl, as_int);
+ (void) zprop_nvlist_one_property(zpool_prop_to_name(prop),
+ propval, ZPROP_SRC_NONE, NULL, NULL, nvl, as_int);
} else {
if (scripted)
(void) printf("\t%s", propval);
@@ -6986,7 +6982,6 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
/*
* print static default line per vdev
- * not compatible with '-o' <proplist> option
*/
static void
collect_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
@@ -7042,48 +7037,98 @@ collect_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
* 'toplevel' boolean value is passed to the print_one_column()
* to indicate that the value is valid.
*/
- if (VDEV_STAT_VALID(vs_pspace, c) && vs->vs_pspace) {
- collect_vdev_prop(ZPOOL_PROP_SIZE, vs->vs_pspace, NULL,
- scripted, B_TRUE, format, cb->cb_json, props,
- cb->cb_json_as_int);
- } else {
- collect_vdev_prop(ZPOOL_PROP_SIZE, vs->vs_space, NULL,
- scripted, toplevel, format, cb->cb_json, props,
- cb->cb_json_as_int);
+ for (zprop_list_t *pl = cb->cb_proplist; pl != NULL;
+ pl = pl->pl_next) {
+ switch (pl->pl_prop) {
+ case ZPOOL_PROP_SIZE:
+ if (VDEV_STAT_VALID(vs_pspace, c) &&
+ vs->vs_pspace) {
+ collect_vdev_prop(
+ ZPOOL_PROP_SIZE, vs->vs_pspace,
+ NULL, scripted, B_TRUE, format,
+ cb->cb_json, props,
+ cb->cb_json_as_int);
+ } else {
+ collect_vdev_prop(
+ ZPOOL_PROP_SIZE, vs->vs_space, NULL,
+ scripted, toplevel, format,
+ cb->cb_json, props,
+ cb->cb_json_as_int);
+ }
+ break;
+ case ZPOOL_PROP_ALLOCATED:
+ collect_vdev_prop(ZPOOL_PROP_ALLOCATED,
+ vs->vs_alloc, NULL, scripted, toplevel,
+ format, cb->cb_json, props,
+ cb->cb_json_as_int);
+ break;
+
+ case ZPOOL_PROP_FREE:
+ collect_vdev_prop(ZPOOL_PROP_FREE,
+ vs->vs_space - vs->vs_alloc, NULL, scripted,
+ toplevel, format, cb->cb_json, props,
+ cb->cb_json_as_int);
+ break;
+
+ case ZPOOL_PROP_CHECKPOINT:
+ collect_vdev_prop(ZPOOL_PROP_CHECKPOINT,
+ vs->vs_checkpoint_space, NULL, scripted,
+ toplevel, format, cb->cb_json, props,
+ cb->cb_json_as_int);
+ break;
+
+ case ZPOOL_PROP_EXPANDSZ:
+ collect_vdev_prop(ZPOOL_PROP_EXPANDSZ,
+ vs->vs_esize, NULL, scripted, B_TRUE,
+ format, cb->cb_json, props,
+ cb->cb_json_as_int);
+ break;
+
+ case ZPOOL_PROP_FRAGMENTATION:
+ collect_vdev_prop(
+ ZPOOL_PROP_FRAGMENTATION,
+ vs->vs_fragmentation, NULL, scripted,
+ (vs->vs_fragmentation != ZFS_FRAG_INVALID &&
+ toplevel),
+ format, cb->cb_json, props,
+ cb->cb_json_as_int);
+ break;
+
+ case ZPOOL_PROP_CAPACITY:
+ cap = (vs->vs_space == 0) ?
+ 0 : (vs->vs_alloc * 10000 / vs->vs_space);
+ collect_vdev_prop(ZPOOL_PROP_CAPACITY, cap,
+ NULL, scripted, toplevel, format,
+ cb->cb_json, props, cb->cb_json_as_int);
+ break;
+
+ case ZPOOL_PROP_HEALTH:
+ state = zpool_state_to_name(vs->vs_state,
+ vs->vs_aux);
+ if (isspare) {
+ if (vs->vs_aux == VDEV_AUX_SPARED)
+ state = "INUSE";
+ else if (vs->vs_state ==
+ VDEV_STATE_HEALTHY)
+ state = "AVAIL";
+ }
+ collect_vdev_prop(ZPOOL_PROP_HEALTH, 0, state,
+ scripted, B_TRUE, format, cb->cb_json,
+ props, cb->cb_json_as_int);
+ break;
+
+ case ZPOOL_PROP_NAME:
+ break;
+
+ default:
+ collect_vdev_prop(pl->pl_prop, 0,
+ NULL, scripted, B_FALSE, format,
+ cb->cb_json, props, cb->cb_json_as_int);
+
+ }
+
+
}
- collect_vdev_prop(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL,
- scripted, toplevel, format, cb->cb_json, props,
- cb->cb_json_as_int);
- collect_vdev_prop(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
- NULL, scripted, toplevel, format, cb->cb_json, props,
- cb->cb_json_as_int);
- collect_vdev_prop(ZPOOL_PROP_CHECKPOINT,
- vs->vs_checkpoint_space, NULL, scripted, toplevel, format,
- cb->cb_json, props, cb->cb_json_as_int);
- collect_vdev_prop(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, NULL,
- scripted, B_TRUE, format, cb->cb_json, props,
- cb->cb_json_as_int);
- collect_vdev_prop(ZPOOL_PROP_FRAGMENTATION,
- vs->vs_fragmentation, NULL, scripted,
- (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel),
- format, cb->cb_json, props, cb->cb_json_as_int);
- cap = (vs->vs_space == 0) ? 0 :
- (vs->vs_alloc * 10000 / vs->vs_space);
- collect_vdev_prop(ZPOOL_PROP_CAPACITY, cap, NULL,
- scripted, toplevel, format, cb->cb_json, props,
- cb->cb_json_as_int);
- collect_vdev_prop(ZPOOL_PROP_DEDUPRATIO, 0, NULL,
- scripted, toplevel, format, cb->cb_json, props,
- cb->cb_json_as_int);
- state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
- if (isspare) {
- if (vs->vs_aux == VDEV_AUX_SPARED)
- state = "INUSE";
- else if (vs->vs_state == VDEV_STATE_HEALTHY)
- state = "AVAIL";
- }
- collect_vdev_prop(ZPOOL_PROP_HEALTH, 0, state, scripted,
- B_TRUE, format, cb->cb_json, props, cb->cb_json_as_int);
if (cb->cb_json) {
fnvlist_add_nvlist(ent, "properties", props);
@@ -7257,7 +7302,7 @@ list_callback(zpool_handle_t *zhp, void *data)
if (cbp->cb_json_pool_key_guid) {
guid = fnvlist_lookup_uint64(config,
ZPOOL_CONFIG_POOL_GUID);
- snprintf(pool_guid, 256, "%llu",
+ (void) snprintf(pool_guid, 256, "%llu",
(u_longlong_t)guid);
p = fnvlist_lookup_nvlist(d, pool_guid);
} else {
@@ -7644,7 +7689,7 @@ zpool_do_replace(int argc, char **argv)
}
/*
- * zpool attach [-fsw] [-o property=value] <pool> <device>|<vdev> <new_device>
+ * zpool attach [-fsw] [-o property=value] <pool> <vdev> <new_device>
*
* -f Force attach, even if <new_device> appears to be in use.
* -s Use sequential instead of healing reconstruction for resilver.
@@ -7652,9 +7697,9 @@ zpool_do_replace(int argc, char **argv)
* -w Wait for resilvering (mirror) or expansion (raidz) to complete
* before returning.
*
- * Attach <new_device> to a <device> or <vdev>, where the vdev can be of type
- * mirror or raidz. If <device> is not part of a mirror, then <device> will
- * be transformed into a mirror of <device> and <new_device>. When a mirror
+ * Attach <new_device> to a <vdev>, where the vdev can be of type
+ * device, mirror or raidz. If <vdev> is not part of a mirror, then <vdev> will
+ * be transformed into a mirror of <vdev> and <new_device>. When a mirror
* is involved, <new_device> will begin life with a DTL of [0, now], and will
* immediately begin to resilver itself. For the raidz case, a expansion will
* commence and reflow the raidz data across all the disks including the
@@ -8086,14 +8131,12 @@ zpool_do_offline(int argc, char **argv)
(void) fprintf(stderr,
gettext("-0 and -f cannot be used together\n"));
usage(B_FALSE);
- return (1);
}
if (is_power_off && istmp) {
(void) fprintf(stderr,
gettext("-0 and -t cannot be used together\n"));
usage(B_FALSE);
- return (1);
}
argc -= optind;
@@ -8131,7 +8174,8 @@ zpool_do_offline(int argc, char **argv)
gettext("unable to power off slot for"),
argv[i], ret);
}
- zpool_vdev_set_removed_state(zhp, guid, VDEV_AUX_NONE);
+ (void) zpool_vdev_set_removed_state(zhp, guid,
+ VDEV_AUX_NONE);
} else if (fault) {
vdev_aux_t aux;
@@ -8247,9 +8291,9 @@ zpool_do_clear(int argc, char **argv)
if (is_power_on) {
if (device == NULL) {
- zpool_power_on_pool_and_wait_for_devices(zhp);
+ (void) zpool_power_on_pool_and_wait_for_devices(zhp);
} else {
- zpool_power_on_and_disk_wait(zhp, device);
+ (void) zpool_power_on_and_disk_wait(zhp, device);
}
}
@@ -8732,7 +8776,6 @@ zpool_do_trim(int argc, char **argv)
if (argc < 1 && !trimall) {
(void) fprintf(stderr, gettext("missing pool name argument\n"));
usage(B_FALSE);
- return (-1);
}
if (wait && (cmd_type != POOL_TRIM_START)) {
@@ -8881,7 +8924,7 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps)
char total_i_buf[7], srate_buf[7], irate_buf[7], time_buf[32];
printf(" ");
- printf_color(ANSI_BOLD, gettext("scan:"));
+ (void) printf_color(ANSI_BOLD, gettext("scan:"));
printf(" ");
/* If there's never been a scan, there's not much to say. */
@@ -9021,7 +9064,7 @@ print_rebuild_status_impl(vdev_rebuild_stat_t *vrs, uint_t c, char *vdev_name)
return;
printf(" ");
- printf_color(ANSI_BOLD, gettext("scan:"));
+ (void) printf_color(ANSI_BOLD, gettext("scan:"));
printf(" ");
uint64_t bytes_scanned = vrs->vrs_bytes_scanned;
@@ -9724,7 +9767,7 @@ dedup_stats_nvlist(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *item)
entry = fnvlist_alloc();
ddt_stats_nvlist(&ddh->ddh_stat[h], cb,
entry);
- snprintf(buf, 16, "%d", h);
+ (void) snprintf(buf, 16, "%d", h);
fnvlist_add_nvlist(hist, buf, entry);
fnvlist_free(entry);
}
@@ -10103,7 +10146,7 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
vdev_name = zpool_vdev_name(g_zfs, zhp,
child[prs->prs_removing_vdev], B_TRUE);
- printf_color(ANSI_BOLD, gettext("remove: "));
+ (void) printf_color(ANSI_BOLD, gettext("remove: "));
start = prs->prs_start_time;
end = prs->prs_end_time;
@@ -10203,7 +10246,7 @@ print_raidz_expand_status(zpool_handle_t *zhp, pool_raidz_expand_stat_t *pres)
&child, &children) == 0);
assert(pres->pres_expanding_vdev < children);
- printf_color(ANSI_BOLD, gettext("expand: "));
+ (void) printf_color(ANSI_BOLD, gettext("expand: "));
time_t start = pres->pres_start_time;
time_t end = pres->pres_end_time;
@@ -10447,32 +10490,38 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp,
switch (reason) {
case ZPOOL_STATUS_MISSING_DEV_R:
- snprintf(status, ST_SIZE, gettext("One or more devices could "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices could "
"not be opened. Sufficient replicas exist for\n\tthe pool "
"to continue functioning in a degraded state.\n"));
- snprintf(action, AC_SIZE, gettext("Attach the missing device "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Attach the missing device "
"and online it using 'zpool online'.\n"));
break;
case ZPOOL_STATUS_MISSING_DEV_NR:
- snprintf(status, ST_SIZE, gettext("One or more devices could "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices could "
"not be opened. There are insufficient\n\treplicas for the"
" pool to continue functioning.\n"));
- snprintf(action, AC_SIZE, gettext("Attach the missing device "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Attach the missing device "
"and online it using 'zpool online'.\n"));
break;
case ZPOOL_STATUS_CORRUPT_LABEL_R:
- snprintf(status, ST_SIZE, gettext("One or more devices could "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices could "
"not be used because the label is missing or\n\tinvalid. "
"Sufficient replicas exist for the pool to continue\n\t"
"functioning in a degraded state.\n"));
- snprintf(action, AC_SIZE, gettext("Replace the device using "
- "'zpool replace'.\n"));
+ (void) snprintf(action, AC_SIZE,
+ gettext("Replace the device using 'zpool replace'.\n"));
break;
case ZPOOL_STATUS_CORRUPT_LABEL_NR:
- snprintf(status, ST_SIZE, gettext("One or more devices could "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices could "
"not be used because the label is missing \n\tor invalid. "
"There are insufficient replicas for the pool to "
"continue\n\tfunctioning.\n"));
@@ -10482,63 +10531,70 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp,
break;
case ZPOOL_STATUS_FAILING_DEV:
- snprintf(status, ST_SIZE, gettext("One or more devices has "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices has "
"experienced an unrecoverable error. An\n\tattempt was "
"made to correct the error. Applications are "
"unaffected.\n"));
- snprintf(action, AC_SIZE, gettext("Determine if the "
+ (void) snprintf(action, AC_SIZE, gettext("Determine if the "
"device needs to be replaced, and clear the errors\n\tusing"
" 'zpool clear' or replace the device with 'zpool "
"replace'.\n"));
break;
case ZPOOL_STATUS_OFFLINE_DEV:
- snprintf(status, ST_SIZE, gettext("One or more devices has "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices has "
"been taken offline by the administrator.\n\tSufficient "
"replicas exist for the pool to continue functioning in "
"a\n\tdegraded state.\n"));
- snprintf(action, AC_SIZE, gettext("Online the device "
+ (void) snprintf(action, AC_SIZE, gettext("Online the device "
"using 'zpool online' or replace the device with\n\t'zpool "
"replace'.\n"));
break;
case ZPOOL_STATUS_REMOVED_DEV:
- snprintf(status, ST_SIZE, gettext("One or more devices have "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices have "
"been removed.\n\tSufficient replicas exist for the pool "
"to continue functioning in a\n\tdegraded state.\n"));
- snprintf(action, AC_SIZE, gettext("Online the device "
+ (void) snprintf(action, AC_SIZE, gettext("Online the device "
"using zpool online' or replace the device with\n\t'zpool "
"replace'.\n"));
break;
case ZPOOL_STATUS_RESILVERING:
case ZPOOL_STATUS_REBUILDING:
- snprintf(status, ST_SIZE, gettext("One or more devices is "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices is "
"currently being resilvered. The pool will\n\tcontinue "
"to function, possibly in a degraded state.\n"));
- snprintf(action, AC_SIZE, gettext("Wait for the resilver to "
- "complete.\n"));
+ (void) snprintf(action, AC_SIZE,
+ gettext("Wait for the resilver to complete.\n"));
break;
case ZPOOL_STATUS_REBUILD_SCRUB:
- snprintf(status, ST_SIZE, gettext("One or more devices have "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices have "
"been sequentially resilvered, scrubbing\n\tthe pool "
"is recommended.\n"));
- snprintf(action, AC_SIZE, gettext("Use 'zpool scrub' to "
+ (void) snprintf(action, AC_SIZE, gettext("Use 'zpool scrub' to "
"verify all data checksums.\n"));
break;
case ZPOOL_STATUS_CORRUPT_DATA:
- snprintf(status, ST_SIZE, gettext("One or more devices has "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices has "
"experienced an error resulting in data\n\tcorruption. "
"Applications may be affected.\n"));
- snprintf(action, AC_SIZE, gettext("Restore the file in question"
+ (void) snprintf(action, AC_SIZE,
+ gettext("Restore the file in question"
" if possible. Otherwise restore the\n\tentire pool from "
"backup.\n"));
break;
case ZPOOL_STATUS_CORRUPT_POOL:
- snprintf(status, ST_SIZE, gettext("The pool metadata is "
+ (void) snprintf(status, ST_SIZE, gettext("The pool metadata is "
"corrupted and the pool cannot be opened.\n"));
zpool_explain_recover(zpool_get_handle(zhp),
zpool_get_name(zhp), reason, zpool_get_config(zhp, NULL),
@@ -10546,75 +10602,84 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp,
break;
case ZPOOL_STATUS_VERSION_OLDER:
- snprintf(status, ST_SIZE, gettext("The pool is formatted using "
+ (void) snprintf(status, ST_SIZE,
+ gettext("The pool is formatted using "
"a legacy on-disk format. The pool can\n\tstill be used, "
"but some features are unavailable.\n"));
- snprintf(action, AC_SIZE, gettext("Upgrade the pool using "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Upgrade the pool using "
"'zpool upgrade'. Once this is done, the\n\tpool will no "
"longer be accessible on software that does not support\n\t"
"feature flags.\n"));
break;
case ZPOOL_STATUS_VERSION_NEWER:
- snprintf(status, ST_SIZE, gettext("The pool has been upgraded "
+ (void) snprintf(status, ST_SIZE,
+ gettext("The pool has been upgraded "
"to a newer, incompatible on-disk version.\n\tThe pool "
"cannot be accessed on this system.\n"));
- snprintf(action, AC_SIZE, gettext("Access the pool from a "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Access the pool from a "
"system running more recent software, or\n\trestore the "
"pool from backup.\n"));
break;
case ZPOOL_STATUS_FEAT_DISABLED:
- snprintf(status, ST_SIZE, gettext("Some supported and "
+ (void) snprintf(status, ST_SIZE, gettext("Some supported and "
"requested features are not enabled on the pool.\n\t"
"The pool can still be used, but some features are "
"unavailable.\n"));
- snprintf(action, AC_SIZE, gettext("Enable all features using "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Enable all features using "
"'zpool upgrade'. Once this is done,\n\tthe pool may no "
"longer be accessible by software that does not support\n\t"
"the features. See zpool-features(7) for details.\n"));
break;
case ZPOOL_STATUS_COMPATIBILITY_ERR:
- snprintf(status, ST_SIZE, gettext("This pool has a "
+ (void) snprintf(status, ST_SIZE, gettext("This pool has a "
"compatibility list specified, but it could not be\n\t"
"read/parsed at this time. The pool can still be used, "
"but this\n\tshould be investigated.\n"));
- snprintf(action, AC_SIZE, gettext("Check the value of the "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Check the value of the "
"'compatibility' property against the\n\t"
"appropriate file in " ZPOOL_SYSCONF_COMPAT_D " or "
ZPOOL_DATA_COMPAT_D ".\n"));
break;
case ZPOOL_STATUS_INCOMPATIBLE_FEAT:
- snprintf(status, ST_SIZE, gettext("One or more features "
+ (void) snprintf(status, ST_SIZE, gettext("One or more features "
"are enabled on the pool despite not being\n\t"
"requested by the 'compatibility' property.\n"));
- snprintf(action, AC_SIZE, gettext("Consider setting "
+ (void) snprintf(action, AC_SIZE, gettext("Consider setting "
"'compatibility' to an appropriate value, or\n\t"
"adding needed features to the relevant file in\n\t"
ZPOOL_SYSCONF_COMPAT_D " or " ZPOOL_DATA_COMPAT_D ".\n"));
break;
case ZPOOL_STATUS_UNSUP_FEAT_READ:
- snprintf(status, ST_SIZE, gettext("The pool cannot be accessed "
+ (void) snprintf(status, ST_SIZE,
+ gettext("The pool cannot be accessed "
"on this system because it uses the\n\tfollowing feature(s)"
" not supported on this system:\n"));
zpool_collect_unsup_feat(zpool_get_config(zhp, NULL), status,
1024);
- snprintf(action, AC_SIZE, gettext("Access the pool from a "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Access the pool from a "
"system that supports the required feature(s),\n\tor "
"restore the pool from backup.\n"));
break;
case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
- snprintf(status, ST_SIZE, gettext("The pool can only be "
+ (void) snprintf(status, ST_SIZE, gettext("The pool can only be "
"accessed in read-only mode on this system. It\n\tcannot be"
" accessed in read-write mode because it uses the "
"following\n\tfeature(s) not supported on this system:\n"));
zpool_collect_unsup_feat(zpool_get_config(zhp, NULL), status,
1024);
- snprintf(action, AC_SIZE, gettext("The pool cannot be accessed "
+ (void) snprintf(action, AC_SIZE,
+ gettext("The pool cannot be accessed "
"in read-write mode. Import the pool with\n"
"\t\"-o readonly=on\", access the pool from a system that "
"supports the\n\trequired feature(s), or restore the "
@@ -10622,90 +10687,105 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp,
break;
case ZPOOL_STATUS_FAULTED_DEV_R:
- snprintf(status, ST_SIZE, gettext("One or more devices are "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices are "
"faulted in response to persistent errors.\n\tSufficient "
"replicas exist for the pool to continue functioning "
"in a\n\tdegraded state.\n"));
- snprintf(action, AC_SIZE, gettext("Replace the faulted device, "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Replace the faulted device, "
"or use 'zpool clear' to mark the device\n\trepaired.\n"));
break;
case ZPOOL_STATUS_FAULTED_DEV_NR:
- snprintf(status, ST_SIZE, gettext("One or more devices are "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices are "
"faulted in response to persistent errors. There are "
"insufficient replicas for the pool to\n\tcontinue "
"functioning.\n"));
- snprintf(action, AC_SIZE, gettext("Destroy and re-create the "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Destroy and re-create the "
"pool from a backup source. Manually marking the device\n"
"\trepaired using 'zpool clear' may allow some data "
"to be recovered.\n"));
break;
case ZPOOL_STATUS_IO_FAILURE_MMP:
- snprintf(status, ST_SIZE, gettext("The pool is suspended "
+ (void) snprintf(status, ST_SIZE,
+ gettext("The pool is suspended "
"because multihost writes failed or were delayed;\n\t"
"another system could import the pool undetected.\n"));
- snprintf(action, AC_SIZE, gettext("Make sure the pool's devices"
+ (void) snprintf(action, AC_SIZE,
+ gettext("Make sure the pool's devices"
" are connected, then reboot your system and\n\timport the "
"pool or run 'zpool clear' to resume the pool.\n"));
break;
case ZPOOL_STATUS_IO_FAILURE_WAIT:
case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
- snprintf(status, ST_SIZE, gettext("One or more devices are "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices are "
"faulted in response to IO failures.\n"));
- snprintf(action, AC_SIZE, gettext("Make sure the affected "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Make sure the affected "
"devices are connected, then run 'zpool clear'.\n"));
break;
case ZPOOL_STATUS_BAD_LOG:
- snprintf(status, ST_SIZE, gettext("An intent log record "
+ (void) snprintf(status, ST_SIZE, gettext("An intent log record "
"could not be read.\n"
"\tWaiting for administrator intervention to fix the "
"faulted pool.\n"));
- snprintf(action, AC_SIZE, gettext("Either restore the affected "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Either restore the affected "
"device(s) and run 'zpool online',\n"
"\tor ignore the intent log records by running "
"'zpool clear'.\n"));
break;
case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
- snprintf(status, ST_SIZE, gettext("One or more devices are "
+ (void) snprintf(status, ST_SIZE,
+ gettext("One or more devices are "
"configured to use a non-native block size.\n"
"\tExpect reduced performance.\n"));
- snprintf(action, AC_SIZE, gettext("Replace affected devices "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Replace affected devices "
"with devices that support the\n\tconfigured block size, "
"or migrate data to a properly configured\n\tpool.\n"));
break;
case ZPOOL_STATUS_HOSTID_MISMATCH:
- snprintf(status, ST_SIZE, gettext("Mismatch between pool hostid"
+ (void) snprintf(status, ST_SIZE,
+ gettext("Mismatch between pool hostid"
" and system hostid on imported pool.\n\tThis pool was "
"previously imported into a system with a different "
"hostid,\n\tand then was verbatim imported into this "
"system.\n"));
- snprintf(action, AC_SIZE, gettext("Export this pool on all "
+ (void) snprintf(action, AC_SIZE,
+ gettext("Export this pool on all "
"systems on which it is imported.\n"
"\tThen import it to correct the mismatch.\n"));
break;
case ZPOOL_STATUS_ERRATA:
- snprintf(status, ST_SIZE, gettext("Errata #%d detected.\n"),
- errata);
+ (void) snprintf(status, ST_SIZE,
+ gettext("Errata #%d detected.\n"), errata);
switch (errata) {
case ZPOOL_ERRATA_NONE:
break;
case ZPOOL_ERRATA_ZOL_2094_SCRUB:
- snprintf(action, AC_SIZE, gettext("To correct the issue"
- " run 'zpool scrub'.\n"));
+ (void) snprintf(action, AC_SIZE,
+ gettext("To correct the issue run "
+ "'zpool scrub'.\n"));
break;
case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION:
(void) strlcat(status, gettext("\tExisting encrypted "
"datasets contain an on-disk incompatibility\n\t "
"which needs to be corrected.\n"), ST_SIZE);
- snprintf(action, AC_SIZE, gettext("To correct the issue"
+ (void) snprintf(action, AC_SIZE,
+ gettext("To correct the issue"
" backup existing encrypted datasets to new\n\t"
"encrypted datasets and destroy the old ones. "
"'zfs mount -o ro' can\n\tbe used to temporarily "
@@ -10718,7 +10798,8 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp,
"incompatibility. This may cause on-disk "
"corruption if they are used\n\twith "
"'zfs recv'.\n"), ST_SIZE);
- snprintf(action, AC_SIZE, gettext("To correct the"
+ (void) snprintf(action, AC_SIZE,
+ gettext("To correct the"
"issue, enable the bookmark_v2 feature. No "
"additional\n\taction is needed if there are no "
"encrypted snapshots or bookmarks.\n\tIf preserving"
@@ -10748,8 +10829,8 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp,
if (cbp->cb_json)
fnvlist_add_string(item, "status", status);
else {
- printf_color(ANSI_BOLD, gettext("status: "));
- printf_color(ANSI_YELLOW, status);
+ (void) printf_color(ANSI_BOLD, gettext("status: "));
+ (void) printf_color(ANSI_YELLOW, status);
}
}
@@ -10757,8 +10838,8 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp,
if (cbp->cb_json)
fnvlist_add_string(item, "action", action);
else {
- printf_color(ANSI_BOLD, gettext("action: "));
- printf_color(ANSI_YELLOW, action);
+ (void) printf_color(ANSI_BOLD, gettext("action: "));
+ (void) printf_color(ANSI_YELLOW, action);
}
}
}
@@ -10808,13 +10889,14 @@ status_callback_json(zpool_handle_t *zhp, void *data)
if (cbp->cb_json_pool_key_guid) {
guid = fnvlist_lookup_uint64(config,
ZPOOL_CONFIG_POOL_GUID);
- snprintf(pool_guid, 256, "%llu", (u_longlong_t)guid);
+ (void) snprintf(pool_guid, 256, "%llu",
+ (u_longlong_t)guid);
}
cbp->cb_count++;
print_status_reason(zhp, cbp, reason, errata, item);
if (msgid != NULL) {
- snprintf(msgbuf, 256,
+ (void) snprintf(msgbuf, 256,
"https://openzfs.github.io/openzfs-docs/msg/%s",
msgid);
fnvlist_add_string(item, "msgid", msgid);
@@ -10937,19 +11019,19 @@ status_callback(zpool_handle_t *zhp, void *data)
health = zpool_get_state_str(zhp);
printf(" ");
- printf_color(ANSI_BOLD, gettext("pool:"));
+ (void) printf_color(ANSI_BOLD, gettext("pool:"));
printf(" %s\n", zpool_get_name(zhp));
- fputc(' ', stdout);
- printf_color(ANSI_BOLD, gettext("state: "));
+ (void) fputc(' ', stdout);
+ (void) printf_color(ANSI_BOLD, gettext("state: "));
- printf_color(health_str_to_color(health), "%s", health);
+ (void) printf_color(health_str_to_color(health), "%s", health);
- fputc('\n', stdout);
+ (void) fputc('\n', stdout);
print_status_reason(zhp, cbp, reason, errata, NULL);
if (msgid != NULL) {
printf(" ");
- printf_color(ANSI_BOLD, gettext("see:"));
+ (void) printf_color(ANSI_BOLD, gettext("see:"));
printf(gettext(
" https://openzfs.github.io/openzfs-docs/msg/%s\n"),
msgid);
@@ -10990,15 +11072,16 @@ status_callback(zpool_handle_t *zhp, void *data)
color_end();
if (cbp->cb_print_slow_ios) {
- printf_color(ANSI_BOLD, " %5s", gettext("SLOW"));
+ (void) printf_color(ANSI_BOLD, " %5s", gettext("SLOW"));
}
if (cbp->cb_print_power) {
- printf_color(ANSI_BOLD, " %5s", gettext("POWER"));
+ (void) printf_color(ANSI_BOLD, " %5s",
+ gettext("POWER"));
}
if (cbp->cb_print_dio_verify) {
- printf_color(ANSI_BOLD, " %5s", gettext("DIO"));
+ (void) printf_color(ANSI_BOLD, " %5s", gettext("DIO"));
}
if (cbp->vcdl != NULL)
@@ -11315,7 +11398,7 @@ check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs)
(*count)++;
}
- zfs_iter_filesystems_v2(zhp, 0, check_unsupp_fs, unsupp_fs);
+ (void) zfs_iter_filesystems_v2(zhp, 0, check_unsupp_fs, unsupp_fs);
zfs_close(zhp);
@@ -12143,17 +12226,17 @@ zpool_do_events_nvprint(nvlist_t *nvl, int depth)
FM_EREPORT_PAYLOAD_ZFS_ZIO_STAGE) == 0 ||
strcmp(name,
FM_EREPORT_PAYLOAD_ZFS_ZIO_PIPELINE) == 0) {
- zfs_valstr_zio_stage(i32, flagstr,
+ (void) zfs_valstr_zio_stage(i32, flagstr,
sizeof (flagstr));
printf(gettext("0x%x [%s]"), i32, flagstr);
} else if (strcmp(name,
FM_EREPORT_PAYLOAD_ZFS_ZIO_TYPE) == 0) {
- zfs_valstr_zio_type(i32, flagstr,
+ (void) zfs_valstr_zio_type(i32, flagstr,
sizeof (flagstr));
printf(gettext("0x%x [%s]"), i32, flagstr);
} else if (strcmp(name,
FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY) == 0) {
- zfs_valstr_zio_priority(i32, flagstr,
+ (void) zfs_valstr_zio_priority(i32, flagstr,
sizeof (flagstr));
printf(gettext("0x%x [%s]"), i32, flagstr);
} else {
@@ -12181,7 +12264,7 @@ zpool_do_events_nvprint(nvlist_t *nvl, int depth)
(u_longlong_t)i64);
} else if (strcmp(name,
FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS) == 0) {
- zfs_valstr_zio_flag(i64, flagstr,
+ (void) zfs_valstr_zio_flag(i64, flagstr,
sizeof (flagstr));
printf(gettext("0x%llx [%s]"),
(u_longlong_t)i64, flagstr);
@@ -12495,7 +12578,7 @@ get_callback_vdev(zpool_handle_t *zhp, char *vdevname, void *data)
if (zpool_get_vdev_prop(zhp, vdevname, pl->pl_prop,
prop_name, value, sizeof (value), &srctype,
cbp->cb_literal) == 0) {
- zprop_collect_property(vdevname, cbp, prop_name,
+ (void) zprop_collect_property(vdevname, cbp, prop_name,
value, srctype, NULL, NULL, props);
}
}
@@ -12567,19 +12650,19 @@ get_callback(zpool_handle_t *zhp, void *data)
}
if (strcmp(cbp->cb_vdevs.cb_names[0], "all-vdevs") == 0) {
- for_each_vdev(zhp, get_callback_vdev_cb, data);
+ (void) for_each_vdev(zhp, get_callback_vdev_cb, data);
} else {
/* Adjust column widths for vdev properties */
for (vid = 0; vid < cbp->cb_vdevs.cb_names_count;
vid++) {
- vdev_expand_proplist(zhp,
+ (void) vdev_expand_proplist(zhp,
cbp->cb_vdevs.cb_names[vid],
&cbp->cb_proplist);
}
/* Display the properties */
for (vid = 0; vid < cbp->cb_vdevs.cb_names_count;
vid++) {
- get_callback_vdev(zhp,
+ (void) get_callback_vdev(zhp,
cbp->cb_vdevs.cb_names[vid], data);
}
}
@@ -12652,7 +12735,7 @@ get_callback(zpool_handle_t *zhp, void *data)
uint64_t guid = fnvlist_lookup_uint64(
zpool_get_config(zhp, NULL),
ZPOOL_CONFIG_POOL_GUID);
- snprintf(buf, 256, "%llu",
+ (void) snprintf(buf, 256, "%llu",
(u_longlong_t)guid);
fnvlist_add_nvlist(d, buf, item);
} else {
@@ -12851,7 +12934,6 @@ found:
argv[0], &cb.cb_vdevs);
fprintf(stderr, "\n");
usage(B_FALSE);
- return (1);
}
} else {
if (cb.cb_json) {
@@ -13347,11 +13429,11 @@ wait_status_thread(void *arg)
} else {
timeout.tv_nsec = nanos;
}
- pthread_mutex_lock(&wd->wd_mutex);
+ (void) pthread_mutex_lock(&wd->wd_mutex);
if (!wd->wd_should_exit)
ret = pthread_cond_timedwait(&wd->wd_cv, &wd->wd_mutex,
&timeout);
- pthread_mutex_unlock(&wd->wd_mutex);
+ (void) pthread_mutex_unlock(&wd->wd_mutex);
if (ret == 0) {
break; /* signaled by main thread */
} else if (ret != ETIMEDOUT) {
@@ -13382,8 +13464,8 @@ zpool_do_wait(int argc, char **argv)
wd.wd_headers_once = B_FALSE;
wd.wd_should_exit = B_FALSE;
- pthread_mutex_init(&wd.wd_mutex, NULL);
- pthread_cond_init(&wd.wd_cv, NULL);
+ (void) pthread_mutex_init(&wd.wd_mutex, NULL);
+ (void) pthread_cond_init(&wd.wd_cv, NULL);
/* By default, wait for all types of activity. */
for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++)
@@ -13507,17 +13589,17 @@ found:;
if (verbose) {
uintptr_t status;
- pthread_mutex_lock(&wd.wd_mutex);
+ (void) pthread_mutex_lock(&wd.wd_mutex);
wd.wd_should_exit = B_TRUE;
- pthread_cond_signal(&wd.wd_cv);
- pthread_mutex_unlock(&wd.wd_mutex);
+ (void) pthread_cond_signal(&wd.wd_cv);
+ (void) pthread_mutex_unlock(&wd.wd_mutex);
(void) pthread_join(status_thr, (void *)&status);
if (status != 0)
error = status;
}
- pthread_mutex_destroy(&wd.wd_mutex);
- pthread_cond_destroy(&wd.wd_cv);
+ (void) pthread_mutex_destroy(&wd.wd_mutex);
+ (void) pthread_cond_destroy(&wd.wd_cv);
return (error);
}
@@ -13670,14 +13752,14 @@ zpool_do_help(int argc, char **argv)
{
char page[MAXNAMELEN];
if (argc < 3 || strcmp(argv[2], "zpool") == 0)
- strcpy(page, "zpool");
+ (void) strcpy(page, "zpool");
else if (strcmp(argv[2], "concepts") == 0 ||
strcmp(argv[2], "props") == 0)
- snprintf(page, sizeof (page), "zpool%s", argv[2]);
+ (void) snprintf(page, sizeof (page), "zpool%s", argv[2]);
else
- snprintf(page, sizeof (page), "zpool-%s", argv[2]);
+ (void) snprintf(page, sizeof (page), "zpool-%s", argv[2]);
- execlp("man", "man", page, NULL);
+ (void) execlp("man", "man", page, NULL);
fprintf(stderr, "couldn't run man program: %s", strerror(errno));
return (-1);
@@ -13804,7 +13886,6 @@ main(int argc, char **argv)
(void) fprintf(stderr, gettext("unrecognized "
"command '%s'\n"), cmdname);
usage(B_FALSE);
- ret = 1;
}
for (i = 0; i < argc; i++)
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_util.h b/sys/contrib/openzfs/cmd/zpool/zpool_util.h
index 5ab7cb9750f1..3af23c52bd45 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_util.h
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_util.h
@@ -76,11 +76,10 @@ typedef struct zpool_list zpool_list_t;
zpool_list_t *pool_list_get(int, char **, zprop_list_t **, zfs_type_t,
boolean_t, int *);
-void pool_list_update(zpool_list_t *);
+int pool_list_refresh(zpool_list_t *);
int pool_list_iter(zpool_list_t *, int unavail, zpool_iter_f, void *);
void pool_list_free(zpool_list_t *);
int pool_list_count(zpool_list_t *);
-void pool_list_remove(zpool_list_t *, zpool_handle_t *);
extern libzfs_handle_t *g_zfs;
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c
index 684b46a2d673..d1e9ef76dc10 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c
@@ -195,7 +195,7 @@ is_shorthand_path(const char *arg, char *path, size_t path_size,
return (0);
}
- strlcpy(path, arg, path_size);
+ (void) strlcpy(path, arg, path_size);
memset(statbuf, 0, sizeof (*statbuf));
*wholedisk = B_FALSE;
@@ -270,14 +270,13 @@ is_spare(nvlist_t *config, const char *path)
* draid* Virtual dRAID spare
*/
static nvlist_t *
-make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
+make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift)
{
char path[MAXPATHLEN];
struct stat64 statbuf;
nvlist_t *vdev = NULL;
const char *type = NULL;
boolean_t wholedisk = B_FALSE;
- uint64_t ashift = 0;
int err;
/*
@@ -309,7 +308,7 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
}
/* After whole disk check restore original passed path */
- strlcpy(path, arg, sizeof (path));
+ (void) strlcpy(path, arg, sizeof (path));
} else if (zpool_is_draid_spare(arg)) {
if (!is_primary) {
(void) fprintf(stderr,
@@ -319,7 +318,7 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
}
wholedisk = B_TRUE;
- strlcpy(path, arg, sizeof (path));
+ (void) strlcpy(path, arg, sizeof (path));
type = VDEV_TYPE_DRAID_SPARE;
} else {
err = is_shorthand_path(arg, path, sizeof (path),
@@ -382,31 +381,6 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
(uint64_t)wholedisk) == 0);
/*
- * Override defaults if custom properties are provided.
- */
- if (props != NULL) {
- const char *value = NULL;
-
- if (nvlist_lookup_string(props,
- zpool_prop_to_name(ZPOOL_PROP_ASHIFT), &value) == 0) {
- if (zfs_nicestrtonum(NULL, value, &ashift) != 0) {
- (void) fprintf(stderr,
- gettext("ashift must be a number.\n"));
- return (NULL);
- }
- if (ashift != 0 &&
- (ashift < ASHIFT_MIN || ashift > ASHIFT_MAX)) {
- (void) fprintf(stderr,
- gettext("invalid 'ashift=%" PRIu64 "' "
- "property: only values between %" PRId32 " "
- "and %" PRId32 " are allowed.\n"),
- ashift, ASHIFT_MIN, ASHIFT_MAX);
- return (NULL);
- }
- }
- }
-
- /*
* If the device is known to incorrectly report its physical sector
* size explicitly provide the known correct value.
*/
@@ -609,22 +583,28 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
ZPOOL_CONFIG_PATH, &path) == 0);
/*
+ * Skip active spares they should never cause
+ * the pool to be evaluated as inconsistent.
+ */
+ if (is_spare(NULL, path))
+ continue;
+
+ /*
* If we have a raidz/mirror that combines disks
- * with files, report it as an error.
+ * with files, only report it as an error when
+ * fatal is set to ensure all the replication
+ * checks aren't skipped in check_replication().
*/
- if (!dontreport && type != NULL &&
+ if (fatal && !dontreport && type != NULL &&
strcmp(type, childtype) != 0) {
if (ret != NULL)
free(ret);
ret = NULL;
- if (fatal)
- vdev_error(gettext(
- "mismatched replication "
- "level: %s contains both "
- "files and devices\n"),
- rep.zprl_type);
- else
- return (NULL);
+ vdev_error(gettext(
+ "mismatched replication "
+ "level: %s contains both "
+ "files and devices\n"),
+ rep.zprl_type);
dontreport = B_TRUE;
}
@@ -1030,7 +1010,7 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv, boolean_t replacing)
* window between when udev deletes and recreates the link
* during which access attempts will fail with ENOENT.
*/
- strlcpy(udevpath, path, MAXPATHLEN);
+ (void) strlcpy(udevpath, path, MAXPATHLEN);
(void) zfs_append_partition(udevpath, MAXPATHLEN);
fd = open(devpath, O_RDWR|O_EXCL);
@@ -1507,6 +1487,29 @@ construct_spec(nvlist_t *props, int argc, char **argv)
const char *type, *fulltype;
boolean_t is_log, is_special, is_dedup, is_spare;
boolean_t seen_logs;
+ uint64_t ashift = 0;
+
+ if (props != NULL) {
+ const char *value = NULL;
+
+ if (nvlist_lookup_string(props,
+ zpool_prop_to_name(ZPOOL_PROP_ASHIFT), &value) == 0) {
+ if (zfs_nicestrtonum(NULL, value, &ashift) != 0) {
+ (void) fprintf(stderr,
+ gettext("ashift must be a number.\n"));
+ return (NULL);
+ }
+ if (ashift != 0 &&
+ (ashift < ASHIFT_MIN || ashift > ASHIFT_MAX)) {
+ (void) fprintf(stderr,
+ gettext("invalid 'ashift=%" PRIu64 "' "
+ "property: only values between %" PRId32 " "
+ "and %" PRId32 " are allowed.\n"),
+ ashift, ASHIFT_MIN, ASHIFT_MAX);
+ return (NULL);
+ }
+ }
+ }
top = NULL;
toplevels = 0;
@@ -1612,9 +1615,9 @@ construct_spec(nvlist_t *props, int argc, char **argv)
children * sizeof (nvlist_t *));
if (child == NULL)
zpool_no_memory();
- if ((nv = make_leaf_vdev(props, argv[c],
+ if ((nv = make_leaf_vdev(argv[c],
!(is_log || is_special || is_dedup ||
- is_spare))) == NULL) {
+ is_spare), ashift)) == NULL) {
for (c = 0; c < children - 1; c++)
nvlist_free(child[c]);
free(child);
@@ -1678,6 +1681,10 @@ construct_spec(nvlist_t *props, int argc, char **argv)
ZPOOL_CONFIG_ALLOCATION_BIAS,
VDEV_ALLOC_BIAS_DEDUP) == 0);
}
+ if (ashift > 0) {
+ fnvlist_add_uint64(nv,
+ ZPOOL_CONFIG_ASHIFT, ashift);
+ }
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
verify(nvlist_add_uint64(nv,
ZPOOL_CONFIG_NPARITY,
@@ -1705,8 +1712,9 @@ construct_spec(nvlist_t *props, int argc, char **argv)
* We have a device. Pass off to make_leaf_vdev() to
* construct the appropriate nvlist describing the vdev.
*/
- if ((nv = make_leaf_vdev(props, argv[0], !(is_log ||
- is_special || is_dedup || is_spare))) == NULL)
+ if ((nv = make_leaf_vdev(argv[0], !(is_log ||
+ is_special || is_dedup || is_spare),
+ ashift)) == NULL)
goto spec_out;
verify(nvlist_add_uint64(nv,
diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_redup.c b/sys/contrib/openzfs/cmd/zstream/zstream_redup.c
index 0e18c52496fd..c1cb6d4d3ad7 100644
--- a/sys/contrib/openzfs/cmd/zstream/zstream_redup.c
+++ b/sys/contrib/openzfs/cmd/zstream/zstream_redup.c
@@ -191,9 +191,9 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
#ifdef _ILP32
uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20;
#else
- uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
+ uint64_t physbytes = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
uint64_t max_rde_size =
- MAX((physmem * MAX_RDT_PHYSMEM_PERCENT) / 100,
+ MAX((physbytes * MAX_RDT_PHYSMEM_PERCENT) / 100,
SMALLEST_POSSIBLE_MAX_RDT_MB << 20);
#endif
diff --git a/sys/contrib/openzfs/cmd/ztest.c b/sys/contrib/openzfs/cmd/ztest.c
index 89752dcb0f0f..dc8ac85b6991 100644
--- a/sys/contrib/openzfs/cmd/ztest.c
+++ b/sys/contrib/openzfs/cmd/ztest.c
@@ -139,9 +139,10 @@
#include <sys/crypto/icp.h>
#include <sys/zfs_impl.h>
#include <sys/backtrace.h>
+#include <libzpool.h>
+#include <libspl.h>
static int ztest_fd_data = -1;
-static int ztest_fd_rand = -1;
typedef struct ztest_shared_hdr {
uint64_t zh_hdr_size;
@@ -902,13 +903,10 @@ ztest_random(uint64_t range)
{
uint64_t r;
- ASSERT3S(ztest_fd_rand, >=, 0);
-
if (range == 0)
return (0);
- if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
- fatal(B_TRUE, "short read from /dev/urandom");
+ random_get_pseudo_bytes((uint8_t *)&r, sizeof (r));
return (r % range);
}
@@ -1228,10 +1226,10 @@ ztest_kill(ztest_shared_t *zs)
* See comment above spa_write_cachefile().
*/
if (raidz_expand_pause_point != RAIDZ_EXPAND_PAUSE_NONE) {
- if (mutex_tryenter(&spa_namespace_lock)) {
+ if (spa_namespace_tryenter(FTAG)) {
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE,
B_FALSE);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
ztest_scratch_state->zs_raidz_scratch_verify_pause =
raidz_expand_pause_point;
@@ -1246,9 +1244,9 @@ ztest_kill(ztest_shared_t *zs)
return;
}
} else {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
(void) raise(SIGKILL);
@@ -2306,7 +2304,8 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
}
if (abuf == NULL) {
- dmu_write(os, lr->lr_foid, offset, length, data, tx);
+ dmu_write(os, lr->lr_foid, offset, length, data, tx,
+ DMU_READ_PREFETCH);
} else {
memcpy(abuf->b_data, data, length);
VERIFY0(dmu_assign_arcbuf_by_dbuf(db, offset, abuf, tx, 0));
@@ -3688,10 +3687,10 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
if (error == 0) {
(void) printf("successful split - results:\n");
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
show_pool_stats(spa);
show_pool_stats(spa_lookup("splitp"));
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
++zs->zs_splits;
--zs->zs_mirrors;
}
@@ -3975,11 +3974,11 @@ raidz_scratch_verify(void)
kernel_init(SPA_MODE_READ);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa = spa_lookup(ztest_opts.zo_pool);
ASSERT(spa);
spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG));
@@ -5243,7 +5242,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
* We've verified all the old bufwads, and made new ones.
* Now write them out.
*/
- dmu_write(os, packobj, packoff, packsize, packbuf, tx);
+ dmu_write(os, packobj, packoff, packsize, packbuf, tx,
+ DMU_READ_PREFETCH);
if (freeit) {
if (ztest_opts.zo_verbose >= 7) {
@@ -5258,7 +5258,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
" txg %"PRIx64"\n",
bigoff, bigsize, txg);
}
- dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx);
+ dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx,
+ DMU_READ_PREFETCH);
}
dmu_tx_commit(tx);
@@ -5513,7 +5514,8 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
* We've verified all the old bufwads, and made new ones.
* Now write them out.
*/
- dmu_write(os, packobj, packoff, packsize, packbuf, tx);
+ dmu_write(os, packobj, packoff, packsize, packbuf, tx,
+ DMU_READ_PREFETCH);
if (ztest_opts.zo_verbose >= 7) {
(void) printf("writing offset %"PRIx64" size %"PRIx64""
" txg %"PRIx64"\n",
@@ -6119,7 +6121,8 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id)
"future leak: got %"PRIu64", open txg is %"PRIu64"",
old_txg, txg);
- dmu_write(os, od->od_object, 0, sizeof (uint64_t), &txg, tx);
+ dmu_write(os, od->od_object, 0, sizeof (uint64_t), &txg, tx,
+ DMU_READ_PREFETCH);
(void) mutex_enter(&zcl.zcl_callbacks_lock);
@@ -7422,11 +7425,11 @@ ztest_walk_pool_directory(const char *header)
if (ztest_opts.zo_verbose >= 6)
(void) puts(header);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
while ((spa = spa_next(spa)) != NULL)
if (ztest_opts.zo_verbose >= 6)
(void) printf("\t%s\n", spa_name(spa));
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
static void
@@ -8140,10 +8143,8 @@ ztest_raidz_expand_run(ztest_shared_t *zs, spa_t *spa)
/* Setup a 1 MiB buffer of random data */
uint64_t bufsize = 1024 * 1024;
void *buffer = umem_alloc(bufsize, UMEM_NOFAIL);
+ random_get_pseudo_bytes((uint8_t *)&buffer, bufsize);
- if (read(ztest_fd_rand, buffer, bufsize) != bufsize) {
- fatal(B_TRUE, "short read from /dev/urandom");
- }
/*
* Put some data in the pool and then attach a vdev to initiate
* reflow.
@@ -8541,11 +8542,11 @@ ztest_run(ztest_shared_t *zs)
/*
* Verify that we can loop over all pools.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
for (spa = spa_next(NULL); spa != NULL; spa = spa_next(spa))
if (ztest_opts.zo_verbose > 3)
(void) printf("spa_next: found %s\n", spa_name(spa));
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
/*
* Verify that we can export the pool and reimport it under a
@@ -8949,13 +8950,13 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
+ libspl_init();
+
/*
* Force random_get_bytes() to use /dev/urandom in order to prevent
* ztest from needlessly depleting the system entropy pool.
*/
- random_path = "/dev/urandom";
- ztest_fd_rand = open(random_path, O_RDONLY | O_CLOEXEC);
- ASSERT3S(ztest_fd_rand, >=, 0);
+ random_force_pseudo(B_TRUE);
if (!fd_data_str) {
process_options(argc, argv);