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."