1#!/bin/ksh 2 3# 4# This file and its contents are supplied under the terms of the 5# Common Development and Distribution License ("CDDL"), version 1.0. 6# You may only use this file in accordance with the terms of version 7# 1.0 of the CDDL. 8# 9# A full copy of the text of the CDDL should have accompanied this 10# source. A copy of the CDDL is also available via the Internet at 11# http://www.illumos.org/license/CDDL. 12# 13 14# 15# Copyright (c) 2018 by Delphix. All rights reserved. 16# 17 18. $STF_SUITE/tests/functional/redacted_send/redacted.kshlib 19 20# 21# Description: 22# Verify redacted send streams reliably handle holes. 23# 24# Strategy: 25# 1. Holes written at the beginning and end of a non-sparse file in the 26# redacted list are correctly redacted. 27# 2. Holes written throughout a non-sparse file in the redacted list are 28# correctly redacted. 29# 3. Data written into a hole in a sparse file in the redacted list are 30# correctly redacted. 31# 4. Holes in metadata blocks. 32# 33 34typeset ds_name="holes" 35typeset sendfs="$POOL/$ds_name" 36typeset recvfs="$POOL2/$ds_name" 37typeset clone="$POOL/${ds_name}_clone" 38typeset tmpdir="$(get_prop mountpoint $POOL)/tmp" 39typeset stream=$(mktemp $tmpdir/stream.XXXX) 40setup_dataset $ds_name '' setup_holes 41typeset clone_mnt="$(get_prop mountpoint $clone)" 42typeset send_mnt="$(get_prop mountpoint $sendfs)" 43typeset recv_mnt="/$POOL2/$ds_name" 44typeset M=$((1024 * 1024)) 45 46log_onexit redacted_cleanup $sendfs $recvfs 47 48# Write holes at the start and end of a non-sparse file. 49if is_illumos; then 50 log_must mkholes -h 0:$M -h $((7 * M)):$M $clone_mnt/f1 51else 52 log_must dd if=/dev/zero of=$clone_mnt/f1 bs=1M count=1 conv=notrunc 53 log_must dd if=/dev/zero of=$clone_mnt/f1 bs=1M count=1 conv=notrunc seek=7 54fi 55log_must zfs snapshot $clone@snap1 56log_must zfs redact $sendfs@snap book1 $clone@snap1 57log_must eval "zfs send --redact book1 $sendfs@snap >$stream" 58log_must eval "zfs recv $recvfs <$stream" 59compare_files $sendfs $recvfs "f1" "$RANGE5" 60log_must zfs rollback -R $clone@snap 61log_must zfs destroy -R $recvfs 62 63# Write two overlapping sets of holes into the same non-sparse file. 64log_must stride_dd -i /dev/zero -o $clone_mnt/f1 -b $((128 * 1024)) -c 8 -s 2 -k 3 65log_must stride_dd -i /dev/zero -o $clone_mnt/f1 -b $((256 * 1024)) -c 8 -s 2 -k 6 66log_must zfs snapshot $clone@snap1 67log_must zfs redact $sendfs@snap book2 $clone@snap1 68log_must eval "zfs send --redact book2 $sendfs@snap >$stream" 69log_must eval "zfs recv $recvfs <$stream" 70compare_files $sendfs $recvfs "f1" "$RANGE6" 71log_must zfs rollback -R $clone@snap 72log_must zfs destroy -R $recvfs 73 74# Write data into the middle of a hole. 75if is_illumos; then 76 log_must mkholes -d $((3 * M)):$((2 * M)) $clone_mnt/f2 77else 78 log_must dd if=/dev/urandom of=$clone_mnt/f2 bs=1M count=2 seek=3 \ 79 conv=notrunc 80fi 81log_must zfs snapshot $clone@snap1 82log_must zfs redact $sendfs@snap book3 $clone@snap1 83log_must eval "zfs send --redact book3 $sendfs@snap >$stream" 84log_must eval "zfs recv $recvfs <$stream" 85compare_files $sendfs $recvfs "f2" "$RANGE14" 86log_must zfs rollback -R $clone@snap 87log_must zfs destroy -R $recvfs 88 89# Remove a file with holes. 90log_must rm $clone_mnt/f3 91log_must zfs snapshot $clone@snap1 92log_must zfs redact $sendfs@snap book4 $clone@snap1 93log_must eval "zfs send --redact book4 $sendfs@snap >$stream" 94log_must eval "zfs recv $recvfs <$stream" 95compare_files $sendfs $recvfs "f3" "$RANGE7" 96log_must zfs rollback -R $clone@snap 97log_must zfs destroy -R $recvfs 98 99# Create a hole in a L0 metadata block by removing files. 100log_must rm $send_mnt/manyrm_clone/f{32..96} 101log_must zfs snapshot $sendfs/manyrm_clone@snap1 102 103log_must zfs redact $sendfs/manyrm@snap book6 $sendfs/manyrm_clone@snap1 104log_must eval "zfs send --redact book6 $sendfs/manyrm@snap >$stream" 105log_must eval "zfs recv $recvfs <$stream" 106log_must mount_redacted -f $recvfs 107for i in {1..31} {97..256}; do 108 diff $send_mnt/manyrm/f$i $recv_mnt/f$i || log_fail \ 109 "File f$i did not match in the send and recv datasets." 110done 111for i in {32..96}; do 112 file_size=$(stat_size $send_mnt/manyrm/f$i) 113 redacted_size=$(stat_size $recv_mnt/f$i) 114 [[ $file_size -eq $redacted_size ]] || log_fail \ 115 "File f$i has size $file_size and redacted size $redacted_size" 116done 117log_must zfs rollback -R $clone@snap 118log_must zfs destroy -R $recvfs 119 120log_pass "Redacted send streams reliably handle holes." 121