1#
2# CDDL HEADER START
3#
4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
7#
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or http://www.opensolaris.org/os/licensing.
10# See the License for the specific language governing permissions
11# and limitations under the License.
12#
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
18#
19# CDDL HEADER END
20#
21
22#
23# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26
27#
28# Copyright (c) 2013, 2016 by Delphix. All rights reserved.
29#
30
31. $STF_SUITE/include/libtest.shlib
32
33export USEDTEST=$TESTPOOL/$TESTFS/usedtest-snapused
34
35function _check_used # dataset
36{
37        typeset dataset=$1
38
39	if [[ "$(get_prop type $dataset)" == "snapshot" ]]; then
40		return
41	fi
42
43	used=$(get_prop used $dataset)
44	usedbychildren=$(get_prop usedbychildren $dataset)
45	usedbydataset=$(get_prop usedbydataset $dataset)
46	usedbyrefreservation=$(get_prop usedbyrefreservation $dataset)
47	usedbysnapshots=$(get_prop usedbysnapshots $dataset)
48	((used_sum = usedbychildren + usedbydataset + \
49		usedbyrefreservation + usedbysnapshots))
50	if ((used != used_sum)); then
51		log_fail "$dataset: used($used) is not the sum($used_sum) of usedby*"
52	fi
53}
54
55function check_used # dataset
56{
57	typeset dataset=$1
58	for child in $(zfs list -rH -t filesystem,volume -o name $dataset)
59	do
60		_check_used $child
61	done
62}
63
64function check_usedbychildren # dataset
65{
66	typeset dataset=$1
67	typeset -i usedbychildren_sum=0
68	typeset -i parent_usedbychildren=0
69	for child in $(zfs list -rH -t filesystem,volume -o name $dataset)
70	do
71		if [[ "$(get_prop type $child)" == "snapshot" ]]; then
72			continue
73		fi
74
75		# parent
76		if [[ "$child" == "$dataset" ]]; then
77			parent_usedbychildren=$(get_prop usedbychildren $child)
78		else #child
79			reservation=$(get_prop reservation $child)
80			used=$(get_prop used $child)
81			if ((reservation > used)); then
82				((usedbychildren_sum += reservation))
83			else
84				((usedbychildren_sum += used))
85			fi
86		fi
87	done
88
89        if ((parent_usedbychildren != usedbychildren_sum)); then
90                log_fail "$dataset: usedbychildren($parent_usedbychildren) is not the sum($usedbychildren_sum) of used by children"
91        fi
92}
93
94function _check_usedbydataset # dataset
95{
96        typeset dataset=$1
97	if [[ "$(get_prop type $dataset)" == "snapshot" ]]; then
98		return
99	fi
100
101	usedbydataset=$(get_prop usedbydataset $dataset)
102	referenced=$(get_prop referenced $dataset)
103
104	is_cloned=$(get_prop is:cloned $dataset)
105
106	if [[ "$is_cloned" == "yes" ]]; then
107		if ((usedbydataset > referenced)); then
108			log_fail "$dataset(cloned): usedbydataset($usedbydataset) is more than referenced($referenced)"
109		fi
110	else
111		#
112		# if non-clones, should usedbydataset == referenced
113		#
114		if ((usedbydataset != referenced)); then
115			log_fail "$dataset: usedbydataset($usedbydataset) is not equal to referenced($referenced)"
116		fi
117	fi
118}
119
120function check_usedbydataset # dataset
121{
122	typeset dataset=$1
123	for child in $(zfs list -rH -t filesystem,volume -o name $dataset)
124	do
125		_check_usedbydataset $child
126	done
127}
128
129function _check_usedbyrefreservation # dataset
130{
131        typeset dataset=$1
132	if [[ "$(get_prop type $dataset)" == "snapshot" ]]; then
133		return
134	fi
135
136	usedbyrefreservation=$(get_prop usedbyrefreservation $dataset)
137	referenced=$(get_prop referenced $dataset)
138	refreservation=$(get_prop refreservation $dataset)
139	((diff_ref = refreservation - referenced))
140	if ((usedbyrefreservation > refreservation || \
141		usedbyrefreservation < diff_ref)); then
142		log_fail "$dataset: usedbyrefreservation($usedbyrefreservation) checking is not ok"
143	fi
144}
145
146function check_usedbyrefreservation # dataset
147{
148	typeset dataset=$1
149	for child in $(zfs list -rH -t filesystem,volume -o name $dataset)
150	do
151		_check_usedbyrefreservation $child
152	done
153}
154
155function check_usedbysnapshots # dataset
156{
157	typeset dataset=$1
158	typeset -i usedbysnapshots_sum=0
159	typeset -i parent_usedbysnapshots=0
160	for child in $(zfs list -rH -t filesystem,volume,snapshot -o name $dataset)
161	do
162		# parent
163		if [[ "$child" == "$dataset" ]]; then
164			parent_usedbysnapshots=$(get_prop usedbysnapshots $child)
165			continue
166		fi
167
168		if [[ "$(get_prop type $child)" != "snapshot" ]]; then
169			continue
170		fi
171
172		if [[ "$child" != "$dataset@"* ]]; then
173			continue
174		fi
175
176		# snapshot
177		used=$(get_prop used $child)
178		((usedbysnapshots_sum += used))
179	done
180
181        if ((parent_usedbysnapshots < usedbysnapshots_sum)); then
182                log_fail "$dataset: usedbysnapshots($parent_usedbysnapshots) is not more than or equal to" \
183				"the sum($usedbysnapshots_sum) of used of snapshots"
184        fi
185}
186