d34455a2d2
When tests timeout, the timeout command sends TERM signal to the command being executed. In the case of run-tests.sh it invokes prove, which further invokes perl and finally the test is run using bash. The TERM signal does not seem to be reachnig the end bash that is actually executing the tests, and hence when any test is terminated due to a timeout, the cleanup routine in include.rc does not get a chance to run and preserve the tarball. Further, cleanup invokes tarball generation, but is invoked at the beginning and end of every test, and at times in beteween as well. This caused way too many tarballs in case we decide to preserve the same whenever generated by cleanup. This patch hence moves the tarball generation to run-tests.sh instead, and further stores them named <test>-iteration-<n>.tar and also prints tarball name generated and stored per iteration. This should help relate failed runs to the tarball iteration # and to look at relevant logs. Further the patch also provides a -p option to run-tests.sh for unit testing purposes, where running a test in a loop without the option will generate as many tarballs, and using the option will reduce this to preserving the last tarball, saving space in smaller unit test setups. Fixes: bz#1614062 Change-Id: I0aee76c89df0691cf4d0c1fcd4c04dffe0d7c896 Signed-off-by: ShyamsundarR <srangana@redhat.com>
1306 lines
30 KiB
Plaintext
1306 lines
30 KiB
Plaintext
M0=${M0:=/mnt/glusterfs/0}; # 0th mount point for FUSE
|
|
M1=${M1:=/mnt/glusterfs/1}; # 1st mount point for FUSE
|
|
M2=${M2:=/mnt/glusterfs/2}; # 2nd mount point for FUSE
|
|
M3=${M3:=/mnt/glusterfs/3}; # 3rd mount point for FUSE
|
|
N0=${N0:=/mnt/nfs/0}; # 0th mount point for NFS
|
|
N1=${N1:=/mnt/nfs/1}; # 1st mount point for NFS
|
|
V0=${V0:=patchy}; # volume name to use in tests
|
|
V1=${V1:=patchy1}; # volume name to use in tests
|
|
GMV0=${GMV0:=master}; # master volume name to use in geo-rep tests
|
|
GSV0=${GSV0:=slave}; # slave volume name to use in geo-rep tests
|
|
B0=${B0:=/d/backends}; # top level of brick directories
|
|
WORKDIRS="$B0 $M0 $M1 $M2 $M3 $N0 $N1"
|
|
|
|
ROOT_GFID="00000000-0000-0000-0000-000000000001"
|
|
DOT_SHARD_GFID="be318638-e8a0-4c6d-977d-7a937aa84806"
|
|
|
|
META_VOL=${META_VOL:=gluster_shared_storage}; # shared gluster storage volume used by snapshot scheduler, nfs ganesha and geo-rep.
|
|
META_MNT=${META_MNT:=/var/run/gluster/shared_storage}; # Mount point of shared gluster volume.
|
|
|
|
CC=cc
|
|
OSTYPE=$(uname -s)
|
|
|
|
env_dir=$(dirname $0)
|
|
while true; do
|
|
ENV_RC=${env_dir}/env.rc
|
|
if [ -f ${ENV_RC} ]; then
|
|
break
|
|
fi
|
|
new_dir=$(dirname $env_dir)
|
|
if [ x"$new_dir" = x"$old_dir" ]; then
|
|
ENV_RC="/not/found"
|
|
break
|
|
fi
|
|
old_dir=$env_dir
|
|
env_dir=$new_dir
|
|
done
|
|
|
|
if [ ! -f $ENV_RC ]; then
|
|
echo "Aborting." | tee /dev/stderr
|
|
echo | tee /dev/stderr
|
|
echo "env.rc not found" | tee /dev/stderr
|
|
echo | tee /dev/stderr
|
|
echo "Please correct the problem and try again." | tee /dev/stderr
|
|
echo | tee /dev/stderr
|
|
exit 1
|
|
fi
|
|
. $ENV_RC
|
|
|
|
H0=${H0:=`hostname`}; # hostname
|
|
MOUNT_TYPE_FUSE="fuse.glusterfs"
|
|
GREP_MOUNT_OPT_RO="grep (ro"
|
|
GREP_MOUNT_OPT_RW="grep (rw"
|
|
UMOUNT_F="umount -f"
|
|
|
|
PATH=$PATH:${PWD}/tests/utils
|
|
|
|
case $OSTYPE in
|
|
Linux)
|
|
H0=${H0:=`hostname --fqdn`}; # hostname
|
|
;;
|
|
NetBSD)
|
|
MOUNT_TYPE_FUSE="puffs|perfuse|fuse.glusterfs"
|
|
GREP_MOUNT_OPT_RO="grep (read-only"
|
|
GREP_MOUNT_OPT_RW="grep -v (read-only"
|
|
UMOUNT_F="umount -f -R"
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
DEBUG=${DEBUG:=0} # turn on debugging?
|
|
|
|
PROCESS_DOWN_TIMEOUT=5
|
|
PROCESS_UP_TIMEOUT=45
|
|
NFS_EXPORT_TIMEOUT=20
|
|
CHILD_UP_TIMEOUT=20
|
|
PROBE_TIMEOUT=60
|
|
PEER_SYNC_TIMEOUT=20
|
|
REBALANCE_TIMEOUT=360
|
|
REOPEN_TIMEOUT=20
|
|
HEAL_TIMEOUT=80
|
|
IO_HEAL_TIMEOUT=120
|
|
MARKER_UPDATE_TIMEOUT=20
|
|
JANITOR_TIMEOUT=60
|
|
UMOUNT_TIMEOUT=5
|
|
CONFIG_UPDATE_TIMEOUT=5
|
|
AUTH_REFRESH_INTERVAL=10
|
|
GRAPH_SWITCH_TIMEOUT=10
|
|
UNLINK_TIMEOUT=5
|
|
MDC_TIMEOUT=5
|
|
IO_WAIT_TIMEOUT=5
|
|
|
|
LOGDIR=$(gluster --print-logdir)
|
|
|
|
statedumpdir=`gluster --print-statedumpdir`; # Default directory for statedump
|
|
|
|
CLI="gluster --mode=script --wignore";
|
|
CLI_NO_FORCE="gluster --mode=script";
|
|
|
|
# CLI_IGNORE_PARTITION makes sure that the warning related to bricks being on
|
|
# root partition is ignored while running the command in a "no force" mode
|
|
CLI_IGNORE_PARTITION="gluster --mode=script --wignore-partition"
|
|
|
|
function wait_delay() {
|
|
local delay="$1"
|
|
local interval="$2"
|
|
shift 2
|
|
local deadline="$(($(date +%s%N) + ${delay}000000000))"
|
|
|
|
$*
|
|
while [[ $? -ne 0 ]]; do
|
|
if [[ $(date +%s%N) -ge ${deadline} ]]; then
|
|
return 1
|
|
fi
|
|
sleep ${interval}
|
|
$*
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
_GFS () {
|
|
glusterfs "$@"
|
|
local mount_ret=$?
|
|
if [ $mount_ret != 0 ]; then
|
|
return $mount_ret
|
|
fi
|
|
local mount_point=${!#}
|
|
local i=0
|
|
while true; do
|
|
touch $mount_point/xy_zzy 2> /dev/null && break
|
|
i=$((i+1))
|
|
[ $i -lt 10 ] || break
|
|
sleep 1
|
|
done
|
|
rm -f $mount_point/xy_zzy
|
|
return $mount_ret
|
|
}
|
|
GFS="_GFS --attribute-timeout=0 --entry-timeout=0";
|
|
|
|
mkdir -p $WORKDIRS
|
|
|
|
case $OSTYPE in
|
|
FreeBSD | Darwin)
|
|
wc () {
|
|
if test "x$1" = "x-l"; then
|
|
awk '{ lines++ } END {print lines}'
|
|
fi
|
|
if test "x$1" = "x-w"; then
|
|
awk '{ words += NF } END {print words}' }
|
|
fi
|
|
if test "x$1" = "x-c"; then
|
|
awk '{ chars += length($0) + 1 } END {print chars}'
|
|
fi
|
|
if test "x$1" = "x-m"; then
|
|
awk '{ chars += length($0) + 1 } END {print chars}'
|
|
fi
|
|
}
|
|
;;
|
|
NetBSD)
|
|
wc() {
|
|
/usr/bin/wc $@ | sed 's/^ *\([0-9]*\).*$/\1/g'
|
|
}
|
|
;;
|
|
esac
|
|
|
|
testcnt=`egrep '^[[:space:]]*(EXPECT|EXPECT_NOT|TEST|EXPECT_WITHIN|EXPECT_KEYWORD)[[:space:]]' $0 | wc -l`
|
|
expect_tests=`egrep '^[[:space:]]*TESTS_EXPECTED_IN_LOOP[[:space:]]*' $0`
|
|
|
|
x_ifs=$IFS
|
|
IFS=$'\n'
|
|
for line in $expect_tests; do
|
|
expect_tests=`echo $line | cut -f 2 -d =`
|
|
testcnt=`expr $testcnt + $expect_tests`
|
|
done
|
|
IFS=$x_ifs
|
|
|
|
echo "1..`echo $testcnt`"
|
|
|
|
t=1
|
|
|
|
function dbg()
|
|
{
|
|
[ "x$DEBUG" = "x0" ] || echo "$*" >&2;
|
|
}
|
|
|
|
function G_LOG()
|
|
{
|
|
local g_log_logdir;
|
|
g_log_logdir=`$CLI --print-logdir`
|
|
test -d $g_log_logdir
|
|
if [ $? != 0 ]; then
|
|
return
|
|
fi
|
|
local g_log_string;
|
|
g_log_string="++++++++++ G_LOG:$0: TEST: $@ ++++++++++"
|
|
g_log_string="`date -u +["%F %T.%6N"]`:$g_log_string"
|
|
local g_log_filename
|
|
for g_log_filename in `find $g_log_logdir/ -type f -name \*.log`;
|
|
do
|
|
echo "$g_log_string" >> "$g_log_filename"
|
|
done
|
|
}
|
|
|
|
function test_header()
|
|
{
|
|
dbg "=========================";
|
|
dbg "TEST $t (line $TESTLINE): $*";
|
|
saved_cmd="$*"
|
|
}
|
|
|
|
|
|
function test_footer()
|
|
{
|
|
RET=$?
|
|
local lineno=$1
|
|
local err=$2
|
|
|
|
if [ $RET -eq 0 ]; then
|
|
echo "ok $t, LINENUM:$lineno";
|
|
else
|
|
echo "not ok $t $err, LINENUM:$lineno";
|
|
# With DEBUG, this was already printed out, so skip it.
|
|
if [ x"$DEBUG" = x"0" ]; then
|
|
echo "FAILED COMMAND: $saved_cmd"
|
|
fi
|
|
if [ "$EXIT_EARLY" = "1" ]; then
|
|
cleanup
|
|
exit $RET
|
|
fi
|
|
fi
|
|
|
|
dbg "RESULT $t: $RET";
|
|
|
|
t=`expr $t + 1`;
|
|
}
|
|
|
|
function test_expect_footer()
|
|
{
|
|
local lineno=$1
|
|
local e=$2
|
|
local a=$3
|
|
local err=""
|
|
|
|
if ! [[ "$a" =~ $e ]]; then
|
|
err="Got \"$a\" instead of \"$e\""
|
|
fi
|
|
[[ "$a" =~ $e ]];
|
|
|
|
test_footer "$lineno" "$err";
|
|
}
|
|
|
|
function _EXPECT()
|
|
{
|
|
TESTLINE=$1;
|
|
shift;
|
|
local a=""
|
|
|
|
G_LOG $TESTLINE "$@";
|
|
test_header "$@";
|
|
|
|
e="$1";
|
|
shift;
|
|
a=$("$@" | tail -1)
|
|
|
|
if [ "x$e" = "x" ] ; then
|
|
test_expect_footer "$TESTLINE" "x$e" "x$a";
|
|
else
|
|
test_expect_footer "$TESTLINE" "$e" "$a";
|
|
fi
|
|
}
|
|
|
|
function test_expect_not_footer()
|
|
{
|
|
local lineno=$1
|
|
local e=$2
|
|
local a=$3
|
|
local err=""
|
|
|
|
if [[ "$a" =~ $e ]]; then
|
|
err="Got \"$a\" when not expecting it"
|
|
fi
|
|
|
|
! [[ "$a" =~ $e ]];
|
|
test_footer "$lineno" "$err";
|
|
}
|
|
|
|
function _EXPECT_NOT()
|
|
{
|
|
TESTLINE=$1;
|
|
shift;
|
|
local a=""
|
|
|
|
G_LOG $TESTLINE "$@";
|
|
test_header "$@";
|
|
|
|
e="$1";
|
|
shift;
|
|
a=$("$@" | tail -1)
|
|
|
|
if [ "x$e" = "x" ] ; then
|
|
test_expect_not_footer "$TESTLINE" "x$e" "x$a";
|
|
else
|
|
test_expect_not_footer "$TESTLINE" "$e" "$a";
|
|
fi
|
|
}
|
|
|
|
function _EXPECT_KEYWORD()
|
|
{
|
|
TESTLINE=$1;
|
|
shift;
|
|
G_LOG $TESTLINE "$@";
|
|
test_header "$@";
|
|
|
|
e="$1";
|
|
shift;
|
|
"$@" | tail -1 | grep -q "$e"
|
|
|
|
test_footer "$TESTLINE";
|
|
}
|
|
|
|
function _TEST()
|
|
{
|
|
TESTLINE=$1;
|
|
shift;
|
|
local redirect=""
|
|
|
|
G_LOG $TESTLINE "$@";
|
|
test_header "$@";
|
|
|
|
if [ "$1" = "!" ]; then
|
|
redirect="2>&1"
|
|
fi
|
|
|
|
eval "$@" >/dev/null $redirect
|
|
|
|
test_footer "$TESTLINE";
|
|
}
|
|
|
|
#This function should be used carefully.
|
|
#The expected regex, given to this function, should be
|
|
#used within ^ and $ to match exactly with the output of
|
|
#command.
|
|
function _EXPECT_WITHIN()
|
|
{
|
|
TESTLINE=$1
|
|
shift;
|
|
|
|
local timeout=$1
|
|
shift;
|
|
|
|
G_LOG $TESTLINE "$@";
|
|
test_header "$@"
|
|
|
|
e=$1;
|
|
a="";
|
|
shift;
|
|
|
|
local endtime=$(( ${timeout}+`date +%s` ))
|
|
|
|
# We *want* this to be globally visible.
|
|
EW_RETRIES=0
|
|
|
|
while [ `date +%s` -lt $endtime ]; do
|
|
a=$("$@" | tail -1 ; exit ${PIPESTATUS[0]})
|
|
## Check command success
|
|
if [ $? -ne 0 ]; then
|
|
break;
|
|
fi
|
|
## Check match success
|
|
if [[ "$a" =~ $e ]]; then
|
|
break;
|
|
fi
|
|
sleep 1;
|
|
EW_RETRIES=$((EW_RETRIES+1))
|
|
done
|
|
|
|
if [ "x$e" = "x" ] ; then
|
|
test_expect_footer "$TESTLINE" "x$e" "x$a";
|
|
else
|
|
test_expect_footer "$TESTLINE" "$e" "$a";
|
|
fi
|
|
}
|
|
|
|
|
|
function SKIP_TESTS()
|
|
{
|
|
dbg "Skipping tests $t-$testcnt";
|
|
while [ $t -le $testcnt ]; do
|
|
true ; test_footer;
|
|
done
|
|
}
|
|
|
|
|
|
function _TEST_IN_LOOP()
|
|
{
|
|
testcnt=`expr $testcnt + 1`;
|
|
_TEST $@
|
|
}
|
|
|
|
function _EXPECT_WITHIN_TEST_IN_LOOP()
|
|
{
|
|
testcnt=`expr $testcnt + 1`;
|
|
_EXPECT_WITHIN $@
|
|
}
|
|
|
|
which killall > /dev/null || {
|
|
killall() {
|
|
pkill $@
|
|
}
|
|
}
|
|
|
|
which pidof > /dev/null || {
|
|
pidof() {
|
|
$PYTHON pidof.py $@
|
|
}
|
|
}
|
|
|
|
stat -c %s /dev/null > /dev/null 2>&1 || {
|
|
stat() {
|
|
local format=""
|
|
local f=""
|
|
|
|
if [ "x$1" = "x-c" ] ; then
|
|
oformat=$2
|
|
shift
|
|
shift
|
|
files=$@
|
|
else
|
|
files=$@
|
|
fi
|
|
|
|
for f in $files ; do
|
|
format=$oformat
|
|
|
|
# %t/%T should return 0 for non devices.
|
|
case "${format}" in
|
|
*%t*|*%T*)
|
|
`which stat` -f '%HT' $f | grep -q 'Device$' || \
|
|
format=`echo "${format}" | sed 's/%t/0/g; s/%T/0/g;'`
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
if [ "x${format}" = "x" ] ; then
|
|
`which stat` $f
|
|
else
|
|
cmd=""
|
|
case $format in
|
|
*%u*) cmd="${cmd} s/%u/`$( which stat ) -f %u $f`/g;" ;&
|
|
*%g*) cmd="${cmd} s/%g/`$( which stat ) -f %g $f`/g;" ;&
|
|
*%a*) cmd="${cmd} s/%a/`$( which stat ) -f %p $f |
|
|
sed 's/^..//; s/^0//'`/g;" ;&
|
|
*%A*) cmd="${cmd} s/%A/`ls -ld $f|awk '{print $1}'`/g;" ;&
|
|
*%s*) cmd="${cmd} s/%s/`$( which stat ) -f %z $f`/g;" ;&
|
|
*%h*) cmd="${cmd} s/%h/`$( which stat ) -f %l $f`/g;" ;&
|
|
*%F*) cmd="${cmd} s/%F/`$( which stat ) -f %HT $f | sed '
|
|
s/Directory/directory/;
|
|
s/Fifo File/fifo/;
|
|
s/Symbolic Link/symbolic link/;
|
|
s/Regular File/regular file/;
|
|
s/Block Device/block special file/;
|
|
s/Character Device/character special file/;
|
|
' | sed \"$(
|
|
test -s $f || echo 's/regular file/regular empty file/g'
|
|
)\"`/g;" ;&
|
|
*%n*) cmd="${cmd} s|%n|`$( which stat ) -f %N $f`|g;" ;&
|
|
*%Y*) cmd="${cmd} s/%Y/`$( which stat ) -f %m $f`/g;" ;&
|
|
*%X*) cmd="${cmd} s/%X/`$( which stat ) -f %a $f`/g;" ;&
|
|
*%Z*) cmd="${cmd} s/%Z/`$( which stat ) -f %c $f`/g;" ;&
|
|
*%.Z*) cmd="${cmd} s/%.Z/`$( which stat ) -f %.9Fc $f`/g;" ;&
|
|
*%b*) cmd="${cmd} s/%b/`$( which stat ) -f %b $f`/g;" ;&
|
|
*%B*) cmd="${cmd} s/%B/512/g;" ;&
|
|
*%t*) cmd="${cmd} s/%t/`$( which stat ) -f %XHr $f`/g;" ;&
|
|
*%T*) cmd="${cmd} s/%T/`$( which stat ) -f %XLr $f`/g;" ;&
|
|
esac
|
|
|
|
`which stat` -f "`echo $format|sed \"$cmd\"`" $f
|
|
fi
|
|
done
|
|
}
|
|
}
|
|
|
|
function signal_pids() {
|
|
local sig="$1"
|
|
shift
|
|
local pids=($*)
|
|
|
|
if [[ ${#pids[@]} -gt 0 ]]; then
|
|
kill -${sig} ${pids[@]} 2>/dev/null || true
|
|
fi
|
|
}
|
|
|
|
function check_pids() {
|
|
local pids=($*)
|
|
local tmp=()
|
|
local pid
|
|
|
|
for pid in "${pids[@]}"; do
|
|
kill -0 "${pid}" 2>/dev/null && tmp+=(${pid})
|
|
done
|
|
|
|
echo "${tmp[@]}"
|
|
}
|
|
|
|
function pids_alive() {
|
|
local pids=($*)
|
|
|
|
if [[ "$(check_pids ${pids[@]})" != "" ]]; then
|
|
return 1;
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
function terminate_pids() {
|
|
local pids=($*)
|
|
|
|
signal_pids TERM ${pids[@]}
|
|
wait_delay ${PROCESS_DOWN_TIMEOUT} 0.1 pids_alive ${pids[@]}
|
|
if [[ $? -ne 0 ]]; then
|
|
pids=($(check_pids ${pids[@]}))
|
|
signal_pids KILL ${pids[@]}
|
|
wait_delay 1 0.1 pids_alive ${pids[@]}
|
|
if [[ $? -ne 0 ]]; then
|
|
return 2
|
|
fi
|
|
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
function process_pids() {
|
|
local proc
|
|
local pids=()
|
|
|
|
for proc in $*; do
|
|
pids+=($(pgrep ${proc}))
|
|
done
|
|
|
|
echo "${pids[@]}"
|
|
}
|
|
|
|
function cleanup()
|
|
{
|
|
|
|
# Prepare flags for umount
|
|
case `uname -s` in
|
|
Linux)
|
|
flag="-l"
|
|
;;
|
|
NetBSD)
|
|
flag="-f -R"
|
|
;;
|
|
FreeBSD|Darwin)
|
|
flag="-f"
|
|
;;
|
|
*)
|
|
flag=""
|
|
;;
|
|
esac
|
|
|
|
# Clean up all client mounts
|
|
for m in `mount | grep fuse.glusterfs | awk '{print $3}'`; do
|
|
umount $flag $m
|
|
done
|
|
|
|
# Unmount all well known mount points
|
|
umount $flag $M0 2>/dev/null || umount -f $M0 2>/dev/null || true;
|
|
umount $flag $M1 2>/dev/null || umount -f $M1 2>/dev/null || true;
|
|
umount $flag $M2 2>/dev/null || umount -f $M2 2>/dev/null || true;
|
|
umount $flag $N0 2>/dev/null || umount -f $N0 2>/dev/null || true;
|
|
umount $flag $N1 2>/dev/null || umount -f $N1 2>/dev/null || true;
|
|
|
|
|
|
# unmount all stale mounts from /tmp, This is a temporary work around
|
|
# till the stale mount in /tmp is found.
|
|
umount $flag /tmp/mnt* 2>/dev/null
|
|
|
|
|
|
# Send SIGTERM to all gluster processes and rpc.statd that are still running
|
|
terminate_pids $(process_pids glusterfs glusterfsd glusterd rpc.statd)
|
|
|
|
test x"$OSTYPE" = x"NetBSD" && pkill -9 perfused || true
|
|
|
|
# unregister nfs and related services from portmapper/rpcbind
|
|
## nfs
|
|
rpcinfo -d 100003 3 2>/dev/null || true;
|
|
## mountd
|
|
rpcinfo -d 100005 1 2>/dev/null || true;
|
|
rpcinfo -d 100005 3 2>/dev/null || true;
|
|
## nlockmgr
|
|
rpcinfo -d 100021 1 2>/dev/null || true;
|
|
rpcinfo -d 100021 4 2>/dev/null || true;
|
|
## nfs_acl
|
|
rpcinfo -d 100227 3 2>/dev/null || true;
|
|
|
|
# unmount brick filesystems after killing daemons
|
|
MOUNTPOINTS=`mount | grep "$B0/" | awk '{print $3}'`
|
|
for m in $MOUNTPOINTS;
|
|
do
|
|
umount $flag $m
|
|
done
|
|
|
|
# Cleanup lvm
|
|
type cleanup_lvm &>/dev/null && cleanup_lvm || true;
|
|
|
|
# Destroy loop devices
|
|
# TODO: This should be a function DESTROY_LOOP
|
|
case `uname -s` in
|
|
Linux)
|
|
LOOPDEVICES=`losetup -a | grep "$B0/" | \
|
|
awk '{print $1}' | tr -d :`
|
|
for l in $LOOPDEVICES;
|
|
do
|
|
losetup -d $l
|
|
done
|
|
;;
|
|
NetBSD)
|
|
# cleanup loopback device with unmounted backing store
|
|
for vnd in /dev/vnd* ; do
|
|
vnconfig -l ${vnd} 2>&1 | \
|
|
grep -q 'Bad file descriptor' && vnconfig -u ${vnd}
|
|
done
|
|
|
|
vnd=`vnconfig -l | \
|
|
awk '!/not in use/{printf("%s%s:%d ", $1, $2, $5);}'`
|
|
for l in ${vnd} ; do
|
|
dev=${l%%:*}
|
|
tmp=${l#*:}
|
|
fs=${tmp%%:*}
|
|
inode=${tmp#*:}
|
|
file=`find -x ${fs} -inum ${inode} -print -exit`
|
|
echo ${file} | grep "$B0/" && \
|
|
LOOPDEVICES="${LOOPDEVICES} $dev"
|
|
done
|
|
for l in $LOOPDEVICES;
|
|
do
|
|
vnconfig -u $l
|
|
done
|
|
;;
|
|
*)
|
|
echo "`uname -s` loopback device supportmissing"
|
|
;;
|
|
esac
|
|
|
|
# remove contents of "GLUSTERD_WORKDIR" except hooks and groups
|
|
# directories.
|
|
if [ -n $GLUSTERD_WORKDIR ]
|
|
then
|
|
find $GLUSTERD_WORKDIR/* -maxdepth 0 -name 'hooks' -prune \
|
|
-o -name 'groups' -prune -o -exec rm -rf '{}' ';'
|
|
else
|
|
echo "GLUSTERD_WORKDIR is not set"
|
|
fi
|
|
|
|
# Complete cleanup time
|
|
rm -rf "$B0/*" "/etc/glusterd/*";
|
|
rm -rf $WORKDIRS
|
|
find $GLUSTERD_PIDFILEDIR -name "*.pid" | xargs rm -rf
|
|
leftover=""
|
|
for d in $WORKDIRS ; do
|
|
if test -d $d ; then
|
|
leftover="$leftover $d"
|
|
fi
|
|
done
|
|
if [ "x$leftover" != "x" ] ; then
|
|
echo "Aborting."
|
|
echo
|
|
echo "$d could not be deleted, here are the left over items"
|
|
for d in $leftover; do
|
|
find $d -exec ls -ld {} \;
|
|
done
|
|
echo
|
|
echo "Please correct the problem and try again."
|
|
echo
|
|
return 1;
|
|
fi >&2
|
|
|
|
mkdir -p $WORKDIRS
|
|
# This is usually the last thing a test script calls, so our return
|
|
# value becomes their exit value. While it's not great for the mkdir
|
|
# above to fail, promoting that into a failure of the whole test (and
|
|
# thus of an entire regression-test run) seems a bit excessive. Make
|
|
# sure we return good status anyway.
|
|
|
|
return 0
|
|
}
|
|
|
|
function force_terminate () {
|
|
local ret=$?;
|
|
>&2 echo -e "\nreceived external"\
|
|
"signal --`kill -l $ret`--, calling 'cleanup' ...\n";
|
|
cleanup;
|
|
exit $ret;
|
|
}
|
|
|
|
trap force_terminate INT TERM HUP
|
|
|
|
function volinfo_field()
|
|
{
|
|
local vol=$1;
|
|
local field=$2;
|
|
|
|
$CLI volume info $vol | grep "^$field: " | sed 's/.*: //';
|
|
}
|
|
|
|
function cleanup_tester ()
|
|
{
|
|
local exe=$1
|
|
rm -f $exe
|
|
}
|
|
|
|
function build_tester ()
|
|
{
|
|
local cfile=$1
|
|
local fname=$(basename "$cfile")
|
|
local ext="${fname##*.}"
|
|
local execname="${fname%.*}"
|
|
shift
|
|
local cflags=$*
|
|
if [ `echo $cflags | grep -c "lgfapi" ` -gt 0 ]
|
|
then
|
|
cflags="$cflags $(pkg-config glusterfs-api --cflags-only-I --libs-only-L)"
|
|
fi
|
|
$CC -g -o $(dirname $cfile)/$execname $cfile $cflags
|
|
}
|
|
|
|
function process_leak_count ()
|
|
{
|
|
local pid=$1;
|
|
return $(ls -lh /proc/$pid/fd | grep "(deleted)"| wc -l)
|
|
}
|
|
|
|
which truncate > /dev/null || {
|
|
truncate() {
|
|
local nocreate=0
|
|
local ioblocks=0
|
|
local fileref=""
|
|
local newsize=""
|
|
|
|
args=`getopt xor:s: $*`
|
|
if [ $? -ne 0 ]; then
|
|
echo 'Usage: truncate [-co](-r file | -s size) file ...'
|
|
exit 2
|
|
fi
|
|
set -- $args
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
-c)
|
|
nocreate=1;
|
|
;;
|
|
-o)
|
|
ioblocks=1;
|
|
echo "Unimplemented -o option"
|
|
exit 2
|
|
;;
|
|
-r)
|
|
fileref=$2;
|
|
shift;
|
|
;;
|
|
-s)
|
|
newsize=$2;
|
|
shift;
|
|
;;
|
|
--)
|
|
shift;
|
|
break;
|
|
;;
|
|
*)
|
|
echo 'Usage: truncate [-co](-r file | -s size) file ...'
|
|
exit 2;
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ "x$newsize" = "x" -a "x$fileref" = "x" ] ; then
|
|
echo 'Usage: truncate [-co](-r file | -s size) file ...'
|
|
exit 2;
|
|
fi
|
|
|
|
if [ "x$newsize" != "x" -a "x$fileref" != "x" ] ; then
|
|
echo 'Usage: truncate [-co](-r file | -s size) file ...'
|
|
exit 2;
|
|
fi
|
|
|
|
if [ "x$newsize" != "x" ] ; then
|
|
echo $newsize | grep -q '^[-_<>%/]' && {
|
|
echo "Unimplemented prefix in ${newsize}"
|
|
exit 2;
|
|
}
|
|
|
|
echo $newsize | egrep -q '[TPEZY]B?$' && {
|
|
echo "Unit not implemented for ${newsize}"
|
|
exit 2;
|
|
}
|
|
|
|
case $newsize in
|
|
*KB)
|
|
newsize=$(( ${newsize/KB/} * 1000 ))
|
|
;;
|
|
*K)
|
|
newsize=$(( ${newsize/K/} * 1024 ))
|
|
;;
|
|
*MB)
|
|
newsize=$(( ${newsize/MB/} * 1000 * 1000 ))
|
|
;;
|
|
*M)
|
|
newsize=$(( ${newsize/M/} * 1024 * 1024 ))
|
|
;;
|
|
*GB)
|
|
newsize=$(( ${newsize/GB/} * 1000 * 1000 * 1000 ))
|
|
;;
|
|
*G)
|
|
newsize=$(( ${newsize/G/} * 1024 * 1024 * 1024 ))
|
|
;;
|
|
esac
|
|
|
|
fi
|
|
|
|
if [ "x$fileref" != "x" ] ; then
|
|
if [ ! -f $fileref ] ; then
|
|
echo "File does not exists: ${fileref}"
|
|
exit 2;
|
|
fi
|
|
newsize=`ls -l ${fileref}|awk '{print $5}'`
|
|
fi
|
|
|
|
if [ $# -eq 0 ]; then
|
|
echo 'Usage: truncate [-co](-r file | -s size) file ...'
|
|
exit 2;
|
|
fi
|
|
|
|
for f in $* ; do
|
|
if [ "x$nocreate" = "x1" -a ! -f $f ] ; then
|
|
continue;
|
|
fi
|
|
|
|
dd bs=1 seek=$newsize if=/dev/null of=$f msgfmt=quiet
|
|
done
|
|
}
|
|
}
|
|
|
|
which md5sum > /dev/null || {
|
|
md5sum() {
|
|
for f in $* ; do
|
|
md5 $f | awk -F'[() ]' '{printf("%s %s\n", $6, $3)}'
|
|
done
|
|
}
|
|
}
|
|
|
|
which setfattr > /dev/null || {
|
|
setfattr() {
|
|
$PYTHON setfattr.py $@
|
|
}
|
|
}
|
|
|
|
which getfattr > /dev/null || {
|
|
getfattr() {
|
|
$PYTHON getfattr.py $@
|
|
}
|
|
}
|
|
|
|
which sha1sum > /dev/null || {
|
|
sha1sum() {
|
|
case $OSTYPE in
|
|
Darwin)
|
|
for f in $* ; do
|
|
openssl sha1 $f | awk -F'[() ]' '{printf("%s %s\n", $4, $2)}'
|
|
done
|
|
;;
|
|
NetBSD | FreeBSD)
|
|
for f in $* ; do
|
|
sha1 $f | awk -F'[() ]' '{printf("%s %s\n", $6, $3)}'
|
|
done
|
|
;;
|
|
esac
|
|
}
|
|
}
|
|
|
|
userdel --help 2>/dev/null | grep -q -- '--force' || {
|
|
userdel() {
|
|
if [ "x$1" = "x--force" ]; then
|
|
user=$2
|
|
else
|
|
user=$1
|
|
fi
|
|
eval "$( which userdel ) $user"
|
|
}
|
|
}
|
|
|
|
useradd --help 2>/dev/null | grep -q -- '--no-create-home' || {
|
|
useradd() {
|
|
# Just remove -M (do not create home) which is the default
|
|
# other options are identical
|
|
args=`echo $*|sed 's/-M//'`
|
|
eval "$( which useradd ) $args"
|
|
}
|
|
}
|
|
|
|
userdel --help 2>/dev/null | grep -q -- '--force' || {
|
|
userdel() {
|
|
if [ "x$1" = "x--force" ]; then
|
|
user=$2
|
|
else
|
|
user=$1
|
|
fi
|
|
eval "$( which userdel ) $user"
|
|
}
|
|
}
|
|
|
|
useradd --help 2>/dev/null | grep -q -- '--no-create-home' || {
|
|
useradd() {
|
|
# Just remove -M (do not create home) which is the default
|
|
# other options are identical
|
|
args=`echo $*|sed 's/-M//'`
|
|
eval "$( which useradd ) $args"
|
|
}
|
|
}
|
|
|
|
DBG_TEST () {
|
|
read -p "execute \"$*\"? " x;
|
|
case $x in
|
|
'y')
|
|
_TEST "$@"
|
|
;;
|
|
'q')
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "skipping"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
alias EXPECT='_EXPECT $LINENO'
|
|
alias EXPECT_NOT='_EXPECT_NOT $LINENO'
|
|
if [ -n "$GF_INTERACTIVE" ]; then
|
|
alias TEST='DBG_TEST $LINENO'
|
|
else
|
|
alias TEST='_TEST $LINENO'
|
|
fi
|
|
alias EXPECT_WITHIN='_EXPECT_WITHIN $LINENO'
|
|
alias EXPECT_KEYWORD='_EXPECT_KEYWORD $LINENO'
|
|
alias TEST_IN_LOOP='_TEST_IN_LOOP $LINENO'
|
|
alias EXPECT_WITHIN_TEST_IN_LOOP='_EXPECT_WITHIN_TEST_IN_LOOP $LINENO'
|
|
shopt -s expand_aliases
|
|
|
|
if [ x"$OSTYPE" = x"Linux" ]; then
|
|
alias dd="dd status=none"
|
|
elif [ x"$OSTYPE" = x"NetBSD" ]; then
|
|
alias dd="dd msgfmt=quiet"
|
|
fi
|
|
# MacOS doesn't seem to support either option. Doing nothing at all is
|
|
# probably the safest option there and on anything we don't recognize, but
|
|
# if you want to reduce the noise level and know the correct option for
|
|
# your favorite platform please feel free to add it here.
|
|
|
|
function SETUP_LOOP ()
|
|
{
|
|
if [ $# != 1 ] ; then
|
|
echo "SETUP_LOOP usage" >&2
|
|
return 1;
|
|
fi
|
|
|
|
backend=$1
|
|
|
|
case ${OSTYPE} in
|
|
Linux)
|
|
losetup --find --show ${backend}
|
|
;;
|
|
NetBSD)
|
|
vnd=`vnconfig -l|awk -F: '/not in use/{print $1; exit}'`
|
|
if [ "x${vnd}" = "x" ] ; then
|
|
echo "no more vnd" >&2
|
|
return 1;
|
|
fi
|
|
vnconfig ${vnd} ${backend}
|
|
echo ${vnd}
|
|
;;
|
|
*)
|
|
echo "Please define SETUP_LOOP for ${OSTYPE} in include.rc" >&2
|
|
return 1;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function MKFS_LOOP ()
|
|
{
|
|
args=`getopt i: $*`
|
|
if [ $? -ne 0 ] ; then
|
|
echo "MKFS_LOOP usage" >&2
|
|
return 1;
|
|
fi
|
|
set -- ${args}
|
|
|
|
isize=""
|
|
while test $# -gt 0; do
|
|
case "$1" in
|
|
-i) isize=$2; shift ;;
|
|
--) shift; break ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
dev=$1
|
|
|
|
case ${OSTYPE} in
|
|
Linux)
|
|
test "x${isize}" != "x" && isize="-i size=${isize}"
|
|
mkfs.xfs -f ${isize} ${dev}
|
|
;;
|
|
NetBSD)
|
|
test "x${isize}" != "x" && isize="-i ${isize}"
|
|
|
|
echo ${dev} | grep -q '^vnd'
|
|
if [ $? -ne 0 ] ; then
|
|
vnd=`vnconfig -l|awk -F: '/not in use/{print $1; exit}'`
|
|
if [ "x${vnd}" = "x" ] ; then
|
|
echo "no more vnd" >&2
|
|
return 1;
|
|
fi
|
|
vnconfig ${vnd} ${dev}
|
|
else
|
|
vnd=${dev}
|
|
fi
|
|
newfs ${isize} /dev/r${vnd}a
|
|
;;
|
|
*)
|
|
echo "Please define MKFS_LOOP for ${OSTYPE} in include.rc" >&2
|
|
return 1;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# usage: log_newer timestamp "string"
|
|
# search in glusterfs logs for "string" logged after timestamp seconds
|
|
# since the Epoch (usually obtained by date +%s)
|
|
log_newer()
|
|
{
|
|
ts=$1
|
|
msg=$2
|
|
logdir=`$CLI --print-logdir`
|
|
|
|
local x_ifs=$IFS
|
|
IFS="["
|
|
for date in `grep -hr "$msg" $logdir | grep -v "G_LOG" | awk -F '[\]]' '{print $1}'` ; do
|
|
if [ `date -d "$date" +%s` -gt $ts ] ; then
|
|
IFS=$x_ifs
|
|
return 0;
|
|
fi
|
|
done 2>/dev/null
|
|
IFS=$x_ifs
|
|
return 1
|
|
}
|
|
|
|
function MOUNT_LOOP ()
|
|
{
|
|
if [ $# != 2 ] ; then
|
|
echo "MOUNT_LOOP usage" >&2
|
|
return 1;
|
|
fi
|
|
|
|
dev=$1
|
|
target=$2
|
|
|
|
case ${OSTYPE} in
|
|
Linux)
|
|
echo ${dev} | grep -q '^/dev/loop'
|
|
if [ $? -eq 0 ] ; then
|
|
mount -t xfs ${dev} ${target}
|
|
else
|
|
mount -o loop ${dev} ${target}
|
|
fi
|
|
;;
|
|
NetBSD)
|
|
echo ${dev} | grep -q '^vnd'
|
|
if [ $? -ne 0 ] ; then
|
|
ino=`/usr/bin/stat -f %i ${dev}`
|
|
dev=`vnconfig -l | awk -v ino=${ino} -F'[: ]*' '($5 == ino) {print $1}'`
|
|
fi
|
|
|
|
mount /dev/${dev}a ${target} >&2
|
|
if [ $? -ne 0 ] ; then
|
|
echo "failed to mount /dev/${dev}a on ${target}" >&2
|
|
return 1;
|
|
fi
|
|
|
|
mkdir -p ${target}/.attribute/system ${target}/.attribute/user
|
|
mount -u -o extattr ${target} >&2
|
|
|
|
;;
|
|
*)
|
|
echo "Please define MOUNT_LOOP for ${OSTYPE} in include.rc" >&2
|
|
return 1;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function UMOUNT_LOOP ()
|
|
{
|
|
case ${OSTYPE} in
|
|
Linux)
|
|
force_umount $*
|
|
;;
|
|
NetBSD)
|
|
for target in $* ; do
|
|
dev=`mount | awk -v target=${target} '($3 == target) {print $1}'`
|
|
force_umount ${target}
|
|
echo ${dev} | grep -q '^/dev/vnd'
|
|
if [ $? -eq 0 ] ; then
|
|
dev=`echo ${dev} | sed 's|^/dev/||; s|a$||'`
|
|
vnconfig -u ${dev}
|
|
else
|
|
ino=`/usr/bin/stat -f %i ${dev}`
|
|
dev=`vnconfig -l | awk -v ino=${ino} -F'[: ]*' '($5 == ino) {print $1}'`
|
|
if [ "x${dev}" != "x" ] ; then
|
|
vnconfig -u ${dev}
|
|
fi
|
|
fi
|
|
done
|
|
;;
|
|
*)
|
|
echo "Please define UMOUNT_LOOP for ${OSTYPE} in include.rc" >&2
|
|
return 1;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function SETUP_LOOP ()
|
|
{
|
|
if [ $# != 1 ] ; then
|
|
echo "SETUP_LOOP usage" >&2
|
|
return 1;
|
|
fi
|
|
|
|
backend=$1
|
|
|
|
case ${OSTYPE} in
|
|
Linux)
|
|
losetup --find --show ${backend}
|
|
;;
|
|
NetBSD)
|
|
vnd=`vnconfig -l|awk -F: '/not in use/{print $1; exit}'`
|
|
if [ "x${vnd}" = "x" ] ; then
|
|
echo "no more vnd" >&2
|
|
return 1;
|
|
fi
|
|
vnconfig ${vnd} ${backend}
|
|
echo ${vnd}
|
|
;;
|
|
*)
|
|
echo "Please define SETUP_LOOP for ${OSTYPE} in include.rc" >&2
|
|
return 1;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function MKFS_LOOP ()
|
|
{
|
|
args=`getopt i: $*`
|
|
if [ $? -ne 0 ] ; then
|
|
echo "MKFS_LOOP usage" >&2
|
|
return 1;
|
|
fi
|
|
set -- ${args}
|
|
|
|
isize=""
|
|
while test $# -gt 0; do
|
|
case "$1" in
|
|
-i) isize=$2; shift ;;
|
|
--) shift; break ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
dev=$1
|
|
|
|
case ${OSTYPE} in
|
|
Linux)
|
|
test "x${isize}" != "x" && isize="-i size=${isize}"
|
|
mkfs.xfs -f ${isize} ${dev}
|
|
;;
|
|
NetBSD)
|
|
test "x${isize}" != "x" && isize="-i ${isize}"
|
|
|
|
echo ${dev} | grep -q '^vnd'
|
|
if [ $? -ne 0 ] ; then
|
|
vnd=`vnconfig -l|awk -F: '/not in use/{print $1; exit}'`
|
|
if [ "x${vnd}" = "x" ] ; then
|
|
echo "no more vnd" >&2
|
|
return 1;
|
|
fi
|
|
vnconfig ${vnd} ${dev}
|
|
else
|
|
vnd=${dev}
|
|
fi
|
|
newfs ${isize} /dev/r${vnd}a
|
|
;;
|
|
*)
|
|
echo "Please define MKFS_LOOP for ${OSTYPE} in include.rc" >&2
|
|
return 1;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function MOUNT_LOOP ()
|
|
{
|
|
if [ $# != 2 ] ; then
|
|
echo "MOUNT_LOOP usage" >&2
|
|
return 1;
|
|
fi
|
|
|
|
dev=$1
|
|
target=$2
|
|
|
|
case ${OSTYPE} in
|
|
Linux)
|
|
echo ${dev} | grep -q '^/dev/loop'
|
|
if [ $? -eq 0 ] ; then
|
|
mount -t xfs ${dev} ${target}
|
|
else
|
|
mount -o loop ${dev} ${target}
|
|
fi
|
|
;;
|
|
NetBSD)
|
|
echo ${dev} | grep -q '^vnd'
|
|
if [ $? -ne 0 ] ; then
|
|
ino=`/usr/bin/stat -f %i ${dev}`
|
|
dev=`vnconfig -l | awk -v ino=${ino} -F'[: ]*' '($5 == ino) {print $1}'`
|
|
fi
|
|
|
|
mount /dev/${dev}a ${target} >&2
|
|
if [ $? -ne 0 ] ; then
|
|
echo "failed to mount /dev/${dev}a on ${target}" >&2
|
|
return 1;
|
|
fi
|
|
|
|
mkdir -p ${target}/.attribute/system ${target}/.attribute/user
|
|
mount -u -o extattr ${target} >&2
|
|
|
|
;;
|
|
*)
|
|
echo "Please define MOUNT_LOOP for ${OSTYPE} in include.rc" >&2
|
|
return 1;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function UMOUNT_LOOP ()
|
|
{
|
|
case ${OSTYPE} in
|
|
Linux)
|
|
force_umount $*
|
|
;;
|
|
NetBSD)
|
|
for target in $* ; do
|
|
dev=`mount | awk -v target=${target} '($3 == target) {print $1}'`
|
|
force_umount ${target}
|
|
echo ${dev} | grep -q '^/dev/vnd'
|
|
if [ $? -eq 0 ] ; then
|
|
dev=`echo ${dev} | sed 's|^/dev/||; s|a$||'`
|
|
vnconfig -u ${dev}
|
|
else
|
|
ino=`/usr/bin/stat -f %i ${dev}`
|
|
dev=`vnconfig -l | awk -v ino=${ino} -F'[: ]*' '($5 == ino) {print $1}'`
|
|
if [ "x${dev}" != "x" ] ; then
|
|
vnconfig -u ${dev}
|
|
fi
|
|
fi
|
|
done
|
|
;;
|
|
*)
|
|
echo "Please define UMOUNT_LOOP for ${OSTYPE} in include.rc" >&2
|
|
return 1;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function STAT()
|
|
{
|
|
stat $1
|
|
echo $?
|
|
}
|
|
|
|
function STAT_INO()
|
|
{
|
|
local ino=$(stat -c '%i' $1)
|
|
if [ $? -eq 0 ]; then
|
|
echo $ino
|
|
else
|
|
echo 0
|
|
fi
|
|
}
|
|
|
|
function get_md5_sum()
|
|
{
|
|
local file=$1;
|
|
md5_sum=$(md5sum $file | awk '{print $1}');
|
|
echo $md5_sum
|
|
}
|