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 32function 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 49function 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 59function 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_illumos; then 67 log_must mkholes -d $((recsize - 8)):8 $mntpnt/$recsize 68 else 69 log_must dd if=/dev/urandom of=$mntpnt/$recsize bs=8 \ 70 count=1 seek=$(((recsize / 8) - 1)) 71 fi 72 done 73} 74 75function setup_holes 76{ 77 typeset sendfs=$1 78 79 typeset mntpnt=$(get_prop mountpoint $sendfs) 80 typeset M=$((1024 * 1024)) 81 82 if is_illumos; then 83 log_must mkholes -d 0:$((8 * M)) $mntpnt/f1 84 log_must mkholes -d 0:$M -d $((7 * M)):$M $mntpnt/f2 85 log_must mkholes -d $M:$((6 * M)) -h $((7 * M)):$M $mntpnt/f3 86 log_must mkholes -h 0:$((8 * M)) $mntpnt/f4 87 else 88 log_must dd if=/dev/urandom of=$mntpnt/f1 bs=8M count=1 89 90 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=1M count=1 91 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=1M count=1 seek=7 \ 92 conv=notrunc 93 94 log_must dd if=/dev/urandom of=$mntpnt/f3 bs=1M count=6 seek=1 95 log_must truncate -s $((8 * M)) $mntpnt/f3 96 97 log_must truncate -s $((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_int_between 1 100) -s $(random_int_between 1 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 111function 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 154function 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 176function 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 ALLOW_REDACTED_DATASET_MOUNT 1 190 zfs mount $flag -oro $ds || return 1 191 log_must set_tunable32 ALLOW_REDACTED_DATASET_MOUNT 0 192 return 0 193} 194 195function 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# 213function 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 235function redacted_cleanup 236{ 237 typeset ds_list=$@ 238 typeset ds 239 240 for ds in $ds_list; do 241 zfs destroy -R $ds 242 done 243 244 set_tunable32 ALLOW_REDACTED_DATASET_MOUNT 0 245 rm -f $(get_prop mountpoint $POOL)/tmp/* 246} 247 248# Retrieve the redaction list of a bookmark or snapshot, using 249# the property or zdb output, as requested. 250function get_guid_list 251{ 252 typeset filename=$1 253 typeset dataset=$2 254 typeset use_zdb=${3:-false} 255 256 if $use_zdb; then 257 guid_list=$(zdb -vvvv $dataset | sed -e 's/,//g' \ 258 -ne 's/^.*Snapshots: \[\(.*\)\]/\1/p') 259 else 260 guid_list=$(get_prop redact_snaps $dataset) 261 fi 262 263 for guid in $(echo $guid_list | tr ',' ' '); do 264 echo $guid 265 done | sort >$filename 266} 267