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 2007 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_mount/zfs_mount.kshlib
34. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
35
36#
37# DESCRIPTION:
38#	Once a pool has been exported, and one or more devices are
39#	damaged or missing (d/m), import should handle this kind of situation
40#	as described:
41#		- Regular, report error while any number of devices failing.
42#		- Mirror could withstand (N-1) devices failing
43#		  before data integrity is compromised
44#		- Raidz could withstand one devices failing
45#		  before data integrity is compromised
46#	Verify those are true.
47#
48# STRATEGY:
49#	1. Create test pool upon device files using the various combinations.
50#		- Regular pool
51#		- Mirror
52#		- Raidz
53#	2. Create necessary filesystem and test files.
54#	3. Export the test pool.
55#	4. Remove one or more devices
56#	5. Verify 'zpool import' will handle d/m device successfully.
57#	   Using the various combinations.
58#		- Regular import
59#		- Alternate Root Specified
60#	   It should succeed with single d/m device upon 'raidz', 'mirror',
61#	   'draid' but failed against 'regular' or more d/m devices.
62#	6. If import succeed, verify following is true:
63#		- The pool shows up under 'zpool list'.
64#		- The pool's health should be DEGRADED.
65#		- It contains the correct test file
66#
67
68verify_runnable "global"
69
70# Randomly test a subset of combinations to speed up the test.
71(( rc=RANDOM % 3 ))
72if [[ $rc == 0 ]] ; then
73	set -A vdevs "" "mirror" "raidz"
74elif [[ $rc == 1 ]] ; then
75	set -A vdevs "" "mirror" "draid"
76else
77	set -A vdevs "" "raidz" "draid"
78fi
79
80set -A options "" "-R $ALTER_ROOT"
81
82function cleanup
83{
84	# recover the vdevs
85	recreate_files
86
87	[[ -d $ALTER_ROOT ]] && \
88		log_must rm -rf $ALTER_ROOT
89}
90
91function recreate_files
92{
93	if poolexists "$TESTPOOL1" ; then
94		cleanup_filesystem $TESTPOOL1 $TESTFS
95		destroy_pool $TESTPOOL1
96	fi
97
98	log_must rm -rf $DEVICE_DIR/*
99	typeset i=0
100	while (( i < $MAX_NUM )); do
101		log_must rm -f ${DEVICE_DIR}/${DEVICE_FILE}$i
102		log_must truncate -s $FILE_SIZE ${DEVICE_DIR}/${DEVICE_FILE}$i
103		((i += 1))
104	done
105}
106
107log_onexit cleanup
108
109log_assert "Verify that import could handle damaged or missing device."
110
111CWD=$PWD
112cd $DEVICE_DIR || log_fail "Unable change directory to $DEVICE_DIR"
113
114read -r checksum1 _ < <(cksum $MYTESTFILE)
115
116typeset -i i=0
117typeset -i j=0
118typeset -i count=0
119typeset basedir backup
120
121while (( i < ${#vdevs[*]} )); do
122
123	setup_filesystem "$DEVICE_FILES" \
124		$TESTPOOL1 $TESTFS $TESTDIR1 \
125		"" ${vdevs[i]}
126
127	backup=""
128
129	guid=$(get_config $TESTPOOL1 pool_guid)
130	log_must cp $MYTESTFILE $TESTDIR1/$TESTFILE0
131
132	log_must zfs umount $TESTDIR1
133
134	j=0
135	while (( j <  ${#options[*]} )); do
136
137		count=0
138		action=log_must
139
140		#
141		# Restore all device files.
142		#
143		[[ -n $backup ]] && \
144			log_must tar xf $DEVICE_DIR/$DEVICE_ARCHIVE
145
146		for device in $DEVICE_FILES ; do
147			log_must rm -f $device
148
149			poolexists $TESTPOOL1 && \
150				log_must zpool export $TESTPOOL1
151
152			#
153			# Backup all device files while filesystem prepared.
154			#
155			if [[ -z $backup ]]; then
156				log_must tar cf $DEVICE_DIR/$DEVICE_ARCHIVE \
157					${DEVICE_FILE}*
158				backup="true"
159			fi
160
161			(( count = count + 1 ))
162
163			case "${vdevs[i]}" in
164				'mirror') (( count == $GROUP_NUM )) && \
165						action=log_mustnot
166					;;
167				'raidz')  (( count > 1 )) && \
168						action=log_mustnot
169					;;
170				'draid')  (( count > 1 )) && \
171						action=log_mustnot
172					;;
173				'')  action=log_mustnot
174					;;
175			esac
176
177			typeset target=$TESTPOOL1
178			if (( RANDOM % 2 == 0 )) ; then
179				target=$guid
180				log_note "Import by guid."
181			fi
182			$action zpool import \
183				-d $DEVICE_DIR ${options[j]} $target
184
185			[[ $action == "log_mustnot" ]] && continue
186
187			log_must poolexists $TESTPOOL1
188
189			health=$(zpool list -H -o health $TESTPOOL1)
190
191			[[ $health == "DEGRADED" ]] || \
192				log_fail "$TESTPOOL1: Incorrect health($health)"
193			log_must ismounted $TESTPOOL1/$TESTFS
194
195			basedir=$TESTDIR1
196			[[ -n ${options[j]} ]] && \
197				basedir=$ALTER_ROOT/$TESTDIR1
198
199			[[ ! -e $basedir/$TESTFILE0 ]] && \
200				log_fail "$basedir/$TESTFILE0 missing after import."
201
202			read -r checksum2 _ < <(cksum $basedir/$TESTFILE0)
203			log_must [ "$checksum1" = "$checksum2" ]
204		done
205
206		((j = j + 1))
207	done
208
209	recreate_files
210
211	((i = i + 1))
212done
213
214log_pass "Import could handle damaged or missing device."
215