1f08c3bdfSopenharmony_ci#!/bin/sh
2f08c3bdfSopenharmony_ci# SPDX-License-Identifier: GPL-2.0-or-later
3f08c3bdfSopenharmony_ci# Copyright (c) Linux Test Project, 2014-2022
4f08c3bdfSopenharmony_ci# Author: Cyril Hrubis <chrubis@suse.cz>
5f08c3bdfSopenharmony_ci#
6f08c3bdfSopenharmony_ci# LTP test library for shell.
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_ci[ -n "$TST_LIB_LOADED" ] && return 0
9f08c3bdfSopenharmony_ci
10f08c3bdfSopenharmony_ciexport TST_PASS=0
11f08c3bdfSopenharmony_ciexport TST_FAIL=0
12f08c3bdfSopenharmony_ciexport TST_BROK=0
13f08c3bdfSopenharmony_ciexport TST_WARN=0
14f08c3bdfSopenharmony_ciexport TST_CONF=0
15f08c3bdfSopenharmony_ciexport TST_COUNT=1
16f08c3bdfSopenharmony_ciexport TST_ITERATIONS=1
17f08c3bdfSopenharmony_ciexport TST_TMPDIR_RHOST=0
18f08c3bdfSopenharmony_ciexport TST_LIB_LOADED=1
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_ci. tst_ansi_color.sh
21f08c3bdfSopenharmony_ci. tst_security.sh
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci# default trap function
24f08c3bdfSopenharmony_citrap "tst_brk TBROK 'test interrupted'" INT
25f08c3bdfSopenharmony_citrap "unset _tst_setup_timer_pid; tst_brk TBROK 'test terminated'" TERM
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_ci_tst_do_cleanup()
28f08c3bdfSopenharmony_ci{
29f08c3bdfSopenharmony_ci	if [ -n "$TST_DO_CLEANUP" -a -n "$TST_CLEANUP" -a -z "$TST_NO_CLEANUP" ]; then
30f08c3bdfSopenharmony_ci		if command -v $TST_CLEANUP >/dev/null 2>/dev/null; then
31f08c3bdfSopenharmony_ci			$TST_CLEANUP
32f08c3bdfSopenharmony_ci		else
33f08c3bdfSopenharmony_ci			tst_res TWARN "TST_CLEANUP=$TST_CLEANUP declared, but function not defined (or cmd not found)"
34f08c3bdfSopenharmony_ci		fi
35f08c3bdfSopenharmony_ci	fi
36f08c3bdfSopenharmony_ci	TST_DO_CLEANUP=
37f08c3bdfSopenharmony_ci}
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci_tst_do_exit()
40f08c3bdfSopenharmony_ci{
41f08c3bdfSopenharmony_ci	local ret=0
42f08c3bdfSopenharmony_ci	TST_DO_EXIT=1
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci	_tst_do_cleanup
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	cd "$LTPROOT"
47f08c3bdfSopenharmony_ci	[ "$TST_MOUNT_FLAG" = 1 ] && tst_umount
48f08c3bdfSopenharmony_ci
49f08c3bdfSopenharmony_ci	if [ "$TST_NEEDS_DEVICE" = 1 -a "$TST_DEVICE_FLAG" = 1 ]; then
50f08c3bdfSopenharmony_ci		if ! tst_device release "$TST_DEVICE"; then
51f08c3bdfSopenharmony_ci			tst_res TWARN "Failed to release device '$TST_DEVICE'"
52f08c3bdfSopenharmony_ci		fi
53f08c3bdfSopenharmony_ci	fi
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_ci	if [ "$TST_NEEDS_TMPDIR" = 1 -a -n "$TST_TMPDIR" ]; then
56f08c3bdfSopenharmony_ci		rm -r "$TST_TMPDIR"
57f08c3bdfSopenharmony_ci		[ "$TST_TMPDIR_RHOST" = 1 ] && tst_cleanup_rhost
58f08c3bdfSopenharmony_ci	fi
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci	if [ -n "$TST_NEEDS_CHECKPOINTS" -a -f "$LTP_IPC_PATH" ]; then
61f08c3bdfSopenharmony_ci		rm $LTP_IPC_PATH
62f08c3bdfSopenharmony_ci	fi
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ci	_tst_cleanup_timer
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci	if [ $TST_FAIL -gt 0 ]; then
67f08c3bdfSopenharmony_ci		ret=$((ret|1))
68f08c3bdfSopenharmony_ci	fi
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_ci	if [ $TST_BROK -gt 0 ]; then
71f08c3bdfSopenharmony_ci		ret=$((ret|2))
72f08c3bdfSopenharmony_ci	fi
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	if [ $TST_WARN -gt 0 ]; then
75f08c3bdfSopenharmony_ci		ret=$((ret|4))
76f08c3bdfSopenharmony_ci	fi
77f08c3bdfSopenharmony_ci
78f08c3bdfSopenharmony_ci	if [ $TST_CONF -gt 0 -a $TST_PASS -eq 0 ]; then
79f08c3bdfSopenharmony_ci		ret=$((ret|32))
80f08c3bdfSopenharmony_ci	fi
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	if [ $TST_BROK -gt 0 -o $TST_FAIL -gt 0 -o $TST_WARN -gt 0 ]; then
83f08c3bdfSopenharmony_ci		_tst_check_security_modules
84f08c3bdfSopenharmony_ci	fi
85f08c3bdfSopenharmony_ci
86f08c3bdfSopenharmony_ci	cat >&2 << EOF
87f08c3bdfSopenharmony_ci
88f08c3bdfSopenharmony_ciSummary:
89f08c3bdfSopenharmony_cipassed   $TST_PASS
90f08c3bdfSopenharmony_cifailed   $TST_FAIL
91f08c3bdfSopenharmony_cibroken   $TST_BROK
92f08c3bdfSopenharmony_ciskipped  $TST_CONF
93f08c3bdfSopenharmony_ciwarnings $TST_WARN
94f08c3bdfSopenharmony_ciEOF
95f08c3bdfSopenharmony_ci
96f08c3bdfSopenharmony_ci	exit $ret
97f08c3bdfSopenharmony_ci}
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_ci_tst_inc_res()
100f08c3bdfSopenharmony_ci{
101f08c3bdfSopenharmony_ci	case "$1" in
102f08c3bdfSopenharmony_ci	TPASS) TST_PASS=$((TST_PASS+1));;
103f08c3bdfSopenharmony_ci	TFAIL) TST_FAIL=$((TST_FAIL+1));;
104f08c3bdfSopenharmony_ci	TBROK) TST_BROK=$((TST_BROK+1));;
105f08c3bdfSopenharmony_ci	TWARN) TST_WARN=$((TST_WARN+1));;
106f08c3bdfSopenharmony_ci	TCONF) TST_CONF=$((TST_CONF+1));;
107f08c3bdfSopenharmony_ci	TINFO) ;;
108f08c3bdfSopenharmony_ci	*) tst_brk TBROK "Invalid res type '$1'";;
109f08c3bdfSopenharmony_ci	esac
110f08c3bdfSopenharmony_ci}
111f08c3bdfSopenharmony_ci
112f08c3bdfSopenharmony_citst_res()
113f08c3bdfSopenharmony_ci{
114f08c3bdfSopenharmony_ci	local res=$1
115f08c3bdfSopenharmony_ci	shift
116f08c3bdfSopenharmony_ci
117f08c3bdfSopenharmony_ci	_tst_inc_res "$res"
118f08c3bdfSopenharmony_ci
119f08c3bdfSopenharmony_ci	printf "$TST_ID $TST_COUNT " >&2
120f08c3bdfSopenharmony_ci	tst_print_colored $res "$res: " >&2
121f08c3bdfSopenharmony_ci	echo "$@" >&2
122f08c3bdfSopenharmony_ci}
123f08c3bdfSopenharmony_ci
124f08c3bdfSopenharmony_citst_brk()
125f08c3bdfSopenharmony_ci{
126f08c3bdfSopenharmony_ci	local res=$1
127f08c3bdfSopenharmony_ci	shift
128f08c3bdfSopenharmony_ci
129f08c3bdfSopenharmony_ci	if [ "$TST_DO_EXIT" = 1 ]; then
130f08c3bdfSopenharmony_ci		tst_res TWARN "$@"
131f08c3bdfSopenharmony_ci		return
132f08c3bdfSopenharmony_ci	fi
133f08c3bdfSopenharmony_ci
134f08c3bdfSopenharmony_ci	tst_res "$res" "$@"
135f08c3bdfSopenharmony_ci	_tst_do_exit
136f08c3bdfSopenharmony_ci}
137f08c3bdfSopenharmony_ci
138f08c3bdfSopenharmony_ciROD_SILENT()
139f08c3bdfSopenharmony_ci{
140f08c3bdfSopenharmony_ci	local tst_out
141f08c3bdfSopenharmony_ci
142f08c3bdfSopenharmony_ci	tst_out="$(tst_rod $@ 2>&1)"
143f08c3bdfSopenharmony_ci	if [ $? -ne 0 ]; then
144f08c3bdfSopenharmony_ci		echo "$tst_out"
145f08c3bdfSopenharmony_ci		tst_brk TBROK "$@ failed"
146f08c3bdfSopenharmony_ci	fi
147f08c3bdfSopenharmony_ci}
148f08c3bdfSopenharmony_ci
149f08c3bdfSopenharmony_ciROD()
150f08c3bdfSopenharmony_ci{
151f08c3bdfSopenharmony_ci	tst_rod "$@"
152f08c3bdfSopenharmony_ci	if [ $? -ne 0 ]; then
153f08c3bdfSopenharmony_ci		tst_brk TBROK "$@ failed"
154f08c3bdfSopenharmony_ci	fi
155f08c3bdfSopenharmony_ci}
156f08c3bdfSopenharmony_ci
157f08c3bdfSopenharmony_ci_tst_expect_pass()
158f08c3bdfSopenharmony_ci{
159f08c3bdfSopenharmony_ci	local fnc="$1"
160f08c3bdfSopenharmony_ci	shift
161f08c3bdfSopenharmony_ci
162f08c3bdfSopenharmony_ci	tst_rod "$@"
163f08c3bdfSopenharmony_ci	if [ $? -eq 0 ]; then
164f08c3bdfSopenharmony_ci		tst_res TPASS "$@ passed as expected"
165f08c3bdfSopenharmony_ci		return 0
166f08c3bdfSopenharmony_ci	else
167f08c3bdfSopenharmony_ci		$fnc TFAIL "$@ failed unexpectedly"
168f08c3bdfSopenharmony_ci		return 1
169f08c3bdfSopenharmony_ci	fi
170f08c3bdfSopenharmony_ci}
171f08c3bdfSopenharmony_ci
172f08c3bdfSopenharmony_ci_tst_expect_fail()
173f08c3bdfSopenharmony_ci{
174f08c3bdfSopenharmony_ci	local fnc="$1"
175f08c3bdfSopenharmony_ci	shift
176f08c3bdfSopenharmony_ci
177f08c3bdfSopenharmony_ci	# redirect stderr since we expect the command to fail
178f08c3bdfSopenharmony_ci	tst_rod "$@" 2> /dev/null
179f08c3bdfSopenharmony_ci	if [ $? -ne 0 ]; then
180f08c3bdfSopenharmony_ci		tst_res TPASS "$@ failed as expected"
181f08c3bdfSopenharmony_ci		return 0
182f08c3bdfSopenharmony_ci	else
183f08c3bdfSopenharmony_ci		$fnc TFAIL "$@ passed unexpectedly"
184f08c3bdfSopenharmony_ci		return 1
185f08c3bdfSopenharmony_ci	fi
186f08c3bdfSopenharmony_ci}
187f08c3bdfSopenharmony_ci
188f08c3bdfSopenharmony_ciEXPECT_PASS()
189f08c3bdfSopenharmony_ci{
190f08c3bdfSopenharmony_ci	_tst_expect_pass tst_res "$@"
191f08c3bdfSopenharmony_ci}
192f08c3bdfSopenharmony_ci
193f08c3bdfSopenharmony_ciEXPECT_PASS_BRK()
194f08c3bdfSopenharmony_ci{
195f08c3bdfSopenharmony_ci	_tst_expect_pass tst_brk "$@"
196f08c3bdfSopenharmony_ci}
197f08c3bdfSopenharmony_ci
198f08c3bdfSopenharmony_ciEXPECT_FAIL()
199f08c3bdfSopenharmony_ci{
200f08c3bdfSopenharmony_ci	_tst_expect_fail tst_res "$@"
201f08c3bdfSopenharmony_ci}
202f08c3bdfSopenharmony_ci
203f08c3bdfSopenharmony_ciEXPECT_FAIL_BRK()
204f08c3bdfSopenharmony_ci{
205f08c3bdfSopenharmony_ci	_tst_expect_fail tst_brk "$@"
206f08c3bdfSopenharmony_ci}
207f08c3bdfSopenharmony_ci
208f08c3bdfSopenharmony_ciTST_RETRY_FN_EXP_BACKOFF()
209f08c3bdfSopenharmony_ci{
210f08c3bdfSopenharmony_ci	local tst_fun="$1"
211f08c3bdfSopenharmony_ci	local tst_exp=$2
212f08c3bdfSopenharmony_ci	local tst_sec=$(($3 * 1000000))
213f08c3bdfSopenharmony_ci	local tst_delay=1
214f08c3bdfSopenharmony_ci
215f08c3bdfSopenharmony_ci	_tst_multiply_timeout tst_sec
216f08c3bdfSopenharmony_ci
217f08c3bdfSopenharmony_ci	if [ $# -ne 3 ]; then
218f08c3bdfSopenharmony_ci		tst_brk TBROK "TST_RETRY_FN_EXP_BACKOFF expects 3 parameters"
219f08c3bdfSopenharmony_ci	fi
220f08c3bdfSopenharmony_ci
221f08c3bdfSopenharmony_ci	if ! tst_is_int "$tst_sec"; then
222f08c3bdfSopenharmony_ci		tst_brk TBROK "TST_RETRY_FN_EXP_BACKOFF: tst_sec must be integer ('$tst_sec')"
223f08c3bdfSopenharmony_ci	fi
224f08c3bdfSopenharmony_ci
225f08c3bdfSopenharmony_ci	while true; do
226f08c3bdfSopenharmony_ci		eval "$tst_fun"
227f08c3bdfSopenharmony_ci		if [ "$?" = "$tst_exp" ]; then
228f08c3bdfSopenharmony_ci			break
229f08c3bdfSopenharmony_ci		fi
230f08c3bdfSopenharmony_ci
231f08c3bdfSopenharmony_ci		if [ $tst_delay -lt $tst_sec ]; then
232f08c3bdfSopenharmony_ci			tst_sleep ${tst_delay}us
233f08c3bdfSopenharmony_ci			tst_delay=$((tst_delay*2))
234f08c3bdfSopenharmony_ci		else
235f08c3bdfSopenharmony_ci			tst_brk TBROK "\"$tst_fun\" timed out"
236f08c3bdfSopenharmony_ci		fi
237f08c3bdfSopenharmony_ci	done
238f08c3bdfSopenharmony_ci
239f08c3bdfSopenharmony_ci	return $tst_exp
240f08c3bdfSopenharmony_ci}
241f08c3bdfSopenharmony_ci
242f08c3bdfSopenharmony_ciTST_RETRY_FUNC()
243f08c3bdfSopenharmony_ci{
244f08c3bdfSopenharmony_ci	if [ $# -ne 2 ]; then
245f08c3bdfSopenharmony_ci		tst_brk TBROK "TST_RETRY_FUNC expects 2 parameters"
246f08c3bdfSopenharmony_ci	fi
247f08c3bdfSopenharmony_ci
248f08c3bdfSopenharmony_ci	TST_RETRY_FN_EXP_BACKOFF "$1" "$2" 1
249f08c3bdfSopenharmony_ci	return $2
250f08c3bdfSopenharmony_ci}
251f08c3bdfSopenharmony_ci
252f08c3bdfSopenharmony_ciTST_RTNL_CHK()
253f08c3bdfSopenharmony_ci{
254f08c3bdfSopenharmony_ci	local msg1="RTNETLINK answers: Function not implemented"
255f08c3bdfSopenharmony_ci	local msg2="RTNETLINK answers: Operation not supported"
256f08c3bdfSopenharmony_ci	local msg3="RTNETLINK answers: Protocol not supported"
257f08c3bdfSopenharmony_ci	local output="$($@ 2>&1 || echo 'LTP_ERR')"
258f08c3bdfSopenharmony_ci	local msg
259f08c3bdfSopenharmony_ci
260f08c3bdfSopenharmony_ci	echo "$output" | grep -q "LTP_ERR" || return 0
261f08c3bdfSopenharmony_ci
262f08c3bdfSopenharmony_ci	for msg in "$msg1" "$msg2" "$msg3"; do
263f08c3bdfSopenharmony_ci		echo "$output" | grep -q "$msg" && tst_brk TCONF "'$@': $msg"
264f08c3bdfSopenharmony_ci	done
265f08c3bdfSopenharmony_ci
266f08c3bdfSopenharmony_ci	tst_brk TBROK "$@ failed: $output"
267f08c3bdfSopenharmony_ci}
268f08c3bdfSopenharmony_ci
269f08c3bdfSopenharmony_ciTST_CHECKPOINT_WAIT()
270f08c3bdfSopenharmony_ci{
271f08c3bdfSopenharmony_ci	ROD tst_checkpoint wait 10000 "$1"
272f08c3bdfSopenharmony_ci}
273f08c3bdfSopenharmony_ci
274f08c3bdfSopenharmony_ciTST_CHECKPOINT_WAKE()
275f08c3bdfSopenharmony_ci{
276f08c3bdfSopenharmony_ci	ROD tst_checkpoint wake 10000 "$1" 1
277f08c3bdfSopenharmony_ci}
278f08c3bdfSopenharmony_ci
279f08c3bdfSopenharmony_ciTST_CHECKPOINT_WAKE2()
280f08c3bdfSopenharmony_ci{
281f08c3bdfSopenharmony_ci	ROD tst_checkpoint wake 10000 "$1" "$2"
282f08c3bdfSopenharmony_ci}
283f08c3bdfSopenharmony_ci
284f08c3bdfSopenharmony_ciTST_CHECKPOINT_WAKE_AND_WAIT()
285f08c3bdfSopenharmony_ci{
286f08c3bdfSopenharmony_ci	TST_CHECKPOINT_WAKE "$1"
287f08c3bdfSopenharmony_ci	TST_CHECKPOINT_WAIT "$1"
288f08c3bdfSopenharmony_ci}
289f08c3bdfSopenharmony_ci
290f08c3bdfSopenharmony_citst_mount()
291f08c3bdfSopenharmony_ci{
292f08c3bdfSopenharmony_ci	local mnt_opt mnt_err mnt_real
293f08c3bdfSopenharmony_ci
294f08c3bdfSopenharmony_ci	if [ -n "$TST_FS_TYPE" ]; then
295f08c3bdfSopenharmony_ci		mnt_opt="-t $TST_FS_TYPE"
296f08c3bdfSopenharmony_ci		mnt_err=" $TST_FS_TYPE type"
297f08c3bdfSopenharmony_ci	fi
298f08c3bdfSopenharmony_ci	local cmd="mount $mnt_opt $TST_DEVICE $TST_MNTPOINT $TST_MNT_PARAMS"
299f08c3bdfSopenharmony_ci
300f08c3bdfSopenharmony_ci	ROD_SILENT mkdir -p $TST_MNTPOINT
301f08c3bdfSopenharmony_ci	tst_res TINFO "Mounting device: $cmd"
302f08c3bdfSopenharmony_ci	$cmd
303f08c3bdfSopenharmony_ci	local ret=$?
304f08c3bdfSopenharmony_ci
305f08c3bdfSopenharmony_ci	if [ $ret -eq 32 ]; then
306f08c3bdfSopenharmony_ci		tst_brk TCONF "Cannot mount${mnt_err}, missing driver?"
307f08c3bdfSopenharmony_ci	fi
308f08c3bdfSopenharmony_ci
309f08c3bdfSopenharmony_ci	if [ $ret -ne 0 ]; then
310f08c3bdfSopenharmony_ci		tst_brk TBROK "Failed to mount device${mnt_err}: mount exit = $ret"
311f08c3bdfSopenharmony_ci	fi
312f08c3bdfSopenharmony_ci}
313f08c3bdfSopenharmony_ci
314f08c3bdfSopenharmony_citst_umount()
315f08c3bdfSopenharmony_ci{
316f08c3bdfSopenharmony_ci	local mntpoint="${1:-$TST_MNTPOINT}"
317f08c3bdfSopenharmony_ci	local i=0
318f08c3bdfSopenharmony_ci
319f08c3bdfSopenharmony_ci	[ -z "$mntpoint" ] && return
320f08c3bdfSopenharmony_ci
321f08c3bdfSopenharmony_ci	if ! echo "$mntpoint" | grep -q ^/; then
322f08c3bdfSopenharmony_ci		tst_brk TCONF "The '$mntpoint' is not an absolute path"
323f08c3bdfSopenharmony_ci	fi
324f08c3bdfSopenharmony_ci
325f08c3bdfSopenharmony_ci	if ! grep -q "${mntpoint%/}" /proc/mounts; then
326f08c3bdfSopenharmony_ci		tst_res TINFO "The '$mntpoint' is not mounted, skipping umount"
327f08c3bdfSopenharmony_ci		return
328f08c3bdfSopenharmony_ci	fi
329f08c3bdfSopenharmony_ci
330f08c3bdfSopenharmony_ci	while [ "$i" -lt 50 ]; do
331f08c3bdfSopenharmony_ci		if umount "$mntpoint" > /dev/null; then
332f08c3bdfSopenharmony_ci			return
333f08c3bdfSopenharmony_ci		fi
334f08c3bdfSopenharmony_ci
335f08c3bdfSopenharmony_ci		i=$((i+1))
336f08c3bdfSopenharmony_ci
337f08c3bdfSopenharmony_ci		tst_res TINFO "umount($mntpoint) failed, try $i ..."
338f08c3bdfSopenharmony_ci		tst_res TINFO "Likely gvfsd-trash is probing newly mounted "\
339f08c3bdfSopenharmony_ci		              "fs, kill it to speed up tests."
340f08c3bdfSopenharmony_ci
341f08c3bdfSopenharmony_ci		tst_sleep 100ms
342f08c3bdfSopenharmony_ci	done
343f08c3bdfSopenharmony_ci
344f08c3bdfSopenharmony_ci	tst_res TWARN "Failed to umount($mntpoint) after 50 retries"
345f08c3bdfSopenharmony_ci}
346f08c3bdfSopenharmony_ci
347f08c3bdfSopenharmony_citst_mkfs()
348f08c3bdfSopenharmony_ci{
349f08c3bdfSopenharmony_ci	local opts
350f08c3bdfSopenharmony_ci	local fs_type=${1:-$TST_FS_TYPE}
351f08c3bdfSopenharmony_ci	[ $# -ge 1 ] && shift
352f08c3bdfSopenharmony_ci
353f08c3bdfSopenharmony_ci	opts="$@"
354f08c3bdfSopenharmony_ci
355f08c3bdfSopenharmony_ci	if [ "$fs_type" = tmpfs ]; then
356f08c3bdfSopenharmony_ci		tst_res TINFO "Skipping mkfs for TMPFS filesystem"
357f08c3bdfSopenharmony_ci		return
358f08c3bdfSopenharmony_ci	fi
359f08c3bdfSopenharmony_ci
360f08c3bdfSopenharmony_ci	if [ -z "$opts" ]; then
361f08c3bdfSopenharmony_ci		if [ "$TST_NEEDS_DEVICE" != 1 ]; then
362f08c3bdfSopenharmony_ci			tst_brk "Using default parameters in tst_mkfs requires TST_NEEDS_DEVICE=1"
363f08c3bdfSopenharmony_ci		fi
364f08c3bdfSopenharmony_ci		opts="$TST_DEVICE"
365f08c3bdfSopenharmony_ci	fi
366f08c3bdfSopenharmony_ci
367f08c3bdfSopenharmony_ci	tst_require_cmds mkfs.$fs_type
368f08c3bdfSopenharmony_ci
369f08c3bdfSopenharmony_ci	tst_res TINFO "Formatting $fs_type with opts='$opts'"
370f08c3bdfSopenharmony_ci	ROD_SILENT mkfs.$fs_type $opts
371f08c3bdfSopenharmony_ci}
372f08c3bdfSopenharmony_ci
373f08c3bdfSopenharmony_ci# Detect whether running under hypervisor: Microsoft Hyper-V
374f08c3bdfSopenharmony_ci# Return 0: running under Hyper-V
375f08c3bdfSopenharmony_ci# Return 1: not running under Hyper-V (bare metal, other hypervisor or
376f08c3bdfSopenharmony_ci#           failure of detection)
377f08c3bdfSopenharmony_citst_virt_hyperv()
378f08c3bdfSopenharmony_ci{
379f08c3bdfSopenharmony_ci	local v
380f08c3bdfSopenharmony_ci
381f08c3bdfSopenharmony_ci	tst_cmd_available systemd-detect-virt || return 1
382f08c3bdfSopenharmony_ci
383f08c3bdfSopenharmony_ci	v="$(systemd-detect-virt)"
384f08c3bdfSopenharmony_ci
385f08c3bdfSopenharmony_ci	[ $? -eq 0 ] || return 1
386f08c3bdfSopenharmony_ci	[ "$v" = "microsoft" ] || return 1
387f08c3bdfSopenharmony_ci
388f08c3bdfSopenharmony_ci	return 0
389f08c3bdfSopenharmony_ci}
390f08c3bdfSopenharmony_ci
391f08c3bdfSopenharmony_citst_cmd_available()
392f08c3bdfSopenharmony_ci{
393f08c3bdfSopenharmony_ci	command -v $1 >/dev/null 2>&1
394f08c3bdfSopenharmony_ci}
395f08c3bdfSopenharmony_ci
396f08c3bdfSopenharmony_citst_require_cmds()
397f08c3bdfSopenharmony_ci{
398f08c3bdfSopenharmony_ci	local cmd
399f08c3bdfSopenharmony_ci	for cmd in $*; do
400f08c3bdfSopenharmony_ci		tst_cmd_available $cmd || tst_brk TCONF "'$cmd' not found"
401f08c3bdfSopenharmony_ci	done
402f08c3bdfSopenharmony_ci}
403f08c3bdfSopenharmony_ci
404f08c3bdfSopenharmony_citst_check_cmds()
405f08c3bdfSopenharmony_ci{
406f08c3bdfSopenharmony_ci	local cmd
407f08c3bdfSopenharmony_ci	for cmd in $*; do
408f08c3bdfSopenharmony_ci		if ! tst_cmd_available $cmd; then
409f08c3bdfSopenharmony_ci			tst_res TCONF "'$cmd' not found"
410f08c3bdfSopenharmony_ci			return 1
411f08c3bdfSopenharmony_ci		fi
412f08c3bdfSopenharmony_ci	done
413f08c3bdfSopenharmony_ci	return 0
414f08c3bdfSopenharmony_ci}
415f08c3bdfSopenharmony_ci
416f08c3bdfSopenharmony_citst_require_drivers()
417f08c3bdfSopenharmony_ci{
418f08c3bdfSopenharmony_ci	[ $# -eq 0 ] && return 0
419f08c3bdfSopenharmony_ci
420f08c3bdfSopenharmony_ci	local drv
421f08c3bdfSopenharmony_ci
422f08c3bdfSopenharmony_ci	drv="$(tst_check_drivers $@ 2>&1)"
423f08c3bdfSopenharmony_ci
424f08c3bdfSopenharmony_ci	[ $? -ne 0 ] && tst_brk TCONF "$drv driver not available"
425f08c3bdfSopenharmony_ci	return 0
426f08c3bdfSopenharmony_ci}
427f08c3bdfSopenharmony_ci
428f08c3bdfSopenharmony_citst_require_kconfigs()
429f08c3bdfSopenharmony_ci{
430f08c3bdfSopenharmony_ci	local delim
431f08c3bdfSopenharmony_ci
432f08c3bdfSopenharmony_ci	if [ $# -gt 2 ]; then
433f08c3bdfSopenharmony_ci		return 0
434f08c3bdfSopenharmony_ci	elif [ $# -eq 1 ]; then
435f08c3bdfSopenharmony_ci		delim="$TST_NEEDS_KCONFIGS_IFS"
436f08c3bdfSopenharmony_ci	else
437f08c3bdfSopenharmony_ci		delim="$2"
438f08c3bdfSopenharmony_ci	fi
439f08c3bdfSopenharmony_ci
440f08c3bdfSopenharmony_ci	[ -z "$1" ] && return 0
441f08c3bdfSopenharmony_ci
442f08c3bdfSopenharmony_ci	tst_check_kconfigs "$1" "$delim" > /dev/null
443f08c3bdfSopenharmony_ci
444f08c3bdfSopenharmony_ci	[ $? -ne 0 ] && tst_brk TCONF "Aborting due to unsuitable kernel config, see above!"
445f08c3bdfSopenharmony_ci	return 0
446f08c3bdfSopenharmony_ci}
447f08c3bdfSopenharmony_ci
448f08c3bdfSopenharmony_citst_is_int()
449f08c3bdfSopenharmony_ci{
450f08c3bdfSopenharmony_ci	[ "$1" -eq "$1" ] 2>/dev/null
451f08c3bdfSopenharmony_ci	return $?
452f08c3bdfSopenharmony_ci}
453f08c3bdfSopenharmony_ci
454f08c3bdfSopenharmony_citst_is_num()
455f08c3bdfSopenharmony_ci{
456f08c3bdfSopenharmony_ci	echo "$1" | grep -Eq '^[-+]?[0-9]+\.?[0-9]*$'
457f08c3bdfSopenharmony_ci}
458f08c3bdfSopenharmony_ci
459f08c3bdfSopenharmony_citst_usage()
460f08c3bdfSopenharmony_ci{
461f08c3bdfSopenharmony_ci	if [ -n "$TST_USAGE" ]; then
462f08c3bdfSopenharmony_ci		$TST_USAGE
463f08c3bdfSopenharmony_ci	else
464f08c3bdfSopenharmony_ci		echo "usage: $0"
465f08c3bdfSopenharmony_ci		echo
466f08c3bdfSopenharmony_ci		echo "Options"
467f08c3bdfSopenharmony_ci		echo "-------"
468f08c3bdfSopenharmony_ci	fi
469f08c3bdfSopenharmony_ci
470f08c3bdfSopenharmony_ci	echo "-h      Prints this help"
471f08c3bdfSopenharmony_ci	echo "-i n    Execute test n times"
472f08c3bdfSopenharmony_ci
473f08c3bdfSopenharmony_ci	cat << EOF
474f08c3bdfSopenharmony_ci
475f08c3bdfSopenharmony_ciEnvironment Variables
476f08c3bdfSopenharmony_ci---------------------
477f08c3bdfSopenharmony_ciKCONFIG_PATH         Specify kernel config file
478f08c3bdfSopenharmony_ciKCONFIG_SKIP_CHECK   Skip kernel config check if variable set (not set by default)
479f08c3bdfSopenharmony_ciLTPROOT              Prefix for installed LTP (default: /opt/ltp)
480f08c3bdfSopenharmony_ciLTP_COLORIZE_OUTPUT  Force colorized output behaviour (y/1 always, n/0: never)
481f08c3bdfSopenharmony_ciLTP_DEV              Path to the block device to be used (for .needs_device)
482f08c3bdfSopenharmony_ciLTP_DEV_FS_TYPE      Filesystem used for testing (default: ext2)
483f08c3bdfSopenharmony_ciLTP_SINGLE_FS_TYPE   Testing only - specifies filesystem instead all supported (for TST_ALL_FILESYSTEMS=1)
484f08c3bdfSopenharmony_ciLTP_TIMEOUT_MUL      Timeout multiplier (must be a number >=1, ceiled to int)
485f08c3bdfSopenharmony_ciTMPDIR               Base directory for template directory (for .needs_tmpdir, default: /tmp)
486f08c3bdfSopenharmony_ciEOF
487f08c3bdfSopenharmony_ci}
488f08c3bdfSopenharmony_ci
489f08c3bdfSopenharmony_ci_tst_resstr()
490f08c3bdfSopenharmony_ci{
491f08c3bdfSopenharmony_ci	echo "$TST_PASS$TST_FAIL$TST_CONF"
492f08c3bdfSopenharmony_ci}
493f08c3bdfSopenharmony_ci
494f08c3bdfSopenharmony_ci_tst_rescmp()
495f08c3bdfSopenharmony_ci{
496f08c3bdfSopenharmony_ci	local res=$(_tst_resstr)
497f08c3bdfSopenharmony_ci
498f08c3bdfSopenharmony_ci	if [ "$1" = "$res" ]; then
499f08c3bdfSopenharmony_ci		tst_brk TBROK "Test didn't report any results"
500f08c3bdfSopenharmony_ci	fi
501f08c3bdfSopenharmony_ci}
502f08c3bdfSopenharmony_ci
503f08c3bdfSopenharmony_ci_tst_multiply_timeout()
504f08c3bdfSopenharmony_ci{
505f08c3bdfSopenharmony_ci	[ $# -ne 1 ] && tst_brk TBROK "_tst_multiply_timeout expect 1 parameter"
506f08c3bdfSopenharmony_ci	eval "local timeout=\$$1"
507f08c3bdfSopenharmony_ci
508f08c3bdfSopenharmony_ci	LTP_TIMEOUT_MUL=${LTP_TIMEOUT_MUL:-1}
509f08c3bdfSopenharmony_ci
510f08c3bdfSopenharmony_ci	local err="LTP_TIMEOUT_MUL must be number >= 1!"
511f08c3bdfSopenharmony_ci
512f08c3bdfSopenharmony_ci	tst_is_num "$LTP_TIMEOUT_MUL" || tst_brk TBROK "$err ($LTP_TIMEOUT_MUL)"
513f08c3bdfSopenharmony_ci
514f08c3bdfSopenharmony_ci	if ! tst_is_int "$LTP_TIMEOUT_MUL"; then
515f08c3bdfSopenharmony_ci		LTP_TIMEOUT_MUL=$(echo "$LTP_TIMEOUT_MUL" | cut -d. -f1)
516f08c3bdfSopenharmony_ci		LTP_TIMEOUT_MUL=$((LTP_TIMEOUT_MUL+1))
517f08c3bdfSopenharmony_ci		tst_res TINFO "ceiling LTP_TIMEOUT_MUL to $LTP_TIMEOUT_MUL"
518f08c3bdfSopenharmony_ci	fi
519f08c3bdfSopenharmony_ci
520f08c3bdfSopenharmony_ci	[ "$LTP_TIMEOUT_MUL" -ge 1 ] || tst_brk TBROK "$err ($LTP_TIMEOUT_MUL)"
521f08c3bdfSopenharmony_ci	[ "$timeout" -ge 1 ] || tst_brk TBROK "timeout need to be >= 1 ($timeout)"
522f08c3bdfSopenharmony_ci
523f08c3bdfSopenharmony_ci	eval "$1='$((timeout * LTP_TIMEOUT_MUL))'"
524f08c3bdfSopenharmony_ci	return 0
525f08c3bdfSopenharmony_ci}
526f08c3bdfSopenharmony_ci
527f08c3bdfSopenharmony_ci_tst_cleanup_timer()
528f08c3bdfSopenharmony_ci{
529f08c3bdfSopenharmony_ci	if [ -n "$_tst_setup_timer_pid" ]; then
530f08c3bdfSopenharmony_ci		kill -TERM $_tst_setup_timer_pid 2>/dev/null
531f08c3bdfSopenharmony_ci		# kill is successful only on test timeout
532f08c3bdfSopenharmony_ci		wait $_tst_setup_timer_pid 2>/dev/null || true
533f08c3bdfSopenharmony_ci	fi
534f08c3bdfSopenharmony_ci}
535f08c3bdfSopenharmony_ci
536f08c3bdfSopenharmony_ci_tst_setup_timer()
537f08c3bdfSopenharmony_ci{
538f08c3bdfSopenharmony_ci	TST_TIMEOUT=${TST_TIMEOUT:-300}
539f08c3bdfSopenharmony_ci
540f08c3bdfSopenharmony_ci	if [ "$TST_TIMEOUT" = -1 ]; then
541f08c3bdfSopenharmony_ci		tst_res TINFO "Timeout per run is disabled"
542f08c3bdfSopenharmony_ci		return
543f08c3bdfSopenharmony_ci	fi
544f08c3bdfSopenharmony_ci
545f08c3bdfSopenharmony_ci	if ! tst_is_int "$TST_TIMEOUT" || [ "$TST_TIMEOUT" -lt 1 ]; then
546f08c3bdfSopenharmony_ci		tst_brk TBROK "TST_TIMEOUT must be int >= 1! ($TST_TIMEOUT)"
547f08c3bdfSopenharmony_ci	fi
548f08c3bdfSopenharmony_ci
549f08c3bdfSopenharmony_ci	local sec=$TST_TIMEOUT
550f08c3bdfSopenharmony_ci	_tst_multiply_timeout sec
551f08c3bdfSopenharmony_ci	local h=$((sec / 3600))
552f08c3bdfSopenharmony_ci	local m=$((sec / 60 % 60))
553f08c3bdfSopenharmony_ci	local s=$((sec % 60))
554f08c3bdfSopenharmony_ci	local pid=$$
555f08c3bdfSopenharmony_ci
556f08c3bdfSopenharmony_ci	tst_res TINFO "timeout per run is ${h}h ${m}m ${s}s"
557f08c3bdfSopenharmony_ci
558f08c3bdfSopenharmony_ci	_tst_cleanup_timer
559f08c3bdfSopenharmony_ci
560f08c3bdfSopenharmony_ci	tst_timeout_kill $sec $pid &
561f08c3bdfSopenharmony_ci
562f08c3bdfSopenharmony_ci	_tst_setup_timer_pid=$!
563f08c3bdfSopenharmony_ci
564f08c3bdfSopenharmony_ci	while true; do
565f08c3bdfSopenharmony_ci		local state
566f08c3bdfSopenharmony_ci
567f08c3bdfSopenharmony_ci		state=$(cut -d' ' -f3 "/proc/$_tst_setup_timer_pid/stat")
568f08c3bdfSopenharmony_ci
569f08c3bdfSopenharmony_ci		if [ "$state" = "S" ]; then
570f08c3bdfSopenharmony_ci			break;
571f08c3bdfSopenharmony_ci		fi
572f08c3bdfSopenharmony_ci
573f08c3bdfSopenharmony_ci		tst_sleep 1ms
574f08c3bdfSopenharmony_ci	done
575f08c3bdfSopenharmony_ci}
576f08c3bdfSopenharmony_ci
577f08c3bdfSopenharmony_citst_require_root()
578f08c3bdfSopenharmony_ci{
579f08c3bdfSopenharmony_ci	if [ "$(id -ru)" != 0 ]; then
580f08c3bdfSopenharmony_ci		tst_brk TCONF "Must be super/root for this test!"
581f08c3bdfSopenharmony_ci	fi
582f08c3bdfSopenharmony_ci}
583f08c3bdfSopenharmony_ci
584f08c3bdfSopenharmony_citst_require_module()
585f08c3bdfSopenharmony_ci{
586f08c3bdfSopenharmony_ci	local _tst_module=$1
587f08c3bdfSopenharmony_ci
588f08c3bdfSopenharmony_ci	for tst_module in "$_tst_module" \
589f08c3bdfSopenharmony_ci	                  "$LTPROOT/testcases/bin/$_tst_module" \
590f08c3bdfSopenharmony_ci	                  "$TST_STARTWD/$_tst_module"; do
591f08c3bdfSopenharmony_ci
592f08c3bdfSopenharmony_ci			if [ -f "$tst_module" ]; then
593f08c3bdfSopenharmony_ci				TST_MODPATH="$tst_module"
594f08c3bdfSopenharmony_ci				break
595f08c3bdfSopenharmony_ci			fi
596f08c3bdfSopenharmony_ci	done
597f08c3bdfSopenharmony_ci
598f08c3bdfSopenharmony_ci	if [ -z "$TST_MODPATH" ]; then
599f08c3bdfSopenharmony_ci		tst_brk TCONF "Failed to find module '$_tst_module'"
600f08c3bdfSopenharmony_ci	fi
601f08c3bdfSopenharmony_ci
602f08c3bdfSopenharmony_ci	tst_res TINFO "Found module at '$TST_MODPATH'"
603f08c3bdfSopenharmony_ci}
604f08c3bdfSopenharmony_ci
605f08c3bdfSopenharmony_citst_set_timeout()
606f08c3bdfSopenharmony_ci{
607f08c3bdfSopenharmony_ci	TST_TIMEOUT="$1"
608f08c3bdfSopenharmony_ci	_tst_setup_timer
609f08c3bdfSopenharmony_ci}
610f08c3bdfSopenharmony_ci
611f08c3bdfSopenharmony_ci_tst_init_checkpoints()
612f08c3bdfSopenharmony_ci{
613f08c3bdfSopenharmony_ci	local pagesize
614f08c3bdfSopenharmony_ci
615f08c3bdfSopenharmony_ci	LTP_IPC_PATH="/dev/shm/ltp_${TST_ID}_$$"
616f08c3bdfSopenharmony_ci	pagesize=$(tst_getconf PAGESIZE)
617f08c3bdfSopenharmony_ci	if [ $? -ne 0 ]; then
618f08c3bdfSopenharmony_ci		tst_brk TBROK "tst_getconf PAGESIZE failed"
619f08c3bdfSopenharmony_ci	fi
620f08c3bdfSopenharmony_ci	ROD_SILENT dd if=/dev/zero of="$LTP_IPC_PATH" bs="$pagesize" count=1
621f08c3bdfSopenharmony_ci	ROD_SILENT chmod 600 "$LTP_IPC_PATH"
622f08c3bdfSopenharmony_ci	export LTP_IPC_PATH
623f08c3bdfSopenharmony_ci}
624f08c3bdfSopenharmony_ci
625f08c3bdfSopenharmony_ci_prepare_device()
626f08c3bdfSopenharmony_ci{
627f08c3bdfSopenharmony_ci	if [ "$TST_FORMAT_DEVICE" = 1 ]; then
628f08c3bdfSopenharmony_ci		tst_device clear "$TST_DEVICE"
629f08c3bdfSopenharmony_ci		tst_mkfs $TST_FS_TYPE $TST_DEV_FS_OPTS $TST_DEVICE $TST_DEV_EXTRA_OPTS
630f08c3bdfSopenharmony_ci	fi
631f08c3bdfSopenharmony_ci
632f08c3bdfSopenharmony_ci	if [ "$TST_MOUNT_DEVICE" = 1 ]; then
633f08c3bdfSopenharmony_ci		tst_mount
634f08c3bdfSopenharmony_ci		TST_MOUNT_FLAG=1
635f08c3bdfSopenharmony_ci	fi
636f08c3bdfSopenharmony_ci}
637f08c3bdfSopenharmony_ci
638f08c3bdfSopenharmony_ci_tst_run_tcases_per_fs()
639f08c3bdfSopenharmony_ci{
640f08c3bdfSopenharmony_ci	local fs
641f08c3bdfSopenharmony_ci	local filesystems
642f08c3bdfSopenharmony_ci
643f08c3bdfSopenharmony_ci	filesystems="$(tst_supported_fs -s "$TST_SKIP_FILESYSTEMS")"
644f08c3bdfSopenharmony_ci	if [ $? -ne 0 ]; then
645f08c3bdfSopenharmony_ci		tst_brk TCONF "There are no supported filesystems or all skipped"
646f08c3bdfSopenharmony_ci	fi
647f08c3bdfSopenharmony_ci
648f08c3bdfSopenharmony_ci	for fs in $filesystems; do
649f08c3bdfSopenharmony_ci		tst_res TINFO "=== Testing on $fs ==="
650f08c3bdfSopenharmony_ci		TST_FS_TYPE="$fs"
651f08c3bdfSopenharmony_ci		_tst_run_iterations
652f08c3bdfSopenharmony_ci	done
653f08c3bdfSopenharmony_ci}
654f08c3bdfSopenharmony_ci
655f08c3bdfSopenharmony_citst_run()
656f08c3bdfSopenharmony_ci{
657f08c3bdfSopenharmony_ci	local _tst_i
658f08c3bdfSopenharmony_ci	local _tst_data
659f08c3bdfSopenharmony_ci	local _tst_max
660f08c3bdfSopenharmony_ci	local _tst_name
661f08c3bdfSopenharmony_ci	local _tst_pattern='[='\''"} \t\/:`$\;|].*'
662f08c3bdfSopenharmony_ci	local ret
663f08c3bdfSopenharmony_ci
664f08c3bdfSopenharmony_ci	if [ -n "$TST_TEST_PATH" ]; then
665f08c3bdfSopenharmony_ci		for _tst_i in $(grep '^[^#]*\bTST_' "$TST_TEST_PATH" | sed "s/.*TST_//; s/$_tst_pattern//"); do
666f08c3bdfSopenharmony_ci			case "$_tst_i" in
667f08c3bdfSopenharmony_ci			ALL_FILESYSTEMS|DISABLE_APPARMOR|DISABLE_SELINUX);;
668f08c3bdfSopenharmony_ci			SETUP|CLEANUP|TESTFUNC|ID|CNT|MIN_KVER);;
669f08c3bdfSopenharmony_ci			OPTS|USAGE|PARSE_ARGS|POS_ARGS);;
670f08c3bdfSopenharmony_ci			NEEDS_ROOT|NEEDS_TMPDIR|TMPDIR|NEEDS_DEVICE|DEVICE);;
671f08c3bdfSopenharmony_ci			NEEDS_CMDS|NEEDS_MODULE|MODPATH|DATAROOT);;
672f08c3bdfSopenharmony_ci			NEEDS_DRIVERS|FS_TYPE|MNTPOINT|MNT_PARAMS);;
673f08c3bdfSopenharmony_ci			NEEDS_KCONFIGS|NEEDS_KCONFIGS_IFS);;
674f08c3bdfSopenharmony_ci			IPV6|IPV6_FLAG|IPVER|TEST_DATA|TEST_DATA_IFS);;
675f08c3bdfSopenharmony_ci			RETRY_FUNC|RETRY_FN_EXP_BACKOFF|TIMEOUT);;
676f08c3bdfSopenharmony_ci			NET_DATAROOT|NET_MAX_PKT|NET_RHOST_RUN_DEBUG|NETLOAD_CLN_NUMBER);;
677f08c3bdfSopenharmony_ci			NET_SKIP_VARIABLE_INIT|NEEDS_CHECKPOINTS);;
678f08c3bdfSopenharmony_ci			CHECKPOINT_WAIT|CHECKPOINT_WAKE);;
679f08c3bdfSopenharmony_ci			CHECKPOINT_WAKE2|CHECKPOINT_WAKE_AND_WAIT);;
680f08c3bdfSopenharmony_ci			DEV_EXTRA_OPTS|DEV_FS_OPTS|FORMAT_DEVICE|MOUNT_DEVICE);;
681f08c3bdfSopenharmony_ci			SKIP_FILESYSTEMS|SKIP_IN_LOCKDOWN|SKIP_IN_SECUREBOOT);;
682f08c3bdfSopenharmony_ci			*) tst_res TWARN "Reserved variable TST_$_tst_i used!";;
683f08c3bdfSopenharmony_ci			esac
684f08c3bdfSopenharmony_ci		done
685f08c3bdfSopenharmony_ci
686f08c3bdfSopenharmony_ci		for _tst_i in $(grep '^[^#]*\b_tst_' "$TST_TEST_PATH" | sed "s/.*_tst_//; s/$_tst_pattern//"); do
687f08c3bdfSopenharmony_ci			tst_res TWARN "Private variable or function _tst_$_tst_i used!"
688f08c3bdfSopenharmony_ci		done
689f08c3bdfSopenharmony_ci	fi
690f08c3bdfSopenharmony_ci
691f08c3bdfSopenharmony_ci	if ! tst_is_int "$TST_ITERATIONS"; then
692f08c3bdfSopenharmony_ci		tst_brk TBROK "Expected number (-i) not '$TST_ITERATIONS'"
693f08c3bdfSopenharmony_ci	fi
694f08c3bdfSopenharmony_ci
695f08c3bdfSopenharmony_ci	if [ "$TST_ITERATIONS" -lt 0 ]; then
696f08c3bdfSopenharmony_ci		tst_brk TBROK "Number of iterations (-i) must be >= 0"
697f08c3bdfSopenharmony_ci	fi
698f08c3bdfSopenharmony_ci
699f08c3bdfSopenharmony_ci	[ "$TST_NEEDS_ROOT" = 1 ] && tst_require_root
700f08c3bdfSopenharmony_ci
701f08c3bdfSopenharmony_ci	if [ "$TST_SKIP_IN_SECUREBOOT" = 1 ] && tst_secureboot_enabled; then
702f08c3bdfSopenharmony_ci		tst_brk TCONF "SecureBoot enabled, skipping test"
703f08c3bdfSopenharmony_ci	fi
704f08c3bdfSopenharmony_ci
705f08c3bdfSopenharmony_ci	if [ "$TST_SKIP_IN_LOCKDOWN" = 1 ] && tst_lockdown_enabled; then
706f08c3bdfSopenharmony_ci		tst_brk TCONF "Kernel is locked down, skipping test"
707f08c3bdfSopenharmony_ci	fi
708f08c3bdfSopenharmony_ci
709f08c3bdfSopenharmony_ci	[ "$TST_DISABLE_APPARMOR" = 1 ] && tst_disable_apparmor
710f08c3bdfSopenharmony_ci	[ "$TST_DISABLE_SELINUX" = 1 ] && tst_disable_selinux
711f08c3bdfSopenharmony_ci
712f08c3bdfSopenharmony_ci	tst_require_cmds $TST_NEEDS_CMDS
713f08c3bdfSopenharmony_ci	tst_require_kconfigs "$TST_NEEDS_KCONFIGS"
714f08c3bdfSopenharmony_ci	tst_require_drivers $TST_NEEDS_DRIVERS
715f08c3bdfSopenharmony_ci
716f08c3bdfSopenharmony_ci	if [ -n "$TST_MIN_KVER" ]; then
717f08c3bdfSopenharmony_ci		tst_kvcmp -lt "$TST_MIN_KVER" && \
718f08c3bdfSopenharmony_ci			tst_brk TCONF "test requires kernel $TST_MIN_KVER+"
719f08c3bdfSopenharmony_ci	fi
720f08c3bdfSopenharmony_ci
721f08c3bdfSopenharmony_ci	[ -n "$TST_NEEDS_MODULE" ] && tst_require_module "$TST_NEEDS_MODULE"
722f08c3bdfSopenharmony_ci
723f08c3bdfSopenharmony_ci	[ "$TST_MOUNT_DEVICE" = 1 ] && TST_FORMAT_DEVICE=1
724f08c3bdfSopenharmony_ci	[ "$TST_FORMAT_DEVICE" = 1 -o "$TST_ALL_FILESYSTEMS" = 1 ] && TST_NEEDS_DEVICE=1
725f08c3bdfSopenharmony_ci	[ "$TST_NEEDS_DEVICE" = 1 ] && TST_NEEDS_TMPDIR=1
726f08c3bdfSopenharmony_ci
727f08c3bdfSopenharmony_ci	if [ "$TST_NEEDS_TMPDIR" = 1 ]; then
728f08c3bdfSopenharmony_ci		if [ -z "$TMPDIR" ]; then
729f08c3bdfSopenharmony_ci			export TMPDIR="/tmp"
730f08c3bdfSopenharmony_ci		fi
731f08c3bdfSopenharmony_ci
732f08c3bdfSopenharmony_ci		TST_TMPDIR=$(mktemp -d "$TMPDIR/LTP_$TST_ID.XXXXXXXXXX")
733f08c3bdfSopenharmony_ci		# remove possible trailing slash or double slashes from TMPDIR
734f08c3bdfSopenharmony_ci		TST_TMPDIR=$(echo "$TST_TMPDIR" | sed 's~/\+~/~g')
735f08c3bdfSopenharmony_ci
736f08c3bdfSopenharmony_ci		chmod 777 "$TST_TMPDIR"
737f08c3bdfSopenharmony_ci
738f08c3bdfSopenharmony_ci		TST_STARTWD=$(pwd)
739f08c3bdfSopenharmony_ci		cd "$TST_TMPDIR"
740f08c3bdfSopenharmony_ci	fi
741f08c3bdfSopenharmony_ci
742f08c3bdfSopenharmony_ci	# needs to be after cd $TST_TMPDIR to keep test_dev.img under $TST_TMPDIR
743f08c3bdfSopenharmony_ci	if [ "$TST_NEEDS_DEVICE" = 1 ]; then
744f08c3bdfSopenharmony_ci		TST_DEVICE=$(tst_device acquire)
745f08c3bdfSopenharmony_ci
746f08c3bdfSopenharmony_ci		if [ ! -b "$TST_DEVICE" -o $? -ne 0 ]; then
747f08c3bdfSopenharmony_ci			unset TST_DEVICE
748f08c3bdfSopenharmony_ci			tst_brk TBROK "Failed to acquire device"
749f08c3bdfSopenharmony_ci		fi
750f08c3bdfSopenharmony_ci		TST_DEVICE_FLAG=1
751f08c3bdfSopenharmony_ci
752f08c3bdfSopenharmony_ci		if [ -z "$TST_FS_TYPE" ]; then
753f08c3bdfSopenharmony_ci			export TST_FS_TYPE="${LTP_DEV_FS_TYPE:-ext2}"
754f08c3bdfSopenharmony_ci		fi
755f08c3bdfSopenharmony_ci	fi
756f08c3bdfSopenharmony_ci
757f08c3bdfSopenharmony_ci	if [ "$TST_ALL_FILESYSTEMS" != 1 -a "$TST_SKIP_FILESYSTEMS" ]; then
758f08c3bdfSopenharmony_ci		if ! tst_supported_fs -s "$TST_SKIP_FILESYSTEMS" -d . > /dev/null; then
759f08c3bdfSopenharmony_ci			tst_brk TCONF "filesystem is not supported by the test"
760f08c3bdfSopenharmony_ci		fi
761f08c3bdfSopenharmony_ci
762f08c3bdfSopenharmony_ci		tst_res TINFO "filesystem is supported by the test"
763f08c3bdfSopenharmony_ci	fi
764f08c3bdfSopenharmony_ci
765f08c3bdfSopenharmony_ci	[ -n "$TST_NEEDS_CHECKPOINTS" ] && _tst_init_checkpoints
766f08c3bdfSopenharmony_ci
767f08c3bdfSopenharmony_ci	TST_MNTPOINT="${TST_MNTPOINT:-$PWD/mntpoint}"
768f08c3bdfSopenharmony_ci
769f08c3bdfSopenharmony_ci	if [ "$TST_ALL_FILESYSTEMS" = 1 ]; then
770f08c3bdfSopenharmony_ci		_tst_run_tcases_per_fs
771f08c3bdfSopenharmony_ci	else
772f08c3bdfSopenharmony_ci		_tst_run_iterations
773f08c3bdfSopenharmony_ci	fi
774f08c3bdfSopenharmony_ci
775f08c3bdfSopenharmony_ci	_tst_do_exit
776f08c3bdfSopenharmony_ci}
777f08c3bdfSopenharmony_ci
778f08c3bdfSopenharmony_ci_tst_run_iterations()
779f08c3bdfSopenharmony_ci{
780f08c3bdfSopenharmony_ci	local _tst_i=$TST_ITERATIONS
781f08c3bdfSopenharmony_ci	local _tst_j
782f08c3bdfSopenharmony_ci
783f08c3bdfSopenharmony_ci	[ "$TST_NEEDS_TMPDIR" = 1 ] && cd "$TST_TMPDIR"
784f08c3bdfSopenharmony_ci
785f08c3bdfSopenharmony_ci	_prepare_device
786f08c3bdfSopenharmony_ci
787f08c3bdfSopenharmony_ci	_tst_setup_timer
788f08c3bdfSopenharmony_ci
789f08c3bdfSopenharmony_ci	if [ -n "$TST_SETUP" ]; then
790f08c3bdfSopenharmony_ci		if command -v $TST_SETUP >/dev/null 2>/dev/null; then
791f08c3bdfSopenharmony_ci			TST_DO_CLEANUP=1
792f08c3bdfSopenharmony_ci			$TST_SETUP
793f08c3bdfSopenharmony_ci		else
794f08c3bdfSopenharmony_ci			tst_brk TBROK "TST_SETUP=$TST_SETUP declared, but function not defined (or cmd not found)"
795f08c3bdfSopenharmony_ci		fi
796f08c3bdfSopenharmony_ci	fi
797f08c3bdfSopenharmony_ci
798f08c3bdfSopenharmony_ci	#TODO check that test reports some results for each test function call
799f08c3bdfSopenharmony_ci	while [ $_tst_i -gt 0 ]; do
800f08c3bdfSopenharmony_ci		if [ -n "$TST_TEST_DATA" ]; then
801f08c3bdfSopenharmony_ci			tst_require_cmds cut tr wc
802f08c3bdfSopenharmony_ci			_tst_max=$(( $(echo $TST_TEST_DATA | tr -cd "$TST_TEST_DATA_IFS" | wc -c) +1))
803f08c3bdfSopenharmony_ci			for _tst_j in $(seq $_tst_max); do
804f08c3bdfSopenharmony_ci				_tst_data="$(echo "$TST_TEST_DATA" | cut -d"$TST_TEST_DATA_IFS" -f$_tst_j)"
805f08c3bdfSopenharmony_ci				_tst_run_tests "$_tst_data"
806f08c3bdfSopenharmony_ci			done
807f08c3bdfSopenharmony_ci		else
808f08c3bdfSopenharmony_ci			_tst_run_tests
809f08c3bdfSopenharmony_ci		fi
810f08c3bdfSopenharmony_ci		_tst_i=$((_tst_i-1))
811f08c3bdfSopenharmony_ci	done
812f08c3bdfSopenharmony_ci
813f08c3bdfSopenharmony_ci	_tst_do_cleanup
814f08c3bdfSopenharmony_ci
815f08c3bdfSopenharmony_ci	if [ "$TST_MOUNT_FLAG" = 1 ]; then
816f08c3bdfSopenharmony_ci		cd "$LTPROOT"
817f08c3bdfSopenharmony_ci		tst_umount
818f08c3bdfSopenharmony_ci		TST_MOUNT_FLAG=
819f08c3bdfSopenharmony_ci	fi
820f08c3bdfSopenharmony_ci}
821f08c3bdfSopenharmony_ci
822f08c3bdfSopenharmony_ci_tst_run_tests()
823f08c3bdfSopenharmony_ci{
824f08c3bdfSopenharmony_ci	local _tst_data="$1"
825f08c3bdfSopenharmony_ci	local _tst_i
826f08c3bdfSopenharmony_ci
827f08c3bdfSopenharmony_ci	TST_DO_CLEANUP=1
828f08c3bdfSopenharmony_ci	for _tst_i in $(seq ${TST_CNT:-1}); do
829f08c3bdfSopenharmony_ci		if command -v ${TST_TESTFUNC}1 > /dev/null 2>&1; then
830f08c3bdfSopenharmony_ci			_tst_run_test "$TST_TESTFUNC$_tst_i" $_tst_i "$_tst_data"
831f08c3bdfSopenharmony_ci		else
832f08c3bdfSopenharmony_ci			_tst_run_test "$TST_TESTFUNC" $_tst_i "$_tst_data"
833f08c3bdfSopenharmony_ci		fi
834f08c3bdfSopenharmony_ci	done
835f08c3bdfSopenharmony_ci}
836f08c3bdfSopenharmony_ci
837f08c3bdfSopenharmony_ci_tst_run_test()
838f08c3bdfSopenharmony_ci{
839f08c3bdfSopenharmony_ci	local _tst_res=$(_tst_resstr)
840f08c3bdfSopenharmony_ci	local _tst_fnc="$1"
841f08c3bdfSopenharmony_ci	shift
842f08c3bdfSopenharmony_ci
843f08c3bdfSopenharmony_ci	$_tst_fnc "$@"
844f08c3bdfSopenharmony_ci	_tst_rescmp "$_tst_res"
845f08c3bdfSopenharmony_ci	TST_COUNT=$((TST_COUNT+1))
846f08c3bdfSopenharmony_ci}
847f08c3bdfSopenharmony_ci
848f08c3bdfSopenharmony_ciexport LC_ALL=C
849f08c3bdfSopenharmony_ci
850f08c3bdfSopenharmony_ciif [ -z "$TST_ID" ]; then
851f08c3bdfSopenharmony_ci	_tst_filename=$(basename $0) || \
852f08c3bdfSopenharmony_ci		tst_brk TCONF "Failed to set TST_ID from \$0 ('$0'), fix it with setting TST_ID before sourcing tst_test.sh"
853f08c3bdfSopenharmony_ci	TST_ID=${_tst_filename%%.*}
854f08c3bdfSopenharmony_cifi
855f08c3bdfSopenharmony_ciexport TST_ID="$TST_ID"
856f08c3bdfSopenharmony_ci
857f08c3bdfSopenharmony_ciif [ -z "$LTPROOT" ]; then
858f08c3bdfSopenharmony_ci	export LTPROOT="$PWD"
859f08c3bdfSopenharmony_ci	export TST_DATAROOT="$LTPROOT/datafiles"
860f08c3bdfSopenharmony_cielse
861f08c3bdfSopenharmony_ci	export TST_DATAROOT="$LTPROOT/testcases/data/$TST_ID"
862f08c3bdfSopenharmony_cifi
863f08c3bdfSopenharmony_ci
864f08c3bdfSopenharmony_ciif [ -z "$TST_NO_DEFAULT_RUN" ]; then
865f08c3bdfSopenharmony_ci	if TST_TEST_PATH=$(command -v $0) 2>/dev/null; then
866f08c3bdfSopenharmony_ci		if ! grep -q tst_run "$TST_TEST_PATH"; then
867f08c3bdfSopenharmony_ci			tst_brk TBROK "Test $0 must call tst_run!"
868f08c3bdfSopenharmony_ci		fi
869f08c3bdfSopenharmony_ci	fi
870f08c3bdfSopenharmony_ci
871f08c3bdfSopenharmony_ci	if [ -z "$TST_TESTFUNC" ]; then
872f08c3bdfSopenharmony_ci		tst_brk TBROK "TST_TESTFUNC is not defined"
873f08c3bdfSopenharmony_ci	fi
874f08c3bdfSopenharmony_ci
875f08c3bdfSopenharmony_ci	TST_TEST_DATA_IFS="${TST_TEST_DATA_IFS:- }"
876f08c3bdfSopenharmony_ci
877f08c3bdfSopenharmony_ci	TST_NEEDS_KCONFIGS_IFS="${TST_NEEDS_KCONFIGS_IFS:-,}"
878f08c3bdfSopenharmony_ci
879f08c3bdfSopenharmony_ci	if [ -n "$TST_CNT" ]; then
880f08c3bdfSopenharmony_ci		if ! tst_is_int "$TST_CNT"; then
881f08c3bdfSopenharmony_ci			tst_brk TBROK "TST_CNT must be integer"
882f08c3bdfSopenharmony_ci		fi
883f08c3bdfSopenharmony_ci
884f08c3bdfSopenharmony_ci		if [ "$TST_CNT" -le 0 ]; then
885f08c3bdfSopenharmony_ci			tst_brk TBROK "TST_CNT must be > 0"
886f08c3bdfSopenharmony_ci		fi
887f08c3bdfSopenharmony_ci	fi
888f08c3bdfSopenharmony_ci
889f08c3bdfSopenharmony_ci	if [ -n "$TST_POS_ARGS" ]; then
890f08c3bdfSopenharmony_ci		if ! tst_is_int "$TST_POS_ARGS"; then
891f08c3bdfSopenharmony_ci			tst_brk TBROK "TST_POS_ARGS must be integer"
892f08c3bdfSopenharmony_ci		fi
893f08c3bdfSopenharmony_ci
894f08c3bdfSopenharmony_ci		if [ "$TST_POS_ARGS" -le 0 ]; then
895f08c3bdfSopenharmony_ci			tst_brk TBROK "TST_POS_ARGS must be > 0"
896f08c3bdfSopenharmony_ci		fi
897f08c3bdfSopenharmony_ci	fi
898f08c3bdfSopenharmony_ci
899f08c3bdfSopenharmony_ci	TST_ARGS="$@"
900f08c3bdfSopenharmony_ci
901f08c3bdfSopenharmony_ci	OPTIND=1
902f08c3bdfSopenharmony_ci
903f08c3bdfSopenharmony_ci	while getopts ":hi:$TST_OPTS" _tst_name $TST_ARGS; do
904f08c3bdfSopenharmony_ci		case $_tst_name in
905f08c3bdfSopenharmony_ci		'h') tst_usage; exit 0;;
906f08c3bdfSopenharmony_ci		'i') TST_ITERATIONS=$OPTARG;;
907f08c3bdfSopenharmony_ci		'?') tst_usage; exit 2;;
908f08c3bdfSopenharmony_ci		*) $TST_PARSE_ARGS "$_tst_name" "$OPTARG";;
909f08c3bdfSopenharmony_ci		esac
910f08c3bdfSopenharmony_ci	done
911f08c3bdfSopenharmony_ci
912f08c3bdfSopenharmony_ci	shift $((OPTIND - 1))
913f08c3bdfSopenharmony_ci
914f08c3bdfSopenharmony_ci	if [ -n "$TST_POS_ARGS" ]; then
915f08c3bdfSopenharmony_ci		if [ $# -ne "$TST_POS_ARGS" ]; then
916f08c3bdfSopenharmony_ci			tst_brk TBROK "Invalid number of positional parameters:"\
917f08c3bdfSopenharmony_ci					  "have ($@) $#, expected ${TST_POS_ARGS}"
918f08c3bdfSopenharmony_ci		fi
919f08c3bdfSopenharmony_ci	else
920f08c3bdfSopenharmony_ci		if [ $# -ne 0 ]; then
921f08c3bdfSopenharmony_ci			tst_brk TBROK "Unexpected positional arguments '$@'"
922f08c3bdfSopenharmony_ci		fi
923f08c3bdfSopenharmony_ci	fi
924f08c3bdfSopenharmony_cifi
925