aboutsummaryrefslogtreecommitdiffstats
path: root/tests/zfs-tests
diff options
context:
space:
mode:
authorPaul Zuchowski <[email protected]>2019-02-15 15:41:38 -0500
committerBrian Behlendorf <[email protected]>2019-02-15 12:41:38 -0800
commit9c5e88b1ded19cb4b19b9d767d5c71b34c189540 (patch)
tree08a51e07bb19bae06bdfbc61ae36b140514870ae /tests/zfs-tests
parente73ab1b38cd099f3416eed0ab5576639383bbdcc (diff)
zfs should optionally send holds
Add -h switch to zfs send command to send dataset holds. If holds are present in the stream, zfs receive will create them on the target dataset, unless the zfs receive -h option is used to skip receive of holds. Reviewed-by: Alek Pinchuk <[email protected]> Reviewed-by: loli10K <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed by: Paul Dagnelie <[email protected]> Signed-off-by: Paul Zuchowski <[email protected]> Closes #7513
Diffstat (limited to 'tests/zfs-tests')
-rw-r--r--tests/zfs-tests/tests/functional/rsend/Makefile.am1
-rwxr-xr-xtests/zfs-tests/tests/functional/rsend/send_holds.ksh177
2 files changed, 178 insertions, 0 deletions
diff --git a/tests/zfs-tests/tests/functional/rsend/Makefile.am b/tests/zfs-tests/tests/functional/rsend/Makefile.am
index 316bcb4e6..0b15f8d2b 100644
--- a/tests/zfs-tests/tests/functional/rsend/Makefile.am
+++ b/tests/zfs-tests/tests/functional/rsend/Makefile.am
@@ -41,6 +41,7 @@ dist_pkgdata_SCRIPTS = \
send-cpL_varied_recsize.ksh \
send_freeobjects.ksh \
send_realloc_dnode_size.ksh \
+ send_holds.ksh \
send_hole_birth.ksh \
send-wDR_encrypted_zvol.ksh
diff --git a/tests/zfs-tests/tests/functional/rsend/send_holds.ksh b/tests/zfs-tests/tests/functional/rsend/send_holds.ksh
new file mode 100755
index 000000000..5dcf0e2a0
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/rsend/send_holds.ksh
@@ -0,0 +1,177 @@
+#!/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) 2012, 2016 by Delphix. All rights reserved.
+# Copyright (c) 2018 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+. $STF_SUITE/tests/functional/cli_root/cli_common.kshlib
+
+#
+# DESCRIPTION:
+# Verify 'zfs send' can send dataset holds.
+# Verify 'zfs receive' can receive dataset holds.
+#
+# STRATEGY:
+# 1. Create a snapshot.
+# 2. Create a full send stream with the fs, including holds.
+# 3. Receive the send stream and verify the data integrity.
+# 4. Fill in fs with some new data.
+# 5. Create an incremental send stream with the fs, including holds.
+# 6. Receive the incremental send stream and verify the data integrity.
+# 7. Verify the holds have been received as expected.
+# 8. Create an incremental snap with no holds, and send that with -h.
+# 9. Confirm the snapshot was received as expected.
+# 10. Create an incremental snapshot and place a hold on it.
+# 11. Receive the incremental stream with -h and verify holds skipped.
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ eval "zfs holds $init_snap |grep -q hold1-1" &&
+ log_must zfs release hold1-1 $init_snap
+ eval "zfs holds $init_snap |grep -q hold1-2" &&
+ log_must zfs release hold1-2 $init_snap
+ eval "zfs holds $recv_snap |grep -q hold1-1" &&
+ log_must zfs release hold1-1 $recv_snap
+ eval "zfs holds $recv_snap |grep -q hold1-2" &&
+ log_must zfs release hold1-2 $recv_snap
+ eval "zfs holds $inc_snap |grep -q hold2-1" &&
+ log_must zfs release hold2-1 $inc_snap
+ eval "zfs holds $recv_inc_snap |grep -q hold2-1" &&
+ log_must zfs release hold2-1 $recv_inc_snap
+ eval "zfs holds $inc_snap3 |grep -q hold3-1" &&
+ log_must zfs release hold3-1 $inc_snap3
+
+ # destroy datasets
+ datasetexists $recv_root/$TESTFS1 &&
+ log_must destroy_dataset "$recv_root/$TESTFS1" "-Rf"
+ datasetexists $recv_root && log_must destroy_dataset "$recv_root" "-Rf"
+ datasetexists $TESTPOOL/$TESTFS1 && log_must destroy_dataset "$TESTPOOL/$TESTFS1" "-Rf"
+
+ [[ -e $full_bkup ]] && log_must rm -f $full_bkup
+ [[ -e $inc_bkup ]] && log_must rm -f $inc_bkup
+ [[ -e $inc_data2 ]] && log_must rm -f $inc_data2
+ [[ -d $TESTDIR1 ]] && log_must rm -rf $TESTDIR1
+
+}
+
+#
+# Check if hold exists on the specified dataset.
+#
+function check_hold #<snapshot> <hold>
+{
+ typeset dataset=$1
+ typeset hold=$2
+
+ log_note "checking $dataset for $hold"
+ eval "zfs holds $dataset |grep -q $hold"
+}
+
+log_assert "Verify 'zfs send/recv' can send and receive dataset holds."
+log_onexit cleanup
+
+init_snap=$TESTPOOL/$TESTFS1@init_snap
+inc_snap=$TESTPOOL/$TESTFS1@inc_snap
+inc_snap2=$TESTPOOL/$TESTFS1@inc_snap2
+inc_snap3=$TESTPOOL/$TESTFS1@inc_snap3
+full_bkup=$TEST_BASE_DIR/fullbkup.$$
+inc_bkup=$TEST_BASE_DIR/incbkup.$$
+init_data=$TESTDIR/$TESTFILE1
+inc_data=$TESTDIR/$TESTFILE2
+inc_data2=$TESTDIR/testfile3
+recv_root=$TESTPOOL/rst_ctr
+recv_snap=$recv_root/$TESTFS1@init_snap
+recv_inc_snap=$recv_root/$TESTFS1@inc_snap
+recv_inc_snap2=$recv_root/$TESTFS1@inc_snap2
+recv_inc_snap3=$recv_root/$TESTFS1@inc_snap3
+recv_data=$TESTDIR1/$TESTFS1/$TESTFILE1
+recv_inc_data=$TESTDIR1/$TESTFS1/$TESTFILE2
+recv_inc_data2=$TESTDIR1/$TESTFS1/testfile3
+
+log_note "Verify 'zfs send' can create full send stream."
+
+# Preparation
+if ! datasetexists $TESTPOOL/$TESTFS1; then
+ log_must zfs create $TESTPOOL/$TESTFS1
+fi
+[[ -e $init_data ]] && log_must rm -f $init_data
+log_must zfs create $recv_root
+[[ ! -d $TESTDIR1 ]] && log_must mkdir -p $TESTDIR1
+[[ ! -d $TESTDIR ]] && log_must mkdir -p $TESTDIR
+log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS1
+log_must zfs set mountpoint=$TESTDIR1 $recv_root
+
+file_write -o create -f $init_data -b $BLOCK_SIZE -c $WRITE_COUNT
+
+log_must zfs snapshot $init_snap
+log_must zfs hold hold1-1 $init_snap
+log_must zfs hold hold1-2 $init_snap
+log_must eval "zfs send -h $init_snap > $full_bkup"
+
+log_note "Verify the send stream is valid to receive."
+
+log_must zfs recv -F $recv_snap <$full_bkup
+log_must datasetexists $recv_snap
+receive_check $recv_snap ${recv_snap%%@*}
+
+log_note "Verify the holds were received."
+log_must check_hold $recv_snap hold1-1
+log_must check_hold $recv_snap hold1-2
+compare_cksum $init_data $recv_data
+
+log_note "Verify 'zfs send -i' can create incremental send stream."
+
+file_write -o create -f $inc_data -b $BLOCK_SIZE -c $WRITE_COUNT -d 0
+
+log_must zfs snapshot $inc_snap
+log_must zfs hold hold2-1 $inc_snap
+log_must eval "zfs send -h -i $init_snap $inc_snap > $inc_bkup"
+
+log_note "Verify the incremental send stream is valid to receive."
+
+log_must zfs recv -F $recv_inc_snap <$inc_bkup
+log_must datasetexists $recv_inc_snap
+log_note "Verify the hold was received from the incremental send."
+
+log_must check_hold $recv_inc_snap hold2-1
+
+compare_cksum $inc_data $recv_inc_data
+
+log_note "Verify send -h works when there are no holds."
+file_write -o create -f $inc_data2 -b $BLOCK_SIZE -c $WRITE_COUNT -d 0
+log_must zfs snapshot $inc_snap2
+log_must eval "zfs send -h -i $inc_snap $inc_snap2 > $inc_bkup"
+log_must zfs recv -F $recv_inc_snap2 <$inc_bkup
+log_must datasetexists $recv_inc_snap2
+compare_cksum $inc_data2 $recv_inc_data2
+
+log_note "Verify send -h fails properly when receive dataset already exists"
+log_must zfs recv -F $recv_inc_snap2 <$inc_bkup
+
+log_note "Verify recv -h skips the receive of holds"
+log_must zfs snapshot $inc_snap3
+log_must zfs hold hold3-1 $inc_snap3
+log_must eval "zfs send -h -i $inc_snap2 $inc_snap3 > $inc_bkup"
+log_must zfs recv -F -h $recv_inc_snap3 <$inc_bkup
+log_must datasetexists $recv_inc_snap3
+log_mustnot check_hold $recv_inc_snap3 hold3-1
+
+log_pass "'zfs send/recv' can send and receive dataset holds."