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 https://opensource.org/licenses/CDDL-1.0.
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 2008 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26
27#
28# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
29#
30
31. $STF_SUITE/include/libtest.shlib
32. $STF_SUITE/tests/functional/cli_root/zfs_copies/zfs_copies.cfg
33
34#
35# Compare the value of copies property with specified value
36# $1, the dataset name
37# $2, the expected copies value
38#
39function cmp_prop
40{
41	typeset ds=$1
42	typeset	val_expect=$2
43	typeset val_actual
44
45	val_actual=$(get_prop copies $ds)
46	if [[ $val_actual != $val_expect ]]; then
47		log_fail "Expected value ($val_expect) != actual value " \
48		    "($val_actual)"
49	fi
50}
51
52#
53# Check the used space is charged correctly
54# $1, the number of used space
55# $2, the expected common factor between the used space and the file space
56#
57function check_used
58{
59	typeset charged_spc=$1
60	typeset -i used
61	typeset -i expected_cfactor=$2
62	typeset -i cfactor
63	typeset -i fsize=${FILESIZE%[m|M]}
64
65	((used = $charged_spc / 1024 / 1024))
66	((cfactor = used / fsize))
67	if ((cfactor != expected_cfactor)); then
68		log_fail "The space is not charged correctly while setting" \
69		    "copies as $expected_cfactor."
70	fi
71}
72
73#
74# test ncopies on volume
75# $1  test type zfs|ufs|ext2
76# $2  copies
77# $3  mntp for ufs|ext2 test
78function do_vol_test
79{
80	typeset type=$1
81	typeset copies=$2
82	typeset mntp=$3
83
84	vol=$TESTPOOL/$TESTVOL1
85	vol_b_path=$ZVOL_DEVDIR/$TESTPOOL/$TESTVOL1
86
87	log_must zfs create -V $VOLSIZE -o copies=$copies $vol
88	log_must zfs set refreservation=none $vol
89	block_device_wait $vol_b_path
90
91	case "$type" in
92	"ext2")
93		if is_freebsd; then
94			log_unsupported "ext2 test not implemented for freebsd"
95		fi
96		log_must eval "new_fs $vol_b_path >/dev/null 2>&1"
97		log_must mount -o rw $vol_b_path $mntp
98		;;
99	"ufs")
100		if is_linux; then
101			log_unsupported "ufs test not implemented for linux"
102		fi
103		log_must eval "new_fs $vol_b_path >/dev/null 2>&1"
104		log_must mount $vol_b_path $mntp
105		;;
106	"zfs")
107		if is_freebsd; then
108			# Pool creation on zvols is forbidden by default.
109			# Save and restore the current setting.
110			typeset _saved=$(get_tunable VOL_RECURSIVE)
111			log_must set_tunable64 VOL_RECURSIVE 1 # Allow
112			zpool create $TESTPOOL1 $vol_b_path
113			typeset _zpool_create_result=$?
114			log_must set_tunable64 VOL_RECURSIVE $_saved # Restore
115			log_must test $_zpool_create_result = 0
116		else
117			log_must zpool create $TESTPOOL1 $vol_b_path
118		fi
119		log_must zfs create $TESTPOOL1/$TESTFS1
120		;;
121	*)
122		log_unsupported "$type test not implemented"
123		;;
124	esac
125
126	((nfilesize = copies * ${FILESIZE%m}))
127	pre_used=$(get_prop used $vol)
128	((target_size = pre_used + nfilesize))
129
130	if [[ $type == "zfs" ]]; then
131		log_must mkfile $FILESIZE /$TESTPOOL1/$TESTFS1/$FILE
132	else
133		log_must mkfile $FILESIZE $mntp/$FILE
134	fi
135
136	post_used=$(get_prop used $vol)
137	((retries = 0))
138	while ((post_used < target_size && retries++ < 42)); do
139		sleep 1
140		post_used=$(get_prop used $vol)
141	done
142
143	((used = post_used - pre_used))
144	if ((used < nfilesize)); then
145		log_fail "The space is not charged correctly while setting" \
146		    "copies as $copies ($used < $nfilesize)" \
147		    "pre=${pre_used} post=${post_used}"
148	fi
149
150	if [[ $type == "zfs" ]]; then
151		log_must zpool destroy $TESTPOOL1
152	else
153		log_must umount $mntp
154	fi
155
156	log_must zfs destroy $vol
157}
158