1#!/bin/ksh -p 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 2019 Joyent, Inc. 15# 16 17. $STF_SUITE/include/libtest.shlib 18. $STF_SUITE/tests/functional/refreserv/refreserv.cfg 19 20# 21# DESCRIPTION: 22# raidz refreservation=auto accounts for extra parity and skip blocks 23# 24# STRATEGY: 25# 1. Create a pool with a single raidz vdev 26# 2. For each block size [512b, 1k, 128k] or [4k, 8k, 128k] 27# - create a volume 28# - fully overwrite it 29# - verify that referenced is less than or equal to reservation 30# - destroy the volume 31# 3. Destroy the pool 32# 4. Recreate the pool with one more disk in the vdev, then repeat steps 33# 2 and 3. 34# 5. Repeat all steps above for raidz2 and raidz3. 35# 36# NOTES: 37# 1. This test will use up to 14 disks but can cover the key concepts with 38# 5 disks. 39# 2. If the disks are a mixture of 4Kn and 512n/512e, failures are likely. 40# 41 42verify_runnable "global" 43 44typeset -a alldisks=($DISKS) 45 46# The larger the volsize, the better zvol_volsize_to_reservation() is at 47# guessing the right number. At 10M on ashift=12, the estimate may be over 26% 48# too high. 49volsize=100 50 51function cleanup 52{ 53 default_cleanup_noexit 54 default_setup_noexit "${alldisks[0]}" 55} 56 57log_assert "raidz refreservation=auto accounts for extra parity and skip blocks" 58log_onexit cleanup 59 60poolexists "$TESTPOOL" && log_must zpool destroy "$TESTPOOL" 61 62# Testing tiny block sizes on ashift=12 pools causes so much size inflation 63# that small test disks may fill before creating small volumes. However, 64# testing 512b and 1K blocks on ashift=9 pools is an ok approximation for 65# testing the problems that arise from 4K and 8K blocks on ashift=12 pools. 66bps=$(prtvtoc /dev/rdsk/${alldisks[0]} | 67 awk '$NF == "bytes/sector" { print $2; exit 0 }') 68log_must test "$bps" -eq 512 -o "$bps" -eq 4096 69case "$bps" in 70512) 71 allshifts=(9 10 17) 72 maxpct=151 73 ;; 744096) 75 allshifts=(12 13 17) 76 maxpct=110 77 ;; 78*) 79 log_fail "bytes/sector != (512|4096)" 80 ;; 81esac 82log_note "Testing in ashift=${allshifts[0]} mode" 83 84# This loop handles all iterations of steps 1 through 4 described in strategy 85# comment above, 86for parity in 1 2 3; do 87 raid=raidz$parity 88 89 # Ensure we hit scenarios with and without skip blocks 90 for ndisks in $((parity * 2)) $((parity * 2 + 1)); do 91 typeset -a disks=(${alldisks[0..$((ndisks - 1))]}) 92 93 if (( ${#disks[@]} < ndisks )); then 94 log_note "Too few disks to test $raid-$ndisks" 95 continue 96 fi 97 98 log_must zpool create "$TESTPOOL" "$raid" "${disks[@]}" 99 100 for bits in "${allshifts[@]}"; do 101 vbs=$((1 << bits)) 102 log_note "Testing $raid-$ndisks volblocksize=$vbs" 103 104 vol=$TESTPOOL/$TESTVOL 105 log_must zfs create -V ${volsize}m \ 106 -o volblocksize=$vbs "$vol" 107 log_must dd if=/dev/zero of=/dev/zvol/dsk/$vol \ 108 bs=1024k count=$volsize 109 sync 110 111 ref=$(zfs get -Hpo value referenced "$vol") 112 refres=$(zfs get -Hpo value refreservation "$vol") 113 log_must test -n "$ref" 114 log_must test -n "$refres" 115 116 typeset -F2 deltapct=$((refres * 100.0 / ref)) 117 log_note "$raid-$ndisks refreservation $refres" \ 118 "is $deltapct% of reservation $res" 119 120 log_must test "$ref" -le "$refres" 121 log_must test "$deltapct" -le $maxpct 122 123 log_must zfs destroy "$vol" 124 done 125 126 log_must zpool destroy "$TESTPOOL" 127 done 128done 129 130log_pass "raidz refreservation=auto accounts for extra parity and skip blocks" 131