1#!/bin/ksh -p 2# 3# CDDL HEADER START 4# 5# This file and its contents are supplied under the terms of the 6# Common Development and Distribution License ("CDDL"), version 1.0. 7# You may only use this file in accordance with the terms of version 8# 1.0 of the CDDL. 9# 10# A full copy of the text of the CDDL should have accompanied this 11# source. A copy of the CDDL is also available via the Internet at 12# http://www.illumos.org/license/CDDL. 13# 14# CDDL HEADER END 15# 16 17# 18# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 19# Copyright (c) 2018 Datto, Inc. All rights reserved. 20# 21 22. $STF_SUITE/tests/functional/rsend/rsend.kshlib 23. $STF_SUITE/tests/functional/cli_root/cli_common.kshlib 24 25# 26# DESCRIPTION: 27# Verify 'zfs send' can send dataset holds. 28# Verify 'zfs receive' can receive dataset holds. 29# 30# STRATEGY: 31# 1. Create a snapshot. 32# 2. Create a full send stream with the fs, including holds. 33# 3. Receive the send stream and verify the data integrity. 34# 4. Fill in fs with some new data. 35# 5. Create an incremental send stream with the fs, including holds. 36# 6. Receive the incremental send stream and verify the data integrity. 37# 7. Verify the holds have been received as expected. 38# 8. Create an incremental snap with no holds, and send that with -h. 39# 9. Confirm the snapshot was received as expected. 40# 10. Create an incremental snapshot and place a hold on it. 41# 11. Receive the incremental stream with -h and verify holds skipped. 42# 43 44verify_runnable "both" 45 46function cleanup 47{ 48 eval "zfs holds $init_snap |grep -q hold1-1" && 49 log_must zfs release hold1-1 $init_snap 50 eval "zfs holds $init_snap |grep -q hold1-2" && 51 log_must zfs release hold1-2 $init_snap 52 eval "zfs holds $recv_snap |grep -q hold1-1" && 53 log_must zfs release hold1-1 $recv_snap 54 eval "zfs holds $recv_snap |grep -q hold1-2" && 55 log_must zfs release hold1-2 $recv_snap 56 eval "zfs holds $inc_snap |grep -q hold2-1" && 57 log_must zfs release hold2-1 $inc_snap 58 eval "zfs holds $recv_inc_snap |grep -q hold2-1" && 59 log_must zfs release hold2-1 $recv_inc_snap 60 eval "zfs holds $inc_snap3 |grep -q hold3-1" && 61 log_must zfs release hold3-1 $inc_snap3 62 63 # destroy datasets 64 datasetexists $recv_root/$TESTFS1 && 65 log_must destroy_dataset "$recv_root/$TESTFS1" "-Rf" 66 datasetexists $recv_root && log_must destroy_dataset "$recv_root" "-Rf" 67 datasetexists $TESTPOOL/$TESTFS1 && log_must destroy_dataset "$TESTPOOL/$TESTFS1" "-Rf" 68 69 [[ -e $full_bkup ]] && log_must rm -f $full_bkup 70 [[ -e $inc_bkup ]] && log_must rm -f $inc_bkup 71 [[ -e $inc_data2 ]] && log_must rm -f $inc_data2 72 [[ -d $TESTDIR1 ]] && log_must rm -rf $TESTDIR1 73 74} 75 76# 77# Check if hold exists on the specified dataset. 78# 79function check_hold #<snapshot> <hold> 80{ 81 typeset dataset=$1 82 typeset hold=$2 83 84 log_note "checking $dataset for $hold" 85 eval "zfs holds $dataset |grep -q $hold" 86} 87 88log_assert "Verify 'zfs send/recv' can send and receive dataset holds." 89log_onexit cleanup 90 91init_snap=$TESTPOOL/$TESTFS1@init_snap 92inc_snap=$TESTPOOL/$TESTFS1@inc_snap 93inc_snap2=$TESTPOOL/$TESTFS1@inc_snap2 94inc_snap3=$TESTPOOL/$TESTFS1@inc_snap3 95full_bkup=$TEST_BASE_DIR/fullbkup.$$ 96inc_bkup=$TEST_BASE_DIR/incbkup.$$ 97init_data=$TESTDIR/$TESTFILE1 98inc_data=$TESTDIR/$TESTFILE2 99inc_data2=$TESTDIR/testfile3 100recv_root=$TESTPOOL/rst_ctr 101recv_snap=$recv_root/$TESTFS1@init_snap 102recv_inc_snap=$recv_root/$TESTFS1@inc_snap 103recv_inc_snap2=$recv_root/$TESTFS1@inc_snap2 104recv_inc_snap3=$recv_root/$TESTFS1@inc_snap3 105recv_data=$TESTDIR1/$TESTFS1/$TESTFILE1 106recv_inc_data=$TESTDIR1/$TESTFS1/$TESTFILE2 107recv_inc_data2=$TESTDIR1/$TESTFS1/testfile3 108 109log_note "Verify 'zfs send' can create full send stream." 110 111# Preparation 112if ! datasetexists $TESTPOOL/$TESTFS1; then 113 log_must zfs create $TESTPOOL/$TESTFS1 114fi 115[[ -e $init_data ]] && log_must rm -f $init_data 116log_must zfs create $recv_root 117[[ ! -d $TESTDIR1 ]] && log_must mkdir -p $TESTDIR1 118[[ ! -d $TESTDIR ]] && log_must mkdir -p $TESTDIR 119log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS1 120log_must zfs set mountpoint=$TESTDIR1 $recv_root 121 122file_write -o create -f $init_data -b $BLOCK_SIZE -c $WRITE_COUNT 123 124log_must zfs snapshot $init_snap 125log_must zfs hold hold1-1 $init_snap 126log_must zfs hold hold1-2 $init_snap 127log_must eval "zfs send -h $init_snap > $full_bkup" 128 129log_note "Verify the send stream is valid to receive." 130 131log_must zfs recv -F $recv_snap <$full_bkup 132log_must datasetexists $recv_snap 133receive_check $recv_snap ${recv_snap%%@*} 134 135log_note "Verify the holds were received." 136log_must check_hold $recv_snap hold1-1 137log_must check_hold $recv_snap hold1-2 138compare_cksum $init_data $recv_data 139 140log_note "Verify 'zfs send -i' can create incremental send stream." 141 142file_write -o create -f $inc_data -b $BLOCK_SIZE -c $WRITE_COUNT -d 0 143 144log_must zfs snapshot $inc_snap 145log_must zfs hold hold2-1 $inc_snap 146log_must eval "zfs send -h -i $init_snap $inc_snap > $inc_bkup" 147 148log_note "Verify the incremental send stream is valid to receive." 149 150log_must zfs recv -F $recv_inc_snap <$inc_bkup 151log_must datasetexists $recv_inc_snap 152log_note "Verify the hold was received from the incremental send." 153 154log_must check_hold $recv_inc_snap hold2-1 155 156compare_cksum $inc_data $recv_inc_data 157 158log_note "Verify send -h works when there are no holds." 159file_write -o create -f $inc_data2 -b $BLOCK_SIZE -c $WRITE_COUNT -d 0 160log_must zfs snapshot $inc_snap2 161log_must eval "zfs send -h -i $inc_snap $inc_snap2 > $inc_bkup" 162log_must zfs recv -F $recv_inc_snap2 <$inc_bkup 163log_must datasetexists $recv_inc_snap2 164compare_cksum $inc_data2 $recv_inc_data2 165 166log_note "Verify send -h fails properly when receive dataset already exists" 167log_must zfs recv -F $recv_inc_snap2 <$inc_bkup 168 169log_note "Verify recv -h skips the receive of holds" 170log_must zfs snapshot $inc_snap3 171log_must zfs hold hold3-1 $inc_snap3 172log_must eval "zfs send -h -i $inc_snap2 $inc_snap3 > $inc_bkup" 173log_must zfs recv -F -h $recv_inc_snap3 <$inc_bkup 174log_must datasetexists $recv_inc_snap3 175log_mustnot check_hold $recv_inc_snap3 hold3-1 176 177log_pass "'zfs send/recv' can send and receive dataset holds." 178