aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/cmd
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2024-05-31 07:31:58 +0000
committerMartin Matuska <mm@FreeBSD.org>2024-05-31 09:26:50 +0000
commitaca928a50a42f00f344df934005b09dbcb4e2f77 (patch)
tree810e8ee1828737bb6edb37ef594118fccbf58b45 /sys/contrib/openzfs/cmd
parentd28bbfa2715a45c841e0eeec38d7f7b73513c66e (diff)
parente2357561b9499296bff758afe4868dbc39735675 (diff)
zfs: merge openzfs/zfs@e2357561b
Notable upstream pull request merges: #15940 41ae864b6 Replace P2ALIGN with P2ALIGN_TYPED and delete P2ALIGN #16128 5137c132a zpool import output is not formated properly #16138 efbef9e6c FreeBSD: Add zfs_link_create() error handling #16146 04bae5ec9 Disable high priority ZIO threads on FreeBSD and Linux #16151 cc3869153 zfs_ioc_send: use a dedicated taskq thread for send #16151 adda768e3 spa: remove spa_taskq_dispatch_sync() #16151 515c4dd21 spa: flatten spa_taskq_dispatch_ent() #16151 0a543db37 spa_taskq_dispatch_ent: simplify arguments #16153 975a13259 Add support for parallel pool exports #16153 89acef992 Simplified the scope of the namespace lock #16159 136c05321 ZAP: Fix leaf references on zap_expand_leaf() errors #16162 af5dbed31 Fix scn_queue races on very old pools #16165 3400127a7 Fix ZIL clone records for legacy holes #16167 414acbd37 Unbreak FreeBSD cross-build on MacOS broken in 051460b8b #16172 eced2e2f1 libzfs: Fix mounting datasets under thread limit pressure #16178 b64afa41d Better control the thread pool size when mounting datasets #16181 fa99d9cd9 zfs_dbgmsg_print: make FreeBSD and Linux consistent #16191 e675852bc dbuf: separate refcount calls for dbuf and dbuf_user #16198 a043b60f1 Correct level handling in zstream recompress #16204 34906f8bb zap: reuse zap_leaf_t on dbuf reuse after shrink #16206 d0aa9dbcc Use memset to zero stack allocations containing unions #16207 8865dfbca Fix assertion in Persistent L2ARC #16208 08648cf0d Allow block cloning to be interrupted by a signal #16210 e2357561b FreeBSD: Add const qualifier to members of struct opensolaris_utsname #16214 800d59d57 Some improvements to metaslabs eviction #16216 02c5aa9b0 Destroy ARC buffer in case of fill error #16225 01c8efdd5 Simplify issig() Obtained from: OpenZFS OpenZFS commit: e2357561b9499296bff758afe4868dbc39735675
Diffstat (limited to 'sys/contrib/openzfs/cmd')
-rw-r--r--sys/contrib/openzfs/cmd/zdb/zdb.c132
-rw-r--r--sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c2
-rw-r--r--sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am2
-rwxr-xr-xsys/contrib/openzfs/cmd/zed/zed.d/deadman-slot_off.sh71
-rw-r--r--sys/contrib/openzfs/cmd/zed/zed.d/zed.rc7
-rw-r--r--sys/contrib/openzfs/cmd/zfs/zfs_main.c6
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_main.c377
-rw-r--r--sys/contrib/openzfs/cmd/zstream/zstream_recompress.c2
-rw-r--r--sys/contrib/openzfs/cmd/zstream/zstream_redup.c4
-rw-r--r--sys/contrib/openzfs/cmd/ztest.c32
10 files changed, 438 insertions, 197 deletions
diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c
index 449b6bf2ccb3..704fcf4422d4 100644
--- a/sys/contrib/openzfs/cmd/zdb/zdb.c
+++ b/sys/contrib/openzfs/cmd/zdb/zdb.c
@@ -85,6 +85,7 @@
#include <sys/brt_impl.h>
#include <zfs_comutil.h>
#include <sys/zstd/zstd.h>
+#include <sys/backtrace.h>
#include <libnvpair.h>
#include <libzutil.h>
@@ -120,6 +121,9 @@ static int flagbits[256];
static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */
static int leaked_objects = 0;
static range_tree_t *mos_refd_objs;
+static spa_t *spa;
+static objset_t *os;
+static boolean_t kernel_init_done;
static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *,
boolean_t);
@@ -131,6 +135,7 @@ static int dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t free,
static void zdb_print_blkptr(const blkptr_t *bp, int flags);
+static void zdb_exit(int reason);
typedef struct sublivelist_verify_block_refcnt {
/* block pointer entry in livelist being verified */
@@ -818,17 +823,40 @@ usage(void)
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
"to make only that option verbose\n");
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
- exit(1);
+ zdb_exit(1);
}
static void
dump_debug_buffer(void)
{
- if (dump_opt['G']) {
- (void) printf("\n");
- (void) fflush(stdout);
- zfs_dbgmsg_print("zdb");
- }
+ ssize_t ret __attribute__((unused));
+
+ if (!dump_opt['G'])
+ return;
+ /*
+ * We use write() instead of printf() so that this function
+ * is safe to call from a signal handler.
+ */
+ ret = write(STDERR_FILENO, "\n", 1);
+ zfs_dbgmsg_print(STDERR_FILENO, "zdb");
+}
+
+static void sig_handler(int signo)
+{
+ struct sigaction action;
+
+ libspl_backtrace(STDERR_FILENO);
+ dump_debug_buffer();
+
+ /*
+ * Restore default action and re-raise signal so SIGSEGV and
+ * SIGABRT can trigger a core dump.
+ */
+ action.sa_handler = SIG_DFL;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ (void) sigaction(signo, &action, NULL);
+ raise(signo);
}
/*
@@ -849,7 +877,7 @@ fatal(const char *fmt, ...)
dump_debug_buffer();
- exit(1);
+ zdb_exit(1);
}
static void
@@ -2276,7 +2304,7 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
buf = malloc(SPA_MAXBLOCKSIZE);
if (buf == NULL) {
(void) fprintf(stderr, "out of memory\n");
- exit(1);
+ zdb_exit(1);
}
decode_embedded_bp_compressed(bp, buf);
memcpy(&zstd_hdr, buf, sizeof (zstd_hdr));
@@ -3231,6 +3259,23 @@ fuid_table_destroy(void)
}
}
+static void
+zdb_exit(int reason)
+{
+ if (os != NULL) {
+ close_objset(os, FTAG);
+ } else if (spa != NULL) {
+ spa_close(spa, FTAG);
+ }
+
+ fuid_table_destroy();
+
+ if (kernel_init_done)
+ kernel_fini();
+
+ exit(reason);
+}
+
/*
* print uid or gid information.
* For normal POSIX id just the id is printed in decimal format.
@@ -4161,32 +4206,32 @@ dump_cachefile(const char *cachefile)
if ((fd = open64(cachefile, O_RDONLY)) < 0) {
(void) printf("cannot open '%s': %s\n", cachefile,
strerror(errno));
- exit(1);
+ zdb_exit(1);
}
if (fstat64(fd, &statbuf) != 0) {
(void) printf("failed to stat '%s': %s\n", cachefile,
strerror(errno));
- exit(1);
+ zdb_exit(1);
}
if ((buf = malloc(statbuf.st_size)) == NULL) {
(void) fprintf(stderr, "failed to allocate %llu bytes\n",
(u_longlong_t)statbuf.st_size);
- exit(1);
+ zdb_exit(1);
}
if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
(void) fprintf(stderr, "failed to read %llu bytes\n",
(u_longlong_t)statbuf.st_size);
- exit(1);
+ zdb_exit(1);
}
(void) close(fd);
if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) {
(void) fprintf(stderr, "failed to unpack nvlist\n");
- exit(1);
+ zdb_exit(1);
}
free(buf);
@@ -5102,14 +5147,14 @@ dump_label(const char *dev)
if ((fd = open64(path, O_RDONLY)) < 0) {
(void) printf("cannot open '%s': %s\n", path, strerror(errno));
- exit(1);
+ zdb_exit(1);
}
if (fstat64_blk(fd, &statbuf) != 0) {
(void) printf("failed to stat '%s': %s\n", path,
strerror(errno));
(void) close(fd);
- exit(1);
+ zdb_exit(1);
}
if (S_ISBLK(statbuf.st_mode) && zfs_dev_flush(fd) != 0)
@@ -5122,7 +5167,7 @@ dump_label(const char *dev)
sizeof (cksum_record_t), offsetof(cksum_record_t, link));
psize = statbuf.st_size;
- psize = P2ALIGN(psize, (uint64_t)sizeof (vdev_label_t));
+ psize = P2ALIGN_TYPED(psize, sizeof (vdev_label_t), uint64_t);
ashift = SPA_MINBLOCKSHIFT;
/*
@@ -8221,7 +8266,7 @@ dump_zpool(spa_t *spa)
if (rc != 0) {
dump_debug_buffer();
- exit(rc);
+ zdb_exit(rc);
}
}
@@ -8825,18 +8870,18 @@ zdb_embedded_block(char *thing)
words + 12, words + 13, words + 14, words + 15);
if (err != 16) {
(void) fprintf(stderr, "invalid input format\n");
- exit(1);
+ zdb_exit(1);
}
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
buf = malloc(SPA_MAXBLOCKSIZE);
if (buf == NULL) {
(void) fprintf(stderr, "out of memory\n");
- exit(1);
+ zdb_exit(1);
}
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
if (err != 0) {
(void) fprintf(stderr, "decode failed: %u\n", err);
- exit(1);
+ zdb_exit(1);
}
zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0);
free(buf);
@@ -8863,8 +8908,6 @@ int
main(int argc, char **argv)
{
int c;
- spa_t *spa = NULL;
- objset_t *os = NULL;
int dump_all = 1;
int verbose = 0;
int error = 0;
@@ -8880,10 +8923,28 @@ main(int argc, char **argv)
char *spa_config_path_env, *objset_str;
boolean_t target_is_spa = B_TRUE, dataset_lookup = B_FALSE;
nvlist_t *cfg = NULL;
+ struct sigaction action;
dprintf_setup(&argc, argv);
/*
+ * Set up signal handlers, so if we crash due to bad on-disk data we
+ * can get more info. Unlike ztest, we don't bail out if we can't set
+ * up signal handlers, because zdb is very useful without them.
+ */
+ action.sa_handler = sig_handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGSEGV, &action, NULL) < 0) {
+ (void) fprintf(stderr, "zdb: cannot catch SIGSEGV: %s\n",
+ strerror(errno));
+ }
+ if (sigaction(SIGABRT, &action, NULL) < 0) {
+ (void) fprintf(stderr, "zdb: cannot catch SIGABRT: %s\n",
+ strerror(errno));
+ }
+
+ /*
* If there is an environment variable SPA_CONFIG_PATH it overrides
* default spa_config_path setting. If -U flag is specified it will
* override this environment variable settings once again.
@@ -9093,6 +9154,7 @@ main(int argc, char **argv)
spa_mode_readable_spacemaps = B_TRUE;
kernel_init(SPA_MODE_READ);
+ kernel_init_done = B_TRUE;
if (dump_all)
verbose = MAX(verbose, 1);
@@ -9116,19 +9178,23 @@ main(int argc, char **argv)
if (argc != 1)
usage();
zdb_embedded_block(argv[0]);
- return (0);
+ error = 0;
+ goto fini;
}
if (argc < 1) {
if (!dump_opt['e'] && dump_opt['C']) {
dump_cachefile(spa_config_path);
- return (0);
+ error = 0;
+ goto fini;
}
usage();
}
- if (dump_opt['l'])
- return (dump_label(argv[0]));
+ if (dump_opt['l']) {
+ error = dump_label(argv[0]);
+ goto fini;
+ }
if (dump_opt['X'] || dump_opt['F'])
rewind = ZPOOL_DO_REWIND |
@@ -9183,7 +9249,8 @@ main(int argc, char **argv)
} else if (objset_str && !zdb_numeric(objset_str + 1) &&
dump_opt['N']) {
printf("Supply a numeric objset ID with -N\n");
- exit(1);
+ error = 1;
+ goto fini;
}
} else {
target_pool = target;
@@ -9240,7 +9307,8 @@ main(int argc, char **argv)
if (argc != 2)
usage();
dump_opt['v'] = verbose + 3;
- return (dump_path(argv[0], argv[1], NULL));
+ error = dump_path(argv[0], argv[1], NULL);
+ goto fini;
}
if (dump_opt['r']) {
@@ -9328,7 +9396,7 @@ main(int argc, char **argv)
fatal("can't dump '%s': %s", target,
strerror(error));
}
- return (error);
+ goto fini;
} else {
target_pool = strdup(target);
if (strpbrk(target, "/@") != NULL)
@@ -9458,9 +9526,10 @@ retry_lookup:
free(checkpoint_target);
}
+fini:
if (os != NULL) {
close_objset(os, FTAG);
- } else {
+ } else if (spa != NULL) {
spa_close(spa, FTAG);
}
@@ -9468,7 +9537,8 @@ retry_lookup:
dump_debug_buffer();
- kernel_fini();
+ if (kernel_init_done)
+ kernel_fini();
return (error);
}
diff --git a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
index 69163b80bd5a..d0372608c723 100644
--- a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
+++ b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
@@ -702,7 +702,7 @@ zfs_enable_ds(void *arg)
{
unavailpool_t *pool = (unavailpool_t *)arg;
- (void) zpool_enable_datasets(pool->uap_zhp, NULL, 0);
+ (void) zpool_enable_datasets(pool->uap_zhp, NULL, 0, 512);
zpool_close(pool->uap_zhp);
free(pool);
}
diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am b/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am
index 812558cf6d0f..093a04c4636a 100644
--- a/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am
+++ b/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am
@@ -9,6 +9,7 @@ dist_zedexec_SCRIPTS = \
%D%/all-debug.sh \
%D%/all-syslog.sh \
%D%/data-notify.sh \
+ %D%/deadman-slot_off.sh \
%D%/generic-notify.sh \
%D%/pool_import-led.sh \
%D%/resilver_finish-notify.sh \
@@ -29,6 +30,7 @@ SUBSTFILES += $(nodist_zedexec_SCRIPTS)
zedconfdefaults = \
all-syslog.sh \
data-notify.sh \
+ deadman-slot_off.sh \
history_event-zfs-list-cacher.sh \
pool_import-led.sh \
resilver_finish-notify.sh \
diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/deadman-slot_off.sh b/sys/contrib/openzfs/cmd/zed/zed.d/deadman-slot_off.sh
new file mode 100755
index 000000000000..7b339b3add01
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zed/zed.d/deadman-slot_off.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+# shellcheck disable=SC3014,SC2154,SC2086,SC2034
+#
+# Turn off disk's enclosure slot if an I/O is hung triggering the deadman.
+#
+# It's possible for outstanding I/O to a misbehaving SCSI disk to neither
+# promptly complete or return an error. This can occur due to retry and
+# recovery actions taken by the SCSI layer, driver, or disk. When it occurs
+# the pool will be unresponsive even though there may be sufficient redundancy
+# configured to proceeded without this single disk.
+#
+# When a hung I/O is detected by the kmods it will be posted as a deadman
+# event. By default an I/O is considered to be hung after 5 minutes. This
+# value can be changed with the zfs_deadman_ziotime_ms module parameter.
+# If ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN is set the disk's enclosure
+# slot will be powered off causing the outstanding I/O to fail. The ZED
+# will then handle this like a normal disk failure and FAULT the vdev.
+#
+# We assume the user will be responsible for turning the slot back on
+# after replacing the disk.
+#
+# Note that this script requires that your enclosure be supported by the
+# Linux SCSI Enclosure services (SES) driver. The script will do nothing
+# if you have no enclosure, or if your enclosure isn't supported.
+#
+# Exit codes:
+# 0: slot successfully powered off
+# 1: enclosure not available
+# 2: ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN disabled
+# 3: System not configured to wait on deadman
+# 4: The enclosure sysfs path passed from ZFS does not exist
+# 5: Enclosure slot didn't actually turn off after we told it to
+
+[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
+. "${ZED_ZEDLET_DIR}/zed-functions.sh"
+
+if [ ! -d /sys/class/enclosure ] ; then
+ # No JBOD enclosure or NVMe slots
+ exit 1
+fi
+
+if [ "${ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN}" != "1" ] ; then
+ exit 2
+fi
+
+if [ "$ZEVENT_POOL_FAILMODE" != "wait" ] ; then
+ exit 3
+fi
+
+if [ ! -f "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status" ] ; then
+ exit 4
+fi
+
+# Turn off the slot and wait for sysfs to report that the slot is off.
+# It can take ~400ms on some enclosures and multiple retries may be needed.
+for i in $(seq 1 20) ; do
+ echo "off" | tee "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status"
+
+ for j in $(seq 1 5) ; do
+ if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" == "off" ] ; then
+ break 2
+ fi
+ sleep 0.1
+ done
+done
+
+if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" != "off" ] ; then
+ exit 5
+fi
+
+zed_log_msg "powered down slot $ZEVENT_VDEV_ENC_SYSFS_PATH for $ZEVENT_VDEV_PATH"
diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/zed.rc b/sys/contrib/openzfs/cmd/zed/zed.d/zed.rc
index ec64ecfaa13c..af56147a969b 100644
--- a/sys/contrib/openzfs/cmd/zed/zed.d/zed.rc
+++ b/sys/contrib/openzfs/cmd/zed/zed.d/zed.rc
@@ -149,6 +149,13 @@ ZED_SYSLOG_SUBCLASS_EXCLUDE="history_event"
#ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT=1
##
+# Power off the drive's slot in the enclosure if there is a hung I/O which
+# exceeds the deadman timeout. This can help prevent a single misbehaving
+# drive from rendering a redundant pool unavailable. This assumes your drive
+# enclosure fully supports slot power control via sysfs.
+#ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN=1
+
+##
# Ntfy topic
# This defines which topic will receive the ntfy notification.
# <https://docs.ntfy.sh/publish/>
diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_main.c b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
index 3fc2d2810495..b77917764c86 100644
--- a/sys/contrib/openzfs/cmd/zfs/zfs_main.c
+++ b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
@@ -7192,6 +7192,8 @@ share_mount(int op, int argc, char **argv)
int c, ret = 0;
char *options = NULL;
int flags = 0;
+ const uint_t mount_nthr = 512;
+ uint_t nthr;
/* check options */
while ((c = getopt(argc, argv, op == OP_MOUNT ? ":aRlvo:Of" : "al"))
@@ -7310,9 +7312,9 @@ share_mount(int op, int argc, char **argv)
* be serialized so that we can prompt the user for their keys
* in a consistent manner.
*/
+ nthr = op == OP_MOUNT && !(flags & MS_CRYPT) ? mount_nthr : 1;
zfs_foreach_mountpoint(g_zfs, cb.cb_handles, cb.cb_used,
- share_mount_one_cb, &share_mount_state,
- op == OP_MOUNT && !(flags & MS_CRYPT));
+ share_mount_one_cb, &share_mount_state, nthr);
zfs_commit_shares(NULL);
ret = share_mount_state.sm_status;
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
index 300b383af4f6..57170c8ae717 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
@@ -80,6 +80,8 @@
libzfs_handle_t *g_zfs;
+static int mount_tp_nthr = 512; /* tpool threads for multi-threaded mounting */
+
static int zpool_do_create(int, char **);
static int zpool_do_destroy(int, char **);
@@ -2030,10 +2032,19 @@ zpool_do_destroy(int argc, char **argv)
}
typedef struct export_cbdata {
+ tpool_t *tpool;
+ pthread_mutex_t mnttab_lock;
boolean_t force;
boolean_t hardforce;
+ int retval;
} export_cbdata_t;
+
+typedef struct {
+ char *aea_poolname;
+ export_cbdata_t *aea_cbdata;
+} async_export_args_t;
+
/*
* Export one pool
*/
@@ -2042,11 +2053,20 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
{
export_cbdata_t *cb = data;
- if (zpool_disable_datasets(zhp, cb->force) != 0)
- return (1);
+ /*
+ * zpool_disable_datasets() is not thread-safe for mnttab access.
+ * So we serialize access here for 'zpool export -a' parallel case.
+ */
+ if (cb->tpool != NULL)
+ pthread_mutex_lock(&cb->mnttab_lock);
- /* The history must be logged as part of the export */
- log_history = B_FALSE;
+ int retval = zpool_disable_datasets(zhp, cb->force);
+
+ if (cb->tpool != NULL)
+ pthread_mutex_unlock(&cb->mnttab_lock);
+
+ if (retval)
+ return (1);
if (cb->hardforce) {
if (zpool_export_force(zhp, history_str) != 0)
@@ -2059,6 +2079,48 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
}
/*
+ * Asynchronous export request
+ */
+static void
+zpool_export_task(void *arg)
+{
+ async_export_args_t *aea = arg;
+
+ zpool_handle_t *zhp = zpool_open(g_zfs, aea->aea_poolname);
+ if (zhp != NULL) {
+ int ret = zpool_export_one(zhp, aea->aea_cbdata);
+ if (ret != 0)
+ aea->aea_cbdata->retval = ret;
+ zpool_close(zhp);
+ } else {
+ aea->aea_cbdata->retval = 1;
+ }
+
+ free(aea->aea_poolname);
+ free(aea);
+}
+
+/*
+ * Process an export request in parallel
+ */
+static int
+zpool_export_one_async(zpool_handle_t *zhp, void *data)
+{
+ tpool_t *tpool = ((export_cbdata_t *)data)->tpool;
+ async_export_args_t *aea = safe_malloc(sizeof (async_export_args_t));
+
+ /* save pool name since zhp will go out of scope */
+ aea->aea_poolname = strdup(zpool_get_name(zhp));
+ aea->aea_cbdata = data;
+
+ /* ship off actual export to another thread */
+ if (tpool_dispatch(tpool, zpool_export_task, (void *)aea) != 0)
+ return (errno); /* unlikely */
+ else
+ return (0);
+}
+
+/*
* zpool export [-f] <pool> ...
*
* -a Export all pools
@@ -2098,17 +2160,33 @@ zpool_do_export(int argc, char **argv)
cb.force = force;
cb.hardforce = hardforce;
+ cb.tpool = NULL;
+ cb.retval = 0;
argc -= optind;
argv += optind;
+ /* The history will be logged as part of the export itself */
+ log_history = B_FALSE;
+
if (do_all) {
if (argc != 0) {
(void) fprintf(stderr, gettext("too many arguments\n"));
usage(B_FALSE);
}
- return (for_each_pool(argc, argv, B_TRUE, NULL,
- ZFS_TYPE_POOL, B_FALSE, zpool_export_one, &cb));
+ cb.tpool = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
+ 0, NULL);
+ 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,
+ B_FALSE, zpool_export_one_async, &cb);
+
+ tpool_wait(cb.tpool);
+ tpool_destroy(cb.tpool);
+ (void) pthread_mutex_destroy(&cb.mnttab_lock);
+
+ return (ret | cb.retval);
}
/* check arguments */
@@ -2938,6 +3016,7 @@ show_import(nvlist_t *config, boolean_t report_error)
const char *health;
uint_t vsc;
const char *comment;
+ const char *indent;
status_cbdata_t cb = { 0 };
verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
@@ -2962,82 +3041,84 @@ show_import(nvlist_t *config, boolean_t report_error)
if (reason != ZPOOL_STATUS_OK && !report_error)
return (reason);
- (void) printf(gettext(" pool: %s\n"), name);
- (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
- (void) printf(gettext(" state: %s"), health);
+ if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0) {
+ indent = " ";
+ } else {
+ comment = NULL;
+ indent = "";
+ }
+
+ (void) printf(gettext("%s pool: %s\n"), indent, name);
+ (void) printf(gettext("%s id: %llu\n"), indent, (u_longlong_t)guid);
+ (void) printf(gettext("%s state: %s"), indent, health);
if (pool_state == POOL_STATE_DESTROYED)
(void) printf(gettext(" (DESTROYED)"));
(void) printf("\n");
+ if (reason != ZPOOL_STATUS_OK) {
+ (void) printf("%s", indent);
+ 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_BOLD, gettext("status: "));
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_BOLD, gettext("status: "));
- printf_color(ANSI_YELLOW, gettext("One or more devices contains"
- " corrupted data.\n"));
+ printf_color(ANSI_YELLOW, gettext("One or more devices "
+ "contains corrupted data.\n"));
break;
case ZPOOL_STATUS_CORRUPT_DATA:
- (void) printf(
- gettext(" status: The pool data is corrupted.\n"));
+ printf_color(ANSI_YELLOW, gettext("The pool data is "
+ "corrupted.\n"));
break;
case ZPOOL_STATUS_OFFLINE_DEV:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("One or more devices "
"are offlined.\n"));
break;
case ZPOOL_STATUS_CORRUPT_POOL:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("The pool metadata is "
"corrupted.\n"));
break;
case ZPOOL_STATUS_VERSION_OLDER:
- printf_color(ANSI_BOLD, gettext("status: "));
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_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("The pool is formatted using "
"an incompatible version.\n"));
break;
case ZPOOL_STATUS_FEAT_DISABLED:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("Some supported "
- "features are not enabled on the pool.\n\t"
- "(Note that they may be intentionally disabled "
- "if the\n\t'compatibility' property is set.)\n"));
+ "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_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("Error reading or parsing "
"the file(s) indicated by the 'compatibility'\n"
- "property.\n"));
+ "\t%sproperty.\n"), indent);
break;
case ZPOOL_STATUS_INCOMPATIBLE_FEAT:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("One or more features "
"are enabled on the pool despite not being\n"
- "requested by the 'compatibility' property.\n"));
+ "\t%srequested by the 'compatibility' property.\n"),
+ indent);
break;
case ZPOOL_STATUS_UNSUP_FEAT_READ:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("The pool uses the following "
"feature(s) not supported on this system:\n"));
color_start(ANSI_YELLOW);
@@ -3046,66 +3127,60 @@ show_import(nvlist_t *config, boolean_t report_error)
break;
case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, 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"));
+ "accessed in read-only mode on this system. It\n"
+ "\t%scannot be accessed in read-write mode because it uses "
+ "the following\n"
+ "\t%sfeature(s) not supported on this system:\n"),
+ indent, indent);
color_start(ANSI_YELLOW);
zpool_print_unsup_feat(config);
color_end();
break;
case ZPOOL_STATUS_HOSTID_ACTIVE:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("The pool is currently "
"imported by another system.\n"));
break;
case ZPOOL_STATUS_HOSTID_REQUIRED:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("The pool has the "
- "multihost property on. It cannot\n\tbe safely imported "
- "when the system hostid is not set.\n"));
+ "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_BOLD, gettext("status: "));
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_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("One or more devices are "
"faulted.\n"));
break;
case ZPOOL_STATUS_BAD_LOG:
- printf_color(ANSI_BOLD, gettext("status: "));
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_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("One or more devices were "
"being resilvered.\n"));
break;
case ZPOOL_STATUS_ERRATA:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"),
errata);
break;
case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
- printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("One or more devices are "
"configured to use a non-native block size.\n"
- "\tExpect reduced performance.\n"));
+ "\t%sExpect reduced performance.\n"), indent);
break;
default:
@@ -3118,114 +3193,121 @@ show_import(nvlist_t *config, boolean_t report_error)
/*
* Print out an action according to the overall state of the pool.
*/
+ if (vs->vs_state != VDEV_STATE_HEALTHY ||
+ reason != ZPOOL_STATUS_ERRATA || errata != ZPOOL_ERRATA_NONE) {
+ (void) printf("%s", indent);
+ (void) printf(gettext("action: "));
+ }
if (vs->vs_state == VDEV_STATE_HEALTHY) {
if (reason == ZPOOL_STATUS_VERSION_OLDER ||
reason == ZPOOL_STATUS_FEAT_DISABLED) {
- (void) printf(gettext(" action: The pool can be "
- "imported using its name or numeric identifier, "
- "though\n\tsome features will not be available "
- "without an explicit 'zpool upgrade'.\n"));
+ (void) printf(gettext("The pool can be imported using "
+ "its name or numeric identifier, though\n"
+ "\t%ssome features will not be available without "
+ "an explicit 'zpool upgrade'.\n"), indent);
} else if (reason == ZPOOL_STATUS_COMPATIBILITY_ERR) {
- (void) printf(gettext(" action: The pool can be "
- "imported using its name or numeric\n\tidentifier, "
- "though the file(s) indicated by its "
- "'compatibility'\n\tproperty cannot be parsed at "
- "this time.\n"));
+ (void) printf(gettext("The pool can be imported using "
+ "its name or numeric\n"
+ "\t%sidentifier, though the file(s) indicated by "
+ "its 'compatibility'\n"
+ "\t%sproperty cannot be parsed at this time.\n"),
+ indent, indent);
} else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
- (void) printf(gettext(" action: The pool can be "
- "imported using its name or numeric "
- "identifier and\n\tthe '-f' flag.\n"));
+ (void) printf(gettext("The pool can be imported using "
+ "its name or numeric identifier and\n"
+ "\t%sthe '-f' flag.\n"), indent);
} else if (reason == ZPOOL_STATUS_ERRATA) {
switch (errata) {
- case ZPOOL_ERRATA_NONE:
- break;
-
case ZPOOL_ERRATA_ZOL_2094_SCRUB:
- (void) printf(gettext(" action: The pool can "
- "be imported using its name or numeric "
- "identifier,\n\thowever there is a compat"
- "ibility issue which should be corrected"
- "\n\tby running 'zpool scrub'\n"));
+ (void) printf(gettext("The pool can be "
+ "imported using its name or numeric "
+ "identifier,\n"
+ "\t%showever there is a compatibility "
+ "issue which should be corrected\n"
+ "\t%sby running 'zpool scrub'\n"),
+ indent, indent);
break;
case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY:
- (void) printf(gettext(" action: The pool can"
- "not be imported with this version of ZFS "
- "due to\n\tan active asynchronous destroy. "
- "Revert to an earlier version\n\tand "
- "allow the destroy to complete before "
- "updating.\n"));
+ (void) printf(gettext("The pool cannot be "
+ "imported with this version of ZFS due to\n"
+ "\t%san active asynchronous destroy. "
+ "Revert to an earlier version\n"
+ "\t%sand allow the destroy to complete "
+ "before updating.\n"), indent, indent);
break;
case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION:
- (void) printf(gettext(" action: Existing "
- "encrypted datasets contain an on-disk "
- "incompatibility, which\n\tneeds to be "
- "corrected. Backup these datasets to new "
- "encrypted datasets\n\tand destroy the "
- "old ones.\n"));
+ (void) printf(gettext("Existing encrypted "
+ "datasets contain an on-disk "
+ "incompatibility, which\n"
+ "\t%sneeds to be corrected. Backup these "
+ "datasets to new encrypted datasets\n"
+ "\t%sand destroy the old ones.\n"),
+ indent, indent);
break;
case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION:
- (void) printf(gettext(" action: Existing "
- "encrypted snapshots and bookmarks contain "
- "an on-disk\n\tincompatibility. This may "
- "cause on-disk corruption if they are used"
- "\n\twith 'zfs recv'. To correct the "
- "issue, enable the bookmark_v2 feature.\n\t"
- "No additional action is needed if there "
- "are no encrypted snapshots or\n\t"
- "bookmarks. If preserving the encrypted "
- "snapshots and bookmarks is\n\trequired, "
- "use a non-raw send to backup and restore "
- "them. Alternately,\n\tthey may be removed"
- " to resolve the incompatibility.\n"));
+ (void) printf(gettext("Existing encrypted "
+ "snapshots and bookmarks contain an "
+ "on-disk\n"
+ "\t%sincompatibility. This may cause "
+ "on-disk corruption if they are used\n"
+ "\t%swith 'zfs recv'. To correct the "
+ "issue, enable the bookmark_v2 feature.\n"
+ "\t%sNo additional action is needed if "
+ "there are no encrypted snapshots or\n"
+ "\t%sbookmarks. If preserving the "
+ "encrypted snapshots and bookmarks is\n"
+ "\t%srequired, use a non-raw send to "
+ "backup and restore them. Alternately,\n"
+ "\t%sthey may be removed to resolve the "
+ "incompatibility.\n"), indent, indent,
+ indent, indent, indent, indent);
break;
default:
/*
* All errata must contain an action message.
*/
- assert(0);
+ assert(errata == ZPOOL_ERRATA_NONE);
}
} else {
- (void) printf(gettext(" action: The pool can be "
- "imported using its name or numeric "
- "identifier.\n"));
+ (void) printf(gettext("The pool can be imported using "
+ "its name or numeric identifier.\n"));
}
} else if (vs->vs_state == VDEV_STATE_DEGRADED) {
- (void) printf(gettext(" action: The pool can be imported "
- "despite missing or damaged devices. The\n\tfault "
- "tolerance of the pool may be compromised if imported.\n"));
+ (void) printf(gettext("The pool can be imported despite "
+ "missing or damaged devices. The\n"
+ "\t%sfault tolerance of the pool may be compromised if "
+ "imported.\n"), indent);
} else {
switch (reason) {
case ZPOOL_STATUS_VERSION_NEWER:
- (void) printf(gettext(" action: The pool cannot be "
- "imported. Access the pool on a system running "
- "newer\n\tsoftware, or recreate the pool from "
- "backup.\n"));
+ (void) printf(gettext("The pool cannot be imported. "
+ "Access the pool on a system running newer\n"
+ "\t%ssoftware, or recreate the pool from "
+ "backup.\n"), indent);
break;
case ZPOOL_STATUS_UNSUP_FEAT_READ:
- printf_color(ANSI_BOLD, gettext("action: "));
- printf_color(ANSI_YELLOW, gettext("The pool cannot be "
- "imported. Access the pool on a system that "
- "supports\n\tthe required feature(s), or recreate "
- "the pool from backup.\n"));
+ (void) printf(gettext("The pool cannot be imported. "
+ "Access the pool on a system that supports\n"
+ "\t%sthe required feature(s), or recreate the pool "
+ "from backup.\n"), indent);
break;
case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
- printf_color(ANSI_BOLD, gettext("action: "));
- printf_color(ANSI_YELLOW, gettext("The pool cannot be "
- "imported in read-write mode. Import the pool "
- "with\n"
- "\t\"-o readonly=on\", access the pool on a system "
- "that supports the\n\trequired feature(s), or "
- "recreate the pool from backup.\n"));
+ (void) printf(gettext("The pool cannot be imported in "
+ "read-write mode. Import the pool with\n"
+ "\t%s'-o readonly=on', access the pool on a system "
+ "that supports the\n"
+ "\t%srequired feature(s), or recreate the pool "
+ "from backup.\n"), indent, indent);
break;
case ZPOOL_STATUS_MISSING_DEV_R:
case ZPOOL_STATUS_MISSING_DEV_NR:
case ZPOOL_STATUS_BAD_GUID_SUM:
- (void) printf(gettext(" action: The pool cannot be "
- "imported. Attach the missing\n\tdevices and try "
- "again.\n"));
+ (void) printf(gettext("The pool cannot be imported. "
+ "Attach the missing\n"
+ "\t%sdevices and try again.\n"), indent);
break;
case ZPOOL_STATUS_HOSTID_ACTIVE:
VERIFY0(nvlist_lookup_nvlist(config,
@@ -3239,47 +3321,49 @@ show_import(nvlist_t *config, boolean_t report_error)
hostid = fnvlist_lookup_uint64(nvinfo,
ZPOOL_CONFIG_MMP_HOSTID);
- (void) printf(gettext(" action: The pool must be "
- "exported from %s (hostid=%"PRIx64")\n\tbefore it "
- "can be safely imported.\n"), hostname, hostid);
+ (void) printf(gettext("The pool must be exported from "
+ "%s (hostid=%"PRIx64")\n"
+ "\t%sbefore it can be safely imported.\n"),
+ hostname, hostid, indent);
break;
case ZPOOL_STATUS_HOSTID_REQUIRED:
- (void) printf(gettext(" action: Set a unique system "
- "hostid with the zgenhostid(8) command.\n"));
+ (void) printf(gettext("Set a unique system hostid with "
+ "the zgenhostid(8) command.\n"));
break;
default:
- (void) printf(gettext(" action: The pool cannot be "
- "imported due to damaged devices or data.\n"));
+ (void) printf(gettext("The pool cannot be imported due "
+ "to damaged devices or data.\n"));
}
}
/* Print the comment attached to the pool. */
- if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
+ if (comment != NULL)
(void) printf(gettext("comment: %s\n"), comment);
/*
* If the state is "closed" or "can't open", and the aux state
* is "corrupt data":
*/
- if (((vs->vs_state == VDEV_STATE_CLOSED) ||
- (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
- (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
+ if ((vs->vs_state == VDEV_STATE_CLOSED ||
+ vs->vs_state == VDEV_STATE_CANT_OPEN) &&
+ vs->vs_aux == VDEV_AUX_CORRUPT_DATA) {
if (pool_state == POOL_STATE_DESTROYED)
- (void) printf(gettext("\tThe pool was destroyed, "
- "but can be imported using the '-Df' flags.\n"));
+ (void) printf(gettext("\t%sThe pool was destroyed, "
+ "but can be imported using the '-Df' flags.\n"),
+ indent);
else if (pool_state != POOL_STATE_EXPORTED)
- (void) printf(gettext("\tThe pool may be active on "
- "another system, but can be imported using\n\t"
- "the '-f' flag.\n"));
+ (void) printf(gettext("\t%sThe pool may be active on "
+ "another system, but can be imported using\n"
+ "\t%sthe '-f' flag.\n"), indent, indent);
}
if (msgid != NULL) {
- (void) printf(gettext(
- " see: https://openzfs.github.io/openzfs-docs/msg/%s\n"),
- msgid);
+ (void) printf(gettext("%s see: "
+ "https://openzfs.github.io/openzfs-docs/msg/%s\n"),
+ indent, msgid);
}
- (void) printf(gettext(" config:\n\n"));
+ (void) printf(gettext("%sconfig:\n\n"), indent);
cb.cb_namewidth = max_width(NULL, nvroot, 0, strlen(name),
VDEV_NAME_TYPE_ID);
@@ -3293,9 +3377,10 @@ show_import(nvlist_t *config, boolean_t report_error)
print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS);
if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
- (void) printf(gettext("\n\tAdditional devices are known to "
- "be part of this pool, though their\n\texact "
- "configuration cannot be determined.\n"));
+ (void) printf(gettext("\n\t%sAdditional devices are known to "
+ "be part of this pool, though their\n"
+ "\t%sexact configuration cannot be determined.\n"),
+ indent, indent);
}
return (0);
}
@@ -3342,7 +3427,7 @@ zfs_force_import_required(nvlist_t *config)
*/
static int
do_import(nvlist_t *config, const char *newname, const char *mntopts,
- nvlist_t *props, int flags)
+ nvlist_t *props, int flags, uint_t mntthreads)
{
int ret = 0;
int ms_status = 0;
@@ -3442,7 +3527,7 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
!(flags & ZFS_IMPORT_ONLY)) {
- ms_status = zpool_enable_datasets(zhp, mntopts, 0);
+ ms_status = zpool_enable_datasets(zhp, mntopts, 0, mntthreads);
if (ms_status == EZFS_SHAREFAILED) {
(void) fprintf(stderr, gettext("Import was "
"successful, but unable to share some datasets\n"));
@@ -3461,6 +3546,7 @@ typedef struct import_parameters {
const char *ip_mntopts;
nvlist_t *ip_props;
int ip_flags;
+ uint_t ip_mntthreads;
int *ip_err;
} import_parameters_t;
@@ -3469,7 +3555,7 @@ do_import_task(void *arg)
{
import_parameters_t *ip = arg;
*ip->ip_err |= do_import(ip->ip_config, NULL, ip->ip_mntopts,
- ip->ip_props, ip->ip_flags);
+ ip->ip_props, ip->ip_flags, ip->ip_mntthreads);
free(ip);
}
@@ -3483,6 +3569,7 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
uint64_t pool_state;
boolean_t pool_specified = (import->poolname != NULL ||
import->guid != 0);
+ uint_t npools = 0;
tpool_t *tp = NULL;
@@ -3500,6 +3587,10 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
int err = 0;
nvpair_t *elem = NULL;
boolean_t first = B_TRUE;
+ if (!pool_specified && import->do_all) {
+ while ((elem = nvlist_next_nvpair(pools, elem)) != NULL)
+ npools++;
+ }
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
verify(nvpair_value_nvlist(elem, &config) == 0);
@@ -3530,6 +3621,7 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
ip->ip_mntopts = mntopts;
ip->ip_props = props;
ip->ip_flags = flags;
+ ip->ip_mntthreads = mount_tp_nthr / npools;
ip->ip_err = &err;
(void) tpool_dispatch(tp, do_import_task,
@@ -3597,7 +3689,7 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
err = B_TRUE;
} else {
err |= do_import(found_config, new_name,
- mntopts, props, flags);
+ mntopts, props, flags, mount_tp_nthr);
}
}
@@ -7141,7 +7233,8 @@ zpool_do_split(int argc, char **argv)
}
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) {
- ms_status = zpool_enable_datasets(zhp, mntopts, 0);
+ ms_status = zpool_enable_datasets(zhp, mntopts, 0,
+ mount_tp_nthr);
if (ms_status == EZFS_SHAREFAILED) {
(void) fprintf(stderr, gettext("Split was successful, "
"datasets are mounted but sharing of some datasets "
diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_recompress.c b/sys/contrib/openzfs/cmd/zstream/zstream_recompress.c
index 8392ef3de72f..f9e01d1aa4c4 100644
--- a/sys/contrib/openzfs/cmd/zstream/zstream_recompress.c
+++ b/sys/contrib/openzfs/cmd/zstream/zstream_recompress.c
@@ -77,7 +77,7 @@ zstream_do_recompress(int argc, char *argv[])
while ((c = getopt(argc, argv, "l:")) != -1) {
switch (c) {
case 'l':
- if (sscanf(optarg, "%d", &level) != 0) {
+ if (sscanf(optarg, "%d", &level) != 1) {
fprintf(stderr,
"failed to parse level '%s'\n",
optarg);
diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_redup.c b/sys/contrib/openzfs/cmd/zstream/zstream_redup.c
index c56a09cee75d..6866639fe465 100644
--- a/sys/contrib/openzfs/cmd/zstream/zstream_redup.c
+++ b/sys/contrib/openzfs/cmd/zstream/zstream_redup.c
@@ -186,7 +186,7 @@ static void
zfs_redup_stream(int infd, int outfd, boolean_t verbose)
{
int bufsz = SPA_MAXBLOCKSIZE;
- dmu_replay_record_t thedrr = { 0 };
+ dmu_replay_record_t thedrr;
dmu_replay_record_t *drr = &thedrr;
redup_table_t rdt;
zio_cksum_t stream_cksum;
@@ -194,6 +194,8 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
uint64_t num_records = 0;
uint64_t num_write_byref_records = 0;
+ memset(&thedrr, 0, sizeof (dmu_replay_record_t));
+
#ifdef _ILP32
uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20;
#else
diff --git a/sys/contrib/openzfs/cmd/ztest.c b/sys/contrib/openzfs/cmd/ztest.c
index b0fea8b3cfb4..f77a37c21545 100644
--- a/sys/contrib/openzfs/cmd/ztest.c
+++ b/sys/contrib/openzfs/cmd/ztest.c
@@ -136,9 +136,7 @@
#include <libzutil.h>
#include <sys/crypto/icp.h>
#include <sys/zfs_impl.h>
-#if (__GLIBC__ && !__UCLIBC__)
-#include <execinfo.h> /* for backtrace() */
-#endif
+#include <sys/backtrace.h>
static int ztest_fd_data = -1;
static int ztest_fd_rand = -1;
@@ -617,22 +615,15 @@ dump_debug_buffer(void)
* We use write() instead of printf() so that this function
* is safe to call from a signal handler.
*/
- ret = write(STDOUT_FILENO, "\n", 1);
- zfs_dbgmsg_print("ztest");
+ ret = write(STDERR_FILENO, "\n", 1);
+ zfs_dbgmsg_print(STDERR_FILENO, "ztest");
}
-#define BACKTRACE_SZ 100
-
static void sig_handler(int signo)
{
struct sigaction action;
-#if (__GLIBC__ && !__UCLIBC__) /* backtrace() is a GNU extension */
- int nptrs;
- void *buffer[BACKTRACE_SZ];
- nptrs = backtrace(buffer, BACKTRACE_SZ);
- backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO);
-#endif
+ libspl_backtrace(STDERR_FILENO);
dump_debug_buffer();
/*
@@ -2529,7 +2520,7 @@ ztest_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
ASSERT3P(zio, !=, NULL);
size = doi.doi_data_block_size;
if (ISP2(size)) {
- offset = P2ALIGN(offset, size);
+ offset = P2ALIGN_TYPED(offset, size, uint64_t);
} else {
ASSERT3U(offset, <, size);
offset = 0;
@@ -3978,7 +3969,8 @@ raidz_scratch_verify(void)
raidvd = vdev_lookup_top(spa, vre->vre_vdev_id);
offset = RRSS_GET_OFFSET(&spa->spa_uberblock);
state = RRSS_GET_STATE(&spa->spa_uberblock);
- write_size = P2ALIGN(VDEV_BOOT_SIZE, 1 << raidvd->vdev_ashift);
+ write_size = P2ALIGN_TYPED(VDEV_BOOT_SIZE, 1 << raidvd->vdev_ashift,
+ uint64_t);
logical_size = write_size * raidvd->vdev_children;
switch (state) {
@@ -5016,7 +5008,8 @@ ztest_dmu_object_next_chunk(ztest_ds_t *zd, uint64_t id)
*/
mutex_enter(&os->os_obj_lock);
object = ztest_random(os->os_obj_next_chunk);
- os->os_obj_next_chunk = P2ALIGN(object, dnodes_per_chunk);
+ os->os_obj_next_chunk = P2ALIGN_TYPED(object, dnodes_per_chunk,
+ uint64_t);
mutex_exit(&os->os_obj_lock);
}
@@ -6638,7 +6631,8 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
* the end of the disk (vdev_psize) is aligned to
* sizeof (vdev_label_t).
*/
- uint64_t psize = P2ALIGN(fsize, sizeof (vdev_label_t));
+ uint64_t psize = P2ALIGN_TYPED(fsize, sizeof (vdev_label_t),
+ uint64_t);
if ((leaf & 1) == 1 &&
offset + sizeof (bad) > psize - VDEV_LABEL_END_SIZE)
continue;
@@ -6962,8 +6956,8 @@ ztest_fletcher_incr(ztest_ds_t *zd, uint64_t id)
size_t inc = 64 * ztest_random(size / 67);
/* sometimes add few bytes to test non-simd */
if (ztest_random(100) < 10)
- inc += P2ALIGN(ztest_random(64),
- sizeof (uint32_t));
+ inc += P2ALIGN_TYPED(ztest_random(64),
+ sizeof (uint32_t), uint64_t);
if (inc > (size - pos))
inc = size - pos;