1#!/usr/local/bin/ksh93 -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26
27. $STF_SUITE/include/libtest.kshlib
28. $STF_SUITE/tests/cli_root/zfs_destroy/zfs_destroy_common.kshlib
29
30#################################################################################
31#
32# __stc_assertion_start
33#
34# ID: zfs_destroy_005_neg
35#
36# DESCRIPTION:
37#	Separately verify 'zfs destroy -f|-r|-rf|-R|-rR <dataset>' will fail in
38#       different conditions.
39#
40# STRATEGY:
41#	1. Create pool, fs & vol.
42#	2. Create snapshot for fs & vol.
43#	3. Invoke 'zfs destroy ''|-f <dataset>', it should fail.
44#	4. Create clone for fs & vol.
45#	5. Invoke 'zfs destroy -r|-rf <dataset>', it should fail.
46#	6. Write file to filesystem or enter snapshot mountpoint.
47#	7. Invoke 'zfs destroy -R|-rR <dataset>', it should fail.
48#
49# TESTABILITY: explicit
50#
51# TEST_AUTOMATION_LEVEL: automated
52#
53# CODING_STATUS: COMPLETED (2005-08-03)
54#
55# __stc_assertion_end
56#
57################################################################################
58
59verify_runnable "both"
60
61log_assert "Separately verify 'zfs destroy -f|-r|-rf|-R|-rR <dataset>' will " \
62	"fail in different conditions."
63log_onexit cleanup_testenv
64
65#
66# Run 'zfs destroy [-rRf] <dataset>', make sure it fail.
67#
68# $1 the collection of options
69# $2 the collection of datasets
70#
71function negative_test
72{
73	typeset options=$1
74	typeset datasets=$2
75
76	for dtst in $datasets; do
77		if ! is_global_zone; then
78			if [[ $dtst == $VOL || $dtst == $VOLSNAP || \
79				$dtst == $VOLCLONE ]]
80			then
81				log_note "UNSUPPORTED: " \
82					"Volume is unavailable in LZ."
83				continue
84			fi
85		fi
86		for opt in $options; do
87			log_mustnot $ZFS destroy $opt $dtst
88		done
89	done
90}
91
92# This filesystem is created by setup.ksh, and conflicts with the filesystems
93# created from within this file
94$ZFS destroy -f $TESTPOOL/$TESTFS
95
96#
97# Create snapshots for filesystem and volume,
98# and verify 'zfs destroy' failed without '-r' or '-R'.
99#
100setup_testenv snap
101negative_test "-f" "$CTR $FS $VOL"
102
103#
104# Create clones for filesystem and volume,
105# and verify 'zfs destroy' failed without '-R'.
106#
107setup_testenv clone
108negative_test "-r -rf" "$CTR $FS $VOL"
109
110#
111# Get $FS mountpoint and make it busy, then verify 'zfs destroy $CTR'
112# failed without '-f'.
113#
114# Then verify the datasets are expected existed or non-existed.
115#
116typeset mtpt_dir=$(get_prop mountpoint $FS)
117make_dir_busy $mtpt_dir
118negative_test "-R -rR" $CTR
119
120#
121# Checking the outcome of the test above is tricky, because the order in
122# which datasets are destroyed is not deterministic. Both $FS and $VOL are
123# busy, and the remaining datasets will be different depending on whether we
124# tried (and failed) to delete $FS or $VOL first.
125
126# The following datasets will exist independent of the order
127check_dataset datasetexists $CTR $FS $VOL
128
129if datasetexists $VOLSNAP && datasetnonexists $FSSNAP; then
130	# The recursive destroy failed on $FS
131	check_dataset datasetnonexists $FSSNAP $FSCLONE
132	check_dataset datasetexists $VOLSNAP $VOLCLONE
133elif datasetexists $FSSNAP && datasetnonexists $VOLSNAP; then
134	# The recursive destroy failed on $VOL
135	check_dataset datasetnonexists $VOLSNAP $VOLCLONE
136	check_dataset datasetexists $FSSNAP $FSCLONE
137else
138	log_must zfs list -rtall
139	log_fail "Unexpected datasets remaining"
140fi
141
142#
143# Create the clones for test environment, then verify 'zfs destroy $FS'
144# failed without '-f'.
145#
146# Then verify the datasets are expected existed or non-existed.
147#
148setup_testenv clone
149negative_test "-R -rR" $FS
150check_dataset datasetexists $CTR $FS $VOL $VOLSNAP $VOLCLONE
151log_must datasetnonexists $FSSNAP $FSCLONE
152
153make_dir_unbusy $mtpt_dir
154
155if is_global_zone; then
156	#
157	# Create the clones for test environment and make the volume busy.
158	# Then verify 'zfs destroy $CTR' failed without '-f'.
159	#
160	# Then verify the datasets are expected existed or non-existed.
161	#
162	setup_testenv clone
163	make_dir_busy $TESTDIR1
164	negative_test "-R -rR" $CTR
165	log_must datasetexists $CTR $VOL
166	log_must datasetnonexists $VOLSNAP $VOLCLONE
167
168	# Here again, the non-determinism of destroy order is a factor. $FS,
169	# $FSSNAP and $FSCLONE will still exist here iff we attempted to destroy
170	# $VOL (and failed) first. So check that either all of the datasets are
171	# present, or they're all gone.
172	if datasetexists $FS; then
173		check_dataset datasetexists $FS $FSSNAP $FSCLONE
174	else
175		check_dataset datasetnonexists $FS $FSSNAP $FSCLONE
176	fi
177
178	#
179	# Create the clones for test environment and make the volume busy.
180	# Then verify 'zfs destroy $VOL' failed without '-f'.
181	#
182	# Then verify the datasets are expected existed or non-existed.
183	#
184	setup_testenv clone
185	negative_test "-R -rR" $VOL
186	log_must datasetexists $CTR $VOL $FS $FSSNAP $FSCLONE
187	log_must datasetnonexists $VOLSNAP $VOLCLONE
188
189	make_dir_unbusy $TESTDIR1
190fi
191
192#
193# Create the clones for test environment and make the snapshot busy.
194# Then verify 'zfs destroy $snap' failed without '-f'.
195#
196# Then verify the datasets are expected existed or non-existed.
197#
198snaplist="$FSSNAP"
199
200setup_testenv clone
201for snap in $snaplist; do
202	for option in -R -rR ; do
203		mtpt_dir=$(snapshot_mountpoint $snap)
204		(( $? != 0 )) && \
205			log_fail "get mountpoint $snap failed."
206
207		init_dir=$PWD
208		log_must cd $mtpt_dir
209
210		log_must $ZFS destroy $option $snap
211		check_dataset datasetexists $CTR $FS $VOL
212		if [[ $snap == $FSSNAP ]]; then
213			log_must datasetnonexists $snap $FSCLONE
214		else
215			log_must datasetnonexists $snap $VOLCLONE
216		fi
217		setup_testenv clone
218	done
219done
220
221cmds="zfs destroy -f|-r|-rf|-R|-rR <dataset>"
222log_pass "'$cmds' must fail in certain conditions."
223