diff options
Diffstat (limited to 'sys/contrib/openzfs/cmd')
| -rw-r--r-- | sys/contrib/openzfs/cmd/raidz_test/raidz_test.c | 1 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zdb/zdb.c | 222 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zfs/zfs_main.c | 46 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zfs/zfs_project.c | 36 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zhack.c | 135 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zinject/zinject.c | 81 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zpool/zpool_iter.c | 118 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zpool/zpool_main.c | 643 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zpool/zpool_util.h | 3 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zpool/zpool_vdev.c | 98 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/zstream/zstream_redup.c | 4 | ||||
| -rw-r--r-- | sys/contrib/openzfs/cmd/ztest.c | 57 |
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); |
