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