1#!/bin/ksh -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 https://opensource.org/licenses/CDDL-1.0. 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 28# 29# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 30# 31 32. $STF_SUITE/include/libtest.shlib 33. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy.cfg 34. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy_common.kshlib 35 36# 37# DESCRIPTION: 38# 'zfs destroy -r|-rf|-R|-Rf <fs|ctr|vol|snap>' should recursively destroy 39# all children and clones based on options. 40# 41# STRATEGY: 42# 1. Create test environment according to options. There are three test 43# models can be created. Only ctr, fs & vol; with snap; with clone. 44# 2. According to option, make the dataset busy or not. 45# 3. Run 'zfs destroy [-rRf] <dataset>' 46# 4. According to dataset and option, check if get the expected results. 47# 48 49verify_runnable "both" 50 51# 52# According to parameters, 1st, create suitable testing environment. 2nd, 53# run 'zfs destroy $opt <dataset>'. 3rd, check the system status. 54# 55# $1 option of 'zfs destroy' 56# $2 dataset will be destroyed. 57# 58function test_n_check 59{ 60 typeset opt=$1 61 typeset dtst=$2 62 63 if ! is_global_zone ; then 64 if [[ $dtst == $VOL || $dtst == $VOLSNAP ]]; then 65 log_note "UNSUPPORTED: Volume are unavailable in LZ." 66 return 67 fi 68 fi 69 70 # '-f' has no effect on non-filesystems 71 if [[ $opt == -f ]]; then 72 if [[ $dtst != $FS ]]; then 73 log_note "UNSUPPORTED: '-f ' is only available for " \ 74 "leaf FS." 75 return 76 fi 77 fi 78 79 # Clean the test environment and make it clear. 80 datasetexists $CTR && destroy_dataset $CTR -Rf 81 82 # According to option create test compatible environment. 83 case $opt in 84 -r|-rf) setup_testenv snap ;; 85 -R|-Rf) setup_testenv clone ;; 86 -f) setup_testenv ;; 87 *) log_fail "Incorrect option: '$opt'." ;; 88 esac 89 90 # 91 # According to different dataset type, create busy condition when try to 92 # destroy this dataset. 93 # 94 typeset mpt_dir 95 case $dtst in 96 $CTR|$FS) 97 if [[ $opt == *f* ]]; then 98 mpt_dir=$(get_prop mountpoint $FS) 99 pidlist="$pidlist $(mkbusy \ 100 $mpt_dir/$TESTFILE0)" 101 log_note "mkbusy $mpt_dir/$TESTFILE0 " \ 102 "(pidlist: $pidlist)" 103 [[ -z $pidlist ]] && \ 104 log_fail "Failure from mkbusy" 105 log_mustnot zfs destroy -rR $dtst 106 fi 107 ;; 108 $VOL) 109 if [[ $opt == *f* ]]; then 110 pidlist="$pidlist $(mkbusy \ 111 $TESTDIR1/$TESTFILE0)" 112 log_note "mkbusy $TESTDIR1/$TESTFILE0 " \ 113 "(pidlist: $pidlist)" 114 [[ -z $pidlist ]] && \ 115 log_fail "Failure from mkbusy" 116 log_mustnot zfs destroy -rR $dtst 117 fi 118 ;; 119 $VOLSNAP) 120 if [[ $opt == *f* ]]; then 121 pidlist="$pidlist $(mkbusy \ 122 $TESTDIR1/$TESTFILE0)" 123 log_note "mkbusy $TESTDIR1/$TESTFILE0 " \ 124 "(pidlist: $pidlist)" 125 [[ -z $pidlist ]] && \ 126 log_fail "Failure from mkbusy" 127 log_must_busy zfs destroy -rR $dtst 128 log_must zfs snapshot $dtst 129 fi 130 ;; 131 $FSSNAP) 132 if [[ $opt == *f* ]]; then 133 mpt_dir=$(snapshot_mountpoint $dtst) 134 pidlist="$pidlist $(mkbusy $mpt_dir)" 135 log_note "mkbusy $mpt_dir (pidlist: $pidlist)" 136 [[ -z $pidlist ]] && \ 137 log_fail "Failure from mkbusy" 138 if is_linux ; then 139 log_mustnot zfs destroy -rR $dtst 140 else 141 log_must zfs destroy -rR $dtst 142 log_must zfs snapshot $dtst 143 fi 144 fi 145 ;; 146 *) log_fail "Unsupported dataset: '$dtst'." 147 esac 148 149 # Kill any lingering instances of mkbusy, and clear the list. 150 if is_linux ; then 151 [[ -z $pidlist ]] || log_must kill -TERM $pidlist 152 pidlist="" 153 log_mustnot pgrep -fl mkbusy 154 fi 155 156 # Firstly, umount ufs filesystem which was created by zfs volume. 157 if is_global_zone; then 158 log_must umount -f $TESTDIR1 159 fi 160 161 # Invoke 'zfs destroy [-rRf] <dataset>' 162 log_must_busy zfs destroy $opt $dtst 163 block_device_wait 164 165 # Kill any lingering instances of mkbusy, and clear the list. 166 if ! is_linux ; then 167 [[ -z $pidlist ]] || log_must kill -TERM $pidlist 168 pidlist="" 169 log_mustnot pgrep -fl mkbusy 170 fi 171 172 case $dtst in 173 $CTR) check_dataset datasetnonexists \ 174 $CTR $FS $VOL $FSSNAP $VOLSNAP 175 if [[ $opt == *R* ]]; then 176 check_dataset datasetnonexists \ 177 $FSCLONE $VOLCLONE 178 fi 179 ;; 180 $FS) check_dataset datasetexists $CTR $VOL 181 check_dataset datasetnonexists $FS 182 if [[ $opt != -f ]]; then 183 check_dataset datasetexists $VOLSNAP 184 check_dataset datasetnonexists $FSSNAP 185 fi 186 if [[ $opt == *R* ]]; then 187 check_dataset datasetexists $VOLCLONE 188 check_dataset datasetnonexists $FSCLONE 189 fi 190 ;; 191 $VOL) check_dataset datasetexists $CTR $FS $FSSNAP 192 check_dataset datasetnonexists $VOL $VOLSNAP 193 if [[ $opt == *R* ]]; then 194 check_dataset datasetexists $FSCLONE 195 check_dataset datasetnonexists $VOLCLONE 196 fi 197 ;; 198 $FSSNAP) 199 check_dataset datasetexists $CTR $FS $VOL $VOLSNAP 200 check_dataset datasetnonexists $FSSNAP 201 if [[ $opt == *R* ]]; then 202 check_dataset datasetexists $VOLCLONE 203 check_dataset datasetnonexists $FSCLONE 204 fi 205 ;; 206 $VOLSNAP) 207 check_dataset datasetexists $CTR $FS $VOL $FSSNAP 208 check_dataset datasetnonexists $VOLSNAP 209 if [[ $opt == *R* ]]; then 210 check_dataset datasetexists $FSCLONE 211 check_dataset datasetnonexists $VOLCLONE 212 fi 213 ;; 214 esac 215 216 log_note "'zfs destroy $opt $dtst' passed." 217} 218 219log_assert "'zfs destroy -r|-R|-f|-rf|-Rf <fs|ctr|vol|snap>' should " \ 220 "recursively destroy all children." 221log_onexit cleanup_testenv 222 223typeset dtst="" 224typeset opt="" 225typeset pidlist="" 226for dtst in $CTR $FS $VOL $FSSNAP $VOLSNAP; do 227 for opt in "-r" "-R" "-f" "-rf" "-Rf"; do 228 log_note "Starting test: zfs destroy $opt $dtst" 229 test_n_check $opt $dtst 230 done 231done 232 233log_pass "'zfs destroy -r|-R|-f|-rf|-Rf <fs|ctr|vol|snap>' passed." 234