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, 2018 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 35verify_runnable "both" 36 37function cleanup 38{ 39 log_must set_tunable32 OVERRIDE_ESTIMATE_RECORDSIZE 8192 40 for ds in $datasets; do 41 destroy_dataset $ds "-rf" 42 done 43} 44 45function cal_percentage 46{ 47 typeset value=$1 48 return=$(echo "$PERCENT * $value" | bc) 49 return=$(echo "$return / 100" | bc) 50 echo $return 51} 52 53function get_estimate_size 54{ 55 typeset snapshot=$1 56 typeset option=$2 57 typeset base_snapshot=${3:-""} 58 if [[ -z $3 ]]; then 59 typeset total_size=$(zfs send $option $snapshot 2>&1 | tail -1) 60 else 61 typeset total_size=$(zfs send $option $base_snapshot $snapshot \ 62 2>&1 | tail -1) 63 fi 64 total_size=$(echo "$total_size" | awk '{print $NF}') 65 if [[ $options != *"P"* ]]; then 66 total_size=${total_size%M} 67 total_size=$(echo "$total_size * $block_count" | bc) 68 fi 69 echo $total_size 70 71} 72 73function verify_size_estimates 74{ 75 typeset options=$1 76 typeset file_size=$2 77 typeset refer_diff=$(echo "$refer_size - $estimate_size" | bc) 78 refer_diff=$(echo "$refer_diff / 1" | bc) 79 refer_diff=$(echo "$refer_diff" | awk '{print ($1 < 0) ? ($1 * -1): $1'}) 80 typeset file_diff=$(echo "$file_size - $estimate_size" | bc) 81 file_diff=$(echo "$file_diff / 1" | bc) 82 file_diff=$(echo "$file_diff" | awk '{print ($1 < 0) ? ($1 * -1):$1'}) 83 typeset expected_diff=$(cal_percentage $refer_size) 84 85 [[ -z $refer_diff && -z $file_diff && -z $expected_diff ]] && \ 86 log_fail "zfs send $options failed" 87 [[ $refer_diff -le $expected_diff && \ 88 $file_diff -le $expected_diff ]] || \ 89 log_fail "zfs send $options gives wrong size estimates" 90} 91 92log_assert "Verify 'zfs send -nvP' generates valid stream estimates" 93log_onexit cleanup 94log_must set_tunable32 OVERRIDE_ESTIMATE_RECORDSIZE 0 95typeset -l block_count=0 96typeset -l block_size 97typeset -i PERCENT=1 98 99((block_count=1024*1024)) 100 101# create dataset 102log_must zfs create $TESTPOOL/$TESTFS1 103 104# create multiple snapshot for the dataset with data 105for 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 log_must zfs bookmark $TESTPOOL/$TESTFS1@snap$block_size \ 110 "$TESTPOOL/$TESTFS1#bmark$block_size" 111done 112 113full_snapshot="$TESTPOOL/$TESTFS1@snap64" 114incremental_snapshot="$TESTPOOL/$TESTFS1@snap256" 115full_bookmark="$TESTPOOL/$TESTFS1#bmark64" 116incremental_bookmark="$TESTPOOL/$TESTFS1#bmark256" 117 118full_size=$(zfs send $full_snapshot 2>&1 | wc -c) 119incremental_size=$(zfs send $incremental_snapshot 2>&1 | wc -c) 120incremental_send=$(zfs send -i $full_snapshot $incremental_snapshot 2>&1 | wc -c) 121 122log_note "verify zfs send -nvV" 123options="-nvV" 124refer_size=$(get_prop refer $full_snapshot) 125estimate_size=$(get_estimate_size $full_snapshot $options) 126log_must verify_size_estimates $options $full_size 127 128log_note "verify zfs send -PnvV" 129options="-PnvV" 130 131estimate_size=$(get_estimate_size $full_snapshot $options) 132log_must verify_size_estimates $options $full_size 133 134log_note "verify zfs send -nvV for multiple snapshot send" 135options="-nvV" 136refer_size=$(get_prop refer $incremental_snapshot) 137 138estimate_size=$(get_estimate_size $incremental_snapshot $options) 139log_must verify_size_estimates $options $incremental_size 140 141log_note "verify zfs send -vVPn for multiple snapshot send" 142options="-vVPn" 143 144estimate_size=$(get_estimate_size $incremental_snapshot $options) 145log_must verify_size_estimates $options $incremental_size 146 147log_note "verify zfs send -invV for incremental send" 148options="-nvVi" 149refer_size=$(get_prop refer $incremental_snapshot) 150deduct_size=$(get_prop refer $full_snapshot) 151refer_size=$(echo "$refer_size - $deduct_size" | bc) 152 153estimate_size=$(get_estimate_size $incremental_snapshot $options $full_snapshot) 154log_must verify_size_estimates $options $incremental_send 155estimate_size=$(get_estimate_size $incremental_snapshot $options $full_bookmark) 156log_must verify_size_estimates $options $incremental_send 157 158log_note "verify zfs send -ivVPn for incremental send" 159options="-vVPni" 160 161estimate_size=$(get_estimate_size $incremental_snapshot $options $full_snapshot) 162log_must verify_size_estimates $options $incremental_send 163estimate_size=$(get_estimate_size $incremental_snapshot $options $full_bookmark) 164log_must verify_size_estimates $options $incremental_send 165 166log_must zfs destroy -r $TESTPOOL/$TESTFS1 167 168#setup_recursive_send 169datasets="$TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1/$TESTFS2 170 $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3" 171# create nested datasets 172log_must zfs create -p $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3 173 174# verify dataset creation 175for ds in $datasets; do 176 datasetexists $ds || log_fail "Create $ds dataset fail." 177done 178for ds in $datasets; do 179 log_must dd if=/dev/urandom of=/$ds/file64 \ 180 bs=1M count=64 181done 182 183# create recursive nested snapshot 184log_must zfs snapshot -r $TESTPOOL/$TESTFS1@snap64 185for ds in $datasets; do 186 datasetexists $ds@snap64 || log_fail "Create $ds@snap64 snapshot fail." 187done 188recursive_size=$(zfs send -R $full_snapshot 2>&1 | wc -c) 189log_note "verify zfs send -RnvV for recursive send" 190options="-RnvV" 191refer_size=$(get_prop refer $full_snapshot) 192refer_size=$(echo "$refer_size * 3" | bc) 193 194estimate_size=$(get_estimate_size $full_snapshot $options) 195log_must verify_size_estimates $options $recursive_size 196 197log_note "verify zfs send -RvVPn for recursive send" 198options="-RvVPn" 199estimate_size=$(get_estimate_size $full_snapshot $options) 200log_must verify_size_estimates $options $recursive_size 201 202log_pass "'zfs send' prints the correct size estimates using '-n' and '-P' options." 203