aboutsummaryrefslogtreecommitdiff
path: root/tests/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_001_pos.ksh
blob: 11157e93c78dbd844695012eb9dc32fdcbca0855 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

#
# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

#
# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
#

. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy.cfg
. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy_common.kshlib

#
# DESCRIPTION:
#	'zfs destroy -r|-rf|-R|-Rf <fs|ctr|vol|snap>' should recursively destroy
#	all children and clones based on options.
#
# STRATEGY:
#	1. Create test environment according to options. There are three test
#	models can be created. Only ctr, fs & vol; with snap; with clone.
#	2. According to option, make the dataset busy or not.
#	3. Run 'zfs destroy [-rRf] <dataset>'
#	4. According to dataset and option, check if get the expected results.
#

verify_runnable "both"

#
# According to parameters, 1st, create suitable testing environment. 2nd,
# run 'zfs destroy $opt <dataset>'. 3rd, check the system status.
#
# $1 option of 'zfs destroy'
# $2 dataset will be destroyed.
#
function test_n_check
{
	typeset opt=$1
	typeset dtst=$2

	if ! is_global_zone ; then
		if [[ $dtst == $VOL || $dtst == $VOLSNAP ]]; then
			log_note "UNSUPPORTED: Volume are unavailable in LZ."
			return
		fi
	fi

	# '-f' has no effect on non-filesystems
	if [[ $opt == -f ]]; then
		if [[ $dtst != $FS ]]; then
			log_note "UNSUPPORTED: '-f ' is only available for " \
			    "leaf FS."
			return
		fi
	fi

	# Clean the test environment and make it clear.
	datasetexists $CTR && destroy_dataset $CTR -Rf

	# According to option create test compatible environment.
	case $opt in
		-r|-rf) setup_testenv snap ;;
		-R|-Rf) setup_testenv clone ;;
		-f)	setup_testenv ;;
		*)	log_fail "Incorrect option: '$opt'." ;;
	esac

	#
	# According to different dataset type, create busy condition when try to
	# destroy this dataset.
	#
	typeset mpt_dir
	case $dtst in
		$CTR|$FS)
			if [[ $opt == *f* ]]; then
				mpt_dir=$(get_prop mountpoint $FS)
				pidlist="$pidlist $(mkbusy \
				    $mpt_dir/$TESTFILE0)"
				log_note "mkbusy $mpt_dir/$TESTFILE0 " \
				    "(pidlist: $pidlist)"
				[[ -z $pidlist ]] && \
				    log_fail "Failure from mkbusy"
				log_mustnot zfs destroy -rR $dtst
			fi
			;;
		$VOL)
			if [[ $opt == *f* ]]; then
				pidlist="$pidlist $(mkbusy \
				    $TESTDIR1/$TESTFILE0)"
				log_note "mkbusy $TESTDIR1/$TESTFILE0 " \
				    "(pidlist: $pidlist)"
				[[ -z $pidlist ]] && \
				    log_fail "Failure from mkbusy"
				log_mustnot zfs destroy -rR $dtst
			fi
			;;
		$VOLSNAP)
			if [[ $opt == *f* ]]; then
				pidlist="$pidlist $(mkbusy \
				    $TESTDIR1/$TESTFILE0)"
				log_note "mkbusy $TESTDIR1/$TESTFILE0 " \
				    "(pidlist: $pidlist)"
				[[ -z $pidlist ]] && \
				    log_fail "Failure from mkbusy"
				log_must_busy zfs destroy -rR $dtst
				log_must zfs snapshot $dtst
			fi
			;;
		$FSSNAP)
			if [[ $opt == *f* ]]; then
				mpt_dir=$(snapshot_mountpoint $dtst)
				pidlist="$pidlist $(mkbusy $mpt_dir)"
				log_note "mkbusy $mpt_dir (pidlist: $pidlist)"
				[[ -z $pidlist ]] && \
				    log_fail "Failure from mkbusy"
				if is_linux ; then
					log_mustnot zfs destroy -rR $dtst
				else
					log_must zfs destroy -rR $dtst
					log_must zfs snapshot $dtst
				fi
			fi
			;;
		*)	log_fail "Unsupported dataset: '$dtst'."
	esac

	# Kill any lingering instances of mkbusy, and clear the list.
	if is_linux ; then
		[[ -z $pidlist ]] || log_must kill -TERM $pidlist
		pidlist=""
		log_mustnot pgrep -fl mkbusy
	fi

	# Firstly, umount ufs filesystem which was created by zfs volume.
	if is_global_zone; then
		log_must umount -f $TESTDIR1
	fi

	# Invoke 'zfs destroy [-rRf] <dataset>'
	log_must_busy zfs destroy $opt $dtst
	block_device_wait

	# Kill any lingering instances of mkbusy, and clear the list.
	if ! is_linux ; then
		[[ -z $pidlist ]] || log_must kill -TERM $pidlist
		pidlist=""
		log_mustnot pgrep -fl mkbusy
	fi

	case $dtst in
		$CTR)	check_dataset datasetnonexists \
					$CTR $FS $VOL $FSSNAP $VOLSNAP
			if [[ $opt == *R* ]]; then
				check_dataset datasetnonexists \
					$FSCLONE $VOLCLONE
			fi
			;;
		$FS)	check_dataset datasetexists $CTR $VOL
			check_dataset datasetnonexists $FS
			if [[ $opt != -f ]]; then
				check_dataset datasetexists $VOLSNAP
				check_dataset datasetnonexists $FSSNAP
			fi
			if [[ $opt == *R* ]]; then
				check_dataset datasetexists $VOLCLONE
				check_dataset datasetnonexists $FSCLONE
			fi
			;;
		$VOL)	check_dataset datasetexists $CTR $FS $FSSNAP
			check_dataset datasetnonexists $VOL $VOLSNAP
			if [[ $opt == *R* ]]; then
				check_dataset datasetexists $FSCLONE
				check_dataset datasetnonexists $VOLCLONE
			fi
			;;
		$FSSNAP)
			check_dataset datasetexists $CTR $FS $VOL $VOLSNAP
			check_dataset datasetnonexists $FSSNAP
			if [[ $opt == *R* ]]; then
				check_dataset datasetexists $VOLCLONE
				check_dataset datasetnonexists $FSCLONE
			fi
			;;
		$VOLSNAP)
			check_dataset datasetexists $CTR $FS $VOL $FSSNAP
			check_dataset datasetnonexists $VOLSNAP
			if [[ $opt == *R* ]]; then
				check_dataset datasetexists $FSCLONE
				check_dataset datasetnonexists $VOLCLONE
			fi
			;;
	esac

	log_note "'zfs destroy $opt $dtst' passed."
}

log_assert "'zfs destroy -r|-R|-f|-rf|-Rf <fs|ctr|vol|snap>' should " \
	"recursively destroy all children."
log_onexit cleanup_testenv

typeset dtst=""
typeset opt=""
typeset pidlist=""
for dtst in $CTR $FS $VOL $FSSNAP $VOLSNAP; do
	for opt in "-r" "-R" "-f" "-rf" "-Rf"; do
		log_note "Starting test: zfs destroy $opt $dtst"
		test_n_check $opt $dtst
	done
done

log_pass "'zfs destroy -r|-R|-f|-rf|-Rf <fs|ctr|vol|snap>' passed."