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# 24*2fae26bdSAlan Somers# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25*2fae26bdSAlan Somers# Use is subject to license terms. 26*2fae26bdSAlan Somers 27*2fae26bdSAlan Somers# 28*2fae26bdSAlan Somers# Function to set the reservation property of a dataset to 29*2fae26bdSAlan Somers# 'none' and verify that it is correctly set using both the 30*2fae26bdSAlan Somers# "normal" 'zfs get reservation' and the '-p' option which 31*2fae26bdSAlan Somers# gives a numerical value. 32*2fae26bdSAlan Somers# 33*2fae26bdSAlan Somersfunction zero_reservation 34*2fae26bdSAlan Somers{ 35*2fae26bdSAlan Somers typeset resv_val 36*2fae26bdSAlan Somers dataset=$1 37*2fae26bdSAlan Somers 38*2fae26bdSAlan Somers log_must $ZFS set reservation=none $dataset 39*2fae26bdSAlan Somers log_must $ZFS set refreservation=none $dataset 40*2fae26bdSAlan Somers 41*2fae26bdSAlan Somers resv_val=`$ZFS get -H refreservation $dataset | awk '{print $3}'` 42*2fae26bdSAlan Somers if [[ $? -ne 0 ]]; then 43*2fae26bdSAlan Somers log_fail "Unable to get reservation prop on $dataset" 44*2fae26bdSAlan Somers elif [[ $resv_val != "none" ]]; then 45*2fae26bdSAlan Somers log_fail "Reservation not 'none' ($resv_val) as expected" 46*2fae26bdSAlan Somers fi 47*2fae26bdSAlan Somers 48*2fae26bdSAlan Somers 49*2fae26bdSAlan Somers resv_val=`$ZFS get -pH refreservation $dataset | awk '{print $3}'` 50*2fae26bdSAlan Somers if [[ $? -ne 0 ]]; then 51*2fae26bdSAlan Somers log_fail "Unable to get reservation prop on $dataset" 52*2fae26bdSAlan Somers elif [[ $resv_val -ne 0 ]]; then 53*2fae26bdSAlan Somers log_fail "Reservation not 0 ($resv_val) as expected" 54*2fae26bdSAlan Somers fi 55*2fae26bdSAlan Somers 56*2fae26bdSAlan Somers return 0 57*2fae26bdSAlan Somers} 58*2fae26bdSAlan Somers 59*2fae26bdSAlan Somers# 60*2fae26bdSAlan Somers# Utility function to see if two values are within a certain specified 61*2fae26bdSAlan Somers# limit of each other. Used primarily to check that a dataset's parent 62*2fae26bdSAlan Somers# is correctly accounting for space used/available. Need this function as 63*2fae26bdSAlan Somers# currently there is some slop in the way space is accounted (i.e. can't 64*2fae26bdSAlan Somers# do a direct comparison). 65*2fae26bdSAlan Somers# 66*2fae26bdSAlan Somersfunction within_limits 67*2fae26bdSAlan Somers{ 68*2fae26bdSAlan Somers typeset -l valA=$1 69*2fae26bdSAlan Somers typeset -l valB=$2 70*2fae26bdSAlan Somers typeset -l delta=$3 71*2fae26bdSAlan Somers 72*2fae26bdSAlan Somers if (( valA <= valB )); then 73*2fae26bdSAlan Somers if (( (valB - valA) <= delta )); then 74*2fae26bdSAlan Somers return 0 75*2fae26bdSAlan Somers fi 76*2fae26bdSAlan Somers elif (( valB <= valA )); then 77*2fae26bdSAlan Somers if (( (valA - valB) <= delta )); then 78*2fae26bdSAlan Somers return 0 79*2fae26bdSAlan Somers fi 80*2fae26bdSAlan Somers fi 81*2fae26bdSAlan Somers 82*2fae26bdSAlan Somers return 1 83*2fae26bdSAlan Somers} 84*2fae26bdSAlan Somers 85*2fae26bdSAlan Somers# 86*2fae26bdSAlan Somers# Function to create and mount multiple filesystems. The filesystem 87*2fae26bdSAlan Somers# will be named according to the name specified with a suffix value 88*2fae26bdSAlan Somers# taken from the loop counter. 89*2fae26bdSAlan Somers# 90*2fae26bdSAlan Somersfunction create_multiple_fs # num_fs base_fs_name base_mnt_name 91*2fae26bdSAlan Somers{ 92*2fae26bdSAlan Somers typeset -i iter=0 93*2fae26bdSAlan Somers typeset -i count=$1 94*2fae26bdSAlan Somers typeset FS_NAME=$2 95*2fae26bdSAlan Somers typeset MNT_NAME=$3 96*2fae26bdSAlan Somers 97*2fae26bdSAlan Somers while (( $iter < $count )); do 98*2fae26bdSAlan Somers log_must $ZFS create ${FS_NAME}$iter 99*2fae26bdSAlan Somers log_must $ZFS set mountpoint=${MNT_NAME}$iter ${FS_NAME}$iter 100*2fae26bdSAlan Somers (( iter = iter + 1 )) 101*2fae26bdSAlan Somers done 102*2fae26bdSAlan Somers} 103*2fae26bdSAlan Somers 104*2fae26bdSAlan Somers# 105*2fae26bdSAlan Somers# This function compute the largest volume size which is multiple of volume 106*2fae26bdSAlan Somers# block size (default 8K) and not greater than the largest expected volsize. 107*2fae26bdSAlan Somers# 108*2fae26bdSAlan Somers# $1 The largest expected volume size. 109*2fae26bdSAlan Somers# $2 The volume block size 110*2fae26bdSAlan Somers# 111*2fae26bdSAlan Somersfunction floor_volsize #<largest_volsize> [volblksize] 112*2fae26bdSAlan Somers{ 113*2fae26bdSAlan Somers typeset -l largest_volsize=$1 114*2fae26bdSAlan Somers typeset -l volblksize=${2:-8192} 115*2fae26bdSAlan Somers 116*2fae26bdSAlan Somers if (( largest_volsize < volblksize )); then 117*2fae26bdSAlan Somers log_fail "The largest_volsize must be greater than volblksize." 118*2fae26bdSAlan Somers fi 119*2fae26bdSAlan Somers typeset -l real_volsize 120*2fae26bdSAlan Somers typeset -l n 121*2fae26bdSAlan Somers 122*2fae26bdSAlan Somers (( n = largest_volsize / volblksize )) 123*2fae26bdSAlan Somers (( largest_volsize = volblksize * n )) 124*2fae26bdSAlan Somers 125*2fae26bdSAlan Somers print $largest_volsize 126*2fae26bdSAlan Somers} 127*2fae26bdSAlan Somers 128*2fae26bdSAlan Somers# 129*2fae26bdSAlan Somers# Simple function to get the expected reservation for a ZVOL given the 130*2fae26bdSAlan Somers# volume size, block size, and number of copies. 131*2fae26bdSAlan Somers# 132*2fae26bdSAlan Somers# NB: This routine must be kept in sync with the ZFS library function 133*2fae26bdSAlan Somers# libzfs_dataset.c:zvol_volsize_to_reservation(). Refer to that function 134*2fae26bdSAlan Somers# for the logic behind the calculations. 135*2fae26bdSAlan Somers# 136*2fae26bdSAlan Somersfunction zvol_volsize_to_reservation 137*2fae26bdSAlan Somers{ 138*2fae26bdSAlan Somers typeset resv_val 139*2fae26bdSAlan Somers typeset nblocks 140*2fae26bdSAlan Somers typeset numdb 141*2fae26bdSAlan Somers typeset volsize=$1 142*2fae26bdSAlan Somers typeset volblocksize=$2 143*2fae26bdSAlan Somers typeset ncopies=$3 144*2fae26bdSAlan Somers typeset ncopies_bp 145*2fae26bdSAlan Somers typeset DN_MAX_INDBLKSHIFT=17 146*2fae26bdSAlan Somers typeset SPA_BLKPTRSHIFT=7 147*2fae26bdSAlan Somers typeset SPA_DVAS_PER_BP=3 148*2fae26bdSAlan Somers typeset DVAS_PER_BP 149*2fae26bdSAlan Somers typeset DNODES_PER_LEVEL_SHIFT 150*2fae26bdSAlan Somers typeset DNODES_PER_LEVEL 151*2fae26bdSAlan Somers typeset DN_MAX_INDBLKS 152*2fae26bdSAlan Somers 153*2fae26bdSAlan Somers (( DNODES_PER_LEVEL_SHIFT = DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT )) 154*2fae26bdSAlan Somers (( DNODES_PER_LEVEL = 1 << DNODES_PER_LEVEL_SHIFT )) 155*2fae26bdSAlan Somers (( DN_MAX_INDBLKS = 1 << DN_MAX_INDBLKSHIFT )) 156*2fae26bdSAlan Somers 157*2fae26bdSAlan Somers resv_val=$volsize 158*2fae26bdSAlan Somers (( nblocks = volsize / volblocksize )) 159*2fae26bdSAlan Somers numdb=7 160*2fae26bdSAlan Somers while (( nblocks > 1 )); do 161*2fae26bdSAlan Somers (( nblocks = nblocks + DNODES_PER_LEVEL - 1 )) 162*2fae26bdSAlan Somers (( nblocks = nblocks / DNODES_PER_LEVEL )) 163*2fae26bdSAlan Somers (( numdb = numdb + nblocks )) 164*2fae26bdSAlan Somers done 165*2fae26bdSAlan Somers (( ncopies_bp = ncopies + 1 )) 166*2fae26bdSAlan Somers DVAS_PER_BP=$(min $SPA_DVAS_PER_BP $ncopies_bp) 167*2fae26bdSAlan Somers (( numdb = numdb * DVAS_PER_BP )) 168*2fae26bdSAlan Somers (( resv_val = volsize * ncopies )) 169*2fae26bdSAlan Somers (( numdb = numdb * DN_MAX_INDBLKS )) 170*2fae26bdSAlan Somers (( resv_val = resv_val + numdb )) 171*2fae26bdSAlan Somers 172*2fae26bdSAlan Somers $ECHO $resv_val 173*2fae26bdSAlan Somers return 0 174*2fae26bdSAlan Somers} 175*2fae26bdSAlan Somers 176