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