2013-06-10 13:28:47 +04:00
#!/usr/bin/env bash
2012-03-20 14:51:57 +04:00
# Copyright (C) 2011-2012 Red Hat, Inc. All rights reserved.
2011-01-05 03:16:18 +03:00
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
2016-01-21 13:49:46 +03:00
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2011-01-05 03:16:18 +03:00
set -e
2011-01-05 03:26:19 +03:00
MAX_TRIES = 4
2012-03-20 14:51:57 +04:00
IFS_NL = '
'
2011-01-05 03:26:19 +03:00
2012-03-16 16:59:43 +04:00
die( ) {
2013-09-16 13:05:03 +04:00
rm -f debug.log
echo -e " $@ " >& 2
2012-03-16 16:59:43 +04:00
return 1
}
rand_bytes( ) {
n = $1
2011-01-05 03:26:19 +03:00
2012-03-16 16:59:43 +04:00
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
2011-01-05 03:26:19 +03:00
2012-03-16 16:59:43 +04:00
dev_rand = "/dev/urandom"
if test -r " $dev_rand " ; then
# Note: 256-length($chars) == 194; 3 copies of $chars is 186 + 8 = 194.
head -c" $n " " $dev_rand " | tr -c " $chars " " 01234567 $chars $chars $chars "
return
fi
2011-01-05 03:26:19 +03:00
2012-03-16 16:59:43 +04:00
cmds = 'date; date +%N; free; who -a; w; ps auxww; ps ef; netstat -n'
data = $( ( eval " $cmds " ) 2>& 1 | gzip )
2011-01-05 03:26:19 +03:00
2017-06-29 11:12:21 +03:00
n_plus_50 = $(( n + 50 ))
2011-01-05 03:26:19 +03:00
2012-03-16 16:59:43 +04:00
# Ensure that $data has length at least 50+$n
while :; do
len = $( echo " $data " | wc -c)
2017-06-29 11:12:21 +03:00
test " $n_plus_50 " -le " $len " && break;
2012-03-16 16:59:43 +04:00
data = $( ( echo " $data " ; eval " $cmds " ) 2>& 1 | gzip )
done
2011-01-05 03:26:19 +03:00
2017-06-29 11:12:21 +03:00
echo " $data " | dd bs = 1 skip = 50 count = " $n " 2>/dev/null \
2012-03-16 16:59:43 +04:00
| tr -c " $chars " " 01234567 $chars $chars $chars "
2011-01-05 03:26:19 +03:00
}
2012-03-16 16:59:43 +04:00
mkdtemp( ) {
case $# in
2) ; ;
*) die "Usage: mkdtemp DIR TEMPLATE" ; ;
esac
destdir = $1
template = $2
2015-03-05 23:00:44 +03:00
test -d " $destdir " || die " DIR (' $destdir ') does not exist. "
2012-03-16 16:59:43 +04:00
case " $template " in
*XXXX) ; ;
*) die " Invalid template: $template (must have a suffix of at least 4 X's) " ; ;
esac
fail = 0
# First, try to use mktemp.
2012-03-20 14:51:57 +04:00
d = $( env -u TMPDIR mktemp -d -t -p " $destdir " " $template " 2>/dev/null) || fail = 1
2012-03-16 16:59:43 +04:00
# The resulting name must be in the specified directory.
case " $d " in " ${ destdir } " *) ; ; *) fail = 1; ; esac
# It must have created the directory.
test -d " $d " || fail = 1
# It must have 0700 permissions.
perms = $( ls -dgo " $d " 2>/dev/null) || fail = 1
case " $perms " in drwx------*) ; ; *) fail = 1; ; esac
test $fail = 0 && { echo " $d " ; return ; }
# If we reach this point, we'll have to create a directory manually.
# Get a copy of the template without its suffix of X's.
base_template = $( echo " $template " | sed 's/XX*$//' )
# Calculate how many X's we've just removed.
nx = $( expr length " $template " - length " $base_template " )
err =
i = 1
while :; do
X = $( rand_bytes " $nx " )
candidate_dir = " $destdir / $base_template $X "
err = $( mkdir -m 0700 " $candidate_dir " 2>& 1) && \
{ echo " $candidate_dir " ; return ; }
test $MAX_TRIES -le $i && break;
2017-06-29 11:19:32 +03:00
i = $(( i + 1 ))
2012-03-16 16:59:43 +04:00
done
die " $err "
2011-01-05 03:26:19 +03:00
}
2015-04-09 14:13:36 +03:00
# Like grep, just always print 1st. line
grep1_( ) {
awk -v pattern = " ${ 1 } " 'NR==1 || $0~pattern' " ${ @ : 2 } "
}
2015-11-19 14:11:58 +03:00
stacktrace( ) {
2012-03-16 16:59:43 +04:00
trap - ERR
2017-07-14 20:51:59 +03:00
# i=1 - ignoring innermost frame - it is always stacktrace function
local i = 1 n = ${# BASH_LINENO [*] }
# n-=1 - ignoring last frame as well - it is not interesting
let n-= 1
echo " ## - $0 : ${ BASH_LINENO [ $(( n-1)) ] } "
while [ [ $i -lt $n ] ] ; do
echo " ## $i ${ FUNCNAME [ $i ] } () called from ${ BASH_SOURCE [ $(( i+1)) ] } : ${ BASH_LINENO [ $i ] } "
2017-06-29 11:19:32 +03:00
i = $(( i + 1 ))
2011-01-05 03:16:18 +03:00
done
2015-11-19 14:11:58 +03:00
}
STACKTRACE( ) {
trap - ERR
2017-06-30 15:28:44 +03:00
local i
2015-11-19 14:11:58 +03:00
stacktrace
2011-01-05 03:16:18 +03:00
2017-07-12 14:38:07 +03:00
test " ${ LVM_TEST_PARALLEL :- 0 } " -eq 0 && test -z " $RUNNING_DMEVENTD " && \
test ! -f LOCAL_DMEVENTD && pgrep dmeventd >DPID 2>/dev/null && {
echo " ## ERROR: The test started dmeventd ( $( < DPID) ) unexpectedly. "
kill " $( < DPID) "
}
2012-03-16 16:59:43 +04:00
# Get backtraces from coredumps
if which gdb & >/dev/null; then
2017-06-30 15:35:42 +03:00
{
echo bt full
echo l
echo quit
} > gdb_commands.txt
2017-07-15 01:12:07 +03:00
# Check for all cores newer then TESTNAME file
# Assume users keep prefix 'core'
2017-07-16 11:33:48 +03:00
# TODO: possibly better integrate with coredumpctl & systemd
2017-07-15 01:12:07 +03:00
while IFS = read -r i; do
2017-06-30 15:28:44 +03:00
bin = $( gdb -batch -c " $i " 2>& 1 | grep "generated by" | \
sed -e "s,.*generated by \`\([^ ']*\).*,\1," ) || continue
2017-07-15 01:12:07 +03:00
echo " ## Checking coredump: $i generated by $bin . "
gdb -batch -c " $i " -x gdb_commands.txt " $( which " $bin " ) " 2>/dev/null | \
sed -e "s,^,## GDB: ," || continue
2017-07-16 11:33:48 +03:00
done < <( find . " $( dirname " $( sysctl -n kernel.core_pattern) " ) " \
"/var/lib/systemd/coredump/" -name 'core*' -newer TESTNAME 2>/dev/null || true )
2012-03-16 16:59:43 +04:00
fi
2015-04-14 15:56:15 +03:00
test -f SKIP_THIS_TEST && exit 200
2017-07-07 22:31:38 +03:00
test -z " $LVM_TEST_NODEBUG " && test -f TESTNAME && {
2015-04-20 11:05:27 +03:00
local name
2017-07-12 02:50:06 +03:00
local idx = 0
2015-04-13 17:30:17 +03:00
for i in debug.log* ; do
2016-04-21 00:19:33 +03:00
test -f " $i " || break # nothing is found (expands to debug.log*)
2015-04-20 11:05:27 +03:00
name = ${ i ##debug.log_ }
name = ${ name %%_* }
2017-06-29 11:19:32 +03:00
test " $name " = "DEBUG" && { name = " $name $idx " ; idx = $(( idx + 1 )) ; }
2015-04-20 11:05:27 +03:00
echo " <======== Debug log $i ========> "
2016-04-21 00:19:33 +03:00
sed -e " s,^,## $name : , " " $i "
2015-04-07 14:40:15 +03:00
done
2015-04-14 15:56:15 +03:00
if test -e strace.log ; then
2015-04-13 17:30:17 +03:00
echo "<======== Strace debug log ========>"
sed -e "s,^,## STRACE: ," strace.log
2015-04-14 15:56:15 +03:00
fi
dmsetup info -c | grep1_ " $PREFIX " > out
2017-06-29 11:12:21 +03:00
if test " $( wc -l < out) " -gt 1 ; then
2015-04-14 15:56:15 +03:00
echo "<======== Info ========>"
sed -e "s,^,## DMINFO: ," out
echo "<======== Active table ========>"
dmsetup table | grep " $PREFIX " | sed -e "s,^,## DMTABLE: ,"
echo "<======== Inactive table ========>"
dmsetup table --inactive | grep " $PREFIX " | sed -e "s,^,## DMITABLE: ,"
echo "<======== Status ========>"
2017-11-10 18:18:41 +03:00
dmsetup status --noflush | grep " $PREFIX " | sed -e "s,^,## DMSTATUS: ,"
2015-04-14 15:56:15 +03:00
echo "<======== Tree ========>"
dmsetup ls --tree | sed -e "s,^,## DMTREE: ,"
echo " <======== Recursive list of $DM_DEV_DIR ========> "
ls -Rl --hide= shm --hide= bus --hide= snd --hide= input --hide= dri \
--hide= net --hide= hugepages --hide= mqueue --hide= pts \
" $DM_DEV_DIR " | sed -e "s,^,## LSLR: ,"
echo "<======== Udev DB content ========>"
for i in /sys/block/dm-* /sys/block/loop* ; do
2015-05-08 21:44:43 +03:00
udevadm info --query= all --path " $i " 2>/dev/null || true
2015-04-14 15:56:15 +03:00
done | sed -e "s,^,## UDEV: ,"
fi
2015-04-13 17:30:17 +03:00
echo " <======== Script file \" $( < TESTNAME) \" ========> "
2015-04-14 10:48:57 +03:00
local script = $0
test -f " $script " || script = " $TESTOLDPWD / $0 "
awk '{print "## Line:", NR, "\t", $0}' " $script "
2012-03-16 16:59:43 +04:00
}
2011-01-05 03:16:18 +03:00
}
init_udev_transaction( ) {
2012-03-16 16:59:43 +04:00
if test " $DM_UDEV_SYNCHRONISATION " = 1; then
2017-06-29 22:22:52 +03:00
local cookie
cookie = $( dmsetup udevcreatecookie)
2012-03-16 16:59:43 +04:00
# Cookie is not generated if udev is not running!
test -z " $cookie " || export DM_UDEV_COOKIE = $cookie
2011-01-05 03:16:18 +03:00
fi
}
finish_udev_transaction( ) {
2017-07-07 22:31:38 +03:00
if test " $DM_UDEV_SYNCHRONISATION " = 1 && test -n " $DM_UDEV_COOKIE " ; then
2012-03-16 16:59:43 +04:00
dmsetup udevreleasecookie
unset DM_UDEV_COOKIE
fi
2011-01-05 03:16:18 +03:00
}
2011-06-29 22:18:18 +04:00
teardown_udev_cookies( ) {
2012-03-16 16:59:43 +04:00
if test " $DM_UDEV_SYNCHRONISATION " = 1; then
# Delete any cookies created more than 10 minutes ago
# and not used in the last 10 minutes.
# Log only non-zero semaphores count
( dmsetup udevcomplete_all -y 10 | grep -v "^0 " ) || true
fi
2011-06-29 22:18:18 +04:00
}
2012-03-28 15:10:08 +04:00
dm_info( ) {
2014-06-05 14:09:02 +04:00
should dmsetup info --noheadings -c -o " $@ "
2012-03-28 15:10:08 +04:00
}
dm_table( ) {
should dmsetup table " $@ "
}
2011-01-07 18:04:52 +03:00
skip( ) {
2016-09-20 18:09:46 +03:00
set +vx # debug off
2015-11-19 14:11:58 +03:00
if test " $# " -eq 0; then
stacktrace
else
2017-06-29 11:14:59 +03:00
echo "TEST SKIPPED:" " $@ "
2015-11-19 14:11:58 +03:00
fi
2012-03-16 16:59:43 +04:00
touch SKIP_THIS_TEST
exit 200
2011-01-07 18:04:52 +03:00
}
2014-06-04 15:55:13 +04:00
get_devs( ) {
local IFS = $IFS_NL
DEVICES = ( $( <DEVICES) )
export DEVICES
# local DEVS=( $(<DEVICES) )
# eval "$1"'=("${DEVS[@]}")'
}
2012-03-16 16:59:43 +04:00
prepare_test_vars( ) {
vg = " ${ PREFIX } vg "
lv = LV
2011-06-09 22:58:00 +04:00
2017-07-09 14:38:37 +03:00
for i in { 1..16} ; do
eval " dev $i =\" $DM_DEV_DIR /mapper/ ${ PREFIX } pv $i \" "
eval " lv $i =\"LV $i \" "
eval " vg $i =\" ${ PREFIX } vg $i \" "
2012-03-16 16:59:43 +04:00
done
2011-06-09 22:58:00 +04:00
}
2014-06-27 02:59:17 +04:00
if test -z " ${ abs_top_builddir +varset } " && test -z " ${ installed_testsuite +varset } " ; then
. lib/paths || die "something went wrong -- lib/paths is missing?"
fi
if test -z " ${ installed_testsuite +varset } " ; then
case " $PATH " in
*" $abs_top_builddir /test/lib " *) ; ;
*)
2017-06-29 11:12:21 +03:00
PATH = " $abs_top_builddir /test/lib: $abs_top_builddir /test/api: $PATH "
2017-03-31 16:27:58 +03:00
LD_LIBRARY_PATH = $( find -L " $abs_top_builddir /libdm/ " " $abs_top_builddir /tools/ " \
" $abs_top_builddir /daemons/ " " $abs_top_builddir /liblvm/ " \
-name "*.so" -printf "%h:" ) " $LD_LIBRARY_PATH "
export PATH LD_LIBRARY_PATH ; ;
2014-06-27 02:59:17 +04:00
esac
fi
2012-03-16 16:59:43 +04:00
test -z " $PREFIX " || prepare_test_vars