]>
Commit | Line | Data |
---|---|---|
30af21b0 PD |
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 | } |