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