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