xref: /freebsd/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.kshlib (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1# SPDX-License-Identifier: CDDL-1.0
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source.  A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11#
12
13#
14# Copyright (c) 2016 by Delphix. All rights reserved.
15# Copyright (c) 2023 by Klara, Inc.
16#
17
18. $STF_SUITE/include/libtest.shlib
19. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
20
21#
22# Prototype cleanup function for zpool_import tests.
23#
24function cleanup
25{
26	# clear any remaining zinjections
27	log_must eval "zinject -c all > /dev/null"
28
29	destroy_pool $TESTPOOL1
30
31	log_must rm -f $CPATH $CPATHBKP $CPATHBKP2 $MD5FILE $MD5FILE2
32
33	log_must rm -rf $DEVICE_DIR/*
34	typeset i=0
35	while (( i < $MAX_NUM )); do
36		log_must truncate -s $FILE_SIZE ${DEVICE_DIR}/${DEVICE_FILE}$i
37		((i += 1))
38	done
39	is_linux && set_tunable32 TXG_HISTORY 0
40}
41
42#
43# Write a bit of data and sync several times.
44# This function is intended to be used by zpool rewind tests.
45#
46function sync_some_data_a_few_times
47{
48	typeset pool=$1
49	typeset -i a_few_times=${2:-10}
50
51	typeset file="/$pool/tmpfile"
52	for i in {0..$a_few_times}; do
53		dd if=/dev/urandom of=${file}_$i bs=128k count=10
54		sync_pool "$pool"
55	done
56
57	return 0
58}
59
60#
61# Just write a moderate amount of data to the pool.
62#
63function write_some_data
64{
65	typeset pool=$1
66	typeset files10mb=${2:-10}
67
68	typeset ds="$pool/fillerds"
69	zfs create $ds || return 1
70
71	# Create 100 MB of data
72	typeset file="/$ds/fillerfile"
73	for i in {1..$files10mb}; do
74		dd if=/dev/urandom of=$file.$i bs=128k count=80 || return 1
75	done
76}
77
78#
79# Create/overwrite a few datasets with files.
80# Checksum all the files and store digests in a file.
81#
82# newdata: overwrite existing files if false.
83# hashfile: file where to store xxh128 digests
84# datasetname: base name for datasets
85#
86function _generate_data_common
87{
88	typeset pool=$1
89	typeset newdata=$2
90	typeset hashfile=$3
91	typeset datasetname=$4
92
93	typeset -i datasets=3
94	typeset -i files=5
95	typeset -i blocks=10
96
97	[[ -n $hashfile ]] && rm -f $hashfile
98	for i in {1..$datasets}; do
99		( $newdata ) && log_must zfs create "$pool/$datasetname$i"
100		for j in {1..$files}; do
101			typeset file="/$pool/$datasetname$i/file$j"
102			dd if=/dev/urandom of=$file bs=128k count=$blocks > /dev/null
103			if [[ -n $hashfile ]]; then
104				typeset cksum=$(xxh128digest $file)
105				echo $cksum $file >> $hashfile
106			fi
107		done
108		( $newdata ) && sync_pool "$pool"
109	done
110
111	return 0
112}
113
114function generate_data
115{
116	typeset pool=$1
117	typeset hashfile="$2"
118	typeset datasetname=${3:-ds}
119
120	_generate_data_common $pool true "$hashfile" $datasetname
121}
122
123function overwrite_data
124{
125	typeset pool=$1
126	typeset hashfile="$2"
127	typeset datasetname=${3:-ds}
128
129	_generate_data_common $1 false "$hashfile" $datasetname
130}
131
132#
133# Verify hashsums of every file in hashsum file $1.
134#
135function verify_data_hashsums
136{
137	typeset hashfile=$1
138
139	if [[ ! -f $hashfile ]]; then
140		log_note "md5 sums file '$hashfile' doesn't exist"
141		return 1
142	fi
143
144	while read -r digest file; do
145		typeset digest1=$(xxh128digest $file)
146		if [[ "$digest1" != "$digest" ]]; then
147			return 1
148		fi
149	done < $hashfile
150
151	return 0
152}
153
154#
155# Set devices size in DEVICE_DIR to $1.
156#
157function increase_device_sizes
158{
159	typeset newfilesize=$1
160
161	typeset -i i=0
162	while (( i < $MAX_NUM )); do
163		log_must truncate -s $newfilesize ${DEVICE_DIR}/${DEVICE_FILE}$i
164		((i += 1))
165	done
166}
167
168#
169# Translate vdev names returned by zpool status into more generic names.
170#
171function _translate_vdev
172{
173	typeset vdev=$1
174
175	#
176	# eg: mirror-2 --> mirror
177	# eg: draid2:4d:12c:1s-0 --> draid2
178	#
179	typeset keywords="mirror replacing raidz1 raidz2 raidz3 indirect draid1 draid2 draid3"
180	for word in $keywords; do
181		if echo $vdev |
182		    grep -qE  "^${word}-[0-9]+\$|^${word}:[0-9]+d:[0-9]c:[0-9]+s-[0-9]+\$"
183		then
184			vdev=$word
185			break
186		fi
187	done
188
189	case "$vdev" in
190		logs) echo "log" ;;
191		raidz1) echo "raidz" ;;
192		draid1) echo "draid" ;;
193		*) echo $vdev ;;
194	esac
195}
196
197#
198# Check that pool configuration returned by zpool status matches expected
199# configuration. Format for the check string is same as the vdev arguments for
200# creating a pool
201# Add -q for quiet mode.
202#
203# eg: check_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0 log c1t1d0s0"
204#
205function check_pool_config
206{
207	typeset logfailure=true
208	if [[ $1 == '-q' ]]; then
209		logfailure=false
210		shift
211	fi
212
213	typeset poolname=$1
214	typeset expected=$2
215
216	typeset status
217	if ! status=$(zpool status $poolname 2>&1); then
218		if $logfailure; then
219			log_note "zpool status $poolname failed: $status"
220		fi
221		return 1
222	fi
223
224	typeset actual=""
225	typeset began=false
226	while read -r vdev _; do
227		if ( ! $began ) && [[ $vdev == NAME ]]; then
228			began=true
229			continue
230		fi
231		( $began ) && [[ -z $vdev ]] && break;
232
233		if ( $began ); then
234			[[ -z $actual ]] && actual="$vdev" && continue
235			vdev=$(_translate_vdev $vdev)
236			actual="$actual $vdev"
237		fi
238	done <<<"$status"
239
240	expected="$poolname $expected"
241
242	if [[ "$actual" != "$expected" ]]; then
243		if $logfailure; then
244			log_note "expected pool vdevs:"
245			log_note "> '$expected'"
246			log_note "actual pool vdevs:"
247			log_note "> '$actual'"
248		fi
249		return 1
250	fi
251
252	return 0
253}
254
255#
256# Check that pool configuration returned by zpool status matches expected
257# configuration within a given timeout in seconds. See check_pool_config().
258#
259# eg: wait_for_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0" 60
260#
261function wait_for_pool_config
262{
263	typeset poolname=$1
264	typeset expectedconfig="$2"
265	typeset -i timeout=${3:-60}
266
267	timeout=$(( $timeout + $(date +%s) ))
268
269	while  (( $(date +%s) < $timeout )); do
270		check_pool_config -q $poolname "$expectedconfig" && return 0
271		sleep 3
272	done
273
274	check_pool_config $poolname "$expectedconfig"
275}
276
277#
278# Check that pool status is ONLINE
279#
280function check_pool_healthy
281{
282	typeset pool=$1
283	typeset status
284
285	if ! status=$(zpool status $pool 2>&1); then
286		log_note "zpool status $pool failed: $status"
287		return 1
288	fi
289
290	status=$(echo "$status" | awk -v p="$pool" '!/pool:/ && $0 ~ p {print $2}')
291
292	if [[ $status != "ONLINE" ]]; then
293		log_note "Invalid zpool status for '$pool': '$status'" \
294		    "!= 'ONLINE'"
295		return 1
296	fi
297
298	return 0
299}
300
301#
302# Return 0 if a device is currently being replaced in the pool.
303#
304function pool_is_replacing
305{
306	typeset pool=$1
307
308	zpool status $pool | grep "replacing" | grep -q "ONLINE"
309}
310
311function set_vdev_validate_skip
312{
313	set_tunable32 VDEV_VALIDATE_SKIP "$1"
314}
315
316function get_zfs_txg_timeout
317{
318	get_tunable TXG_TIMEOUT
319}
320
321function set_zfs_txg_timeout
322{
323	set_tunable32 TXG_TIMEOUT "$1"
324}
325
326function set_spa_load_verify_metadata
327{
328	set_tunable32 SPA_LOAD_VERIFY_METADATA "$1"
329}
330
331function set_spa_load_verify_data
332{
333	set_tunable32 SPA_LOAD_VERIFY_DATA "$1"
334}
335
336function set_zfs_max_missing_tvds
337{
338	set_tunable32 MAX_MISSING_TVDS "$1"
339}
340
341#
342# Use zdb to find the last txg that was synced in an active pool.
343#
344function get_last_txg_synced
345{
346	typeset pool=$1
347
348	zdb -u $pool | awk '$1 == "txg" { print $3 }' | sort -n | tail -n 1
349}
350