xref: /spdk/test/common/autotest_common.sh (revision 47d1bc800616b03fc8fb8adc941fbd549e890cdc)
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
177c9e5d2a6SSeth Howell
178b8a51a93STomasz Zawadzki# always test with SPDK shared objects.
179b8a51a93STomasz Zawadzkiexport SPDK_LIB_DIR="$rootdir/build/lib"
18030116833SDarek Stojaczykexport DPDK_LIB_DIR="${SPDK_RUN_EXTERNAL_DPDK:-$rootdir/dpdk/build}/lib"
181619da103SChangpeng Liuexport VFIO_LIB_DIR="$rootdir/build/libvfio-user/usr/local/lib"
182b8a51a93STomasz Zawadzkiexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SPDK_LIB_DIR:$DPDK_LIB_DIR:$VFIO_LIB_DIR
18330116833SDarek Stojaczyk
18444775a80SMichal Berger# Tell setup.sh to wait for block devices upon each reset
18544775a80SMichal Bergerexport PCI_BLOCK_SYNC_ON_RESET=yes
18644775a80SMichal Berger
18705dde5c2STomasz Zawadzki# Export PYTHONPATH with addition of RPC framework. New scripts can be created
18805dde5c2STomasz Zawadzki# specific use cases for tests.
1897610bc38SKonrad Sztyberexport PYTHONPATH=$PYTHONPATH:$rootdir/python
19005dde5c2STomasz Zawadzki
191f657669eSKarol Latecki# Don't create Python .pyc files. When running with sudo these will be
192f657669eSKarol Latecki# created with root ownership and can cause problems when cleaning the repository.
193f657669eSKarol Lateckiexport PYTHONDONTWRITEBYTECODE=1
194f657669eSKarol Latecki
195cc2a4920SSebastian Brzezinka# Export new_delete_type_mismatch to skip the known bug that exists in librados
196cc2a4920SSebastian Brzezinka# https://tracker.ceph.com/issues/24078
19723b3340fSTomasz Zawadzkiexport ASAN_OPTIONS=new_delete_type_mismatch=0:disable_coredump=0:abort_on_error=1:use_sigaltstack=0
19849ba9965SKonrad Sztyberexport UBSAN_OPTIONS='halt_on_error=1:print_stacktrace=1:abort_on_error=1:disable_coredump=0:exitcode=134'
199f40d2451SSeth Howell
2009fda9814STomasz Zawadzki# Export LeakSanitizer option to use suppression file in order to prevent false positives
2019fda9814STomasz Zawadzki# and known leaks in external executables or libraries from showing up.
2029fda9814STomasz Zawadzkiasan_suppression_file="/var/tmp/asan_suppression_file"
203b9a66791SAlexis Lescouetrm -rf "$asan_suppression_file" 2> /dev/null || sudo rm -rf "$asan_suppression_file"
20402925187SMaciej Wawrykcat << EOL >> "$asan_suppression_file"
2059fda9814STomasz Zawadzki# ASAN has some bugs around thread_local variables.  We have a destructor in place
2069fda9814STomasz Zawadzki# to free the thread contexts, but ASAN complains about the leak before those
2079fda9814STomasz Zawadzki# destructors have a chance to run.  So suppress this one specific leak using
2089fda9814STomasz Zawadzki# LSAN_OPTIONS.
20902925187SMaciej Wawrykleak:spdk_fs_alloc_thread_ctx
2109fda9814STomasz Zawadzki
2111bed9c1fSTomasz Zawadzki# Suppress known leaks in fio project
212053c15b3SMichal Bergerleak:$CONFIG_FIO_SOURCE_DIR/parse.c
213053c15b3SMichal Bergerleak:$CONFIG_FIO_SOURCE_DIR/iolog.c
214053c15b3SMichal Bergerleak:$CONFIG_FIO_SOURCE_DIR/init.c
215053c15b3SMichal Bergerleak:$CONFIG_FIO_SOURCE_DIR/filesetup.c
21602925187SMaciej Wawrykleak:fio_memalign
21702925187SMaciej Wawrykleak:spdk_fio_io_u_init
218bec627fcSMichal Berger# Suppress leaks in gperftools-libs from fio
219bec627fcSMichal Bergerleak:libtcmalloc_minimal.so
2201bed9c1fSTomasz Zawadzki
2211891f2e5STomasz Zawadzki# Suppress leaks in libiscsi
22202925187SMaciej Wawrykleak:libiscsi.so
223690cf1c9SKarol Latecki
224690cf1c9SKarol Latecki# Suppress leaks in libcrypto
225690cf1c9SKarol Latecki# Below is caused by openssl 3.0.8 leaks
226690cf1c9SKarol Lateckileak:libcrypto.so
2279d513abfSTomasz Zawadzki
2289d513abfSTomasz Zawadzki# Suppress leaks in accel-config
2299d513abfSTomasz Zawadzki# Versions with unresolved leaks:
2309d513abfSTomasz Zawadzki# v3.4.6.4 [Fedora 37]
2319d513abfSTomasz Zawadzkileak:add_wq
2329d513abfSTomasz Zawadzkileak:add_group
2339d513abfSTomasz Zawadzki# v3.5.2 [Fedora 38]
2349d513abfSTomasz Zawadzkileak:accfg_get_param_str
2359d513abfSTomasz Zawadzki# v4.0 [Fedora 39]
2369d513abfSTomasz Zawadzkileak:__scandir64_tail
23702925187SMaciej WawrykEOL
2381891f2e5STomasz Zawadzki
2398e70c6e3STomasz Kulasek# Suppress leaks in libfuse3
2408e70c6e3STomasz Kulasekecho "leak:libfuse3.so" >> "$asan_suppression_file"
2418e70c6e3STomasz Kulasek
2429fda9814STomasz Zawadzkiexport LSAN_OPTIONS=suppressions="$asan_suppression_file"
2439fda9814STomasz Zawadzki
244f40d2451SSeth Howellexport DEFAULT_RPC_ADDR="/var/tmp/spdk.sock"
245f40d2451SSeth Howell
2463f52d265SMike Gerdtsif [ -z "${DEPENDENCY_DIR:-}" ]; then
247a4a04624SMichal Berger	export DEPENDENCY_DIR=/var/spdk/dependencies
248f04277f0SJohn Meneghinielse
249f04277f0SJohn Meneghini	export DEPENDENCY_DIR
250f04277f0SJohn Meneghinifi
251f04277f0SJohn Meneghini
2526b9b448eSBen Walker# Export location of where all the SPDK binaries are
2536b9b448eSBen Walkerexport SPDK_BIN_DIR="$rootdir/build/bin"
25485bdd43bSBen Walkerexport SPDK_EXAMPLE_DIR="$rootdir/build/examples"
2556b9b448eSBen Walker
2566abaf4fcSMichal Berger# for vhost, vfio-user tests
2576abaf4fcSMichal Bergerexport QEMU_BIN=${QEMU_BIN:-}
2586abaf4fcSMichal Bergerexport VFIO_QEMU_BIN=${VFIO_QEMU_BIN:-}
2596abaf4fcSMichal Berger
260c8f62d79SMichal Bergerexport AR_TOOL=$rootdir/scripts/ar-xnvme-fixer
261c8f62d79SMichal Berger
262db0d8682SMichal Berger# For testing nvmes which are attached to some sort of a fanout switch in the CI pool
263db0d8682SMichal Bergerexport UNBIND_ENTIRE_IOMMU_GROUP=${UNBIND_ENTIRE_IOMMU_GROUP:-no}
264db0d8682SMichal Berger
2656f2b8056SMichal Berger_LCOV_MAIN=0
2666f2b8056SMichal Berger_LCOV_LLVM=1
2676f2b8056SMichal Berger_LCOV=$LCOV_MAIN
2686f2b8056SMichal Berger[[ $CC == *clang* || $SPDK_TEST_FUZZER -eq 1 ]] && _LCOV=$_LCOV_LLVM
2696f2b8056SMichal Berger
2706f2b8056SMichal Berger_lcov_opt[_LCOV_LLVM]="--gcov-tool $rootdir/test/fuzz/llvm/llvm-gcov.sh"
2716f2b8056SMichal Berger_lcov_opt[_LCOV_MAIN]=""
2726f2b8056SMichal Berger
2736f2b8056SMichal Bergerlcov_opt=${_lcov_opt[_LCOV]}
2746f2b8056SMichal Berger
275c9e5d2a6SSeth Howell# pass our valgrind desire on to unittest.sh
276c9e5d2a6SSeth Howellif [ $SPDK_RUN_VALGRIND -eq 0 ]; then
277c9e5d2a6SSeth Howell	export valgrind=''
2781f4a8945SMichal Bergerelse
2791f4a8945SMichal Berger	# unset all DEBUGINFOD_* vars that may affect our valgrind instance
2801f4a8945SMichal Berger	unset -v "${!DEBUGINFOD_@}"
281c9e5d2a6SSeth Howellfi
282c9e5d2a6SSeth Howell
283f40d2451SSeth Howellif [ "$(uname -s)" = "Linux" ]; then
28499fb6780SJim Harris	HUGEMEM=${HUGEMEM:-4096}
28599fb6780SJim Harris	export CLEAR_HUGE=yes
286227428c3SMichal Berger
28738d4a2a2SPawel Kaminski	MAKE="make"
288f40d2451SSeth Howell	MAKEFLAGS=${MAKEFLAGS:--j$(nproc)}
289f40d2451SSeth Howellelif [ "$(uname -s)" = "FreeBSD" ]; then
29038d4a2a2SPawel Kaminski	MAKE="gmake"
291772eb8ebSKarol Latecki	MAKEFLAGS=${MAKEFLAGS:--j$(sysctl -a | grep -E -i 'hw.ncpu' | awk '{print $2}')}
292f40d2451SSeth Howell	# FreeBSD runs a much more limited set of tests, so keep the default 2GB.
29399fb6780SJim Harris	HUGEMEM=${HUGEMEM:-2048}
2945a21edf4SNick Connollyelif [ "$(uname -s)" = "Windows" ]; then
2955a21edf4SNick Connolly	MAKE="make"
2965a21edf4SNick Connolly	MAKEFLAGS=${MAKEFLAGS:--j$(nproc)}
2975a21edf4SNick Connolly	# Keep the default 2GB for Windows.
29899fb6780SJim Harris	HUGEMEM=${HUGEMEM:-2048}
299f40d2451SSeth Howellelse
300f40d2451SSeth Howell	echo "Unknown OS \"$(uname -s)\""
301f40d2451SSeth Howell	exit 1
302f40d2451SSeth Howellfi
303f40d2451SSeth Howell
30499fb6780SJim Harrisexport HUGEMEM=$HUGEMEM
30599fb6780SJim Harris
3061826245aSSarvesh LankeNO_HUGE=()
3074f7f0f09SSeth HowellTEST_MODE=
3084f7f0f09SSeth Howellfor i in "$@"; do
3094f7f0f09SSeth Howell	case "$i" in
3104f7f0f09SSeth Howell		--iso)
3114f7f0f09SSeth Howell			TEST_MODE=iso
3124f7f0f09SSeth Howell			;;
3134f7f0f09SSeth Howell		--transport=*)
3144f7f0f09SSeth Howell			TEST_TRANSPORT="${i#*=}"
3154f7f0f09SSeth Howell			;;
3164f7f0f09SSeth Howell		--sock=*)
3174f7f0f09SSeth Howell			TEST_SOCK="${i#*=}"
3184f7f0f09SSeth Howell			;;
3191826245aSSarvesh Lanke		--no-hugepages)
3201826245aSSarvesh Lanke			NO_HUGE=(--no-huge -s 1024)
3211826245aSSarvesh Lanke			;;
32281fc34dfSKrzysztof Goreczny		--interrupt-mode)
32381fc34dfSKrzysztof Goreczny			TEST_INTERRUPT_MODE=1
32481fc34dfSKrzysztof Goreczny			;;
3254f7f0f09SSeth Howell	esac
3264f7f0f09SSeth Howelldone
3274f7f0f09SSeth Howell
3284f7f0f09SSeth Howell# start rpc.py coprocess if it's not started yet
3293f52d265SMike Gerdtsif [[ -z ${RPC_PIPE_PID:-} ]] || ! kill -0 "$RPC_PIPE_PID" &> /dev/null; then
3307347f60bSMichal Berger	# Include list to all known plugins we use in the tests
3317347f60bSMichal Berger	PYTHONPATH+=":$rootdir/test/rpc_plugins"
3327347f60bSMichal Berger	coproc RPC_PIPE { PYTHONPATH="$PYTHONPATH" "$rootdir/scripts/rpc.py" --server; }
3334f7f0f09SSeth Howell	exec {RPC_PIPE_OUTPUT}<&${RPC_PIPE[0]} {RPC_PIPE_INPUT}>&${RPC_PIPE[1]}
3344f7f0f09SSeth Howell	# all descriptors will automatically close together with this bash
3354f7f0f09SSeth Howell	# process, this will make rpc.py stop reading and exit gracefully
3364f7f0f09SSeth Howellfi
3374f7f0f09SSeth Howell
3381430096aSMichal Bergerfunction set_test_storage() {
3391430096aSMichal Berger	[[ -v testdir ]] || return 0
3401430096aSMichal Berger
3411430096aSMichal Berger	local requested_size=$1 # bytes
3421430096aSMichal Berger	local mount target_dir
3431430096aSMichal Berger
3441430096aSMichal Berger	local -A mounts fss sizes avails uses
3451430096aSMichal Berger	local source fs size avail mount use
3461430096aSMichal Berger
3471430096aSMichal Berger	local storage_fallback storage_candidates
3489aeaafa1SMichal Berger
3499aeaafa1SMichal Berger	storage_fallback=$(mktemp -udt spdk.XXXXXX)
3501430096aSMichal Berger	storage_candidates=(
3511430096aSMichal Berger		"$testdir"
3521430096aSMichal Berger		"$storage_fallback/tests/${testdir##*/}"
3531430096aSMichal Berger		"$storage_fallback"
3541430096aSMichal Berger	)
3551430096aSMichal Berger
3563f52d265SMike Gerdts	if [[ -n ${ADD_TEST_STORAGE:-} ]]; then
3571430096aSMichal Berger		# List of dirs|mounts separated by whitespaces
3581430096aSMichal Berger		storage_candidates+=($ADD_TEST_STORAGE)
3591430096aSMichal Berger	fi
3601430096aSMichal Berger
3613f52d265SMike Gerdts	if [[ -n ${DEDICATED_TEST_STORAGE:-} ]]; then
3621430096aSMichal Berger		# Single, dedicated dir|mount
3631430096aSMichal Berger		storage_candidates=("$DEDICATED_TEST_STORAGE")
3641430096aSMichal Berger	fi
3651430096aSMichal Berger
3661430096aSMichal Berger	mkdir -p "${storage_candidates[@]}"
3671430096aSMichal Berger
3681430096aSMichal Berger	# add some headroom - 64M
3691430096aSMichal Berger	requested_size=$((requested_size + (64 << 20)))
3701430096aSMichal Berger
3711430096aSMichal Berger	while read -r source fs size use avail _ mount; do
3721430096aSMichal Berger		mounts["$mount"]=$source fss["$mount"]=$fs
3731430096aSMichal Berger		avails["$mount"]=$((avail * 1024)) sizes["$mount"]=$((size * 1024))
3741430096aSMichal Berger		uses["$mount"]=$((use * 1024))
3751430096aSMichal Berger	done < <(df -T | grep -v Filesystem)
3761430096aSMichal Berger
3771430096aSMichal Berger	printf '* Looking for test storage...\n' >&2
3781430096aSMichal Berger
3791430096aSMichal Berger	local target_space new_size
3801430096aSMichal Berger	for target_dir in "${storage_candidates[@]}"; do
3811430096aSMichal Berger		# FreeBSD's df is lacking the --output arg
3821430096aSMichal Berger		# mount=$(df --output=target "$target_dir" | grep -v "Mounted on")
3831430096aSMichal Berger		mount=$(df "$target_dir" | awk '$1 !~ /Filesystem/{print $6}')
3841430096aSMichal Berger
3851430096aSMichal Berger		target_space=${avails["$mount"]}
3861430096aSMichal Berger		if ((target_space == 0 || target_space < requested_size)); then
3871430096aSMichal Berger			continue
3881430096aSMichal Berger		fi
3891430096aSMichal Berger		if ((target_space >= requested_size)); then
3901430096aSMichal Berger			# For in-memory fs, and / make sure our requested size won't fill most of the space.
3911430096aSMichal Berger			if [[ ${fss["$mount"]} == tmpfs ]] || [[ ${fss["$mount"]} == ramfs ]] || [[ $mount == / ]]; then
3921430096aSMichal Berger				new_size=$((uses["$mount"] + requested_size))
3931430096aSMichal Berger				if ((new_size * 100 / sizes["$mount"] > 95)); then
3941430096aSMichal Berger					continue
3951430096aSMichal Berger				fi
3961430096aSMichal Berger			fi
3971430096aSMichal Berger		fi
3981430096aSMichal Berger		export SPDK_TEST_STORAGE=$target_dir
3991430096aSMichal Berger		printf '* Found test storage at %s\n' "$SPDK_TEST_STORAGE" >&2
4001430096aSMichal Berger		return 0
4011430096aSMichal Berger	done
4021430096aSMichal Berger	printf '* Test storage is not available\n'
4031430096aSMichal Berger	return 1
4041430096aSMichal Berger}
4051430096aSMichal Berger
4064f7f0f09SSeth Howellfunction get_config_params() {
4074f7f0f09SSeth Howell	xtrace_disable
408c9e5d2a6SSeth Howell	config_params='--enable-debug --enable-werror'
409c9e5d2a6SSeth Howell
4108a43cd27Spaul luse	# for options with dependencies but no test flag, set them here
4118a43cd27Spaul luse	if [ -f /usr/include/infiniband/verbs.h ]; then
4128a43cd27Spaul luse		config_params+=' --with-rdma'
4138a43cd27Spaul luse	fi
4148a43cd27Spaul luse
41591751e1eSMonica Kenguva	if [ $SPDK_TEST_USDT -eq 1 ]; then
41691751e1eSMonica Kenguva		config_params+=" --with-usdt"
41791751e1eSMonica Kenguva	fi
41891751e1eSMonica Kenguva
4192755fbdfSpaul luse	if [ $(uname -s) == "FreeBSD" ]; then
4202755fbdfSpaul luse		intel="hw.model: Intel"
4212755fbdfSpaul luse		cpu_vendor=$(sysctl -a | grep hw.model | cut -c 1-15)
4222755fbdfSpaul luse	else
423e58e9fbdSpaul luse		intel="GenuineIntel"
424e58e9fbdSpaul luse		cpu_vendor=$(grep -i 'vendor' /proc/cpuinfo --max-count=1)
4252755fbdfSpaul luse	fi
426e58e9fbdSpaul luse	if [[ "$cpu_vendor" != *"$intel"* ]]; then
427e58e9fbdSpaul luse		config_params+=" --without-idxd"
428e58e9fbdSpaul luse	else
429e58e9fbdSpaul luse		config_params+=" --with-idxd"
430e58e9fbdSpaul luse	fi
431e58e9fbdSpaul luse
432053c15b3SMichal Berger	if [[ -d $CONFIG_FIO_SOURCE_DIR ]]; then
433053c15b3SMichal Berger		config_params+=" --with-fio=$CONFIG_FIO_SOURCE_DIR"
4348a43cd27Spaul luse	fi
4358a43cd27Spaul luse
4368a43cd27Spaul luse	if [ -d ${DEPENDENCY_DIR}/vtune_codes ]; then
4378a43cd27Spaul luse		config_params+=' --with-vtune='${DEPENDENCY_DIR}'/vtune_codes'
4388a43cd27Spaul luse	fi
4398a43cd27Spaul luse
4408a43cd27Spaul luse	if [ -d /usr/include/iscsi ]; then
44185bf4c81SMichal Berger		[[ $(< /usr/include/iscsi/iscsi.h) =~ "define LIBISCSI_API_VERSION ("([0-9]+)")" ]] \
44285bf4c81SMichal Berger			&& libiscsi_version=${BASH_REMATCH[1]}
44385bf4c81SMichal Berger		if ((libiscsi_version >= 20150621)); then
4448a43cd27Spaul luse			config_params+=' --with-iscsi-initiator'
4458a43cd27Spaul luse		fi
4468a43cd27Spaul luse	fi
4478a43cd27Spaul luse
448dfb2950fSMichal Berger	if [[ $SPDK_TEST_UNITTEST -eq 0 &&
449dfb2950fSMichal Berger		$SPDK_TEST_SCANBUILD -eq 0 && -z ${SPDK_TEST_AUTOBUILD:-} ]]; then
45079c28aa6STomasz Zawadzki		config_params+=' --disable-unit-tests'
45179c28aa6STomasz Zawadzki	fi
45279c28aa6STomasz Zawadzki
45319e2dc38Spaul luse	if [ -f /usr/include/libpmem.h ] && [ $SPDK_TEST_VBDEV_COMPRESS -eq 1 ]; then
454dbd140b2SMichal Berger		if ge "$(nasm --version | awk '{print $3}')" 2.14 && [[ $SPDK_TEST_ISAL -eq 1 ]]; then
455976f8b09Spaul luse			config_params+=' --with-vbdev-compress --with-dpdk-compressdev'
4568a43cd27Spaul luse		fi
4578a43cd27Spaul luse	fi
4588a43cd27Spaul luse
4598a43cd27Spaul luse	if [ -d /usr/include/rbd ] && [ -d /usr/include/rados ] && [ $SPDK_TEST_RBD -eq 1 ]; then
4608a43cd27Spaul luse		config_params+=' --with-rbd'
4618a43cd27Spaul luse	fi
4628a43cd27Spaul luse
4638a43cd27Spaul luse	# for options with no required dependencies, just test flags, set them here
46451606ed4SPaul Luse	if [ $SPDK_TEST_CRYPTO -eq 1 ]; then
46551606ed4SPaul Luse		config_params+=' --with-crypto'
46651606ed4SPaul Luse	fi
46751606ed4SPaul Luse
4682fde729fSVitaliy Mysak	if [ $SPDK_TEST_OCF -eq 1 ]; then
46934bdceabSVitaliy Mysak		config_params+=" --with-ocf"
4702fde729fSVitaliy Mysak	fi
4712fde729fSVitaliy Mysak
472e20401c8SDarek Stojaczyk	if [ $SPDK_RUN_UBSAN -eq 1 ]; then
473e20401c8SDarek Stojaczyk		config_params+=' --enable-ubsan'
474e20401c8SDarek Stojaczyk	fi
475e20401c8SDarek Stojaczyk
476e20401c8SDarek Stojaczyk	if [ $SPDK_RUN_ASAN -eq 1 ]; then
477e20401c8SDarek Stojaczyk		config_params+=' --enable-asan'
478e20401c8SDarek Stojaczyk	fi
479e20401c8SDarek Stojaczyk
480c9e5d2a6SSeth Howell	config_params+=' --enable-coverage'
481c9e5d2a6SSeth Howell
4827fa15e28SXiaodong Liu	if [ $SPDK_TEST_BLOBFS -eq 1 ]; then
4835f66e5b1SChangpeng Liu		if [[ -d /usr/include/fuse3 ]] || [[ -d /usr/local/include/fuse3 ]]; then
4847fa15e28SXiaodong Liu			config_params+=' --with-fuse'
4857fa15e28SXiaodong Liu		fi
4867fa15e28SXiaodong Liu	fi
4877fa15e28SXiaodong Liu
48840e8ee2aSYifan Bian	if [[ -f /usr/include/liburing/io_uring.h && -f /usr/include/linux/ublk_cmd.h ]]; then
48940e8ee2aSYifan Bian		config_params+=' --with-ublk'
49040e8ee2aSYifan Bian	fi
49140e8ee2aSYifan Bian
492cac68eecSKamil Godzwon	if [ $SPDK_TEST_RAID -eq 1 ]; then
49383a4b155SArtur Paszkiewicz		config_params+=' --with-raid5f'
49473763d40SArtur Paszkiewicz	fi
49573763d40SArtur Paszkiewicz
4964978c4feSXin Yang	if [ $SPDK_TEST_VFIOUSER -eq 1 ] || [ $SPDK_TEST_VFIOUSER_QEMU -eq 1 ] || [ $SPDK_TEST_SMA -eq 1 ]; then
4973b673b84SChangpeng Liu		config_params+=' --with-vfio-user'
4983b673b84SChangpeng Liu	fi
4993b673b84SChangpeng Liu
500cd8b9455SZiye Yang	# Check whether liburing library header exists
501cd8b9455SZiye Yang	if [ -f /usr/include/liburing/io_uring.h ] && [ $SPDK_TEST_URING -eq 1 ]; then
502cd8b9455SZiye Yang		config_params+=' --with-uring'
503cd8b9455SZiye Yang	fi
504cd8b9455SZiye Yang
5053f52d265SMike Gerdts	if [ -n "${SPDK_RUN_EXTERNAL_DPDK:-}" ]; then
50649473bdcSDarek Stojaczyk		config_params+=" --with-dpdk=$SPDK_RUN_EXTERNAL_DPDK"
507c9e5d2a6SSeth Howell	fi
508c9e5d2a6SSeth Howell
509cfbab2dcSJaroslaw Chachulski	if [[ $SPDK_TEST_SMA -eq 1 ]]; then
510cfbab2dcSJaroslaw Chachulski		config_params+=' --with-sma'
511a9d10dadSSebastian Brzezinka		config_params+=' --with-crypto'
512cfbab2dcSJaroslaw Chachulski	fi
513cfbab2dcSJaroslaw Chachulski
5142e283fcbS0xe0f	if [ -f /usr/include/daos.h ] && [ $SPDK_TEST_DAOS -eq 1 ]; then
5152e283fcbS0xe0f		config_params+=' --with-daos'
5162e283fcbS0xe0f	fi
5172e283fcbS0xe0f
518c8f62d79SMichal Berger	# Make the xnvme module available for the tests
519c8f62d79SMichal Berger	if [[ $SPDK_TEST_XNVME -eq 1 ]]; then
520c8f62d79SMichal Berger		config_params+=' --with-xnvme'
521c8f62d79SMichal Berger	fi
522c8f62d79SMichal Berger
523f72f1547SMichal Berger	if [[ $SPDK_TEST_FUZZER -eq 1 ]]; then
524f72f1547SMichal Berger		config_params+=" $(get_fuzzer_target_config)"
525f72f1547SMichal Berger	fi
526f72f1547SMichal Berger
5276d4d5c62SParameswaran Krishnamurthy	if [[ $SPDK_TEST_NVMF_MDNS -eq 1 ]]; then
5286d4d5c62SParameswaran Krishnamurthy		config_params+=' --with-avahi'
5296d4d5c62SParameswaran Krishnamurthy	fi
5306d4d5c62SParameswaran Krishnamurthy
5311e46e023SMaciej Mis	if [[ $SPDK_JSONRPC_GO_CLIENT -eq 1 ]]; then
5321e46e023SMaciej Mis		config_params+=' --with-golang'
5331e46e023SMaciej Mis	fi
5341e46e023SMaciej Mis
5354f7f0f09SSeth Howell	echo "$config_params"
5364f7f0f09SSeth Howell	xtrace_restore
5374f7f0f09SSeth Howell}
5388b98cdb6SDarek Stojaczyk
539f72f1547SMichal Bergerfunction get_fuzzer_target_config() {
540f72f1547SMichal Berger	local -A fuzzer_targets_to_config=()
541f72f1547SMichal Berger	local config target
542f72f1547SMichal Berger
543f72f1547SMichal Berger	fuzzer_targets_to_config["vfio"]="--with-vfio-user"
544f72f1547SMichal Berger	for target in $(get_fuzzer_targets); do
5453f52d265SMike Gerdts		[[ -n ${fuzzer_targets_to_config["$target"]:-} ]] || continue
546f72f1547SMichal Berger		config+=("${fuzzer_targets_to_config["$target"]}")
547f72f1547SMichal Berger	done
548f72f1547SMichal Berger
549f72f1547SMichal Berger	if ((${#config[@]} > 0)); then
550f72f1547SMichal Berger		echo "${config[*]}"
551f72f1547SMichal Berger	fi
552f72f1547SMichal Berger}
553f72f1547SMichal Berger
554f72f1547SMichal Bergerfunction get_fuzzer_targets() {
555f72f1547SMichal Berger	local fuzzers=()
556f72f1547SMichal Berger
5573f52d265SMike Gerdts	if [[ -n ${SPDK_TEST_FUZZER_TARGET:-} ]]; then
558f72f1547SMichal Berger		IFS="," read -ra fuzzers <<< "$SPDK_TEST_FUZZER_TARGET"
559f72f1547SMichal Berger	else
560f72f1547SMichal Berger		fuzzers=("$rootdir/test/fuzz/llvm/"*)
561f72f1547SMichal Berger		fuzzers=("${fuzzers[@]##*/}")
562f72f1547SMichal Berger	fi
563f72f1547SMichal Berger
564f72f1547SMichal Berger	echo "${fuzzers[*]}"
565f72f1547SMichal Berger}
566f72f1547SMichal Berger
5678b98cdb6SDarek Stojaczykfunction rpc_cmd() {
5688b98cdb6SDarek Stojaczyk	xtrace_disable
56908d4dce2SMichal Berger	local rsp rc=1
57008d4dce2SMichal Berger	local stdin cmd cmds_number=0 status_number=0 status
5718b98cdb6SDarek Stojaczyk
57208d4dce2SMichal Berger	if (($#)); then
57308d4dce2SMichal Berger		cmds_number=1
5748b98cdb6SDarek Stojaczyk		echo "$@" >&$RPC_PIPE_INPUT
57508d4dce2SMichal Berger	elif [[ ! -t 0 ]]; then
57608d4dce2SMichal Berger		mapfile -t stdin <&0
57708d4dce2SMichal Berger		cmds_number=${#stdin[@]}
57808d4dce2SMichal Berger		printf '%s\n' "${stdin[@]}" >&$RPC_PIPE_INPUT
57908d4dce2SMichal Berger	else
58008d4dce2SMichal Berger		return 0
58108d4dce2SMichal Berger	fi
58208d4dce2SMichal Berger
5837755333cSMichal Berger	while read -t "${RPC_PIPE_TIMEOUT:-15}" -ru $RPC_PIPE_OUTPUT rsp; do
5848b98cdb6SDarek Stojaczyk		if [[ $rsp == "**STATUS="* ]]; then
58508d4dce2SMichal Berger			status[${rsp#*=}]=$rsp
58608d4dce2SMichal Berger			if ((++status_number == cmds_number)); then
5878b98cdb6SDarek Stojaczyk				break
5888b98cdb6SDarek Stojaczyk			fi
58908d4dce2SMichal Berger			continue
59008d4dce2SMichal Berger		fi
5918b98cdb6SDarek Stojaczyk		echo "$rsp"
5928b98cdb6SDarek Stojaczyk	done
5938b98cdb6SDarek Stojaczyk
59408d4dce2SMichal Berger	rc=${!status[*]}
5958b98cdb6SDarek Stojaczyk	xtrace_restore
5968b98cdb6SDarek Stojaczyk	[[ $rc == 0 ]]
5978b98cdb6SDarek Stojaczyk}
5988b98cdb6SDarek Stojaczyk
59964cfaf3fSMichal Bergerfunction rpc_cmd_simple_data_json() {
60064cfaf3fSMichal Berger
60164cfaf3fSMichal Berger	local elems="$1[@]" elem
60264cfaf3fSMichal Berger	local -gA jq_out=()
60364cfaf3fSMichal Berger	local jq val
60464cfaf3fSMichal Berger
60564cfaf3fSMichal Berger	local lvs=(
60664cfaf3fSMichal Berger		"uuid"
60764cfaf3fSMichal Berger		"name"
60864cfaf3fSMichal Berger		"base_bdev"
60964cfaf3fSMichal Berger		"total_data_clusters"
61064cfaf3fSMichal Berger		"free_clusters"
61164cfaf3fSMichal Berger		"block_size"
61264cfaf3fSMichal Berger		"cluster_size"
61364cfaf3fSMichal Berger	)
61464cfaf3fSMichal Berger
61564cfaf3fSMichal Berger	local bdev=(
61664cfaf3fSMichal Berger		"name"
61764cfaf3fSMichal Berger		"aliases[0]"
61864cfaf3fSMichal Berger		"block_size"
61964cfaf3fSMichal Berger		"num_blocks"
62064cfaf3fSMichal Berger		"uuid"
62164cfaf3fSMichal Berger		"product_name"
622a67e0eb3SMike Gerdts		"supported_io_types.read"
623a67e0eb3SMike Gerdts		"supported_io_types.write"
624a67e0eb3SMike Gerdts		"driver_specific.lvol.clone"
625a67e0eb3SMike Gerdts		"driver_specific.lvol.base_snapshot"
626a67e0eb3SMike Gerdts		"driver_specific.lvol.esnap_clone"
627a67e0eb3SMike Gerdts		"driver_specific.lvol.external_snapshot_name"
62864cfaf3fSMichal Berger	)
62964cfaf3fSMichal Berger
63064cfaf3fSMichal Berger	[[ -v $elems ]] || return 1
63164cfaf3fSMichal Berger
63264cfaf3fSMichal Berger	for elem in "${!elems}"; do
63364cfaf3fSMichal Berger		jq="${jq:+$jq,\"\\n\",}\"$elem\",\" \",.[0].$elem"
63464cfaf3fSMichal Berger	done
63564cfaf3fSMichal Berger	jq+=',"\n"'
63664cfaf3fSMichal Berger
63764cfaf3fSMichal Berger	shift
63864cfaf3fSMichal Berger	while read -r elem val; do
63964cfaf3fSMichal Berger		jq_out["$elem"]=$val
64064cfaf3fSMichal Berger	done < <(rpc_cmd "$@" | jq -jr "$jq")
64164cfaf3fSMichal Berger	((${#jq_out[@]} > 0)) || return 1
64264cfaf3fSMichal Berger}
64364cfaf3fSMichal Berger
6442cdc7e39SMichal Bergerfunction valid_exec_arg() {
6452cdc7e39SMichal Berger	local arg=$1
6462cdc7e39SMichal Berger	# First argument must be the executable so do some basic sanity checks first. For bash, this
6472cdc7e39SMichal Berger	# covers two basic cases where es == 126 || es == 127 so catch them early on and fail hard
6482cdc7e39SMichal Berger	# if needed.
6492cdc7e39SMichal Berger	case "$(type -t "$arg")" in
6502cdc7e39SMichal Berger		builtin | function) ;;
6512cdc7e39SMichal Berger		file) arg=$(type -P "$arg") && [[ -x $arg ]] ;;
6522cdc7e39SMichal Berger		*) return 1 ;;
6532cdc7e39SMichal Berger	esac
6542cdc7e39SMichal Berger}
6552cdc7e39SMichal Berger
656c29329feSDarek Stojaczykfunction NOT() {
657a9337f72SMichal Berger	local es=0
658a9337f72SMichal Berger
6592cdc7e39SMichal Berger	valid_exec_arg "$@" || return 1
660a9337f72SMichal Berger	"$@" || es=$?
661a9337f72SMichal Berger
662a9337f72SMichal Berger	# Logic looks like so:
663a9337f72SMichal Berger	#  - return false if command exit successfully
664a9337f72SMichal Berger	#  - return false if command exit after receiving a core signal (FIXME: or any signal?)
665a9337f72SMichal Berger	#  - return true if command exit with an error
666a9337f72SMichal Berger
667a9337f72SMichal Berger	# This naively assumes that the process doesn't exit with > 128 on its own.
668a9337f72SMichal Berger	if ((es > 128)); then
669a9337f72SMichal Berger		es=$((es & ~128))
670a9337f72SMichal Berger		case "$es" in
671a9337f72SMichal Berger			3) ;&       # SIGQUIT
672a9337f72SMichal Berger			4) ;&       # SIGILL
673a9337f72SMichal Berger			6) ;&       # SIGABRT
674a9337f72SMichal Berger			8) ;&       # SIGFPE
675a9337f72SMichal Berger			9) ;&       # SIGKILL
676a9337f72SMichal Berger			11) es=0 ;; # SIGSEGV
677a9337f72SMichal Berger			*) es=1 ;;
678a9337f72SMichal Berger		esac
6793f52d265SMike Gerdts	elif [[ -n ${EXIT_STATUS:-} ]] && ((es != EXIT_STATUS)); then
680a9337f72SMichal Berger		es=0
681c29329feSDarek Stojaczyk	fi
682a9337f72SMichal Berger
683a9337f72SMichal Berger	# invert error code of any command and also trigger ERR on 0 (unlike bash ! prefix)
684a9337f72SMichal Berger	((!es == 0))
685c29329feSDarek Stojaczyk}
686c29329feSDarek Stojaczyk
687c9e5d2a6SSeth Howellfunction timing() {
688c9e5d2a6SSeth Howell	direction="$1"
689c9e5d2a6SSeth Howell	testname="$2"
690c9e5d2a6SSeth Howell
691c9e5d2a6SSeth Howell	now=$(date +%s)
692c9e5d2a6SSeth Howell
693c9e5d2a6SSeth Howell	if [ "$direction" = "enter" ]; then
6943f52d265SMike Gerdts		export timing_stack="${timing_stack:-};${now}"
6953f52d265SMike Gerdts		export test_stack="${test_stack:-};${testname}"
696c9e5d2a6SSeth Howell	else
6977c00bdabSDarek Stojaczyk		touch "$output_dir/timing.txt"
698c9e5d2a6SSeth Howell		child_time=$(grep "^${test_stack:1};" $output_dir/timing.txt | awk '{s+=$2} END {print s}')
699c9e5d2a6SSeth Howell
700c9e5d2a6SSeth Howell		start_time=$(echo "$timing_stack" | sed -e 's@^.*;@@')
701c9e5d2a6SSeth Howell		timing_stack=$(echo "$timing_stack" | sed -e 's@;[^;]*$@@')
702c9e5d2a6SSeth Howell
703c9e5d2a6SSeth Howell		elapsed=$((now - start_time - child_time))
704c9e5d2a6SSeth Howell		echo "${test_stack:1} $elapsed" >> $output_dir/timing.txt
705c9e5d2a6SSeth Howell
706c9e5d2a6SSeth Howell		test_stack=$(echo "$test_stack" | sed -e 's@;[^;]*$@@')
707c9e5d2a6SSeth Howell	fi
708c9e5d2a6SSeth Howell}
709c9e5d2a6SSeth Howell
7108d3047dfSMichal Bergerfunction timing_cmd() (
7118d3047dfSMichal Berger	# The use-case here is this: ts=$(timing_cmd echo bar). Since stdout is always redirected
7128d3047dfSMichal Berger	# to a pipe handling the $(), lookup the stdin's device and determine if it's sane to send
7138d3047dfSMichal Berger	# cmd's output to it. If not, just null it.
714f3febe42SMichal Berger	local cmd_es=$?
7158d3047dfSMichal Berger
7168d3047dfSMichal Berger	[[ -t 0 ]] && exec {cmd_out}>&0 || exec {cmd_out}> /dev/null
7178d3047dfSMichal Berger
7188d3047dfSMichal Berger	local time=0 TIMEFORMAT=%2R # seconds
7198d3047dfSMichal Berger
7208d3047dfSMichal Berger	# We redirect cmd's std{out,err} to a separate fd dup'ed to stdin's device (or /dev/null) to
7218d3047dfSMichal Berger	# catch only output from the time builtin - output from the actual cmd would be still visible,
7228d3047dfSMichal Berger	# but $() will return just the time's data, hence making it possible to just do:
7238d3047dfSMichal Berger	#  time_of_super_verbose_cmd=$(timing_cmd super_verbose_cmd)
724f3febe42SMichal Berger	time=$({ time "$@" >&"$cmd_out" 2>&1; } 2>&1) || cmd_es=$?
7258d3047dfSMichal Berger	echo "$time"
726f3febe42SMichal Berger
727f3febe42SMichal Berger	return "$cmd_es"
7288d3047dfSMichal Berger)
7298d3047dfSMichal Berger
730c9e5d2a6SSeth Howellfunction timing_enter() {
7313b660ea8SDarek Stojaczyk	xtrace_disable
732c9e5d2a6SSeth Howell	timing "enter" "$1"
7333b660ea8SDarek Stojaczyk	xtrace_restore
734c9e5d2a6SSeth Howell}
735c9e5d2a6SSeth Howell
736c9e5d2a6SSeth Howellfunction timing_exit() {
7373b660ea8SDarek Stojaczyk	xtrace_disable
738c9e5d2a6SSeth Howell	timing "exit" "$1"
7393b660ea8SDarek Stojaczyk	xtrace_restore
740c9e5d2a6SSeth Howell}
741c9e5d2a6SSeth Howell
742c9e5d2a6SSeth Howellfunction timing_finish() {
743c9e5d2a6SSeth Howell	flamegraph='/usr/local/FlameGraph/flamegraph.pl'
74426f88ce7SMichal Berger	[[ -x "$flamegraph" ]] || return 1
74526f88ce7SMichal Berger
746c9e5d2a6SSeth Howell	"$flamegraph" \
747c9e5d2a6SSeth Howell		--title 'Build Timing' \
748c9e5d2a6SSeth Howell		--nametype 'Step:' \
749c9e5d2a6SSeth Howell		--countname seconds \
75026f88ce7SMichal Berger		"$output_dir/timing.txt" \
75126f88ce7SMichal Berger		> "$output_dir/timing.svg"
752c9e5d2a6SSeth Howell}
753c9e5d2a6SSeth Howell
754a562812dSSeth Howellfunction create_test_list() {
75552330a6bSDarek Stojaczyk	xtrace_disable
756863d73d3STomasz Zawadzki	# First search all scripts in main SPDK directory.
757863d73d3STomasz Zawadzki	completion=$(grep -shI -d skip --include="*.sh" -e "run_test " $rootdir/*)
758863d73d3STomasz Zawadzki	# Follow up with search in test directory recursively.
7598a810f5fSMichal Berger	completion+=$'\n'$(grep -rshI --include="*.sh" --exclude="*autotest_common.sh" -e "run_test " $rootdir/test)
760863d73d3STomasz Zawadzki	printf "%s" "$completion" | grep -v "#" \
761844c8ec3SMichal Berger		| sed 's/^.*run_test/run_test/' | awk '{print $2}' \
762844c8ec3SMichal Berger		| sed 's/\"//g' | sort > $output_dir/all_tests.txt || true
76352330a6bSDarek Stojaczyk	xtrace_restore
764a562812dSSeth Howell}
765a562812dSSeth Howell
766327668c8STomasz Kulasekfunction gdb_attach() {
767327668c8STomasz Kulasek	gdb -q --batch \
768327668c8STomasz Kulasek		-ex 'handle SIGHUP nostop pass' \
769327668c8STomasz Kulasek		-ex 'handle SIGQUIT nostop pass' \
770327668c8STomasz Kulasek		-ex 'handle SIGPIPE nostop pass' \
771327668c8STomasz Kulasek		-ex 'handle SIGALRM nostop pass' \
772327668c8STomasz Kulasek		-ex 'handle SIGTERM nostop pass' \
773327668c8STomasz Kulasek		-ex 'handle SIGUSR1 nostop pass' \
774327668c8STomasz Kulasek		-ex 'handle SIGUSR2 nostop pass' \
775327668c8STomasz Kulasek		-ex 'handle SIGCHLD nostop pass' \
776327668c8STomasz Kulasek		-ex 'set print thread-events off' \
777327668c8STomasz Kulasek		-ex 'cont' \
778327668c8STomasz Kulasek		-ex 'thread apply all bt' \
779327668c8STomasz Kulasek		-ex 'quit' \
780327668c8STomasz Kulasek		--tty=/dev/stdout \
781327668c8STomasz Kulasek		-p $1
782327668c8STomasz Kulasek}
783327668c8STomasz Kulasek
784c9e5d2a6SSeth Howellfunction process_core() {
78545c42ac2SMichal Berger	# Note that this always was racy as we can't really sync with the kernel
78645c42ac2SMichal Berger	# to see if there's any core queued up for writing. We could check if
78745c42ac2SMichal Berger	# collector is running and wait for it explicitly, but it doesn't seem
78845c42ac2SMichal Berger	# to be worth the effort. So assume that if we are being called via
78989df50bcSMichal Berger	# trap, as in, when some error has occurred, wait up to 10s for any
79045c42ac2SMichal Berger	# potential cores. If we are called just for cleanup at the very end,
79145c42ac2SMichal Berger	# don't wait since all the tests ended successfully, hence having any
79245c42ac2SMichal Berger	# critical cores lying around is unlikely.
79389df50bcSMichal Berger	((autotest_es != 0)) && sleep 10
79445c42ac2SMichal Berger
79545c42ac2SMichal Berger	local coredumps core
79645c42ac2SMichal Berger
79745c42ac2SMichal Berger	coredumps=("$output_dir/coredumps/"*.bt.txt)
79845c42ac2SMichal Berger
79945c42ac2SMichal Berger	((${#coredumps[@]} > 0)) || return 0
80045c42ac2SMichal Berger	chmod -R a+r "$output_dir/coredumps"
80145c42ac2SMichal Berger
80245c42ac2SMichal Berger	for core in "${coredumps[@]}"; do
80345c42ac2SMichal Berger		cat <<- BT
80445c42ac2SMichal Berger			##### CORE BT ${core##*/} #####
80545c42ac2SMichal Berger
80645c42ac2SMichal Berger			$(< "$core")
80745c42ac2SMichal Berger
80845c42ac2SMichal Berger			--
80945c42ac2SMichal Berger		BT
81045c42ac2SMichal Berger	done
81145c42ac2SMichal Berger	return 1
812c9e5d2a6SSeth Howell}
813c9e5d2a6SSeth Howell
814af32aa1bSKarol Lateckifunction process_shm() {
815af32aa1bSKarol Latecki	type=$1
816af32aa1bSKarol Latecki	id=$2
817af32aa1bSKarol Latecki	if [ "$type" = "--pid" ]; then
818af32aa1bSKarol Latecki		id="pid${id}"
819af32aa1bSKarol Latecki	fi
820af32aa1bSKarol Latecki
821af32aa1bSKarol Latecki	shm_files=$(find /dev/shm -name "*.${id}" -printf "%f\n")
822af32aa1bSKarol Latecki
8233f52d265SMike Gerdts	if [[ -z ${shm_files:-} ]]; then
824af32aa1bSKarol Latecki		echo "SHM File for specified PID or shared memory id: ${id} not found!"
825af32aa1bSKarol Latecki		return 1
826af32aa1bSKarol Latecki	fi
827af32aa1bSKarol Latecki	for n in $shm_files; do
828af32aa1bSKarol Latecki		tar -C /dev/shm/ -cvzf $output_dir/${n}_shm.tar.gz ${n}
829af32aa1bSKarol Latecki	done
830af32aa1bSKarol Latecki	return 0
831af32aa1bSKarol Latecki}
832af32aa1bSKarol Latecki
8334674af01SPawel Piatek# Parameters:
8344674af01SPawel Piatek# $1 - process pid
8354674af01SPawel Piatek# $2 - rpc address (optional)
8364674af01SPawel Piatek# $3 - max retries (optional)
837c9e5d2a6SSeth Howellfunction waitforlisten() {
8383f52d265SMike Gerdts	if [ -z "${1:-}" ]; then
839c9e5d2a6SSeth Howell		exit 1
840c9e5d2a6SSeth Howell	fi
841c9e5d2a6SSeth Howell
842f751ea17SPawel Wodkowski	local rpc_addr="${2:-$DEFAULT_RPC_ADDR}"
8434674af01SPawel Piatek	local max_retries=${3:-100}
844c9e5d2a6SSeth Howell
845c9e5d2a6SSeth Howell	echo "Waiting for process to start up and listen on UNIX domain socket $rpc_addr..."
846c9e5d2a6SSeth Howell	# turn off trace for this loop
8473b660ea8SDarek Stojaczyk	xtrace_disable
848f751ea17SPawel Wodkowski	local ret=0
849db1236efSPawel Wodkowski	local i
8504674af01SPawel Piatek	for ((i = max_retries; i != 0; i--)); do
851c9e5d2a6SSeth Howell		# if the process is no longer running, then exit the script
852c9e5d2a6SSeth Howell		#  since it means the application crashed
853c9e5d2a6SSeth Howell		if ! kill -s 0 $1; then
854db1236efSPawel Wodkowski			echo "ERROR: process (pid: $1) is no longer running"
855f751ea17SPawel Wodkowski			ret=1
856f751ea17SPawel Wodkowski			break
857c9e5d2a6SSeth Howell		fi
8585bafc240STomasz Zawadzki
8596ee44c69SJim Harris		if $rootdir/scripts/rpc.py -t 1 -s "$rpc_addr" rpc_get_methods &> /dev/null; then
860db1236efSPawel Wodkowski			break
861c9e5d2a6SSeth Howell		fi
86282583134SDarek Stojaczyk
863db1236efSPawel Wodkowski		sleep 0.5
864c9e5d2a6SSeth Howell	done
865f751ea17SPawel Wodkowski
8663b660ea8SDarek Stojaczyk	xtrace_restore
867db1236efSPawel Wodkowski	if ((i == 0)); then
868db1236efSPawel Wodkowski		echo "ERROR: timeout while waiting for process (pid: $1) to start listening on '$rpc_addr'"
869db1236efSPawel Wodkowski		ret=1
870f751ea17SPawel Wodkowski	fi
871db1236efSPawel Wodkowski	return $ret
872c9e5d2a6SSeth Howell}
873c9e5d2a6SSeth Howell
874c9e5d2a6SSeth Howellfunction waitfornbd() {
875bf9dbae5SPawel Wodkowski	local nbd_name=$1
876bf9dbae5SPawel Wodkowski	local i
877c9e5d2a6SSeth Howell
878c9e5d2a6SSeth Howell	for ((i = 1; i <= 20; i++)); do
879c9e5d2a6SSeth Howell		if grep -q -w $nbd_name /proc/partitions; then
880c9e5d2a6SSeth Howell			break
881c9e5d2a6SSeth Howell		else
882c9e5d2a6SSeth Howell			sleep 0.1
883c9e5d2a6SSeth Howell		fi
884c9e5d2a6SSeth Howell	done
885c9e5d2a6SSeth Howell
886c9e5d2a6SSeth Howell	# The nbd device is now recognized as a block device, but there can be
887c9e5d2a6SSeth Howell	#  a small delay before we can start I/O to that block device.  So loop
888c9e5d2a6SSeth Howell	#  here trying to read the first block of the nbd block device to a temp
889c9e5d2a6SSeth Howell	#  file.  Note that dd returns success when reading an empty file, so we
890c9e5d2a6SSeth Howell	#  need to check the size of the output file instead.
891c9e5d2a6SSeth Howell	for ((i = 1; i <= 20; i++)); do
892fe711156SMichal Berger		dd if=/dev/$nbd_name of="$SPDK_TEST_STORAGE/nbdtest" bs=4096 count=1 iflag=direct
893fe711156SMichal Berger		size=$(stat -c %s "$SPDK_TEST_STORAGE/nbdtest")
894fe711156SMichal Berger		rm -f "$SPDK_TEST_STORAGE/nbdtest"
895c9e5d2a6SSeth Howell		if [ "$size" != "0" ]; then
896c9e5d2a6SSeth Howell			return 0
897c9e5d2a6SSeth Howell		else
898c9e5d2a6SSeth Howell			sleep 0.1
899c9e5d2a6SSeth Howell		fi
900c9e5d2a6SSeth Howell	done
901c9e5d2a6SSeth Howell
902c9e5d2a6SSeth Howell	return 1
903c9e5d2a6SSeth Howell}
904c9e5d2a6SSeth Howell
905975e4614Spaul lusefunction waitforbdev() {
906975e4614Spaul luse	local bdev_name=$1
907d66bb2d1SKamil Godzwon	local bdev_timeout=$2
908975e4614Spaul luse	local i
9093f52d265SMike Gerdts	[[ -z ${bdev_timeout:-} ]] && bdev_timeout=2000 # ms
910975e4614Spaul luse
9117d5ba105SJim Harris	$rpc_py bdev_wait_for_examine
9127d5ba105SJim Harris
913d66bb2d1SKamil Godzwon	if $rpc_py bdev_get_bdevs -b $bdev_name -t $bdev_timeout; then
914975e4614Spaul luse		return 0
915975e4614Spaul luse	fi
916ab854135SBen Walker
917975e4614Spaul luse	return 1
918975e4614Spaul luse}
919975e4614Spaul luse
920cf9e9b2eSPawel Piatekfunction waitforcondition() {
921cf9e9b2eSPawel Piatek	local cond=$1
922cf9e9b2eSPawel Piatek	local max=${2:-10}
923cf9e9b2eSPawel Piatek	while ((max--)); do
924cf9e9b2eSPawel Piatek		if eval $cond; then
925cf9e9b2eSPawel Piatek			return 0
926cf9e9b2eSPawel Piatek		fi
927cf9e9b2eSPawel Piatek		sleep 1
928cf9e9b2eSPawel Piatek	done
929cf9e9b2eSPawel Piatek	return 1
930cf9e9b2eSPawel Piatek}
931cf9e9b2eSPawel Piatek
9320c7aeea9STomasz Zawadzkifunction make_filesystem() {
9330c7aeea9STomasz Zawadzki	local fstype=$1
9340c7aeea9STomasz Zawadzki	local dev_name=$2
9350c7aeea9STomasz Zawadzki	local i=0
9360c7aeea9STomasz Zawadzki	local force
9370c7aeea9STomasz Zawadzki
9380c7aeea9STomasz Zawadzki	if [ $fstype = ext4 ]; then
9390c7aeea9STomasz Zawadzki		force=-F
9400c7aeea9STomasz Zawadzki	else
9410c7aeea9STomasz Zawadzki		force=-f
9420c7aeea9STomasz Zawadzki	fi
9430c7aeea9STomasz Zawadzki
9440c7aeea9STomasz Zawadzki	while ! mkfs.${fstype} $force ${dev_name}; do
9450c7aeea9STomasz Zawadzki		if [ $i -ge 15 ]; then
9460c7aeea9STomasz Zawadzki			return 1
9470c7aeea9STomasz Zawadzki		fi
9480c7aeea9STomasz Zawadzki		i=$((i + 1))
9490c7aeea9STomasz Zawadzki		sleep 1
9500c7aeea9STomasz Zawadzki	done
9510c7aeea9STomasz Zawadzki
9520c7aeea9STomasz Zawadzki	return 0
9530c7aeea9STomasz Zawadzki}
9540c7aeea9STomasz Zawadzki
955c9e5d2a6SSeth Howellfunction killprocess() {
956c9e5d2a6SSeth Howell	# $1 = process pid
9573f52d265SMike Gerdts	if [ -z "${1:-}" ]; then
958f3b3c5bdSMichal Berger		return 1
959c9e5d2a6SSeth Howell	fi
960c9e5d2a6SSeth Howell
961f0a2cc82SKarol Latecki	if kill -0 $1; then
96239dce00bSJim Harris		if [ $(uname) = Linux ]; then
96339dce00bSJim Harris			process_name=$(ps --no-headers -o comm= $1)
96439dce00bSJim Harris		else
96539dce00bSJim Harris			process_name=$(ps -c -o command $1 | tail -1)
96639dce00bSJim Harris		fi
96739dce00bSJim Harris		if [ "$process_name" = "sudo" ]; then
968714a5646SBen Walker			# kill the child process, which is the actual app
969714a5646SBen Walker			# (assume $1 has just one child)
970074df1d8SPawel Kaminski			local child
971074df1d8SPawel Kaminski			child="$(pgrep -P $1)"
972714a5646SBen Walker			echo "killing process with pid $child"
973714a5646SBen Walker			kill $child
974714a5646SBen Walker		else
975c9e5d2a6SSeth Howell			echo "killing process with pid $1"
976c9e5d2a6SSeth Howell			kill $1
977714a5646SBen Walker		fi
978714a5646SBen Walker
979714a5646SBen Walker		# wait for the process regardless if its the dummy sudo one
980714a5646SBen Walker		# or the actual app - it should terminate anyway
981c9e5d2a6SSeth Howell		wait $1
98282f60376SGangCao	else
98382f60376SGangCao		# the process is not there anymore
98482f60376SGangCao		echo "Process with pid $1 is not found"
985f0a2cc82SKarol Latecki	fi
986c9e5d2a6SSeth Howell}
987c9e5d2a6SSeth Howell
988c9e5d2a6SSeth Howellfunction iscsicleanup() {
989c9e5d2a6SSeth Howell	echo "Cleaning up iSCSI connection"
990c9e5d2a6SSeth Howell	iscsiadm -m node --logout || true
991c9e5d2a6SSeth Howell	iscsiadm -m node -o delete || true
992dbb84dd5SKarol Latecki	rm -rf /var/lib/iscsi/nodes/*
993c9e5d2a6SSeth Howell}
994c9e5d2a6SSeth Howell
995c9e5d2a6SSeth Howellfunction stop_iscsi_service() {
996c9e5d2a6SSeth Howell	if cat /etc/*-release | grep Ubuntu; then
997c9e5d2a6SSeth Howell		service open-iscsi stop
998c9e5d2a6SSeth Howell	else
999c9e5d2a6SSeth Howell		service iscsid stop
1000c9e5d2a6SSeth Howell	fi
1001c9e5d2a6SSeth Howell}
1002c9e5d2a6SSeth Howell
1003c9e5d2a6SSeth Howellfunction start_iscsi_service() {
1004c9e5d2a6SSeth Howell	if cat /etc/*-release | grep Ubuntu; then
1005c9e5d2a6SSeth Howell		service open-iscsi start
1006c9e5d2a6SSeth Howell	else
1007c9e5d2a6SSeth Howell		service iscsid start
1008c9e5d2a6SSeth Howell	fi
1009c9e5d2a6SSeth Howell}
1010c9e5d2a6SSeth Howell
1011c9e5d2a6SSeth Howellfunction rbd_setup() {
10120629b01dSTomasz Zawadzki	# $1 = monitor ip address
10135bafc240STomasz Zawadzki	# $2 = name of the namespace
10143f52d265SMike Gerdts	if [ -z "${1:-}" ]; then
10150629b01dSTomasz Zawadzki		echo "No monitor IP address provided for ceph"
10160629b01dSTomasz Zawadzki		exit 1
10170629b01dSTomasz Zawadzki	fi
10183f52d265SMike Gerdts	if [ -n "${2:-}" ]; then
10195bafc240STomasz Zawadzki		if ip netns list | grep "$2"; then
10205bafc240STomasz Zawadzki			NS_CMD="ip netns exec $2"
10215bafc240STomasz Zawadzki		else
10225bafc240STomasz Zawadzki			echo "No namespace $2 exists"
10235bafc240STomasz Zawadzki			exit 1
10245bafc240STomasz Zawadzki		fi
10255bafc240STomasz Zawadzki	fi
10260629b01dSTomasz Zawadzki
1027c9e5d2a6SSeth Howell	if hash ceph; then
1028397521bdSSeth Howell		export PG_NUM=128
1029c9e5d2a6SSeth Howell		export RBD_POOL=rbd
1030c9e5d2a6SSeth Howell		export RBD_NAME=foo
10316907c36fSyidong0635		$NS_CMD $rootdir/scripts/ceph/stop.sh || true
10325bafc240STomasz Zawadzki		$NS_CMD $rootdir/scripts/ceph/start.sh $1
1033397521bdSSeth Howell
10345bafc240STomasz Zawadzki		$NS_CMD ceph osd pool create $RBD_POOL $PG_NUM || true
10355bafc240STomasz Zawadzki		$NS_CMD rbd create $RBD_NAME --size 1000
1036c9e5d2a6SSeth Howell	fi
1037c9e5d2a6SSeth Howell}
1038c9e5d2a6SSeth Howell
1039c9e5d2a6SSeth Howellfunction rbd_cleanup() {
1040c9e5d2a6SSeth Howell	if hash ceph; then
1041d51ea8deSDaniel Verkamp		$rootdir/scripts/ceph/stop.sh || true
1042ab1622aaSKarol Latecki		rm -f /var/tmp/ceph_raw.img
1043c9e5d2a6SSeth Howell	fi
1044c9e5d2a6SSeth Howell}
1045c9e5d2a6SSeth Howell
10462e283fcbS0xe0ffunction daos_setup() {
10472e283fcbS0xe0f	# $1 = pool name
10482e283fcbS0xe0f	# $2 = cont name
10493f52d265SMike Gerdts	if [ -z "${1:-}" ]; then
10502e283fcbS0xe0f		echo "No pool name provided"
10512e283fcbS0xe0f		exit 1
10522e283fcbS0xe0f	fi
10533f52d265SMike Gerdts	if [ -z "${2:-}" ]; then
10542e283fcbS0xe0f		echo "No cont name provided"
10552e283fcbS0xe0f		exit 1
10562e283fcbS0xe0f	fi
10572e283fcbS0xe0f
10582e283fcbS0xe0f	dmg pool create --size=10G $1 || true
10592e283fcbS0xe0f	daos container create --type=POSIX --label=$2 $1 || true
10602e283fcbS0xe0f}
10612e283fcbS0xe0f
10622e283fcbS0xe0ffunction daos_cleanup() {
10632e283fcbS0xe0f	local pool=${1:-testpool}
10642e283fcbS0xe0f	local cont=${2:-testcont}
10652e283fcbS0xe0f
10662e283fcbS0xe0f	daos container destroy -f $pool $cont || true
10672e283fcbS0xe0f	sudo dmg pool destroy -f $pool || true
10682e283fcbS0xe0f}
10692e283fcbS0xe0f
10709ba80de0SMichal Bergerfunction _start_stub() {
107118f3a22bSJim Harris	# Disable ASLR for multi-process testing.  SPDK does support using DPDK multi-process,
10729d04d0efSJim Harris	# but ASLR can still be unreliable in some cases.
10733f912cf0SMichal Berger	# We will re-enable it again after multi-process testing is complete in kill_stub().
10744b1dbc94SMichal Berger	# Save current setting so it can be restored upon calling kill_stub().
10754b1dbc94SMichal Berger	_randomize_va_space=$(< /proc/sys/kernel/randomize_va_space)
107618f3a22bSJim Harris	echo 0 > /proc/sys/kernel/randomize_va_space
1077c9e5d2a6SSeth Howell	$rootdir/test/app/stub/stub $1 &
1078c9e5d2a6SSeth Howell	stubpid=$!
1079c9e5d2a6SSeth Howell	echo Waiting for stub to ready for secondary processes...
1080c9e5d2a6SSeth Howell	while ! [ -e /var/run/spdk_stub0 ]; do
10819ba80de0SMichal Berger		# If stub dies while we wait, bail
10829ba80de0SMichal Berger		[[ -e /proc/$stubpid ]] || return 1
1083c9e5d2a6SSeth Howell		sleep 1s
1084c9e5d2a6SSeth Howell	done
1085c9e5d2a6SSeth Howell	echo done.
1086c9e5d2a6SSeth Howell}
1087c9e5d2a6SSeth Howell
10889ba80de0SMichal Bergerfunction start_stub() {
10899ba80de0SMichal Berger	if ! _start_stub "$@"; then
10909ba80de0SMichal Berger		echo "stub failed" >&2
10919ba80de0SMichal Berger		return 1
10929ba80de0SMichal Berger	fi
10939ba80de0SMichal Berger}
10949ba80de0SMichal Berger
1095c9e5d2a6SSeth Howellfunction kill_stub() {
10969ba80de0SMichal Berger	if [[ -e /proc/$stubpid ]]; then
1097ef6832efSJim Harris		kill $1 $stubpid
1098c9e5d2a6SSeth Howell		wait $stubpid
10999ba80de0SMichal Berger	fi 2> /dev/null || :
1100c9e5d2a6SSeth Howell	rm -f /var/run/spdk_stub0
110118f3a22bSJim Harris	# Re-enable ASLR now that we are done with multi-process testing
110218f3a22bSJim Harris	# Note: "1" enables ASLR w/o randomizing data segments, "2" adds data segment
110318f3a22bSJim Harris	#  randomizing and is the default on all recent Linux kernels
11044b1dbc94SMichal Berger	echo "${_randomize_va_space:-2}" > /proc/sys/kernel/randomize_va_space
1105c9e5d2a6SSeth Howell}
1106c9e5d2a6SSeth Howell
1107c9e5d2a6SSeth Howellfunction run_test() {
1108cb90136cSSeth Howell	if [ $# -le 1 ]; then
1109fd17f1aaSSeth Howell		echo "Not enough parameters"
1110cb90136cSSeth Howell		echo "usage: run_test test_name test_script [script_params]"
1111fd17f1aaSSeth Howell		exit 1
1112fd17f1aaSSeth Howell	fi
1113fd17f1aaSSeth Howell
11143b660ea8SDarek Stojaczyk	xtrace_disable
111548e6cc6fSMichal Berger	local test_name="$1" pid
111637100484SSeth Howell	shift
11171fafd71bSSeth Howell
11183f52d265SMike Gerdts	if [ -n "${test_domain:-}" ]; then
1119ea781d6dSSeth Howell		export test_domain="${test_domain}.${test_name}"
1120ea781d6dSSeth Howell	else
1121ea781d6dSSeth Howell		export test_domain="$test_name"
1122ea781d6dSSeth Howell	fi
1123ea781d6dSSeth Howell
11248d588fbcSMichal Berger	# Signal our daemons to update the test tag
1125d5fe62b2SMichal Berger	update_tag_monitor_resources "$test_domain"
11268d588fbcSMichal Berger
11271fafd71bSSeth Howell	timing_enter $test_name
1128c9e5d2a6SSeth Howell	echo "************************************"
1129cb90136cSSeth Howell	echo "START TEST $test_name"
1130c9e5d2a6SSeth Howell	echo "************************************"
11313b660ea8SDarek Stojaczyk	xtrace_restore
113248e6cc6fSMichal Berger	time "$@"
11333b660ea8SDarek Stojaczyk	xtrace_disable
1134c9e5d2a6SSeth Howell	echo "************************************"
1135cb90136cSSeth Howell	echo "END TEST $test_name"
1136c9e5d2a6SSeth Howell	echo "************************************"
11371fafd71bSSeth Howell	timing_exit $test_name
1138ea781d6dSSeth Howell
1139ea781d6dSSeth Howell	export test_domain=${test_domain%"$test_name"}
1140ea781d6dSSeth Howell	if [ -n "$test_domain" ]; then
1141ea781d6dSSeth Howell		export test_domain=${test_domain%?}
1142ea781d6dSSeth Howell	fi
1143ea781d6dSSeth Howell
11443f52d265SMike Gerdts	if [ -z "${test_domain:-}" ]; then
1145ea781d6dSSeth Howell		echo "top_level $test_name" >> $output_dir/test_completions.txt
1146ea781d6dSSeth Howell	else
1147ea781d6dSSeth Howell		echo "$test_domain $test_name" >> $output_dir/test_completions.txt
1148ea781d6dSSeth Howell	fi
11493b660ea8SDarek Stojaczyk	xtrace_restore
1150c9e5d2a6SSeth Howell}
1151c9e5d2a6SSeth Howell
1152148719daSKarol Lateckifunction skip_run_test_with_warning() {
1153148719daSKarol Latecki	echo "WARNING: $1"
1154148719daSKarol Latecki	echo "Test run may fail if run with autorun.sh"
1155148719daSKarol Latecki	echo "Please check your $rootdir/test/common/skipped_tests.txt"
1156148719daSKarol Latecki}
1157148719daSKarol Latecki
1158c9e5d2a6SSeth Howellfunction print_backtrace() {
1159b5d1b4f4SJim Harris	# if errexit is not enabled, don't print a backtrace
1160b5d1b4f4SJim Harris	[[ "$-" =~ e ]] || return 0
1161b5d1b4f4SJim Harris
116218b9303dSMichal Berger	local args=("${BASH_ARGV[@]}")
116318b9303dSMichal Berger
11643b660ea8SDarek Stojaczyk	xtrace_disable
11659d8e1ec0SMichal Berger	# Reset IFS in case we were called from an environment where it was modified
11669d8e1ec0SMichal Berger	IFS=" "$'\t'$'\n'
1167c9e5d2a6SSeth Howell	echo "========== Backtrace start: =========="
1168c9e5d2a6SSeth Howell	echo ""
11699d8e1ec0SMichal Berger	for ((i = 1; i < ${#FUNCNAME[@]}; i++)); do
1170c9e5d2a6SSeth Howell		local func="${FUNCNAME[$i]}"
1171c9e5d2a6SSeth Howell		local line_nr="${BASH_LINENO[$((i - 1))]}"
1172c9e5d2a6SSeth Howell		local src="${BASH_SOURCE[$i]}"
117318b9303dSMichal Berger		local bt="" cmdline=()
11741baf379eSMichal Berger
11751baf379eSMichal Berger		if [[ -f $src ]]; then
1176844c8ec3SMichal Berger			bt=$(nl -w 4 -ba -nln $src | grep -B 5 -A 5 "^${line_nr}[^0-9]" \
1177844c8ec3SMichal Berger				| sed "s/^/   /g" | sed "s/^   $line_nr /=> $line_nr /g")
11781baf379eSMichal Berger		fi
11791baf379eSMichal Berger
118018b9303dSMichal Berger		# If extdebug set the BASH_ARGC[i], try to fetch all the args
118118b9303dSMichal Berger		if ((BASH_ARGC[i] > 0)); then
118218b9303dSMichal Berger			# Use argc as index to reverse the stack
118318b9303dSMichal Berger			local argc=${BASH_ARGC[i]} arg
118418b9303dSMichal Berger			for arg in "${args[@]::BASH_ARGC[i]}"; do
118518b9303dSMichal Berger				cmdline[argc--]="[\"$arg\"]"
118618b9303dSMichal Berger			done
118718b9303dSMichal Berger			args=("${args[@]:BASH_ARGC[i]}")
118818b9303dSMichal Berger		fi
118918b9303dSMichal Berger
1190844c8ec3SMichal Berger		echo "in $src:$line_nr -> $func($(
1191844c8ec3SMichal Berger			IFS=","
1192844c8ec3SMichal Berger			printf '%s\n' "${cmdline[*]:-[]}"
1193844c8ec3SMichal Berger		))"
1194c9e5d2a6SSeth Howell		echo "     ..."
11951baf379eSMichal Berger		echo "${bt:-backtrace unavailable}"
1196c9e5d2a6SSeth Howell		echo "     ..."
1197c9e5d2a6SSeth Howell	done
1198c9e5d2a6SSeth Howell	echo ""
1199c9e5d2a6SSeth Howell	echo "========== Backtrace end =========="
12003b660ea8SDarek Stojaczyk	xtrace_restore
1201c9e5d2a6SSeth Howell	return 0
1202c9e5d2a6SSeth Howell}
1203c9e5d2a6SSeth Howell
1204844c8ec3SMichal Bergerfunction waitforserial() {
120553147e0dSMaciej Wawryk	local i=0
120629907b72SMichal Berger	local nvme_device_counter=1 nvme_devices=0
12073f52d265SMike Gerdts	if [[ -n "${2:-}" ]]; then
120853147e0dSMaciej Wawryk		nvme_device_counter=$2
120953147e0dSMaciej Wawryk	fi
121053147e0dSMaciej Wawryk
12115fb5e91eSKarol Latecki	# Wait initially for min 2s to make sure all devices are ready for use.
12125fb5e91eSKarol Latecki	sleep 2
12138bb27fafSMichal Berger	while ((i++ <= 15)); do
121429907b72SMichal Berger		nvme_devices=$(lsblk -l -o NAME,SERIAL | grep -c "$1")
121529907b72SMichal Berger		((nvme_devices == nvme_device_counter)) && return 0
121629907b72SMichal Berger		if ((nvme_devices > nvme_device_counter)); then
121729907b72SMichal Berger			echo "$nvme_device_counter device(s) expected, found $nvme_devices" >&2
121829907b72SMichal Berger		fi
121953147e0dSMaciej Wawryk		echo "Waiting for devices"
122053147e0dSMaciej Wawryk		sleep 1
122153147e0dSMaciej Wawryk	done
122253147e0dSMaciej Wawryk	return 1
122353147e0dSMaciej Wawryk}
122453147e0dSMaciej Wawryk
1225844c8ec3SMichal Bergerfunction waitforserial_disconnect() {
122653147e0dSMaciej Wawryk	local i=0
122753147e0dSMaciej Wawryk	while lsblk -o NAME,SERIAL | grep -q -w $1; do
122853147e0dSMaciej Wawryk		[ $i -lt 15 ] || break
122953147e0dSMaciej Wawryk		i=$((i + 1))
123053147e0dSMaciej Wawryk		echo "Waiting for disconnect devices"
123153147e0dSMaciej Wawryk		sleep 1
123253147e0dSMaciej Wawryk	done
123353147e0dSMaciej Wawryk
1234e1946cd7SMichal Berger	if lsblk -l -o NAME,SERIAL | grep -q -w $1; then
123553147e0dSMaciej Wawryk		return 1
123653147e0dSMaciej Wawryk	fi
123753147e0dSMaciej Wawryk
123853147e0dSMaciej Wawryk	return 0
123953147e0dSMaciej Wawryk}
124053147e0dSMaciej Wawryk
1241844c8ec3SMichal Bergerfunction waitforblk() {
1242e3263286SSeth Howell	local i=0
1243e3263286SSeth Howell	while ! lsblk -l -o NAME | grep -q -w $1; do
1244e3263286SSeth Howell		[ $i -lt 15 ] || break
12450f0cd0a8SKarol Latecki		i=$((i + 1))
1246e3263286SSeth Howell		sleep 1
1247e3263286SSeth Howell	done
1248e3263286SSeth Howell
1249e3263286SSeth Howell	if ! lsblk -l -o NAME | grep -q -w $1; then
1250e3263286SSeth Howell		return 1
1251e3263286SSeth Howell	fi
1252e3263286SSeth Howell
1253e3263286SSeth Howell	return 0
1254e3263286SSeth Howell}
1255e3263286SSeth Howell
1256844c8ec3SMichal Bergerfunction waitforblk_disconnect() {
12575232a73fSSeth Howell	local i=0
12585232a73fSSeth Howell	while lsblk -l -o NAME | grep -q -w $1; do
12595232a73fSSeth Howell		[ $i -lt 15 ] || break
12600f0cd0a8SKarol Latecki		i=$((i + 1))
12615232a73fSSeth Howell		sleep 1
12625232a73fSSeth Howell	done
12635232a73fSSeth Howell
12645232a73fSSeth Howell	if lsblk -l -o NAME | grep -q -w $1; then
12655232a73fSSeth Howell		return 1
12665232a73fSSeth Howell	fi
12675232a73fSSeth Howell
12685232a73fSSeth Howell	return 0
12695232a73fSSeth Howell}
12705232a73fSSeth Howell
1271844c8ec3SMichal Bergerfunction waitforfile() {
1272b118729fSJim Harris	local i=0
1273a44c7434STomasz Kulasek	while [ ! -e $1 ]; do
1274b118729fSJim Harris		[ $i -lt 200 ] || break
12750f0cd0a8SKarol Latecki		i=$((i + 1))
1276b118729fSJim Harris		sleep 0.1
1277b118729fSJim Harris	done
1278b118729fSJim Harris
1279a44c7434STomasz Kulasek	if [ ! -e $1 ]; then
1280b118729fSJim Harris		return 1
1281b118729fSJim Harris	fi
1282b118729fSJim Harris
1283b118729fSJim Harris	return 0
1284b118729fSJim Harris}
1285b118729fSJim Harris
1286844c8ec3SMichal Bergerfunction fio_config_gen() {
1287c9e5d2a6SSeth Howell	local config_file=$1
1288c9e5d2a6SSeth Howell	local workload=$2
12893fbc84d3SGangCao	local bdev_type=$3
1290872e0e46SYuriy Umanets	local env_context=$4
1291053c15b3SMichal Berger	local fio_dir=$CONFIG_FIO_SOURCE_DIR
1292c9e5d2a6SSeth Howell
1293c9e5d2a6SSeth Howell	if [ -e "$config_file" ]; then
1294c9e5d2a6SSeth Howell		echo "Configuration File Already Exists!: $config_file"
129539e8a95cSPawel Kaminski		return 1
1296c9e5d2a6SSeth Howell	fi
1297c9e5d2a6SSeth Howell
12983f52d265SMike Gerdts	if [ -z "${workload:-}" ]; then
1299c9e5d2a6SSeth Howell		workload=randrw
1300c9e5d2a6SSeth Howell	fi
1301c9e5d2a6SSeth Howell
1302872e0e46SYuriy Umanets	if [ -n "$env_context" ]; then
1303872e0e46SYuriy Umanets		env_context="env_context=$env_context"
1304872e0e46SYuriy Umanets	fi
1305872e0e46SYuriy Umanets
1306c9e5d2a6SSeth Howell	touch $1
1307c9e5d2a6SSeth Howell
1308c9e5d2a6SSeth Howell	cat > $1 << EOL
1309c9e5d2a6SSeth Howell[global]
1310c9e5d2a6SSeth Howellthread=1
1311872e0e46SYuriy Umanets$env_context
1312c9e5d2a6SSeth Howellgroup_reporting=1
1313c9e5d2a6SSeth Howelldirect=1
1314c9e5d2a6SSeth Howellnorandommap=1
1315c9e5d2a6SSeth Howellpercentile_list=50:99:99.9:99.99:99.999
1316c9e5d2a6SSeth Howelltime_based=1
1317c9e5d2a6SSeth Howellramp_time=0
1318c9e5d2a6SSeth HowellEOL
1319c9e5d2a6SSeth Howell
1320c9e5d2a6SSeth Howell	if [ "$workload" == "verify" ]; then
132102925187SMaciej Wawryk		cat <<- EOL >> $config_file
132202925187SMaciej Wawryk			verify=sha1
132302925187SMaciej Wawryk			verify_backlog=1024
132402925187SMaciej Wawryk			rw=randwrite
132502925187SMaciej Wawryk		EOL
13263fbc84d3SGangCao
13273fbc84d3SGangCao		# To avoid potential data race issue due to the AIO device
13283fbc84d3SGangCao		# flush mechanism, add the flag to serialize the writes.
13293fbc84d3SGangCao		# This is to fix the intermittent IO failure issue of #935
13303fbc84d3SGangCao		if [ "$bdev_type" == "AIO" ]; then
13313fbc84d3SGangCao			if [[ $($fio_dir/fio --version) == *"fio-3"* ]]; then
13323fbc84d3SGangCao				echo "serialize_overlap=1" >> $config_file
13333fbc84d3SGangCao			fi
13343fbc84d3SGangCao		fi
1335c9e5d2a6SSeth Howell	elif [ "$workload" == "trim" ]; then
1336c9e5d2a6SSeth Howell		echo "rw=trimwrite" >> $config_file
1337c9e5d2a6SSeth Howell	else
1338c9e5d2a6SSeth Howell		echo "rw=$workload" >> $config_file
1339c9e5d2a6SSeth Howell	fi
1340c9e5d2a6SSeth Howell}
1341c9e5d2a6SSeth Howell
134224d34ac7SKonrad Sztyberfunction fio_plugin() {
13433b9db6c4STomasz Zawadzki	# Setup fio binary cmd line
1344053c15b3SMichal Berger	local fio_dir=$CONFIG_FIO_SOURCE_DIR
134506fdd44cSKonrad Sztyber	# gcc and clang uses different sanitizer libraries
134606fdd44cSKonrad Sztyber	local sanitizers=(libasan libclang_rt.asan)
134724d34ac7SKonrad Sztyber	local plugin=$1
134824d34ac7SKonrad Sztyber	shift
13493b9db6c4STomasz Zawadzki
135006fdd44cSKonrad Sztyber	local asan_lib=
135106fdd44cSKonrad Sztyber	for sanitizer in "${sanitizers[@]}"; do
135206fdd44cSKonrad Sztyber		asan_lib=$(ldd $plugin | grep $sanitizer | awk '{print $3}')
13533f52d265SMike Gerdts		if [[ -n "${asan_lib:-}" ]]; then
135406fdd44cSKonrad Sztyber			break
135506fdd44cSKonrad Sztyber		fi
135606fdd44cSKonrad Sztyber	done
13571bed9c1fSTomasz Zawadzki
135806fdd44cSKonrad Sztyber	# Preload the sanitizer library to fio if fio_plugin was compiled with it
135924d34ac7SKonrad Sztyber	LD_PRELOAD="$asan_lib $plugin" "$fio_dir"/fio "$@"
136024d34ac7SKonrad Sztyber}
136124d34ac7SKonrad Sztyber
136224d34ac7SKonrad Sztyberfunction fio_bdev() {
136324d34ac7SKonrad Sztyber	fio_plugin "$rootdir/build/fio/spdk_bdev" "$@"
13643b9db6c4STomasz Zawadzki}
13653b9db6c4STomasz Zawadzki
1366844c8ec3SMichal Bergerfunction fio_nvme() {
136724d34ac7SKonrad Sztyber	fio_plugin "$rootdir/build/fio/spdk_nvme" "$@"
13683b9db6c4STomasz Zawadzki}
13693b9db6c4STomasz Zawadzki
1370844c8ec3SMichal Bergerfunction get_lvs_free_mb() {
1371c9e5d2a6SSeth Howell	local lvs_uuid=$1
1372074df1d8SPawel Kaminski	local lvs_info
1373074df1d8SPawel Kaminski	local fc
1374074df1d8SPawel Kaminski	local cs
1375074df1d8SPawel Kaminski	lvs_info=$($rpc_py bdev_lvol_get_lvstores)
1376074df1d8SPawel Kaminski	fc=$(jq ".[] | select(.uuid==\"$lvs_uuid\") .free_clusters" <<< "$lvs_info")
1377074df1d8SPawel Kaminski	cs=$(jq ".[] | select(.uuid==\"$lvs_uuid\") .cluster_size" <<< "$lvs_info")
1378c9e5d2a6SSeth Howell
1379c9e5d2a6SSeth Howell	# Change to MB's
1380c9e5d2a6SSeth Howell	free_mb=$((fc * cs / 1024 / 1024))
1381c9e5d2a6SSeth Howell	echo "$free_mb"
1382c9e5d2a6SSeth Howell}
1383c9e5d2a6SSeth Howell
1384844c8ec3SMichal Bergerfunction get_bdev_size() {
1385c9e5d2a6SSeth Howell	local bdev_name=$1
1386074df1d8SPawel Kaminski	local bdev_info
1387074df1d8SPawel Kaminski	local bs
1388074df1d8SPawel Kaminski	local nb
1389074df1d8SPawel Kaminski	bdev_info=$($rpc_py bdev_get_bdevs -b $bdev_name)
1390074df1d8SPawel Kaminski	bs=$(jq ".[] .block_size" <<< "$bdev_info")
1391074df1d8SPawel Kaminski	nb=$(jq ".[] .num_blocks" <<< "$bdev_info")
1392c9e5d2a6SSeth Howell
1393c9e5d2a6SSeth Howell	# Change to MB's
1394c9e5d2a6SSeth Howell	bdev_size=$((bs * nb / 1024 / 1024))
1395c9e5d2a6SSeth Howell	echo "$bdev_size"
1396c9e5d2a6SSeth Howell}
1397c9e5d2a6SSeth Howell
1398844c8ec3SMichal Bergerfunction autotest_cleanup() {
1399a57af488SMichal Berger	local autotest_es=$?
1400a57af488SMichal Berger	xtrace_disable
1401a57af488SMichal Berger
140276a2663eSMichal Berger	# Slurp at_app_exit() so we can kill all lingering vhost and qemu processes
140376a2663eSMichal Berger	# in one swing. We do this in a subshell as vhost/common.sh is too eager to
140476a2663eSMichal Berger	# do some extra work which we don't care about in this context.
140576a2663eSMichal Berger	# shellcheck source=/dev/null
14068ad5671fSMichal Berger	vhost_reap() (source "$rootdir/test/vhost/common.sh" &> /dev/null || return 0 && at_app_exit)
140776a2663eSMichal Berger
1408a57af488SMichal Berger	# catch any stray core files and kill all remaining SPDK processes. Update
1409a57af488SMichal Berger	# autotest_es in case autotest reported success but cores and/or processes
1410a57af488SMichal Berger	# were left behind regardless.
1411a57af488SMichal Berger
1412a57af488SMichal Berger	process_core || autotest_es=1
1413a57af488SMichal Berger	reap_spdk_processes || autotest_es=1
141476a2663eSMichal Berger	vhost_reap || autotest_es=1
1415a57af488SMichal Berger
1416d1f9da82SSeth Howell	$rootdir/scripts/setup.sh reset
1417af32aa1bSKarol Latecki	$rootdir/scripts/setup.sh cleanup
1418d63d4d5aSSeth Howell	if [ $(uname -s) = "Linux" ]; then
1419d63d4d5aSSeth Howell		modprobe -r uio_pci_generic
1420d63d4d5aSSeth Howell	fi
14219fda9814STomasz Zawadzki	rm -rf "$asan_suppression_file"
14223f52d265SMike Gerdts	if [[ -n ${old_core_pattern:-} ]]; then
142316589c82SMichal Berger		echo "$old_core_pattern" > /proc/sys/kernel/core_pattern
142416589c82SMichal Berger	fi
142523040b8bSMichal Berger	if [[ -e /proc/$udevadm_pid/status ]]; then
142623040b8bSMichal Berger		kill "$udevadm_pid" || :
142723040b8bSMichal Berger	fi
1428570c8bb4SMichal Berger
1429570c8bb4SMichal Berger	local storage_fallback_purge=("${TMPDIR:-/tmp}/spdk."??????)
1430570c8bb4SMichal Berger
1431570c8bb4SMichal Berger	if ((${#storage_fallback_purge[@]} > 0)); then
1432570c8bb4SMichal Berger		rm -rf "${storage_fallback_purge[@]}"
1433570c8bb4SMichal Berger	fi
1434a57af488SMichal Berger
14357d4f7b7fSMichal Berger	if ((autotest_es)); then
14367d4f7b7fSMichal Berger		if [[ $(uname) == FreeBSD ]]; then
14377d4f7b7fSMichal Berger			ps aux
14387d4f7b7fSMichal Berger		elif [[ $(uname) == Linux ]]; then
14397d4f7b7fSMichal Berger			# Get more detailed view
14407d4f7b7fSMichal Berger			grep . /proc/[0-9]*/status
14417d4f7b7fSMichal Berger			# Dump some extra info into kernel log
14427d4f7b7fSMichal Berger			echo "######## Autotest Cleanup Dump ########" > /dev/kmsg
14437d4f7b7fSMichal Berger			# Show cpus backtraces
14447d4f7b7fSMichal Berger			echo l > /proc/sysrq-trigger
14457d4f7b7fSMichal Berger			# Show mem usage
14467d4f7b7fSMichal Berger			echo m > /proc/sysrq-trigger
14477d4f7b7fSMichal Berger			# show task states
14487d4f7b7fSMichal Berger			echo t > /proc/sysrq-trigger
14497d4f7b7fSMichal Berger			# show blocked tasks
14507d4f7b7fSMichal Berger			echo w > /proc/sysrq-trigger
14517d4f7b7fSMichal Berger
14527d4f7b7fSMichal Berger		fi > "$output_dir/proc_list.txt" 2>&1 || :
14537d4f7b7fSMichal Berger	fi
14543d834218SMichal Berger
1455d5fe62b2SMichal Berger	stop_monitor_resources
14563d834218SMichal Berger
1457a57af488SMichal Berger	xtrace_restore
1458a57af488SMichal Berger	return $autotest_es
1459d1f9da82SSeth Howell}
1460d1f9da82SSeth Howell
1461844c8ec3SMichal Bergerfunction freebsd_update_contigmem_mod() {
1462fb9c4ee6SKarol Latecki	if [ $(uname) = FreeBSD ]; then
146386ee572bSSeth Howell		kldunload contigmem.ko || true
14643f52d265SMike Gerdts		if [ -n "${SPDK_RUN_EXTERNAL_DPDK:-}" ]; then
146549473bdcSDarek Stojaczyk			cp -f "$SPDK_RUN_EXTERNAL_DPDK/kmod/contigmem.ko" /boot/modules/
146649473bdcSDarek Stojaczyk			cp -f "$SPDK_RUN_EXTERNAL_DPDK/kmod/contigmem.ko" /boot/kernel/
146749473bdcSDarek Stojaczyk			cp -f "$SPDK_RUN_EXTERNAL_DPDK/kmod/nic_uio.ko" /boot/modules/
146849473bdcSDarek Stojaczyk			cp -f "$SPDK_RUN_EXTERNAL_DPDK/kmod/nic_uio.ko" /boot/kernel/
1469d68ee5b4SDarek Stojaczyk		else
1470d68ee5b4SDarek Stojaczyk			cp -f "$rootdir/dpdk/build/kmod/contigmem.ko" /boot/modules/
1471d68ee5b4SDarek Stojaczyk			cp -f "$rootdir/dpdk/build/kmod/contigmem.ko" /boot/kernel/
14727cf4602dSPawel Kaminski			cp -f "$rootdir/dpdk/build/kmod/nic_uio.ko" /boot/modules/
14737cf4602dSPawel Kaminski			cp -f "$rootdir/dpdk/build/kmod/nic_uio.ko" /boot/kernel/
1474d68ee5b4SDarek Stojaczyk		fi
147586ee572bSSeth Howell	fi
147686ee572bSSeth Howell}
147786ee572bSSeth Howell
1478a7d3e106SKarol Lateckifunction freebsd_set_maxsock_buf() {
1479a7d3e106SKarol Latecki	# FreeBSD needs 4MB maxsockbuf size to pass socket unit tests.
1480a7d3e106SKarol Latecki	# Otherwise tests fail due to ENOBUFS when trying to do setsockopt(SO_RCVBUF|SO_SNDBUF).
1481a7d3e106SKarol Latecki	# See https://github.com/spdk/spdk/issues/2943
1482a7d3e106SKarol Latecki	if [[ $(uname) = FreeBSD ]] && (($(sysctl -n kern.ipc.maxsockbuf) < 4194304)); then
1483a7d3e106SKarol Latecki		sysctl kern.ipc.maxsockbuf=4194304
1484a7d3e106SKarol Latecki	fi
1485a7d3e106SKarol Latecki}
1486a7d3e106SKarol Latecki
1487844c8ec3SMichal Bergerfunction get_nvme_name_from_bdf() {
1488cb7af50cSMichal Berger	get_block_dev_from_nvme "$@"
148928f4299fSMarcin Dziegielewski}
149028f4299fSMarcin Dziegielewski
1491256f554dSTomasz Zawadzkifunction get_nvme_ctrlr_from_bdf() {
1492256f554dSTomasz Zawadzki	bdf_sysfs_path=$(readlink -f /sys/class/nvme/nvme* | grep "$1/nvme/nvme")
14933f52d265SMike Gerdts	if [[ -z "${bdf_sysfs_path:-}" ]]; then
1494256f554dSTomasz Zawadzki		return
1495256f554dSTomasz Zawadzki	fi
1496256f554dSTomasz Zawadzki
1497256f554dSTomasz Zawadzki	printf '%s\n' "$(basename $bdf_sysfs_path)"
1498256f554dSTomasz Zawadzki}
1499256f554dSTomasz Zawadzki
1500db43b387SKarol Latecki# Get BDF addresses of all NVMe drives currently attached to
1501db43b387SKarol Latecki# uio-pci-generic or vfio-pci
1502db43b387SKarol Lateckifunction get_nvme_bdfs() {
15034641aa53SMichal Berger	local bdfs=()
15044641aa53SMichal Berger	bdfs=($("$rootdir/scripts/gen_nvme.sh" | jq -r '.config[].params.traddr'))
15054641aa53SMichal Berger	if ((${#bdfs[@]} == 0)); then
15064641aa53SMichal Berger		echo "No bdevs found" >&2
15074641aa53SMichal Berger		return 1
15086b19775bSTomasz Zawadzki	fi
15094641aa53SMichal Berger	printf '%s\n' "${bdfs[@]}"
1510db43b387SKarol Latecki}
1511db43b387SKarol Latecki
1512db43b387SKarol Latecki# Same as function above, but just get the first disks BDF address
1513db43b387SKarol Lateckifunction get_first_nvme_bdf() {
15144641aa53SMichal Berger	local bdfs=()
15154641aa53SMichal Berger	bdfs=($(get_nvme_bdfs))
15164641aa53SMichal Berger
15174641aa53SMichal Berger	echo "${bdfs[0]}"
1518db43b387SKarol Latecki}
1519db43b387SKarol Latecki
15204c21ef36STomasz Zawadzkifunction nvme_namespace_revert() {
15214c21ef36STomasz Zawadzki	$rootdir/scripts/setup.sh
15224c21ef36STomasz Zawadzki	sleep 1
15234641aa53SMichal Berger	local bdfs=()
15244641aa53SMichal Berger	bdfs=($(get_nvme_bdfs))
15254c21ef36STomasz Zawadzki
15264c21ef36STomasz Zawadzki	$rootdir/scripts/setup.sh reset
15274c21ef36STomasz Zawadzki
15284641aa53SMichal Berger	for bdf in "${bdfs[@]}"; do
15294c21ef36STomasz Zawadzki		nvme_ctrlr=/dev/$(get_nvme_ctrlr_from_bdf ${bdf})
15303f52d265SMike Gerdts		if [[ -z "${nvme_ctrlr:-}" ]]; then
15314c21ef36STomasz Zawadzki			continue
15324c21ef36STomasz Zawadzki		fi
15334c21ef36STomasz Zawadzki
15344c21ef36STomasz Zawadzki		# Check Optional Admin Command Support for Namespace Management
15354c21ef36STomasz Zawadzki		oacs=$(nvme id-ctrl ${nvme_ctrlr} | grep oacs | cut -d: -f2)
15364c21ef36STomasz Zawadzki		oacs_ns_manage=$((oacs & 0x8))
15374c21ef36STomasz Zawadzki
15384c21ef36STomasz Zawadzki		if [[ "$oacs_ns_manage" -ne 0 ]]; then
15394c21ef36STomasz Zawadzki			# This assumes every NVMe controller contains single namespace,
15408e8864f2SKarol Latecki			# encompassing Total NVM Capacity and formatted as 512 block size.
15418e8864f2SKarol Latecki			# 512 block size is needed for test/vhost/vhost_boot.sh to
1542c9c7c281SJosh Soref			# successfully run.
15434c21ef36STomasz Zawadzki
15444c21ef36STomasz Zawadzki			unvmcap=$(nvme id-ctrl ${nvme_ctrlr} | grep unvmcap | cut -d: -f2)
15454c21ef36STomasz Zawadzki			if [[ "$unvmcap" -eq 0 ]]; then
15464c21ef36STomasz Zawadzki				# All available space already used
15474c21ef36STomasz Zawadzki				continue
15484c21ef36STomasz Zawadzki			fi
15494c21ef36STomasz Zawadzki			tnvmcap=$(nvme id-ctrl ${nvme_ctrlr} | grep tnvmcap | cut -d: -f2)
155066a35235SMichal Berger			cntlid=$(nvme id-ctrl ${nvme_ctrlr} | grep cntlid | cut -d: -f2)
15518e8864f2SKarol Latecki			blksize=512
15524c21ef36STomasz Zawadzki
15534c21ef36STomasz Zawadzki			size=$((tnvmcap / blksize))
15544c21ef36STomasz Zawadzki
155566a35235SMichal Berger			nvme detach-ns ${nvme_ctrlr} -n 0xffffffff -c $cntlid || true
15564c21ef36STomasz Zawadzki			nvme delete-ns ${nvme_ctrlr} -n 0xffffffff || true
15574c21ef36STomasz Zawadzki			nvme create-ns ${nvme_ctrlr} -s ${size} -c ${size} -b ${blksize}
155866a35235SMichal Berger			nvme attach-ns ${nvme_ctrlr} -n 1 -c $cntlid
15594c21ef36STomasz Zawadzki			nvme reset ${nvme_ctrlr}
1560f803df51SKarol Latecki			waitforfile "${nvme_ctrlr}n1"
15614c21ef36STomasz Zawadzki		fi
15624c21ef36STomasz Zawadzki	done
15634c21ef36STomasz Zawadzki}
15644c21ef36STomasz Zawadzki
1565919fdeceSChangpeng Liu# Get BDFs based on device ID, such as 0x0a54
1566919fdeceSChangpeng Liufunction get_nvme_bdfs_by_id() {
1567919fdeceSChangpeng Liu	local bdfs=()
1568919fdeceSChangpeng Liu
1569919fdeceSChangpeng Liu	for bdf in $(get_nvme_bdfs); do
1570919fdeceSChangpeng Liu		device=$(cat /sys/bus/pci/devices/$bdf/device) || true
1571919fdeceSChangpeng Liu		if [[ "$device" == "$1" ]]; then
1572919fdeceSChangpeng Liu			bdfs+=($bdf)
1573919fdeceSChangpeng Liu		fi
1574919fdeceSChangpeng Liu	done
1575919fdeceSChangpeng Liu
1576919fdeceSChangpeng Liu	printf '%s\n' "${bdfs[@]}"
1577919fdeceSChangpeng Liu}
1578919fdeceSChangpeng Liu
1579919fdeceSChangpeng Liufunction opal_revert_cleanup() {
1580919fdeceSChangpeng Liu	# The OPAL CI tests is only used for P4510 devices.
1581919fdeceSChangpeng Liu	mapfile -t bdfs < <(get_nvme_bdfs_by_id 0x0a54)
15823f52d265SMike Gerdts	if [[ -z ${bdfs[0]:-} ]]; then
1583919fdeceSChangpeng Liu		return 0
1584919fdeceSChangpeng Liu	fi
1585919fdeceSChangpeng Liu
1586919fdeceSChangpeng Liu	$SPDK_BIN_DIR/spdk_tgt &
1587919fdeceSChangpeng Liu	spdk_tgt_pid=$!
1588919fdeceSChangpeng Liu	waitforlisten $spdk_tgt_pid
1589919fdeceSChangpeng Liu
15905e65adccSwanghailiangx	bdf_id=0
1591919fdeceSChangpeng Liu	for bdf in "${bdfs[@]}"; do
15925e65adccSwanghailiangx		$rootdir/scripts/rpc.py bdev_nvme_attach_controller -b "nvme"${bdf_id} -t "pcie" -a ${bdf}
1593919fdeceSChangpeng Liu		# Ignore if this fails.
15945e65adccSwanghailiangx		$rootdir/scripts/rpc.py bdev_nvme_opal_revert -b "nvme"${bdf_id} -p test || true
15955e65adccSwanghailiangx		((++bdf_id))
1596919fdeceSChangpeng Liu	done
1597919fdeceSChangpeng Liu
1598919fdeceSChangpeng Liu	killprocess $spdk_tgt_pid
1599919fdeceSChangpeng Liu}
1600919fdeceSChangpeng Liu
1601f574014aSMichal Bergerfunction pap() {
1602f574014aSMichal Berger	while read -r file; do
1603f574014aSMichal Berger		cat <<- FILE
1604f574014aSMichal Berger			--- $file ---
1605f574014aSMichal Berger			$(< "$file")
1606f574014aSMichal Berger			--- $file ---
1607f574014aSMichal Berger		FILE
1608f574014aSMichal Berger		rm -f "$file"
1609f574014aSMichal Berger	done < <(find "$@" -type f | sort -u)
1610f574014aSMichal Berger}
1611f574014aSMichal Berger
1612a57af488SMichal Bergerfunction get_proc_paths() {
161315e31017SMichal Berger	case "$(uname -s)" in
161415e31017SMichal Berger		Linux) # ps -e -opid,exe <- not supported under {centos7,rocky8}'s procps-ng
16156693862fSMichal Berger			local pid exe
161615e31017SMichal Berger			for pid in /proc/[0-9]*; do
16176693862fSMichal Berger				exe=$(readlink "$pid/exe") || continue
16186693862fSMichal Berger				exe=${exe/ (deleted)/}
16196693862fSMichal Berger				echo "${pid##*/} $exe"
1620a57af488SMichal Berger			done
162115e31017SMichal Berger			;;
162215e31017SMichal Berger		FreeeBSD) procstat -ab | awk '{print $1, $4}' ;;
162315e31017SMichal Berger	esac
1624a57af488SMichal Berger}
1625a57af488SMichal Berger
162615e31017SMichal Bergerexec_files() { file "$@" | awk -F: '/ELF.+executable/{print $1}'; }
1627a57af488SMichal Berger
1628a57af488SMichal Bergerfunction reap_spdk_processes() {
162915e31017SMichal Berger	local bins test_bins procs
163015e31017SMichal Berger	local spdk_procs spdk_pids
1631a57af488SMichal Berger
163215e31017SMichal Berger	mapfile -t test_bins < <(find "$rootdir"/test/{app,env,event} -type f)
163315e31017SMichal Berger	mapfile -t bins < <(
163415e31017SMichal Berger		exec_files "${test_bins[@]}"
163515e31017SMichal Berger		readlink -f "$SPDK_BIN_DIR/"* "$SPDK_EXAMPLE_DIR/"*
163615e31017SMichal Berger	)
1637*47d1bc80SJim Harris	((${#bins[@]} > 0)) || return 0
1638a57af488SMichal Berger
163915e31017SMichal Berger	mapfile -t spdk_procs < <(get_proc_paths | grep -E "$(
164015e31017SMichal Berger		IFS="|"
164115e31017SMichal Berger		echo "${bins[*]#$rootdir/}"
164215e31017SMichal Berger	)" || true)
164315e31017SMichal Berger	((${#spdk_procs[@]} > 0)) || return 0
1644a57af488SMichal Berger
164515e31017SMichal Berger	printf '%s is still up, killing\n' "${spdk_procs[@]}" >&2
164615e31017SMichal Berger	mapfile -t spdk_pids < <(printf '%s\n' "${spdk_procs[@]}" | awk '{print $1}')
1647a57af488SMichal Berger
164815e31017SMichal Berger	kill -SIGKILL "${spdk_pids[@]}" 2> /dev/null || :
1649a57af488SMichal Berger	return 1
1650a57af488SMichal Berger}
1651a57af488SMichal Berger
16520231fdc7SMichal Bergerfunction is_block_zoned() {
16530231fdc7SMichal Berger	local device=$1
16540231fdc7SMichal Berger
16550231fdc7SMichal Berger	[[ -e /sys/block/$device/queue/zoned ]] || return 1
16560231fdc7SMichal Berger	[[ $(< "/sys/block/$device/queue/zoned") != none ]]
16570231fdc7SMichal Berger}
16580231fdc7SMichal Berger
16590231fdc7SMichal Bergerfunction get_zoned_devs() {
16600231fdc7SMichal Berger	local -gA zoned_devs=()
16610231fdc7SMichal Berger	local nvme bdf
16620231fdc7SMichal Berger
16630231fdc7SMichal Berger	for nvme in /sys/block/nvme*; do
16640231fdc7SMichal Berger		if is_block_zoned "${nvme##*/}"; then
16650231fdc7SMichal Berger			zoned_devs["${nvme##*/}"]=$(< "$nvme/device/address")
16660231fdc7SMichal Berger		fi
16670231fdc7SMichal Berger	done
16680231fdc7SMichal Berger}
16690231fdc7SMichal Berger
16701430096aSMichal Berger# Define temp storage for all the tests. Look for 2GB at minimum
16711430096aSMichal Bergerset_test_storage "${TEST_MIN_STORAGE_SIZE:-$((1 << 31))}"
16721430096aSMichal Berger
1673c9e5d2a6SSeth Howellset -o errtrace
1674a8d01691SMichal Bergershopt -s extdebug
1675c9e5d2a6SSeth Howelltrap "trap - ERR; print_backtrace >&2" ERR
16767612ac47SDarek Stojaczyk
1677b18e53d4SMichal BergerPS4=' \t ${test_domain:-} -- ${BASH_SOURCE#${BASH_SOURCE%/*/*}/}@${LINENO} -- \$ '
16787612ac47SDarek Stojaczykif $SPDK_AUTOTEST_X; then
167939fe5c84SSeth Howell	# explicitly enable xtraces, overriding any tracking information.
1680c2feee4fSMichal Berger	xtrace_fd
16817612ac47SDarek Stojaczykelse
168213479ef5SMichal Berger	xtrace_disable
16837612ac47SDarek Stojaczykfi
1684