1*e716630dSMartin Matuska#!/bin/ksh -p
2*e716630dSMartin Matuska#
3*e716630dSMartin Matuska# CDDL HEADER START
4*e716630dSMartin Matuska#
5*e716630dSMartin Matuska# The contents of this file are subject to the terms of the
6*e716630dSMartin Matuska# Common Development and Distribution License (the "License").
7*e716630dSMartin Matuska# You may not use this file except in compliance with the License.
8*e716630dSMartin Matuska#
9*e716630dSMartin Matuska# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*e716630dSMartin Matuska# or http://www.opensolaris.org/os/licensing.
11*e716630dSMartin Matuska# See the License for the specific language governing permissions
12*e716630dSMartin Matuska# and limitations under the License.
13*e716630dSMartin Matuska#
14*e716630dSMartin Matuska# When distributing Covered Code, include this CDDL HEADER in each
15*e716630dSMartin Matuska# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*e716630dSMartin Matuska# If applicable, add the following below this CDDL HEADER, with the
17*e716630dSMartin Matuska# fields enclosed by brackets "[]" replaced with your own identifying
18*e716630dSMartin Matuska# information: Portions Copyright [yyyy] [name of copyright owner]
19*e716630dSMartin Matuska#
20*e716630dSMartin Matuska# CDDL HEADER END
21*e716630dSMartin Matuska#
22*e716630dSMartin Matuska
23*e716630dSMartin Matuska#
24*e716630dSMartin Matuska# Copyright (c) 2020 by vStack. All rights reserved.
25*e716630dSMartin Matuska#
26*e716630dSMartin Matuska
27*e716630dSMartin Matuska. $STF_SUITE/include/libtest.shlib
28*e716630dSMartin Matuska
29*e716630dSMartin Matuska#
30*e716630dSMartin Matuska# DESCRIPTION:
31*e716630dSMartin Matuska#	'zpool attach poolname raidz ...' should attach new device to the pool.
32*e716630dSMartin Matuska#
33*e716630dSMartin Matuska# STRATEGY:
34*e716630dSMartin Matuska#	1. Create block device files for the test raidz pool
35*e716630dSMartin Matuska#	2. For each parity value [1..3]
36*e716630dSMartin Matuska#	    - create raidz pool
37*e716630dSMartin Matuska#	    - fill it with some directories/files
38*e716630dSMartin Matuska#	    - attach device to the raidz pool
39*e716630dSMartin Matuska#	    - verify that device attached and the raidz pool size increase
40*e716630dSMartin Matuska#	    - verify resilver by replacing parity devices
41*e716630dSMartin Matuska#	    - verify resilver by replacing data devices
42*e716630dSMartin Matuska#	    - verify scrub by zeroing parity devices
43*e716630dSMartin Matuska#	    - verify scrub by zeroing data devices
44*e716630dSMartin Matuska#	    - verify the raidz pool
45*e716630dSMartin Matuska#	    - destroy the raidz pool
46*e716630dSMartin Matuska
47*e716630dSMartin Matuskatypeset -r devs=6
48*e716630dSMartin Matuskatypeset -r dev_size_mb=128
49*e716630dSMartin Matuska
50*e716630dSMartin Matuskatypeset -a disks
51*e716630dSMartin Matuska
52*e716630dSMartin Matuskaprefetch_disable=$(get_tunable PREFETCH_DISABLE)
53*e716630dSMartin Matuska
54*e716630dSMartin Matuskafunction cleanup
55*e716630dSMartin Matuska{
56*e716630dSMartin Matuska	log_pos zpool status $TESTPOOL
57*e716630dSMartin Matuska
58*e716630dSMartin Matuska	poolexists "$TESTPOOL" && log_must_busy zpool destroy "$TESTPOOL"
59*e716630dSMartin Matuska
60*e716630dSMartin Matuska	for i in {0..$devs}; do
61*e716630dSMartin Matuska		log_must rm -f "$TEST_BASE_DIR/dev-$i"
62*e716630dSMartin Matuska	done
63*e716630dSMartin Matuska
64*e716630dSMartin Matuska	log_must set_tunable32 PREFETCH_DISABLE $prefetch_disable
65*e716630dSMartin Matuska	log_must set_tunable64 RAIDZ_EXPAND_MAX_REFLOW_BYTES 0
66*e716630dSMartin Matuska}
67*e716630dSMartin Matuska
68*e716630dSMartin Matuskafunction wait_expand_paused
69*e716630dSMartin Matuska{
70*e716630dSMartin Matuska	oldcopied='0'
71*e716630dSMartin Matuska	newcopied='1'
72*e716630dSMartin Matuska	while [[ $oldcopied != $newcopied ]]; do
73*e716630dSMartin Matuska		oldcopied=$newcopied
74*e716630dSMartin Matuska		sleep 2
75*e716630dSMartin Matuska		newcopied=$(zpool status $TESTPOOL | \
76*e716630dSMartin Matuska		    grep 'copied out of' | \
77*e716630dSMartin Matuska		    awk '{print $1}')
78*e716630dSMartin Matuska		log_note "newcopied=$newcopied"
79*e716630dSMartin Matuska	done
80*e716630dSMartin Matuska	log_note "paused at $newcopied"
81*e716630dSMartin Matuska}
82*e716630dSMartin Matuska
83*e716630dSMartin Matuskafunction test_resilver # <pool> <parity> <dir>
84*e716630dSMartin Matuska{
85*e716630dSMartin Matuska	typeset pool=$1
86*e716630dSMartin Matuska	typeset nparity=$2
87*e716630dSMartin Matuska	typeset dir=$3
88*e716630dSMartin Matuska
89*e716630dSMartin Matuska	for (( i=0; i<$nparity; i=i+1 )); do
90*e716630dSMartin Matuska		log_must zpool offline $pool $dir/dev-$i
91*e716630dSMartin Matuska	done
92*e716630dSMartin Matuska
93*e716630dSMartin Matuska	log_must zpool export $pool
94*e716630dSMartin Matuska
95*e716630dSMartin Matuska	for (( i=0; i<$nparity; i=i+1 )); do
96*e716630dSMartin Matuska		log_must zpool labelclear -f $dir/dev-$i
97*e716630dSMartin Matuska	done
98*e716630dSMartin Matuska
99*e716630dSMartin Matuska	log_must zpool import -o cachefile=none -d $dir $pool
100*e716630dSMartin Matuska
101*e716630dSMartin Matuska	for (( i=0; i<$nparity; i=i+1 )); do
102*e716630dSMartin Matuska		log_must zpool replace -f $pool $dir/dev-$i
103*e716630dSMartin Matuska	done
104*e716630dSMartin Matuska
105*e716630dSMartin Matuska	log_must zpool wait -t resilver $pool
106*e716630dSMartin Matuska
107*e716630dSMartin Matuska	log_must check_pool_status $pool "errors" "No known data errors"
108*e716630dSMartin Matuska
109*e716630dSMartin Matuska	log_must zpool clear $pool
110*e716630dSMartin Matuska
111*e716630dSMartin Matuska	for (( i=$nparity; i<$nparity*2; i=i+1 )); do
112*e716630dSMartin Matuska		log_must zpool offline $pool $dir/dev-$i
113*e716630dSMartin Matuska	done
114*e716630dSMartin Matuska
115*e716630dSMartin Matuska	log_must zpool export $pool
116*e716630dSMartin Matuska
117*e716630dSMartin Matuska	for (( i=$nparity; i<$nparity*2; i=i+1 )); do
118*e716630dSMartin Matuska		log_must zpool labelclear -f $dir/dev-$i
119*e716630dSMartin Matuska	done
120*e716630dSMartin Matuska
121*e716630dSMartin Matuska	log_must zpool import -o cachefile=none -d $dir $pool
122*e716630dSMartin Matuska
123*e716630dSMartin Matuska	for (( i=$nparity; i<$nparity*2; i=i+1 )); do
124*e716630dSMartin Matuska		log_must zpool replace -f $pool $dir/dev-$i
125*e716630dSMartin Matuska	done
126*e716630dSMartin Matuska
127*e716630dSMartin Matuska	log_must zpool wait -t resilver $pool
128*e716630dSMartin Matuska
129*e716630dSMartin Matuska	log_must check_pool_status $pool "errors" "No known data errors"
130*e716630dSMartin Matuska
131*e716630dSMartin Matuska	log_must zpool clear $pool
132*e716630dSMartin Matuska}
133*e716630dSMartin Matuska
134*e716630dSMartin Matuskafunction test_scrub # <pool> <parity> <dir>
135*e716630dSMartin Matuska{
136*e716630dSMartin Matuska	typeset pool=$1
137*e716630dSMartin Matuska	typeset nparity=$2
138*e716630dSMartin Matuska	typeset dir=$3
139*e716630dSMartin Matuska	typeset combrec=$4
140*e716630dSMartin Matuska
141*e716630dSMartin Matuska	reflow_size=$(get_pool_prop allocated $pool)
142*e716630dSMartin Matuska	randbyte=$(( ((RANDOM<<15) + RANDOM) % $reflow_size ))
143*e716630dSMartin Matuska	log_must set_tunable64 RAIDZ_EXPAND_MAX_REFLOW_BYTES $randbyte
144*e716630dSMartin Matuska	log_must zpool attach $TESTPOOL ${raid}-0 $dir/dev-$devs
145*e716630dSMartin Matuska	wait_expand_paused
146*e716630dSMartin Matuska
147*e716630dSMartin Matuska	log_must zpool export $pool
148*e716630dSMartin Matuska
149*e716630dSMartin Matuska	# zero out parity disks
150*e716630dSMartin Matuska	for (( i=0; i<$nparity; i=i+1 )); do
151*e716630dSMartin Matuska		dd conv=notrunc if=/dev/zero of=$dir/dev-$i \
152*e716630dSMartin Matuska		    bs=1M seek=4 count=$(($dev_size_mb-4))
153*e716630dSMartin Matuska	done
154*e716630dSMartin Matuska
155*e716630dSMartin Matuska	log_must zpool import -o cachefile=none -d $dir $pool
156*e716630dSMartin Matuska
157*e716630dSMartin Matuska	log_must zpool scrub -w $pool
158*e716630dSMartin Matuska	log_must zpool clear $pool
159*e716630dSMartin Matuska	log_must zpool export $pool
160*e716630dSMartin Matuska
161*e716630dSMartin Matuska	# zero out parity count worth of data disks
162*e716630dSMartin Matuska	for (( i=$nparity; i<$nparity*2; i=i+1 )); do
163*e716630dSMartin Matuska		dd conv=notrunc if=/dev/zero of=$dir/dev-$i \
164*e716630dSMartin Matuska		    bs=1M seek=4 count=$(($dev_size_mb-4))
165*e716630dSMartin Matuska	done
166*e716630dSMartin Matuska
167*e716630dSMartin Matuska	log_must zpool import -o cachefile=none -d $dir $pool
168*e716630dSMartin Matuska
169*e716630dSMartin Matuska	log_must zpool scrub -w $pool
170*e716630dSMartin Matuska
171*e716630dSMartin Matuska	log_must check_pool_status $pool "errors" "No known data errors"
172*e716630dSMartin Matuska
173*e716630dSMartin Matuska	log_must zpool clear $pool
174*e716630dSMartin Matuska	log_must set_tunable64 RAIDZ_EXPAND_MAX_REFLOW_BYTES 0
175*e716630dSMartin Matuska	log_must zpool wait -t raidz_expand $TESTPOOL
176*e716630dSMartin Matuska}
177*e716630dSMartin Matuska
178*e716630dSMartin Matuskalog_onexit cleanup
179*e716630dSMartin Matuska
180*e716630dSMartin Matuskalog_must set_tunable32 PREFETCH_DISABLE 1
181*e716630dSMartin Matuska
182*e716630dSMartin Matuska# Disk files which will be used by pool
183*e716630dSMartin Matuskafor i in {0..$(($devs - 1))}; do
184*e716630dSMartin Matuska	device=$TEST_BASE_DIR/dev-$i
185*e716630dSMartin Matuska	log_must truncate -s ${dev_size_mb}M $device
186*e716630dSMartin Matuska	disks[${#disks[*]}+1]=$device
187*e716630dSMartin Matuskadone
188*e716630dSMartin Matuska
189*e716630dSMartin Matuska# Disk file which will be attached
190*e716630dSMartin Matuskalog_must truncate -s 512M $TEST_BASE_DIR/dev-$devs
191*e716630dSMartin Matuska
192*e716630dSMartin Matuskanparity=$((RANDOM%(3) + 1))
193*e716630dSMartin Matuskaraid=raidz$nparity
194*e716630dSMartin Matuskadir=$TEST_BASE_DIR
195*e716630dSMartin Matuska
196*e716630dSMartin Matuskalog_must zpool create -f -o cachefile=none $TESTPOOL $raid ${disks[@]}
197*e716630dSMartin Matuskalog_must zfs set primarycache=metadata $TESTPOOL
198*e716630dSMartin Matuska
199*e716630dSMartin Matuskalog_must zfs create $TESTPOOL/fs
200*e716630dSMartin Matuskalog_must fill_fs /$TESTPOOL/fs 1 512 100 1024 R
201*e716630dSMartin Matuska
202*e716630dSMartin Matuskalog_must zfs create -o compress=on $TESTPOOL/fs2
203*e716630dSMartin Matuskalog_must fill_fs /$TESTPOOL/fs2 1 512 100 1024 R
204*e716630dSMartin Matuska
205*e716630dSMartin Matuskalog_must zfs create -o compress=on -o recordsize=8k $TESTPOOL/fs3
206*e716630dSMartin Matuskalog_must fill_fs /$TESTPOOL/fs3 1 512 100 1024 R
207*e716630dSMartin Matuska
208*e716630dSMartin Matuskalog_must check_pool_status $TESTPOOL "errors" "No known data errors"
209*e716630dSMartin Matuska
210*e716630dSMartin Matuskatest_scrub $TESTPOOL $nparity $dir
211*e716630dSMartin Matuskatest_resilver $TESTPOOL $nparity $dir
212*e716630dSMartin Matuska
213*e716630dSMartin Matuskazpool destroy "$TESTPOOL"
214*e716630dSMartin Matuska
215*e716630dSMartin Matuskalog_pass "raidz expansion test succeeded."
216