1 #!/bin/ksh 2 # 3 # CDDL HEADER START 4 # 5 # This file and its contents are supplied under the terms of the 6 # Common Development and Distribution License ("CDDL"), version 1.0. 7 # You may only use this file in accordance with the terms of version 8 # 1.0 of the CDDL. 9 # 10 # A full copy of the text of the CDDL should have accompanied this 11 # source. A copy of the CDDL is also available via the Internet at 12 # http://www.illumos.org/license/CDDL. 13 # 14 # CDDL HEADER END 15 # 16 17 # 18 # Copyright (c) 2012 by Delphix. All rights reserved. 19 # 20 21 . $STF_SUITE/include/libtest.shlib 22 # 23 # DESCRIPTION: 24 # Verify 'zfs send' can generate valid streams with different options 25 # 26 # STRATEGY: 27 # 1. Create datasets 28 # 2. Write some data to the datasets 29 # 3. Create a full send streams 30 # 4. Receive the send stream 31 # 5. Do a dry run with different options and verify the generated size 32 # estimate against the received stream 33 # 34 35 verify_runnable "both" 36 37 function cleanup 38 { 39 for ds in $datasets; do 40 datasetexists $ds && $ZFS destroy -rf $ds 41 done 42 } 43 44 function cal_percentage 45 { 46 typeset value=$1 47 return=$($ECHO "$PERCENT * $value" | bc) 48 return=$($ECHO "$return / 100" | bc) 49 echo $return 50 } 51 52 function get_estimate_size 53 { 54 typeset snapshot=$1 55 typeset option=$2 56 typeset base_snapshot=${3:-""} 57 if [[ -z $3 ]];then 58 typeset total_size=$($ZFS send $option $snapshot 2>&1 | $TAIL -1) 59 else 60 typeset total_size=$($ZFS send $option $base_snapshot $snapshot \ 61 2>&1 | $TAIL -1) 62 fi 63 if [[ $options == *"P"* ]]; then 64 total_size=$($ECHO "$total_size" | $AWK '{print $2}') 65 else 66 total_size=$($ECHO "$total_size" | $AWK '{print $5}') 67 total_size=${total_size%M} 68 total_size=$($ECHO "$total_size * $block_count" | bc) 69 fi 70 $ECHO $total_size 71 72 } 73 74 function verify_size_estimates 75 { 76 typeset options=$1 77 typeset file_size=$2 78 typeset refer_diff=$($ECHO "$refer_size - $estimate_size" | bc) 79 refer_diff=$($ECHO "$refer_diff / 1" | bc) 80 refer_diff=$($ECHO "$refer_diff" | $AWK '{print ($1 < 0) ? ($1 * -1): $1'}) 81 typeset file_diff=$($ECHO "$file_size - $estimate_size" | bc) 82 file_diff=$($ECHO "$file_diff / 1" | bc) 83 file_diff=$($ECHO "$file_diff" | $AWK '{print ($1 < 0) ? ($1 * -1):$1'}) 84 typeset expected_diff=$(cal_percentage $refer_size) 85 86 [[ -z $refer_diff && -z $file_diff && -z $expected_diff ]] && \ 87 log_fail "zfs send $options failed" 88 [[ $refer_diff -le $expected_diff && \ 89 $file_diff -le $expected_diff ]] || \ 90 log_fail "zfs send $options gives wrong size estimates" 91 } 92 93 log_assert "Verify 'zfs send -nvP' generates valid stream estimates" 94 log_onexit cleanup 95 typeset -l block_count=0 96 typeset -l block_size 97 typeset -i PERCENT=1 98 99 ((block_count=1024*1024)) 100 101 # create dataset 102 log_must $ZFS create $TESTPOOL/$TESTFS1 103 104 # create multiple snapshot for the dataset with data 105 for block_size in 64 128 256; do 106 log_must $DD if=/dev/urandom of=/$TESTPOOL/$TESTFS1/file$block_size \ 107 bs=1M count=$block_size 108 log_must $ZFS snapshot $TESTPOOL/$TESTFS1@snap$block_size 109 done 110 111 full_snapshot="$TESTPOOL/$TESTFS1@snap64" 112 increamental_snapshot="$TESTPOOL/$TESTFS1@snap256" 113 114 full_size=$($ZFS send $full_snapshot 2>&1 | wc -c) 115 increamental_size=$($ZFS send $increamental_snapshot 2>&1 | wc -c) 116 increamental_send=$($ZFS send -i $full_snapshot $increamental_snapshot 2>&1 | wc -c) 117 118 log_note "verify zfs send -nv" 119 options="-nv" 120 refer_size=$(get_prop refer $full_snapshot) 121 estimate_size=$(get_estimate_size $full_snapshot $options) 122 log_must verify_size_estimates $options $full_size 123 124 log_note "verify zfs send -Pnv" 125 options="-Pnv" 126 127 estimate_size=$(get_estimate_size $full_snapshot $options) 128 log_must verify_size_estimates $options $full_size 129 130 log_note "verify zfs send -nv for multiple snapshot send" 131 options="-nv" 132 refer_size=$(get_prop refer $increamental_snapshot) 133 134 estimate_size=$(get_estimate_size $increamental_snapshot $options) 135 log_must verify_size_estimates $options $increamental_size 136 137 log_note "verify zfs send -vPn for multiple snapshot send" 138 options="-vPn" 139 140 estimate_size=$(get_estimate_size $increamental_snapshot $options) 141 log_must verify_size_estimates $options $increamental_size 142 143 log_note "verify zfs send -inv for increamental send" 144 options="-nvi" 145 refer_size=$(get_prop refer $increamental_snapshot) 146 deduct_size=$(get_prop refer $full_snapshot) 147 refer_size=$($ECHO "$refer_size - $deduct_size" | bc) 148 149 estimate_size=$(get_estimate_size $increamental_snapshot $options $full_snapshot) 150 log_must verify_size_estimates $options $increamental_send 151 152 log_note "verify zfs send -ivPn for increamental send" 153 options="-vPni" 154 155 estimate_size=$(get_estimate_size $increamental_snapshot $options $full_snapshot) 156 log_must verify_size_estimates $options $increamental_send 157 158 log_must $ZFS destroy -r $TESTPOOL/$TESTFS1 159 160 #setup_recursive_send 161 datasets="$TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1/$TESTFS2 162 $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3" 163 # create nested datasets 164 log_must $ZFS create -p $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3 165 166 # verify dataset creation 167 for ds in $datasets; do 168 datasetexists $ds || log_fail "Create $ds dataset fail." 169 done 170 for ds in $datasets; do 171 log_must $DD if=/dev/urandom of=/$ds/file64 \ 172 bs=1M count=64 173 done 174 175 # create recursive nested snapshot 176 log_must $ZFS snapshot -r $TESTPOOL/$TESTFS1@snap64 177 for ds in $datasets; do 178 datasetexists $ds@snap64 || log_fail "Create $ds@snap64 snapshot fail." 179 done 180 recursive_size=$($ZFS send -R $full_snapshot 2>&1 | wc -c) 181 log_note "verify zfs send -Rnv for recursive send" 182 options="-Rnv" 183 refer_size=$(get_prop refer $full_snapshot) 184 refer_size=$($ECHO "$refer_size * 3" | bc) 185 186 estimate_size=$(get_estimate_size $full_snapshot $options) 187 log_must verify_size_estimates $options $recursive_size 188 189 log_note "verify zfs send -RvPn for recursive send" 190 options="-RvPn" 191 estimate_size=$(get_estimate_size $full_snapshot $options) 192 log_must verify_size_estimates $options $recursive_size 193 194 log_pass "'zfs send' prints the correct size estimates using '-n' and '-P' options."