aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb')
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/Makefile.am17
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_002_pos.ksh51
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_003_pos.ksh72
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_004_pos.ksh93
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_005_pos.ksh78
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_006_pos.ksh64
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh83
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_pos.ksh104
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_block_size_histogram.ksh272
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_checksum.ksh64
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_decompress.ksh119
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_decompress_zstd.ksh114
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_display_block.ksh128
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_object_range_neg.ksh72
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_object_range_pos.ksh171
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_objset_id.ksh96
16 files changed, 1598 insertions, 0 deletions
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/Makefile.am
new file mode 100644
index 000000000000..18420efcb26a
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/Makefile.am
@@ -0,0 +1,17 @@
+pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zdb
+dist_pkgdata_SCRIPTS = \
+ zdb_002_pos.ksh \
+ zdb_003_pos.ksh \
+ zdb_004_pos.ksh \
+ zdb_005_pos.ksh \
+ zdb_006_pos.ksh \
+ zdb_args_neg.ksh \
+ zdb_args_pos.ksh \
+ zdb_block_size_histogram.ksh \
+ zdb_checksum.ksh \
+ zdb_decompress.ksh \
+ zdb_decompress_zstd.ksh \
+ zdb_object_range_neg.ksh \
+ zdb_object_range_pos.ksh \
+ zdb_display_block.ksh \
+ zdb_objset_id.ksh
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_002_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_002_pos.ksh
new file mode 100755
index 000000000000..ec7e1dcab9c9
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_002_pos.ksh
@@ -0,0 +1,51 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2015 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb will accurately count the feature refcount for pools with and without
+# features enabled.
+#
+# Strategy:
+# 1. Create a pool, and collect zdb output for the pool.
+# 2. Verify there are no 'feature refcount mismatch' messages.
+# 3. Repeat for a pool with features disabled.
+#
+
+log_assert "Verify zdb accurately counts feature refcounts."
+log_onexit cleanup
+
+typeset errstr="feature refcount mismatch"
+typeset tmpfile="$TEST_BASE_DIR/zdb-feature-mismatch"
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+ grep "$errstr" $tmpfile
+ rm -f $tmpfile
+}
+
+for opt in '' -d; do
+ log_must zpool create -f $opt $TESTPOOL ${DISKS%% *}
+ log_must eval "zdb $TESTPOOL >$tmpfile"
+ grep -q "$errstr" $tmpfile && \
+ log_fail "Found feature refcount mismatches in zdb output."
+ destroy_pool $TESTPOOL
+done
+
+log_pass "zdb accurately counts feature refcounts."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_003_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_003_pos.ksh
new file mode 100755
index 000000000000..36f1929dd193
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_003_pos.ksh
@@ -0,0 +1,72 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb will not produce redundant dumps of configurations
+#
+# Strategy:
+# 1. Create a pool with two vdevs
+# 2. Copy label 1 from the first vdev to the second vdev
+# 3. Collect zdb -l output for both vdevs
+# 4. Verify that the correct number of configs is dumped for each
+#
+
+log_assert "Verify zdb does not produce redundant dumps of configurations"
+log_onexit cleanup
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+ if is_freebsd ; then
+ log_must sysctl kern.geom.debugflags=$saved_debugflags
+ fi
+}
+
+if is_freebsd ; then
+ # FreeBSD won't allow writing to an in-use device without this set
+ saved_debugflags=$(sysctl -n kern.geom.debugflags)
+ log_must sysctl kern.geom.debugflags=16
+fi
+
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+config_count=(1 2)
+set -A DISK $DISKS
+
+default_mirror_setup_noexit $DISKS
+
+DEVS=$(get_pool_devices ${TESTPOOL} ${DEV_RDSKDIR})
+log_note "$DEVS"
+[[ -n $DEVS ]] && set -A DISK $DEVS
+
+log_must dd if=/dev/${DISK[0]} of=/dev/${DISK[1]} bs=1K count=256 conv=notrunc
+
+for x in 0 1 ; do
+ config_count=$(zdb -l $DEV_RDSKDIR/${DISK[$x]} | grep -c features_for_read)
+ (( $? != 0)) && log_fail "failed to get config_count from DISK[$x]"
+ log_note "vdev $x: message_count $config_count"
+ [ $config_count -ne ${config_count[$x]} ] && \
+ log_fail "zdb produces an incorrect number of configuration dumps."
+done
+
+cleanup
+
+log_pass "zdb produces unique dumps of configurations."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_004_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_004_pos.ksh
new file mode 100755
index 000000000000..2c6e6e9be070
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_004_pos.ksh
@@ -0,0 +1,93 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
+# Copyright (c) 2020 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb will not produce redundant dumps of uberblocks
+#
+# Strategy:
+# 1. Create a pool with two vdevs, A and B
+# 2. Offline vdev A
+# 3. Do some I/O
+# 4. Export the pool
+# 5. Copy label 1 from vdev A to vdev B
+# 6. Collect zdb -lu output for vdev B
+# 7. Verify labels 0 and 1 have unique Uberblocks, but 2 and 3 have none
+#
+
+log_assert "Verify zdb produces unique dumps of uberblocks"
+log_onexit cleanup
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+ for DISK in $DISKS; do
+ zpool labelclear -f $DEV_RDSKDIR/$DISK
+ done
+ if is_freebsd; then
+ log_must sysctl kern.geom.debugflags=$saved_debugflags
+ fi
+}
+
+if is_freebsd; then
+ # FreeBSD won't allow writing to an in-use device without this set
+ saved_debugflags=$(sysctl -n kern.geom.debugflags)
+ log_must sysctl kern.geom.debugflags=16
+fi
+
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+set -A DISK $DISKS
+WHOLE_DISK=${DISK[0]}
+
+default_mirror_setup_noexit $DISKS
+DEVS=$(get_pool_devices ${TESTPOOL} ${DEV_RDSKDIR})
+[[ -n $DEVS ]] && set -A DISK $DEVS
+
+log_must zpool offline $TESTPOOL $WHOLE_DISK
+log_must dd if=/dev/urandom of=$TESTDIR/testfile bs=1K count=2
+log_must zpool export $TESTPOOL
+
+log_must dd if=$DEV_RDSKDIR/${DISK[0]} of=$DEV_RDSKDIR/${DISK[1]} bs=1K count=256 conv=notrunc
+
+ubs=$(zdb -lu ${DISK[1]} | grep -e LABEL -e Uberblock -e 'labels = ')
+log_note "vdev 1: ubs $ubs"
+
+ub_dump_counts=$(zdb -lu ${DISK[1]} | \
+ awk ' /LABEL/ {label=$NF; blocks[label]=0};
+ /Uberblock/ {blocks[label]++};
+ END {print blocks[0],blocks[1],blocks[2],blocks[3]}')
+(( $? != 0)) && log_fail "failed to get ub_dump_counts from DISK[1]"
+log_note "vdev 1: ub_dump_counts $ub_dump_counts"
+
+set -A dump_count $ub_dump_counts
+for label in 0 1 2 3; do
+ if [[ $label -lt 2 ]]; then
+ [[ ${dump_count[$label]} -eq 0 ]] && \
+ log_fail "zdb incorrectly dumps duplicate uberblocks"
+ else
+ [[ ${dump_count[$label]} -ne 0 ]] && \
+ log_fail "zdb incorrectly dumps duplicate uberblocks"
+ fi
+done
+
+cleanup
+
+log_pass "zdb produces unique dumps of uberblocks"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_005_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_005_pos.ksh
new file mode 100755
index 000000000000..74975dbb0dde
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_005_pos.ksh
@@ -0,0 +1,78 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb -l exit codes are correct
+#
+# Strategy:
+# 1. Create a pool
+# 2. Overwrite label 0 on vdev[1] with dd
+# 3. Create an empty file
+# 3. Run zdb -l on vdev[0] and verify exit value 0
+# 4. Run zdb -l on vdev[1] and verify exit value 1
+# 5. Run zdb -l on the empty file and verify exit value 2
+#
+
+log_assert "Verify zdb -l exit codes are correct"
+log_onexit cleanup
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+ rm -f $TEMPFILE
+ if is_freebsd ; then
+ log_must sysctl kern.geom.debugflags=$saved_debugflags
+ fi
+}
+
+if is_freebsd ; then
+ # FreeBSD won't allow writing to an in-use device without this set
+ saved_debugflags=$(sysctl -n kern.geom.debugflags)
+ log_must sysctl kern.geom.debugflags=16
+fi
+
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+set -A DISK $DISKS
+
+default_mirror_setup_noexit $DISKS
+DEVS=$(get_pool_devices ${TESTPOOL} ${DEV_RDSKDIR})
+log_note "$DEVS"
+[[ -n $DEVS ]] && set -A DISK $DEVS
+
+log_must dd if=/dev/zero of=$DEV_RDSKDIR/${DISK[1]} bs=1K count=256 conv=notrunc
+log_must truncate -s 0 $TEMPFILE
+
+zdb -l $DEV_RDSKDIR/${DISK[0]}
+[[ $? -ne 0 ]] &&
+ log_fail "zdb -l exit codes are incorrect."
+
+zdb -l $DEV_RDSKDIR/${DISK[1]}
+[[ $? -ne 1 ]] &&
+ log_fail "zdb -l exit codes are incorrect."
+
+zdb -l $TEMPFILE
+[[ $? -ne 2 ]] &&
+ log_fail "zdb -l exit codes are incorrect."
+
+cleanup
+
+log_pass "zdb -l exit codes are correct."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_006_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_006_pos.ksh
new file mode 100755
index 000000000000..97b00e9e1996
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_006_pos.ksh
@@ -0,0 +1,64 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2018 by Nutanix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb -d will work on imported/exported pool with pool/dataset argument
+#
+# Strategy:
+# 1. Create a pool
+# 2. Run zdb -d with pool and dataset arguments.
+# 3. Export the pool
+# 4. Run zdb -ed with pool and dataset arguments.
+#
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+ for DISK in $DISKS; do
+ zpool labelclear -f $DEV_RDSKDIR/$DISK
+ done
+}
+
+log_assert "Verify zdb -d works on imported/exported pool with pool/dataset argument"
+log_onexit cleanup
+
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+default_mirror_setup_noexit $DISKS
+log_must zfs snap $TESTPOOL/$TESTFS@snap
+
+log_must zdb -d $TESTPOOL
+log_must zdb -d $TESTPOOL/
+log_must zdb -d $TESTPOOL/$TESTFS
+log_must zdb -d $TESTPOOL/$TESTFS@snap
+
+log_must zpool export $TESTPOOL
+
+log_must zdb -ed $TESTPOOL
+log_must zdb -ed $TESTPOOL/
+log_must zdb -ed $TESTPOOL/$TESTFS
+log_must zdb -ed $TESTPOOL/$TESTFS@snap
+
+log_must zpool import $TESTPOOL
+
+cleanup
+
+log_pass "zdb -d works on imported/exported pool with pool/dataset argument"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh
new file mode 100755
index 000000000000..1b0219780adc
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh
@@ -0,0 +1,83 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2012, 2017 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# A badly formed parameter passed to zdb(1) should
+# return an error.
+#
+# STRATEGY:
+# 1. Create an array containing bad zdb parameters.
+# 2. For each element, execute the sub-command.
+# 3. Verify it returns an error.
+#
+
+verify_runnable "global"
+
+set -A args "create" "add" "destroy" "import fakepool" \
+ "export fakepool" "create fakepool" "add fakepool" \
+ "create mirror" "create raidz" \
+ "create mirror fakepool" "create raidz fakepool" \
+ "create raidz1 fakepool" "create raidz2 fakepool" \
+ "create fakepool mirror" "create fakepool raidz" \
+ "create fakepool raidz1" "create fakepool raidz2" \
+ "add fakepool mirror" "add fakepool raidz" \
+ "add fakepool raidz1" "add fakepool raidz2" \
+ "add mirror fakepool" "add raidz fakepool" \
+ "add raidz1 fakepool" "add raidz2 fakepool" \
+ "setvprop" "blah blah" "-%" "--?" "-*" "-=" \
+ "-a" "-f" "-g" "-j" "-n" "-o" "-p" "-p /tmp" "-r" \
+ "-t" "-w" "-z" "-E" "-H" "-I" "-J" "-K" \
+ "-N" "-Q" "-R" "-T" "-W"
+
+log_assert "Execute zdb using invalid parameters."
+
+log_onexit cleanup
+
+function cleanup
+{
+ default_cleanup_noexit
+}
+
+function test_imported_pool
+{
+ for i in ${args[@]}; do
+ log_mustnot zdb $i $TESTPOOL
+ done
+}
+
+default_mirror_setup_noexit $DISKS
+
+test_imported_pool
+
+log_pass "Badly formed zdb parameters fail as expected."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_pos.ksh
new file mode 100755
index 000000000000..4c2fc15ec025
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_pos.ksh
@@ -0,0 +1,104 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2012, 2020 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZDB allows a large number of possible inputs
+# and combinations of those inputs. Test for non-zero
+# exit values. These input options are based on the zdb
+# man page
+#
+# STRATEGY:
+# 1. Create an array containing value zdb parameters.
+# 2. For each element, execute the sub-command.
+# 3. Verify it does not return a error.
+#
+
+verify_runnable "global"
+
+log_assert "Execute zdb using valid parameters."
+
+log_onexit cleanup
+
+function cleanup
+{
+ default_cleanup_noexit
+}
+
+function test_imported_pool
+{
+ typeset -a args=("-A" "-b" "-C" "-c" "-d" "-D" "-G" "-h" "-i" "-L" \
+ "-M" "-P" "-s" "-v" "-Y" "-y")
+ for i in ${args[@]}; do
+ log_must eval "zdb $i $TESTPOOL >/dev/null"
+ done
+}
+
+function test_exported_pool
+{
+ log_must zpool export $TESTPOOL
+ typeset -a args=("-A" "-b" "-C" "-c" "-d" "-D" "-F" "-G" "-h" "-i" "-L" "-M" \
+ "-P" "-s" "-v" "-X" "-Y" "-y")
+ for i in ${args[@]}; do
+ log_must eval "zdb -e $i $TESTPOOL >/dev/null"
+ done
+ log_must zpool import $TESTPOOL
+}
+
+function test_vdev
+{
+ typeset -a args=("-A" "-q" "-u" "-Aqu")
+ VDEVS=$(get_pool_devices ${TESTPOOL} ${DEV_RDSKDIR})
+ log_note $VDEVS
+ set -A VDEV_ARRAY $VDEVS
+ for i in ${args[@]}; do
+ log_must eval "zdb -l $i ${VDEV_ARRAY[0]} >/dev/null"
+ done
+}
+
+function test_metaslab
+{
+ typeset -a args=("-A" "-L" "-P" "-Y")
+ for i in ${args[@]}; do
+ log_must eval "zdb -m $i $TESTPOOL >/dev/null"
+ done
+}
+
+default_mirror_setup_noexit $DISKS
+
+test_imported_pool
+test_exported_pool
+test_vdev
+test_metaslab
+
+log_pass "Valid zdb parameters pass as expected."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_block_size_histogram.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_block_size_histogram.ksh
new file mode 100755
index 000000000000..0c949f9839e1
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_block_size_histogram.ksh
@@ -0,0 +1,272 @@
+#!/bin/ksh -p
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2017 by Delphix. All rights reserved.
+# Copyright (c) 2020 by Lawrence Livermore National Security LLC.
+
+. $STF_SUITE/include/libtest.shlib
+
+
+#
+# DESCRIPTION:
+# Create a pool and populate it with files of various
+# recordsizes
+#
+# STRATEGY:
+# 1. Create pool
+# 2. Populate it
+# 3. Run zdb -Pbbb on pool
+# 4. Verify variance on blocksizes
+#
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+SPA_MAXBLOCKSHIFT=24
+
+function histo_populate_test_pool
+{
+ if [ $# -ne 1 ]; then
+ log_note "histo_populate_test_pool: insufficient parameters"
+ log_fail "hptp: 1 requested $# received"
+ fi
+ typeset pool=$1
+
+ set -A recordsizes
+ typeset -i min_rsbits=9 #512
+ typeset -i max_rsbits=SPA_MAXBLOCKSHIFT #16 MiB
+ typeset -i sum_filesizes=0
+ re_number='^[0-9]+$'
+
+ let histo_pool_size=$(get_pool_prop size ${pool})
+ if [[ ! ${histo_pool_size} =~ ${re_number} ]]; then
+ log_fail "histo_pool_size is not numeric ${pool_size}"
+ fi
+ let max_pool_record_size=$(get_prop recordsize ${pool})
+ if [[ ! ${max_pool_record_size} =~ ${re_number} ]]; then
+ log_fail "hptp: max_pool_record_size is not numeric ${max_pool_record_size}"
+ fi
+
+ sum_filesizes=$(echo "2^21"|bc)
+ ((min_pool_size=12*sum_filesizes))
+ if [ ${histo_pool_size} -lt ${min_pool_size} ]; then
+ log_note "hptp: Your pool size ${histo_pool_size}"
+ log_fail "hptp: is less than minimum ${min_pool_size}"
+ fi
+ this_ri=min_rsbits
+ file_num=0
+ total_count=0
+ ###################
+ # generate 10% + 20% + 30% + 31% = 91% of the filespace
+ # attempting to use 100% will lead to no space left on device
+ # Heuristic testing showed that 91% was the practical upper
+ # bound on the default 4G zpool (mirrored) that is used in
+ # testing.
+ #
+ # In order to expedite testing, we will only fill 2G (of 4G)
+ # of the test pool. You may want to modify this for
+ # standalone testing.
+ #
+ # In filling only 50% of the pool, we create one object on
+ # each "pass" below to achieve multiple objects per record
+ # size. Creating one file per object would lead to
+ # excessive file creation time.
+ ###################
+ # for pass in 10 20 30 31 # 91%
+ for pass in 20 20 10 # 50%
+ do
+ ((thiscount=(((histo_pool_size*pass)/100)/sum_filesizes)))
+
+ ((total_count+=thiscount))
+ for rb in $(seq ${min_rsbits} ${max_rsbits})
+ do
+ this_rs=$(echo "2^${rb}" | bc)
+ if [ ${this_rs} -gt ${max_pool_record_size} ]; then
+ continue
+ fi
+
+ if [ ! -d /${pool}/B_${this_rs} ]; then
+ zfs create ${pool}/B_${this_rs}
+ zfs set recordsize=${this_rs} \
+ ${pool}/B_${this_rs}
+ fi
+ ####################
+ # Create the files in the devices and datasets
+ # of the right size. The files are filled
+ # with random data to defeat the compression
+ #
+ # Note that the dd output is suppressed unless
+ # there are errors
+ ####################
+
+ dd if=/dev/urandom \
+ of=/${pool}/B_${this_rs}/file_${filenum} \
+ bs=${this_rs} count=${thiscount} \
+ iflag=fullblock 2>&1 | \
+ egrep -v -e "records in" -e "records out" \
+ -e "bytes.*copied"
+ ((filenum+=1))
+ done
+ done
+
+ ####################
+ # Testing showed that on some devices, unless the pool is
+ # synchronized, that the block counts will be below the
+ # anticipated sizes since not all of the blocks will be flushed
+ # to the device. This 'sync' command prevents that from
+ # happening.
+ ####################
+ log_must zpool sync ${pool}
+}
+function histo_check_test_pool
+{
+ if [ $# -ne 1 ]; then
+ log_note "histo_check_test_pool: insufficient parameters"
+ log_fail "hctp: 1 requested $# received"
+ fi
+ typeset pool=$1
+
+ set -A recordsizes
+ set -A recordcounts
+ typeset -i rb
+ typeset -i min_rsbits=9 #512
+ typeset -i max_rsbits=SPA_MAXBLOCKSHIFT+1
+ typeset -i this_rs
+ typeset -i this_ri
+ typeset -i sum_filesizes=0
+ typeset dumped
+ typeset stripped
+
+ let histo_check_pool_size=$(get_pool_prop size ${pool})
+ if [[ ! ${histo_check_pool_size} =~ ${re_number} ]]; then
+ log_fail "histo_check_pool_size is not numeric ${histo_check_pool_size}"
+ fi
+ let max_pool_record_size=$(get_prop recordsize ${pool})
+ if [[ ! ${max_pool_record_size} =~ ${re_number} ]]; then
+ log_fail "hctp: max_pool_record_size is not numeric ${max_pool_record_size}"
+ fi
+
+ dumped="${TEST_BASE_DIR}/${pool}_dump.txt"
+ stripped="${TEST_BASE_DIR}/${pool}_stripped.txt"
+
+ zdb -Pbbb ${pool} | \
+ tee ${dumped} | \
+ sed -e '1,/^block[ ][ ]*psize[ ][ ]*lsize.*$/d' \
+ -e '/^size[ ]*Count/d' -e '/^$/,$d' \
+ > ${stripped}
+
+ sum_filesizes=$(echo "2^21"|bc)
+
+ ###################
+ # generate 10% + 20% + 30% + 31% = 91% of the filespace
+ # attempting to use 100% will lead to no space left on device
+ # attempting to use 100% will lead to no space left on device
+ # Heuristic testing showed that 91% was the practical upper
+ # bound on the default 4G zpool (mirrored) that is used in
+ # testing.
+ #
+ # In order to expedite testing, we will only fill 2G (of 4G)
+ # of the test pool. You may want to modify this for
+ # standalone testing.
+ #
+ # In filling only 50% of the pool, we create one object on
+ # each "pass" below to achieve multiple objects per record
+ # size. Creating one file per object would lead to
+ # excessive file creation time.
+ ###################
+ # for pass in 10 20 30 31 # 91%
+ for pass in 20 20 10 # 50%
+ do
+ ((thiscount=(((histo_check_pool_size*pass)/100)/sum_filesizes)))
+
+ for rb in $(seq ${min_rsbits} ${max_rsbits})
+ do
+ blksize=$(echo "2^$rb"|bc)
+ if [ $blksize -le $max_pool_record_size ]; then
+ ((recordcounts[$blksize]+=thiscount))
+ fi
+ done
+ done
+
+ ###################
+ # compare the above computed counts for blocks against
+ # lsize count. Since some devices have a minimum hardware
+ # blocksize > 512, we cannot compare against the asize count.
+ # E.G., if the HWBlocksize = 4096, then the asize counts for
+ # 512, 1024 and 2048 will be zero and rolled up into the
+ # 4096 blocksize count for asize. For verification we stick
+ # to just lsize counts.
+ #
+ # The max_variance is hard-coded here at 10%. testing so far
+ # has shown this to be in the range of 2%-8% so we leave a
+ # generous allowance... This might need changes in the future
+ ###################
+ let max_variance=10
+ let fail_value=0
+ let error_count=0
+ log_note "Comparisons for ${pool}"
+ log_note "Bsize is the blocksize, Count is predicted value"
+ log_note "Bsize\tCount\tpsize\tlsize\tasize"
+ while read -r blksize pc pl pm lc ll lm ac al am
+ do
+ if [ $blksize -gt $max_pool_record_size ]; then
+ continue
+ fi
+ log_note \
+ "$blksize\t${recordcounts[${blksize}]}\t$pc\t$lc\t$ac"
+
+ ###################
+ # get the computer record count and compute the
+ # difference percentage in integer arithmetic
+ ###################
+ rc=${recordcounts[${blksize}]}
+ ((rclc=(rc-lc)<0?lc-rc:rc-lc)) # absolute value
+ ((dp=(rclc*100)/rc))
+
+ ###################
+ # Check against the allowed variance
+ ###################
+ if [ $dp -gt ${max_variance} ]; then
+ log_note \
+ "Expected variance < ${max_variance}% observed ${dp}%"
+ if [ ${dp} -gt ${fail_value} ]; then
+ fail_value=${dp}
+ ((error_count++))
+ fi
+ fi
+ done < ${stripped}
+ if [ ${fail_value} -gt 0 ]; then
+ if [ ${error_count} -eq 1 ]; then
+ log_note "hctp: There was ${error_count} error"
+ else
+ log_note "hctp:There were a total of ${error_count} errors"
+ fi
+ log_fail \
+ "hctp: Max variance of ${max_variance}% exceeded, saw ${fail_value}%"
+ fi
+}
+
+log_assert "Verify zdb -Pbbb (block histogram) works as expected"
+log_onexit cleanup
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+default_mirror_setup_noexit $DISKS
+
+histo_populate_test_pool $TESTPOOL
+
+histo_check_test_pool $TESTPOOL
+
+log_pass "Histogram for zdb"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_checksum.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_checksum.ksh
new file mode 100755
index 000000000000..eeff6575f0f4
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_checksum.ksh
@@ -0,0 +1,64 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2019 by Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb -c will display the same checksum as -ddddddbbbbbb
+#
+# Strategy:
+# 1. Create a pool
+# 2. Write some data to a file
+# 3. Run zdb -ddddddbbbbbb against the file
+# 4. Record the checksum and DVA of L0 block 0
+# 5. Run zdb -R with :c flag and match the checksum
+
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Verify zdb -R generates the correct checksum."
+log_onexit cleanup
+init_data=$TESTDIR/file1
+write_count=8
+blksize=131072
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+default_mirror_setup_noexit $DISKS
+file_write -o create -w -f $init_data -b $blksize -c $write_count
+
+# get object number of file
+listing=$(ls -i $init_data)
+set -A array $listing
+obj=${array[0]}
+log_note "file $init_data has object number $obj"
+
+output=$(zdb -ddddddbbbbbb $TESTPOOL/$TESTFS $obj 2> /dev/null \
+ |grep -m 1 "L0 DVA" |head -n1)
+dva=$(sed -Ene 's/^.+DVA\[0\]=<([^>]+)>.*$/\1/p' <<< "$output")
+log_note "block 0 of $init_data has a DVA of $dva"
+cksum_expected=$(sed -Ene 's/^.+ cksum=([a-z0-9:]+)$/\1/p' <<< "$output")
+log_note "expecting cksum $cksum_expected"
+output=$(zdb -R $TESTPOOL $dva:c 2> /dev/null)
+result=$(grep $cksum_expected <<< "$output")
+(( $? != 0 )) && log_fail "zdb -R failed to print the correct checksum"
+
+log_pass "zdb -R generates the correct checksum"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_decompress.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_decompress.ksh
new file mode 100755
index 000000000000..1ebcbfb44953
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_decompress.ksh
@@ -0,0 +1,119 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2019 by Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb -R pool <DVA>:d will display the correct data and length
+#
+# Strategy:
+# 1. Create a pool, set compression to lzjb
+# 2. Write some identifiable data to a file
+# 3. Run zdb -ddddddbbbbbb against the file
+# 4. Record the DVA, lsize, and psize of L0 block 0
+# 5. Run zdb -R with :d flag and match the data
+# 6. Run zdb -R with :dr flags and match the lsize/psize
+# 7. Run zdb -R with :dr flags and match the lsize
+# 8. Run zdb -R with :dr flags and match the psize
+#
+
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Verify zdb -R :d flag (decompress) works as expected"
+log_onexit cleanup
+init_data=$TESTDIR/file1
+write_count=256
+blksize=4096
+pattern="_match__pattern_"
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+default_mirror_setup_noexit $DISKS
+log_must zfs set recordsize=$blksize $TESTPOOL/$TESTFS
+log_must zfs set compression=lzjb $TESTPOOL/$TESTFS
+
+# 16 chars 256 times = 4k = block size
+typeset four_k=""
+for i in {1..$write_count}
+do
+ four_k=$four_k$pattern
+done
+
+# write the 4k block 256 times
+for i in {1..$write_count}
+do
+ echo $four_k >> $init_data
+done
+
+sync_pool $TESTPOOL true
+
+# get object number of file
+listing=$(ls -i $init_data)
+set -A array $listing
+obj=${array[0]}
+log_note "file $init_data has object number $obj"
+
+output=$(zdb -ddddddbbbbbb $TESTPOOL/$TESTFS $obj 2> /dev/null \
+ |grep -m 1 "L0 DVA" |head -n1)
+dva=$(sed -Ene 's/^.+DVA\[0\]=<([^>]+)>.*$/\1/p' <<< "$output")
+log_note "block 0 of $init_data has a DVA of $dva"
+
+# use the length reported by zdb -ddddddbbbbbb
+size_str=$(sed -Ene 's/^.+ size=([^ ]+) .*$/\1/p' <<< "$output")
+log_note "block size $size_str"
+
+vdev=$(echo "$dva" |awk '{split($0,array,":")} END{print array[1]}')
+offset=$(echo "$dva" |awk '{split($0,array,":")} END{print array[2]}')
+output=$(zdb -R $TESTPOOL $vdev:$offset:$size_str:d 2> /dev/null)
+echo $output |grep $pattern > /dev/null
+(( $? != 0 )) && log_fail "zdb -R :d failed to decompress the data properly"
+
+output=$(zdb -R $TESTPOOL $vdev:$offset:$size_str:dr 2> /dev/null)
+echo $output |grep $four_k > /dev/null
+(( $? != 0 )) && log_fail "zdb -R :dr failed to decompress the data properly"
+
+output=$(zdb -R $TESTPOOL $vdev:$offset:$size_str:dr 2> /dev/null)
+result=${#output}
+(( $result != $blksize)) && log_fail \
+"zdb -R failed to decompress the data to the length (${#output} != $size_str)"
+
+# decompress using lsize
+lsize=$(echo $size_str |awk '{split($0,array,"/")} END{print array[1]}')
+psize=$(echo $size_str |awk '{split($0,array,"/")} END{print array[2]}')
+output=$(zdb -R $TESTPOOL $vdev:$offset:$lsize:dr 2> /dev/null)
+result=${#output}
+(( $result != $blksize)) && log_fail \
+"zdb -R failed to decompress the data (length ${#output} != $blksize)"
+
+# Specifying psize will decompress successfully , but not always to full
+# lsize since zdb has to guess lsize incrementally.
+output=$(zdb -R $TESTPOOL $vdev:$offset:$psize:dr 2> /dev/null)
+result=${#output}
+# convert psize to decimal
+psize_orig=$psize
+psize=${psize%?}
+psize=$((16#$psize))
+(( $result < $psize)) && log_fail \
+"zdb -R failed to decompress the data with psize $psize_orig\
+ (length ${#output} < $psize)"
+
+log_pass "zdb -R :d flag (decompress) works as expected"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_decompress_zstd.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_decompress_zstd.ksh
new file mode 100755
index 000000000000..238d49560461
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_decompress_zstd.ksh
@@ -0,0 +1,114 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2020 The FreeBSD Foundation [1]
+#
+# [1] Portions of this software were developed by Allan Jude
+# under sponsorship from the FreeBSD Foundation.
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb -Z pool <objid> will display the ZSTD compression header
+# This will contain the actual length of the compressed data, as well as
+# the version of ZSTD used to compress the block, and the compression level
+#
+# Strategy:
+# 1. Create a pool, set compression to zstd-<random level>
+# 2. Write some identifiable data to a file
+# 3. Run zdb -Zddddddbbbbbb against the file
+# 4. Record the DVA, lsize, and psize, and ZSTD header of L0 block 0
+# 5. Check that the ZSTD length is less than psize
+# 6. Check that the ZSTD level matches the level we requested
+# 7. Run zdb -R with :dr flags and confirm the size and content match
+#
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Verify zdb -Z (read ZSTD header) works as expected"
+log_onexit cleanup
+src_data="$STF_SUITE/tests/functional/cli_root/zfs_receive/zstd_test_data.txt"
+init_data=$TESTDIR/file1
+write_count=128
+blksize=131072
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+random_level=$((RANDOM%19 + 1))
+
+default_mirror_setup_noexit $DISKS
+log_must zfs set recordsize=$blksize $TESTPOOL/$TESTFS
+log_must zfs set compression=zstd-$random_level $TESTPOOL/$TESTFS
+
+# write the 1k of text 128 times
+for i in {1..$write_count}
+do
+ cat $src_data >> $init_data
+done
+
+sync_pool $TESTPOOL true
+
+# get object number of file
+listing=$(ls -i $init_data)
+set -A array $listing
+obj=${array[0]}
+log_note "file $init_data has object number $obj"
+
+output=$(zdb -Zddddddbbbbbb $TESTPOOL/$TESTFS $obj 2> /dev/null \
+ |grep -m 1 "L0 DVA" |head -n1)
+dva=$(sed -Ene 's/^.+DVA\[0\]=<([^>]+)>.*$/\1/p' <<< "$output")
+log_note "block 0 of $init_data has a DVA of $dva"
+
+# use the length reported by zdb -ddddddbbbbbb
+size_str=$(sed -Ene 's/^.+ size=([^ ]+) .*$/\1/p' <<< "$output")
+# convert sizes to decimal
+lsize=$(echo $size_str |awk '{split($0,array,"/")} END{print array[1]}')
+lsize_orig=$lsize
+lsize=${lsize%?}
+lsize_bytes=$((16#$lsize))
+psize=$(echo $size_str |awk '{split($0,array,"/")} END{print array[2]}')
+psize_orig=$psize
+psize=${psize%?}
+psize_bytes=$((16#$psize))
+log_note "block size $size_str"
+
+# Get the ZSTD header reported by zdb -Z
+zstd_str=$(sed -Ene 's/^.+ ZSTD:size=([^:]+):version=([^:]+):level=([^:]+):.*$/\1:\2:\3/p' <<< "$output")
+zstd_size=$(echo "$zstd_str" |awk '{split($0,array,":")} END{print array[1]}')
+log_note "ZSTD compressed size $zstd_size"
+(( $psize_bytes < $zstd_size )) && log_fail \
+"zdb -Z failed: physical block size was less than header content length ($psize_bytes < $zstd_size)"
+
+zstd_version=$(echo "$zstd_str" |awk '{split($0,array,":")} END{print array[2]}')
+log_note "ZSTD version $zstd_version"
+
+zstd_level=$(echo "$zstd_str" |awk '{split($0,array,":")} END{print array[3]}')
+log_note "ZSTD level $zstd_level"
+(( $zstd_level != $random_level )) && log_fail \
+"zdb -Z failed: compression level did not match header level ($zstd_level < $random_level)"
+
+vdev=$(echo "$dva" |awk '{split($0,array,":")} END{print array[1]}')
+offset=$(echo "$dva" |awk '{split($0,array,":")} END{print array[2]}')
+# Check the first 1024 bytes
+output=$(ZDB_NO_ZLE="true" zdb -R $TESTPOOL $vdev:$offset:$size_str:dr 2> /dev/null)
+outsize=$(wc -c <<< "$output")
+(( $outsize != $blksize )) && log_fail \
+"zdb -Z failed to decompress the data to the expected length ($outsize != $lsize_bytes)"
+cmp $init_data - <<< "$output"
+(( $? != 0 )) && log_fail "zdb -R :dr failed to decompress the data properly"
+
+log_pass "zdb -Z flag (ZSTD compression header) works as expected"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_display_block.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_display_block.ksh
new file mode 100755
index 000000000000..5cc4575851f7
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_display_block.ksh
@@ -0,0 +1,128 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2019 by Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb -R pool <DVA>:b will display the block
+#
+# Strategy:
+# 1. Create a pool, set compression to lzjb
+# 2. Write some identifiable data to a file
+# 3. Run zdb -ddddddbbbbbb against the file
+# 4. Record the DVA of the first L1 block;
+# record the first L0 block display; and
+# record the 2nd L0 block display.
+# 5. Run zdb -R with :bd displays first L0
+# 6. Run zdb -R with :b80d displays 2nd L0
+# 7. Run zdb -R with :db80 displays 2nd L0
+# 8. Run zdb -R with :id flag displays indirect block
+# (similar to zdb -ddddddbbbbbb output)
+# 9. Run zdb -R with :id flag and .0 vdev
+#
+
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Verify zdb -R :b flag (block display) works as expected"
+log_onexit cleanup
+init_data=$TESTDIR/file1
+write_count=256
+blksize=4096
+
+# only read 256 128 byte block pointers in L1 (:i flag)
+# 256 x 128 = 32k / 0x8000
+l1_read_size="8000"
+
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+default_mirror_setup_noexit $DISKS
+log_must zfs set recordsize=$blksize $TESTPOOL/$TESTFS
+log_must zfs set compression=lzjb $TESTPOOL/$TESTFS
+
+file_write -d R -o create -w -f $init_data -b $blksize -c $write_count
+sync_pool $TESTPOOL true
+
+# get object number of file
+listing=$(ls -i $init_data)
+set -A array $listing
+obj=${array[0]}
+log_note "file $init_data has object number $obj"
+
+output=$(zdb -ddddddbbbbbb $TESTPOOL/$TESTFS $obj 2> /dev/null \
+ |grep -m 1 "L1 DVA" |head -n1)
+dva=$(sed -Ene 's/^.+DVA\[0\]=<([^>]+)>.*/\1/p' <<< "$output")
+log_note "first L1 block $init_data has a DVA of $dva"
+output=$(zdb -ddddddbbbbbb $TESTPOOL/$TESTFS $obj 2> /dev/null \
+ |grep -m 1 "L0 DVA" |head -n1)
+blk_out0=${output##*>}
+blk_out0=${blk_out0##+([[:space:]])}
+
+output=$(zdb -ddddddbbbbbb $TESTPOOL/$TESTFS $obj 2> /dev/null \
+ |grep -m 1 "1000 L0 DVA" |head -n1)
+blk_out1=${output##*>}
+blk_out1=${blk_out1##+([[:space:]])}
+
+output=$(export ZDB_NO_ZLE=\"true\"; zdb -R $TESTPOOL $dva:bd\
+ 2> /dev/null)
+output=${output##*>}
+output=${output##+([[:space:]])}
+if [ "$output" != "$blk_out0" ]; then
+ log_fail "zdb -R :bd (block 0 display/decompress) failed"
+fi
+
+output=$(export ZDB_NO_ZLE=\"true\"; zdb -R $TESTPOOL $dva:db80\
+ 2> /dev/null)
+output=${output##*>}
+output=${output##+([[:space:]])}
+if [ "$output" != "$blk_out1" ]; then
+ log_fail "zdb -R :db80 (block 1 display/decompress) failed"
+fi
+
+output=$(export ZDB_NO_ZLE=\"true\"; zdb -R $TESTPOOL $dva:b80d\
+ 2> /dev/null)
+output=${output##*>}
+output=${output##+([[:space:]])}
+if [ "$output" != "$blk_out1" ]; then
+ log_fail "zdb -R :b80d (block 1 display/decompress) failed"
+fi
+
+vdev=$(echo "$dva" |awk '{split($0,array,":")} END{print array[1]}')
+offset=$(echo "$dva" |awk '{split($0,array,":")} END{print array[2]}')
+output=$(export ZDB_NO_ZLE=\"true\";\
+ zdb -R $TESTPOOL $vdev:$offset:$l1_read_size:id 2> /dev/null)
+block_cnt=$(echo "$output" | grep 'L0' | wc -l)
+if [ $block_cnt -ne $write_count ]; then
+ log_fail "zdb -R :id (indirect block display) failed"
+fi
+
+# read from specific half of mirror
+vdev="$vdev.0"
+log_note "Reading from DVA $vdev:$offset:$l1_read_size"
+output=$(export ZDB_NO_ZLE=\"true\";\
+ zdb -R $TESTPOOL $vdev:$offset:$l1_read_size:id 2> /dev/null)
+block_cnt=$(echo "$output" | grep 'L0' | wc -l)
+if [ $block_cnt -ne $write_count ]; then
+ log_fail "zdb -R 0.0:offset:length:id (indirect block display) failed"
+fi
+
+log_pass "zdb -R :b flag (block display) works as expected"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_object_range_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_object_range_neg.ksh
new file mode 100755
index 000000000000..430180788044
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_object_range_neg.ksh
@@ -0,0 +1,72 @@
+#!/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) 2020 Lawrence Livermore National Security, LLC.
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# A badly formed object range parameter passed to zdb -dd should
+# return an error.
+#
+# Strategy:
+# 1. Create a pool
+# 2. Run zdb -dd with assorted invalid object range arguments and
+# confirm it fails as expected
+# 3. Run zdb -dd with an invalid object identifier and
+# confirm it fails as expected
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Execute zdb using invalid object range parameters."
+log_onexit cleanup
+verify_runnable "both"
+verify_disk_count "$DISKS" 2
+default_mirror_setup_noexit $DISKS
+
+log_must zpool sync
+
+set -A bad_flags a b c e g h i j k l n o p q r s t u v w x y \
+ B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
+ 0 1 2 3 4 5 6 7 8 9 _ - + % . , :
+
+typeset -i i=0
+while [[ $i -lt ${#bad_flags[*]} ]]; do
+ log_mustnot zdb -dd $TESTPOOL 0:1:${bad_flags[i]}
+ log_mustnot zdb -dd $TESTPOOL 0:1:A-${bad_flags[i]}
+ ((i = i + 1))
+done
+
+set -A bad_ranges ":" "::" ":::" ":0" "0:" "0:1:" "0:1::" "0::f" "0a:1" \
+ "a0:1" "a:1" "0:a" "0:1a" "0:a1" "a:b0" "a:0b" "0:1:A-" "1:0" \
+ "0:1:f:f" "0:1:f:"
+
+i=0
+while [[ $i -lt ${#bad_ranges[*]} ]]; do
+ log_mustnot zdb -dd $TESTPOOL ${bad_ranges[i]}
+ ((i = i + 1))
+done
+
+# Specifying a non-existent object identifier returns an error
+obj_id_highest=$(zdb -P -dd $TESTPOOL/$TESTFS 2>/dev/null |
+ egrep "^ +-?([0-9]+ +){7}" | sort -n | tail -n 1 | awk '{print $1}')
+obj_id_invalid=$(( $obj_id_highest + 1 ))
+log_mustnot zdb -dd $TESTPOOL/$TESTFS $obj_id_invalid
+
+log_pass "Badly formed zdb object range parameters fail as expected."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_object_range_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_object_range_pos.ksh
new file mode 100755
index 000000000000..b7f47d11ad2f
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_object_range_pos.ksh
@@ -0,0 +1,171 @@
+#!/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) 2020 Lawrence Livermore National Security, LLC.
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# Object range parameters passed to zdb -dd work correctly.
+#
+# Strategy:
+# 1. Create a pool
+# 2. Create some files
+# 3. Run zdb -dd with assorted object range arguments and verify output
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+#
+# Print objects in @dataset with identifiers greater than or equal to
+# @begin and less than or equal to @end, without using object range
+# parameters.
+#
+function get_object_list_range
+{
+ dataset=$1
+ begin=$2
+ end=$3
+ get_object_list $dataset |
+ while read line; do
+ obj=$(echo $line | awk '{print $1}')
+ if [[ $obj -ge $begin && $obj -le $end ]] ; then
+ echo "$line"
+ elif [[ $obj -gt $end ]] ; then
+ break
+ fi
+ done
+}
+
+#
+# Print just the list of objects from 'zdb -dd' with leading whitespace
+# trimmed, discarding other zdb output, sorted by object identifier.
+# Caller must pass in the dataset argument at minimum.
+#
+function get_object_list
+{
+ zdb -P -dd $@ 2>/dev/null |
+ egrep "^ +-?([0-9]+ +){7}" |
+ sed 's/^[[:space:]]*//' |
+ sort -n
+}
+
+log_assert "Verify zdb -dd object range arguments work correctly."
+log_onexit cleanup
+verify_runnable "both"
+verify_disk_count "$DISKS" 2
+default_mirror_setup_noexit $DISKS
+
+for x in $(seq 0 7); do
+ touch $TESTDIR/file$x
+ mkdir $TESTDIR/dir$x
+done
+
+log_must zpool sync
+
+# Get list of all objects, but filter out user/group objects which don't
+# appear when using object or object range arguments
+all_objects=$(get_object_list $TESTPOOL/$TESTFS | grep -v 'used$')
+
+# Range 0:-1 gets all objects
+expected=$all_objects
+actual=$(get_object_list $TESTPOOL/$TESTFS 0:-1)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Range 0:-1:A gets all objects
+expected=$all_objects
+actual=$(get_object_list $TESTPOOL/$TESTFS 0:-1:A)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Range 0:-1:f must output all file objects
+expected=$(grep "ZFS plain file" <<< $all_objects)
+actual=$(get_object_list $TESTPOOL/$TESTFS 0:-1:f)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Range 0:-1:d must output all directory objects
+expected=$(grep "ZFS directory" <<< $all_objects)
+actual=$(get_object_list $TESTPOOL/$TESTFS 0:-1:d)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Range 0:-1:df must output all directory and file objects
+expected=$(grep -e "ZFS directory" -e "ZFS plain file" <<< $all_objects)
+actual=$(get_object_list $TESTPOOL/$TESTFS 0:-1:df)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Range 0:-1:A-f-d must output all non-files and non-directories
+expected=$(grep -v -e "ZFS plain file" -e "ZFS directory" <<< $all_objects)
+actual=$(get_object_list $TESTPOOL/$TESTFS 0:-1:A-f-d)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Specifying multiple ranges works
+set -A obj_ids $(ls -i $TESTDIR | awk '{print $1}' | sort -n)
+start1=${obj_ids[0]}
+end1=${obj_ids[5]}
+start2=${obj_ids[8]}
+end2=${obj_ids[13]}
+expected=$(get_object_list_range $TESTPOOL/$TESTFS $start1 $end1;
+ get_object_list_range $TESTPOOL/$TESTFS $start2 $end2)
+actual=$(get_object_list $TESTPOOL/$TESTFS $start1:$end1 $start2:$end2)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Combining ranges with individual object IDs works
+expected=$(get_object_list_range $TESTPOOL/$TESTFS $start1 $end1;
+ get_object_list $TESTPOOL/$TESTFS $start2 $end2)
+actual=$(get_object_list $TESTPOOL/$TESTFS $start1:$end1 $start2 $end2)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Hex conversion must work for ranges and individual object identifiers
+# (this test uses expected result from previous test).
+start1_hex=$(printf "0x%x" $start1)
+end1_hex=$(printf "0x%x" $end1)
+start2_hex=$(printf "0x%x" $start2)
+end2_hex=$(printf "0x%x" $end2)
+actual=$(get_object_list $TESTPOOL/$TESTFS $start1_hex:$end1_hex \
+ $start2_hex $end2_hex)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Specifying individual object IDs works
+objects="$start1 $end1 $start2 $end2"
+expected="$objects"
+actual=$(get_object_list $TESTPOOL/$TESTFS $objects | awk '{print $1}' | xargs)
+log_must test "$actual" == "$expected"
+
+# Get all objects in the meta-objset to test m (spacemap) and z (zap) flags
+all_mos_objects=$(get_object_list $TESTPOOL 0:-1)
+
+# Range 0:-1:m must output all space map objects
+expected=$(grep "SPA space map" <<< $all_mos_objects)
+actual=$(get_object_list $TESTPOOL 0:-1:m)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Range 0:-1:z must output all zap objects
+expected=$(grep "zap" <<< $all_mos_objects)
+actual=$(get_object_list $TESTPOOL 0:-1:z)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Range 0:-1:A-m-z must output all non-space maps and non-zaps
+expected=$(grep -v -e "zap" -e "SPA space map" <<< $all_mos_objects)
+actual=$(get_object_list $TESTPOOL 0:-1:A-m-z)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+# Range 0:-1:mz must output all space maps and zaps
+expected=$(grep -e "SPA space map" -e "zap" <<< $all_mos_objects)
+actual=$(get_object_list $TESTPOOL 0:-1:mz)
+log_must test "\n$actual\n" == "\n$expected\n"
+
+log_pass "zdb -dd object range arguments work correctly"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_objset_id.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_objset_id.ksh
new file mode 100755
index 000000000000..f0c1076c97bd
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_objset_id.ksh
@@ -0,0 +1,96 @@
+#!/bin/ksh
+
+#
+# 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.
+#
+
+#
+# Copyright (c) 2020 by Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# Description:
+# zdb -d pool/<objset id> will display the dataset
+#
+# Strategy:
+# 1. Create a pool
+# 2. Write some data to a file
+# 3. Get the inode number (object number) of the file
+# 4. Run zdb -d to get the objset ID of the dataset
+# 5. Run zdb -dddddd pool/objsetID objectID (decimal)
+# 6. Confirm names
+# 7. Run zdb -dddddd pool/objsetID objectID (hex)
+# 8. Confirm names
+# 9. Obtain objsetID from /proc/spl/kstat/zfs/testpool/obset-0x<ID>
+# (linux only)
+# 10. Run zdb -dddddd pool/objsetID (hex)
+# 11. Match name from zdb against proc entry
+#
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Verify zdb -d <pool>/<objset ID> generates the correct names."
+log_onexit cleanup
+init_data=$TESTDIR/file1
+write_count=8
+blksize=131072
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+default_mirror_setup_noexit $DISKS
+file_write -o create -w -f $init_data -b $blksize -c $write_count
+
+# get object number of file
+listing=$(ls -i $init_data)
+set -A array $listing
+obj=${array[0]}
+log_note "file $init_data has object number $obj"
+
+output=$(zdb -d $TESTPOOL/$TESTFS)
+objset_id=$(echo $output | awk '{split($0,array,",")} END{print array[2]}' |
+ awk '{split($0,array," ")} END{print array[2]}')
+objset_hex=$(printf "0x%X" $objset_id)
+log_note "objset $TESTPOOL/$TESTFS has objset ID $objset_id ($objset_hex)"
+
+for id in "$objset_id" "$objset_hex"
+do
+ log_note "zdb -dddddd $TESTPOOL/$id $obj"
+ output=$(zdb -dddddd $TESTPOOL/$id $obj)
+ reason="($TESTPOOL/$TESTFS not in zdb output)"
+ echo $output |grep "$TESTPOOL/$TESTFS" > /dev/null
+ (( $? != 0 )) && log_fail \
+ "zdb -dddddd $TESTPOOL/$id $obj failed $reason"
+ reason="(file1 not in zdb output)"
+ echo $output |grep "file1" > /dev/null
+ (( $? != 0 )) && log_fail \
+ "zdb -dddddd $TESTPOOL/$id $obj failed $reason"
+ obj=$(printf "0x%X" $obj)
+done
+
+if is_linux; then
+ output=$(ls -1 /proc/spl/kstat/zfs/$TESTPOOL |grep objset- |tail -1)
+ objset_hex=${output#*-}
+ name_from_proc=$(cat /proc/spl/kstat/zfs/$TESTPOOL/$output |
+ grep dataset_name | awk '{split($0,array," ")} END{print array[3]}')
+ log_note "checking zdb output for $name_from_proc"
+ reason="(name $name_from_proc from proc not in zdb output)"
+ log_note "zdb -dddddd $TESTPOOL/$objset_hex"
+ output=$(zdb -dddddd $TESTPOOL/$objset_hex)
+ echo $output |grep "$name_from_proc" > /dev/null
+ (( $? != 0 )) && log_fail \
+ "zdb -dddddd $TESTPOOL/$objset_hex failed $reason"
+fi
+
+log_pass "zdb -d <pool>/<objset ID> generates the correct names."