mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
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 <apinchuk@datto.com> Reviewed-by: loli10K <ezomori.nozomu@gmail.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: Paul Dagnelie <pcd@delphix.com> Signed-off-by: Paul Zuchowski <pzuchowski@datto.com> Closes #7513
This commit is contained in:
committed by
Brian Behlendorf
parent
e73ab1b38c
commit
9c5e88b1de
@@ -793,7 +793,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
|
||||
'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize',
|
||||
'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_heirarchy',
|
||||
'send_encrypted_props', 'send_freeobjects', 'send_realloc_dnode_size',
|
||||
'send_hole_birth', 'send-wDR_encrypted_zvol']
|
||||
'send_holds', 'send_hole_birth', 'send-wDR_encrypted_zvol']
|
||||
tags = ['functional', 'rsend']
|
||||
|
||||
[tests/functional/scrub_mirror]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+177
@@ -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."
|
||||
Reference in New Issue
Block a user