summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libzfs.h1
-rw-r--r--lib/libzfs/libzfs_pool.c6
-rw-r--r--lib/libzfs/libzfs_util.c3
-rw-r--r--man/man8/zpool.84
-rw-r--r--module/zfs/spa.c4
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_bad_args.ksh13
6 files changed, 30 insertions, 1 deletions
diff --git a/include/libzfs.h b/include/libzfs.h
index 8d79fe69e..e2ec2d9bc 100644
--- a/include/libzfs.h
+++ b/include/libzfs.h
@@ -146,6 +146,7 @@ typedef enum zfs_error {
EZFS_TRIMMING, /* currently trimming */
EZFS_NO_TRIM, /* no active trim */
EZFS_TRIM_NOTSUP, /* device does not support trim */
+ EZFS_NO_RESILVER_DEFER, /* pool doesn't support resilver_defer */
EZFS_UNKNOWN
} zfs_error_t;
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c
index 6c797d06b..a6e26ebcd 100644
--- a/lib/libzfs/libzfs_pool.c
+++ b/lib/libzfs/libzfs_pool.c
@@ -2354,6 +2354,10 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd)
(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
"cannot scrub %s"), zc.zc_name);
}
+ } else if (func == POOL_SCAN_RESILVER) {
+ assert(cmd == POOL_SCRUB_NORMAL);
+ (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+ "cannot restart resilver on %s"), zc.zc_name);
} else if (func == POOL_SCAN_NONE) {
(void) snprintf(msg, sizeof (msg),
dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
@@ -2381,6 +2385,8 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd)
}
} else if (err == ENOENT) {
return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
+ } else if (err == ENOTSUP && func == POOL_SCAN_RESILVER) {
+ return (zfs_error(hdl, EZFS_NO_RESILVER_DEFER, msg));
} else {
return (zpool_standard_error(hdl, err, msg));
}
diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c
index b988d8f31..19bb57ad4 100644
--- a/lib/libzfs/libzfs_util.c
+++ b/lib/libzfs/libzfs_util.c
@@ -300,6 +300,9 @@ libzfs_error_description(libzfs_handle_t *hdl)
case EZFS_TRIM_NOTSUP:
return (dgettext(TEXT_DOMAIN, "trim operations are not "
"supported by this device"));
+ case EZFS_NO_RESILVER_DEFER:
+ return (dgettext(TEXT_DOMAIN, "this action requires the "
+ "resilver_defer feature"));
case EZFS_UNKNOWN:
return (dgettext(TEXT_DOMAIN, "unknown error"));
default:
diff --git a/man/man8/zpool.8 b/man/man8/zpool.8
index eb93d3bb3..971501d8d 100644
--- a/man/man8/zpool.8
+++ b/man/man8/zpool.8
@@ -2216,7 +2216,9 @@ again.
.Xc
Starts a resilver. If an existing resilver is already running it will be
restarted from the beginning. Any drives that were scheduled for a deferred
-resilver will be added to the new one.
+resilver will be added to the new one. This requires the
+.Sy resilver_defer
+feature.
.It Xo
.Nm
.Cm trim
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index c76163b6f..4d26d698e 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -7261,6 +7261,10 @@ spa_scan(spa_t *spa, pool_scan_func_t func)
if (func >= POOL_SCAN_FUNCS || func == POOL_SCAN_NONE)
return (SET_ERROR(ENOTSUP));
+ if (func == POOL_SCAN_RESILVER &&
+ !spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER))
+ return (SET_ERROR(ENOTSUP));
+
/*
* If a resilver was requested, but there is no DTL on a
* writeable leaf device, we have nothing to do.
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_bad_args.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_bad_args.ksh
index 9d973bec7..abd514086 100755
--- a/tests/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_bad_args.ksh
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_bad_args.ksh
@@ -35,6 +35,8 @@
# 1. Create an array containing bad 'zpool reilver' parameters.
# 2. For each element, execute the sub-command.
# 3. Verify it returns an error.
+# 4. Confirm the sub-command returns an error if the resilver_defer
+# feature isn't active.
#
verify_runnable "global"
@@ -45,6 +47,13 @@ set -A args "" "-?" "blah blah" "-%" "--?" "-*" "-=" \
"-A" "-B" "-C" "-D" "-E" "-F" "-G" "-H" "-I" "-J" "-K" "-L" \
"-M" "-N" "-O" "-P" "-Q" "-R" "-S" "-T" "-U" "-V" "-W" "-X" "-W" "-Z"
+function cleanup
+{
+ log_must destroy_pool $TESTPOOL2
+ log_must rm -f $TEST_BASE_DIR/zpool_resilver.dat
+}
+
+log_onexit cleanup
log_assert "Execute 'zpool resilver' using invalid parameters."
@@ -55,4 +64,8 @@ while [[ $i -lt ${#args[*]} ]]; do
((i = i + 1))
done
+log_must mkfile $MINVDEVSIZE $TEST_BASE_DIR/zpool_resilver.dat
+log_must zpool create -d $TESTPOOL2 $TEST_BASE_DIR/zpool_resilver.dat
+log_mustnot zpool resilver $TESTPOOL2
+
log_pass "Badly formed 'zpool resilver' parameters fail as expected."