1#!/usr/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) 2013, 2016 by Delphix. All rights reserved.
30#
31
32. $STF_SUITE/include/libtest.shlib
33
34#
35# DESCRIPTION:
36# Turning disks in a pool offline should fail when there is no longer
37# sufficient redundancy.
38#
39# STRATEGY:
40# 1. Start some random I/O on the mirror or raidz.
41# 2. Verify that we can offline as many disks as the redundancy level
42# will support, but not more.
43# 3. Verify the integrity of the file system and the resilvering.
44#
45
46verify_runnable "global"
47
48DISKLIST=$(get_disklist $TESTPOOL)
49
50function cleanup
51{
52	#
53	# Ensure we don't leave disks in the offline state
54	#
55	for disk in $DISKLIST; do
56		log_must zpool online $TESTPOOL $disk
57		check_state $TESTPOOL $disk "online"
58		if [[ $? != 0 ]]; then
59			log_fail "Unable to online $disk"
60		fi
61
62	done
63
64	kill $killpid >/dev/null 2>&1
65	[[ -e $TESTDIR ]] && log_must rm -rf $TESTDIR/*
66}
67
68log_assert "Turning both disks offline should fail."
69
70log_onexit cleanup
71
72file_trunc -f $((64 * 1024 * 1024)) -b 8192 -c 0 -r $TESTDIR/$TESTFILE1 &
73typeset killpid="$! "
74
75disks=($DISKLIST)
76
77#
78# The setup script will give us either a mirror or a raidz. The former can have
79# all but one vdev offlined, whereas with raidz there can be only one.
80#
81pooltype='mirror'
82zpool list -v $TESTPOOL | grep raidz >/dev/null 2>&1 && pooltype='raidz'
83
84typeset -i i=0
85while [[ $i -lt ${#disks[*]} ]]; do
86	typeset -i j=0
87	if [[ $pooltype = 'mirror' ]]; then
88		# Hold one disk online, verify the others can be offlined.
89		log_must zpool online $TESTPOOL ${disks[$i]}
90		check_state $TESTPOOL ${disks[$i]} "online" || \
91		    log_fail "Failed to set ${disks[$i]} online"
92		while [[ $j -lt ${#disks[*]} ]]; do
93			if [[ $j -eq $i ]]; then
94				((j++))
95				continue
96			fi
97			log_must zpool offline $TESTPOOL ${disks[$j]}
98			check_state $TESTPOOL ${disks[$j]} "offline" || \
99			    log_fail "Failed to set ${disks[$j]} offline"
100			((j++))
101		done
102	elif [[ $pooltype = 'raidz' ]]; then
103		# Hold one disk offline, verify the others can't be offlined.
104		log_must zpool offline $TESTPOOL ${disks[$i]}
105		check_state $TESTPOOL ${disks[$i]} "offline" || \
106		    log_fail "Failed to set ${disks[$i]} offline"
107		while [[ $j -lt ${#disks[*]} ]]; do
108			if [[ $j -eq $i ]]; then
109				((j++))
110				continue
111			fi
112			log_mustnot zpool offline $TESTPOOL ${disks[$j]}
113			check_state $TESTPOOL ${disks[$j]} "online" || \
114			    log_fail "Failed to set ${disks[$j]} online"
115			check_state $TESTPOOL ${disks[$i]} "offline" || \
116			    log_fail "Failed to set ${disks[$i]} offline"
117			((j++))
118		done
119		log_must zpool online $TESTPOOL ${disks[$i]}
120		check_state $TESTPOOL ${disks[$i]} "online" || \
121		    log_fail "Failed to set ${disks[$i]} online"
122	fi
123	((i++))
124done
125
126log_must kill $killpid
127sync_all_pools
128log_must sync
129
130typeset dir=$(get_device_dir $DISKS)
131verify_filesys "$TESTPOOL" "$TESTPOOL/$TESTFS" "$dir"
132
133log_pass
134