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, 2016 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 mdb_set_uint32 zfs_override_estimate_recordsize 8192 40 for ds in $datasets; do 41 datasetexists $ds && zfs destroy -rf $ds 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 if [[ $options == *"P"* ]]; then 65 total_size=$(echo "$total_size" | awk '{print $2}') 66 else 67 total_size=$(echo "$total_size" | awk '{print $5}') 68 total_size=${total_size%M} 69 total_size=$(echo "$total_size * $block_count" | bc) 70 fi 71 echo $total_size 72 73} 74 75function verify_size_estimates 76{ 77 typeset options=$1 78 typeset file_size=$2 79 typeset refer_diff=$(echo "$refer_size - $estimate_size" | bc) 80 refer_diff=$(echo "$refer_diff / 1" | bc) 81 refer_diff=$(echo "$refer_diff" | nawk '{print ($1 < 0) ? ($1 * -1): $1'}) 82 typeset file_diff=$(echo "$file_size - $estimate_size" | bc) 83 file_diff=$(echo "$file_diff / 1" | bc) 84 file_diff=$(echo "$file_diff" | nawk '{print ($1 < 0) ? ($1 * -1):$1'}) 85 typeset expected_diff=$(cal_percentage $refer_size) 86 87 [[ -z $refer_diff && -z $file_diff && -z $expected_diff ]] && \ 88 log_fail "zfs send $options failed" 89 [[ $refer_diff -le $expected_diff && \ 90 $file_diff -le $expected_diff ]] || \ 91 log_fail "zfs send $options gives wrong size estimates" 92} 93 94log_assert "Verify 'zfs send -nvP' generates valid stream estimates" 95log_onexit cleanup 96mdb_set_uint32 zfs_override_estimate_recordsize 0 97typeset -l block_count=0 98typeset -l block_size 99typeset -i PERCENT=1 100 101((block_count=1024*1024)) 102 103# create dataset 104log_must zfs create $TESTPOOL/$TESTFS1 105 106# create multiple snapshot for the dataset with data 107for block_size in 64 128 256; do 108 log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS1/file$block_size \ 109 bs=1M count=$block_size 110 log_must zfs snapshot $TESTPOOL/$TESTFS1@snap$block_size 111done 112 113full_snapshot="$TESTPOOL/$TESTFS1@snap64" 114increamental_snapshot="$TESTPOOL/$TESTFS1@snap256" 115 116full_size=$(zfs send $full_snapshot 2>&1 | wc -c) 117increamental_size=$(zfs send $increamental_snapshot 2>&1 | wc -c) 118increamental_send=$(zfs send -i $full_snapshot $increamental_snapshot 2>&1 | wc -c) 119 120log_note "verify zfs send -nv" 121options="-nv" 122refer_size=$(get_prop refer $full_snapshot) 123estimate_size=$(get_estimate_size $full_snapshot $options) 124log_must verify_size_estimates $options $full_size 125 126log_note "verify zfs send -Pnv" 127options="-Pnv" 128 129estimate_size=$(get_estimate_size $full_snapshot $options) 130log_must verify_size_estimates $options $full_size 131 132log_note "verify zfs send -nv for multiple snapshot send" 133options="-nv" 134refer_size=$(get_prop refer $increamental_snapshot) 135 136estimate_size=$(get_estimate_size $increamental_snapshot $options) 137log_must verify_size_estimates $options $increamental_size 138 139log_note "verify zfs send -vPn for multiple snapshot send" 140options="-vPn" 141 142estimate_size=$(get_estimate_size $increamental_snapshot $options) 143log_must verify_size_estimates $options $increamental_size 144 145log_note "verify zfs send -inv for increamental send" 146options="-nvi" 147refer_size=$(get_prop refer $increamental_snapshot) 148deduct_size=$(get_prop refer $full_snapshot) 149refer_size=$(echo "$refer_size - $deduct_size" | bc) 150 151estimate_size=$(get_estimate_size $increamental_snapshot $options $full_snapshot) 152log_must verify_size_estimates $options $increamental_send 153 154log_note "verify zfs send -ivPn for increamental send" 155options="-vPni" 156 157estimate_size=$(get_estimate_size $increamental_snapshot $options $full_snapshot) 158log_must verify_size_estimates $options $increamental_send 159 160log_must zfs destroy -r $TESTPOOL/$TESTFS1 161 162#setup_recursive_send 163datasets="$TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1/$TESTFS2 164 $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3" 165# create nested datasets 166log_must zfs create -p $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3 167 168# verify dataset creation 169for ds in $datasets; do 170 datasetexists $ds || log_fail "Create $ds dataset fail." 171done 172for ds in $datasets; do 173 log_must dd if=/dev/urandom of=/$ds/file64 \ 174 bs=1M count=64 175done 176 177# create recursive nested snapshot 178log_must zfs snapshot -r $TESTPOOL/$TESTFS1@snap64 179for ds in $datasets; do 180 datasetexists $ds@snap64 || log_fail "Create $ds@snap64 snapshot fail." 181done 182recursive_size=$(zfs send -R $full_snapshot 2>&1 | wc -c) 183log_note "verify zfs send -Rnv for recursive send" 184options="-Rnv" 185refer_size=$(get_prop refer $full_snapshot) 186refer_size=$(echo "$refer_size * 3" | bc) 187 188estimate_size=$(get_estimate_size $full_snapshot $options) 189log_must verify_size_estimates $options $recursive_size 190 191log_note "verify zfs send -RvPn for recursive send" 192options="-RvPn" 193estimate_size=$(get_estimate_size $full_snapshot $options) 194log_must verify_size_estimates $options $recursive_size 195 196log_pass "'zfs send' prints the correct size estimates using '-n' and '-P' options." 197