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_busy 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. 66if is_freebsd; then 67 bps=$(diskinfo -v ${alldisks[0]} | awk '/sectorsize/ { print $1 }') 68elif is_linux; then 69 bps=$(lsblk -nrdo min-io /dev/${alldisks[0]}) 70fi 71log_must test "$bps" -eq 512 -o "$bps" -eq 4096 72case "$bps" in 73512) 74 allshifts=(9 10 17) 75 maxpct=151 76 ;; 774096) 78 allshifts=(12 13 17) 79 maxpct=110 80 ;; 81*) 82 log_fail "bytes/sector: $bps != (512|4096)" 83 ;; 84esac 85log_note "Testing in ashift=${allshifts[0]} mode" 86 87# This loop handles all iterations of steps 1 through 4 described in strategy 88# comment above, 89for parity in 1 2 3; do 90 raid=raidz$parity 91 92 # Ensure we hit scenarios with and without skip blocks 93 for ndisks in $((parity * 2)) $((parity * 2 + 1)); do 94 typeset -a disks=(${alldisks[0..$((ndisks - 1))]}) 95 96 if (( ${#disks[@]} < ndisks )); then 97 log_note "Too few disks to test $raid-$ndisks" 98 continue 99 fi 100 101 log_must zpool create -O compression=off "$TESTPOOL" "$raid" "${disks[@]}" 102 103 for bits in "${allshifts[@]}"; do 104 vbs=$((1 << bits)) 105 log_note "Testing $raid-$ndisks volblocksize=$vbs" 106 107 vol=$TESTPOOL/$TESTVOL 108 log_must zfs create -V ${volsize}m \ 109 -o volblocksize=$vbs "$vol" 110 block_device_wait "/dev/zvol/$vol" 111 log_must dd if=/dev/zero of=/dev/zvol/$vol \ 112 bs=1024k count=$volsize 113 sync_pool $TESTPOOL 114 115 ref=$(zfs get -Hpo value referenced "$vol") 116 refres=$(zfs get -Hpo value refreservation "$vol") 117 log_must test -n "$ref" 118 log_must test -n "$refres" 119 120 typeset -F2 deltapct=$((refres * 100.0 / ref)) 121 log_note "$raid-$ndisks refreservation $refres" \ 122 "is $deltapct% of reservation $res" 123 124 log_must test "$ref" -le "$refres" 125 log_must test "$deltapct" -le $maxpct 126 127 log_must_busy zfs destroy "$vol" 128 block_device_wait 129 done 130 131 log_must_busy zpool destroy "$TESTPOOL" 132 done 133done 134 135log_pass "raidz refreservation=auto accounts for extra parity and skip blocks" 136