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 https://opensource.org/licenses/CDDL-1.0. 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 32if ! is_linux; then 33 alias udevadm=: 34fi 35 36function setup_dataset 37{ 38 typeset ds_name=$1 39 typeset opts=$2 40 typeset file_create_func=$3 41 typeset sendfs="$POOL/$ds_name" 42 [[ -n $file_create_func ]] || file_create_func=setup_common 43 44 log_must zfs create $opts $sendfs 45 46 $file_create_func $sendfs 47 48 log_must zfs snapshot $sendfs@snap 49 log_must zfs clone $opts $sendfs@snap $POOL/${ds_name}_clone 50 log_must zfs snapshot $POOL/${ds_name}_clone@snap 51} 52 53function setup_common 54{ 55 typeset sendfs=$1 56 57 typeset mntpnt=$(get_prop mountpoint $sendfs) 58 typeset bs=$(get_prop recsize $sendfs) 59 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=$bs count=16 60 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=$bs count=32 61} 62 63function setup_embedded 64{ 65 typeset sendfs=$1 66 67 typeset recsize 68 typeset mntpnt=$(get_prop mountpoint $sendfs) 69 for recsize in 512 1024 2048 4096 8192 16384; do 70 if is_illumos; then 71 log_must mkholes -d $((recsize - 8)):8 $mntpnt/$recsize 72 else 73 log_must dd if=/dev/urandom of=$mntpnt/$recsize bs=8 \ 74 count=1 seek=$(((recsize / 8) - 1)) 75 fi 76 done 77} 78 79function setup_holes 80{ 81 typeset sendfs=$1 82 83 typeset mntpnt=$(get_prop mountpoint $sendfs) 84 typeset M=$((1024 * 1024)) 85 86 if is_illumos; then 87 log_must mkholes -d 0:$((8 * M)) $mntpnt/f1 88 log_must mkholes -d 0:$M -d $((7 * M)):$M $mntpnt/f2 89 log_must mkholes -d $M:$((6 * M)) -h $((7 * M)):$M $mntpnt/f3 90 log_must mkholes -h 0:$((8 * M)) $mntpnt/f4 91 else 92 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=8M count=1 93 94 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=1M count=1 95 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=1M count=1 seek=7 \ 96 conv=notrunc 97 98 log_must dd if=/dev/urandom of=$mntpnt/f3 bs=1M count=6 seek=1 99 log_must truncate -s $((8 * M)) $mntpnt/f3 100 101 log_must truncate -s $((8 * M)) $mntpnt/f4 102 fi 103 104 log_must zfs create $sendfs/manyrm 105 for i in {1..256}; do 106 log_must stride_dd -i /dev/urandom -o $mntpnt/manyrm/f$i -b 512 \ 107 -c $(random_int_between 1 100) -s $(random_int_between 1 4) 108 done 109 110 log_must zfs snapshot $sendfs/manyrm@snap 111 log_must zfs clone $sendfs/manyrm@snap $sendfs/manyrm_clone 112 log_must zfs snapshot $sendfs/manyrm_clone@snap 113} 114 115function setup_incrementals 116{ 117 typeset sendfs=$1 118 119 typeset mntpnt=$(get_prop mountpoint $sendfs) 120 typeset bs=$(get_prop recsize $sendfs) 121 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=$bs count=16 122 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=$bs count=32 123 log_must mkdir $mntpnt/d1 124 log_must eval "cat $mntpnt/f1 $mntpnt/f2 >$mntpnt/d1/f1" 125 log_must zfs snapshot $sendfs@snap0 126 127 log_must zfs clone $sendfs@snap0 $POOL/hole 128 mntpnt=$(get_prop mountpoint $POOL/hole) 129 log_must dd if=/dev/zero of=$mntpnt/f2 bs=$bs count=16 conv=notrunc 130 log_must zfs snapshot $POOL/hole@snap 131 132 log_must zfs clone $sendfs@snap0 $POOL/stride3 133 mntpnt=$(get_prop mountpoint $POOL/stride3) 134 log_must stride_dd -i /dev/urandom -o $mntpnt/f2 -b $bs -c 11 -s 3 135 log_must zfs snapshot $POOL/stride3@snap 136 137 log_must zfs clone $sendfs@snap0 $POOL/stride5 138 mntpnt=$(get_prop mountpoint $POOL/stride5) 139 log_must stride_dd -i /dev/urandom -o $mntpnt/f2 -b $bs -c 7 -s 5 140 log_must zfs snapshot $POOL/stride5@snap 141 142 log_must zfs clone $sendfs@snap0 $POOL/int 143 log_must zfs snapshot $POOL/int@snap 144 145 log_must zfs clone $POOL/int@snap $POOL/rm 146 mntpnt=$(get_prop mountpoint $POOL/rm) 147 log_must rm -rf $mntpnt/[df][12] 148 log_must zfs snapshot $POOL/rm@snap 149 150 log_must zfs clone $POOL/int@snap $POOL/write 151 mntpnt=$(get_prop mountpoint $POOL/write) 152 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=512 count=16 conv=notrunc 153 log_must dd if=/dev/urandom of=$mntpnt/d1/f1 bs=512 count=16 seek=16 \ 154 conv=notrunc 155 log_must zfs snapshot $POOL/write@snap 156} 157 158function setup_mounts 159{ 160 typeset sendfs=$1 161 162 typeset mntpnt=$(get_prop mountpoint $sendfs) 163 log_must touch $mntpnt/empty 164 log_must dd if=/dev/urandom of=$mntpnt/contents1 bs=512 count=2 165 log_must dd if=/dev/urandom of=$mntpnt/contents2 bs=512 count=2 166 log_must mkdir $mntpnt/dir1 167 log_must touch $mntpnt/dir1/empty 168 log_must dd if=/dev/urandom of=$mntpnt/dir1/contents1 bs=512 count=2 169 log_must dd if=/dev/urandom of=$mntpnt/dir1/contents2 bs=512 count=2 170 log_must mkdir $mntpnt/dir1/dir2 171 log_must touch $mntpnt/dir1/dir2/empty 172 log_must dd if=/dev/urandom of=$mntpnt/dir1/dir2/file bs=512 count=2 173 174 log_must zfs create -s -V 16p $sendfs/vol 175 log_must zfs snapshot $sendfs/vol@snap 176 log_must zfs clone $sendfs/vol@snap $sendfs/vol_clone 177 log_must zfs snapshot $sendfs/vol_clone@snap 178} 179 180function mount_redacted 181{ 182 typeset flag='' 183 while getopts "f" opt; do 184 case $opt in 185 f) 186 flag='-f' 187 ;; 188 esac 189 done 190 shift $(($OPTIND - 1)) 191 192 typeset ds=$1 193 log_must set_tunable32 ALLOW_REDACTED_DATASET_MOUNT 1 194 zfs mount $flag -oro $ds || return 1 195 log_must set_tunable32 ALLOW_REDACTED_DATASET_MOUNT 0 196 return 0 197} 198 199function unmount_redacted 200{ 201 typeset ds=$1 202 203 zfs unmount $ds 204} 205 206# 207# This function calls a utility that prints out the ranges where a file 208# and its redacted counterpart differ, each range on a new line like this: 209# 210# 0,131072 211# 1966080,131072 212# 3932160,131072 213# 214# The output is then checked against a variable containing the expected 215# output to verify the redacted ranges are the ones expected. 216# 217function compare_files 218{ 219 typeset sendfs=$1 220 typeset recvfs=$2 221 typeset file=$3 222 typeset expected="$4" 223 typeset tmpfile="$tmpdir/get_file.out" 224 225 log_must mount_redacted -f $recvfs 226 227 typeset file1="$(get_prop mountpoint $sendfs)/$file" 228 typeset file2="$(get_prop mountpoint $recvfs)/$file" 229 log_note "Comparing $file1 and $file2" 230 [[ -f $file1 ]] || log_fail "File $file1 does not exist." 231 [[ -f $file2 ]] || log_fail "File $file2 does not exist." 232 233 log_must eval "get_diff $file1 $file2 >$tmpfile" 234 typeset range="$(<$tmpfile)" 235 log_must unmount_redacted $recvfs 236 [[ "$expected" = "$range" ]] || log_fail "Unexpected range: $range" 237} 238 239function redacted_cleanup 240{ 241 typeset ds_list=$@ 242 typeset ds 243 244 for ds in $ds_list; do 245 zfs destroy -R $ds 246 done 247 248 set_tunable32 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. 254function 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} 271