xref: /spdk/test/common/autotest_common.sh (revision 61617956cb960d4e775c15137677771a1f626ef4)
1f3bea411SSeth Howell#!/usr/bin/env bash
2eb53c232Spaul luse#  SPDX-License-Identifier: BSD-3-Clause
3eb53c232Spaul luse#  Copyright (C) 2015 Intel Corporation
4eb53c232Spaul luse#  All rights reserved.
53f52d265SMike Gerdts#  Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
6eb53c232Spaul luse#
7eaebf841SKrzysztof Karasrpc_py=rpc_cmd
8eaebf841SKrzysztof Karas
913479ef5SMichal Bergerfunction xtrace_disable() {
1013479ef5SMichal Berger	set +x
1113479ef5SMichal Berger	X_STACK+=("${FUNCNAME[*]}") # push
1213479ef5SMichal Berger}
1313479ef5SMichal Berger
1413479ef5SMichal Bergerfunction xtrace_restore() {
1513479ef5SMichal Berger	# unset'ing foo[-1] under older Bash (4.2 -> Centos7) won't work, hence the dance
1613479ef5SMichal Berger	unset -v "X_STACK[${#X_STACK[@]} - 1 < 0 ? 0 : ${#X_STACK[@]} - 1]" # pop
1713479ef5SMichal Berger	if ((${#X_STACK[@]} == 0)); then
1813479ef5SMichal Berger		set -x
1913479ef5SMichal Berger	fi
2013479ef5SMichal Berger}
2113479ef5SMichal Berger
2213479ef5SMichal Bergerfunction xtrace_disable_per_cmd() { eval "$* ${BASH_XTRACEFD}> /dev/null"; }
2313479ef5SMichal Berger
24c2feee4fSMichal Bergerfunction xtrace_fd() {
253f52d265SMike Gerdts	if [[ -n ${BASH_XTRACEFD:-} && -e /proc/self/fd/$BASH_XTRACEFD ]]; then
26c2feee4fSMichal Berger		# Close it first to make sure it's sane
27c2feee4fSMichal Berger		exec {BASH_XTRACEFD}>&-
28c2feee4fSMichal Berger	fi
29c2feee4fSMichal Berger	exec {BASH_XTRACEFD}>&2
30c2feee4fSMichal Berger
3113479ef5SMichal Berger	xtrace_restore
32c2feee4fSMichal Berger}
33c2feee4fSMichal Berger
34fadcb08dSDarek Stojaczykset -e
354641aa53SMichal Bergershopt -s nullglob
364641aa53SMichal Bergershopt -s extglob
37c6338c36SMichal Bergershopt -s inherit_errexit
38fadcb08dSDarek Stojaczyk
39d5fe62b2SMichal Bergerif [ -z "${output_dir:-}" ]; then
40d5fe62b2SMichal Berger	mkdir -p "$rootdir/../output"
41d5fe62b2SMichal Berger	export output_dir="$rootdir/../output"
42d5fe62b2SMichal Bergerfi
43d5fe62b2SMichal Berger
446aa9db94SMichal Bergerif [[ -e $rootdir/test/common/build_config.sh ]]; then
456aa9db94SMichal Berger	source "$rootdir/test/common/build_config.sh"
466aa9db94SMichal Bergerelif [[ -e $rootdir/mk/config.mk ]]; then
476aa9db94SMichal Berger	build_config=$(< "$rootdir/mk/config.mk")
486aa9db94SMichal Berger	source <(echo "${build_config//\?=/=}")
496aa9db94SMichal Bergerelse
506aa9db94SMichal Berger	source "$rootdir/CONFIG"
516aa9db94SMichal Bergerfi
52b4c5509cSMichal Berger
535a21edf4SNick Connolly# Source scripts after the config so that the definitions are available.
545a21edf4SNick Connollysource "$rootdir/test/common/applications.sh"
555a21edf4SNick Connollysource "$rootdir/scripts/common.sh"
568d588fbcSMichal Bergersource "$rootdir/scripts/perf/pm/common"
575a21edf4SNick Connolly
58c9e5d2a6SSeth Howell: ${RUN_NIGHTLY:=0}
59c9e5d2a6SSeth Howellexport RUN_NIGHTLY
60c9e5d2a6SSeth Howell
61c9e5d2a6SSeth Howell# Set defaults for missing test config options
62844c8ec3SMichal Berger: ${SPDK_AUTOTEST_DEBUG_APPS:=0}
63844c8ec3SMichal Bergerexport SPDK_AUTOTEST_DEBUG_APPS
64844c8ec3SMichal Berger: ${SPDK_RUN_VALGRIND=0}
65844c8ec3SMichal Bergerexport SPDK_RUN_VALGRIND
66844c8ec3SMichal Berger: ${SPDK_RUN_FUNCTIONAL_TEST=0}
67844c8ec3SMichal Bergerexport SPDK_RUN_FUNCTIONAL_TEST
68844c8ec3SMichal Berger: ${SPDK_TEST_UNITTEST=0}
69844c8ec3SMichal Bergerexport SPDK_TEST_UNITTEST
70f658f463SPawel Piatek: ${SPDK_TEST_AUTOBUILD=""}
71844c8ec3SMichal Bergerexport SPDK_TEST_AUTOBUILD
72af62eb57SKarol Latecki: ${SPDK_TEST_RELEASE_BUILD=0}
73af62eb57SKarol Lateckiexport SPDK_TEST_RELEASE_BUILD
74844c8ec3SMichal Berger: ${SPDK_TEST_ISAL=0}
75844c8ec3SMichal Bergerexport SPDK_TEST_ISAL
76844c8ec3SMichal Berger: ${SPDK_TEST_ISCSI=0}
77844c8ec3SMichal Bergerexport SPDK_TEST_ISCSI
78844c8ec3SMichal Berger: ${SPDK_TEST_ISCSI_INITIATOR=0}
79844c8ec3SMichal Bergerexport SPDK_TEST_ISCSI_INITIATOR
80844c8ec3SMichal Berger: ${SPDK_TEST_NVME=0}
81844c8ec3SMichal Bergerexport SPDK_TEST_NVME
82e04da24cSKrishna Kanth Reddy: ${SPDK_TEST_NVME_PMR=0}
83e04da24cSKrishna Kanth Reddyexport SPDK_TEST_NVME_PMR
84e93e308dSKrishna Kanth Reddy: ${SPDK_TEST_NVME_BP=0}
85e93e308dSKrishna Kanth Reddyexport SPDK_TEST_NVME_BP
86844c8ec3SMichal Berger: ${SPDK_TEST_NVME_CLI=0}
87844c8ec3SMichal Bergerexport SPDK_TEST_NVME_CLI
88844c8ec3SMichal Berger: ${SPDK_TEST_NVME_CUSE=0}
89844c8ec3SMichal Bergerexport SPDK_TEST_NVME_CUSE
90c976353bSAnkit Kumar: ${SPDK_TEST_NVME_FDP=0}
91c976353bSAnkit Kumarexport SPDK_TEST_NVME_FDP
92844c8ec3SMichal Berger: ${SPDK_TEST_NVMF=0}
93844c8ec3SMichal Bergerexport SPDK_TEST_NVMF
943b673b84SChangpeng Liu: ${SPDK_TEST_VFIOUSER=0}
953b673b84SChangpeng Liuexport SPDK_TEST_VFIOUSER
96a0d255acSMao Jiang: ${SPDK_TEST_VFIOUSER_QEMU=0}
97a0d255acSMao Jiangexport SPDK_TEST_VFIOUSER_QEMU
9859a0d2c6SJun Wen: ${SPDK_TEST_FUZZER=0}
9959a0d2c6SJun Wenexport SPDK_TEST_FUZZER
10003402efdSJun Wen: ${SPDK_TEST_FUZZER_SHORT=0}
10103402efdSJun Wenexport SPDK_TEST_FUZZER_SHORT
102844c8ec3SMichal Berger: ${SPDK_TEST_NVMF_TRANSPORT="rdma"}
103844c8ec3SMichal Bergerexport SPDK_TEST_NVMF_TRANSPORT
104844c8ec3SMichal Berger: ${SPDK_TEST_RBD=0}
105844c8ec3SMichal Bergerexport SPDK_TEST_RBD
106844c8ec3SMichal Berger: ${SPDK_TEST_VHOST=0}
107844c8ec3SMichal Bergerexport SPDK_TEST_VHOST
108844c8ec3SMichal Berger: ${SPDK_TEST_BLOCKDEV=0}
109844c8ec3SMichal Bergerexport SPDK_TEST_BLOCKDEV
110cac68eecSKamil Godzwon: ${SPDK_TEST_RAID=0}
111cac68eecSKamil Godzwonexport SPDK_TEST_RAID
112844c8ec3SMichal Berger: ${SPDK_TEST_IOAT=0}
113844c8ec3SMichal Bergerexport SPDK_TEST_IOAT
114844c8ec3SMichal Berger: ${SPDK_TEST_BLOBFS=0}
115844c8ec3SMichal Bergerexport SPDK_TEST_BLOBFS
116844c8ec3SMichal Berger: ${SPDK_TEST_VHOST_INIT=0}
117844c8ec3SMichal Bergerexport SPDK_TEST_VHOST_INIT
118844c8ec3SMichal Berger: ${SPDK_TEST_LVOL=0}
119844c8ec3SMichal Bergerexport SPDK_TEST_LVOL
12019e2dc38Spaul luse: ${SPDK_TEST_VBDEV_COMPRESS=0}
12119e2dc38Spaul luseexport SPDK_TEST_VBDEV_COMPRESS
122844c8ec3SMichal Berger: ${SPDK_RUN_ASAN=0}
123844c8ec3SMichal Bergerexport SPDK_RUN_ASAN
124844c8ec3SMichal Berger: ${SPDK_RUN_UBSAN=0}
125844c8ec3SMichal Bergerexport SPDK_RUN_UBSAN
12649473bdcSDarek Stojaczyk: ${SPDK_RUN_EXTERNAL_DPDK=""}
12749473bdcSDarek Stojaczykexport SPDK_RUN_EXTERNAL_DPDK
128844c8ec3SMichal Berger: ${SPDK_RUN_NON_ROOT=0}
129844c8ec3SMichal Bergerexport SPDK_RUN_NON_ROOT
130844c8ec3SMichal Berger: ${SPDK_TEST_CRYPTO=0}
131844c8ec3SMichal Bergerexport SPDK_TEST_CRYPTO
132844c8ec3SMichal Berger: ${SPDK_TEST_FTL=0}
133844c8ec3SMichal Bergerexport SPDK_TEST_FTL
134844c8ec3SMichal Berger: ${SPDK_TEST_OCF=0}
135844c8ec3SMichal Bergerexport SPDK_TEST_OCF
136844c8ec3SMichal Berger: ${SPDK_TEST_VMD=0}
137844c8ec3SMichal Bergerexport SPDK_TEST_VMD
138844c8ec3SMichal Berger: ${SPDK_TEST_OPAL=0}
139844c8ec3SMichal Bergerexport SPDK_TEST_OPAL
14030116833SDarek Stojaczyk: ${SPDK_TEST_NATIVE_DPDK}
14130116833SDarek Stojaczykexport SPDK_TEST_NATIVE_DPDK
142844c8ec3SMichal Berger: ${SPDK_AUTOTEST_X=true}
143844c8ec3SMichal Bergerexport SPDK_AUTOTEST_X
144cd8b9455SZiye Yang: ${SPDK_TEST_URING=0}
145cd8b9455SZiye Yangexport SPDK_TEST_URING
14691751e1eSMonica Kenguva: ${SPDK_TEST_USDT=0}
14791751e1eSMonica Kenguvaexport SPDK_TEST_USDT
148785d6ca2SMichal Berger: ${SPDK_TEST_USE_IGB_UIO:=0}
149785d6ca2SMichal Bergerexport SPDK_TEST_USE_IGB_UIO
150c313f1b2SMichal Berger: ${SPDK_TEST_SCHEDULER:=0}
151c313f1b2SMichal Bergerexport SPDK_TEST_SCHEDULER
1523a53213fSMichal Berger: ${SPDK_TEST_SCANBUILD:=0}
1533a53213fSMichal Bergerexport SPDK_TEST_SCANBUILD
154c32476bbSMichal Berger: ${SPDK_TEST_NVMF_NICS:=}
155c32476bbSMichal Bergerexport SPDK_TEST_NVMF_NICS
156cfbab2dcSJaroslaw Chachulski: ${SPDK_TEST_SMA=0}
157cfbab2dcSJaroslaw Chachulskiexport SPDK_TEST_SMA
1582e283fcbS0xe0f: ${SPDK_TEST_DAOS=0}
1592e283fcbS0xe0fexport SPDK_TEST_DAOS
160c8f62d79SMichal Berger: ${SPDK_TEST_XNVME:=0}
161c8f62d79SMichal Bergerexport SPDK_TEST_XNVME
1628711e7e9SKamil Godzwon: ${SPDK_TEST_ACCEL:=0}
1638711e7e9SKamil Godzwonexport SPDK_TEST_ACCEL
164cbfd7a26SKarol Latecki: ${SPDK_TEST_ACCEL_DSA=0}
165cbfd7a26SKarol Lateckiexport SPDK_TEST_ACCEL_DSA
166cbfd7a26SKarol Latecki: ${SPDK_TEST_ACCEL_IAA=0}
167cbfd7a26SKarol Lateckiexport SPDK_TEST_ACCEL_IAA
168f72f1547SMichal Berger# Comma-separated list of fuzzer targets matching test/fuzz/llvm/$target
169f72f1547SMichal Berger: ${SPDK_TEST_FUZZER_TARGET:=}
170f72f1547SMichal Bergerexport SPDK_TEST_FUZZER_TARGET
1716d4d5c62SParameswaran Krishnamurthy: ${SPDK_TEST_NVMF_MDNS=0}
1726d4d5c62SParameswaran Krishnamurthyexport SPDK_TEST_NVMF_MDNS
173fa79ecf8SEmilia Haligowska: ${SPDK_JSONRPC_GO_CLIENT=0}
174fa79ecf8SEmilia Haligowskaexport SPDK_JSONRPC_GO_CLIENT
175b4e49c37SJaroslaw Chachulski: ${SPDK_TEST_SETUP=0}
176b4e49c37SJaroslaw Chachulskiexport SPDK_TEST_SETUP
1778531656dSAnkit Kumar: ${SPDK_TEST_NVME_INTERRUPT=0}
1788531656dSAnkit Kumarexport SPDK_TEST_NVME_INTERRUPT
179c9e5d2a6SSeth Howell
180b8a51a93STomasz Zawadzki# always test with SPDK shared objects.
181b8a51a93STomasz Zawadzkiexport SPDK_LIB_DIR="$rootdir/build/lib"
18230116833SDarek Stojaczykexport DPDK_LIB_DIR="${SPDK_RUN_EXTERNAL_DPDK:-$rootdir/dpdk/build}/lib"
183619da103SChangpeng Liuexport VFIO_LIB_DIR="$rootdir/build/libvfio-user/usr/local/lib"
184b8a51a93STomasz Zawadzkiexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SPDK_LIB_DIR:$DPDK_LIB_DIR:$VFIO_LIB_DIR
18530116833SDarek Stojaczyk
18644775a80SMichal Berger# Tell setup.sh to wait for block devices upon each reset
18744775a80SMichal Bergerexport PCI_BLOCK_SYNC_ON_RESET=yes
18844775a80SMichal Berger
18905dde5c2STomasz Zawadzki# Export PYTHONPATH with addition of RPC framework. New scripts can be created
19005dde5c2STomasz Zawadzki# specific use cases for tests.
1917610bc38SKonrad Sztyberexport PYTHONPATH=$PYTHONPATH:$rootdir/python
19205dde5c2STomasz Zawadzki
193f657669eSKarol Latecki# Don't create Python .pyc files. When running with sudo these will be
194f657669eSKarol Latecki# created with root ownership and can cause problems when cleaning the repository.
195f657669eSKarol Lateckiexport PYTHONDONTWRITEBYTECODE=1
196f657669eSKarol Latecki
197cc2a4920SSebastian Brzezinka# Export new_delete_type_mismatch to skip the known bug that exists in librados
198cc2a4920SSebastian Brzezinka# https://tracker.ceph.com/issues/24078
19923b3340fSTomasz Zawadzkiexport ASAN_OPTIONS=new_delete_type_mismatch=0:disable_coredump=0:abort_on_error=1:use_sigaltstack=0
20049ba9965SKonrad Sztyberexport UBSAN_OPTIONS='halt_on_error=1:print_stacktrace=1:abort_on_error=1:disable_coredump=0:exitcode=134'
201f40d2451SSeth Howell
2029fda9814STomasz Zawadzki# Export LeakSanitizer option to use suppression file in order to prevent false positives
2039fda9814STomasz Zawadzki# and known leaks in external executables or libraries from showing up.
2049fda9814STomasz Zawadzkiasan_suppression_file="/var/tmp/asan_suppression_file"
205b9a66791SAlexis Lescouetrm -rf "$asan_suppression_file" 2> /dev/null || sudo rm -rf "$asan_suppression_file"
20602925187SMaciej Wawrykcat << EOL >> "$asan_suppression_file"
2079fda9814STomasz Zawadzki# ASAN has some bugs around thread_local variables.  We have a destructor in place
2089fda9814STomasz Zawadzki# to free the thread contexts, but ASAN complains about the leak before those
2099fda9814STomasz Zawadzki# destructors have a chance to run.  So suppress this one specific leak using
2109fda9814STomasz Zawadzki# LSAN_OPTIONS.
21102925187SMaciej Wawrykleak:spdk_fs_alloc_thread_ctx
2129fda9814STomasz Zawadzki
2131bed9c1fSTomasz Zawadzki# Suppress known leaks in fio project
214053c15b3SMichal Bergerleak:$CONFIG_FIO_SOURCE_DIR/parse.c
215053c15b3SMichal Bergerleak:$CONFIG_FIO_SOURCE_DIR/iolog.c
216053c15b3SMichal Bergerleak:$CONFIG_FIO_SOURCE_DIR/init.c
217053c15b3SMichal Bergerleak:$CONFIG_FIO_SOURCE_DIR/filesetup.c
21802925187SMaciej Wawrykleak:fio_memalign
21902925187SMaciej Wawrykleak:spdk_fio_io_u_init
220bec627fcSMichal Berger# Suppress leaks in gperftools-libs from fio
221bec627fcSMichal Bergerleak:libtcmalloc_minimal.so
2221bed9c1fSTomasz Zawadzki
2231891f2e5STomasz Zawadzki# Suppress leaks in libiscsi
22402925187SMaciej Wawrykleak:libiscsi.so
225690cf1c9SKarol Latecki
226690cf1c9SKarol Latecki# Suppress leaks in libcrypto
227690cf1c9SKarol Latecki# Below is caused by openssl 3.0.8 leaks
228690cf1c9SKarol Lateckileak:libcrypto.so
2299d513abfSTomasz Zawadzki
2309d513abfSTomasz Zawadzki# Suppress leaks in accel-config
2319d513abfSTomasz Zawadzki# Versions with unresolved leaks:
2329d513abfSTomasz Zawadzki# v3.4.6.4 [Fedora 37]
2339d513abfSTomasz Zawadzkileak:add_wq
2349d513abfSTomasz Zawadzkileak:add_group
2359d513abfSTomasz Zawadzki# v3.5.2 [Fedora 38]
2369d513abfSTomasz Zawadzkileak:accfg_get_param_str
2379d513abfSTomasz Zawadzki# v4.0 [Fedora 39]
2389d513abfSTomasz Zawadzkileak:__scandir64_tail
23902925187SMaciej WawrykEOL
2401891f2e5STomasz Zawadzki
2418e70c6e3STomasz Kulasek# Suppress leaks in libfuse3
2428e70c6e3STomasz Kulasekecho "leak:libfuse3.so" >> "$asan_suppression_file"
2438e70c6e3STomasz Kulasek
2449fda9814STomasz Zawadzkiexport LSAN_OPTIONS=suppressions="$asan_suppression_file"
2459fda9814STomasz Zawadzki
246f40d2451SSeth Howellexport DEFAULT_RPC_ADDR="/var/tmp/spdk.sock"
247f40d2451SSeth Howell
2483f52d265SMike Gerdtsif [ -z "${DEPENDENCY_DIR:-}" ]; then
249a4a04624SMichal Berger	export DEPENDENCY_DIR=/var/spdk/dependencies
250f04277f0SJohn Meneghinielse
251f04277f0SJohn Meneghini	export DEPENDENCY_DIR
252f04277f0SJohn Meneghinifi
253f04277f0SJohn Meneghini
2546b9b448eSBen Walker# Export location of where all the SPDK binaries are
2556b9b448eSBen Walkerexport SPDK_BIN_DIR="$rootdir/build/bin"
25685bdd43bSBen Walkerexport SPDK_EXAMPLE_DIR="$rootdir/build/examples"
2576b9b448eSBen Walker
2586abaf4fcSMichal Berger# for vhost, vfio-user tests
2596abaf4fcSMichal Bergerexport QEMU_BIN=${QEMU_BIN:-}
2606abaf4fcSMichal Bergerexport VFIO_QEMU_BIN=${VFIO_QEMU_BIN:-}
2616abaf4fcSMichal Berger
262c8f62d79SMichal Bergerexport AR_TOOL=$rootdir/scripts/ar-xnvme-fixer
263c8f62d79SMichal Berger
264db0d8682SMichal Berger# For testing nvmes which are attached to some sort of a fanout switch in the CI pool
265db0d8682SMichal Bergerexport UNBIND_ENTIRE_IOMMU_GROUP=${UNBIND_ENTIRE_IOMMU_GROUP:-no}
266db0d8682SMichal Berger
2676f2b8056SMichal Berger_LCOV_MAIN=0
2686f2b8056SMichal Berger_LCOV_LLVM=1
2696f2b8056SMichal Berger_LCOV=$LCOV_MAIN
2706f2b8056SMichal Berger[[ $CC == *clang* || $SPDK_TEST_FUZZER -eq 1 ]] && _LCOV=$_LCOV_LLVM
2716f2b8056SMichal Berger
2726f2b8056SMichal Berger_lcov_opt[_LCOV_LLVM]="--gcov-tool $rootdir/test/fuzz/llvm/llvm-gcov.sh"
2736f2b8056SMichal Berger_lcov_opt[_LCOV_MAIN]=""
2746f2b8056SMichal Berger
2756f2b8056SMichal Bergerlcov_opt=${_lcov_opt[_LCOV]}
2766f2b8056SMichal Berger
277c9e5d2a6SSeth Howell# pass our valgrind desire on to unittest.sh
278c9e5d2a6SSeth Howellif [ $SPDK_RUN_VALGRIND -eq 0 ]; then
279c9e5d2a6SSeth Howell	export valgrind=''
2801f4a8945SMichal Bergerelse
2811f4a8945SMichal Berger	# unset all DEBUGINFOD_* vars that may affect our valgrind instance
2821f4a8945SMichal Berger	unset -v "${!DEBUGINFOD_@}"
283c9e5d2a6SSeth Howellfi
284c9e5d2a6SSeth Howell
285f40d2451SSeth Howellif [ "$(uname -s)" = "Linux" ]; then
28699fb6780SJim Harris	HUGEMEM=${HUGEMEM:-4096}
28799fb6780SJim Harris	export CLEAR_HUGE=yes
288227428c3SMichal Berger
28938d4a2a2SPawel Kaminski	MAKE="make"
290f40d2451SSeth Howell	MAKEFLAGS=${MAKEFLAGS:--j$(nproc)}
291f40d2451SSeth Howellelif [ "$(uname -s)" = "FreeBSD" ]; then
29238d4a2a2SPawel Kaminski	MAKE="gmake"
293772eb8ebSKarol Latecki	MAKEFLAGS=${MAKEFLAGS:--j$(sysctl -a | grep -E -i 'hw.ncpu' | awk '{print $2}')}
294f40d2451SSeth Howell	# FreeBSD runs a much more limited set of tests, so keep the default 2GB.
29599fb6780SJim Harris	HUGEMEM=${HUGEMEM:-2048}
2965a21edf4SNick Connollyelif [ "$(uname -s)" = "Windows" ]; then
2975a21edf4SNick Connolly	MAKE="make"
2985a21edf4SNick Connolly	MAKEFLAGS=${MAKEFLAGS:--j$(nproc)}
2995a21edf4SNick Connolly	# Keep the default 2GB for Windows.
30099fb6780SJim Harris	HUGEMEM=${HUGEMEM:-2048}
301f40d2451SSeth Howellelse
302f40d2451SSeth Howell	echo "Unknown OS \"$(uname -s)\""
303f40d2451SSeth Howell	exit 1
304f40d2451SSeth Howellfi
305f40d2451SSeth Howell
30699fb6780SJim Harrisexport HUGEMEM=$HUGEMEM
30799fb6780SJim Harris
3081826245aSSarvesh LankeNO_HUGE=()
3094f7f0f09SSeth HowellTEST_MODE=
3104f7f0f09SSeth Howellfor i in "$@"; do
3114f7f0f09SSeth Howell	case "$i" in
3124f7f0f09SSeth Howell		--iso)
3134f7f0f09SSeth Howell			TEST_MODE=iso
3144f7f0f09SSeth Howell			;;
3154f7f0f09SSeth Howell		--transport=*)
3164f7f0f09SSeth Howell			TEST_TRANSPORT="${i#*=}"
3174f7f0f09SSeth Howell			;;
3184f7f0f09SSeth Howell		--sock=*)
3194f7f0f09SSeth Howell			TEST_SOCK="${i#*=}"
3204f7f0f09SSeth Howell			;;
3211826245aSSarvesh Lanke		--no-hugepages)
3221826245aSSarvesh Lanke			NO_HUGE=(--no-huge -s 1024)
3231826245aSSarvesh Lanke			;;
32481fc34dfSKrzysztof Goreczny		--interrupt-mode)
32581fc34dfSKrzysztof Goreczny			TEST_INTERRUPT_MODE=1
32681fc34dfSKrzysztof Goreczny			;;
3274f7f0f09SSeth Howell	esac
3284f7f0f09SSeth Howelldone
3294f7f0f09SSeth Howell
3304f7f0f09SSeth Howell# start rpc.py coprocess if it's not started yet
3313f52d265SMike Gerdtsif [[ -z ${RPC_PIPE_PID:-} ]] || ! kill -0 "$RPC_PIPE_PID" &> /dev/null; then
3327347f60bSMichal Berger	# Include list to all known plugins we use in the tests
3337347f60bSMichal Berger	PYTHONPATH+=":$rootdir/test/rpc_plugins"
3347347f60bSMichal Berger	coproc RPC_PIPE { PYTHONPATH="$PYTHONPATH" "$rootdir/scripts/rpc.py" --server; }
3354f7f0f09SSeth Howell	exec {RPC_PIPE_OUTPUT}<&${RPC_PIPE[0]} {RPC_PIPE_INPUT}>&${RPC_PIPE[1]}
3364f7f0f09SSeth Howell	# all descriptors will automatically close together with this bash
3374f7f0f09SSeth Howell	# process, this will make rpc.py stop reading and exit gracefully
3384f7f0f09SSeth Howellfi
3394f7f0f09SSeth Howell
3401430096aSMichal Bergerfunction set_test_storage() {
3411430096aSMichal Berger	[[ -v testdir ]] || return 0
3421430096aSMichal Berger
3431430096aSMichal Berger	local requested_size=$1 # bytes
3441430096aSMichal Berger	local mount target_dir
3451430096aSMichal Berger
3461430096aSMichal Berger	local -A mounts fss sizes avails uses
3471430096aSMichal Berger	local source fs size avail mount use
3481430096aSMichal Berger
3491430096aSMichal Berger	local storage_fallback storage_candidates
3509aeaafa1SMichal Berger
3519aeaafa1SMichal Berger	storage_fallback=$(mktemp -udt spdk.XXXXXX)
3521430096aSMichal Berger	storage_candidates=(
3531430096aSMichal Berger		"$testdir"
3541430096aSMichal Berger		"$storage_fallback/tests/${testdir##*/}"
3551430096aSMichal Berger		"$storage_fallback"
3561430096aSMichal Berger	)
3571430096aSMichal Berger
3583f52d265SMike Gerdts	if [[ -n ${ADD_TEST_STORAGE:-} ]]; then
3591430096aSMichal Berger		# List of dirs|mounts separated by whitespaces
3601430096aSMichal Berger		storage_candidates+=($ADD_TEST_STORAGE)
3611430096aSMichal Berger	fi
3621430096aSMichal Berger
3633f52d265SMike Gerdts	if [[ -n ${DEDICATED_TEST_STORAGE:-} ]]; then
3641430096aSMichal Berger		# Single, dedicated dir|mount
3651430096aSMichal Berger		storage_candidates=("$DEDICATED_TEST_STORAGE")
3661430096aSMichal Berger	fi
3671430096aSMichal Berger
3681430096aSMichal Berger	mkdir -p "${storage_candidates[@]}"
3691430096aSMichal Berger
3701430096aSMichal Berger	# add some headroom - 64M
3711430096aSMichal Berger	requested_size=$((requested_size + (64 << 20)))
3721430096aSMichal Berger
3731430096aSMichal Berger	while read -r source fs size use avail _ mount; do
3741430096aSMichal Berger		mounts["$mount"]=$source fss["$mount"]=$fs
3751430096aSMichal Berger		avails["$mount"]=$((avail * 1024)) sizes["$mount"]=$((size * 1024))
3761430096aSMichal Berger		uses["$mount"]=$((use * 1024))
3771430096aSMichal Berger	done < <(df -T | grep -v Filesystem)
3781430096aSMichal Berger
3791430096aSMichal Berger	printf '* Looking for test storage...\n' >&2
3801430096aSMichal Berger
3811430096aSMichal Berger	local target_space new_size
3821430096aSMichal Berger	for target_dir in "${storage_candidates[@]}"; do
3831430096aSMichal Berger		# FreeBSD's df is lacking the --output arg
3841430096aSMichal Berger		# mount=$(df --output=target "$target_dir" | grep -v "Mounted on")
3851430096aSMichal Berger		mount=$(df "$target_dir" | awk '$1 !~ /Filesystem/{print $6}')
3861430096aSMichal Berger
3871430096aSMichal Berger		target_space=${avails["$mount"]}
3881430096aSMichal Berger		if ((target_space == 0 || target_space < requested_size)); then
3891430096aSMichal Berger			continue
3901430096aSMichal Berger		fi
3911430096aSMichal Berger		if ((target_space >= requested_size)); then
3921430096aSMichal Berger			# For in-memory fs, and / make sure our requested size won't fill most of the space.
3931430096aSMichal Berger			if [[ ${fss["$mount"]} == tmpfs ]] || [[ ${fss["$mount"]} == ramfs ]] || [[ $mount == / ]]; then
3941430096aSMichal Berger				new_size=$((uses["$mount"] + requested_size))
3951430096aSMichal Berger				if ((new_size * 100 / sizes["$mount"] > 95)); then
3961430096aSMichal Berger					continue
3971430096aSMichal Berger				fi
3981430096aSMichal Berger			fi
3991430096aSMichal Berger		fi
4001430096aSMichal Berger		export SPDK_TEST_STORAGE=$target_dir
4011430096aSMichal Berger		printf '* Found test storage at %s\n' "$SPDK_TEST_STORAGE" >&2
4021430096aSMichal Berger		return 0
4031430096aSMichal Berger	done
4041430096aSMichal Berger	printf '* Test storage is not available\n'
4051430096aSMichal Berger	return 1
4061430096aSMichal Berger}
4071430096aSMichal Berger
4084f7f0f09SSeth Howellfunction get_config_params() {
4094f7f0f09SSeth Howell	xtrace_disable
410c9e5d2a6SSeth Howell	config_params='--enable-debug --enable-werror'
411c9e5d2a6SSeth Howell
4128a43cd27Spaul luse	# for options with dependencies but no test flag, set them here
4138a43cd27Spaul luse	if [ -f /usr/include/infiniband/verbs.h ]; then
4148a43cd27Spaul luse		config_params+=' --with-rdma'
4158a43cd27Spaul luse	fi
4168a43cd27Spaul luse
41791751e1eSMonica Kenguva	if [ $SPDK_TEST_USDT -eq 1 ]; then
41891751e1eSMonica Kenguva		config_params+=" --with-usdt"
41991751e1eSMonica Kenguva	fi
42091751e1eSMonica Kenguva
421e2d2ca7cSJim Harris	case "$(uname -s)" in
422e2d2ca7cSJim Harris		FreeBSD) [[ $(sysctl -n hw.model) == Intel* ]] ;;
423e2d2ca7cSJim Harris		Linux) [[ $(< /proc/cpuinfo) == *GenuineIntel* ]] ;;
424e2d2ca7cSJim Harris		*) false ;;
425e2d2ca7cSJim Harris	esac && config_params+=" --with-idxd" || config_params+=" --without-idxd"
426e58e9fbdSpaul luse
427053c15b3SMichal Berger	if [[ -d $CONFIG_FIO_SOURCE_DIR ]]; then
428053c15b3SMichal Berger		config_params+=" --with-fio=$CONFIG_FIO_SOURCE_DIR"
4298a43cd27Spaul luse	fi
4308a43cd27Spaul luse
4318a43cd27Spaul luse	if [ -d ${DEPENDENCY_DIR}/vtune_codes ]; then
4328a43cd27Spaul luse		config_params+=' --with-vtune='${DEPENDENCY_DIR}'/vtune_codes'
4338a43cd27Spaul luse	fi
4348a43cd27Spaul luse
4358a43cd27Spaul luse	if [ -d /usr/include/iscsi ]; then
43685bf4c81SMichal Berger		[[ $(< /usr/include/iscsi/iscsi.h) =~ "define LIBISCSI_API_VERSION ("([0-9]+)")" ]] \
43785bf4c81SMichal Berger			&& libiscsi_version=${BASH_REMATCH[1]}
43885bf4c81SMichal Berger		if ((libiscsi_version >= 20150621)); then
4398a43cd27Spaul luse			config_params+=' --with-iscsi-initiator'
4408a43cd27Spaul luse		fi
4418a43cd27Spaul luse	fi
4428a43cd27Spaul luse
443dfb2950fSMichal Berger	if [[ $SPDK_TEST_UNITTEST -eq 0 &&
444dfb2950fSMichal Berger		$SPDK_TEST_SCANBUILD -eq 0 && -z ${SPDK_TEST_AUTOBUILD:-} ]]; then
44579c28aa6STomasz Zawadzki		config_params+=' --disable-unit-tests'
44679c28aa6STomasz Zawadzki	fi
44779c28aa6STomasz Zawadzki
44819e2dc38Spaul luse	if [ -f /usr/include/libpmem.h ] && [ $SPDK_TEST_VBDEV_COMPRESS -eq 1 ]; then
449dbd140b2SMichal Berger		if ge "$(nasm --version | awk '{print $3}')" 2.14 && [[ $SPDK_TEST_ISAL -eq 1 ]]; then
450976f8b09Spaul luse			config_params+=' --with-vbdev-compress --with-dpdk-compressdev'
4518a43cd27Spaul luse		fi
4528a43cd27Spaul luse	fi
4538a43cd27Spaul luse
4548a43cd27Spaul luse	if [ -d /usr/include/rbd ] && [ -d /usr/include/rados ] && [ $SPDK_TEST_RBD -eq 1 ]; then
4558a43cd27Spaul luse		config_params+=' --with-rbd'
4568a43cd27Spaul luse	fi
4578a43cd27Spaul luse
4588a43cd27Spaul luse	# for options with no required dependencies, just test flags, set them here
45951606ed4SPaul Luse	if [ $SPDK_TEST_CRYPTO -eq 1 ]; then
46051606ed4SPaul Luse		config_params+=' --with-crypto'
46151606ed4SPaul Luse	fi
46251606ed4SPaul Luse
4632fde729fSVitaliy Mysak	if [ $SPDK_TEST_OCF -eq 1 ]; then
46434bdceabSVitaliy Mysak		config_params+=" --with-ocf"
4652fde729fSVitaliy Mysak	fi
4662fde729fSVitaliy Mysak
467e20401c8SDarek Stojaczyk	if [ $SPDK_RUN_UBSAN -eq 1 ]; then
468e20401c8SDarek Stojaczyk		config_params+=' --enable-ubsan'
469e20401c8SDarek Stojaczyk	fi
470e20401c8SDarek Stojaczyk
471e20401c8SDarek Stojaczyk	if [ $SPDK_RUN_ASAN -eq 1 ]; then
472e20401c8SDarek Stojaczyk		config_params+=' --enable-asan'
473e20401c8SDarek Stojaczyk	fi
474e20401c8SDarek Stojaczyk
475c9e5d2a6SSeth Howell	config_params+=' --enable-coverage'
476c9e5d2a6SSeth Howell
4777fa15e28SXiaodong Liu	if [ $SPDK_TEST_BLOBFS -eq 1 ]; then
4785f66e5b1SChangpeng Liu		if [[ -d /usr/include/fuse3 ]] || [[ -d /usr/local/include/fuse3 ]]; then
4797fa15e28SXiaodong Liu			config_params+=' --with-fuse'
4807fa15e28SXiaodong Liu		fi
4817fa15e28SXiaodong Liu	fi
4827fa15e28SXiaodong Liu
48340e8ee2aSYifan Bian	if [[ -f /usr/include/liburing/io_uring.h && -f /usr/include/linux/ublk_cmd.h ]]; then
48440e8ee2aSYifan Bian		config_params+=' --with-ublk'
48540e8ee2aSYifan Bian	fi
48640e8ee2aSYifan Bian
487cac68eecSKamil Godzwon	if [ $SPDK_TEST_RAID -eq 1 ]; then
48883a4b155SArtur Paszkiewicz		config_params+=' --with-raid5f'
48973763d40SArtur Paszkiewicz	fi
49073763d40SArtur Paszkiewicz
4914978c4feSXin Yang	if [ $SPDK_TEST_VFIOUSER -eq 1 ] || [ $SPDK_TEST_VFIOUSER_QEMU -eq 1 ] || [ $SPDK_TEST_SMA -eq 1 ]; then
4923b673b84SChangpeng Liu		config_params+=' --with-vfio-user'
4933b673b84SChangpeng Liu	fi
4943b673b84SChangpeng Liu
495cd8b9455SZiye Yang	# Check whether liburing library header exists
496cd8b9455SZiye Yang	if [ -f /usr/include/liburing/io_uring.h ] && [ $SPDK_TEST_URING -eq 1 ]; then
497cd8b9455SZiye Yang		config_params+=' --with-uring'
498cd8b9455SZiye Yang	fi
499cd8b9455SZiye Yang
5003f52d265SMike Gerdts	if [ -n "${SPDK_RUN_EXTERNAL_DPDK:-}" ]; then
50149473bdcSDarek Stojaczyk		config_params+=" --with-dpdk=$SPDK_RUN_EXTERNAL_DPDK"
502c9e5d2a6SSeth Howell	fi
503c9e5d2a6SSeth Howell
504cfbab2dcSJaroslaw Chachulski	if [[ $SPDK_TEST_SMA -eq 1 ]]; then
505cfbab2dcSJaroslaw Chachulski		config_params+=' --with-sma'
506a9d10dadSSebastian Brzezinka		config_params+=' --with-crypto'
507cfbab2dcSJaroslaw Chachulski	fi
508cfbab2dcSJaroslaw Chachulski
5092e283fcbS0xe0f	if [ -f /usr/include/daos.h ] && [ $SPDK_TEST_DAOS -eq 1 ]; then
5102e283fcbS0xe0f		config_params+=' --with-daos'
5112e283fcbS0xe0f	fi
5122e283fcbS0xe0f
513c8f62d79SMichal Berger	# Make the xnvme module available for the tests
514c8f62d79SMichal Berger	if [[ $SPDK_TEST_XNVME -eq 1 ]]; then
515c8f62d79SMichal Berger		config_params+=' --with-xnvme'
516c8f62d79SMichal Berger	fi
517c8f62d79SMichal Berger
518f72f1547SMichal Berger	if [[ $SPDK_TEST_FUZZER -eq 1 ]]; then
519f72f1547SMichal Berger		config_params+=" $(get_fuzzer_target_config)"
520f72f1547SMichal Berger	fi
521f72f1547SMichal Berger
5226d4d5c62SParameswaran Krishnamurthy	if [[ $SPDK_TEST_NVMF_MDNS -eq 1 ]]; then
5236d4d5c62SParameswaran Krishnamurthy		config_params+=' --with-avahi'
5246d4d5c62SParameswaran Krishnamurthy	fi
5256d4d5c62SParameswaran Krishnamurthy
5261e46e023SMaciej Mis	if [[ $SPDK_JSONRPC_GO_CLIENT -eq 1 ]]; then
5271e46e023SMaciej Mis		config_params+=' --with-golang'
5281e46e023SMaciej Mis	fi
5291e46e023SMaciej Mis
5304f7f0f09SSeth Howell	echo "$config_params"
5314f7f0f09SSeth Howell	xtrace_restore
5324f7f0f09SSeth Howell}
5338b98cdb6SDarek Stojaczyk
534f72f1547SMichal Bergerfunction get_fuzzer_target_config() {
535f72f1547SMichal Berger	local -A fuzzer_targets_to_config=()
536f72f1547SMichal Berger	local config target
537f72f1547SMichal Berger
538f72f1547SMichal Berger	fuzzer_targets_to_config["vfio"]="--with-vfio-user"
539f72f1547SMichal Berger	for target in $(get_fuzzer_targets); do
5403f52d265SMike Gerdts		[[ -n ${fuzzer_targets_to_config["$target"]:-} ]] || continue
541f72f1547SMichal Berger		config+=("${fuzzer_targets_to_config["$target"]}")
542f72f1547SMichal Berger	done
543f72f1547SMichal Berger
544f72f1547SMichal Berger	if ((${#config[@]} > 0)); then
545f72f1547SMichal Berger		echo "${config[*]}"
546f72f1547SMichal Berger	fi
547f72f1547SMichal Berger}
548f72f1547SMichal Berger
549f72f1547SMichal Bergerfunction get_fuzzer_targets() {
550f72f1547SMichal Berger	local fuzzers=()
551f72f1547SMichal Berger
5523f52d265SMike Gerdts	if [[ -n ${SPDK_TEST_FUZZER_TARGET:-} ]]; then
553f72f1547SMichal Berger		IFS="," read -ra fuzzers <<< "$SPDK_TEST_FUZZER_TARGET"
554f72f1547SMichal Berger	else
555f72f1547SMichal Berger		fuzzers=("$rootdir/test/fuzz/llvm/"*)
556f72f1547SMichal Berger		fuzzers=("${fuzzers[@]##*/}")
557f72f1547SMichal Berger	fi
558f72f1547SMichal Berger
559f72f1547SMichal Berger	echo "${fuzzers[*]}"
560f72f1547SMichal Berger}
561f72f1547SMichal Berger
5628b98cdb6SDarek Stojaczykfunction rpc_cmd() {
5638b98cdb6SDarek Stojaczyk	xtrace_disable
56408d4dce2SMichal Berger	local rsp rc=1
56508d4dce2SMichal Berger	local stdin cmd cmds_number=0 status_number=0 status
5668b98cdb6SDarek Stojaczyk
56708d4dce2SMichal Berger	if (($#)); then
56808d4dce2SMichal Berger		cmds_number=1
5698b98cdb6SDarek Stojaczyk		echo "$@" >&$RPC_PIPE_INPUT
57008d4dce2SMichal Berger	elif [[ ! -t 0 ]]; then
57108d4dce2SMichal Berger		mapfile -t stdin <&0
57208d4dce2SMichal Berger		cmds_number=${#stdin[@]}
57308d4dce2SMichal Berger		printf '%s\n' "${stdin[@]}" >&$RPC_PIPE_INPUT
57408d4dce2SMichal Berger	else
57508d4dce2SMichal Berger		return 0
57608d4dce2SMichal Berger	fi
57708d4dce2SMichal Berger
5787755333cSMichal Berger	while read -t "${RPC_PIPE_TIMEOUT:-15}" -ru $RPC_PIPE_OUTPUT rsp; do
5798b98cdb6SDarek Stojaczyk		if [[ $rsp == "**STATUS="* ]]; then
58008d4dce2SMichal Berger			status[${rsp#*=}]=$rsp
58108d4dce2SMichal Berger			if ((++status_number == cmds_number)); then
5828b98cdb6SDarek Stojaczyk				break
5838b98cdb6SDarek Stojaczyk			fi
58408d4dce2SMichal Berger			continue
58508d4dce2SMichal Berger		fi
5868b98cdb6SDarek Stojaczyk		echo "$rsp"
5878b98cdb6SDarek Stojaczyk	done
5888b98cdb6SDarek Stojaczyk
58908d4dce2SMichal Berger	rc=${!status[*]}
5908b98cdb6SDarek Stojaczyk	xtrace_restore
5918b98cdb6SDarek Stojaczyk	[[ $rc == 0 ]]
5928b98cdb6SDarek Stojaczyk}
5938b98cdb6SDarek Stojaczyk
59464cfaf3fSMichal Bergerfunction rpc_cmd_simple_data_json() {
59564cfaf3fSMichal Berger
59664cfaf3fSMichal Berger	local elems="$1[@]" elem
59764cfaf3fSMichal Berger	local -gA jq_out=()
59864cfaf3fSMichal Berger	local jq val
59964cfaf3fSMichal Berger
60064cfaf3fSMichal Berger	local lvs=(
60164cfaf3fSMichal Berger		"uuid"
60264cfaf3fSMichal Berger		"name"
60364cfaf3fSMichal Berger		"base_bdev"
60464cfaf3fSMichal Berger		"total_data_clusters"
60564cfaf3fSMichal Berger		"free_clusters"
60664cfaf3fSMichal Berger		"block_size"
60764cfaf3fSMichal Berger		"cluster_size"
60864cfaf3fSMichal Berger	)
60964cfaf3fSMichal Berger
61064cfaf3fSMichal Berger	local bdev=(
61164cfaf3fSMichal Berger		"name"
61264cfaf3fSMichal Berger		"aliases[0]"
61364cfaf3fSMichal Berger		"block_size"
61464cfaf3fSMichal Berger		"num_blocks"
61564cfaf3fSMichal Berger		"uuid"
61664cfaf3fSMichal Berger		"product_name"
617a67e0eb3SMike Gerdts		"supported_io_types.read"
618a67e0eb3SMike Gerdts		"supported_io_types.write"
619a67e0eb3SMike Gerdts		"driver_specific.lvol.clone"
620a67e0eb3SMike Gerdts		"driver_specific.lvol.base_snapshot"
621a67e0eb3SMike Gerdts		"driver_specific.lvol.esnap_clone"
622a67e0eb3SMike Gerdts		"driver_specific.lvol.external_snapshot_name"
62364cfaf3fSMichal Berger	)
62464cfaf3fSMichal Berger
62564cfaf3fSMichal Berger	[[ -v $elems ]] || return 1
62664cfaf3fSMichal Berger
62764cfaf3fSMichal Berger	for elem in "${!elems}"; do
62864cfaf3fSMichal Berger		jq="${jq:+$jq,\"\\n\",}\"$elem\",\" \",.[0].$elem"
62964cfaf3fSMichal Berger	done
63064cfaf3fSMichal Berger	jq+=',"\n"'
63164cfaf3fSMichal Berger
63264cfaf3fSMichal Berger	shift
63364cfaf3fSMichal Berger	while read -r elem val; do
63464cfaf3fSMichal Berger		jq_out["$elem"]=$val
63564cfaf3fSMichal Berger	done < <(rpc_cmd "$@" | jq -jr "$jq")
63664cfaf3fSMichal Berger	((${#jq_out[@]} > 0)) || return 1
63764cfaf3fSMichal Berger}
63864cfaf3fSMichal Berger
6392cdc7e39SMichal Bergerfunction valid_exec_arg() {
6402cdc7e39SMichal Berger	local arg=$1
6412cdc7e39SMichal Berger	# First argument must be the executable so do some basic sanity checks first. For bash, this
6422cdc7e39SMichal Berger	# covers two basic cases where es == 126 || es == 127 so catch them early on and fail hard
6432cdc7e39SMichal Berger	# if needed.
6442cdc7e39SMichal Berger	case "$(type -t "$arg")" in
6452cdc7e39SMichal Berger		builtin | function) ;;
6462cdc7e39SMichal Berger		file) arg=$(type -P "$arg") && [[ -x $arg ]] ;;
6472cdc7e39SMichal Berger		*) return 1 ;;
6482cdc7e39SMichal Berger	esac
6492cdc7e39SMichal Berger}
6502cdc7e39SMichal Berger
651c29329feSDarek Stojaczykfunction NOT() {
652a9337f72SMichal Berger	local es=0
653a9337f72SMichal Berger
6542cdc7e39SMichal Berger	valid_exec_arg "$@" || return 1
655a9337f72SMichal Berger	"$@" || es=$?
656a9337f72SMichal Berger
657a9337f72SMichal Berger	# Logic looks like so:
658a9337f72SMichal Berger	#  - return false if command exit successfully
659a9337f72SMichal Berger	#  - return false if command exit after receiving a core signal (FIXME: or any signal?)
660a9337f72SMichal Berger	#  - return true if command exit with an error
661a9337f72SMichal Berger
662a9337f72SMichal Berger	# This naively assumes that the process doesn't exit with > 128 on its own.
663a9337f72SMichal Berger	if ((es > 128)); then
664a9337f72SMichal Berger		es=$((es & ~128))
665a9337f72SMichal Berger		case "$es" in
666a9337f72SMichal Berger			3) ;&       # SIGQUIT
667a9337f72SMichal Berger			4) ;&       # SIGILL
668a9337f72SMichal Berger			6) ;&       # SIGABRT
669a9337f72SMichal Berger			8) ;&       # SIGFPE
670a9337f72SMichal Berger			9) ;&       # SIGKILL
671a9337f72SMichal Berger			11) es=0 ;; # SIGSEGV
672a9337f72SMichal Berger			*) es=1 ;;
673a9337f72SMichal Berger		esac
6743f52d265SMike Gerdts	elif [[ -n ${EXIT_STATUS:-} ]] && ((es != EXIT_STATUS)); then
675a9337f72SMichal Berger		es=0
676c29329feSDarek Stojaczyk	fi
677a9337f72SMichal Berger
678a9337f72SMichal Berger	# invert error code of any command and also trigger ERR on 0 (unlike bash ! prefix)
679a9337f72SMichal Berger	((!es == 0))
680c29329feSDarek Stojaczyk}
681c29329feSDarek Stojaczyk
682c9e5d2a6SSeth Howellfunction timing() {
683c9e5d2a6SSeth Howell	direction="$1"
684c9e5d2a6SSeth Howell	testname="$2"
685c9e5d2a6SSeth Howell
686c9e5d2a6SSeth Howell	now=$(date +%s)
687c9e5d2a6SSeth Howell
688c9e5d2a6SSeth Howell	if [ "$direction" = "enter" ]; then
6893f52d265SMike Gerdts		export timing_stack="${timing_stack:-};${now}"
6903f52d265SMike Gerdts		export test_stack="${test_stack:-};${testname}"
691c9e5d2a6SSeth Howell	else
6927c00bdabSDarek Stojaczyk		touch "$output_dir/timing.txt"
693c9e5d2a6SSeth Howell		child_time=$(grep "^${test_stack:1};" $output_dir/timing.txt | awk '{s+=$2} END {print s}')
694c9e5d2a6SSeth Howell
695c9e5d2a6SSeth Howell		start_time=$(echo "$timing_stack" | sed -e 's@^.*;@@')
696c9e5d2a6SSeth Howell		timing_stack=$(echo "$timing_stack" | sed -e 's@;[^;]*$@@')
697c9e5d2a6SSeth Howell
698c9e5d2a6SSeth Howell		elapsed=$((now - start_time - child_time))
699c9e5d2a6SSeth Howell		echo "${test_stack:1} $elapsed" >> $output_dir/timing.txt
700c9e5d2a6SSeth Howell
701c9e5d2a6SSeth Howell		test_stack=$(echo "$test_stack" | sed -e 's@;[^;]*$@@')
702c9e5d2a6SSeth Howell	fi
703c9e5d2a6SSeth Howell}
704c9e5d2a6SSeth Howell
7058d3047dfSMichal Bergerfunction timing_cmd() (
7068d3047dfSMichal Berger	# The use-case here is this: ts=$(timing_cmd echo bar). Since stdout is always redirected
7078d3047dfSMichal Berger	# to a pipe handling the $(), lookup the stdin's device and determine if it's sane to send
7088d3047dfSMichal Berger	# cmd's output to it. If not, just null it.
709f3febe42SMichal Berger	local cmd_es=$?
7108d3047dfSMichal Berger
7118d3047dfSMichal Berger	[[ -t 0 ]] && exec {cmd_out}>&0 || exec {cmd_out}> /dev/null
7128d3047dfSMichal Berger
7138d3047dfSMichal Berger	local time=0 TIMEFORMAT=%2R # seconds
7148d3047dfSMichal Berger
7158d3047dfSMichal Berger	# We redirect cmd's std{out,err} to a separate fd dup'ed to stdin's device (or /dev/null) to
7168d3047dfSMichal Berger	# catch only output from the time builtin - output from the actual cmd would be still visible,
7178d3047dfSMichal Berger	# but $() will return just the time's data, hence making it possible to just do:
7188d3047dfSMichal Berger	#  time_of_super_verbose_cmd=$(timing_cmd super_verbose_cmd)
719f3febe42SMichal Berger	time=$({ time "$@" >&"$cmd_out" 2>&1; } 2>&1) || cmd_es=$?
7208d3047dfSMichal Berger	echo "$time"
721f3febe42SMichal Berger
722f3febe42SMichal Berger	return "$cmd_es"
7238d3047dfSMichal Berger)
7248d3047dfSMichal Berger
725c9e5d2a6SSeth Howellfunction timing_enter() {
7263b660ea8SDarek Stojaczyk	xtrace_disable
727c9e5d2a6SSeth Howell	timing "enter" "$1"
7283b660ea8SDarek Stojaczyk	xtrace_restore
729c9e5d2a6SSeth Howell}
730c9e5d2a6SSeth Howell
731c9e5d2a6SSeth Howellfunction timing_exit() {
7323b660ea8SDarek Stojaczyk	xtrace_disable
733c9e5d2a6SSeth Howell	timing "exit" "$1"
7343b660ea8SDarek Stojaczyk	xtrace_restore
735c9e5d2a6SSeth Howell}
736c9e5d2a6SSeth Howell
737c9e5d2a6SSeth Howellfunction timing_finish() {
73812fc2abfSMichal Berger	[[ -e $output_dir/timing.txt ]] || return 0
73912fc2abfSMichal Berger
740c9e5d2a6SSeth Howell	flamegraph='/usr/local/FlameGraph/flamegraph.pl'
74126f88ce7SMichal Berger	[[ -x "$flamegraph" ]] || return 1
74226f88ce7SMichal Berger
743c9e5d2a6SSeth Howell	"$flamegraph" \
744c9e5d2a6SSeth Howell		--title 'Build Timing' \
745c9e5d2a6SSeth Howell		--nametype 'Step:' \
746c9e5d2a6SSeth Howell		--countname seconds \
74726f88ce7SMichal Berger		"$output_dir/timing.txt" \
74826f88ce7SMichal Berger		> "$output_dir/timing.svg"
749c9e5d2a6SSeth Howell}
750c9e5d2a6SSeth Howell
751a562812dSSeth Howellfunction create_test_list() {
75252330a6bSDarek Stojaczyk	xtrace_disable
753863d73d3STomasz Zawadzki	# First search all scripts in main SPDK directory.
754863d73d3STomasz Zawadzki	completion=$(grep -shI -d skip --include="*.sh" -e "run_test " $rootdir/*)
755863d73d3STomasz Zawadzki	# Follow up with search in test directory recursively.
7568a810f5fSMichal Berger	completion+=$'\n'$(grep -rshI --include="*.sh" --exclude="*autotest_common.sh" -e "run_test " $rootdir/test)
757863d73d3STomasz Zawadzki	printf "%s" "$completion" | grep -v "#" \
758844c8ec3SMichal Berger		| sed 's/^.*run_test/run_test/' | awk '{print $2}' \
759844c8ec3SMichal Berger		| sed 's/\"//g' | sort > $output_dir/all_tests.txt || true
76052330a6bSDarek Stojaczyk	xtrace_restore
761a562812dSSeth Howell}
762a562812dSSeth Howell
763327668c8STomasz Kulasekfunction gdb_attach() {
764327668c8STomasz Kulasek	gdb -q --batch \
765327668c8STomasz Kulasek		-ex 'handle SIGHUP nostop pass' \
766327668c8STomasz Kulasek		-ex 'handle SIGQUIT nostop pass' \
767327668c8STomasz Kulasek		-ex 'handle SIGPIPE nostop pass' \
768327668c8STomasz Kulasek		-ex 'handle SIGALRM nostop pass' \
769327668c8STomasz Kulasek		-ex 'handle SIGTERM nostop pass' \
770327668c8STomasz Kulasek		-ex 'handle SIGUSR1 nostop pass' \
771327668c8STomasz Kulasek		-ex 'handle SIGUSR2 nostop pass' \
772327668c8STomasz Kulasek		-ex 'handle SIGCHLD nostop pass' \
773327668c8STomasz Kulasek		-ex 'set print thread-events off' \
774327668c8STomasz Kulasek		-ex 'cont' \
775327668c8STomasz Kulasek		-ex 'thread apply all bt' \
776327668c8STomasz Kulasek		-ex 'quit' \
777327668c8STomasz Kulasek		--tty=/dev/stdout \
778327668c8STomasz Kulasek		-p $1
779327668c8STomasz Kulasek}
780327668c8STomasz Kulasek
781c9e5d2a6SSeth Howellfunction process_core() {
78245c42ac2SMichal Berger	# Note that this always was racy as we can't really sync with the kernel
78345c42ac2SMichal Berger	# to see if there's any core queued up for writing. We could check if
78445c42ac2SMichal Berger	# collector is running and wait for it explicitly, but it doesn't seem
78545c42ac2SMichal Berger	# to be worth the effort. So assume that if we are being called via
78689df50bcSMichal Berger	# trap, as in, when some error has occurred, wait up to 10s for any
78745c42ac2SMichal Berger	# potential cores. If we are called just for cleanup at the very end,
78845c42ac2SMichal Berger	# don't wait since all the tests ended successfully, hence having any
78945c42ac2SMichal Berger	# critical cores lying around is unlikely.
79089df50bcSMichal Berger	((autotest_es != 0)) && sleep 10
79145c42ac2SMichal Berger
79245c42ac2SMichal Berger	local coredumps core
79345c42ac2SMichal Berger
79445c42ac2SMichal Berger	coredumps=("$output_dir/coredumps/"*.bt.txt)
79545c42ac2SMichal Berger
79645c42ac2SMichal Berger	((${#coredumps[@]} > 0)) || return 0
79745c42ac2SMichal Berger	chmod -R a+r "$output_dir/coredumps"
79845c42ac2SMichal Berger
79945c42ac2SMichal Berger	for core in "${coredumps[@]}"; do
80045c42ac2SMichal Berger		cat <<- BT
80145c42ac2SMichal Berger			##### CORE BT ${core##*/} #####
80245c42ac2SMichal Berger
80345c42ac2SMichal Berger			$(< "$core")
80445c42ac2SMichal Berger
80545c42ac2SMichal Berger			--
80645c42ac2SMichal Berger		BT
80745c42ac2SMichal Berger	done
80845c42ac2SMichal Berger	return 1
809c9e5d2a6SSeth Howell}
810c9e5d2a6SSeth Howell
811af32aa1bSKarol Lateckifunction process_shm() {
812af32aa1bSKarol Latecki	type=$1
813af32aa1bSKarol Latecki	id=$2
814af32aa1bSKarol Latecki	if [ "$type" = "--pid" ]; then
815af32aa1bSKarol Latecki		id="pid${id}"
816af32aa1bSKarol Latecki	fi
817af32aa1bSKarol Latecki
818af32aa1bSKarol Latecki	shm_files=$(find /dev/shm -name "*.${id}" -printf "%f\n")
819af32aa1bSKarol Latecki
8203f52d265SMike Gerdts	if [[ -z ${shm_files:-} ]]; then
821af32aa1bSKarol Latecki		echo "SHM File for specified PID or shared memory id: ${id} not found!"
822af32aa1bSKarol Latecki		return 1
823af32aa1bSKarol Latecki	fi
824af32aa1bSKarol Latecki	for n in $shm_files; do
825af32aa1bSKarol Latecki		tar -C /dev/shm/ -cvzf $output_dir/${n}_shm.tar.gz ${n}
826af32aa1bSKarol Latecki	done
827af32aa1bSKarol Latecki	return 0
828af32aa1bSKarol Latecki}
829af32aa1bSKarol Latecki
8304674af01SPawel Piatek# Parameters:
8314674af01SPawel Piatek# $1 - process pid
8324674af01SPawel Piatek# $2 - rpc address (optional)
8334674af01SPawel Piatek# $3 - max retries (optional)
834c9e5d2a6SSeth Howellfunction waitforlisten() {
8353f52d265SMike Gerdts	if [ -z "${1:-}" ]; then
836c9e5d2a6SSeth Howell		exit 1
837c9e5d2a6SSeth Howell	fi
838c9e5d2a6SSeth Howell
839f751ea17SPawel Wodkowski	local rpc_addr="${2:-$DEFAULT_RPC_ADDR}"
8404674af01SPawel Piatek	local max_retries=${3:-100}
841c9e5d2a6SSeth Howell
842c9e5d2a6SSeth Howell	echo "Waiting for process to start up and listen on UNIX domain socket $rpc_addr..."
843c9e5d2a6SSeth Howell	# turn off trace for this loop
8443b660ea8SDarek Stojaczyk	xtrace_disable
845f751ea17SPawel Wodkowski	local ret=0
846db1236efSPawel Wodkowski	local i
8474674af01SPawel Piatek	for ((i = max_retries; i != 0; i--)); do
848c9e5d2a6SSeth Howell		# if the process is no longer running, then exit the script
849c9e5d2a6SSeth Howell		#  since it means the application crashed
850c9e5d2a6SSeth Howell		if ! kill -s 0 $1; then
851db1236efSPawel Wodkowski			echo "ERROR: process (pid: $1) is no longer running"
852f751ea17SPawel Wodkowski			ret=1
853f751ea17SPawel Wodkowski			break
854c9e5d2a6SSeth Howell		fi
8555bafc240STomasz Zawadzki
8566ee44c69SJim Harris		if $rootdir/scripts/rpc.py -t 1 -s "$rpc_addr" rpc_get_methods &> /dev/null; then
857db1236efSPawel Wodkowski			break
858c9e5d2a6SSeth Howell		fi
85982583134SDarek Stojaczyk
860db1236efSPawel Wodkowski		sleep 0.5
861c9e5d2a6SSeth Howell	done
862f751ea17SPawel Wodkowski
8633b660ea8SDarek Stojaczyk	xtrace_restore
864db1236efSPawel Wodkowski	if ((i == 0)); then
865db1236efSPawel Wodkowski		echo "ERROR: timeout while waiting for process (pid: $1) to start listening on '$rpc_addr'"
866db1236efSPawel Wodkowski		ret=1
867f751ea17SPawel Wodkowski	fi
868db1236efSPawel Wodkowski	return $ret
869c9e5d2a6SSeth Howell}
870c9e5d2a6SSeth Howell
871c9e5d2a6SSeth Howellfunction waitfornbd() {
872bf9dbae5SPawel Wodkowski	local nbd_name=$1
873bf9dbae5SPawel Wodkowski	local i
874c9e5d2a6SSeth Howell
875c9e5d2a6SSeth Howell	for ((i = 1; i <= 20; i++)); do
876c9e5d2a6SSeth Howell		if grep -q -w $nbd_name /proc/partitions; then
877c9e5d2a6SSeth Howell			break
878c9e5d2a6SSeth Howell		else
879c9e5d2a6SSeth Howell			sleep 0.1
880c9e5d2a6SSeth Howell		fi
881c9e5d2a6SSeth Howell	done
882c9e5d2a6SSeth Howell
883c9e5d2a6SSeth Howell	# The nbd device is now recognized as a block device, but there can be
884c9e5d2a6SSeth Howell	#  a small delay before we can start I/O to that block device.  So loop
885c9e5d2a6SSeth Howell	#  here trying to read the first block of the nbd block device to a temp
886c9e5d2a6SSeth Howell	#  file.  Note that dd returns success when reading an empty file, so we
887c9e5d2a6SSeth Howell	#  need to check the size of the output file instead.
888c9e5d2a6SSeth Howell	for ((i = 1; i <= 20; i++)); do
889fe711156SMichal Berger		dd if=/dev/$nbd_name of="$SPDK_TEST_STORAGE/nbdtest" bs=4096 count=1 iflag=direct
890fe711156SMichal Berger		size=$(stat -c %s "$SPDK_TEST_STORAGE/nbdtest")
891fe711156SMichal Berger		rm -f "$SPDK_TEST_STORAGE/nbdtest"
892c9e5d2a6SSeth Howell		if [ "$size" != "0" ]; then
893c9e5d2a6SSeth Howell			return 0
894c9e5d2a6SSeth Howell		else
895c9e5d2a6SSeth Howell			sleep 0.1
896c9e5d2a6SSeth Howell		fi
897c9e5d2a6SSeth Howell	done
898c9e5d2a6SSeth Howell
899c9e5d2a6SSeth Howell	return 1
900c9e5d2a6SSeth Howell}
901c9e5d2a6SSeth Howell
902975e4614Spaul lusefunction waitforbdev() {
903975e4614Spaul luse	local bdev_name=$1
904d66bb2d1SKamil Godzwon	local bdev_timeout=$2
905975e4614Spaul luse	local i
9063f52d265SMike Gerdts	[[ -z ${bdev_timeout:-} ]] && bdev_timeout=2000 # ms
907975e4614Spaul luse
9087d5ba105SJim Harris	$rpc_py bdev_wait_for_examine
9097d5ba105SJim Harris
910d66bb2d1SKamil Godzwon	if $rpc_py bdev_get_bdevs -b $bdev_name -t $bdev_timeout; then
911975e4614Spaul luse		return 0
912975e4614Spaul luse	fi
913ab854135SBen Walker
914975e4614Spaul luse	return 1
915975e4614Spaul luse}
916975e4614Spaul luse
917cf9e9b2eSPawel Piatekfunction waitforcondition() {
918cf9e9b2eSPawel Piatek	local cond=$1
919cf9e9b2eSPawel Piatek	local max=${2:-10}
920cf9e9b2eSPawel Piatek	while ((max--)); do
921cf9e9b2eSPawel Piatek		if eval $cond; then
922cf9e9b2eSPawel Piatek			return 0
923cf9e9b2eSPawel Piatek		fi
924cf9e9b2eSPawel Piatek		sleep 1
925cf9e9b2eSPawel Piatek	done
926cf9e9b2eSPawel Piatek	return 1
927cf9e9b2eSPawel Piatek}
928cf9e9b2eSPawel Piatek
9290c7aeea9STomasz Zawadzkifunction make_filesystem() {
9300c7aeea9STomasz Zawadzki	local fstype=$1
9310c7aeea9STomasz Zawadzki	local dev_name=$2
9320c7aeea9STomasz Zawadzki	local i=0
9330c7aeea9STomasz Zawadzki	local force
9340c7aeea9STomasz Zawadzki
9350c7aeea9STomasz Zawadzki	if [ $fstype = ext4 ]; then
9360c7aeea9STomasz Zawadzki		force=-F
9370c7aeea9STomasz Zawadzki	else
9380c7aeea9STomasz Zawadzki		force=-f
9390c7aeea9STomasz Zawadzki	fi
9400c7aeea9STomasz Zawadzki
9410c7aeea9STomasz Zawadzki	while ! mkfs.${fstype} $force ${dev_name}; do
9420c7aeea9STomasz Zawadzki		if [ $i -ge 15 ]; then
9430c7aeea9STomasz Zawadzki			return 1
9440c7aeea9STomasz Zawadzki		fi
9450c7aeea9STomasz Zawadzki		i=$((i + 1))
9460c7aeea9STomasz Zawadzki		sleep 1
9470c7aeea9STomasz Zawadzki	done
9480c7aeea9STomasz Zawadzki
9490c7aeea9STomasz Zawadzki	return 0
9500c7aeea9STomasz Zawadzki}
9510c7aeea9STomasz Zawadzki
952c9e5d2a6SSeth Howellfunction killprocess() {
953c9e5d2a6SSeth Howell	# $1 = process pid
9543f52d265SMike Gerdts	if [ -z "${1:-}" ]; then
955f3b3c5bdSMichal Berger		return 1
956c9e5d2a6SSeth Howell	fi
957c9e5d2a6SSeth Howell
958f0a2cc82SKarol Latecki	if kill -0 $1; then
95939dce00bSJim Harris		if [ $(uname) = Linux ]; then
96039dce00bSJim Harris			process_name=$(ps --no-headers -o comm= $1)
96139dce00bSJim Harris		else
96239dce00bSJim Harris			process_name=$(ps -c -o command $1 | tail -1)
96339dce00bSJim Harris		fi
96439dce00bSJim Harris		if [ "$process_name" = "sudo" ]; then
965714a5646SBen Walker			# kill the child process, which is the actual app
966714a5646SBen Walker			# (assume $1 has just one child)
967074df1d8SPawel Kaminski			local child
968074df1d8SPawel Kaminski			child="$(pgrep -P $1)"
969714a5646SBen Walker			echo "killing process with pid $child"
970714a5646SBen Walker			kill $child
971714a5646SBen Walker		else
972c9e5d2a6SSeth Howell			echo "killing process with pid $1"
973c9e5d2a6SSeth Howell			kill $1
974714a5646SBen Walker		fi
975714a5646SBen Walker
976714a5646SBen Walker		# wait for the process regardless if its the dummy sudo one
977714a5646SBen Walker		# or the actual app - it should terminate anyway
978c9e5d2a6SSeth Howell		wait $1
97982f60376SGangCao	else
98082f60376SGangCao		# the process is not there anymore
98182f60376SGangCao		echo "Process with pid $1 is not found"
982f0a2cc82SKarol Latecki	fi
983c9e5d2a6SSeth Howell}
984c9e5d2a6SSeth Howell
985c9e5d2a6SSeth Howellfunction iscsicleanup() {
986c9e5d2a6SSeth Howell	echo "Cleaning up iSCSI connection"
987c9e5d2a6SSeth Howell	iscsiadm -m node --logout || true
988c9e5d2a6SSeth Howell	iscsiadm -m node -o delete || true
989dbb84dd5SKarol Latecki	rm -rf /var/lib/iscsi/nodes/*
990c9e5d2a6SSeth Howell}
991c9e5d2a6SSeth Howell
992c9e5d2a6SSeth Howellfunction stop_iscsi_service() {
993c9e5d2a6SSeth Howell	if cat /etc/*-release | grep Ubuntu; then
994c9e5d2a6SSeth Howell		service open-iscsi stop
995c9e5d2a6SSeth Howell	else
996c9e5d2a6SSeth Howell		service iscsid stop
997c9e5d2a6SSeth Howell	fi
998c9e5d2a6SSeth Howell}
999c9e5d2a6SSeth Howell
1000c9e5d2a6SSeth Howellfunction start_iscsi_service() {
1001c9e5d2a6SSeth Howell	if cat /etc/*-release | grep Ubuntu; then
1002c9e5d2a6SSeth Howell		service open-iscsi start
1003c9e5d2a6SSeth Howell	else
1004c9e5d2a6SSeth Howell		service iscsid start
1005c9e5d2a6SSeth Howell	fi
1006c9e5d2a6SSeth Howell}
1007c9e5d2a6SSeth Howell
1008c9e5d2a6SSeth Howellfunction rbd_setup() {
10090629b01dSTomasz Zawadzki	# $1 = monitor ip address
10105bafc240STomasz Zawadzki	# $2 = name of the namespace
10113f52d265SMike Gerdts	if [ -z "${1:-}" ]; then
10120629b01dSTomasz Zawadzki		echo "No monitor IP address provided for ceph"
10130629b01dSTomasz Zawadzki		exit 1
10140629b01dSTomasz Zawadzki	fi
10153f52d265SMike Gerdts	if [ -n "${2:-}" ]; then
10165bafc240STomasz Zawadzki		if ip netns list | grep "$2"; then
10175bafc240STomasz Zawadzki			NS_CMD="ip netns exec $2"
10185bafc240STomasz Zawadzki		else
10195bafc240STomasz Zawadzki			echo "No namespace $2 exists"
10205bafc240STomasz Zawadzki			exit 1
10215bafc240STomasz Zawadzki		fi
10225bafc240STomasz Zawadzki	fi
10230629b01dSTomasz Zawadzki
1024c9e5d2a6SSeth Howell	if hash ceph; then
1025397521bdSSeth Howell		export PG_NUM=128
1026c9e5d2a6SSeth Howell		export RBD_POOL=rbd
1027c9e5d2a6SSeth Howell		export RBD_NAME=foo
10286907c36fSyidong0635		$NS_CMD $rootdir/scripts/ceph/stop.sh || true
10295bafc240STomasz Zawadzki		$NS_CMD $rootdir/scripts/ceph/start.sh $1
1030397521bdSSeth Howell
10315bafc240STomasz Zawadzki		$NS_CMD ceph osd pool create $RBD_POOL $PG_NUM || true
10325bafc240STomasz Zawadzki		$NS_CMD rbd create $RBD_NAME --size 1000
1033c9e5d2a6SSeth Howell	fi
1034c9e5d2a6SSeth Howell}
1035c9e5d2a6SSeth Howell
1036c9e5d2a6SSeth Howellfunction rbd_cleanup() {
1037c9e5d2a6SSeth Howell	if hash ceph; then
1038d51ea8deSDaniel Verkamp		$rootdir/scripts/ceph/stop.sh || true
1039ab1622aaSKarol Latecki		rm -f /var/tmp/ceph_raw.img
1040c9e5d2a6SSeth Howell	fi
1041c9e5d2a6SSeth Howell}
1042c9e5d2a6SSeth Howell
10432e283fcbS0xe0ffunction daos_setup() {
10442e283fcbS0xe0f	# $1 = pool name
10452e283fcbS0xe0f	# $2 = cont name
10463f52d265SMike Gerdts	if [ -z "${1:-}" ]; then
10472e283fcbS0xe0f		echo "No pool name provided"
10482e283fcbS0xe0f		exit 1
10492e283fcbS0xe0f	fi
10503f52d265SMike Gerdts	if [ -z "${2:-}" ]; then
10512e283fcbS0xe0f		echo "No cont name provided"
10522e283fcbS0xe0f		exit 1
10532e283fcbS0xe0f	fi
10542e283fcbS0xe0f
10552e283fcbS0xe0f	dmg pool create --size=10G $1 || true
10562e283fcbS0xe0f	daos container create --type=POSIX --label=$2 $1 || true
10572e283fcbS0xe0f}
10582e283fcbS0xe0f
10592e283fcbS0xe0ffunction daos_cleanup() {
10602e283fcbS0xe0f	local pool=${1:-testpool}
10612e283fcbS0xe0f	local cont=${2:-testcont}
10622e283fcbS0xe0f
10632e283fcbS0xe0f	daos container destroy -f $pool $cont || true
10642e283fcbS0xe0f	sudo dmg pool destroy -f $pool || true
10652e283fcbS0xe0f}
10662e283fcbS0xe0f
10679ba80de0SMichal Bergerfunction _start_stub() {
106818f3a22bSJim Harris	# Disable ASLR for multi-process testing.  SPDK does support using DPDK multi-process,
10699d04d0efSJim Harris	# but ASLR can still be unreliable in some cases.
10703f912cf0SMichal Berger	# We will re-enable it again after multi-process testing is complete in kill_stub().
10714b1dbc94SMichal Berger	# Save current setting so it can be restored upon calling kill_stub().
10724b1dbc94SMichal Berger	_randomize_va_space=$(< /proc/sys/kernel/randomize_va_space)
107318f3a22bSJim Harris	echo 0 > /proc/sys/kernel/randomize_va_space
1074c9e5d2a6SSeth Howell	$rootdir/test/app/stub/stub $1 &
1075c9e5d2a6SSeth Howell	stubpid=$!
1076c9e5d2a6SSeth Howell	echo Waiting for stub to ready for secondary processes...
1077c9e5d2a6SSeth Howell	while ! [ -e /var/run/spdk_stub0 ]; do
10789ba80de0SMichal Berger		# If stub dies while we wait, bail
10799ba80de0SMichal Berger		[[ -e /proc/$stubpid ]] || return 1
1080c9e5d2a6SSeth Howell		sleep 1s
1081c9e5d2a6SSeth Howell	done
1082c9e5d2a6SSeth Howell	echo done.
1083c9e5d2a6SSeth Howell}
1084c9e5d2a6SSeth Howell
10859ba80de0SMichal Bergerfunction start_stub() {
10869ba80de0SMichal Berger	if ! _start_stub "$@"; then
10879ba80de0SMichal Berger		echo "stub failed" >&2
10889ba80de0SMichal Berger		return 1
10899ba80de0SMichal Berger	fi
10909ba80de0SMichal Berger}
10919ba80de0SMichal Berger
1092c9e5d2a6SSeth Howellfunction kill_stub() {
10939ba80de0SMichal Berger	if [[ -e /proc/$stubpid ]]; then
1094ef6832efSJim Harris		kill $1 $stubpid
1095c9e5d2a6SSeth Howell		wait $stubpid
10969ba80de0SMichal Berger	fi 2> /dev/null || :
1097c9e5d2a6SSeth Howell	rm -f /var/run/spdk_stub0
109818f3a22bSJim Harris	# Re-enable ASLR now that we are done with multi-process testing
109918f3a22bSJim Harris	# Note: "1" enables ASLR w/o randomizing data segments, "2" adds data segment
110018f3a22bSJim Harris	#  randomizing and is the default on all recent Linux kernels
11014b1dbc94SMichal Berger	echo "${_randomize_va_space:-2}" > /proc/sys/kernel/randomize_va_space
1102c9e5d2a6SSeth Howell}
1103c9e5d2a6SSeth Howell
1104c9e5d2a6SSeth Howellfunction run_test() {
1105cb90136cSSeth Howell	if [ $# -le 1 ]; then
1106fd17f1aaSSeth Howell		echo "Not enough parameters"
1107cb90136cSSeth Howell		echo "usage: run_test test_name test_script [script_params]"
1108fd17f1aaSSeth Howell		exit 1
1109fd17f1aaSSeth Howell	fi
1110fd17f1aaSSeth Howell
11113b660ea8SDarek Stojaczyk	xtrace_disable
111248e6cc6fSMichal Berger	local test_name="$1" pid
111337100484SSeth Howell	shift
11141fafd71bSSeth Howell
11153f52d265SMike Gerdts	if [ -n "${test_domain:-}" ]; then
1116ea781d6dSSeth Howell		export test_domain="${test_domain}.${test_name}"
1117ea781d6dSSeth Howell	else
1118ea781d6dSSeth Howell		export test_domain="$test_name"
1119ea781d6dSSeth Howell	fi
1120ea781d6dSSeth Howell
11218d588fbcSMichal Berger	# Signal our daemons to update the test tag
1122d5fe62b2SMichal Berger	update_tag_monitor_resources "$test_domain"
11238d588fbcSMichal Berger
11241fafd71bSSeth Howell	timing_enter $test_name
1125c9e5d2a6SSeth Howell	echo "************************************"
1126cb90136cSSeth Howell	echo "START TEST $test_name"
1127c9e5d2a6SSeth Howell	echo "************************************"
11283b660ea8SDarek Stojaczyk	xtrace_restore
112948e6cc6fSMichal Berger	time "$@"
11303b660ea8SDarek Stojaczyk	xtrace_disable
1131c9e5d2a6SSeth Howell	echo "************************************"
1132cb90136cSSeth Howell	echo "END TEST $test_name"
1133c9e5d2a6SSeth Howell	echo "************************************"
11341fafd71bSSeth Howell	timing_exit $test_name
1135ea781d6dSSeth Howell
1136ea781d6dSSeth Howell	export test_domain=${test_domain%"$test_name"}
1137ea781d6dSSeth Howell	if [ -n "$test_domain" ]; then
1138ea781d6dSSeth Howell		export test_domain=${test_domain%?}
1139ea781d6dSSeth Howell	fi
1140ea781d6dSSeth Howell
11413f52d265SMike Gerdts	if [ -z "${test_domain:-}" ]; then
1142ea781d6dSSeth Howell		echo "top_level $test_name" >> $output_dir/test_completions.txt
1143ea781d6dSSeth Howell	else
1144ea781d6dSSeth Howell		echo "$test_domain $test_name" >> $output_dir/test_completions.txt
1145ea781d6dSSeth Howell	fi
11463b660ea8SDarek Stojaczyk	xtrace_restore
1147c9e5d2a6SSeth Howell}
1148c9e5d2a6SSeth Howell
1149148719daSKarol Lateckifunction skip_run_test_with_warning() {
1150148719daSKarol Latecki	echo "WARNING: $1"
1151148719daSKarol Latecki	echo "Test run may fail if run with autorun.sh"
1152148719daSKarol Latecki	echo "Please check your $rootdir/test/common/skipped_tests.txt"
1153148719daSKarol Latecki}
1154148719daSKarol Latecki
1155c9e5d2a6SSeth Howellfunction print_backtrace() {
1156b5d1b4f4SJim Harris	# if errexit is not enabled, don't print a backtrace
1157b5d1b4f4SJim Harris	[[ "$-" =~ e ]] || return 0
1158b5d1b4f4SJim Harris
115918b9303dSMichal Berger	local args=("${BASH_ARGV[@]}")
116018b9303dSMichal Berger
11613b660ea8SDarek Stojaczyk	xtrace_disable
11629d8e1ec0SMichal Berger	# Reset IFS in case we were called from an environment where it was modified
11639d8e1ec0SMichal Berger	IFS=" "$'\t'$'\n'
1164c9e5d2a6SSeth Howell	echo "========== Backtrace start: =========="
1165c9e5d2a6SSeth Howell	echo ""
11669d8e1ec0SMichal Berger	for ((i = 1; i < ${#FUNCNAME[@]}; i++)); do
1167c9e5d2a6SSeth Howell		local func="${FUNCNAME[$i]}"
1168c9e5d2a6SSeth Howell		local line_nr="${BASH_LINENO[$((i - 1))]}"
1169c9e5d2a6SSeth Howell		local src="${BASH_SOURCE[$i]}"
117018b9303dSMichal Berger		local bt="" cmdline=()
11711baf379eSMichal Berger
11721baf379eSMichal Berger		if [[ -f $src ]]; then
1173844c8ec3SMichal Berger			bt=$(nl -w 4 -ba -nln $src | grep -B 5 -A 5 "^${line_nr}[^0-9]" \
1174844c8ec3SMichal Berger				| sed "s/^/   /g" | sed "s/^   $line_nr /=> $line_nr /g")
11751baf379eSMichal Berger		fi
11761baf379eSMichal Berger
117718b9303dSMichal Berger		# If extdebug set the BASH_ARGC[i], try to fetch all the args
117818b9303dSMichal Berger		if ((BASH_ARGC[i] > 0)); then
117918b9303dSMichal Berger			# Use argc as index to reverse the stack
118018b9303dSMichal Berger			local argc=${BASH_ARGC[i]} arg
118118b9303dSMichal Berger			for arg in "${args[@]::BASH_ARGC[i]}"; do
118218b9303dSMichal Berger				cmdline[argc--]="[\"$arg\"]"
118318b9303dSMichal Berger			done
118418b9303dSMichal Berger			args=("${args[@]:BASH_ARGC[i]}")
118518b9303dSMichal Berger		fi
118618b9303dSMichal Berger
1187844c8ec3SMichal Berger		echo "in $src:$line_nr -> $func($(
1188844c8ec3SMichal Berger			IFS=","
1189844c8ec3SMichal Berger			printf '%s\n' "${cmdline[*]:-[]}"
1190844c8ec3SMichal Berger		))"
1191c9e5d2a6SSeth Howell		echo "     ..."
11921baf379eSMichal Berger		echo "${bt:-backtrace unavailable}"
1193c9e5d2a6SSeth Howell		echo "     ..."
1194c9e5d2a6SSeth Howell	done
1195c9e5d2a6SSeth Howell	echo ""
1196c9e5d2a6SSeth Howell	echo "========== Backtrace end =========="
11973b660ea8SDarek Stojaczyk	xtrace_restore
1198c9e5d2a6SSeth Howell	return 0
1199c9e5d2a6SSeth Howell}
1200c9e5d2a6SSeth Howell
1201844c8ec3SMichal Bergerfunction waitforserial() {
120253147e0dSMaciej Wawryk	local i=0
120329907b72SMichal Berger	local nvme_device_counter=1 nvme_devices=0
12043f52d265SMike Gerdts	if [[ -n "${2:-}" ]]; then
120553147e0dSMaciej Wawryk		nvme_device_counter=$2
120653147e0dSMaciej Wawryk	fi
120753147e0dSMaciej Wawryk
12085fb5e91eSKarol Latecki	# Wait initially for min 2s to make sure all devices are ready for use.
12095fb5e91eSKarol Latecki	sleep 2
12108bb27fafSMichal Berger	while ((i++ <= 15)); do
121129907b72SMichal Berger		nvme_devices=$(lsblk -l -o NAME,SERIAL | grep -c "$1")
121229907b72SMichal Berger		((nvme_devices == nvme_device_counter)) && return 0
121329907b72SMichal Berger		if ((nvme_devices > nvme_device_counter)); then
121429907b72SMichal Berger			echo "$nvme_device_counter device(s) expected, found $nvme_devices" >&2
121529907b72SMichal Berger		fi
121653147e0dSMaciej Wawryk		echo "Waiting for devices"
121753147e0dSMaciej Wawryk		sleep 1
121853147e0dSMaciej Wawryk	done
121953147e0dSMaciej Wawryk	return 1
122053147e0dSMaciej Wawryk}
122153147e0dSMaciej Wawryk
1222844c8ec3SMichal Bergerfunction waitforserial_disconnect() {
122353147e0dSMaciej Wawryk	local i=0
122453147e0dSMaciej Wawryk	while lsblk -o NAME,SERIAL | grep -q -w $1; do
122553147e0dSMaciej Wawryk		[ $i -lt 15 ] || break
122653147e0dSMaciej Wawryk		i=$((i + 1))
122753147e0dSMaciej Wawryk		echo "Waiting for disconnect devices"
122853147e0dSMaciej Wawryk		sleep 1
122953147e0dSMaciej Wawryk	done
123053147e0dSMaciej Wawryk
1231e1946cd7SMichal Berger	if lsblk -l -o NAME,SERIAL | grep -q -w $1; then
123253147e0dSMaciej Wawryk		return 1
123353147e0dSMaciej Wawryk	fi
123453147e0dSMaciej Wawryk
123553147e0dSMaciej Wawryk	return 0
123653147e0dSMaciej Wawryk}
123753147e0dSMaciej Wawryk
1238844c8ec3SMichal Bergerfunction waitforblk() {
1239e3263286SSeth Howell	local i=0
1240e3263286SSeth Howell	while ! lsblk -l -o NAME | grep -q -w $1; do
1241e3263286SSeth Howell		[ $i -lt 15 ] || break
12420f0cd0a8SKarol Latecki		i=$((i + 1))
1243e3263286SSeth Howell		sleep 1
1244e3263286SSeth Howell	done
1245e3263286SSeth Howell
1246e3263286SSeth Howell	if ! lsblk -l -o NAME | grep -q -w $1; then
1247e3263286SSeth Howell		return 1
1248e3263286SSeth Howell	fi
1249e3263286SSeth Howell
1250e3263286SSeth Howell	return 0
1251e3263286SSeth Howell}
1252e3263286SSeth Howell
1253844c8ec3SMichal Bergerfunction waitforblk_disconnect() {
12545232a73fSSeth Howell	local i=0
12555232a73fSSeth Howell	while lsblk -l -o NAME | grep -q -w $1; do
12565232a73fSSeth Howell		[ $i -lt 15 ] || break
12570f0cd0a8SKarol Latecki		i=$((i + 1))
12585232a73fSSeth Howell		sleep 1
12595232a73fSSeth Howell	done
12605232a73fSSeth Howell
12615232a73fSSeth Howell	if lsblk -l -o NAME | grep -q -w $1; then
12625232a73fSSeth Howell		return 1
12635232a73fSSeth Howell	fi
12645232a73fSSeth Howell
12655232a73fSSeth Howell	return 0
12665232a73fSSeth Howell}
12675232a73fSSeth Howell
1268844c8ec3SMichal Bergerfunction waitforfile() {
1269b118729fSJim Harris	local i=0
1270a44c7434STomasz Kulasek	while [ ! -e $1 ]; do
1271b118729fSJim Harris		[ $i -lt 200 ] || break
12720f0cd0a8SKarol Latecki		i=$((i + 1))
1273b118729fSJim Harris		sleep 0.1
1274b118729fSJim Harris	done
1275b118729fSJim Harris
1276a44c7434STomasz Kulasek	if [ ! -e $1 ]; then
1277b118729fSJim Harris		return 1
1278b118729fSJim Harris	fi
1279b118729fSJim Harris
1280b118729fSJim Harris	return 0
1281b118729fSJim Harris}
1282b118729fSJim Harris
1283844c8ec3SMichal Bergerfunction fio_config_gen() {
1284c9e5d2a6SSeth Howell	local config_file=$1
1285c9e5d2a6SSeth Howell	local workload=$2
12863fbc84d3SGangCao	local bdev_type=$3
1287872e0e46SYuriy Umanets	local env_context=$4
1288053c15b3SMichal Berger	local fio_dir=$CONFIG_FIO_SOURCE_DIR
1289c9e5d2a6SSeth Howell
1290c9e5d2a6SSeth Howell	if [ -e "$config_file" ]; then
1291c9e5d2a6SSeth Howell		echo "Configuration File Already Exists!: $config_file"
129239e8a95cSPawel Kaminski		return 1
1293c9e5d2a6SSeth Howell	fi
1294c9e5d2a6SSeth Howell
12953f52d265SMike Gerdts	if [ -z "${workload:-}" ]; then
1296c9e5d2a6SSeth Howell		workload=randrw
1297c9e5d2a6SSeth Howell	fi
1298c9e5d2a6SSeth Howell
1299872e0e46SYuriy Umanets	if [ -n "$env_context" ]; then
1300872e0e46SYuriy Umanets		env_context="env_context=$env_context"
1301872e0e46SYuriy Umanets	fi
1302872e0e46SYuriy Umanets
1303c9e5d2a6SSeth Howell	touch $1
1304c9e5d2a6SSeth Howell
1305c9e5d2a6SSeth Howell	cat > $1 << EOL
1306c9e5d2a6SSeth Howell[global]
1307c9e5d2a6SSeth Howellthread=1
1308872e0e46SYuriy Umanets$env_context
1309c9e5d2a6SSeth Howellgroup_reporting=1
1310c9e5d2a6SSeth Howelldirect=1
1311c9e5d2a6SSeth Howellnorandommap=1
1312c9e5d2a6SSeth Howellpercentile_list=50:99:99.9:99.99:99.999
1313c9e5d2a6SSeth Howelltime_based=1
1314c9e5d2a6SSeth Howellramp_time=0
1315c9e5d2a6SSeth HowellEOL
1316c9e5d2a6SSeth Howell
1317c9e5d2a6SSeth Howell	if [ "$workload" == "verify" ]; then
131802925187SMaciej Wawryk		cat <<- EOL >> $config_file
131902925187SMaciej Wawryk			verify=sha1
132002925187SMaciej Wawryk			verify_backlog=1024
132102925187SMaciej Wawryk			rw=randwrite
132202925187SMaciej Wawryk		EOL
13233fbc84d3SGangCao
13243fbc84d3SGangCao		# To avoid potential data race issue due to the AIO device
13253fbc84d3SGangCao		# flush mechanism, add the flag to serialize the writes.
13263fbc84d3SGangCao		# This is to fix the intermittent IO failure issue of #935
13273fbc84d3SGangCao		if [ "$bdev_type" == "AIO" ]; then
13283fbc84d3SGangCao			if [[ $($fio_dir/fio --version) == *"fio-3"* ]]; then
13293fbc84d3SGangCao				echo "serialize_overlap=1" >> $config_file
13303fbc84d3SGangCao			fi
13313fbc84d3SGangCao		fi
1332c9e5d2a6SSeth Howell	elif [ "$workload" == "trim" ]; then
1333c9e5d2a6SSeth Howell		echo "rw=trimwrite" >> $config_file
1334c9e5d2a6SSeth Howell	else
1335c9e5d2a6SSeth Howell		echo "rw=$workload" >> $config_file
1336c9e5d2a6SSeth Howell	fi
1337c9e5d2a6SSeth Howell}
1338c9e5d2a6SSeth Howell
133924d34ac7SKonrad Sztyberfunction fio_plugin() {
13403b9db6c4STomasz Zawadzki	# Setup fio binary cmd line
1341053c15b3SMichal Berger	local fio_dir=$CONFIG_FIO_SOURCE_DIR
134206fdd44cSKonrad Sztyber	# gcc and clang uses different sanitizer libraries
134306fdd44cSKonrad Sztyber	local sanitizers=(libasan libclang_rt.asan)
134424d34ac7SKonrad Sztyber	local plugin=$1
134524d34ac7SKonrad Sztyber	shift
13463b9db6c4STomasz Zawadzki
134706fdd44cSKonrad Sztyber	local asan_lib=
134806fdd44cSKonrad Sztyber	for sanitizer in "${sanitizers[@]}"; do
134906fdd44cSKonrad Sztyber		asan_lib=$(ldd $plugin | grep $sanitizer | awk '{print $3}')
13503f52d265SMike Gerdts		if [[ -n "${asan_lib:-}" ]]; then
135106fdd44cSKonrad Sztyber			break
135206fdd44cSKonrad Sztyber		fi
135306fdd44cSKonrad Sztyber	done
13541bed9c1fSTomasz Zawadzki
135506fdd44cSKonrad Sztyber	# Preload the sanitizer library to fio if fio_plugin was compiled with it
135624d34ac7SKonrad Sztyber	LD_PRELOAD="$asan_lib $plugin" "$fio_dir"/fio "$@"
135724d34ac7SKonrad Sztyber}
135824d34ac7SKonrad Sztyber
135924d34ac7SKonrad Sztyberfunction fio_bdev() {
136024d34ac7SKonrad Sztyber	fio_plugin "$rootdir/build/fio/spdk_bdev" "$@"
13613b9db6c4STomasz Zawadzki}
13623b9db6c4STomasz Zawadzki
1363844c8ec3SMichal Bergerfunction fio_nvme() {
136424d34ac7SKonrad Sztyber	fio_plugin "$rootdir/build/fio/spdk_nvme" "$@"
13653b9db6c4STomasz Zawadzki}
13663b9db6c4STomasz Zawadzki
1367844c8ec3SMichal Bergerfunction get_lvs_free_mb() {
1368c9e5d2a6SSeth Howell	local lvs_uuid=$1
1369074df1d8SPawel Kaminski	local lvs_info
1370074df1d8SPawel Kaminski	local fc
1371074df1d8SPawel Kaminski	local cs
1372074df1d8SPawel Kaminski	lvs_info=$($rpc_py bdev_lvol_get_lvstores)
1373074df1d8SPawel Kaminski	fc=$(jq ".[] | select(.uuid==\"$lvs_uuid\") .free_clusters" <<< "$lvs_info")
1374074df1d8SPawel Kaminski	cs=$(jq ".[] | select(.uuid==\"$lvs_uuid\") .cluster_size" <<< "$lvs_info")
1375c9e5d2a6SSeth Howell
1376c9e5d2a6SSeth Howell	# Change to MB's
1377c9e5d2a6SSeth Howell	free_mb=$((fc * cs / 1024 / 1024))
1378c9e5d2a6SSeth Howell	echo "$free_mb"
1379c9e5d2a6SSeth Howell}
1380c9e5d2a6SSeth Howell
1381844c8ec3SMichal Bergerfunction get_bdev_size() {
1382c9e5d2a6SSeth Howell	local bdev_name=$1
1383074df1d8SPawel Kaminski	local bdev_info
1384074df1d8SPawel Kaminski	local bs
1385074df1d8SPawel Kaminski	local nb
1386074df1d8SPawel Kaminski	bdev_info=$($rpc_py bdev_get_bdevs -b $bdev_name)
1387074df1d8SPawel Kaminski	bs=$(jq ".[] .block_size" <<< "$bdev_info")
1388074df1d8SPawel Kaminski	nb=$(jq ".[] .num_blocks" <<< "$bdev_info")
1389c9e5d2a6SSeth Howell
1390c9e5d2a6SSeth Howell	# Change to MB's
1391c9e5d2a6SSeth Howell	bdev_size=$((bs * nb / 1024 / 1024))
1392c9e5d2a6SSeth Howell	echo "$bdev_size"
1393c9e5d2a6SSeth Howell}
1394c9e5d2a6SSeth Howell
1395844c8ec3SMichal Bergerfunction autotest_cleanup() {
1396a57af488SMichal Berger	local autotest_es=$?
1397a57af488SMichal Berger	xtrace_disable
1398a57af488SMichal Berger
139976a2663eSMichal Berger	# Slurp at_app_exit() so we can kill all lingering vhost and qemu processes
140076a2663eSMichal Berger	# in one swing. We do this in a subshell as vhost/common.sh is too eager to
140176a2663eSMichal Berger	# do some extra work which we don't care about in this context.
140276a2663eSMichal Berger	# shellcheck source=/dev/null
14038ad5671fSMichal Berger	vhost_reap() (source "$rootdir/test/vhost/common.sh" &> /dev/null || return 0 && at_app_exit)
140476a2663eSMichal Berger
1405a57af488SMichal Berger	# catch any stray core files and kill all remaining SPDK processes. Update
1406a57af488SMichal Berger	# autotest_es in case autotest reported success but cores and/or processes
1407a57af488SMichal Berger	# were left behind regardless.
1408a57af488SMichal Berger
1409a57af488SMichal Berger	process_core || autotest_es=1
1410a57af488SMichal Berger	reap_spdk_processes || autotest_es=1
141176a2663eSMichal Berger	vhost_reap || autotest_es=1
1412a57af488SMichal Berger
1413d1f9da82SSeth Howell	$rootdir/scripts/setup.sh reset
1414af32aa1bSKarol Latecki	$rootdir/scripts/setup.sh cleanup
1415d63d4d5aSSeth Howell	if [ $(uname -s) = "Linux" ]; then
1416d63d4d5aSSeth Howell		modprobe -r uio_pci_generic
1417d63d4d5aSSeth Howell	fi
14189fda9814STomasz Zawadzki	rm -rf "$asan_suppression_file"
14193f52d265SMike Gerdts	if [[ -n ${old_core_pattern:-} ]]; then
142016589c82SMichal Berger		echo "$old_core_pattern" > /proc/sys/kernel/core_pattern
142116589c82SMichal Berger	fi
142223040b8bSMichal Berger	if [[ -e /proc/$udevadm_pid/status ]]; then
142323040b8bSMichal Berger		kill "$udevadm_pid" || :
142423040b8bSMichal Berger	fi
1425570c8bb4SMichal Berger
1426570c8bb4SMichal Berger	local storage_fallback_purge=("${TMPDIR:-/tmp}/spdk."??????)
1427570c8bb4SMichal Berger
1428570c8bb4SMichal Berger	if ((${#storage_fallback_purge[@]} > 0)); then
1429570c8bb4SMichal Berger		rm -rf "${storage_fallback_purge[@]}"
1430570c8bb4SMichal Berger	fi
1431a57af488SMichal Berger
14327d4f7b7fSMichal Berger	if ((autotest_es)); then
14337d4f7b7fSMichal Berger		if [[ $(uname) == FreeBSD ]]; then
14347d4f7b7fSMichal Berger			ps aux
14357d4f7b7fSMichal Berger		elif [[ $(uname) == Linux ]]; then
14367d4f7b7fSMichal Berger			# Get more detailed view
14377d4f7b7fSMichal Berger			grep . /proc/[0-9]*/status
14387d4f7b7fSMichal Berger			# Dump some extra info into kernel log
14397d4f7b7fSMichal Berger			echo "######## Autotest Cleanup Dump ########" > /dev/kmsg
14407d4f7b7fSMichal Berger			# Show cpus backtraces
14417d4f7b7fSMichal Berger			echo l > /proc/sysrq-trigger
14427d4f7b7fSMichal Berger			# Show mem usage
14437d4f7b7fSMichal Berger			echo m > /proc/sysrq-trigger
14447d4f7b7fSMichal Berger			# show blocked tasks
14457d4f7b7fSMichal Berger			echo w > /proc/sysrq-trigger
14467d4f7b7fSMichal Berger
14477d4f7b7fSMichal Berger		fi > "$output_dir/proc_list.txt" 2>&1 || :
14487d4f7b7fSMichal Berger	fi
14493d834218SMichal Berger
1450d5fe62b2SMichal Berger	stop_monitor_resources
14513d834218SMichal Berger
1452a57af488SMichal Berger	xtrace_restore
1453a57af488SMichal Berger	return $autotest_es
1454d1f9da82SSeth Howell}
1455d1f9da82SSeth Howell
1456844c8ec3SMichal Bergerfunction freebsd_update_contigmem_mod() {
1457fb9c4ee6SKarol Latecki	if [ $(uname) = FreeBSD ]; then
145886ee572bSSeth Howell		kldunload contigmem.ko || true
14593f52d265SMike Gerdts		if [ -n "${SPDK_RUN_EXTERNAL_DPDK:-}" ]; then
146049473bdcSDarek Stojaczyk			cp -f "$SPDK_RUN_EXTERNAL_DPDK/kmod/contigmem.ko" /boot/modules/
146149473bdcSDarek Stojaczyk			cp -f "$SPDK_RUN_EXTERNAL_DPDK/kmod/contigmem.ko" /boot/kernel/
146249473bdcSDarek Stojaczyk			cp -f "$SPDK_RUN_EXTERNAL_DPDK/kmod/nic_uio.ko" /boot/modules/
146349473bdcSDarek Stojaczyk			cp -f "$SPDK_RUN_EXTERNAL_DPDK/kmod/nic_uio.ko" /boot/kernel/
1464d68ee5b4SDarek Stojaczyk		else
1465d68ee5b4SDarek Stojaczyk			cp -f "$rootdir/dpdk/build/kmod/contigmem.ko" /boot/modules/
1466d68ee5b4SDarek Stojaczyk			cp -f "$rootdir/dpdk/build/kmod/contigmem.ko" /boot/kernel/
14677cf4602dSPawel Kaminski			cp -f "$rootdir/dpdk/build/kmod/nic_uio.ko" /boot/modules/
14687cf4602dSPawel Kaminski			cp -f "$rootdir/dpdk/build/kmod/nic_uio.ko" /boot/kernel/
1469d68ee5b4SDarek Stojaczyk		fi
147086ee572bSSeth Howell	fi
147186ee572bSSeth Howell}
147286ee572bSSeth Howell
1473a7d3e106SKarol Lateckifunction freebsd_set_maxsock_buf() {
1474a7d3e106SKarol Latecki	# FreeBSD needs 4MB maxsockbuf size to pass socket unit tests.
1475a7d3e106SKarol Latecki	# Otherwise tests fail due to ENOBUFS when trying to do setsockopt(SO_RCVBUF|SO_SNDBUF).
1476a7d3e106SKarol Latecki	# See https://github.com/spdk/spdk/issues/2943
1477a7d3e106SKarol Latecki	if [[ $(uname) = FreeBSD ]] && (($(sysctl -n kern.ipc.maxsockbuf) < 4194304)); then
1478a7d3e106SKarol Latecki		sysctl kern.ipc.maxsockbuf=4194304
1479a7d3e106SKarol Latecki	fi
1480a7d3e106SKarol Latecki}
1481a7d3e106SKarol Latecki
1482844c8ec3SMichal Bergerfunction get_nvme_name_from_bdf() {
1483cb7af50cSMichal Berger	get_block_dev_from_nvme "$@"
148428f4299fSMarcin Dziegielewski}
148528f4299fSMarcin Dziegielewski
1486256f554dSTomasz Zawadzkifunction get_nvme_ctrlr_from_bdf() {
1487256f554dSTomasz Zawadzki	bdf_sysfs_path=$(readlink -f /sys/class/nvme/nvme* | grep "$1/nvme/nvme")
14883f52d265SMike Gerdts	if [[ -z "${bdf_sysfs_path:-}" ]]; then
1489256f554dSTomasz Zawadzki		return
1490256f554dSTomasz Zawadzki	fi
1491256f554dSTomasz Zawadzki
1492256f554dSTomasz Zawadzki	printf '%s\n' "$(basename $bdf_sysfs_path)"
1493256f554dSTomasz Zawadzki}
1494256f554dSTomasz Zawadzki
1495db43b387SKarol Latecki# Get BDF addresses of all NVMe drives currently attached to
1496db43b387SKarol Latecki# uio-pci-generic or vfio-pci
1497db43b387SKarol Lateckifunction get_nvme_bdfs() {
14984641aa53SMichal Berger	local bdfs=()
14994641aa53SMichal Berger	bdfs=($("$rootdir/scripts/gen_nvme.sh" | jq -r '.config[].params.traddr'))
15004641aa53SMichal Berger	if ((${#bdfs[@]} == 0)); then
15014641aa53SMichal Berger		echo "No bdevs found" >&2
15024641aa53SMichal Berger		return 1
15036b19775bSTomasz Zawadzki	fi
15044641aa53SMichal Berger	printf '%s\n' "${bdfs[@]}"
1505db43b387SKarol Latecki}
1506db43b387SKarol Latecki
1507db43b387SKarol Latecki# Same as function above, but just get the first disks BDF address
1508db43b387SKarol Lateckifunction get_first_nvme_bdf() {
15094641aa53SMichal Berger	local bdfs=()
15104641aa53SMichal Berger	bdfs=($(get_nvme_bdfs))
15114641aa53SMichal Berger
15124641aa53SMichal Berger	echo "${bdfs[0]}"
1513db43b387SKarol Latecki}
1514db43b387SKarol Latecki
15154c21ef36STomasz Zawadzkifunction nvme_namespace_revert() {
15164c21ef36STomasz Zawadzki	$rootdir/scripts/setup.sh
15174c21ef36STomasz Zawadzki	sleep 1
15184641aa53SMichal Berger	local bdfs=()
151954f9ed4cSJim Harris	# If there are no nvme bdfs, just return immediately
152054f9ed4cSJim Harris	bdfs=($(get_nvme_bdfs)) || return 0
15214c21ef36STomasz Zawadzki
15224c21ef36STomasz Zawadzki	$rootdir/scripts/setup.sh reset
15234c21ef36STomasz Zawadzki
15244641aa53SMichal Berger	for bdf in "${bdfs[@]}"; do
15254c21ef36STomasz Zawadzki		nvme_ctrlr=/dev/$(get_nvme_ctrlr_from_bdf ${bdf})
15263f52d265SMike Gerdts		if [[ -z "${nvme_ctrlr:-}" ]]; then
15274c21ef36STomasz Zawadzki			continue
15284c21ef36STomasz Zawadzki		fi
15294c21ef36STomasz Zawadzki
15304c21ef36STomasz Zawadzki		# Check Optional Admin Command Support for Namespace Management
15314c21ef36STomasz Zawadzki		oacs=$(nvme id-ctrl ${nvme_ctrlr} | grep oacs | cut -d: -f2)
15324c21ef36STomasz Zawadzki		oacs_ns_manage=$((oacs & 0x8))
15334c21ef36STomasz Zawadzki
15344c21ef36STomasz Zawadzki		if [[ "$oacs_ns_manage" -ne 0 ]]; then
15354c21ef36STomasz Zawadzki			# This assumes every NVMe controller contains single namespace,
15368e8864f2SKarol Latecki			# encompassing Total NVM Capacity and formatted as 512 block size.
15378e8864f2SKarol Latecki			# 512 block size is needed for test/vhost/vhost_boot.sh to
1538c9c7c281SJosh Soref			# successfully run.
15394c21ef36STomasz Zawadzki
15404c21ef36STomasz Zawadzki			unvmcap=$(nvme id-ctrl ${nvme_ctrlr} | grep unvmcap | cut -d: -f2)
15414c21ef36STomasz Zawadzki			if [[ "$unvmcap" -eq 0 ]]; then
15424c21ef36STomasz Zawadzki				# All available space already used
15434c21ef36STomasz Zawadzki				continue
15444c21ef36STomasz Zawadzki			fi
15454c21ef36STomasz Zawadzki			tnvmcap=$(nvme id-ctrl ${nvme_ctrlr} | grep tnvmcap | cut -d: -f2)
154666a35235SMichal Berger			cntlid=$(nvme id-ctrl ${nvme_ctrlr} | grep cntlid | cut -d: -f2)
15478e8864f2SKarol Latecki			blksize=512
15484c21ef36STomasz Zawadzki
15494c21ef36STomasz Zawadzki			size=$((tnvmcap / blksize))
15504c21ef36STomasz Zawadzki
155166a35235SMichal Berger			nvme detach-ns ${nvme_ctrlr} -n 0xffffffff -c $cntlid || true
15524c21ef36STomasz Zawadzki			nvme delete-ns ${nvme_ctrlr} -n 0xffffffff || true
15534c21ef36STomasz Zawadzki			nvme create-ns ${nvme_ctrlr} -s ${size} -c ${size} -b ${blksize}
155466a35235SMichal Berger			nvme attach-ns ${nvme_ctrlr} -n 1 -c $cntlid
15554c21ef36STomasz Zawadzki			nvme reset ${nvme_ctrlr}
1556f803df51SKarol Latecki			waitforfile "${nvme_ctrlr}n1"
15574c21ef36STomasz Zawadzki		fi
15584c21ef36STomasz Zawadzki	done
15594c21ef36STomasz Zawadzki}
15604c21ef36STomasz Zawadzki
1561919fdeceSChangpeng Liu# Get BDFs based on device ID, such as 0x0a54
1562919fdeceSChangpeng Liufunction get_nvme_bdfs_by_id() {
156354f9ed4cSJim Harris	local bdfs=() _bdfs=()
156454f9ed4cSJim Harris	_bdfs=($(get_nvme_bdfs)) || return 0
156554f9ed4cSJim Harris	for bdf in "${_bdfs[@]}"; do
1566919fdeceSChangpeng Liu		device=$(cat /sys/bus/pci/devices/$bdf/device) || true
1567919fdeceSChangpeng Liu		if [[ "$device" == "$1" ]]; then
1568919fdeceSChangpeng Liu			bdfs+=($bdf)
1569919fdeceSChangpeng Liu		fi
1570919fdeceSChangpeng Liu	done
1571919fdeceSChangpeng Liu
157254f9ed4cSJim Harris	((${#bdfs[@]} > 0)) || return 0
1573919fdeceSChangpeng Liu	printf '%s\n' "${bdfs[@]}"
1574919fdeceSChangpeng Liu}
1575919fdeceSChangpeng Liu
1576919fdeceSChangpeng Liufunction opal_revert_cleanup() {
1577919fdeceSChangpeng Liu	# The OPAL CI tests is only used for P4510 devices.
1578919fdeceSChangpeng Liu	mapfile -t bdfs < <(get_nvme_bdfs_by_id 0x0a54)
15793f52d265SMike Gerdts	if [[ -z ${bdfs[0]:-} ]]; then
1580919fdeceSChangpeng Liu		return 0
1581919fdeceSChangpeng Liu	fi
1582919fdeceSChangpeng Liu
1583919fdeceSChangpeng Liu	$SPDK_BIN_DIR/spdk_tgt &
1584919fdeceSChangpeng Liu	spdk_tgt_pid=$!
1585919fdeceSChangpeng Liu	waitforlisten $spdk_tgt_pid
1586919fdeceSChangpeng Liu
15875e65adccSwanghailiangx	bdf_id=0
1588919fdeceSChangpeng Liu	for bdf in "${bdfs[@]}"; do
15895e65adccSwanghailiangx		$rootdir/scripts/rpc.py bdev_nvme_attach_controller -b "nvme"${bdf_id} -t "pcie" -a ${bdf}
1590919fdeceSChangpeng Liu		# Ignore if this fails.
15915e65adccSwanghailiangx		$rootdir/scripts/rpc.py bdev_nvme_opal_revert -b "nvme"${bdf_id} -p test || true
15925e65adccSwanghailiangx		((++bdf_id))
1593919fdeceSChangpeng Liu	done
1594919fdeceSChangpeng Liu
1595919fdeceSChangpeng Liu	killprocess $spdk_tgt_pid
1596919fdeceSChangpeng Liu}
1597919fdeceSChangpeng Liu
1598f574014aSMichal Bergerfunction pap() {
1599f574014aSMichal Berger	while read -r file; do
1600f574014aSMichal Berger		cat <<- FILE
1601f574014aSMichal Berger			--- $file ---
1602f574014aSMichal Berger			$(< "$file")
1603f574014aSMichal Berger			--- $file ---
1604f574014aSMichal Berger		FILE
1605f574014aSMichal Berger		rm -f "$file"
1606f574014aSMichal Berger	done < <(find "$@" -type f | sort -u)
1607f574014aSMichal Berger}
1608f574014aSMichal Berger
1609a57af488SMichal Bergerfunction get_proc_paths() {
161015e31017SMichal Berger	case "$(uname -s)" in
161115e31017SMichal Berger		Linux) # ps -e -opid,exe <- not supported under {centos7,rocky8}'s procps-ng
16126693862fSMichal Berger			local pid exe
161315e31017SMichal Berger			for pid in /proc/[0-9]*; do
16146693862fSMichal Berger				exe=$(readlink "$pid/exe") || continue
16156693862fSMichal Berger				exe=${exe/ (deleted)/}
16166693862fSMichal Berger				echo "${pid##*/} $exe"
1617a57af488SMichal Berger			done
161815e31017SMichal Berger			;;
161915e31017SMichal Berger		FreeeBSD) procstat -ab | awk '{print $1, $4}' ;;
162015e31017SMichal Berger	esac
1621a57af488SMichal Berger}
1622a57af488SMichal Berger
162315e31017SMichal Bergerexec_files() { file "$@" | awk -F: '/ELF.+executable/{print $1}'; }
1624a57af488SMichal Berger
1625a57af488SMichal Bergerfunction reap_spdk_processes() {
162615e31017SMichal Berger	local bins test_bins procs
162715e31017SMichal Berger	local spdk_procs spdk_pids
1628a57af488SMichal Berger
1629982c2051SMichal Berger	mapfile -t test_bins < <(find "$rootdir"/test/{app,env,event,nvme} -type f)
163015e31017SMichal Berger	mapfile -t bins < <(
163115e31017SMichal Berger		exec_files "${test_bins[@]}"
163215e31017SMichal Berger		readlink -f "$SPDK_BIN_DIR/"* "$SPDK_EXAMPLE_DIR/"*
163315e31017SMichal Berger	)
163447d1bc80SJim Harris	((${#bins[@]} > 0)) || return 0
1635a57af488SMichal Berger
163615e31017SMichal Berger	mapfile -t spdk_procs < <(get_proc_paths | grep -E "$(
163715e31017SMichal Berger		IFS="|"
163815e31017SMichal Berger		echo "${bins[*]#$rootdir/}"
163915e31017SMichal Berger	)" || true)
164015e31017SMichal Berger	((${#spdk_procs[@]} > 0)) || return 0
1641a57af488SMichal Berger
164215e31017SMichal Berger	printf '%s is still up, killing\n' "${spdk_procs[@]}" >&2
164315e31017SMichal Berger	mapfile -t spdk_pids < <(printf '%s\n' "${spdk_procs[@]}" | awk '{print $1}')
1644a57af488SMichal Berger
164515e31017SMichal Berger	kill -SIGKILL "${spdk_pids[@]}" 2> /dev/null || :
1646a57af488SMichal Berger	return 1
1647a57af488SMichal Berger}
1648a57af488SMichal Berger
16490231fdc7SMichal Bergerfunction is_block_zoned() {
16500231fdc7SMichal Berger	local device=$1
16510231fdc7SMichal Berger
16520231fdc7SMichal Berger	[[ -e /sys/block/$device/queue/zoned ]] || return 1
16530231fdc7SMichal Berger	[[ $(< "/sys/block/$device/queue/zoned") != none ]]
16540231fdc7SMichal Berger}
16550231fdc7SMichal Berger
16560231fdc7SMichal Bergerfunction get_zoned_devs() {
16570231fdc7SMichal Berger	local -gA zoned_devs=()
1658*61617956SMichal Berger	local -A zoned_ctrls=()
1659*61617956SMichal Berger	local nvme bdf ns
16600231fdc7SMichal Berger
1661*61617956SMichal Berger	# When given ctrl has > 1 namespaces attached, we need to make
1662*61617956SMichal Berger	# sure we pick up ALL of them, even if only one of them is zoned.
1663*61617956SMichal Berger	# This is because the zoned_devs[] is mainly used for PCI_BLOCKED
1664*61617956SMichal Berger	# which passed to setup.sh will skip entire ctrl, not a single
1665*61617956SMichal Berger	# ns. FIXME: this should not be necessary. We need to find a way
1666*61617956SMichal Berger	# to handle zoned devices more gracefully instead of hiding them
1667*61617956SMichal Berger	# like that from all the other non-zns test suites.
1668*61617956SMichal Berger	for nvme in /sys/class/nvme/nvme*; do
1669*61617956SMichal Berger		bdf=$(< "$nvme/address")
1670*61617956SMichal Berger		for ns in "$nvme/"nvme*n*; do
1671*61617956SMichal Berger			if is_block_zoned "${ns##*/}"; then
1672*61617956SMichal Berger				zoned_ctrls["$nvme"]=$bdf
1673*61617956SMichal Berger				continue 2
16740231fdc7SMichal Berger			fi
16750231fdc7SMichal Berger		done
1676*61617956SMichal Berger	done
1677*61617956SMichal Berger
1678*61617956SMichal Berger	for nvme in "${!zoned_ctrls[@]}"; do
1679*61617956SMichal Berger		for ns in "$nvme/"nvme*n*; do
1680*61617956SMichal Berger			zoned_devs["${ns##*/}"]=${zoned_ctrls["$nvme"]}
1681*61617956SMichal Berger		done
1682*61617956SMichal Berger	done
16830231fdc7SMichal Berger}
16840231fdc7SMichal Berger
1685a711f445SMichal Bergerfunction is_pid_child() {
1686a711f445SMichal Berger	local pid=$1 _pid
1687a711f445SMichal Berger
1688a711f445SMichal Berger	while read -r _pid; do
1689a711f445SMichal Berger		((pid == _pid)) && return 0
1690a711f445SMichal Berger	done < <(jobs -pr)
1691a711f445SMichal Berger
1692a711f445SMichal Berger	return 1
1693a711f445SMichal Berger}
1694a711f445SMichal Berger
16951430096aSMichal Berger# Define temp storage for all the tests. Look for 2GB at minimum
16961430096aSMichal Bergerset_test_storage "${TEST_MIN_STORAGE_SIZE:-$((1 << 31))}"
16971430096aSMichal Berger
1698c9e5d2a6SSeth Howellset -o errtrace
1699a8d01691SMichal Bergershopt -s extdebug
1700c9e5d2a6SSeth Howelltrap "trap - ERR; print_backtrace >&2" ERR
17017612ac47SDarek Stojaczyk
1702b18e53d4SMichal BergerPS4=' \t ${test_domain:-} -- ${BASH_SOURCE#${BASH_SOURCE%/*/*}/}@${LINENO} -- \$ '
17037612ac47SDarek Stojaczykif $SPDK_AUTOTEST_X; then
170439fe5c84SSeth Howell	# explicitly enable xtraces, overriding any tracking information.
1705c2feee4fSMichal Berger	xtrace_fd
17067612ac47SDarek Stojaczykelse
170713479ef5SMichal Berger	xtrace_disable
17087612ac47SDarek Stojaczykfi
17091ebcd2fdSJim Harris
17101ebcd2fdSJim Harrisif [[ $CONFIG_COVERAGE == y ]]; then
17117c65373eSJim Harris	if lt "$(lcov --version | awk '{print $NF}')" 2; then
17127c65373eSJim Harris		lcov_rc_opt="--rc lcov_branch_coverage=1 --rc lcov_function_coverage=1"
17137c65373eSJim Harris	else
17147c65373eSJim Harris		lcov_rc_opt="--rc branch_coverage=1 --rc function_coverage=1"
17157c65373eSJim Harris	fi
17161ebcd2fdSJim Harris	export LCOV_OPTS="
17177c65373eSJim Harris		$lcov_rc_opt
17181ebcd2fdSJim Harris		--rc genhtml_branch_coverage=1
17191ebcd2fdSJim Harris		--rc genhtml_function_coverage=1
17201ebcd2fdSJim Harris		--rc genhtml_legend=1
17211ebcd2fdSJim Harris		--rc geninfo_all_blocks=1
17226468abf0SJim Harris		--rc geninfo_unexecuted_blocks=1
17231ebcd2fdSJim Harris		$lcov_opt
17241ebcd2fdSJim Harris		"
1725125c6010SJim Harris	export LCOV="lcov $LCOV_OPTS"
17261ebcd2fdSJim Harrisfi
1727