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