1# vim: filetype=sh 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# $FreeBSD$ 24 25# 26# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 27# Use is subject to license terms. 28# 29# ident "@(#)reservation.kshlib 1.3 09/01/12 SMI" 30# 31 32# 33# Function to set the reservation property of a dataset to 34# 'none' and verify that it is correctly set using both the 35# "normal" 'zfs get reservation' and the '-p' option which 36# gives a numerical value. 37# 38function zero_reservation 39{ 40 typeset resv_val 41 dataset=$1 42 43 log_must $ZFS set reservation=none $dataset 44 log_must $ZFS set refreservation=none $dataset 45 46 resv_val=`$ZFS get -H refreservation $dataset | awk '{print $3}'` 47 if [[ $? -ne 0 ]]; then 48 log_fail "Unable to get reservation prop on $dataset" 49 elif [[ $resv_val != "none" ]]; then 50 log_fail "Reservation not 'none' ($resv_val) as expected" 51 fi 52 53 54 resv_val=`$ZFS get -pH refreservation $dataset | awk '{print $3}'` 55 if [[ $? -ne 0 ]]; then 56 log_fail "Unable to get reservation prop on $dataset" 57 elif [[ $resv_val -ne 0 ]]; then 58 log_fail "Reservation not 0 ($resv_val) as expected" 59 fi 60 61 return 0 62} 63 64# 65# Utility function to see if two values are within a certain specified 66# limit of each other. Used primarily to check that a dataset's parent 67# is correctly accounting for space used/available. Need this function as 68# currently there is some slop in the way space is accounted (i.e. can't 69# do a direct comparison). 70# 71function within_limits 72{ 73 typeset -l valA=$1 74 typeset -l valB=$2 75 typeset -l delta=$3 76 77 if (( valA <= valB )); then 78 if (( (valB - valA) <= delta )); then 79 return 0 80 fi 81 elif (( valB <= valA )); then 82 if (( (valA - valB) <= delta )); then 83 return 0 84 fi 85 fi 86 87 return 1 88} 89 90# 91# Function to create and mount multiple filesystems. The filesystem 92# will be named according to the name specified with a suffix value 93# taken from the loop counter. 94# 95function create_multiple_fs # num_fs base_fs_name base_mnt_name 96{ 97 typeset -i iter=0 98 typeset -i count=$1 99 typeset FS_NAME=$2 100 typeset MNT_NAME=$3 101 102 while (( $iter < $count )); do 103 log_must $ZFS create ${FS_NAME}$iter 104 log_must $ZFS set mountpoint=${MNT_NAME}$iter ${FS_NAME}$iter 105 (( iter = iter + 1 )) 106 done 107} 108 109# 110# This function compute the largest volume size which is multiple of volume 111# block size (default 8K) and not greater than the largest expected volsize. 112# 113# $1 The largest expected volume size. 114# $2 The volume block size 115# 116function floor_volsize #<largest_volsize> [volblksize] 117{ 118 typeset -l largest_volsize=$1 119 typeset -l volblksize=${2:-8192} 120 121 if (( largest_volsize < volblksize )); then 122 log_fail "The largest_volsize must be greater than volblksize." 123 fi 124 typeset -l real_volsize 125 typeset -l n 126 127 (( n = largest_volsize / volblksize )) 128 (( largest_volsize = volblksize * n )) 129 130 print $largest_volsize 131} 132 133# 134# Simple function to get the expected reservation for a ZVOL given the 135# volume size, block size, and number of copies. 136# 137# NB: This routine must be kept in sync with the ZFS library function 138# libzfs_dataset.c:zvol_volsize_to_reservation(). Refer to that function 139# for the logic behind the calculations. 140# 141function zvol_volsize_to_reservation 142{ 143 typeset resv_val 144 typeset nblocks 145 typeset numdb 146 typeset volsize=$1 147 typeset volblocksize=$2 148 typeset ncopies=$3 149 typeset ncopies_bp 150 typeset DN_MAX_INDBLKSHIFT=17 151 typeset SPA_BLKPTRSHIFT=7 152 typeset SPA_DVAS_PER_BP=3 153 typeset DVAS_PER_BP 154 typeset DNODES_PER_LEVEL_SHIFT 155 typeset DNODES_PER_LEVEL 156 typeset DN_MAX_INDBLKS 157 158 (( DNODES_PER_LEVEL_SHIFT = DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT )) 159 (( DNODES_PER_LEVEL = 1 << DNODES_PER_LEVEL_SHIFT )) 160 (( DN_MAX_INDBLKS = 1 << DN_MAX_INDBLKSHIFT )) 161 162 resv_val=$volsize 163 (( nblocks = volsize / volblocksize )) 164 numdb=7 165 while (( nblocks > 1 )); do 166 (( nblocks = nblocks + DNODES_PER_LEVEL - 1 )) 167 (( nblocks = nblocks / DNODES_PER_LEVEL )) 168 (( numdb = numdb + nblocks )) 169 done 170 (( ncopies_bp = ncopies + 1 )) 171 DVAS_PER_BP=$(min $SPA_DVAS_PER_BP $ncopies_bp) 172 (( numdb = numdb * DVAS_PER_BP )) 173 (( resv_val = volsize * ncopies )) 174 (( numdb = numdb * DN_MAX_INDBLKS )) 175 (( resv_val = resv_val + numdb )) 176 177 $ECHO $resv_val 178 return 0 179} 180 181