]> git.proxmox.com Git - mirror_zfs.git/blob - tests/zfs-tests/tests/functional/redacted_send/redacted.kshlib
Implement Redacted Send/Receive
[mirror_zfs.git] / tests / zfs-tests / tests / functional / redacted_send / redacted.kshlib
1 #!/bin/ksh
2
3 #
4 # CDDL HEADER START
5 #
6 # The contents of this file are subject to the terms of the
7 # Common Development and Distribution License (the "License").
8 # You may not use this file except in compliance with the License.
9 #
10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 # or http://www.opensolaris.org/os/licensing.
12 # See the License for the specific language governing permissions
13 # and limitations under the License.
14 #
15 # When distributing Covered Code, include this CDDL HEADER in each
16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 # If applicable, add the following below this CDDL HEADER, with the
18 # fields enclosed by brackets "[]" replaced with your own identifying
19 # information: Portions Copyright [yyyy] [name of copyright owner]
20 #
21 # CDDL HEADER END
22 #
23
24 #
25 # Copyright (c) 2016, 2018 by Delphix. All rights reserved.
26 #
27
28 . $STF_SUITE/include/libtest.shlib
29 . $STF_SUITE/tests/functional/rsend/rsend.kshlib
30 . $STF_SUITE/tests/functional/redacted_send/redacted.cfg
31
32 function setup_dataset
33 {
34 typeset ds_name=$1
35 typeset opts=$2
36 typeset file_create_func=$3
37 typeset sendfs="$POOL/$ds_name"
38 [[ -n $file_create_func ]] || file_create_func=setup_common
39
40 log_must zfs create $opts $sendfs
41
42 $file_create_func $sendfs
43
44 log_must zfs snapshot $sendfs@snap
45 log_must zfs clone $opts $sendfs@snap $POOL/${ds_name}_clone
46 log_must zfs snapshot $POOL/${ds_name}_clone@snap
47 }
48
49 function setup_common
50 {
51 typeset sendfs=$1
52
53 typeset mntpnt=$(get_prop mountpoint $sendfs)
54 typeset bs=$(get_prop recsize $sendfs)
55 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=$bs count=16
56 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=$bs count=32
57 }
58
59 function setup_embedded
60 {
61 typeset sendfs=$1
62
63 typeset recsize
64 typeset mntpnt=$(get_prop mountpoint $sendfs)
65 for recsize in 512 1024 2048 4096 8192 16384; do
66 if is_linux; then
67 log_must dd if=/dev/urandom of=$mntpnt/$recsize bs=8 \
68 count=1 seek=$(((recsize / 8) - 1))
69 else
70 log_must mkholes -d $((recsize - 8)):8 $mntpnt/$recsize
71 fi
72 done
73 }
74
75 function setup_holes
76 {
77 typeset sendfs=$1
78
79 typeset mntpnt=$(get_prop mountpoint $sendfs)
80 typeset M=$((1024 * 1024))
81
82 if is_linux; then
83 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=8M count=1
84
85 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=1M count=1
86 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=1M count=1 seek=7 \
87 conv=notrunc
88
89 log_must dd if=/dev/urandom of=$mntpnt/f3 bs=1M count=6 seek=1
90 log_must truncate $mntpnt/f3 --size=$((8 * M))
91
92 log_must truncate $mntpnt/f4 --size=$((8 * M))
93 else
94 log_must mkholes -d 0:$((8 * M)) $mntpnt/f1
95 log_must mkholes -d 0:$M -d $((7 * M)):$M $mntpnt/f2
96 log_must mkholes -d $M:$((6 * M)) -h $((7 * M)):$M $mntpnt/f3
97 log_must mkholes -h 0:$((8 * M)) $mntpnt/f4
98 fi
99
100 log_must zfs create $sendfs/manyrm
101 for i in {1..256}; do
102 log_must stride_dd -i /dev/urandom -o $mntpnt/manyrm/f$i -b 512 \
103 -c $(random 100) -s $(random 4)
104 done
105
106 log_must zfs snapshot $sendfs/manyrm@snap
107 log_must zfs clone $sendfs/manyrm@snap $sendfs/manyrm_clone
108 log_must zfs snapshot $sendfs/manyrm_clone@snap
109 }
110
111 function setup_incrementals
112 {
113 typeset sendfs=$1
114
115 typeset mntpnt=$(get_prop mountpoint $sendfs)
116 typeset bs=$(get_prop recsize $sendfs)
117 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=$bs count=16
118 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=$bs count=32
119 log_must mkdir $mntpnt/d1
120 log_must eval "cat $mntpnt/f1 $mntpnt/f2 >$mntpnt/d1/f1"
121 log_must zfs snapshot $sendfs@snap0
122
123 log_must zfs clone $sendfs@snap0 $POOL/hole
124 mntpnt=$(get_prop mountpoint $POOL/hole)
125 log_must dd if=/dev/zero of=$mntpnt/f2 bs=$bs count=16 conv=notrunc
126 log_must zfs snapshot $POOL/hole@snap
127
128 log_must zfs clone $sendfs@snap0 $POOL/stride3
129 mntpnt=$(get_prop mountpoint $POOL/stride3)
130 log_must stride_dd -i /dev/urandom -o $mntpnt/f2 -b $bs -c 11 -s 3
131 log_must zfs snapshot $POOL/stride3@snap
132
133 log_must zfs clone $sendfs@snap0 $POOL/stride5
134 mntpnt=$(get_prop mountpoint $POOL/stride5)
135 log_must stride_dd -i /dev/urandom -o $mntpnt/f2 -b $bs -c 7 -s 5
136 log_must zfs snapshot $POOL/stride5@snap
137
138 log_must zfs clone $sendfs@snap0 $POOL/int
139 log_must zfs snapshot $POOL/int@snap
140
141 log_must zfs clone $POOL/int@snap $POOL/rm
142 mntpnt=$(get_prop mountpoint $POOL/rm)
143 log_must rm -rf $mntpnt/[df][12]
144 log_must zfs snapshot $POOL/rm@snap
145
146 log_must zfs clone $POOL/int@snap $POOL/write
147 mntpnt=$(get_prop mountpoint $POOL/write)
148 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=512 count=16 conv=notrunc
149 log_must dd if=/dev/urandom of=$mntpnt/d1/f1 bs=512 count=16 seek=16 \
150 conv=notrunc
151 log_must zfs snapshot $POOL/write@snap
152 }
153
154 function setup_mounts
155 {
156 typeset sendfs=$1
157
158 typeset mntpnt=$(get_prop mountpoint $sendfs)
159 log_must touch $mntpnt/empty
160 log_must dd if=/dev/urandom of=$mntpnt/contents1 bs=512 count=2
161 log_must dd if=/dev/urandom of=$mntpnt/contents2 bs=512 count=2
162 log_must mkdir $mntpnt/dir1
163 log_must touch $mntpnt/dir1/empty
164 log_must dd if=/dev/urandom of=$mntpnt/dir1/contents1 bs=512 count=2
165 log_must dd if=/dev/urandom of=$mntpnt/dir1/contents2 bs=512 count=2
166 log_must mkdir $mntpnt/dir1/dir2
167 log_must touch $mntpnt/dir1/dir2/empty
168 log_must dd if=/dev/urandom of=$mntpnt/dir1/dir2/file bs=512 count=2
169
170 log_must zfs create -s -V 16p $sendfs/vol
171 log_must zfs snapshot $sendfs/vol@snap
172 log_must zfs clone $sendfs/vol@snap $sendfs/vol_clone
173 log_must zfs snapshot $sendfs/vol_clone@snap
174 }
175
176 function mount_redacted
177 {
178 typeset flag=''
179 while getopts "f" opt; do
180 case $opt in
181 f)
182 flag='-f'
183 ;;
184 esac
185 done
186 shift $(($OPTIND - 1))
187
188 typeset ds=$1
189 log_must set_tunable32 zfs_allow_redacted_dataset_mount 1
190 zfs mount $flag -oro $ds || return 1
191 log_must set_tunable32 zfs_allow_redacted_dataset_mount 0
192 return 0
193 }
194
195 function unmount_redacted
196 {
197 typeset ds=$1
198
199 zfs unmount $ds
200 }
201
202 #
203 # This function calls a utility that prints out the ranges where a file
204 # and its redacted counterpart differ, each range on a new line like this:
205 #
206 # 0,131072
207 # 1966080,131072
208 # 3932160,131072
209 #
210 # The output is then checked against a variable containing the expected
211 # output to verify the redacted ranges are the ones expected.
212 #
213 function compare_files
214 {
215 typeset sendfs=$1
216 typeset recvfs=$2
217 typeset file=$3
218 typeset expected="$4"
219 typeset tmpfile="$tmpdir/get_file.out"
220
221 log_must mount_redacted -f $recvfs
222
223 typeset file1="$(get_prop mountpoint $sendfs)/$file"
224 typeset file2="$(get_prop mountpoint $recvfs)/$file"
225 log_note "Comparing $file1 and $file2"
226 [[ -f $file1 ]] || log_fail "File $file1 does not exist."
227 [[ -f $file2 ]] || log_fail "File $file2 does not exist."
228
229 log_must eval "get_diff $file1 $file2 >$tmpfile"
230 typeset range="$(cat $tmpfile)"
231 log_must unmount_redacted $recvfs
232 [[ "$expected" = "$range" ]] || log_fail "Unexpected range: $range"
233 }
234
235 function redacted_cleanup
236 {
237 typeset ds_list=$@
238 typeset ds
239
240 # Verify the receiving pool can still be exported and imported.
241 log_must zpool export $POOL2
242 log_must zpool import $POOL2
243
244 for ds in $ds_list; do
245 datasetexists $ds && log_must zfs destroy -R $ds
246 done
247
248 log_must set_tunable32 zfs_allow_redacted_dataset_mount 0
249 rm -f $(get_prop mountpoint $POOL)/tmp/*
250 }
251
252 # Retrieve the redaction list of a bookmark or snapshot, using
253 # the property or zdb output, as requested.
254 function get_guid_list
255 {
256 typeset filename=$1
257 typeset dataset=$2
258 typeset use_zdb=${3:-false}
259
260 if $use_zdb; then
261 guid_list=$(zdb -vvvv $dataset | sed -e 's/,//g' \
262 -ne 's/^.*Snapshots: \[\(.*\)\]/\1/p')
263 else
264 guid_list=$(get_prop redact_snaps $dataset)
265 fi
266
267 for guid in $(echo $guid_list | tr ',' ' '); do
268 echo $guid
269 done | sort >$filename
270 }