#!/bin/ksh # SPDX-License-Identifier: CDDL-1.0 # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or https://opensource.org/licenses/CDDL-1.0. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright (c) 2016, 2018 by Delphix. All rights reserved. # . $STF_SUITE/include/libtest.shlib . $STF_SUITE/tests/functional/rsend/rsend.kshlib . $STF_SUITE/tests/functional/redacted_send/redacted.cfg if ! is_linux; then alias udevadm=: fi function setup_dataset { typeset ds_name=$1 typeset opts=$2 typeset file_create_func=$3 typeset sendfs="$POOL/$ds_name" [[ -n $file_create_func ]] || file_create_func=setup_common log_must zfs create $opts $sendfs $file_create_func $sendfs log_must zfs snapshot $sendfs@snap log_must zfs clone $opts $sendfs@snap $POOL/${ds_name}_clone log_must zfs snapshot $POOL/${ds_name}_clone@snap } function setup_common { typeset sendfs=$1 typeset mntpnt=$(get_prop mountpoint $sendfs) typeset bs=$(get_prop recsize $sendfs) log_must dd if=/dev/urandom of=$mntpnt/f1 bs=$bs count=16 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=$bs count=32 } function setup_embedded { typeset sendfs=$1 typeset recsize typeset mntpnt=$(get_prop mountpoint $sendfs) for recsize in 512 1024 2048 4096 8192 16384; do if is_illumos; then log_must mkholes -d $((recsize - 8)):8 $mntpnt/$recsize else log_must dd if=/dev/urandom of=$mntpnt/$recsize bs=8 \ count=1 seek=$(((recsize / 8) - 1)) fi done } function setup_holes { typeset sendfs=$1 typeset mntpnt=$(get_prop mountpoint $sendfs) typeset M=$((1024 * 1024)) if is_illumos; then log_must mkholes -d 0:$((8 * M)) $mntpnt/f1 log_must mkholes -d 0:$M -d $((7 * M)):$M $mntpnt/f2 log_must mkholes -d $M:$((6 * M)) -h $((7 * M)):$M $mntpnt/f3 log_must mkholes -h 0:$((8 * M)) $mntpnt/f4 else log_must dd if=/dev/urandom of=$mntpnt/f1 bs=8M count=1 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=1M count=1 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=1M count=1 seek=7 \ conv=notrunc log_must dd if=/dev/urandom of=$mntpnt/f3 bs=1M count=6 seek=1 log_must truncate -s $((8 * M)) $mntpnt/f3 log_must truncate -s $((8 * M)) $mntpnt/f4 fi log_must zfs create $sendfs/manyrm for i in {1..256}; do log_must stride_dd -i /dev/urandom -o $mntpnt/manyrm/f$i -b 512 \ -c $(random_int_between 1 100) -s $(random_int_between 1 4) done log_must zfs snapshot $sendfs/manyrm@snap log_must zfs clone $sendfs/manyrm@snap $sendfs/manyrm_clone log_must zfs snapshot $sendfs/manyrm_clone@snap } function setup_incrementals { typeset sendfs=$1 typeset mntpnt=$(get_prop mountpoint $sendfs) typeset bs=$(get_prop recsize $sendfs) log_must dd if=/dev/urandom of=$mntpnt/f1 bs=$bs count=16 log_must dd if=/dev/urandom of=$mntpnt/f2 bs=$bs count=32 log_must mkdir $mntpnt/d1 log_must eval "cat $mntpnt/f1 $mntpnt/f2 >$mntpnt/d1/f1" log_must zfs snapshot $sendfs@snap0 log_must zfs clone $sendfs@snap0 $POOL/hole mntpnt=$(get_prop mountpoint $POOL/hole) log_must dd if=/dev/zero of=$mntpnt/f2 bs=$bs count=16 conv=notrunc log_must zfs snapshot $POOL/hole@snap log_must zfs clone $sendfs@snap0 $POOL/stride3 mntpnt=$(get_prop mountpoint $POOL/stride3) log_must stride_dd -i /dev/urandom -o $mntpnt/f2 -b $bs -c 11 -s 3 log_must zfs snapshot $POOL/stride3@snap log_must zfs clone $sendfs@snap0 $POOL/stride5 mntpnt=$(get_prop mountpoint $POOL/stride5) log_must stride_dd -i /dev/urandom -o $mntpnt/f2 -b $bs -c 7 -s 5 log_must zfs snapshot $POOL/stride5@snap log_must zfs clone $sendfs@snap0 $POOL/int log_must zfs snapshot $POOL/int@snap log_must zfs clone $POOL/int@snap $POOL/rm mntpnt=$(get_prop mountpoint $POOL/rm) log_must rm -rf $mntpnt/[df][12] log_must zfs snapshot $POOL/rm@snap log_must zfs clone $POOL/int@snap $POOL/write mntpnt=$(get_prop mountpoint $POOL/write) log_must dd if=/dev/urandom of=$mntpnt/f1 bs=512 count=16 conv=notrunc log_must dd if=/dev/urandom of=$mntpnt/d1/f1 bs=512 count=16 seek=16 \ conv=notrunc log_must zfs snapshot $POOL/write@snap } function setup_mounts { typeset sendfs=$1 typeset mntpnt=$(get_prop mountpoint $sendfs) log_must touch $mntpnt/empty log_must dd if=/dev/urandom of=$mntpnt/contents1 bs=512 count=2 log_must dd if=/dev/urandom of=$mntpnt/contents2 bs=512 count=2 log_must mkdir $mntpnt/dir1 log_must touch $mntpnt/dir1/empty log_must dd if=/dev/urandom of=$mntpnt/dir1/contents1 bs=512 count=2 log_must dd if=/dev/urandom of=$mntpnt/dir1/contents2 bs=512 count=2 log_must mkdir $mntpnt/dir1/dir2 log_must touch $mntpnt/dir1/dir2/empty log_must dd if=/dev/urandom of=$mntpnt/dir1/dir2/file bs=512 count=2 log_must zfs create -s -V 16p $sendfs/vol log_must zfs snapshot $sendfs/vol@snap log_must zfs clone $sendfs/vol@snap $sendfs/vol_clone log_must zfs snapshot $sendfs/vol_clone@snap } function mount_redacted { typeset flag='' while getopts "f" opt; do case $opt in f) flag='-f' ;; esac done shift $(($OPTIND - 1)) typeset ds=$1 log_must set_tunable32 ALLOW_REDACTED_DATASET_MOUNT 1 zfs mount $flag -oro $ds || return 1 log_must set_tunable32 ALLOW_REDACTED_DATASET_MOUNT 0 return 0 } function unmount_redacted { typeset ds=$1 zfs unmount $ds } # # This function calls a utility that prints out the ranges where a file # and its redacted counterpart differ, each range on a new line like this: # # 0,131072 # 1966080,131072 # 3932160,131072 # # The output is then checked against a variable containing the expected # output to verify the redacted ranges are the ones expected. # function compare_files { typeset sendfs=$1 typeset recvfs=$2 typeset file=$3 typeset expected="$4" typeset tmpfile="$tmpdir/get_file.out" log_must mount_redacted -f $recvfs typeset file1="$(get_prop mountpoint $sendfs)/$file" typeset file2="$(get_prop mountpoint $recvfs)/$file" log_note "Comparing $file1 and $file2" [[ -f $file1 ]] || log_fail "File $file1 does not exist." [[ -f $file2 ]] || log_fail "File $file2 does not exist." log_must eval "get_diff $file1 $file2 >$tmpfile" typeset range="$(<$tmpfile)" log_must unmount_redacted $recvfs [[ "$expected" = "$range" ]] || log_fail "Unexpected range: $range" } function redacted_cleanup { typeset ds_list=$@ typeset ds for ds in $ds_list; do zfs destroy -R $ds done set_tunable32 ALLOW_REDACTED_DATASET_MOUNT 0 rm -f $(get_prop mountpoint $POOL)/tmp/* } # Retrieve the redaction list of a bookmark or snapshot, using # the property or zdb output, as requested. function get_guid_list { typeset filename=$1 typeset dataset=$2 typeset use_zdb=${3:-false} if $use_zdb; then guid_list=$(zdb -vvvv $dataset | sed -e 's/,//g' \ -ne 's/^.*Snapshots: \[\(.*\)\]/\1/p') else guid_list=$(get_prop redact_snaps $dataset) fi for guid in $(echo $guid_list | tr ',' ' '); do echo $guid done | sort >$filename }