xref: /freebsd/tests/sys/cddl/zfs/tests/reservation/reservation.kshlib (revision ac00d4d59b18a76c6148ca5d7439bb446d38da5c)
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