aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim')
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/Makefile.am24
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/cleanup.ksh34
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/setup.ksh43
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib43
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_attach_detach_add_remove.ksh64
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_import_export.ksh88
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_multiple.ksh65
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_neg.ksh53
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_offline_export_import_online.ksh62
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_online_offline.ksh70
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_partial.ksh114
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_rate.ksh90
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_rate_neg.ksh53
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_secure.ksh59
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_split.ksh60
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_neg.ksh56
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_pos.ksh48
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_suspend_resume.ksh74
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_unsupported_vdevs.ksh70
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_checksums.ksh69
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_trimmed.ksh81
21 files changed, 1320 insertions, 0 deletions
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/Makefile.am
new file mode 100644
index 000000000000..d2d3b4ae88bb
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/Makefile.am
@@ -0,0 +1,24 @@
+pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zpool_trim
+dist_pkgdata_SCRIPTS = \
+ setup.ksh \
+ cleanup.ksh \
+ zpool_trim_attach_detach_add_remove.ksh \
+ zpool_trim_import_export.ksh \
+ zpool_trim_multiple.ksh \
+ zpool_trim_neg.ksh \
+ zpool_trim_offline_export_import_online.ksh \
+ zpool_trim_online_offline.ksh \
+ zpool_trim_partial.ksh \
+ zpool_trim_rate.ksh \
+ zpool_trim_rate_neg.ksh \
+ zpool_trim_secure.ksh \
+ zpool_trim_split.ksh \
+ zpool_trim_start_and_cancel_neg.ksh \
+ zpool_trim_start_and_cancel_pos.ksh \
+ zpool_trim_suspend_resume.ksh \
+ zpool_trim_unsupported_vdevs.ksh \
+ zpool_trim_verify_checksums.ksh \
+ zpool_trim_verify_trimmed.ksh
+
+dist_pkgdata_DATA = \
+ zpool_trim.kshlib
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/cleanup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/cleanup.ksh
new file mode 100755
index 000000000000..8ba8166333eb
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/cleanup.ksh
@@ -0,0 +1,34 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "global"
+
+if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+fi
+
+if poolexists $TESTPOOL1; then
+ destroy_pool $TESTPOOL1
+fi
+
+default_cleanup
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/setup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/setup.ksh
new file mode 100755
index 000000000000..09489600b3dc
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/setup.ksh
@@ -0,0 +1,43 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "global"
+
+if is_freebsd; then
+ log_unsupported "FreeBSD has no hole punching mechanism for the time being."
+ diskinfo -v $DISKS | grep -qE 'No.*# TRIM/UNMAP support' &&
+ log_unsupported "DISKS do not support discard (TRIM/UNMAP)"
+else
+ DISK1=${DISKS%% *}
+
+ typeset -i max_discard=0
+ if is_disk_device $DEV_RDSKDIR/$DISK1; then
+ max_discard=$(lsblk -Dbn $DEV_RDSKDIR/$DISK1 | awk '{ print $4; exit }')
+ fi
+
+ if test $max_discard -eq 0; then
+ log_unsupported "DISKS do not support discard (TRIM/UNMAP)"
+ fi
+fi
+
+log_pass
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
new file mode 100644
index 000000000000..1c54c66c129c
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2016 by Delphix. All rights reserved.
+# Copyright (c) 2019 by Lawrence Livermore National Security, LLC.
+#
+
+function trim_prog_line # pool disk
+{
+ typeset pool="$1"
+ typeset disk="$2"
+ zpool status -t "$pool" | grep "$disk" | grep "[[:digit:]]* trimmed"
+}
+
+function trim_progress # pool disk
+{
+ trim_prog_line "$1" "$2" | sed 's/.*(\([0-9]\{1,\}\)% trimmed.*/\1/g'
+}
+
+function cleanup
+{
+ if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+
+ if poolexists $TESTPOOL1; then
+ destroy_pool $TESTPOOL1
+ fi
+}
+log_onexit cleanup
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_attach_detach_add_remove.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_attach_detach_add_remove.ksh
new file mode 100755
index 000000000000..e715de9644b1
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_attach_detach_add_remove.ksh
@@ -0,0 +1,64 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Detaching/attaching, adding/removing data devices works with trimming.
+#
+# STRATEGY:
+# 1. Create a single-disk pool.
+# 2. Start trimming.
+# 3. Attach a second disk, ensure trimming continues.
+# 4. Detach the second disk, ensure trimming continues.
+# 5. Add a second disk, ensure trimming continues.
+# 6. Remove the first disk, ensure trimming stops.
+#
+
+DISK1="$(echo $DISKS | cut -d' ' -f1)"
+DISK2="$(echo $DISKS | cut -d' ' -f2)"
+
+log_must zpool create -f $TESTPOOL $DISK1
+
+log_must zpool trim -r 128M $TESTPOOL $DISK1
+progress="$(trim_progress $TESTPOOL $DISK1)"
+[[ -z "$progress" ]] && log_fail "Trim did not start"
+
+log_must zpool attach $TESTPOOL $DISK1 $DISK2
+new_progress="$(trim_progress $TESTPOOL $DISK1)"
+[[ "$progress" -le "$new_progress" ]] || \
+ log_fail "Lost trimming progress on demotion to child vdev"
+progress="$new_progress"
+
+log_must zpool detach $TESTPOOL $DISK2
+new_progress="$(trim_progress $TESTPOOL $DISK1)"
+[[ "$progress" -le "$new_progress" ]] || \
+ log_fail "Lost trimming progress on promotion to top vdev"
+progress="$new_progress"
+
+log_must zpool add $TESTPOOL $DISK2
+log_must zpool remove $TESTPOOL $DISK1
+[[ -z "$(trim_prog_line $TESTPOOL $DISK1)" ]] || \
+ log_fail "Trimming continued after initiating removal"
+
+log_pass "Trimming worked as expected across attach/detach and add/remove"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_import_export.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_import_export.ksh
new file mode 100755
index 000000000000..a624d368c3c1
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_import_export.ksh
@@ -0,0 +1,88 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Trimming automatically resumes across import/export.
+#
+# STRATEGY:
+# 1. Create a one-disk pool.
+# 2. Start trimming and verify that trimming is active.
+# 3. Export the pool.
+# 4. Import the pool.
+# 5. Verify that trimming resumes and progress does not regress.
+# 6. Suspend trimming.
+# 7. Repeat steps 3-4.
+# 8. Verify that progress does not regress but trimming is still suspended.
+#
+
+function cleanup
+{
+ if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+
+ if [[ -d "$TESTDIR" ]]; then
+ rm -rf "$TESTDIR"
+ fi
+}
+
+LARGEFILE="$TESTDIR/largefile"
+
+log_must mkdir "$TESTDIR"
+log_must truncate -s 10G "$LARGEFILE"
+log_must zpool create -f $TESTPOOL $LARGEFILE
+
+log_must zpool trim -r 256M $TESTPOOL
+sleep 2
+
+progress="$(trim_progress $TESTPOOL $LARGEFILE)"
+[[ -z "$progress" ]] && log_fail "Trimming did not start"
+
+log_must zpool export $TESTPOOL
+log_must zpool import -d $TESTDIR $TESTPOOL
+
+new_progress="$(trim_progress $TESTPOOL $LARGEFILE)"
+[[ -z "$new_progress" ]] && log_fail "Trimming did not restart after import"
+
+[[ "$progress" -le "$new_progress" ]] || \
+ log_fail "Trimming lost progress after import"
+log_mustnot eval "trim_prog_line $TESTPOOL $LARGEFILE | grep suspended"
+
+log_must zpool trim -s $TESTPOOL $LARGEFILE
+action_date="$(trim_prog_line $TESTPOOL $LARGEFILE | \
+ sed 's/.*ed at \(.*\)).*/\1/g')"
+log_must zpool export $TESTPOOL
+log_must zpool import -d $TESTDIR $TESTPOOL
+new_action_date=$(trim_prog_line $TESTPOOL $LARGEFILE | \
+ sed 's/.*ed at \(.*\)).*/\1/g')
+[[ "$action_date" != "$new_action_date" ]] && \
+ log_fail "Trimming action date did not persist across export/import"
+
+[[ "$new_progress" -le "$(trim_progress $TESTPOOL $LARGEFILE)" ]] || \
+ log_fail "Trimming lost progress after import"
+
+log_must eval "trim_prog_line $TESTPOOL $LARGEFILE | grep suspended"
+
+log_pass "Trimming retains state as expected across export/import"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_multiple.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_multiple.ksh
new file mode 100755
index 000000000000..e8236ff83134
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_multiple.ksh
@@ -0,0 +1,65 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Trimming can be performed multiple times
+#
+# STRATEGY:
+# 1. Create a pool with a single disk.
+# 2. Trim the entire pool.
+# 3. Verify trimming is reset (status, offset, and action date).
+# 4. Repeat steps 2 and 3 with the existing pool.
+#
+
+DISK1=${DISKS%% *}
+
+log_must zpool create -f $TESTPOOL $DISK1
+
+typeset action_date="none"
+for n in {1..3}; do
+ log_must zpool trim -r 2G $TESTPOOL
+ log_mustnot eval "trim_prog_line $TESTPOOL $DISK1 | grep complete"
+
+ [[ "$(trim_progress $TESTPOOL $DISK1)" -lt "100" ]] ||
+ log_fail "Trimming progress wasn't reset"
+
+ new_action_date="$(trim_prog_line $TESTPOOL $DISK1 | \
+ sed 's/.*ed at \(.*\)).*/\1/g')"
+ [[ "$action_date" != "$new_action_date" ]] ||
+ log_fail "Trimming action date wasn't reset"
+ action_date=$new_action_date
+
+ while [[ "$(trim_progress $TESTPOOL $DISK1)" -lt "100" ]]; do
+ progress="$(trim_progress $TESTPOOL $DISK1)"
+ sleep 0.5
+ [[ "$progress" -le "$(trim_progress $TESTPOOL $DISK1)" ]] ||
+ log_fail "Trimming progress regressed"
+ done
+
+ log_must eval "trim_prog_line $TESTPOOL $DISK1 | grep complete"
+ sleep 1
+done
+
+log_pass "Trimming multiple times performs as expected"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_neg.ksh
new file mode 100755
index 000000000000..4ab2eb1a71b4
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_neg.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# A badly formed parameter passed to 'zpool trim' should
+# return an error.
+#
+# STRATEGY:
+# 1. Create an array containing bad 'zpool trim' parameters.
+# 2. For each element, execute the sub-command.
+# 3. Verify it returns an error.
+#
+
+DISK1=${DISKS%% *}
+DISK2="$(echo $DISKS | cut -d' ' -f2)"
+
+verify_runnable "global"
+
+set -A args "1" "-a" "-?" "--%" "-123456" "0.5" "-o" "-b" "-b no" "-z 2"
+
+log_assert "Execute 'zpool trim' using invalid parameters."
+
+log_must zpool create -f $TESTPOOL mirror $DISK1 $DISK2
+
+typeset -i i=0
+while [[ $i -lt ${#args[*]} ]]; do
+ log_mustnot zpool trim ${args[i]} $TESTPOOL
+ ((i = i + 1))
+done
+
+log_pass "Invalid parameters to 'zpool trim' fail as expected."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_offline_export_import_online.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_offline_export_import_online.ksh
new file mode 100755
index 000000000000..4f904d11ddda
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_offline_export_import_online.ksh
@@ -0,0 +1,62 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Miscellaneous complex sequences of operations function as expected.
+#
+# STRATEGY:
+# 1. Create a pool with a two-way mirror.
+# 2. Start trimming, offline, export, import, online and verify that
+# trimming state is preserved / trimming behaves as expected
+# at each step.
+#
+
+DISK1="$(echo $DISKS | cut -d' ' -f1)"
+DISK2="$(echo $DISKS | cut -d' ' -f2)"
+
+log_must zpool create -f $TESTPOOL mirror $DISK1 $DISK2
+
+log_must zpool trim -r 128M $TESTPOOL $DISK1
+log_must zpool offline $TESTPOOL $DISK1
+progress="$(trim_progress $TESTPOOL $DISK1)"
+[[ -z "$progress" ]] && log_fail "Trimming did not start"
+log_mustnot eval "trim_prog_line $TESTPOOL $DISK1 | grep suspended"
+
+log_must zpool export $TESTPOOL
+log_must zpool import $TESTPOOL
+
+new_progress="$(trim_progress $TESTPOOL $DISK1)"
+[[ -z "$new_progress" ]] && log_fail "Trimming did not start after import"
+[[ "$new_progress" -ge "$progress" ]] || \
+ log_fail "Trimming lost progress after import"
+log_mustnot eval "trim_prog_line $TESTPOOL $DISK1 | grep suspended"
+
+log_must zpool online $TESTPOOL $DISK1
+new_progress="$(trim_progress $TESTPOOL $DISK1)"
+[[ "$new_progress" -ge "$progress" ]] || \
+ log_fail "Trimming lost progress after online"
+
+log_pass "Trimming behaves as expected at each step of:" \
+ "trim + offline + export + import + online"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_online_offline.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_online_offline.ksh
new file mode 100755
index 000000000000..681cd12f71c5
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_online_offline.ksh
@@ -0,0 +1,70 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Trimming automatically resumes across offline/online.
+#
+# STRATEGY:
+# 1. Create a pool with a two-way mirror.
+# 2. Start trimming one of the disks and verify that trimming is active.
+# 3. Offline the disk.
+# 4. Online the disk.
+# 5. Verify that trimming resumes and progress does not regress.
+# 6. Suspend trimming.
+# 7. Repeat steps 3-4 and verify that trimming does not resume.
+#
+
+DISK1=${DISKS%% *}
+DISK2="$(echo $DISKS | cut -d' ' -f2)"
+
+log_must zpool create -f $TESTPOOL mirror $DISK1 $DISK2
+log_must zpool trim -r 128M $TESTPOOL $DISK1
+
+log_must zpool offline $TESTPOOL $DISK1
+
+progress="$(trim_progress $TESTPOOL $DISK1)"
+[[ -z "$progress" ]] && log_fail "Trimming did not start"
+
+log_must zpool online $TESTPOOL $DISK1
+
+new_progress="$(trim_progress $TESTPOOL $DISK1)"
+[[ -z "$new_progress" ]] && \
+ log_fail "Trimming did not restart after onlining"
+[[ "$progress" -le "$new_progress" ]] || \
+ log_fail "Trimming lost progress after onlining"
+log_mustnot eval "trim_prog_line $TESTPOOL $DISK1 | grep suspended"
+
+log_must zpool trim -s $TESTPOOL $DISK1
+action_date="$(trim_prog_line $TESTPOOL $DISK1 | \
+ sed 's/.*ed at \(.*\)).*/\1/g')"
+log_must zpool offline $TESTPOOL $DISK1
+log_must zpool online $TESTPOOL $DISK1
+new_action_date=$(trim_prog_line $TESTPOOL $DISK1 | \
+ sed 's/.*ed at \(.*\)).*/\1/g')
+[[ "$action_date" != "$new_action_date" ]] && \
+ log_fail "Trimming action date did not persist across offline/online"
+log_must eval "trim_prog_line $TESTPOOL $DISK1 | grep suspended"
+
+log_pass "Trimming performs as expected across offline/online"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_partial.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_partial.ksh
new file mode 100755
index 000000000000..5d14b74ecc15
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_partial.ksh
@@ -0,0 +1,114 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Verify 'zpool trim' partial trim.
+#
+# STRATEGY:
+# 1. Create a pool on a single disk and mostly fill it.
+# 2. Expand the pool to create new unallocated metaslabs.
+# 3. Run 'zpool trim' to only TRIM allocated space maps.
+# 4. Verify the disk is least 90% of its original size.
+# 5. Run 'zpool trim' to perform a full TRIM.
+# 6. Verify the disk is less than 10% of its original size.
+
+function cleanup
+{
+ if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+
+ if [[ -d "$TESTDIR" ]]; then
+ rm -rf "$TESTDIR"
+ fi
+
+ log_must set_tunable64 TRIM_METASLAB_SKIP 0
+ log_must set_tunable64 TRIM_EXTENT_BYTES_MIN $trim_extent_bytes_min
+ log_must set_tunable64 VDEV_MIN_MS_COUNT $vdev_min_ms_count
+}
+log_onexit cleanup
+
+LARGESIZE=$((MINVDEVSIZE * 4))
+LARGEFILE="$TESTDIR/largefile"
+
+# The minimum number of metaslabs is increased in order to simulate the
+# behavior of partial trimming on a more typically sized 1TB disk.
+typeset vdev_min_ms_count=$(get_tunable VDEV_MIN_MS_COUNT)
+log_must set_tunable64 VDEV_MIN_MS_COUNT 64
+
+# Minimum trim size is decreased to verify all trim sizes.
+typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN)
+log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096
+
+log_must mkdir "$TESTDIR"
+log_must truncate -s $LARGESIZE "$LARGEFILE"
+log_must zpool create $TESTPOOL "$LARGEFILE"
+log_must mkfile $(( floor(LARGESIZE * 0.80) )) /$TESTPOOL/file
+log_must zpool sync
+
+new_size=$(du -B1 "$LARGEFILE" | cut -f1)
+log_must test $new_size -le $LARGESIZE
+log_must test $new_size -gt $(( floor(LARGESIZE * 0.70) ))
+
+# Expand the pool to create new unallocated metaslabs.
+log_must zpool export $TESTPOOL
+log_must dd if=/dev/urandom of=$LARGEFILE conv=notrunc,nocreat \
+ seek=$((LARGESIZE / (1024 * 1024))) bs=$((1024 * 1024)) \
+ count=$((3 * LARGESIZE / (1024 * 1024)))
+log_must zpool import -d $TESTDIR $TESTPOOL
+log_must zpool online -e $TESTPOOL "$LARGEFILE"
+
+new_size=$(du -B1 "$LARGEFILE" | cut -f1)
+log_must test $new_size -gt $((4 * floor(LARGESIZE * 0.70) ))
+
+# Perform a partial trim, we expect it to skip most of the new metaslabs
+# which have never been used and therefore do not need be trimmed.
+log_must set_tunable64 TRIM_METASLAB_SKIP 1
+log_must zpool trim $TESTPOOL
+log_must set_tunable64 TRIM_METASLAB_SKIP 0
+
+log_must zpool sync
+while [[ "$(trim_progress $TESTPOOL $LARGEFILE)" -lt "100" ]]; do
+ sleep 0.5
+done
+
+new_size=$(du -B1 "$LARGEFILE" | cut -f1)
+log_must test $new_size -gt $LARGESIZE
+
+# Perform a full trim, all metaslabs will be trimmed the pool vdev
+# size will be reduced but not down to its original size due to the
+# space usage of the new metaslabs.
+log_must zpool trim $TESTPOOL
+
+log_must zpool sync
+while [[ "$(trim_progress $TESTPOOL $LARGEFILE)" -lt "100" ]]; do
+ sleep 0.5
+done
+
+new_size=$(du -B1 "$LARGEFILE" | cut -f1)
+log_must test $new_size -le $(( 2 * LARGESIZE))
+log_must test $new_size -gt $(( floor(LARGESIZE * 0.70) ))
+
+log_pass "Manual 'zpool trim' successfully partially trimmed pool"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_rate.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_rate.ksh
new file mode 100755
index 000000000000..6b83a1eede8e
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_rate.ksh
@@ -0,0 +1,90 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Verify 'zpool trim -r <rate>' rate limiting.
+#
+# STRATEGY:
+# 1. Create a pool on a single disk.
+# 2. Manually TRIM the pool with rate limiting.
+# 3. Verify the TRIM can be suspended.
+# 4. Restart the TRIM and verify the rate is preserved.
+#
+# NOTE: The tolerances and delays used in the test below are intentionally
+# set be to fairly large since we are capping the maximum trim rate. The
+# actual trim rate can be lower. The critical thing is that the trim rate
+# is limited, the rate is preserved when resuming, and it can be changed.
+#
+
+function cleanup
+{
+ if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+
+ if [[ -d "$TESTDIR" ]]; then
+ rm -rf "$TESTDIR"
+ fi
+}
+log_onexit cleanup
+
+LARGEFILE="$TESTDIR/largefile"
+
+log_must mkdir "$TESTDIR"
+log_must truncate -s 10G "$LARGEFILE"
+log_must zpool create -f $TESTPOOL "$LARGEFILE"
+
+# Start trimming at 200M/s for 5 seconds (approximately 10% of the pool)
+log_must zpool trim -r 200M $TESTPOOL
+log_must sleep 4
+progress=$(trim_progress $TESTPOOL $LARGEFILE)
+log_must zpool trim -s $TESTPOOL
+log_must eval "trim_prog_line $TESTPOOL $LARGEFILE | grep suspended"
+log_must within_tolerance 10 $progress 5
+
+# Resuming trimming at 200M/s for 5 seconds (approximately 20% of the pool)
+log_must zpool trim $TESTPOOL
+log_must sleep 4
+progress=$(trim_progress $TESTPOOL $LARGEFILE)
+log_must zpool trim -s $TESTPOOL
+log_must eval "trim_prog_line $TESTPOOL $LARGEFILE | grep suspended"
+log_must within_tolerance 20 $progress 10
+
+# Increase trimming to 600M/s for 5 seconds (approximately 50% of the pool)
+log_must zpool trim -r 600M $TESTPOOL
+log_must sleep 4
+progress=$(trim_progress $TESTPOOL $LARGEFILE)
+log_must zpool trim -s $TESTPOOL
+log_must eval "trim_prog_line $TESTPOOL $LARGEFILE | grep suspended"
+log_must within_tolerance 50 $progress 15
+
+# Set maximum trim rate for 5 seconds (100% of the pool)
+log_must zpool trim -r 1T $TESTPOOL
+log_must sleep 4
+progress=$(trim_progress $TESTPOOL $LARGEFILE)
+log_must eval "trim_prog_line $TESTPOOL $LARGEFILE | grep complete"
+log_must within_tolerance 100 $progress 0
+
+log_pass "Manual TRIM rate throttles as expected"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_rate_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_rate_neg.ksh
new file mode 100755
index 000000000000..11bd43076279
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_rate_neg.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# A badly formed parameter passed to 'zpool trim -r' should
+# return an error.
+#
+# STRATEGY:
+# 1. Create an array containing bad 'zpool trim -r' parameters.
+# 2. For each element, execute the sub-command.
+# 3. Verify it returns an error.
+#
+
+DISK1=${DISKS%% *}
+DISK2="$(echo $DISKS | cut -d' ' -f2)"
+
+verify_runnable "global"
+
+set -A args "a" "--%" "10X" "yes" "-?" "z 99"
+
+log_assert "Execute 'zpool trim -r' using invalid parameters."
+
+log_must zpool create -f $TESTPOOL mirror $DISK1 $DISK2
+
+typeset -i i=0
+while [[ $i -lt ${#args[*]} ]]; do
+ log_mustnot zpool trim -r ${args[i]} $TESTPOOL
+ ((i = i + 1))
+done
+
+log_pass "Invalid parameters to 'zpool trim -r' fail as expected."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_secure.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_secure.ksh
new file mode 100755
index 000000000000..e97d09f515bc
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_secure.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Verify 'zpool trim -d' secure trim.
+#
+# STRATEGY:
+# 1. Create a pool on a single file vdev.
+# 2. Run 'zpool trim -d' to securely TRIM allocated space maps.
+# 3. Verify it fails when using a file vdev.
+#
+# NOTE: Currently secure discard cannot be verified using file vdevs,
+# loopback, or scsi_debug devices. None of which support the feature.
+# It can only be tested using real SSDs which provide support.
+#
+
+function cleanup
+{
+ if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+
+ if [[ -d "$TESTDIR" ]]; then
+ rm -rf "$TESTDIR"
+ fi
+}
+log_onexit cleanup
+
+LARGESIZE=$((MINVDEVSIZE * 4))
+LARGEFILE="$TESTDIR/largefile"
+
+log_must mkdir "$TESTDIR"
+log_must truncate -s $LARGESIZE "$LARGEFILE"
+log_must zpool create $TESTPOOL "$LARGEFILE"
+log_mustnot zpool trim -d $TESTPOOL
+
+log_pass "Manual 'zpool trim -d' failed as expected for file vdevs"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_split.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_split.ksh
new file mode 100755
index 000000000000..450dc6fd80f4
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_split.ksh
@@ -0,0 +1,60 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Trimming state is preserved across zpool split.
+#
+# STRATEGY:
+# 1. Create a pool with a two-way mirror.
+# 2. Start trimming both devices.
+# 3. Split the pool. Ensure trimming continues on the original.
+# 4. Import the new pool. Ensure trimming resumes on it.
+#
+
+DISK1="$(echo $DISKS | cut -d' ' -f1)"
+DISK2="$(echo $DISKS | cut -d' ' -f2)"
+POOL2="${TESTPOOL}_split"
+
+log_must zpool create -f $TESTPOOL mirror $DISK1 $DISK2
+
+log_must zpool trim $TESTPOOL $DISK1 $DISK2
+orig_prog1="$(trim_progress $TESTPOOL $DISK1)"
+orig_prog2="$(trim_progress $TESTPOOL $DISK2)"
+[[ -z "$orig_prog1" ]] && log_fail "Trimming did not start"
+
+log_must zpool split $TESTPOOL $TESTPOOL1 $DISK2
+
+# Ensure trimming continued as expected on the original pool.
+[[ "$(trim_progress $TESTPOOL $DISK1)" -ge "$orig_prog1" ]] || \
+ log_fail "Trimming lost progress on original pool"
+log_mustnot eval "trim_prog_line $TESTPOOL $DISK1 | grep suspended"
+
+log_must zpool import $TESTPOOL1
+
+[[ "$(trim_progress $TESTPOOL1 $DISK2)" -ge "$orig_prog2" ]] || \
+ log_fail "Trimming lost progress on split pool"
+log_mustnot eval "trim_prog_line $TESTPOOL1 $DISK1 | grep suspended"
+
+log_pass "Trimming behaves as expected on zpool split"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_neg.ksh
new file mode 100755
index 000000000000..faf134fbbd8d
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_neg.ksh
@@ -0,0 +1,56 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Cancelling and suspending trim doesn't work if not all specified vdevs
+# are being trimmed.
+#
+# STRATEGY:
+# 1. Create a three-disk pool.
+# 2. Start trimming and verify that trimming is active.
+# 3. Try to cancel and suspend trimming on the non-trimming disks.
+# 4. Try to re-trim the currently trimming disk.
+#
+
+DISK1=${DISKS%% *}
+DISK2="$(echo $DISKS | cut -d' ' -f2)"
+DISK3="$(echo $DISKS | cut -d' ' -f3)"
+
+log_must zpool list -v
+log_must zpool create -f $TESTPOOL $DISK1 $DISK2 $DISK3
+log_must zpool trim -r 128M $TESTPOOL $DISK1
+
+[[ -z "$(trim_progress $TESTPOOL $DISK1)" ]] && \
+ log_fail "Trim did not start"
+
+log_mustnot zpool trim -c $TESTPOOL $DISK2
+log_mustnot zpool trim -c $TESTPOOL $DISK2 $DISK3
+
+log_mustnot zpool trim -s $TESTPOOL $DISK2
+log_mustnot zpool trim -s $TESTPOOL $DISK2 $DISK3
+
+log_mustnot zpool trim $TESTPOOL $DISK1
+
+log_pass "Nonsensical trim operations fail"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_pos.ksh
new file mode 100755
index 000000000000..eaa4d90444b6
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_pos.ksh
@@ -0,0 +1,48 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
+
+#
+# DESCRIPTION:
+# Starting and stopping an initialize works.
+#
+# STRATEGY:
+# 1. Create a one-disk pool.
+# 2. Start initializing and verify that initializing is active.
+# 3. Cancel initializing and verify that initializing is not active.
+#
+
+DISK1=${DISKS%% *}
+
+log_must zpool create -f $TESTPOOL $DISK1
+log_must zpool initialize $TESTPOOL
+
+[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] && \
+ log_fail "Initialize did not start"
+
+log_must zpool initialize -c $TESTPOOL
+
+[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] || \
+ log_fail "Initialize did not stop"
+
+log_pass "Initialize start + cancel works"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_suspend_resume.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_suspend_resume.ksh
new file mode 100755
index 000000000000..553d911e124c
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_suspend_resume.ksh
@@ -0,0 +1,74 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Suspending and resuming trimming works.
+#
+# STRATEGY:
+# 1. Create a one-disk pool.
+# 2. Start trimming and verify that trimming is active.
+# 3. Wait 3 seconds, then suspend trimming and verify that the progress
+# reporting says so.
+# 4. Wait 3 seconds and ensure trimming progress doesn't advance.
+# 5. Restart trimming and verify that the progress doesn't regress.
+#
+
+function cleanup
+{
+ if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+
+ if [[ -d "$TESTDIR" ]]; then
+ rm -rf "$TESTDIR"
+ fi
+}
+
+LARGEFILE="$TESTDIR/largefile"
+
+log_must mkdir "$TESTDIR"
+log_must truncate -s 10G "$LARGEFILE"
+log_must zpool create -f $TESTPOOL $LARGEFILE
+
+log_must zpool trim -r 256M $TESTPOOL
+sleep 2
+
+[[ -z "$(trim_progress $TESTPOOL $LARGEFILE)" ]] && \
+ log_fail "Trimming did not start"
+
+sleep 3
+log_must zpool trim -s $TESTPOOL
+log_must eval "trim_prog_line $TESTPOOL $LARGEFILE | grep suspended"
+progress="$(trim_progress $TESTPOOL $LARGEFILE)"
+
+sleep 3
+[[ "$progress" -eq "$(trim_progress $TESTPOOL $LARGEFILE)" ]] || \
+ log_fail "Trimming progress advanced while suspended"
+
+log_must zpool trim $TESTPOOL $LARGEFILE
+[[ "$progress" -le "$(trim_progress $TESTPOOL $LARGEFILE)" ]] ||
+ log_fail "Trimming progress regressed after resuming"
+
+log_pass "Suspend + resume trimming works as expected"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_unsupported_vdevs.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_unsupported_vdevs.ksh
new file mode 100755
index 000000000000..988745e30e97
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_unsupported_vdevs.ksh
@@ -0,0 +1,70 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Attempting to trim unsupported vdevs should fail.
+#
+# STRATEGY:
+# 1. Create a pool with the following configuration:
+# root
+# mirror
+# vdev0
+# vdev1 (offline)
+# cache
+# vdev2
+# spare
+# vdev3
+# 2. Try to trim vdev1, vdev2, and vdev3. Ensure that all 3 fail.
+#
+function cleanup
+{
+ if datasetexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+ if [[ -d $TESTDIR ]]; then
+ log_must rm -rf $TESTDIR
+ fi
+}
+log_onexit cleanup
+
+log_must mkdir $TESTDIR
+set -A FDISKS
+for n in {0..2}; do
+ log_must mkfile $MINVDEVSIZE $TESTDIR/vdev$n
+ FDISKS+=("$TESTDIR/vdev$n")
+done
+FDISKS+=("${DISKS%% *}")
+
+log_must zpool create $TESTPOOL mirror ${FDISKS[0]} ${FDISKS[1]} \
+ spare ${FDISKS[2]} cache ${FDISKS[3]}
+
+log_must zpool offline $TESTPOOL ${FDISKS[1]}
+
+log_mustnot zpool trim $TESTPOOL mirror-0
+for n in {1..3}; do
+ log_mustnot zpool trim $TESTPOOL ${FDISKS[$n]}
+done
+
+log_pass "Attempting to trim failed on unsupported devices"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_checksums.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_checksums.ksh
new file mode 100755
index 000000000000..093dc3fb9e76
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_checksums.ksh
@@ -0,0 +1,69 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# Trimming does not cause file corruption.
+#
+# STRATEGY:
+# 1. Create a one-disk pool.
+# 2. Write data to the pool.
+# 3. Start trimming and verify that trimming is active.
+# 4. Write more data to the pool.
+# 5. Export the pool and use zdb to validate checksums.
+#
+
+function cleanup
+{
+ if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+
+ if [[ -d "$TESTDIR" ]]; then
+ rm -rf "$TESTDIR"
+ fi
+}
+log_onexit cleanup
+
+LARGESIZE=$((MINVDEVSIZE * 4))
+LARGEFILE="$TESTDIR/largefile"
+
+log_must mkdir "$TESTDIR"
+log_must truncate -s $LARGESIZE "$LARGEFILE"
+log_must zpool create $TESTPOOL "$LARGEFILE"
+
+log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=1048576 count=64
+log_must zpool sync
+log_must zpool trim $TESTPOOL
+
+[[ -z "$(trim_progress $TESTPOOL $DISK1)" ]] && \
+ log_fail "Trimming did not start"
+
+log_must dd if=/dev/urandom of=/$TESTPOOL/file2 bs=1048576 count=64
+log_must zpool sync
+
+log_must zpool export $TESTPOOL
+log_must zdb -e -p "$TESTDIR" -cc $TESTPOOL
+
+log_pass "Trimming does not corrupt existing or new data"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_trimmed.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_trimmed.ksh
new file mode 100755
index 000000000000..d5aaf49aebc5
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_trimmed.ksh
@@ -0,0 +1,81 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 by Tim Chase. All rights reserved.
+# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
+
+#
+# DESCRIPTION:
+# After trimming, the disk is actually trimmed.
+#
+# STRATEGY:
+# 1. Create a one-disk pool using a sparse file.
+# 2. Initialize the pool and verify the file vdev is no longer sparse.
+# 3. Trim the pool and verify the file vdev is again sparse.
+#
+
+function cleanup
+{
+ if poolexists $TESTPOOL; then
+ destroy_pool $TESTPOOL
+ fi
+
+ if [[ -d "$TESTDIR" ]]; then
+ rm -rf "$TESTDIR"
+ fi
+
+ log_must set_tunable64 TRIM_EXTENT_BYTES_MIN $trim_extent_bytes_min
+}
+log_onexit cleanup
+
+LARGESIZE=$((MINVDEVSIZE * 4))
+LARGEFILE="$TESTDIR/largefile"
+
+# Reduce trim size to allow for tighter tolerance below when checking.
+typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN)
+log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096
+
+log_must mkdir "$TESTDIR"
+log_must truncate -s $LARGESIZE "$LARGEFILE"
+log_must zpool create $TESTPOOL "$LARGEFILE"
+
+original_size=$(du -B1 "$LARGEFILE" | cut -f1)
+
+log_must zpool initialize $TESTPOOL
+
+while [[ "$(initialize_progress $TESTPOOL $LARGEFILE)" -lt "100" ]]; do
+ sleep 0.5
+done
+
+new_size=$(du -B1 "$LARGEFILE" | cut -f1)
+log_must within_tolerance $new_size $LARGESIZE $((128 * 1024 * 1024))
+
+log_must zpool trim $TESTPOOL
+
+while [[ "$(trim_progress $TESTPOOL $LARGEFILE)" -lt "100" ]]; do
+ sleep 0.5
+done
+
+new_size=$(du -B1 "$LARGEFILE" | cut -f1)
+log_must within_tolerance $new_size $original_size $((128 * 1024 * 1024))
+
+log_pass "Trimmed appropriate amount of disk space"