summaryrefslogtreecommitdiff
path: root/usr/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/test')
-rw-r--r--usr/src/test/zfs-tests/include/commands.cfg2
-rw-r--r--usr/src/test/zfs-tests/runfiles/delphix.run4
-rw-r--r--usr/src/test/zfs-tests/runfiles/omnios.run4
-rw-r--r--usr/src/test/zfs-tests/runfiles/openindiana.run4
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/Makefile5
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib197
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh51
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh49
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh52
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh60
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh52
11 files changed, 466 insertions, 14 deletions
diff --git a/usr/src/test/zfs-tests/include/commands.cfg b/usr/src/test/zfs-tests/include/commands.cfg
index 36f9457197..6fd8a66ea1 100644
--- a/usr/src/test/zfs-tests/include/commands.cfg
+++ b/usr/src/test/zfs-tests/include/commands.cfg
@@ -124,6 +124,7 @@ export SHARE="/usr/sbin/share"
export SHUF="/usr/bin/shuf"
export SLEEP="/usr/bin/sleep"
export SORT="/usr/bin/sort"
+export STAT="/usr/bin/stat"
export STRINGS="/usr/bin/strings"
export SU="/usr/bin/su"
export SUM="/usr/bin/sum"
@@ -136,6 +137,7 @@ export TAIL="/usr/bin/tail"
export TAR="/usr/sbin/tar"
export TOUCH="/usr/bin/touch"
export TR="/usr/bin/tr"
+export TRUNCATE="/usr/bin/truncate"
export TRUE="/usr/bin/true"
export TUNEFS="/usr/sbin/tunefs"
export UFSDUMP="/usr/sbin/ufsdump"
diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run
index 0ab2739792..895b8d908c 100644
--- a/usr/src/test/zfs-tests/runfiles/delphix.run
+++ b/usr/src/test/zfs-tests/runfiles/delphix.run
@@ -463,7 +463,9 @@ tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_neg']
tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'rsend_005_pos', 'rsend_006_pos', 'rsend_007_pos', 'rsend_008_pos',
'rsend_009_pos', 'rsend_010_pos', 'rsend_011_pos', 'rsend_012_pos',
- 'rsend_013_pos', 'rsend_014_pos']
+ 'rsend_013_pos', 'rsend_014_pos',
+ 'rsend_019_pos', 'rsend_020_pos',
+ 'rsend_021_pos', 'rsend_022_pos', 'rsend_024_pos']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run
index f19c83f10d..0542ddb23c 100644
--- a/usr/src/test/zfs-tests/runfiles/omnios.run
+++ b/usr/src/test/zfs-tests/runfiles/omnios.run
@@ -463,7 +463,9 @@ tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_neg']
tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'rsend_005_pos', 'rsend_006_pos', 'rsend_007_pos', 'rsend_008_pos',
'rsend_009_pos', 'rsend_010_pos', 'rsend_011_pos', 'rsend_012_pos',
- 'rsend_013_pos', 'rsend_014_pos']
+ 'rsend_013_pos', 'rsend_014_pos',
+ 'rsend_019_pos', 'rsend_020_pos',
+ 'rsend_021_pos', 'rsend_022_pos', 'rsend_024_pos']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run
index f525b7297e..7add5337c2 100644
--- a/usr/src/test/zfs-tests/runfiles/openindiana.run
+++ b/usr/src/test/zfs-tests/runfiles/openindiana.run
@@ -463,7 +463,9 @@ tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_neg']
tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'rsend_005_pos', 'rsend_006_pos', 'rsend_007_pos', 'rsend_008_pos',
'rsend_009_pos', 'rsend_010_pos', 'rsend_011_pos', 'rsend_012_pos',
- 'rsend_013_pos', 'rsend_014_pos']
+ 'rsend_013_pos', 'rsend_014_pos',
+ 'rsend_019_pos', 'rsend_020_pos',
+ 'rsend_021_pos', 'rsend_022_pos', 'rsend_024_pos']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/Makefile b/usr/src/test/zfs-tests/tests/functional/rsend/Makefile
index fb757b29a3..c482d9d607 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/Makefile
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/Makefile
@@ -33,6 +33,11 @@ PROGS = cleanup \
rsend_012_pos \
rsend_013_pos \
rsend_014_pos \
+ rsend_019_pos \
+ rsend_020_pos \
+ rsend_021_pos \
+ rsend_022_pos \
+ rsend_024_pos \
setup
FILES = rsend.cfg \
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib b/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
index 0a856cfe97..24bec0de6b 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
@@ -25,7 +25,7 @@
#
#
-# Copyright (c) 2013 by Delphix. All rights reserved.
+# Copyright (c) 2013, 2015 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
@@ -200,15 +200,15 @@ function cmp_ds_prop
typeset dtst2=$2
for item in "type" "origin" "volblocksize" "aclinherit" "aclmode" \
- "atime" "canmount" "checksum" "compression" "copies" "devices" \
- "exec" "quota" "readonly" "recordsize" "reservation" "setuid" \
- "sharenfs" "snapdir" "version" "volsize" "xattr" "zoned" \
- "mountpoint";
+ "atime" "canmount" "checksum" "compression" "copies" "devices" \
+ "exec" "quota" "readonly" "recordsize" "reservation" "setuid" \
+ "sharenfs" "snapdir" "version" "volsize" "xattr" "zoned" \
+ "mountpoint";
do
$ZFS get -H -o property,value,source $item $dtst1 >> \
- $BACKDIR/dtst1
+ $BACKDIR/dtst1
$ZFS get -H -o property,value,source $item $dtst2 >> \
- $BACKDIR/dtst2
+ $BACKDIR/dtst2
done
eval $SED -e 's:$dtst1:PREFIX:g' < $BACKDIR/dtst1 > $BACKDIR/dtst1
@@ -323,7 +323,7 @@ function getds_with_suffix
typeset suffix=$2
typeset list=$($ZFS list -r -H -t filesystem,snapshot,volume -o name $ds \
- | $GREP "$suffix$")
+ | $GREP "$suffix$")
$ECHO $list
}
@@ -336,14 +336,14 @@ function fs_inherit_prop
typeset fs_prop
if is_global_zone ; then
fs_prop=$($ZFS inherit 2>&1 | \
- $AWK '$2=="YES" && $3=="YES" {print $1}')
+ $AWK '$2=="YES" && $3=="YES" {print $1}')
if ! is_te_enabled ; then
fs_prop=$(echo $fs_prop | $GREP -v "mlslabel")
fi
else
fs_prop=$($ZFS inherit 2>&1 | \
- $AWK '$2=="YES" && $3=="YES" {print $1}'|
- $EGREP -v "devices|mlslabel|sharenfs|sharesmb|zoned")
+ $AWK '$2=="YES" && $3=="YES" {print $1}'|
+ $EGREP -v "devices|mlslabel|sharenfs|sharesmb|zoned")
fi
$ECHO $fs_prop
@@ -374,3 +374,178 @@ function get_dst_ds
$ECHO $dstfs
}
+
+#
+# Make test files
+#
+# $1 Number of files to create
+# $2 Maximum file size
+# $3 File ID offset
+# $4 File system to create the files on
+#
+function mk_files
+{
+ nfiles=$1
+ maxsize=$2
+ file_id_offset=$3
+ fs=$4
+
+ for ((i=0; i<$nfiles; i=i+1)); do
+ $DD if=/dev/urandom \
+ of=/$fs/file-$maxsize-$((i+$file_id_offset)) \
+ bs=$(($RANDOM * $RANDOM % $maxsize)) \
+ count=1 >/dev/null 2>&1 || log_fail \
+ "Failed to create /$fs/file-$maxsize-$((i+$file_id_offset))"
+ done
+ $ECHO Created $nfiles files of random sizes up to $maxsize bytes
+}
+
+#
+# Remove test files
+#
+# $1 Number of files to remove
+# $2 Maximum file size
+# $3 File ID offset
+# $4 File system to remove the files from
+#
+function rm_files
+{
+ nfiles=$1
+ maxsize=$2
+ file_id_offset=$3
+ fs=$4
+
+ for ((i=0; i<$nfiles; i=i+1)); do
+ $RM -f /$fs/file-$maxsize-$((i+$file_id_offset))
+ done
+ $ECHO Removed $nfiles files of random sizes up to $maxsize bytes
+}
+
+#
+# Mess up file contents
+#
+# $1 The file path
+#
+function mess_file
+{
+ file=$1
+
+ filesize=$($STAT -c '%s' $file)
+ offset=$(($RANDOM * $RANDOM % $filesize))
+ if (($RANDOM % 7 <= 1)); then
+ #
+ # We corrupt 2 bytes to minimize the chance that we
+ # write the same value that's already there.
+ #
+ log_must eval "$DD if=/dev/random of=$file conv=notrunc " \
+ "bs=1 count=2 oseek=$offset >/dev/null 2>&1"
+ else
+ log_must $TRUNCATE -s $offset $file
+ fi
+}
+
+#
+# Diff the send/receive filesystems
+#
+# $1 The sent filesystem
+# $2 The received filesystem
+#
+function file_check
+{
+ sendfs=$1
+ recvfs=$2
+
+ if [[ -d /$recvfs/.zfs/snapshot/a && -d \
+ /$sendfs/.zfs/snapshot/a ]]; then
+ $DIFF -r /$recvfs/.zfs/snapshot/a /$sendfs/.zfs/snapshot/a
+ [[ $? -eq 0 ]] || log_fail "Differences found in snap a"
+ fi
+ if [[ -d /$recvfs/.zfs/snapshot/b && -d \
+ /$sendfs/.zfs/snapshot/b ]]; then
+ $DIFF -r /$recvfs/.zfs/snapshot/b /$sendfs/.zfs/snapshot/b
+ [[ $? -eq 0 ]] || log_fail "Differences found in snap b"
+ fi
+}
+
+#
+# Resume test helper
+#
+# $1 The ZFS send command
+# $2 The filesystem where the streams are sent
+# $3 The receive filesystem
+#
+function resume_test
+{
+ sendcmd=$1
+ streamfs=$2
+ recvfs=$3
+
+ stream_num=1
+ log_must eval "$sendcmd >/$streamfs/$stream_num"
+
+ for ((i=0; i<2; i=i+1)); do
+ mess_file /$streamfs/$stream_num
+ log_mustnot $ZFS recv -sv $recvfs </$streamfs/$stream_num
+ stream_num=$((stream_num+1))
+
+ token=$($ZFS get -Hp -o value receive_resume_token $recvfs)
+ log_must eval "$ZFS send -v -t $token >/$streamfs/$stream_num"
+ [[ -f /$streamfs/$stream_num ]] || \
+ log_fail "NO FILE /$streamfs/$stream_num"
+ done
+ log_must $ZFS recv -sv $recvfs </$streamfs/$stream_num
+}
+
+#
+# Setup filesystems for the resumable send/receive tests
+#
+# $1 The pool to set up with the "send" filesystems
+# $2 The pool for receive
+#
+function test_fs_setup
+{
+ sendpool=$1
+ recvpool=$2
+
+ sendfs=$sendpool/sendfs
+ recvfs=$recvpool/recvfs
+ streamfs=$sendpool/stream
+
+ if datasetexists $recvfs; then
+ log_must $ZFS destroy -r $recvfs
+ fi
+ if datasetexists $sendfs; then
+ log_must $ZFS destroy -r $sendfs
+ fi
+ if $($ZFS create -o compress=lz4 $sendfs); then
+ mk_files 1000 256 0 $sendfs &
+ mk_files 1000 131072 0 $sendfs &
+ mk_files 100 1048576 0 $sendfs &
+ mk_files 10 10485760 0 $sendfs &
+ mk_files 1 104857600 0 $sendfs &
+ log_must $WAIT
+ log_must $ZFS snapshot $sendfs@a
+
+ rm_files 200 256 0 $sendfs &
+ rm_files 200 131072 0 $sendfs &
+ rm_files 20 1048576 0 $sendfs &
+ rm_files 2 10485760 0 $sendfs &
+ log_must $WAIT
+
+ mk_files 400 256 0 $sendfs &
+ mk_files 400 131072 0 $sendfs &
+ mk_files 40 1048576 0 $sendfs &
+ mk_files 4 10485760 0 $sendfs &
+ log_must $WAIT
+
+ log_must $ZFS snapshot $sendfs@b
+ log_must eval "$ZFS send -v $sendfs@a >/$sendpool/initial.zsend"
+ log_must eval "$ZFS send -v -i @a $sendfs@b " \
+ ">/$sendpool/incremental.zsend"
+ fi
+
+ if datasetexists $streamfs; then
+ log_must $ZFS destroy -r $streamfs
+ fi
+ log_must $ZFS create -o compress=lz4 $sendpool/stream
+}
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh
new file mode 100644
index 0000000000..c8550de98a
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh
@@ -0,0 +1,51 @@
+#!/usr/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) 2014 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# Description:
+# Verify resumability of a full and incremental ZFS send/receive in the
+# presence of a corrupted stream.
+#
+# Strategy:
+# 1. Start a full ZFS send, redirect output to a file
+# 2. Mess up the contents of the stream state file on disk
+# 3. Try ZFS receive, which should fail with a checksum mismatch error
+# 4. ZFS send to the stream state file again using the receive_resume_token
+# 5. ZFS receieve and verify the receive completes successfully
+# 6. Repeat steps on an incremental ZFS send
+#
+
+verify_runnable "both"
+
+log_assert "Verify resumability of a full and incremental ZFS send/receive " \
+ "in the presence of a corrupted stream"
+log_onexit cleanup_pool $POOL2
+
+sendfs=$POOL/sendfs
+recvfs=$POOL2/recvfs
+streamfs=$POOL/stream
+
+test_fs_setup $POOL $POOL2
+resume_test "$ZFS send -v $sendfs@a" $streamfs $recvfs
+resume_test "$ZFS send -v -i @a $sendfs@b" $streamfs $recvfs
+file_check $sendfs $recvfs
+
+log_pass "Verify resumability of a full and incremental ZFS send/receive " \
+ "in the presence of a corrupted stream"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh
new file mode 100644
index 0000000000..e4c13d78f4
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh
@@ -0,0 +1,49 @@
+#!/usr/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) 2014 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# Description:
+# Verify resumability of a full ZFS send/receive with the -D (dedup) flag in
+# the presence of a corrupted stream.
+#
+# Strategy:
+# 1. Start a full ZFS send with the -D flag (dedup), redirect output to a file
+# 2. Mess up the contents of the stream state file on disk
+# 3. Try ZFS receive, which should fail with a checksum mismatch error
+# 4. ZFS send to the stream state file again using the receive_resume_token
+# 5. ZFS receieve and verify the receive completes successfully
+#
+
+verify_runnable "both"
+
+log_assert "Verify resumability of full ZFS send/receive with the -D " \
+ "(dedup) flag"
+log_onexit cleanup_pool $POOL2
+
+sendfs=$POOL/sendfs
+recvfs=$POOL2/recvfs
+streamfs=$POOL/stream
+
+test_fs_setup $POOL $POOL2
+resume_test "$ZFS send -D -v $sendfs@a" $streamfs $recvfs
+file_check $sendfs $recvfs
+
+log_pass "Verify resumability of full ZFS send/receive with the -D " \
+ "(dedup) flag"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh
new file mode 100644
index 0000000000..d7d952fded
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh
@@ -0,0 +1,52 @@
+#!/usr/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) 2014 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# Description:
+# Verify resumability of a full and incremental ZFS send/receive with the
+# -e (embedded) flag in the presence of a corrupted stream.
+#
+# Strategy:
+# 1. Start a full ZFS send with the -e flag (embedded), redirect output to
+# a file
+# 2. Mess up the contents of the stream state file on disk
+# 3. Try ZFS receive, which should fail with a checksum mismatch error
+# 4. ZFS send to the stream state file again using the receive_resume_token
+# 5. ZFS receieve and verify the receive completes successfully
+# 6. Repeat steps on an incremental ZFS send
+#
+
+verify_runnable "both"
+
+log_assert "Verify resumability of a full and incremental ZFS send/receive " \
+ "with the -e (embedded) flag"
+log_onexit cleanup_pool $POOL2
+
+sendfs=$POOL/sendfs
+recvfs=$POOL2/recvfs
+streamfs=$POOL/stream
+
+test_fs_setup $POOL $POOL2
+resume_test "$ZFS send -v -e $sendfs@a" $streamfs $recvfs
+resume_test "$ZFS send -v -e -i @a $sendfs@b" $streamfs $recvfs
+file_check $sendfs $recvfs
+
+log_pass "Verify resumability of a full and incremental ZFS send/receive " \
+ "with the -e (embedded) flag"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh
new file mode 100644
index 0000000000..9e377cb846
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh
@@ -0,0 +1,60 @@
+#!/usr/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) 2014 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# Description:
+# Verify resumability of an incremental ZFS send/receive with ZFS bookmarks in
+# the presence of a corrupted stream.
+#
+# Strategy:
+# 1. Bookmark a ZFS snapshot
+# 2. Destroy the ZFS sanpshot
+# 3. Destroy the filesystem for the receive
+# 4. Verify receive of the full send stream
+# 5. Start an incremental ZFS send of the ZFS bookmark, redirect output to a
+# file
+# 6. Mess up the contents of the stream state file on disk
+# 7. Try ZFS receive, which should fail with a checksum mismatch error
+# 8. ZFS send to the stream state file again using the receive_resume_token
+# 9. ZFS receieve and verify the receive completes successfully
+#
+
+verify_runnable "both"
+
+log_assert "Verify resumability of an incremental ZFS send/receive with ZFS " \
+ "bookmarks"
+log_onexit cleanup_pool $POOL2
+
+sendfs=$POOL/sendfs
+recvfs=$POOL2/recvfs
+streamfs=$POOL/stream
+
+test_fs_setup $POOL $POOL2
+log_must $ZFS bookmark $sendfs@a $sendfs#bm_a
+log_must $ZFS destroy $sendfs@a
+log_must $ZFS receive -v $recvfs </$POOL/initial.zsend
+resume_test "$ZFS send -i \#bm_a $sendfs@b" $streamfs $recvfs
+log_must $ZFS destroy -r -f $sendfs
+log_must $ZFS receive -v $sendfs </$POOL/initial.zsend
+log_must $ZFS receive -v $sendfs </$POOL/incremental.zsend
+file_check $sendfs $recvfs
+
+log_pass "Verify resumability of an incremental ZFS send/receive with ZFS " \
+ "bookmarks"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh
new file mode 100644
index 0000000000..e5e299a0e7
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh
@@ -0,0 +1,52 @@
+#!/usr/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) 2014 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# Description:
+# Verify resumability of a full ZFS send/receive with the source filesystem
+# unmounted.
+#
+# Strategy:
+# 1. Destroy the filesystem for the receive
+# 2. Unmount the source filsesystem
+# 3. Start a full ZFS send, redirect output to a file
+# 4. Mess up the contents of the stream state file on disk
+# 5. Try ZFS receive, which should fail with a checksum mismatch error
+# 6. ZFS send to the stream state file again using the receive_resume_token
+# 7. ZFS receieve and verify the receive completes successfully
+#
+
+verify_runnable "both"
+
+log_assert "Verify resumability of a full ZFS send/receive with the source " \
+ "filesystem unmounted"
+log_onexit cleanup_pool $POOL2
+
+sendfs=$POOL/sendfs
+recvfs=$POOL2/recvfs
+streamfs=$POOL/stream
+
+test_fs_setup $POOL $POOL2
+log_must $ZFS unmount $sendfs
+resume_test "$ZFS send $sendfs" $streamfs $recvfs
+file_check $sendfs $recvfs
+
+log_pass "Verify resumability of a full ZFS send/receive with the source " \
+ "filesystem unmounted"