1# !/bin/ksh 2# 3# This file and its contents are supplied under the terms of the 4# Common Development and Distribution License ("CDDL"), version 1.0. 5# You may only use this file in accordance with the terms of version 6# 1.0 of the CDDL. 7# 8# A full copy of the text of the CDDL should have accompanied this 9# source. A copy of the CDDL is also available via the Internet at 10# http://www.illumos.org/license/CDDL. 11# 12 13# 14# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 15# 16 17# 18# DESCRIPTION 19# Verify that "zfs list" gives correct values for written and written@ 20# proerties for the dataset when different operations are on done on it 21# 22# 23# STRATEGY 24# 1) Create recursive datasets 25# 2) Take snapshots, write data and verify written/ written@ properties for 26# following cases 27# a) Delete data 28# b) Write Data 29# c) Clone 30# d) Delete snapshot 31# e) Recursive datasets 32 33. $STF_SUITE/include/libtest.shlib 34. $STF_SUITE/include/math.shlib 35 36function cleanup 37{ 38 for ds in $datasets; do 39 datasetexists $ds && log_must zfs destroy -R $TESTPOOL/$TESTFS1 40 done 41} 42function get_prop_mb 43{ 44 typeset prop=$1 45 typeset dataset=$2 46 typeset -l value=$(get_prop $prop $dataset) 47 ((value = value / mb_block)) 48 echo $value 49} 50 51datasets="$TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1/$TESTFS2 \ 52 $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3" 53 54log_assert "verify zfs written and written@ property" 55log_onexit cleanup 56 57typeset -l i=1 58typeset -l blocks=50 59typeset -l expected_written=0 60typeset -l expected_writtenat=0 61typeset -l written=0 62typeset -l total=0 63typeset -l snap1_size=0 64typeset -l snap2_size=0 65typeset -l snap3_size=0 66typeset -l mb_block=0 67((mb_block = 1024 * 1024)) 68 69log_note "verify written property statistics for dataset" 70log_must zfs create -p $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3 71for i in 1 2 3; do 72 log_must zfs snapshot $TESTPOOL/$TESTFS1@snap$i 73 log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS1/testfile.$i bs=1M \ 74 count=$blocks 75 log_must sync 76 written=$(get_prop written $TESTPOOL/$TESTFS1) 77 ((expected_written=blocks * mb_block)) 78 within_percent $written $expected_written 99.5 || \ 79 log_fail "Unexpected written value $written $expected_written" 80 ((total = total + blocks)) 81 ((blocks = blocks + 50)) 82done 83 84log_note "verify written property statistics for snapshots" 85blocks=0 86for i in 1 2 3; do 87 written=$(get_prop written $TESTPOOL/$TESTFS1@snap$i) 88 if [[ $blocks -eq 0 ]]; then 89 # Written value for the frist non-clone snapshot is 90 # expected to be equal to the referenced value. 91 expected_written=$( \ 92 get_prop referenced $TESTPOOL/$TESTFS1@snap$i) 93 else 94 ((expected_written = blocks * mb_block)) 95 fi 96 within_percent $written $expected_written 99.5 || \ 97 log_fail "Unexpected written value $written $expected_written $i" 98 ((blocks = blocks + 50)) 99done 100 101snap1_size=$total 102((snap2_size = total-50)) 103((snap3_size = total-100)) 104 105log_note "verify written@ for the same dataset" 106blocks=50 107for i in 1 2 3; do 108 writtenat=$(get_prop written@snap$i $TESTPOOL/$TESTFS1) 109 ((expected_writtenat = total * mb_block)) 110 within_percent $writtenat $expected_writtenat 99.5 || \ 111 log_fail "Unexpected written@ value" 112 ((total = total - blocks)) 113 ((blocks = blocks + 50)) 114done 115log_note "delete data" 116before_written=$(get_prop written $TESTPOOL/$TESTFS1) 117log_must rm /$TESTPOOL/$TESTFS1/testfile.3 118snap3_size=0 119log_must sync 120written=$(get_prop written $TESTPOOL/$TESTFS1) 121writtenat3=$(get_prop written@snap3 $TESTPOOL/$TESTFS1) 122[[ $written -eq $writtenat3 ]] || \ 123 log_fail "Written and written@ dont match $written $writtenat3" 124within_percent $written $before_written 0.1 && \ 125 log_fail "Unexpected written value after delete $written $before_written" 126writtenat=$(get_prop written@snap1 $TESTPOOL/$TESTFS1) 127((snap1_size = snap1_size - 150)) 128((expected_writtenat = snap1_size * mb_block)) 129within_percent $writtenat $expected_writtenat 99.5 || \ 130 log_fail "Unexpected written value after delete $writtenat $expected_writtenat" 131writtenat=$(get_prop written@snap2 $TESTPOOL/$TESTFS1) 132((snap2_size = snap2_size - 150)) 133((expected_writtenat = snap2_size * mb_block)) 134within_percent $writtenat $expected_writtenat 99.5 || \ 135 log_fail "Unexpected written value after delete" 136 137log_note "write data" 138blocks=20 139log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS1/testfile.3 bs=1M \ 140 count=$blocks 141log_must sync 142written=$(get_prop written $TESTPOOL/$TESTFS1) 143writtenat1=$(get_prop written@snap1 $TESTPOOL/$TESTFS1) 144writtenat2=$(get_prop written@snap2 $TESTPOOL/$TESTFS1) 145writtenat3=$(get_prop written@snap3 $TESTPOOL/$TESTFS1) 146((snap3_size = snap3_size + blocks)) 147((expected_writtenat = snap3_size * mb_block)) 148[[ $written -eq $writtenat3 ]] || \ 149 log_fail "Unexpected_written value" 150within_percent $writtenat3 $expected_writtenat 99.5 || \ 151 log_fail "Unexpected_written@ value for snap3" 152((snap2_size = snap2_size + blocks)) 153((expected_writtenat = snap2_size * mb_block)) 154within_percent $writtenat2 $expected_writtenat 99.5 || \ 155 log_fail "Unexpected_written@ value for snap2" 156((snap1_size = snap1_size + blocks)) 157((expected_writtenat = snap1_size * mb_block)) 158within_percent $writtenat1 $expected_writtenat 99.5 || \ 159 log_fail "Unexpected_written@ value for snap1" 160 161log_note "write data to a clone" 162before_clone=$(get_prop written $TESTPOOL/$TESTFS1) 163log_must zfs clone $TESTPOOL/$TESTFS1@snap1 $TESTPOOL/$TESTFS1/snap1.clone 164log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS1/snap1.clone/testfile bs=1M \ 165 count=40 166after_clone=$(get_prop written $TESTPOOL/$TESTFS1) 167[[ $before_clone -eq $after_clone ]] || \ 168 log_fail "unexpected written for clone $before_clone $after_clone" 169 170log_note "deleted snapshot" 171typeset -l before_written1=$(get_prop_mb written@snap1 $TESTPOOL/$TESTFS1) 172typeset -l before_written3=$(get_prop_mb written@snap3 $TESTPOOL/$TESTFS1) 173typeset -l snap_before_written2=$(get_prop_mb written $TESTPOOL/$TESTFS1@snap2) 174typeset -l snap_before_written3=$(get_prop_mb written $TESTPOOL/$TESTFS1@snap3) 175log_must zfs destroy $TESTPOOL/$TESTFS1@snap2 176log_mustnot snapexists $TESTPOOL/$TESTFS1@snap2 177log_must sync 178written1=$(get_prop_mb written@snap1 $TESTPOOL/$TESTFS1) 179written3=$(get_prop_mb written@snap3 $TESTPOOL/$TESTFS1) 180[[ $before_written1 -eq $written1 && $before_written3 -eq $written3 ]] || \ 181 log_fail "unexpected written values $before_written1 $written1" 182typeset -l expected_written3 183((expected_written3 = snap_before_written2 + snap_before_written3)) 184prev_written=$(get_prop_mb written $TESTPOOL/$TESTFS1@snap3) 185within_percent $prev_written $expected_written3 99.5 || \ 186 log_fail "unexpected written value $prev_written $expected_written3" 187 188log_must zfs destroy $TESTPOOL/$TESTFS1@snap3 189log_mustnot snapexists $TESTPOOL/$TESTFS1@snap3 190written=$(get_prop written $TESTPOOL/$TESTFS1) 191writtenat1=$(get_prop written@snap1 $TESTPOOL/$TESTFS1) 192[[ $written -ne $writtenat1 ]] && \ 193 log_fail "Unexpected last snapshot written value" 194 195log_note "verify written@ property for recursive datasets" 196blocks=10 197log_must zfs snapshot -r $TESTPOOL/$TESTFS1@now 198for ds in $datasets; do 199 writtenat=$(get_prop written@now $ds) 200 [[ $writtenat -ne 0 ]] && \ 201 log_fail "Unexpected written@ value" 202 log_must dd if=/dev/urandom of=/$ds/testfile bs=1M count=$blocks 203 log_must sync 204 writtenat=$(get_prop written@now $ds) 205 ((expected_writtenat = blocks * mb_block)) 206 within_percent $writtenat $expected_writtenat 0.1 || \ 207 log_fail "Unexpected written value" 208 ((blocks = blocks + 10)) 209done 210 211log_note "verify written@ output for recursive datasets" 212blocks=20 213for ds in $datasets; do 214 log_must zfs snapshot $ds@current 215 log_must dd if=/dev/urandom of=/$ds/testfile bs=1M \ 216 count=$blocks 217 log_must sync 218done 219recursive_output=$(zfs get -r written@current $TESTPOOL | \ 220 grep -v $TESTFS1@ | grep -v $TESTFS2@ | grep -v $TESTFS3@ | \ 221 grep -v "VALUE" | grep -v "-") 222expected="20.0M" 223for ds in $datasets; do 224 writtenat=$(echo "$recursive_output" | grep -v $ds/) 225 writtenat=$(echo "$writtenat" | grep $ds | awk '{print $3}') 226 [[ $writtenat == $expected ]] || \ 227 log_fail "recursive written property output mismatch" 228done 229 230log_pass "zfs written and written@ property fields print correct values" 231