1#!/bin/ksh -p 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) 2015 by Delphix. All rights reserved. 16# 17 18. $STF_SUITE/tests/functional/rsend/rsend.kshlib 19 20# 21# Description: 22# Verify compressed send works correctly with datasets of varying recsize. 23# 24# Strategy: 25# 1. Check the recv behavior (into pools with features enabled and disabled) 26# of all combinations of -c -p and -L. Verify the stream is compressed, 27# and that the recsize property and that of a received file is correct 28# according to this matrix: 29# 30# +---------+--------+------------+------------+-----------+-----------+ 31# | send | send | received | received | received | received | 32# | stream | stream | file bs | prop | file bs | props | 33# | recsize | flags | (disabled) | (disabled) | (enabled) | (enabled) | 34# +---------+--------+------------+------------+-----------+-----------+ 35# | 128k | | 128k | 128k | 128k | 128k | 36# | 128k | -c | Fails | Fails | 128k | 128k | 37# | 128k | -p | 128k | 128k | 128k | 128k | 38# | 128k | -L | 128k | 128k | 128k | 128k | 39# | 128k | -cp | Fails | Fails | 128k | 128k | 40# | 128k | -cL | Fails | Fails | 128k | 128k | 41# | 128k | -pL | 128k | 128k | 128k | 128k | 42# | 128k | -cpL | Fails | Fails | 128k | 128k | 43# | 1m | | Fails | Fails | 128k | 128k | 44# | 1m | -c | Fails | Fails | 128k | 128k | 45# | 1m | -p | 128k | 128k | 128k | 1m | 46# | 1m | -L | Fails | Fails | 1m | 128k | 47# | 1m | -cp | Fails | Fails | 128k | 1m | 48# | 1m | -cL | Fails | Fails | 1m | 128k | 49# | 1m | -pL | Fails | Fails | 1m | 1m | 50# | 1m | -cpL | Fails | Fails | 1m | 1m | 51# +---------+--------+------------+------------+-----------+-----------+ 52# 53 54verify_runnable "both" 55 56function cleanup 57{ 58 datasetexists $TESTPOOL/128k && destroy_dataset $TESTPOOL/128k 59 datasetexists $TESTPOOL/1m && destroy_dataset $TESTPOOL/1m 60 cleanup_pool $POOL2 61 destroy_pool $POOL3 62} 63 64# For a received stream, verify the recsize (prop and file) match expectations. 65function check_recsize 66{ 67 typeset recv_ds=$1 68 typeset expected_file_bs=$2 69 typeset expected_recsize=$3 70 typeset file="$(get_prop mountpoint $recv_ds)/testfile" 71 72 [[ -f $file ]] || log_fail "file '$file' doesn't exist" 73 74 typeset read_recsize=$(get_prop recsize $recv_ds) 75 if is_freebsd; then 76 typeset read_file_bs=$(stat -f "%k" $file) 77 else 78 typeset read_file_bs=$(stat $file | sed -n \ 79 's/.*IO Block: \([0-9]*\).*/\1/p') 80 fi 81 82 [[ $read_recsize = $expected_recsize ]] || log_fail \ 83 "read_recsize: $read_recsize expected_recsize: $expected_recsize" 84 [[ $read_file_bs = $expected_file_bs ]] || log_fail \ 85 "read_file_bs: $read_file_bs expected_file_bs: $expected_file_bs" 86} 87 88# 89# This function does a zfs send and receive according to the parameters 90# below, and verifies the data shown in the strategy section. 91# 92# -[cpL] flags to pass through to 'zfs send' 93# -d Receive into a pool with all features disabled 94# 95# $1 The recordsize of the send dataset 96# $2 Whether or not the recv should work. 97# $3 The blocksize expected in a received file (default 128k) 98# $4 The recordsize property expected in a received dataset (default 128k) 99# 100function check 101{ 102 typeset recv_pool=$POOL2 103 typeset flags='-' 104 105 while getopts "cdpL" opt; do 106 case $opt in 107 c) 108 flags+='c' 109 ;; 110 d) 111 recv_pool=$POOL3 112 ;; 113 p) 114 flags+='p' 115 ;; 116 L) 117 flags+='L' 118 ;; 119 esac 120 done 121 shift $(($OPTIND - 1)) 122 [[ ${#flags} -eq 1 ]] && flags='' 123 124 typeset recsize=$1 125 typeset verify=$2 126 typeset expected_file_bs=${3-131072} 127 typeset expected_recsize=${4-131072} 128 typeset send_ds=$TESTPOOL/$recsize 129 typeset send_snap=$send_ds@snap 130 typeset recv_ds=$recv_pool/$recsize 131 typeset stream=$BACKDIR/stream.out 132 133 datasetexists $send_ds || log_fail "send ds: $send_ds doesn't exist" 134 [[ -f $stream ]] && log_must rm $stream 135 log_must eval "zfs send $flags $send_snap >$stream" 136 $verify eval "zfs recv $recv_ds <$stream" 137 typeset stream_size=$(zstream dump $stream | sed -n \ 138 's/ Total write size = \(.*\) (0x.*)/\1/p') 139 140 # 141 # Special case: For a send dataset with large blocks, don't try to 142 # verify the stream size is correct if the compress flag is present 143 # but the large blocks flag isn't. In these cases, the user data 144 # isn't compressed in the stream (though metadata is) so the 145 # verification would fail. 146 # 147 typeset do_size_test=true 148 [[ $recsize = $large && $flags =~ 'c' && ! $flags =~ 'L' ]] && \ 149 do_size_test=false 150 151 $do_size_test && verify_stream_size $stream $send_ds 152 153 if [[ $verify = "log_mustnot" ]]; then 154 datasetnonexists $recv_ds || log_fail "$recv_ds shouldn't exist" 155 return 156 fi 157 158 check_recsize $recv_ds $expected_file_bs $expected_recsize 159 $do_size_test && verify_stream_size $stream $recv_ds 160 log_must_busy zfs destroy -r $recv_ds 161} 162 163log_assert "Verify compressed send works with datasets of varying recsize." 164log_onexit cleanup 165typeset recsize opts dir 166typeset small=$((128 * 1024)) 167typeset large=$((1024 * 1024)) 168 169# Create POOL3 with features disabled and datasets to create test send streams 170datasetexists $POOL3 && log_must zpool destroy $POOL3 171log_must zpool create -d $POOL3 $DISK3 172write_compressible $BACKDIR 32m 173for recsize in $small $large; do 174 log_must zfs create -o compress=gzip -o recsize=$recsize \ 175 $TESTPOOL/$recsize 176 dir=$(get_prop mountpoint $TESTPOOL/$recsize) 177 log_must cp $BACKDIR/file.0 $dir/testfile 178 log_must zfs snapshot $TESTPOOL/$recsize@snap 179done 180 181# Run tests for send streams without large blocks 182for opts in '' -d -c -p -dp -L -dL -cp -cL -pL -dpL -cpL; do 183 check $opts $small log_must 184done 185for opts in -dc -dcp -dcL -dcpL; do 186 check $opts $small log_mustnot 187done 188 189# Run tests for send streams with large blocks 190for opts in '' -d -dp -c; do 191 check $opts $large log_must 192done 193for opts in -dc -dL -dcp -dcL -dpL -dcpL; do 194 check $opts $large log_mustnot 195done 196check -p $large log_must $small $large 197check -L $large log_must $large $small 198check -cp $large log_must $small $large 199check -cL $large log_must $large $small 200check -pL $large log_must $large $large 201check -cpL $large log_must $large $large 202 203log_pass "Compressed send works with datasets of varying recsize." 204