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 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 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 if datasetexists $CTR; then 81 log_must zfs destroy -Rf $CTR 82 fi 83 84 # According to option create test compatible environment. 85 case $opt in 86 -r|-rf) setup_testenv snap ;; 87 -R|-Rf) setup_testenv clone ;; 88 -f) setup_testenv ;; 89 *) log_fail "Incorrect option: '$opt'." ;; 90 esac 91 92 # 93 # According to different dataset type, create busy condition when try to 94 # destroy this dataset. 95 # 96 typeset mpt_dir 97 case $dtst in 98 $CTR|$FS) 99 if [[ $opt == *f* ]]; then 100 mpt_dir=$(get_prop mountpoint $FS) 101 pidlist="$pidlist $(mkbusy \ 102 $mpt_dir/$TESTFILE0)" 103 log_note "mkbusy $mpt_dir/$TESTFILE0 " \ 104 "(pidlist: $pidlist)" 105 [[ -z $pidlist ]] && \ 106 log_fail "Failure from mkbusy" 107 log_mustnot zfs destroy -rR $dtst 108 fi 109 ;; 110 $VOL) 111 if [[ $opt == *f* ]]; then 112 pidlist="$pidlist $(mkbusy \ 113 $TESTDIR1/$TESTFILE0)" 114 log_note "mkbusy $TESTDIR1/$TESTFILE0 " \ 115 "(pidlist: $pidlist)" 116 [[ -z $pidlist ]] && \ 117 log_fail "Failure from mkbusy" 118 log_mustnot zfs destroy -rR $dtst 119 fi 120 ;; 121 $VOLSNAP) 122 if [[ $opt == *f* ]]; then 123 pidlist="$pidlist $(mkbusy \ 124 $TESTDIR1/$TESTFILE0)" 125 log_note "mkbusy $TESTDIR1/$TESTFILE0 " \ 126 "(pidlist: $pidlist)" 127 [[ -z $pidlist ]] && \ 128 log_fail "Failure from mkbusy" 129 log_must_busy zfs destroy -rR $dtst 130 log_must zfs snapshot $dtst 131 fi 132 ;; 133 $FSSNAP) 134 if [[ $opt == *f* ]]; then 135 mpt_dir=$(snapshot_mountpoint $dtst) 136 pidlist="$pidlist $(mkbusy $mpt_dir)" 137 log_note "mkbusy $mpt_dir (pidlist: $pidlist)" 138 [[ -z $pidlist ]] && \ 139 log_fail "Failure from mkbusy" 140 if is_linux ; then 141 log_mustnot zfs destroy -rR $dtst 142 else 143 log_must zfs destroy -rR $dtst 144 log_must zfs snapshot $dtst 145 fi 146 fi 147 ;; 148 *) log_fail "Unsupported dataset: '$dtst'." 149 esac 150 151 # Kill any lingering instances of mkbusy, and clear the list. 152 if is_linux ; then 153 [[ -z $pidlist ]] || log_must kill -TERM $pidlist 154 pidlist="" 155 log_mustnot pgrep -fl mkbusy 156 fi 157 158 # Firstly, umount ufs filesystem which was created by zfs volume. 159 if is_global_zone; then 160 log_must umount -f $TESTDIR1 161 fi 162 163 # Invoke 'zfs destroy [-rRf] <dataset>' 164 log_must_busy zfs destroy $opt $dtst 165 block_device_wait 166 167 # Kill any lingering instances of mkbusy, and clear the list. 168 if ! is_linux ; then 169 [[ -z $pidlist ]] || log_must kill -TERM $pidlist 170 pidlist="" 171 log_mustnot pgrep -fl mkbusy 172 fi 173 174 case $dtst in 175 $CTR) check_dataset datasetnonexists \ 176 $CTR $FS $VOL $FSSNAP $VOLSNAP 177 if [[ $opt == *R* ]]; then 178 check_dataset datasetnonexists \ 179 $FSCLONE $VOLCLONE 180 fi 181 ;; 182 $FS) check_dataset datasetexists $CTR $VOL 183 check_dataset datasetnonexists $FS 184 if [[ $opt != -f ]]; then 185 check_dataset datasetexists $VOLSNAP 186 check_dataset datasetnonexists $FSSNAP 187 fi 188 if [[ $opt == *R* ]]; then 189 check_dataset datasetexists $VOLCLONE 190 check_dataset datasetnonexists $FSCLONE 191 fi 192 ;; 193 $VOL) check_dataset datasetexists $CTR $FS $FSSNAP 194 check_dataset datasetnonexists $VOL $VOLSNAP 195 if [[ $opt == *R* ]]; then 196 check_dataset datasetexists $FSCLONE 197 check_dataset datasetnonexists $VOLCLONE 198 fi 199 ;; 200 $FSSNAP) 201 check_dataset datasetexists $CTR $FS $VOL $VOLSNAP 202 check_dataset datasetnonexists $FSSNAP 203 if [[ $opt == *R* ]]; then 204 check_dataset datasetexists $VOLCLONE 205 check_dataset datasetnonexists $FSCLONE 206 fi 207 ;; 208 $VOLSNAP) 209 check_dataset datasetexists $CTR $FS $VOL $FSSNAP 210 check_dataset datasetnonexists $VOLSNAP 211 if [[ $opt == *R* ]]; then 212 check_dataset datasetexists $FSCLONE 213 check_dataset datasetnonexists $VOLCLONE 214 fi 215 ;; 216 esac 217 218 log_note "'zfs destroy $opt $dtst' passed." 219} 220 221log_assert "'zfs destroy -r|-R|-f|-rf|-Rf <fs|ctr|vol|snap>' should " \ 222 "recursively destroy all children." 223log_onexit cleanup_testenv 224 225typeset dtst="" 226typeset opt="" 227typeset pidlist="" 228for dtst in $CTR $FS $VOL $FSSNAP $VOLSNAP; do 229 for opt in "-r" "-R" "-f" "-rf" "-Rf"; do 230 log_note "Starting test: zfs destroy $opt $dtst" 231 test_n_check $opt $dtst 232 done 233done 234 235log_pass "'zfs destroy -r|-R|-f|-rf|-Rf <fs|ctr|vol|snap>' passed." 236