1*f38cb554SJohn Wren Kennedy# 2*f38cb554SJohn Wren Kennedy# CDDL HEADER START 3*f38cb554SJohn Wren Kennedy# 4*f38cb554SJohn Wren Kennedy# The contents of this file are subject to the terms of the 5*f38cb554SJohn Wren Kennedy# Common Development and Distribution License (the "License"). 6*f38cb554SJohn Wren Kennedy# You may not use this file except in compliance with the License. 7*f38cb554SJohn Wren Kennedy# 8*f38cb554SJohn Wren Kennedy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*f38cb554SJohn Wren Kennedy# or http://www.opensolaris.org/os/licensing. 10*f38cb554SJohn Wren Kennedy# See the License for the specific language governing permissions 11*f38cb554SJohn Wren Kennedy# and limitations under the License. 12*f38cb554SJohn Wren Kennedy# 13*f38cb554SJohn Wren Kennedy# When distributing Covered Code, include this CDDL HEADER in each 14*f38cb554SJohn Wren Kennedy# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*f38cb554SJohn Wren Kennedy# If applicable, add the following below this CDDL HEADER, with the 16*f38cb554SJohn Wren Kennedy# fields enclosed by brackets "[]" replaced with your own identifying 17*f38cb554SJohn Wren Kennedy# information: Portions Copyright [yyyy] [name of copyright owner] 18*f38cb554SJohn Wren Kennedy# 19*f38cb554SJohn Wren Kennedy# CDDL HEADER END 20*f38cb554SJohn Wren Kennedy# 21*f38cb554SJohn Wren Kennedy 22*f38cb554SJohn Wren Kennedy# 23*f38cb554SJohn Wren Kennedy# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*f38cb554SJohn Wren Kennedy# Use is subject to license terms. 25*f38cb554SJohn Wren Kennedy# 26*f38cb554SJohn Wren Kennedy 27*f38cb554SJohn Wren Kennedy# 28*f38cb554SJohn Wren Kennedy# Copyright (c) 2013 by Delphix. All rights reserved. 29*f38cb554SJohn Wren Kennedy# 30*f38cb554SJohn Wren Kennedy 31*f38cb554SJohn Wren Kennedy. $STF_SUITE/tests/functional/reservation/reservation.cfg 32*f38cb554SJohn Wren Kennedy 33*f38cb554SJohn Wren Kennedy# 34*f38cb554SJohn Wren Kennedy# Function to set the reservation property of a dataset to 35*f38cb554SJohn Wren Kennedy# 'none' and verify that it is correctly set using both the 36*f38cb554SJohn Wren Kennedy# "normal" 'zfs get reservation' and the '-p' option which 37*f38cb554SJohn Wren Kennedy# gives a numerical value. 38*f38cb554SJohn Wren Kennedy# 39*f38cb554SJohn Wren Kennedyfunction zero_reservation 40*f38cb554SJohn Wren Kennedy{ 41*f38cb554SJohn Wren Kennedy typeset resv_val 42*f38cb554SJohn Wren Kennedy dataset=$1 43*f38cb554SJohn Wren Kennedy 44*f38cb554SJohn Wren Kennedy log_must $ZFS set reservation=none $dataset 45*f38cb554SJohn Wren Kennedy 46*f38cb554SJohn Wren Kennedy resv_val=`$ZFS get -H reservation $dataset | awk '{print $3}'` 47*f38cb554SJohn Wren Kennedy if [[ $? -ne 0 ]]; then 48*f38cb554SJohn Wren Kennedy log_fail "Unable to get reservation prop on $dataset" 49*f38cb554SJohn Wren Kennedy elif [[ $resv_val != "none" ]]; then 50*f38cb554SJohn Wren Kennedy log_fail "Reservation not 'none' ($resv_val) as expected" 51*f38cb554SJohn Wren Kennedy fi 52*f38cb554SJohn Wren Kennedy 53*f38cb554SJohn Wren Kennedy 54*f38cb554SJohn Wren Kennedy resv_val=`$ZFS get -pH reservation $dataset | awk '{print $3}'` 55*f38cb554SJohn Wren Kennedy if [[ $? -ne 0 ]]; then 56*f38cb554SJohn Wren Kennedy log_fail "Unable to get reservation prop on $dataset" 57*f38cb554SJohn Wren Kennedy elif [[ $resv_val -ne 0 ]]; then 58*f38cb554SJohn Wren Kennedy log_fail "Reservation not 0 ($resv_val) as expected" 59*f38cb554SJohn Wren Kennedy fi 60*f38cb554SJohn Wren Kennedy 61*f38cb554SJohn Wren Kennedy return 0 62*f38cb554SJohn Wren Kennedy} 63*f38cb554SJohn Wren Kennedy 64*f38cb554SJohn Wren Kennedy# 65*f38cb554SJohn Wren Kennedy# Utility function to see if two values are within a certain specified 66*f38cb554SJohn Wren Kennedy# limit of each other. Used primarily to check that a dataset's parent 67*f38cb554SJohn Wren Kennedy# is correctly accounting for space used/available. Need this function as 68*f38cb554SJohn Wren Kennedy# currently there is some slop in the way space is accounted (i.e. can't 69*f38cb554SJohn Wren Kennedy# do a direct comparison). 70*f38cb554SJohn Wren Kennedy# 71*f38cb554SJohn Wren Kennedyfunction within_limits 72*f38cb554SJohn Wren Kennedy{ 73*f38cb554SJohn Wren Kennedy typeset -l valA=$1 74*f38cb554SJohn Wren Kennedy typeset -l valB=$2 75*f38cb554SJohn Wren Kennedy typeset -l delta=$3 76*f38cb554SJohn Wren Kennedy 77*f38cb554SJohn Wren Kennedy if ((valA <= valB)); then 78*f38cb554SJohn Wren Kennedy if (((valB - valA) <= delta)); then 79*f38cb554SJohn Wren Kennedy return 0 80*f38cb554SJohn Wren Kennedy fi 81*f38cb554SJohn Wren Kennedy elif ((valB <= valA)); then 82*f38cb554SJohn Wren Kennedy if (((valA - valB) <= delta)); then 83*f38cb554SJohn Wren Kennedy return 0 84*f38cb554SJohn Wren Kennedy fi 85*f38cb554SJohn Wren Kennedy fi 86*f38cb554SJohn Wren Kennedy 87*f38cb554SJohn Wren Kennedy return 1 88*f38cb554SJohn Wren Kennedy} 89*f38cb554SJohn Wren Kennedy 90*f38cb554SJohn Wren Kennedy# 91*f38cb554SJohn Wren Kennedy# Function to create and mount multiple filesystems. The filesystem 92*f38cb554SJohn Wren Kennedy# will be named according to the name specified with a suffix value 93*f38cb554SJohn Wren Kennedy# taken from the loop counter. 94*f38cb554SJohn Wren Kennedy# 95*f38cb554SJohn Wren Kennedyfunction create_multiple_fs # num_fs base_fs_name base_mnt_name 96*f38cb554SJohn Wren Kennedy{ 97*f38cb554SJohn Wren Kennedy typeset -i iter=0 98*f38cb554SJohn Wren Kennedy typeset -i count=$1 99*f38cb554SJohn Wren Kennedy typeset FS_NAME=$2 100*f38cb554SJohn Wren Kennedy typeset MNT_NAME=$3 101*f38cb554SJohn Wren Kennedy 102*f38cb554SJohn Wren Kennedy while (($iter < $count)); do 103*f38cb554SJohn Wren Kennedy log_must $ZFS create ${FS_NAME}$iter 104*f38cb554SJohn Wren Kennedy log_must $ZFS set mountpoint=${MNT_NAME}$iter ${FS_NAME}$iter 105*f38cb554SJohn Wren Kennedy ((iter = iter + 1)) 106*f38cb554SJohn Wren Kennedy done 107*f38cb554SJohn Wren Kennedy} 108*f38cb554SJohn Wren Kennedy 109*f38cb554SJohn Wren Kennedy# 110*f38cb554SJohn Wren Kennedy# This function compute the largest volume size which is multiple of volume 111*f38cb554SJohn Wren Kennedy# block size (default 8K) and not greater than the largest expected volsize. 112*f38cb554SJohn Wren Kennedy# 113*f38cb554SJohn Wren Kennedy# $1 The largest expected volume size. 114*f38cb554SJohn Wren Kennedy# $2 The volume block size 115*f38cb554SJohn Wren Kennedy# 116*f38cb554SJohn Wren Kennedyfunction floor_volsize #<largest_volsize> [volblksize] 117*f38cb554SJohn Wren Kennedy{ 118*f38cb554SJohn Wren Kennedy typeset -l largest_volsize=$1 119*f38cb554SJohn Wren Kennedy typeset -l volblksize=${2:-8192} 120*f38cb554SJohn Wren Kennedy 121*f38cb554SJohn Wren Kennedy if ((largest_volsize < volblksize)); then 122*f38cb554SJohn Wren Kennedy log_fail "The largest_volsize must be greater than volblksize." 123*f38cb554SJohn Wren Kennedy fi 124*f38cb554SJohn Wren Kennedy typeset -l real_volsize 125*f38cb554SJohn Wren Kennedy typeset -l n 126*f38cb554SJohn Wren Kennedy 127*f38cb554SJohn Wren Kennedy ((n = largest_volsize / volblksize)) 128*f38cb554SJohn Wren Kennedy ((largest_volsize = volblksize * n)) 129*f38cb554SJohn Wren Kennedy 130*f38cb554SJohn Wren Kennedy print $largest_volsize 131*f38cb554SJohn Wren Kennedy} 132*f38cb554SJohn Wren Kennedy 133*f38cb554SJohn Wren Kennedy# 134*f38cb554SJohn Wren Kennedy# This function is a copy of a function by the same name in libzfs_dataset.c 135*f38cb554SJohn Wren Kennedy# Its purpose is to reserve additional space for volume metadata so volumes 136*f38cb554SJohn Wren Kennedy# don't unexpectedly run out of room. 137*f38cb554SJohn Wren Kennedy# 138*f38cb554SJohn Wren Kennedy# Note: This function can be used to do an estimate for a volume that has not 139*f38cb554SJohn Wren Kennedy# yet been created. In this case, $vol is not a volume, but rather a pool in 140*f38cb554SJohn Wren Kennedy# which a volume is going to be created. In this case, use default properties. 141*f38cb554SJohn Wren Kennedy# 142*f38cb554SJohn Wren Kennedyfunction volsize_to_reservation 143*f38cb554SJohn Wren Kennedy{ 144*f38cb554SJohn Wren Kennedy typeset vol=$1 145*f38cb554SJohn Wren Kennedy typeset -i volsize=$2 146*f38cb554SJohn Wren Kennedy 147*f38cb554SJohn Wren Kennedy typeset -i DN_MAX_INDBLKSHIFT=14 148*f38cb554SJohn Wren Kennedy typeset -i SPA_BLKPTRSHIFT=7 149*f38cb554SJohn Wren Kennedy typeset -i SPA_DVAS_PER_BP=3 150*f38cb554SJohn Wren Kennedy 151*f38cb554SJohn Wren Kennedy typeset -i DNODES_PER_LEVEL_SHIFT=$((DN_MAX_INDBLKSHIFT - \ 152*f38cb554SJohn Wren Kennedy SPA_BLKPTRSHIFT)) 153*f38cb554SJohn Wren Kennedy typeset -i DNODES_PER_LEVEL=$((1 << $DNODES_PER_LEVEL_SHIFT)) 154*f38cb554SJohn Wren Kennedy 155*f38cb554SJohn Wren Kennedy if ds_is_volume $vol; then 156*f38cb554SJohn Wren Kennedy typeset -i ncopies=$(get_prop copies $vol) 157*f38cb554SJohn Wren Kennedy typeset -i volblocksize=$(get_prop volblocksize $vol) 158*f38cb554SJohn Wren Kennedy else 159*f38cb554SJohn Wren Kennedy typeset -i ncopies=1 160*f38cb554SJohn Wren Kennedy typeset -i volblocksize=8192 161*f38cb554SJohn Wren Kennedy fi 162*f38cb554SJohn Wren Kennedy typeset -i nblocks=$((volsize / volblocksize)) 163*f38cb554SJohn Wren Kennedy 164*f38cb554SJohn Wren Kennedy typeset -i numdb=7 165*f38cb554SJohn Wren Kennedy while ((nblocks > 1)); do 166*f38cb554SJohn Wren Kennedy ((nblocks += DNODES_PER_LEVEL - 1)) 167*f38cb554SJohn Wren Kennedy ((nblocks /= DNODES_PER_LEVEL)) 168*f38cb554SJohn Wren Kennedy ((numdb += nblocks)) 169*f38cb554SJohn Wren Kennedy done 170*f38cb554SJohn Wren Kennedy 171*f38cb554SJohn Wren Kennedy ((numdb *= SPA_DVAS_PER_BP < ncopies + 1 ? SPA_DVAS_PER_BP : \ 172*f38cb554SJohn Wren Kennedy ncopies + 1)) 173*f38cb554SJohn Wren Kennedy ((volsize *= ncopies)) 174*f38cb554SJohn Wren Kennedy ((numdb *= 1 << DN_MAX_INDBLKSHIFT)) 175*f38cb554SJohn Wren Kennedy ((volsize += numdb)) 176*f38cb554SJohn Wren Kennedy echo $volsize 177*f38cb554SJohn Wren Kennedy} 178*f38cb554SJohn Wren Kennedy 179*f38cb554SJohn Wren Kennedy# 180*f38cb554SJohn Wren Kennedy# This function takes a pool name as an argument, and returns the largest (give 181*f38cb554SJohn Wren Kennedy# or take some slop) -V value that can be used to create a volume in that pool. 182*f38cb554SJohn Wren Kennedy# This is necessary because during volume creation, a reservation is created 183*f38cb554SJohn Wren Kennedy# that will be larger than the value specified with -V, and potentially larger 184*f38cb554SJohn Wren Kennedy# than the available space in the pool. See volsize_to_reservation(). 185*f38cb554SJohn Wren Kennedy# 186*f38cb554SJohn Wren Kennedyfunction largest_volsize_from_pool 187*f38cb554SJohn Wren Kennedy{ 188*f38cb554SJohn Wren Kennedy typeset pool=$1 189*f38cb554SJohn Wren Kennedy typeset -i poolsize=$(get_prop available $pool) 190*f38cb554SJohn Wren Kennedy typeset -i volsize=$poolsize 191*f38cb554SJohn Wren Kennedy typeset -i nvolsize 192*f38cb554SJohn Wren Kennedy 193*f38cb554SJohn Wren Kennedy while :; do 194*f38cb554SJohn Wren Kennedy # knock 50M off the volsize each time through 195*f38cb554SJohn Wren Kennedy ((volsize -= 50 * 1024 * 1024)) 196*f38cb554SJohn Wren Kennedy nvolsize=$(volsize_to_reservation $pool $volsize) 197*f38cb554SJohn Wren Kennedy nvolsize=$(floor_volsize $nvolsize) 198*f38cb554SJohn Wren Kennedy ((nvolsize < poolsize)) && break 199*f38cb554SJohn Wren Kennedy done 200*f38cb554SJohn Wren Kennedy echo $volsize 201*f38cb554SJohn Wren Kennedy} 202