2007-07-20 07:43:49 -05:00
|
|
|
#
|
|
|
|
# Copyright (C) 2007 Karel Zak <kzak@redhat.com>
|
|
|
|
#
|
2010-11-30 04:41:59 -06:00
|
|
|
# This file is part of util-linux.
|
2007-07-20 07:43:49 -05:00
|
|
|
#
|
|
|
|
# This file is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This file is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
2007-01-04 07:23:48 -06:00
|
|
|
|
|
|
|
|
2009-01-19 15:36:27 -06:00
|
|
|
function ts_abspath {
|
|
|
|
cd $1
|
|
|
|
pwd
|
|
|
|
}
|
2009-01-19 11:08:06 -06:00
|
|
|
|
2012-07-30 10:10:38 -05:00
|
|
|
function ts_canonicalize {
|
|
|
|
P="$1"
|
|
|
|
C=$(readlink -f $P)
|
|
|
|
|
|
|
|
if [ -n "$C" ]; then
|
|
|
|
echo "$C"
|
|
|
|
else
|
|
|
|
echo "$P"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2014-06-22 04:20:54 -05:00
|
|
|
function ts_cd {
|
|
|
|
if [ $# -eq 0 ]; then
|
|
|
|
ts_failed "ul_cd: not enough arguments"
|
|
|
|
fi
|
|
|
|
DEST=$(readlink -f "$1" 2>/dev/null)
|
|
|
|
if [ "x$DEST" = "x" ] || [ ! -d "$DEST" ]; then
|
|
|
|
ts_failed "ul_cd: $1: no such directory"
|
|
|
|
fi
|
|
|
|
cd "$DEST" 2>/dev/null || ts_failed "ul_cd: $1: cannot change directory"
|
|
|
|
if [ "$PWD" != "$DEST" ]; then
|
|
|
|
ts_failed "ul_cd: $PWD is not $DEST"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-02-15 05:48:06 -06:00
|
|
|
function ts_separator {
|
|
|
|
local header="$1"
|
|
|
|
echo >> $TS_OUTPUT
|
|
|
|
if [ -z "$header" ]; then
|
|
|
|
echo "============================================" >> $TS_OUTPUT
|
|
|
|
else
|
|
|
|
echo "=====$header================================" >> $TS_OUTPUT
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2014-02-16 17:54:15 -06:00
|
|
|
function ts_report {
|
2015-12-17 03:46:32 -06:00
|
|
|
local desc=
|
|
|
|
|
2016-03-05 08:40:57 -06:00
|
|
|
if [ "$TS_PARSABLE" != "yes" ]; then
|
2015-12-17 03:46:32 -06:00
|
|
|
if [ $TS_NSUBTESTS -ne 0 ] && [ -z "$TS_SUBNAME" ]; then
|
|
|
|
desc=$(printf "%11s...")
|
|
|
|
fi
|
|
|
|
echo "$desc$1"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$TS_SUBNAME" ]; then
|
|
|
|
desc=$(printf "%s: [%02d] %s" "$TS_DESC" "$TS_NSUBTESTS" "$TS_SUBNAME")
|
2014-02-16 17:54:15 -06:00
|
|
|
else
|
2015-12-17 03:46:32 -06:00
|
|
|
desc=$TS_DESC
|
2014-02-16 17:54:15 -06:00
|
|
|
fi
|
2015-12-17 03:46:32 -06:00
|
|
|
printf "%13s: %-45s ...%s\n" "$TS_COMPONENT" "$desc" "$1"
|
2014-02-16 09:22:56 -06:00
|
|
|
}
|
2014-02-16 17:54:15 -06:00
|
|
|
|
2014-02-16 09:22:56 -06:00
|
|
|
function ts_check_test_command {
|
2019-03-04 10:10:04 -06:00
|
|
|
case "$1" in
|
|
|
|
*/*)
|
|
|
|
# paths
|
|
|
|
if [ ! -x "$1" ]; then
|
|
|
|
ts_skip "${1##*/} not found"
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
# just command names (e.g. --use-system-commands)
|
|
|
|
local cmd=$1
|
2019-03-05 04:06:41 -06:00
|
|
|
type "$cmd" >/dev/null 2>&1
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
if [ "$TS_NOSKIP_COMMANDS" = "yes" ]; then
|
|
|
|
ts_failed "missing in PATH: $cmd"
|
|
|
|
fi
|
|
|
|
ts_skip "missing in PATH: $cmd"
|
|
|
|
fi
|
2019-03-04 10:10:04 -06:00
|
|
|
;;
|
|
|
|
esac
|
2014-02-16 17:54:15 -06:00
|
|
|
}
|
|
|
|
|
2014-05-14 16:53:52 -05:00
|
|
|
function ts_check_prog {
|
|
|
|
local cmd=$1
|
|
|
|
type "$cmd" >/dev/null 2>&1 || ts_skip "missing in PATH: $cmd"
|
|
|
|
}
|
|
|
|
|
2014-05-11 19:45:10 -05:00
|
|
|
function ts_check_losetup {
|
|
|
|
local tmp
|
|
|
|
ts_check_test_command "$TS_CMD_LOSETUP"
|
|
|
|
|
2015-03-17 05:34:22 -05:00
|
|
|
if [ "$TS_SKIP_LOOPDEVS" = "yes" ]; then
|
2015-03-16 06:22:53 -05:00
|
|
|
ts_skip "loop-device tests disabled"
|
|
|
|
fi
|
|
|
|
|
2014-05-11 19:45:10 -05:00
|
|
|
# assuming that losetup -f works ... to be checked somewhere else
|
|
|
|
tmp=$($TS_CMD_LOSETUP -f 2>/dev/null)
|
|
|
|
if test -b "$tmp"; then
|
|
|
|
return 0
|
|
|
|
fi
|
2015-02-17 14:45:46 -06:00
|
|
|
ts_skip "no loop-device support"
|
2014-05-11 19:45:10 -05:00
|
|
|
}
|
|
|
|
|
2016-07-11 04:01:14 -05:00
|
|
|
function ts_report_skip {
|
2015-02-17 14:45:46 -06:00
|
|
|
ts_report " SKIPPED ($1)"
|
2009-01-20 08:38:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
function ts_skip {
|
2016-07-11 04:01:14 -05:00
|
|
|
ts_report_skip "$1"
|
2015-03-31 07:19:40 -05:00
|
|
|
|
2015-03-31 03:54:56 -05:00
|
|
|
ts_cleanup_on_exit
|
2007-01-02 18:07:55 -06:00
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
2007-05-15 17:41:14 -05:00
|
|
|
function ts_skip_nonroot {
|
2008-11-06 09:46:22 -06:00
|
|
|
if [ $UID -ne 0 ]; then
|
2015-02-17 14:45:46 -06:00
|
|
|
ts_skip "no root permissions"
|
2007-05-15 17:41:14 -05:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
function ts_failed_subtest {
|
2014-05-12 15:56:57 -05:00
|
|
|
local msg="FAILED"
|
|
|
|
local ret=1
|
|
|
|
if [ "$TS_KNOWN_FAIL" = "yes" ]; then
|
|
|
|
msg="KNOWN FAILED"
|
|
|
|
ret=0
|
|
|
|
fi
|
|
|
|
|
2007-03-19 17:27:40 -05:00
|
|
|
if [ x"$1" == x"" ]; then
|
2014-05-12 15:56:57 -05:00
|
|
|
ts_report " $msg ($TS_NS)"
|
2007-03-19 17:27:40 -05:00
|
|
|
else
|
2014-05-12 15:56:57 -05:00
|
|
|
ts_report " $msg ($1)"
|
2007-03-19 17:27:40 -05:00
|
|
|
fi
|
2014-05-12 15:56:57 -05:00
|
|
|
|
|
|
|
return $ret
|
2007-03-19 17:27:40 -05:00
|
|
|
}
|
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
function ts_failed {
|
|
|
|
ts_failed_subtest "$1"
|
2014-05-12 15:56:57 -05:00
|
|
|
exit $?
|
2014-05-09 20:57:26 -05:00
|
|
|
}
|
|
|
|
|
2016-07-11 04:01:14 -05:00
|
|
|
function ts_report_ok {
|
2007-03-19 17:27:40 -05:00
|
|
|
if [ x"$1" == x"" ]; then
|
2014-02-16 17:54:15 -06:00
|
|
|
ts_report " OK"
|
2007-03-19 17:27:40 -05:00
|
|
|
else
|
2014-02-16 17:54:15 -06:00
|
|
|
ts_report " OK ($1)"
|
2007-03-19 17:27:40 -05:00
|
|
|
fi
|
2009-01-20 08:38:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
function ts_ok {
|
2016-07-11 04:01:14 -05:00
|
|
|
ts_report_ok "$1"
|
2007-03-19 17:27:40 -05:00
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
2007-05-18 08:34:28 -05:00
|
|
|
function ts_log {
|
|
|
|
echo "$1" >> $TS_OUTPUT
|
|
|
|
[ "$TS_VERBOSE" == "yes" ] && echo "$1"
|
|
|
|
}
|
|
|
|
|
2019-08-30 08:50:07 -05:00
|
|
|
function ts_logerr {
|
|
|
|
echo "$1" >> $TS_ERRLOG
|
|
|
|
[ "$TS_VERBOSE" == "yes" ] && echo "$1"
|
|
|
|
}
|
|
|
|
|
|
|
|
function ts_log_both {
|
|
|
|
echo "$1" >> $TS_OUTPUT
|
|
|
|
echo "$1" >> $TS_ERRLOG
|
|
|
|
[ "$TS_VERBOSE" == "yes" ] && echo "$1"
|
|
|
|
}
|
|
|
|
|
2007-06-11 07:45:32 -05:00
|
|
|
function ts_has_option {
|
|
|
|
NAME="$1"
|
|
|
|
ALL="$2"
|
2014-05-09 19:00:53 -05:00
|
|
|
|
|
|
|
# user may set options by env for a single test or whole component
|
|
|
|
# e.g. TS_OPT_ipcs_limits2_fake="yes" or TS_OPT_ipcs_fake="yes"
|
2014-05-10 00:04:11 -05:00
|
|
|
local v_test=${TS_TESTNAME//[-.]/_}
|
|
|
|
local v_comp=${TS_COMPONENT//[-.]/_}
|
|
|
|
local v_name=${NAME//[-.]/_}
|
|
|
|
eval local env_opt_test=\$TS_OPT_${v_comp}_${v_test}_${v_name}
|
|
|
|
eval local env_opt_comp=\$TS_OPT_${v_comp}_${v_name}
|
2014-05-09 19:00:53 -05:00
|
|
|
if [ "$env_opt_test" = "yes" \
|
|
|
|
-o "$env_opt_comp" = "yes" -a "$env_opt_test" != "no" ]; then
|
|
|
|
echo "yes"
|
|
|
|
return
|
|
|
|
elif [ "$env_opt_test" = "no" \
|
|
|
|
-o "$env_opt_comp" = "no" -a "$env_opt_test" != "yes" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
# or just check the global command line options
|
2016-03-05 08:40:57 -06:00
|
|
|
if [[ $ALL =~ ([$' \t\n']|^)--$NAME([$'= \t\n']|$) ]]; then
|
|
|
|
echo yes
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
# or the _global_ env, e.g TS_OPT_parsable="yes"
|
|
|
|
eval local env_opt=\$TS_OPT_${v_name}
|
|
|
|
if [ "$env_opt" = "yes" ]; then echo "yes"; fi
|
2007-06-11 07:45:32 -05:00
|
|
|
}
|
|
|
|
|
2012-08-03 14:24:51 -05:00
|
|
|
function ts_option_argument {
|
|
|
|
NAME="$1"
|
|
|
|
ALL="$2"
|
2016-02-17 08:01:21 -06:00
|
|
|
|
|
|
|
# last option wins!
|
|
|
|
echo "$ALL" | sed -n "s/.*[ \t\n]--$NAME=\([^ \t\n]*\).*/\1/p" | tail -n 1
|
2012-08-03 14:24:51 -05:00
|
|
|
}
|
|
|
|
|
2010-10-20 05:40:02 -05:00
|
|
|
function ts_init_core_env {
|
2015-12-17 03:46:32 -06:00
|
|
|
TS_SUBNAME=""
|
2010-10-20 05:40:02 -05:00
|
|
|
TS_NS="$TS_COMPONENT/$TS_TESTNAME"
|
|
|
|
TS_OUTPUT="$TS_OUTDIR/$TS_TESTNAME"
|
2019-08-30 08:50:07 -05:00
|
|
|
TS_ERRLOG="$TS_OUTDIR/$TS_TESTNAME.err"
|
2012-01-26 06:51:38 -06:00
|
|
|
TS_VGDUMP="$TS_OUTDIR/$TS_TESTNAME.vgdump"
|
2020-06-27 21:15:23 -05:00
|
|
|
TS_EXIT_CODE="$TS_OUTDIR/$TS_TESTNAME.exit_code"
|
2010-10-20 05:40:02 -05:00
|
|
|
TS_DIFF="$TS_DIFFDIR/$TS_TESTNAME"
|
|
|
|
TS_EXPECTED="$TS_TOPDIR/expected/$TS_NS"
|
2019-08-30 08:50:07 -05:00
|
|
|
TS_EXPECTED_ERR="$TS_TOPDIR/expected/$TS_NS.err"
|
2010-10-20 05:40:02 -05:00
|
|
|
TS_MOUNTPOINT="$TS_OUTDIR/${TS_TESTNAME}-mnt"
|
|
|
|
}
|
|
|
|
|
|
|
|
function ts_init_core_subtest_env {
|
|
|
|
TS_NS="$TS_COMPONENT/$TS_TESTNAME-$TS_SUBNAME"
|
|
|
|
TS_OUTPUT="$TS_OUTDIR/$TS_TESTNAME-$TS_SUBNAME"
|
2019-08-30 08:50:07 -05:00
|
|
|
TS_ERRLOG="$TS_OUTDIR/$TS_TESTNAME-$TS_SUBNAME.err"
|
2012-01-26 06:51:38 -06:00
|
|
|
TS_VGDUMP="$TS_OUTDIR/$TS_TESTNAME-$TS_SUBNAME.vgdump"
|
2020-06-27 21:15:23 -05:00
|
|
|
TS_EXIT_CODE="$TS_OUTDIR/$TS_TESTNAME-$TS_SUBNAME.exit_code"
|
2010-10-20 05:40:02 -05:00
|
|
|
TS_DIFF="$TS_DIFFDIR/$TS_TESTNAME-$TS_SUBNAME"
|
|
|
|
TS_EXPECTED="$TS_TOPDIR/expected/$TS_NS"
|
2019-08-30 08:50:07 -05:00
|
|
|
TS_EXPECTED_ERR="$TS_TOPDIR/expected/$TS_NS.err"
|
2010-11-23 06:06:46 -06:00
|
|
|
TS_MOUNTPOINT="$TS_OUTDIR/${TS_TESTNAME}-${TS_SUBNAME}-mnt"
|
2012-01-26 06:51:38 -06:00
|
|
|
|
2020-06-27 21:15:23 -05:00
|
|
|
rm -f $TS_OUTPUT $TS_ERRLOG $TS_VGDUMP $TS_EXIT_CODE
|
2012-02-28 07:37:45 -06:00
|
|
|
[ -d "$TS_OUTDIR" ] || mkdir -p "$TS_OUTDIR"
|
|
|
|
|
2020-06-27 21:15:23 -05:00
|
|
|
touch $TS_OUTPUT $TS_ERRLOG $TS_EXIT_CODE
|
2012-01-26 06:51:38 -06:00
|
|
|
[ -n "$TS_VALGRIND_CMD" ] && touch $TS_VGDUMP
|
2010-10-20 05:40:02 -05:00
|
|
|
}
|
|
|
|
|
2009-01-20 06:19:43 -06:00
|
|
|
function ts_init_env {
|
2014-02-16 17:54:14 -06:00
|
|
|
local mydir=$(ts_abspath ${0%/*})
|
2014-05-09 21:51:22 -05:00
|
|
|
local tmp
|
2009-01-19 11:08:06 -06:00
|
|
|
|
2010-03-31 09:48:39 -05:00
|
|
|
LANG="POSIX"
|
|
|
|
LANGUAGE="POSIX"
|
|
|
|
LC_ALL="POSIX"
|
|
|
|
CHARSET="UTF-8"
|
2017-11-23 07:59:05 -06:00
|
|
|
ASAN_OPTIONS="detect_leaks=0"
|
2020-07-01 14:52:51 -05:00
|
|
|
UBSAN_OPTIONS="print_stacktrace=1:print_summary=1:halt_on_error=1"
|
2010-03-31 09:48:39 -05:00
|
|
|
|
2020-07-01 14:52:51 -05:00
|
|
|
export LANG LANGUAGE LC_ALL CHARSET ASAN_OPTIONS UBSAN_OPTIONS
|
2012-08-03 14:24:51 -05:00
|
|
|
|
2012-07-30 10:10:38 -05:00
|
|
|
mydir=$(ts_canonicalize "$mydir")
|
|
|
|
|
2012-08-03 14:24:51 -05:00
|
|
|
# automake directories
|
|
|
|
top_srcdir=$(ts_option_argument "srcdir" "$*")
|
|
|
|
top_builddir=$(ts_option_argument "builddir" "$*")
|
2009-01-19 11:08:06 -06:00
|
|
|
|
2012-08-03 14:24:51 -05:00
|
|
|
# where is this script
|
2009-01-19 15:36:27 -06:00
|
|
|
TS_TOPDIR=$(ts_abspath $mydir/../../)
|
2012-08-03 14:24:51 -05:00
|
|
|
|
|
|
|
# default
|
|
|
|
if [ -z "$top_srcdir" ]; then
|
|
|
|
top_srcdir="$TS_TOPDIR/.."
|
|
|
|
fi
|
|
|
|
if [ -z "$top_builddir" ]; then
|
|
|
|
top_builddir="$TS_TOPDIR/.."
|
|
|
|
fi
|
|
|
|
|
|
|
|
top_srcdir=$(ts_abspath $top_srcdir)
|
|
|
|
top_builddir=$(ts_abspath $top_builddir)
|
|
|
|
|
meson: add second build system
To build: meson build && ninja -C build
To run tests: ninja -C build check
To install for packaging: DESTDIR=/var/tmp/inst ninja -C build install
To install for realz: sudo ninja -C build install
v2:
- Optional items are now based on the 'feature' feature in meson.
Built libraries which are disabled turn into disabler() objects
and also poison any executables which link to them.
What is there:
- building of the binaries and libs and the python module
- installation of binaries, libs, python module, localization files,
man pages, pkgconfig files
- running of tests
- most options to configure build equivalently to the
./configure settings
Partially implemented:
- disabling of stuff when things missing. In the C code, the defines
are all used, so that should be fine. In the build system, some
files should be skipped, but that is probably not always done properly.
Getting this right might require some testing of various build option
combinations to get the details right.
Not implemented:
- static builds of fdisk and other binaries
- things marked with XXX or FIXME
- ???
Differences:
- .la files are not created. They are useless and everybody hates them.
- Requires.private in pkgconfig files are not present in the
autogenerated .pc file. Not sure if they should be there or not. If
necessary, they can be added by hand.
- man pages and systemd units are installed by the install target. Not
sure why 'make install' doesn't do that.
- the split between / and /usr is probably wrong. But it's all pointless
anyway, so maybe we could simplify things but not implementing it at
all under meson?
2020-02-23 12:42:55 -06:00
|
|
|
if [ -e "$top_builddir/meson.conf" ]; then
|
|
|
|
. "$top_builddir/meson.conf"
|
|
|
|
fi
|
|
|
|
|
2019-03-04 10:10:04 -06:00
|
|
|
# We use helpser always from build tree
|
|
|
|
ts_helpersdir="${top_builddir}/"
|
|
|
|
|
|
|
|
TS_USE_SYSTEM_COMMANDS=$(ts_has_option "use-system-commands" "$*")
|
|
|
|
if [ "$TS_USE_SYSTEM_COMMANDS" == "yes" ]; then
|
|
|
|
# Don't define anything, just follow current PATH
|
|
|
|
ts_commandsdir=""
|
|
|
|
else
|
|
|
|
# The default is to use commands from build tree
|
|
|
|
ts_commandsdir="${top_builddir}/"
|
|
|
|
|
|
|
|
# some ul commands search other ul commands in $PATH
|
|
|
|
export PATH="$ts_commandsdir:$PATH"
|
|
|
|
fi
|
2015-04-13 08:51:02 -05:00
|
|
|
|
2009-01-19 15:36:27 -06:00
|
|
|
TS_SCRIPT="$mydir/$(basename $0)"
|
2009-01-19 11:08:06 -06:00
|
|
|
TS_SUBDIR=$(dirname $TS_SCRIPT)
|
|
|
|
TS_TESTNAME=$(basename $TS_SCRIPT)
|
|
|
|
TS_COMPONENT=$(basename $TS_SUBDIR)
|
2016-01-05 05:31:32 -06:00
|
|
|
TS_DESC=${TS_DESC:-$TS_TESTNAME}
|
2009-01-19 11:08:06 -06:00
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
TS_NSUBTESTS=0
|
|
|
|
TS_NSUBFAILED=0
|
|
|
|
|
2009-01-19 11:08:06 -06:00
|
|
|
TS_SELF="$TS_SUBDIR"
|
|
|
|
|
2012-08-03 14:24:51 -05:00
|
|
|
TS_OUTDIR="$top_builddir/tests/output/$TS_COMPONENT"
|
|
|
|
TS_DIFFDIR="$top_builddir/tests/diff/$TS_COMPONENT"
|
2010-10-20 05:40:02 -05:00
|
|
|
|
2017-12-06 07:21:38 -06:00
|
|
|
TS_NOLOCKS=$(ts_has_option "nolocks" "$*")
|
|
|
|
TS_LOCKDIR="$top_builddir/tests/output"
|
|
|
|
|
2017-12-07 07:41:08 -06:00
|
|
|
# Don't lock if flock(1) is missing
|
|
|
|
type "flock" >/dev/null 2>&1 || TS_NOLOCKS="yes"
|
|
|
|
|
2010-10-20 05:40:02 -05:00
|
|
|
ts_init_core_env
|
2009-01-19 11:08:06 -06:00
|
|
|
|
2019-03-05 04:06:41 -06:00
|
|
|
TS_NOSKIP_COMMANDS=$(ts_has_option "noskip-commands" "$*")
|
2009-01-19 16:35:35 -06:00
|
|
|
TS_VERBOSE=$(ts_has_option "verbose" "$*")
|
2017-02-16 07:14:54 -06:00
|
|
|
TS_SHOWDIFF=$(ts_has_option "show-diff" "$*")
|
2014-02-16 17:54:15 -06:00
|
|
|
TS_PARALLEL=$(ts_has_option "parallel" "$*")
|
2014-05-09 20:57:26 -05:00
|
|
|
TS_KNOWN_FAIL=$(ts_has_option "known-fail" "$*")
|
2015-03-17 05:34:22 -05:00
|
|
|
TS_SKIP_LOOPDEVS=$(ts_has_option "skip-loopdevs" "$*")
|
2016-03-05 08:40:57 -06:00
|
|
|
TS_PARSABLE=$(ts_has_option "parsable" "$*")
|
|
|
|
[ "$TS_PARSABLE" = "yes" ] || TS_PARSABLE="$TS_PARALLEL"
|
2009-01-19 11:08:06 -06:00
|
|
|
|
2017-11-23 07:03:23 -06:00
|
|
|
tmp=$( ts_has_option "memcheck-valgrind" "$*")
|
2014-05-09 21:51:22 -05:00
|
|
|
if [ "$tmp" == "yes" -a -f /usr/bin/valgrind ]; then
|
|
|
|
TS_VALGRIND_CMD="/usr/bin/valgrind"
|
|
|
|
fi
|
2017-11-23 07:59:05 -06:00
|
|
|
tmp=$( ts_has_option "memcheck-asan" "$*")
|
|
|
|
if [ "$tmp" == "yes" ]; then
|
|
|
|
TS_ENABLE_ASAN="yes"
|
|
|
|
fi
|
2020-07-01 14:52:51 -05:00
|
|
|
tmp=$( ts_has_option "memcheck-ubsan" "$*")
|
|
|
|
if [ "$tmp" == "yes" ]; then
|
|
|
|
TS_ENABLE_UBSAN="yes"
|
|
|
|
fi
|
2014-05-09 21:51:22 -05:00
|
|
|
|
2009-01-19 17:24:23 -06:00
|
|
|
BLKID_FILE="$TS_OUTDIR/${TS_TESTNAME}.blkidtab"
|
2009-01-19 11:08:06 -06:00
|
|
|
|
2007-06-15 08:55:10 -05:00
|
|
|
declare -a TS_SUID_PROGS
|
|
|
|
declare -a TS_SUID_USER
|
|
|
|
declare -a TS_SUID_GROUP
|
2015-03-31 07:19:40 -05:00
|
|
|
declare -a TS_LOOP_DEVS
|
2018-03-08 04:45:30 -06:00
|
|
|
declare -a TS_LOCKFILE_FD
|
2007-06-15 08:55:10 -05:00
|
|
|
|
2011-11-04 14:58:21 -05:00
|
|
|
if [ -f $TS_TOPDIR/commands.sh ]; then
|
|
|
|
. $TS_TOPDIR/commands.sh
|
|
|
|
fi
|
2009-01-19 15:36:27 -06:00
|
|
|
|
2007-12-06 15:46:00 -06:00
|
|
|
export BLKID_FILE
|
2007-05-25 07:53:22 -05:00
|
|
|
|
2020-06-27 21:15:23 -05:00
|
|
|
rm -f $TS_OUTPUT $TS_ERRLOG $TS_VGDUMP $TS_EXIT_CODE
|
2012-02-28 07:37:45 -06:00
|
|
|
[ -d "$TS_OUTDIR" ] || mkdir -p "$TS_OUTDIR"
|
|
|
|
|
2020-06-27 21:15:23 -05:00
|
|
|
touch $TS_OUTPUT $TS_ERRLOG $TS_EXIT_CODE
|
2012-01-26 06:51:38 -06:00
|
|
|
[ -n "$TS_VALGRIND_CMD" ] && touch $TS_VGDUMP
|
2007-01-02 17:42:23 -06:00
|
|
|
|
2009-01-19 11:08:06 -06:00
|
|
|
if [ "$TS_VERBOSE" == "yes" ]; then
|
|
|
|
echo
|
|
|
|
echo " script: $TS_SCRIPT"
|
2019-03-04 10:10:04 -06:00
|
|
|
echo " commands: $ts_commandsdir"
|
|
|
|
echo " helpers: $ts_helpersdir"
|
2009-01-19 11:08:06 -06:00
|
|
|
echo " sub dir: $TS_SUBDIR"
|
2009-01-19 15:36:27 -06:00
|
|
|
echo " top dir: $TS_TOPDIR"
|
2009-01-19 11:08:06 -06:00
|
|
|
echo " self: $TS_SELF"
|
|
|
|
echo " test name: $TS_TESTNAME"
|
|
|
|
echo " test desc: $TS_DESC"
|
|
|
|
echo " component: $TS_COMPONENT"
|
|
|
|
echo " namespace: $TS_NS"
|
|
|
|
echo " verbose: $TS_VERBOSE"
|
|
|
|
echo " output: $TS_OUTPUT"
|
2019-08-30 08:50:07 -05:00
|
|
|
echo " error log: $TS_ERRLOG"
|
2020-06-27 21:15:23 -05:00
|
|
|
echo " exit code: $TS_EXIT_CODE"
|
2012-01-26 06:51:38 -06:00
|
|
|
echo " valgrind: $TS_VGDUMP"
|
2019-08-30 08:50:07 -05:00
|
|
|
echo " expected: $TS_EXPECTED{.err}"
|
2009-01-19 11:08:06 -06:00
|
|
|
echo " mountpoint: $TS_MOUNTPOINT"
|
|
|
|
echo
|
|
|
|
fi
|
2009-01-20 06:19:43 -06:00
|
|
|
}
|
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
function ts_init_subtest {
|
|
|
|
|
|
|
|
TS_SUBNAME="$1"
|
2010-10-20 05:40:02 -05:00
|
|
|
ts_init_core_subtest_env
|
2009-01-20 08:38:01 -06:00
|
|
|
TS_NSUBTESTS=$(( $TS_NSUBTESTS + 1 ))
|
|
|
|
|
2016-03-05 08:40:57 -06:00
|
|
|
if [ "$TS_PARSABLE" != "yes" ]; then
|
2015-12-17 03:46:32 -06:00
|
|
|
[ $TS_NSUBTESTS -eq 1 ] && echo
|
|
|
|
printf "%16s: %-27s ..." "" "$TS_SUBNAME"
|
2014-02-16 17:54:15 -06:00
|
|
|
fi
|
2009-01-20 08:38:01 -06:00
|
|
|
}
|
|
|
|
|
2009-01-20 06:19:43 -06:00
|
|
|
function ts_init {
|
2014-05-09 21:51:22 -05:00
|
|
|
ts_init_env "$*"
|
|
|
|
|
2009-01-20 06:19:43 -06:00
|
|
|
local is_fake=$( ts_has_option "fake" "$*")
|
2011-11-03 07:20:24 -05:00
|
|
|
local is_force=$( ts_has_option "force" "$*")
|
2009-01-20 06:19:43 -06:00
|
|
|
|
2016-03-05 08:40:57 -06:00
|
|
|
if [ "$TS_PARSABLE" != "yes" ]; then
|
2015-12-17 03:46:32 -06:00
|
|
|
printf "%13s: %-30s ..." "$TS_COMPONENT" "$TS_DESC"
|
2014-02-16 17:54:15 -06:00
|
|
|
fi
|
2009-01-19 11:08:06 -06:00
|
|
|
|
|
|
|
[ "$is_fake" == "yes" ] && ts_skip "fake mode"
|
2011-11-03 07:20:24 -05:00
|
|
|
[ "$TS_OPTIONAL" == "yes" -a "$is_force" != "yes" ] && ts_skip "optional"
|
2007-01-04 07:23:48 -06:00
|
|
|
}
|
|
|
|
|
2007-06-15 08:55:10 -05:00
|
|
|
function ts_init_suid {
|
|
|
|
PROG="$1"
|
|
|
|
ct=${#TS_SUID_PROGS[*]}
|
|
|
|
|
|
|
|
# Save info about original setting
|
|
|
|
TS_SUID_PROGS[$ct]=$PROG
|
|
|
|
TS_SUID_USER[$ct]=$(stat --printf="%U" $PROG)
|
|
|
|
TS_SUID_GROUP[$ct]=$(stat --printf="%G" $PROG)
|
|
|
|
|
|
|
|
chown root.root $PROG &> /dev/null
|
|
|
|
chmod u+s $PROG &> /dev/null
|
|
|
|
}
|
|
|
|
|
2013-08-19 08:35:52 -05:00
|
|
|
function ts_init_py {
|
|
|
|
LIBNAME="$1"
|
|
|
|
|
meson: add second build system
To build: meson build && ninja -C build
To run tests: ninja -C build check
To install for packaging: DESTDIR=/var/tmp/inst ninja -C build install
To install for realz: sudo ninja -C build install
v2:
- Optional items are now based on the 'feature' feature in meson.
Built libraries which are disabled turn into disabler() objects
and also poison any executables which link to them.
What is there:
- building of the binaries and libs and the python module
- installation of binaries, libs, python module, localization files,
man pages, pkgconfig files
- running of tests
- most options to configure build equivalently to the
./configure settings
Partially implemented:
- disabling of stuff when things missing. In the C code, the defines
are all used, so that should be fine. In the build system, some
files should be skipped, but that is probably not always done properly.
Getting this right might require some testing of various build option
combinations to get the details right.
Not implemented:
- static builds of fdisk and other binaries
- things marked with XXX or FIXME
- ???
Differences:
- .la files are not created. They are useless and everybody hates them.
- Requires.private in pkgconfig files are not present in the
autogenerated .pc file. Not sure if they should be there or not. If
necessary, they can be added by hand.
- man pages and systemd units are installed by the install target. Not
sure why 'make install' doesn't do that.
- the split between / and /usr is probably wrong. But it's all pointless
anyway, so maybe we could simplify things but not implementing it at
all under meson?
2020-02-23 12:42:55 -06:00
|
|
|
if [ -f "$top_builddir/py${LIBNAME}.la" ]; then
|
|
|
|
# autotoolz build
|
|
|
|
export LD_LIBRARY_PATH="$top_builddir/.libs:$LD_LIBRARY_PATH"
|
|
|
|
export PYTHONPATH="$top_builddir/$LIBNAME/python:$top_builddir/.libs:$PYTHONPATH"
|
|
|
|
|
|
|
|
PYTHON_VERSION=$(awk '/^PYTHON_VERSION/ { print $3 }' $top_builddir/Makefile)
|
|
|
|
PYTHON_MAJOR_VERSION=$(echo $PYTHON_VERSION | sed 's/\..*//')
|
2013-08-19 08:35:52 -05:00
|
|
|
|
meson: add second build system
To build: meson build && ninja -C build
To run tests: ninja -C build check
To install for packaging: DESTDIR=/var/tmp/inst ninja -C build install
To install for realz: sudo ninja -C build install
v2:
- Optional items are now based on the 'feature' feature in meson.
Built libraries which are disabled turn into disabler() objects
and also poison any executables which link to them.
What is there:
- building of the binaries and libs and the python module
- installation of binaries, libs, python module, localization files,
man pages, pkgconfig files
- running of tests
- most options to configure build equivalently to the
./configure settings
Partially implemented:
- disabling of stuff when things missing. In the C code, the defines
are all used, so that should be fine. In the build system, some
files should be skipped, but that is probably not always done properly.
Getting this right might require some testing of various build option
combinations to get the details right.
Not implemented:
- static builds of fdisk and other binaries
- things marked with XXX or FIXME
- ???
Differences:
- .la files are not created. They are useless and everybody hates them.
- Requires.private in pkgconfig files are not present in the
autogenerated .pc file. Not sure if they should be there or not. If
necessary, they can be added by hand.
- man pages and systemd units are installed by the install target. Not
sure why 'make install' doesn't do that.
- the split between / and /usr is probably wrong. But it's all pointless
anyway, so maybe we could simplify things but not implementing it at
all under meson?
2020-02-23 12:42:55 -06:00
|
|
|
export PYTHON="python${PYTHON_MAJOR_VERSION}"
|
2013-08-29 07:57:04 -05:00
|
|
|
|
meson: add second build system
To build: meson build && ninja -C build
To run tests: ninja -C build check
To install for packaging: DESTDIR=/var/tmp/inst ninja -C build install
To install for realz: sudo ninja -C build install
v2:
- Optional items are now based on the 'feature' feature in meson.
Built libraries which are disabled turn into disabler() objects
and also poison any executables which link to them.
What is there:
- building of the binaries and libs and the python module
- installation of binaries, libs, python module, localization files,
man pages, pkgconfig files
- running of tests
- most options to configure build equivalently to the
./configure settings
Partially implemented:
- disabling of stuff when things missing. In the C code, the defines
are all used, so that should be fine. In the build system, some
files should be skipped, but that is probably not always done properly.
Getting this right might require some testing of various build option
combinations to get the details right.
Not implemented:
- static builds of fdisk and other binaries
- things marked with XXX or FIXME
- ???
Differences:
- .la files are not created. They are useless and everybody hates them.
- Requires.private in pkgconfig files are not present in the
autogenerated .pc file. Not sure if they should be there or not. If
necessary, they can be added by hand.
- man pages and systemd units are installed by the install target. Not
sure why 'make install' doesn't do that.
- the split between / and /usr is probably wrong. But it's all pointless
anyway, so maybe we could simplify things but not implementing it at
all under meson?
2020-02-23 12:42:55 -06:00
|
|
|
elif compgen -G "$top_builddir/$LIBNAME/python/py$LIBNAME*.so" >/dev/null; then
|
|
|
|
# mezon!
|
|
|
|
export PYTHONPATH="$top_builddir/$LIBNAME/python:$PYTHONPATH"
|
2013-08-29 07:57:04 -05:00
|
|
|
|
meson: add second build system
To build: meson build && ninja -C build
To run tests: ninja -C build check
To install for packaging: DESTDIR=/var/tmp/inst ninja -C build install
To install for realz: sudo ninja -C build install
v2:
- Optional items are now based on the 'feature' feature in meson.
Built libraries which are disabled turn into disabler() objects
and also poison any executables which link to them.
What is there:
- building of the binaries and libs and the python module
- installation of binaries, libs, python module, localization files,
man pages, pkgconfig files
- running of tests
- most options to configure build equivalently to the
./configure settings
Partially implemented:
- disabling of stuff when things missing. In the C code, the defines
are all used, so that should be fine. In the build system, some
files should be skipped, but that is probably not always done properly.
Getting this right might require some testing of various build option
combinations to get the details right.
Not implemented:
- static builds of fdisk and other binaries
- things marked with XXX or FIXME
- ???
Differences:
- .la files are not created. They are useless and everybody hates them.
- Requires.private in pkgconfig files are not present in the
autogenerated .pc file. Not sure if they should be there or not. If
necessary, they can be added by hand.
- man pages and systemd units are installed by the install target. Not
sure why 'make install' doesn't do that.
- the split between / and /usr is probably wrong. But it's all pointless
anyway, so maybe we could simplify things but not implementing it at
all under meson?
2020-02-23 12:42:55 -06:00
|
|
|
else
|
|
|
|
ts_skip "py${LIBNAME} not compiled"
|
|
|
|
fi
|
2013-08-19 08:35:52 -05:00
|
|
|
}
|
|
|
|
|
2017-11-23 06:44:53 -06:00
|
|
|
function ts_run {
|
2019-08-28 01:56:24 -05:00
|
|
|
declare -a args
|
2020-07-03 08:26:08 -05:00
|
|
|
local asan_options="strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1"
|
2019-08-28 01:56:24 -05:00
|
|
|
|
2017-11-23 07:03:23 -06:00
|
|
|
#
|
2019-08-23 08:32:53 -05:00
|
|
|
# ASAN mode
|
2017-11-23 07:03:23 -06:00
|
|
|
#
|
2020-07-01 14:52:51 -05:00
|
|
|
if [ "$TS_ENABLE_ASAN" == "yes" -o "$TS_ENABLE_UBSAN" == "yes" ]; then
|
|
|
|
args+=(env)
|
|
|
|
if [ "$TS_ENABLE_ASAN" == "yes" ]; then
|
2020-07-03 08:26:08 -05:00
|
|
|
# detect_leaks isn't supported on s390x: https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/lsan/lsan_common.h
|
|
|
|
if [ "$(uname -m)" != "s390x" ]; then
|
|
|
|
asan_options="$asan_options:detect_leaks=1"
|
|
|
|
fi
|
|
|
|
args+=(ASAN_OPTIONS=$asan_options)
|
2020-07-01 14:52:51 -05:00
|
|
|
fi
|
|
|
|
if [ "$TS_ENABLE_UBSAN" == "yes" ]; then
|
|
|
|
args+=(UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1)
|
|
|
|
fi
|
2019-08-28 01:56:24 -05:00
|
|
|
fi
|
2017-11-23 07:03:23 -06:00
|
|
|
|
2019-08-27 06:02:38 -05:00
|
|
|
#
|
2019-08-28 01:56:24 -05:00
|
|
|
# valgrind mode
|
2019-08-27 06:02:38 -05:00
|
|
|
#
|
2019-08-28 01:56:24 -05:00
|
|
|
if [ -n "$TS_VALGRIND_CMD" ]; then
|
|
|
|
args+=(libtool --mode=execute "$TS_VALGRIND_CMD" --tool=memcheck --leak-check=full)
|
|
|
|
args+=(--leak-resolution=high --num-callers=20 --log-file="$TS_VGDUMP")
|
2012-01-26 06:51:38 -06:00
|
|
|
fi
|
2019-08-28 01:56:24 -05:00
|
|
|
|
|
|
|
"${args[@]}" "$@"
|
2020-06-27 21:15:23 -05:00
|
|
|
echo $? >$TS_EXIT_CODE
|
2012-01-26 06:51:38 -06:00
|
|
|
}
|
|
|
|
|
2019-08-30 08:50:07 -05:00
|
|
|
function ts_gen_diff_from {
|
2009-01-20 08:38:01 -06:00
|
|
|
local res=0
|
2019-08-30 08:50:07 -05:00
|
|
|
local expected="$1"
|
|
|
|
local output="$2"
|
|
|
|
local difffile="$3"
|
2009-01-20 08:38:01 -06:00
|
|
|
|
2019-08-30 08:50:07 -05:00
|
|
|
diff -u $expected $output > $difffile
|
2012-02-28 07:37:45 -06:00
|
|
|
|
2019-08-30 08:50:07 -05:00
|
|
|
if [ $? -ne 0 ] || [ -s $difffile ]; then
|
2009-01-20 08:38:01 -06:00
|
|
|
res=1
|
2019-08-27 07:38:21 -05:00
|
|
|
if [ "$TS_SHOWDIFF" == "yes" -a "$TS_KNOWN_FAIL" != "yes" ]; then
|
2017-02-16 07:14:54 -06:00
|
|
|
echo
|
|
|
|
echo "diff-{{{"
|
2019-08-30 08:50:07 -05:00
|
|
|
cat $difffile
|
2017-02-16 07:14:54 -06:00
|
|
|
echo "}}}-diff"
|
|
|
|
echo
|
|
|
|
fi
|
2016-03-05 11:51:59 -06:00
|
|
|
else
|
2019-08-30 08:50:07 -05:00
|
|
|
rm -f $difffile;
|
2009-01-20 08:38:01 -06:00
|
|
|
fi
|
2016-03-05 11:51:59 -06:00
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
return $res
|
|
|
|
}
|
|
|
|
|
2019-08-30 08:50:07 -05:00
|
|
|
function ts_gen_diff {
|
|
|
|
local status_out=0
|
|
|
|
local status_err=0
|
2020-06-27 21:15:23 -05:00
|
|
|
local exit_code=0
|
2019-08-30 08:50:07 -05:00
|
|
|
|
|
|
|
[ -f "$TS_OUTPUT" ] || return 1
|
|
|
|
[ -f "$TS_EXPECTED" ] || TS_EXPECTED=/dev/null
|
|
|
|
|
|
|
|
# remove libtool lt- prefixes
|
|
|
|
sed --in-place 's/^lt\-\(.*\: \)/\1/g' $TS_OUTPUT
|
|
|
|
sed --in-place 's/^lt\-\(.*\: \)/\1/g' $TS_ERRLOG
|
|
|
|
|
|
|
|
[ -d "$TS_DIFFDIR" ] || mkdir -p "$TS_DIFFDIR"
|
|
|
|
|
|
|
|
# error log is fully optional
|
|
|
|
[ -f "$TS_EXPECTED_ERR" ] || TS_EXPECTED_ERR=/dev/null
|
|
|
|
[ -f "$TS_ERRLOG" ] || TS_ERRLOG=/dev/null
|
|
|
|
|
2020-06-27 21:15:23 -05:00
|
|
|
if [ "$TS_COMPONENT" != "fuzzers" ]; then
|
|
|
|
ts_gen_diff_from $TS_EXPECTED $TS_OUTPUT $TS_DIFF
|
|
|
|
status_out=$?
|
|
|
|
|
|
|
|
ts_gen_diff_from $TS_EXPECTED_ERR $TS_ERRLOG $TS_DIFF.err
|
|
|
|
status_err=$?
|
|
|
|
else
|
|
|
|
# TS_EXIT_CODE is empty when tests aren't run with ts_run: https://github.com/karelzak/util-linux/issues/1072
|
|
|
|
# or when ts_finalize is called right after ts_finalize_subtest.
|
|
|
|
exit_code="$(cat $TS_EXIT_CODE)"
|
|
|
|
if [ -z "$exit_code" ]; then
|
|
|
|
exit_code=0
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $exit_code -ne 0 ]; then
|
|
|
|
ts_gen_diff_from $TS_EXPECTED $TS_OUTPUT $TS_DIFF
|
|
|
|
ts_gen_diff_from $TS_EXPECTED_ERR $TS_ERRLOG $TS_DIFF.err
|
|
|
|
fi
|
|
|
|
fi
|
2019-08-30 08:50:07 -05:00
|
|
|
|
2020-06-27 21:15:23 -05:00
|
|
|
if [ $status_out -ne 0 -o $status_err -ne 0 -o $exit_code -ne 0 ]; then
|
2019-08-30 08:50:07 -05:00
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2012-01-26 06:51:38 -06:00
|
|
|
function tt_gen_mem_report {
|
2017-11-23 07:03:23 -06:00
|
|
|
if [ -n "$TS_VALGRIND_CMD" ]; then
|
|
|
|
grep -q -E 'ERROR SUMMARY: [1-9]' $TS_VGDUMP &> /dev/null
|
|
|
|
if [ $? -eq 0 ]; then
|
|
|
|
echo "mem-error detected!"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo "$1"
|
2012-01-26 06:51:38 -06:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
function ts_finalize_subtest {
|
2007-01-04 07:23:48 -06:00
|
|
|
local res=0
|
|
|
|
|
2016-03-05 11:51:59 -06:00
|
|
|
ts_gen_diff
|
|
|
|
if [ $? -eq 1 ]; then
|
|
|
|
ts_failed_subtest "$1"
|
|
|
|
res=1
|
2009-01-20 08:38:01 -06:00
|
|
|
else
|
2016-07-11 04:01:14 -05:00
|
|
|
ts_report_ok "$(tt_gen_mem_report "$1")"
|
2009-01-20 08:38:01 -06:00
|
|
|
fi
|
|
|
|
|
|
|
|
[ $res -ne 0 ] && TS_NSUBFAILED=$(( $TS_NSUBFAILED + 1 ))
|
2010-10-20 05:40:02 -05:00
|
|
|
|
|
|
|
# reset environment back to parental test
|
|
|
|
ts_init_core_env
|
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
return $res
|
|
|
|
}
|
|
|
|
|
2016-07-11 04:01:14 -05:00
|
|
|
function ts_skip_subtest {
|
|
|
|
ts_report_skip "$1"
|
|
|
|
# reset environment back to parental test
|
|
|
|
ts_init_core_env
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
function ts_finalize {
|
2015-03-31 03:54:56 -05:00
|
|
|
ts_cleanup_on_exit
|
2007-06-15 08:55:10 -05:00
|
|
|
|
2009-01-20 08:38:01 -06:00
|
|
|
if [ $TS_NSUBTESTS -ne 0 ]; then
|
2016-03-05 11:51:59 -06:00
|
|
|
if ! ts_gen_diff || [ $TS_NSUBFAILED -ne 0 ]; then
|
2009-01-20 08:38:01 -06:00
|
|
|
ts_failed "$TS_NSUBFAILED from $TS_NSUBTESTS sub-tests"
|
|
|
|
else
|
|
|
|
ts_ok "all $TS_NSUBTESTS sub-tests PASSED"
|
|
|
|
fi
|
2007-01-04 07:23:48 -06:00
|
|
|
fi
|
2009-01-20 16:42:33 -06:00
|
|
|
|
2016-03-05 11:51:59 -06:00
|
|
|
ts_gen_diff || ts_failed "$1"
|
|
|
|
ts_ok "$1"
|
2007-01-04 07:23:48 -06:00
|
|
|
}
|
|
|
|
|
2007-05-18 06:49:15 -05:00
|
|
|
function ts_die {
|
2007-05-18 08:34:28 -05:00
|
|
|
ts_log "$1"
|
2007-05-18 06:49:15 -05:00
|
|
|
ts_finalize
|
|
|
|
}
|
|
|
|
|
2015-03-31 03:54:56 -05:00
|
|
|
function ts_cleanup_on_exit {
|
|
|
|
|
|
|
|
for idx in $(seq 0 $((${#TS_SUID_PROGS[*]} - 1))); do
|
|
|
|
PROG=${TS_SUID_PROGS[$idx]}
|
|
|
|
chmod a-s $PROG &> /dev/null
|
|
|
|
chown ${TS_SUID_USER[$idx]}.${TS_SUID_GROUP[$idx]} $PROG &> /dev/null
|
|
|
|
done
|
2015-03-31 07:19:40 -05:00
|
|
|
|
|
|
|
for dev in "${TS_LOOP_DEVS[@]}"; do
|
|
|
|
ts_device_deinit "$dev"
|
|
|
|
done
|
|
|
|
unset TS_LOOP_DEVS
|
2016-10-21 06:01:55 -05:00
|
|
|
|
|
|
|
ts_scsi_debug_rmmod
|
2015-03-31 03:54:56 -05:00
|
|
|
}
|
|
|
|
|
2009-05-19 09:13:09 -05:00
|
|
|
function ts_image_md5sum {
|
|
|
|
local img=${1:-"$TS_OUTDIR/${TS_TESTNAME}.img"}
|
2016-04-06 05:30:18 -05:00
|
|
|
echo $("$TS_HELPER_MD5" < "$img") $(basename "$img")
|
2009-05-19 09:13:09 -05:00
|
|
|
}
|
2007-03-19 17:27:40 -05:00
|
|
|
|
2009-05-19 09:13:09 -05:00
|
|
|
function ts_image_init {
|
|
|
|
local mib=${1:-"5"} # size in MiBs
|
|
|
|
local img=${2:-"$TS_OUTDIR/${TS_TESTNAME}.img"}
|
2014-02-16 09:22:56 -06:00
|
|
|
|
2015-12-15 10:46:58 -06:00
|
|
|
rm -f $img
|
|
|
|
truncate -s "${mib}M" "$img"
|
2009-05-19 09:13:09 -05:00
|
|
|
echo "$img"
|
|
|
|
return 0
|
|
|
|
}
|
2007-03-19 17:27:40 -05:00
|
|
|
|
2015-03-31 07:19:40 -05:00
|
|
|
function ts_register_loop_device {
|
|
|
|
local ct=${#TS_LOOP_DEVS[*]}
|
|
|
|
TS_LOOP_DEVS[$ct]=$1
|
|
|
|
}
|
|
|
|
|
2009-05-19 09:13:09 -05:00
|
|
|
function ts_device_init {
|
2014-05-11 18:43:03 -05:00
|
|
|
local img
|
|
|
|
local dev
|
2007-05-15 18:38:13 -05:00
|
|
|
|
2014-05-11 18:43:03 -05:00
|
|
|
img=$(ts_image_init $1 $2)
|
|
|
|
dev=$($TS_CMD_LOSETUP --show -f "$img")
|
2015-03-31 07:19:40 -05:00
|
|
|
if [ "$?" != "0" -o "$dev" = "" ]; then
|
|
|
|
ts_die "Cannot init device"
|
|
|
|
fi
|
2007-05-15 18:38:13 -05:00
|
|
|
|
2015-03-31 07:19:40 -05:00
|
|
|
ts_register_loop_device "$dev"
|
|
|
|
TS_LODEV=$dev
|
2007-05-15 18:38:13 -05:00
|
|
|
}
|
|
|
|
|
2015-03-31 07:19:40 -05:00
|
|
|
# call from ts_cleanup_on_exit() only because of TS_LOOP_DEVS maintenance
|
2007-05-15 18:38:13 -05:00
|
|
|
function ts_device_deinit {
|
2007-05-18 06:49:15 -05:00
|
|
|
local DEV="$1"
|
|
|
|
|
|
|
|
if [ -b "$DEV" ]; then
|
|
|
|
$TS_CMD_UMOUNT "$DEV" &> /dev/null
|
|
|
|
$TS_CMD_LOSETUP -d "$DEV" &> /dev/null
|
2007-05-15 18:38:13 -05:00
|
|
|
fi
|
|
|
|
}
|
2007-05-15 19:07:07 -05:00
|
|
|
|
tests: consolidate ts_device_has UUID or LABEL
Regarding parallel root checks ...
- fix: add a few missing "udevadm settle" where we are using LABELs or UUIDs
- introduce ts_udevadm_settle():
* Still trivial implementation. The idea is to use it in future for all
tests instead of directly calling "udevadm settle". So we could add debug
messages, wait for specific events, add code for non-udev systems or even
use "udevadm --{start,stop}-exec-queue" to be really sure what we are
doing and why using udevadm at all.
* The currently unused args may be used in future and show the code reader
already now why we are calling "udevadm settle" at all.
* So far this patch only affects swapon/, mount/, libmount/ tests, and is
only about UUIDs and LABELs, but may be continued later for "partitions",
"md devices", whatever.
* We are calling ts_udevadm_settle() right *before* we need a LABEL or
UUID, not just *after* we created one. This may be a bit better for
speed and shows the code reader which command would fail without settle.
- function ts_device_has_uuid() is unused now, we trust blkid(1). Renamed to
ts_is_uuid() in case we would need it again.
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
2018-03-10 12:44:32 -06:00
|
|
|
function ts_blkidtag_by_devname()
|
|
|
|
{
|
|
|
|
local tag=$1
|
|
|
|
local dev=$2
|
|
|
|
local out
|
|
|
|
local rval
|
|
|
|
|
|
|
|
out=$($TS_CMD_BLKID -p -s "$tag" -o value "$dev")
|
|
|
|
rval=$?
|
|
|
|
printf "%s\n" "$out"
|
|
|
|
|
|
|
|
test -n "$out" -a "$rval" = "0"
|
|
|
|
return $?
|
|
|
|
}
|
|
|
|
|
2007-05-17 13:16:25 -05:00
|
|
|
function ts_uuid_by_devname {
|
tests: consolidate ts_device_has UUID or LABEL
Regarding parallel root checks ...
- fix: add a few missing "udevadm settle" where we are using LABELs or UUIDs
- introduce ts_udevadm_settle():
* Still trivial implementation. The idea is to use it in future for all
tests instead of directly calling "udevadm settle". So we could add debug
messages, wait for specific events, add code for non-udev systems or even
use "udevadm --{start,stop}-exec-queue" to be really sure what we are
doing and why using udevadm at all.
* The currently unused args may be used in future and show the code reader
already now why we are calling "udevadm settle" at all.
* So far this patch only affects swapon/, mount/, libmount/ tests, and is
only about UUIDs and LABELs, but may be continued later for "partitions",
"md devices", whatever.
* We are calling ts_udevadm_settle() right *before* we need a LABEL or
UUID, not just *after* we created one. This may be a bit better for
speed and shows the code reader which command would fail without settle.
- function ts_device_has_uuid() is unused now, we trust blkid(1). Renamed to
ts_is_uuid() in case we would need it again.
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
2018-03-10 12:44:32 -06:00
|
|
|
ts_blkidtag_by_devname "UUID" "$1"
|
|
|
|
return $?
|
2007-05-17 13:16:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
function ts_label_by_devname {
|
tests: consolidate ts_device_has UUID or LABEL
Regarding parallel root checks ...
- fix: add a few missing "udevadm settle" where we are using LABELs or UUIDs
- introduce ts_udevadm_settle():
* Still trivial implementation. The idea is to use it in future for all
tests instead of directly calling "udevadm settle". So we could add debug
messages, wait for specific events, add code for non-udev systems or even
use "udevadm --{start,stop}-exec-queue" to be really sure what we are
doing and why using udevadm at all.
* The currently unused args may be used in future and show the code reader
already now why we are calling "udevadm settle" at all.
* So far this patch only affects swapon/, mount/, libmount/ tests, and is
only about UUIDs and LABELs, but may be continued later for "partitions",
"md devices", whatever.
* We are calling ts_udevadm_settle() right *before* we need a LABEL or
UUID, not just *after* we created one. This may be a bit better for
speed and shows the code reader which command would fail without settle.
- function ts_device_has_uuid() is unused now, we trust blkid(1). Renamed to
ts_is_uuid() in case we would need it again.
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
2018-03-10 12:44:32 -06:00
|
|
|
ts_blkidtag_by_devname "LABEL" "$1"
|
|
|
|
return $?
|
2007-05-17 13:16:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
function ts_fstype_by_devname {
|
tests: consolidate ts_device_has UUID or LABEL
Regarding parallel root checks ...
- fix: add a few missing "udevadm settle" where we are using LABELs or UUIDs
- introduce ts_udevadm_settle():
* Still trivial implementation. The idea is to use it in future for all
tests instead of directly calling "udevadm settle". So we could add debug
messages, wait for specific events, add code for non-udev systems or even
use "udevadm --{start,stop}-exec-queue" to be really sure what we are
doing and why using udevadm at all.
* The currently unused args may be used in future and show the code reader
already now why we are calling "udevadm settle" at all.
* So far this patch only affects swapon/, mount/, libmount/ tests, and is
only about UUIDs and LABELs, but may be continued later for "partitions",
"md devices", whatever.
* We are calling ts_udevadm_settle() right *before* we need a LABEL or
UUID, not just *after* we created one. This may be a bit better for
speed and shows the code reader which command would fail without settle.
- function ts_device_has_uuid() is unused now, we trust blkid(1). Renamed to
ts_is_uuid() in case we would need it again.
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
2018-03-10 12:44:32 -06:00
|
|
|
ts_blkidtag_by_devname "TYPE" "$1"
|
|
|
|
return $?
|
2007-05-17 13:16:25 -05:00
|
|
|
}
|
|
|
|
|
2021-01-26 03:30:01 -06:00
|
|
|
function ts_vfs_dump {
|
|
|
|
if [ "$TS_SHOWDIFF" == "yes" -a "$TS_KNOWN_FAIL" != "yes" ]; then
|
|
|
|
echo
|
|
|
|
echo "{{{{ VFS dump:"
|
|
|
|
findmnt
|
|
|
|
echo "}}}}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function ts_blk_dump {
|
|
|
|
if [ "$TS_SHOWDIFF" == "yes" -a "$TS_KNOWN_FAIL" != "yes" ]; then
|
|
|
|
echo
|
|
|
|
echo "{{{{ blkdevs dump:"
|
|
|
|
lsblk -o+FSTYPE
|
|
|
|
echo "}}}}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2007-05-17 13:16:25 -05:00
|
|
|
function ts_device_has {
|
|
|
|
local TAG="$1"
|
|
|
|
local VAL="$2"
|
|
|
|
local DEV="$3"
|
2007-05-18 06:49:15 -05:00
|
|
|
local vl=""
|
2021-01-26 03:30:01 -06:00
|
|
|
local res=""
|
2007-05-17 13:16:25 -05:00
|
|
|
|
tests: consolidate ts_device_has UUID or LABEL
Regarding parallel root checks ...
- fix: add a few missing "udevadm settle" where we are using LABELs or UUIDs
- introduce ts_udevadm_settle():
* Still trivial implementation. The idea is to use it in future for all
tests instead of directly calling "udevadm settle". So we could add debug
messages, wait for specific events, add code for non-udev systems or even
use "udevadm --{start,stop}-exec-queue" to be really sure what we are
doing and why using udevadm at all.
* The currently unused args may be used in future and show the code reader
already now why we are calling "udevadm settle" at all.
* So far this patch only affects swapon/, mount/, libmount/ tests, and is
only about UUIDs and LABELs, but may be continued later for "partitions",
"md devices", whatever.
* We are calling ts_udevadm_settle() right *before* we need a LABEL or
UUID, not just *after* we created one. This may be a bit better for
speed and shows the code reader which command would fail without settle.
- function ts_device_has_uuid() is unused now, we trust blkid(1). Renamed to
ts_is_uuid() in case we would need it again.
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
2018-03-10 12:44:32 -06:00
|
|
|
vl=$(ts_blkidtag_by_devname "$TAG" "$DEV")
|
|
|
|
test $? = 0 -a "$vl" = "$VAL"
|
2021-01-26 03:30:01 -06:00
|
|
|
res=$?
|
|
|
|
|
|
|
|
if [ "$res" != 0 ]; then
|
|
|
|
ts_vfs_dump
|
|
|
|
ts_blk_dump
|
|
|
|
fi
|
|
|
|
|
|
|
|
return $res
|
2007-05-17 13:16:25 -05:00
|
|
|
}
|
2007-05-18 06:49:15 -05:00
|
|
|
|
tests: consolidate ts_device_has UUID or LABEL
Regarding parallel root checks ...
- fix: add a few missing "udevadm settle" where we are using LABELs or UUIDs
- introduce ts_udevadm_settle():
* Still trivial implementation. The idea is to use it in future for all
tests instead of directly calling "udevadm settle". So we could add debug
messages, wait for specific events, add code for non-udev systems or even
use "udevadm --{start,stop}-exec-queue" to be really sure what we are
doing and why using udevadm at all.
* The currently unused args may be used in future and show the code reader
already now why we are calling "udevadm settle" at all.
* So far this patch only affects swapon/, mount/, libmount/ tests, and is
only about UUIDs and LABELs, but may be continued later for "partitions",
"md devices", whatever.
* We are calling ts_udevadm_settle() right *before* we need a LABEL or
UUID, not just *after* we created one. This may be a bit better for
speed and shows the code reader which command would fail without settle.
- function ts_device_has_uuid() is unused now, we trust blkid(1). Renamed to
ts_is_uuid() in case we would need it again.
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
2018-03-10 12:44:32 -06:00
|
|
|
function ts_is_uuid()
|
|
|
|
{
|
|
|
|
printf "%s\n" "$1" | egrep -q '^[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$'
|
2007-05-18 06:49:15 -05:00
|
|
|
return $?
|
|
|
|
}
|
|
|
|
|
tests: consolidate ts_device_has UUID or LABEL
Regarding parallel root checks ...
- fix: add a few missing "udevadm settle" where we are using LABELs or UUIDs
- introduce ts_udevadm_settle():
* Still trivial implementation. The idea is to use it in future for all
tests instead of directly calling "udevadm settle". So we could add debug
messages, wait for specific events, add code for non-udev systems or even
use "udevadm --{start,stop}-exec-queue" to be really sure what we are
doing and why using udevadm at all.
* The currently unused args may be used in future and show the code reader
already now why we are calling "udevadm settle" at all.
* So far this patch only affects swapon/, mount/, libmount/ tests, and is
only about UUIDs and LABELs, but may be continued later for "partitions",
"md devices", whatever.
* We are calling ts_udevadm_settle() right *before* we need a LABEL or
UUID, not just *after* we created one. This may be a bit better for
speed and shows the code reader which command would fail without settle.
- function ts_device_has_uuid() is unused now, we trust blkid(1). Renamed to
ts_is_uuid() in case we would need it again.
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
2018-03-10 12:44:32 -06:00
|
|
|
function ts_udevadm_settle()
|
|
|
|
{
|
|
|
|
local dev=$1 # optional, might be empty
|
|
|
|
shift # all other args are tags, LABEL, UUID, ...
|
|
|
|
udevadm settle
|
|
|
|
}
|
|
|
|
|
2014-05-15 06:20:31 -05:00
|
|
|
function ts_mount {
|
|
|
|
local out
|
|
|
|
local result
|
|
|
|
local msg
|
2014-05-15 09:27:28 -05:00
|
|
|
local fs
|
2014-05-15 09:56:18 -05:00
|
|
|
local fs_exp=$1
|
|
|
|
shift
|
2014-05-15 06:20:31 -05:00
|
|
|
|
|
|
|
out=$($TS_CMD_MOUNT "$@" 2>&1)
|
|
|
|
result=$?
|
|
|
|
echo -n "$out" >> $TS_OUTPUT
|
|
|
|
|
2014-05-15 09:27:28 -05:00
|
|
|
if [ $result != 0 ] \
|
|
|
|
&& msg=$(echo "$out" | grep -m1 "unknown filesystem type")
|
|
|
|
then
|
|
|
|
# skip only if reported fs correctly and if it's not available
|
|
|
|
fs=$(echo "$msg" | sed -n "s/.*type '\(.*\)'$/\1/p")
|
2014-05-15 09:56:18 -05:00
|
|
|
[ "$fs" = "fs_exp" ] \
|
2014-05-15 09:27:28 -05:00
|
|
|
&& grep -qe "[[:space:]]${fs}$" /proc/filesystems &>/dev/null \
|
|
|
|
|| ts_skip "$msg"
|
2014-05-15 06:20:31 -05:00
|
|
|
fi
|
|
|
|
return $result
|
|
|
|
}
|
|
|
|
|
2009-02-04 15:38:34 -06:00
|
|
|
function ts_is_mounted {
|
2012-07-30 10:10:38 -05:00
|
|
|
local DEV=$(ts_canonicalize "$1")
|
2009-02-04 15:38:34 -06:00
|
|
|
|
2018-03-09 11:27:44 -06:00
|
|
|
grep -q "\(^\| \)$DEV " /proc/mounts && return 0
|
2009-02-04 15:38:34 -06:00
|
|
|
|
|
|
|
if [ "${DEV#/dev/loop/}" != "$DEV" ]; then
|
2018-03-09 11:27:44 -06:00
|
|
|
grep -q "^/dev/loop${DEV#/dev/loop/} " /proc/mounts && return 0
|
2009-02-04 15:38:34 -06:00
|
|
|
fi
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2007-05-22 09:01:55 -05:00
|
|
|
function ts_fstab_open {
|
2010-11-30 04:41:59 -06:00
|
|
|
echo "# <!-- util-linux test entry" >> /etc/fstab
|
2007-05-22 09:01:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
function ts_fstab_close {
|
|
|
|
echo "# -->" >> /etc/fstab
|
2018-01-23 09:59:26 -06:00
|
|
|
sync /etc/fstab 2>/dev/null
|
2007-05-22 09:01:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
function ts_fstab_addline {
|
|
|
|
local SPEC="$1"
|
|
|
|
local MNT=${2:-"$TS_MOUNTPOINT"}
|
|
|
|
local FS=${3:-"auto"}
|
2007-06-15 04:29:04 -05:00
|
|
|
local OPT=${4:-"defaults"}
|
2007-05-22 09:01:55 -05:00
|
|
|
|
2007-06-15 04:29:04 -05:00
|
|
|
echo "$SPEC $MNT $FS $OPT 0 0" >> /etc/fstab
|
2007-05-22 09:01:55 -05:00
|
|
|
}
|
|
|
|
|
2017-12-06 07:38:44 -06:00
|
|
|
function ts_fstab_lock {
|
|
|
|
ts_lock "fstab"
|
|
|
|
}
|
|
|
|
|
2007-05-22 09:01:55 -05:00
|
|
|
function ts_fstab_add {
|
2017-12-06 07:38:44 -06:00
|
|
|
ts_fstab_lock
|
2007-05-22 09:01:55 -05:00
|
|
|
ts_fstab_open
|
2007-06-15 04:29:04 -05:00
|
|
|
ts_fstab_addline $*
|
2007-05-22 09:01:55 -05:00
|
|
|
ts_fstab_close
|
|
|
|
}
|
|
|
|
|
|
|
|
function ts_fstab_clean {
|
2018-03-07 10:51:35 -06:00
|
|
|
ts_have_lock "fstab" || return 0
|
2007-05-22 09:01:55 -05:00
|
|
|
sed --in-place "
|
2010-11-30 04:41:59 -06:00
|
|
|
/# <!-- util-linux/!b
|
2007-05-22 09:01:55 -05:00
|
|
|
:a
|
|
|
|
/# -->/!{
|
|
|
|
N
|
|
|
|
ba
|
|
|
|
}
|
2010-11-30 04:41:59 -06:00
|
|
|
s/# <!-- util-linux.*-->//;
|
2007-05-22 09:01:55 -05:00
|
|
|
/^$/d" /etc/fstab
|
2017-12-06 07:38:44 -06:00
|
|
|
|
2018-01-23 09:59:26 -06:00
|
|
|
sync /etc/fstab 2>/dev/null
|
2017-12-06 07:38:44 -06:00
|
|
|
ts_unlock "fstab"
|
2007-05-22 09:01:55 -05:00
|
|
|
}
|
|
|
|
|
2011-08-16 17:19:05 -05:00
|
|
|
function ts_fdisk_clean {
|
2013-09-18 08:38:33 -05:00
|
|
|
local DEVNAME=$1
|
2013-04-12 09:36:33 -05:00
|
|
|
|
2011-08-16 17:19:05 -05:00
|
|
|
# remove non comparable parts of fdisk output
|
2016-02-03 16:44:42 -06:00
|
|
|
if [ -n "${DEVNAME}" ]; then
|
2019-08-30 08:50:07 -05:00
|
|
|
sed -i -e "s@${DEVNAME}@<removed>@;" $TS_OUTPUT $TS_ERRLOG
|
2016-02-03 16:44:42 -06:00
|
|
|
fi
|
|
|
|
|
|
|
|
sed -i \
|
|
|
|
-e 's/Disk identifier:.*/Disk identifier: <removed>/' \
|
2020-03-24 08:30:16 -05:00
|
|
|
-e 's/Created a new partition.*/Created a new partition <removed>./' \
|
|
|
|
-e 's/Created a new .* disklabel .*/Created a new disklabel./' \
|
2016-02-03 16:44:42 -06:00
|
|
|
-e 's/^Device[[:blank:]]*Start/Device Start/' \
|
|
|
|
-e 's/^Device[[:blank:]]*Boot/Device Boot/' \
|
|
|
|
-e 's/Welcome to fdisk.*/Welcome to fdisk <removed>./' \
|
|
|
|
-e 's/typescript file.*/typescript file <removed>./' \
|
2016-02-03 17:58:04 -06:00
|
|
|
-e 's@^\(I/O size (minimum/op.* bytes /\) [1-9][0-9]* @\1 <removed> @' \
|
2019-08-30 08:50:07 -05:00
|
|
|
$TS_OUTPUT $TS_ERRLOG
|
2011-08-16 17:19:05 -05:00
|
|
|
}
|
2013-04-12 09:36:33 -05:00
|
|
|
|
2017-12-06 07:21:38 -06:00
|
|
|
|
2018-03-06 17:29:59 -06:00
|
|
|
# https://stackoverflow.com/questions/41603787/how-to-find-next-available-file-descriptor-in-bash
|
|
|
|
function ts_find_free_fd()
|
|
|
|
{
|
|
|
|
local rco
|
|
|
|
local rci
|
|
|
|
for fd in {3..200}; do
|
|
|
|
rco="$(true 2>/dev/null >&${fd}; echo $?)"
|
|
|
|
rci="$(true 2>/dev/null <&${fd}; echo $?)"
|
|
|
|
if [[ "${rco}${rci}" = "11" ]]; then
|
|
|
|
echo "$fd"
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
return 1
|
2017-12-07 07:41:08 -06:00
|
|
|
}
|
|
|
|
|
2018-03-08 04:45:30 -06:00
|
|
|
function ts_get_lock_fd {
|
|
|
|
local resource=$1
|
|
|
|
local fd
|
|
|
|
|
|
|
|
for fd in "${!TS_LOCKFILE_FD[@]}"; do
|
|
|
|
if [ "${TS_LOCKFILE_FD["$fd"]}" = "$resource" ]; then
|
|
|
|
echo "$fd"
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2018-03-07 10:51:35 -06:00
|
|
|
function ts_have_lock {
|
|
|
|
local resource=$1
|
|
|
|
|
|
|
|
test "$TS_NOLOCKS" = "yes" && return 0
|
2018-03-08 04:45:30 -06:00
|
|
|
ts_get_lock_fd "$resource" >/dev/null && return 0
|
2018-03-07 10:51:35 -06:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2017-12-06 07:21:38 -06:00
|
|
|
function ts_lock {
|
|
|
|
local resource="$1"
|
|
|
|
local lockfile="${TS_LOCKDIR}/${resource}.lock"
|
2017-12-07 07:41:08 -06:00
|
|
|
local fd
|
2017-12-06 07:21:38 -06:00
|
|
|
|
|
|
|
if [ "$TS_NOLOCKS" == "yes" ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
2017-12-07 07:41:08 -06:00
|
|
|
# Don't lock again
|
2018-03-08 04:45:30 -06:00
|
|
|
fd=$(ts_get_lock_fd "$resource")
|
2017-12-07 07:41:08 -06:00
|
|
|
if [ -n "$fd" ]; then
|
2017-12-07 08:08:29 -06:00
|
|
|
echo "[$$ $TS_TESTNAME] ${resource} already locked!"
|
2017-12-07 07:41:08 -06:00
|
|
|
return 0
|
|
|
|
fi
|
2017-12-06 07:21:38 -06:00
|
|
|
|
2018-03-06 17:29:59 -06:00
|
|
|
fd=$(ts_find_free_fd) || ts_skip "failed to find lock fd"
|
2017-12-07 07:41:08 -06:00
|
|
|
|
|
|
|
eval "exec $fd>$lockfile"
|
2018-03-07 10:58:23 -06:00
|
|
|
flock --exclusive "$fd" || ts_skip "failed to lock $resource"
|
2017-12-07 07:41:08 -06:00
|
|
|
|
2018-03-08 04:45:30 -06:00
|
|
|
TS_LOCKFILE_FD["$fd"]="$resource"
|
2017-12-07 08:08:29 -06:00
|
|
|
###echo "[$$ $TS_TESTNAME] Locked $resource"
|
2017-12-06 07:21:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
function ts_unlock {
|
2017-12-07 07:41:08 -06:00
|
|
|
local resource="$1"
|
|
|
|
local lockfile="${TS_LOCKDIR}/${resource}.lock"
|
|
|
|
local fd
|
|
|
|
|
|
|
|
if [ "$TS_NOLOCKS" == "yes" ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
2018-03-08 04:45:30 -06:00
|
|
|
fd=$(ts_get_lock_fd "$resource")
|
2017-12-07 07:41:08 -06:00
|
|
|
if [ -n "$fd" ]; then
|
|
|
|
eval "exec $fd<&-"
|
2018-03-08 04:45:30 -06:00
|
|
|
TS_LOCKFILE_FD["$fd"]=""
|
2018-03-06 17:29:59 -06:00
|
|
|
###echo "[$$ $TS_TESTNAME] Unlocked $resource"
|
2018-03-07 10:51:35 -06:00
|
|
|
else
|
2018-03-08 04:45:30 -06:00
|
|
|
echo "[$$ $TS_TESTNAME] unlocking unlocked $resource!?"
|
2017-12-07 07:41:08 -06:00
|
|
|
fi
|
2017-12-06 07:21:38 -06:00
|
|
|
}
|
|
|
|
|
2013-04-12 09:36:33 -05:00
|
|
|
function ts_scsi_debug_init {
|
2014-05-11 15:48:16 -05:00
|
|
|
local devname
|
2016-03-09 05:26:38 -06:00
|
|
|
local t
|
2014-05-11 15:48:16 -05:00
|
|
|
TS_DEVICE="none"
|
2013-04-12 09:36:33 -05:00
|
|
|
|
2017-12-06 07:21:38 -06:00
|
|
|
ts_lock "scsi_debug"
|
|
|
|
|
2014-11-15 14:41:43 -06:00
|
|
|
# dry run is not really reliable, real modprobe may still fail
|
2014-05-21 18:37:17 -05:00
|
|
|
modprobe --dry-run --quiet scsi_debug &>/dev/null \
|
|
|
|
|| ts_skip "missing scsi_debug module (dry-run)"
|
2013-04-12 09:36:33 -05:00
|
|
|
|
2014-05-21 18:37:17 -05:00
|
|
|
# skip if still in use or removal of modules not supported at all
|
2016-10-21 06:01:55 -05:00
|
|
|
# We don't want a slow timeout here so we don't use ts_scsi_debug_rmmod!
|
2017-12-07 08:08:29 -06:00
|
|
|
modprobe -r scsi_debug &>/dev/null
|
|
|
|
if [ "$?" -eq 1 ]; then
|
|
|
|
ts_unlock "scsi_debug"
|
|
|
|
ts_skip "cannot remove scsi_debug module (rmmod)"
|
|
|
|
fi
|
2014-05-21 18:37:17 -05:00
|
|
|
|
2015-03-28 09:32:30 -05:00
|
|
|
modprobe -b scsi_debug "$@" &>/dev/null \
|
2014-05-21 18:37:17 -05:00
|
|
|
|| ts_skip "cannot load scsi_debug module (modprobe)"
|
|
|
|
|
|
|
|
# it might be still not loaded, modprobe.conf or whatever
|
2016-11-07 02:35:17 -06:00
|
|
|
lsmod 2>/dev/null | grep -q "^scsi_debug " \
|
2014-05-21 18:37:17 -05:00
|
|
|
|| ts_skip "scsi_debug module not loaded (lsmod)"
|
2013-04-12 09:36:33 -05:00
|
|
|
|
|
|
|
udevadm settle
|
|
|
|
|
2016-03-09 05:26:38 -06:00
|
|
|
# wait for device if udevadm settle does not work
|
|
|
|
for t in 0 0.02 0.05 0.1 1; do
|
|
|
|
sleep $t
|
2021-07-14 09:13:21 -05:00
|
|
|
devname=$(grep --no-messages --with-filename scsi_debug /sys/block/*/device/model) && break
|
2016-03-09 05:26:38 -06:00
|
|
|
done
|
2021-07-14 09:13:21 -05:00
|
|
|
[ -n "${devname}" ] || ts_skip "timeout waiting for scsi_debug device"
|
2015-03-28 09:32:30 -05:00
|
|
|
|
2016-03-09 05:26:38 -06:00
|
|
|
devname=$(echo $devname | awk -F '/' '{print $4}')
|
2014-05-11 15:48:16 -05:00
|
|
|
TS_DEVICE="/dev/${devname}"
|
2016-03-09 05:26:38 -06:00
|
|
|
|
|
|
|
# TODO validate that device is really up, for now just a warning on stderr
|
2016-10-21 06:01:55 -05:00
|
|
|
test -b $TS_DEVICE || echo "warning: scsi_debug device is still down" >&2
|
|
|
|
}
|
|
|
|
|
|
|
|
# automatically called once in ts_cleanup_on_exit()
|
|
|
|
function ts_scsi_debug_rmmod {
|
|
|
|
local err=1
|
|
|
|
local t
|
|
|
|
local lastmsg
|
|
|
|
|
2018-03-07 10:51:35 -06:00
|
|
|
# We must not run if we don't have the lock
|
|
|
|
ts_have_lock "scsi_debug" || return 0
|
|
|
|
|
2016-10-21 06:01:55 -05:00
|
|
|
# Return early most importantly in case we are not root or the module does
|
|
|
|
# not exist at all.
|
|
|
|
[ $UID -eq 0 ] || return 0
|
|
|
|
[ -n "$TS_DEVICE" ] || return 0
|
2016-11-07 02:35:17 -06:00
|
|
|
lsmod 2>/dev/null | grep -q "^scsi_debug " || return 0
|
2016-10-21 06:01:55 -05:00
|
|
|
|
|
|
|
udevadm settle
|
|
|
|
|
|
|
|
# wait for successful rmmod if udevadm settle does not work
|
|
|
|
for t in 0 0.02 0.05 0.1 1; do
|
|
|
|
sleep $t
|
|
|
|
lastmsg="$(modprobe -r scsi_debug 2>&1)" && err=0 && break
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ "$err" = "1" ]; then
|
|
|
|
ts_log "rmmod failed: '$lastmsg'"
|
|
|
|
ts_log "timeout removing scsi_debug module (rmmod)"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
if lsmod | grep -q "^scsi_debug "; then
|
|
|
|
ts_log "BUG! scsi_debug still loaded"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# TODO Do we need to validate that all devices are gone?
|
|
|
|
udevadm settle
|
|
|
|
test -b "$TS_DEVICE" && echo "warning: scsi_debug device is still up" >&2
|
|
|
|
|
|
|
|
# TODO unset TS_DEVICE, check that nobody uses it later, e.g. ts_fdisk_clean
|
|
|
|
|
2017-12-06 07:21:38 -06:00
|
|
|
ts_unlock "scsi_debug"
|
2016-10-21 06:01:55 -05:00
|
|
|
return 0
|
2013-04-12 09:36:33 -05:00
|
|
|
}
|
2014-06-11 12:28:20 -05:00
|
|
|
|
|
|
|
function ts_resolve_host {
|
|
|
|
local host="$1"
|
|
|
|
local tmp
|
|
|
|
|
|
|
|
# currently we just resolve default records (might be "A", ipv4 only)
|
|
|
|
if type "dig" >/dev/null 2>&1; then
|
|
|
|
tmp=$(dig "$host" +short 2>/dev/null) || return 1
|
|
|
|
elif type "nslookup" >/dev/null 2>&1; then
|
|
|
|
tmp=$(nslookup "$host" 2>/dev/null) || return 1
|
|
|
|
tmp=$(echo "$tmp"| grep -A1 "^Name:"| grep "^Address:"| cut -d" " -f2)
|
2014-07-24 14:28:44 -05:00
|
|
|
elif type "host" >/dev/null 2>&1; then
|
|
|
|
tmp=$(host "$host" 2>/dev/null) || return 1
|
|
|
|
tmp=$(echo "$tmp" | grep " has address " | cut -d " " -f4)
|
|
|
|
elif type "getent" >/dev/null 2>&1; then
|
|
|
|
tmp=$(getent ahosts "$host" 2>/dev/null) || return 1
|
|
|
|
tmp=$(echo "$tmp" | cut -d " " -f 1 | sort -u)
|
2014-06-11 12:28:20 -05:00
|
|
|
fi
|
|
|
|
|
|
|
|
# we return 1 if tmp is empty
|
|
|
|
test -n "$tmp" || return 1
|
|
|
|
echo "$tmp" | sort -R | head -n 1
|
|
|
|
}
|
2015-04-09 10:12:34 -05:00
|
|
|
|
|
|
|
# listen to unix socket (background socat)
|
|
|
|
function ts_init_socket_to_file {
|
|
|
|
local socket=$1
|
|
|
|
local outfile=$2
|
|
|
|
local pid="0"
|
|
|
|
|
|
|
|
ts_check_prog "socat"
|
|
|
|
rm -f "$socket" "$outfile"
|
|
|
|
|
2016-03-09 11:15:25 -06:00
|
|
|
# if socat is too old for these options we'll skip it below
|
2015-04-09 10:12:34 -05:00
|
|
|
socat -u UNIX-LISTEN:$socket,fork,max-children=1,backlog=128 \
|
2016-03-09 11:15:25 -06:00
|
|
|
STDOUT > "$outfile" 2>/dev/null &
|
2015-04-09 10:12:34 -05:00
|
|
|
pid=$!
|
|
|
|
|
|
|
|
# check for running background process
|
2016-03-09 11:15:25 -06:00
|
|
|
if [ "$pid" -le "0" ] || ! kill -s 0 "$pid" &>/dev/null; then
|
2015-04-09 10:12:34 -05:00
|
|
|
ts_skip "unable to run socat"
|
|
|
|
fi
|
|
|
|
# wait for the socket listener
|
2016-03-09 11:15:25 -06:00
|
|
|
if ! socat -u /dev/null UNIX-CONNECT:$socket,retry=30,interval=0.1 &>/dev/null; then
|
|
|
|
kill -9 "$pid" &>/dev/null
|
|
|
|
ts_skip "timeout waiting for socat socket"
|
2015-04-09 10:12:34 -05:00
|
|
|
fi
|
|
|
|
# check socket again
|
2016-03-09 11:15:25 -06:00
|
|
|
if ! socat -u /dev/null UNIX-CONNECT:$socket &>/dev/null; then
|
|
|
|
kill -9 "$pid" &>/dev/null
|
|
|
|
ts_skip "socat socket stopped listening"
|
2015-04-09 10:12:34 -05:00
|
|
|
fi
|
|
|
|
}
|
2016-04-15 07:10:23 -05:00
|
|
|
|
|
|
|
function ts_has_mtab_support {
|
|
|
|
grep -q '#define USE_LIBMOUNT_SUPPORT_MTAB' ${top_builddir}/config.h
|
|
|
|
if [ $? == 0 ]; then
|
|
|
|
echo "yes"
|
|
|
|
else
|
|
|
|
echo "no"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-06-09 05:10:33 -05:00
|
|
|
function ts_has_ncurses_support {
|
|
|
|
grep -q '#define HAVE_LIBNCURSES' ${top_builddir}/config.h
|
|
|
|
if [ $? == 0 ]; then
|
|
|
|
echo "yes"
|
|
|
|
else
|
|
|
|
echo "no"
|
|
|
|
fi
|
|
|
|
}
|
ci: deal with uninstrumented binaries using instrumented libs
All `eject` tests were failing under ASan, since they call /bin/mount,
which is uninstrumented, but it picks up the instrumented `libblkid`
library, causing ASan to complain:
gcc:
ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.
eject: unmount of `/home/runner/work/util-linux/util-linux/tests/output/eject/umount-by-disk-mounted-mnt' failed
clang:
/bin/umount: symbol lookup error: /home/runner/work/util-linux/util-linux/.libs/libblkid.so.1: undefined symbol: __sancov_lowest_stack
eject: unmount of `/home/runner/work/util-linux/util-linux/tests/output/eject/umount-by-disk-mounted-mnt' failed
Subsequently, all tests which require the `scsi_debug` module get skipped,
since it's still in use due to the failed umount:
fdisk: align 512/4K ... SKIPPED (cannot remove scsi_debug module (rmmod))
fdisk: align 512/4K +alignment_offset ... SKIPPED (cannot remove scsi_debug module (rmmod))
fdisk: align 512/4K +MD ... SKIPPED (cannot remove scsi_debug module (rmmod))
In case of gcc this can be easily resolved by setting $LD_PRELOAD to the
respective ASan library. clang makes this a bit more difficult, since it
compiles the ASan library statically, so firstly we need to force dynamic
linking (via -shared-asan), and then add the runtime DSO path to the
linker cache, since it's in a non-standard path.
2021-01-29 15:01:02 -06:00
|
|
|
|
|
|
|
# Get path to the ASan runtime DSO the given binary was compiled with
|
|
|
|
function ts_get_asan_rt_path {
|
|
|
|
local binary="${1?}"
|
|
|
|
local rt_path
|
|
|
|
|
|
|
|
ts_check_prog "ldd"
|
|
|
|
ts_check_prog "awk"
|
|
|
|
|
|
|
|
rt_path="$(ldd "$binary" | awk '/lib.+asan.*.so/ {print $3; exit}')"
|
|
|
|
if [ -n "$rt_path" -a -f "$rt_path" ]; then
|
|
|
|
echo "$rt_path"
|
|
|
|
fi
|
|
|
|
}
|