mirror of
https://github.com/gluster/glusterfs.git
synced 2026-02-05 15:48:40 +01:00
We were not passing xattr_req when doing a name self heal as well as a meta data heal. Because of this, some xdata was missing which causes i/o errors Change-Id: Ibfb1205a7eb0195632dc3820116ffbbb8043545f Fixes: bz#1728770 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
1351 lines
31 KiB
Plaintext
1351 lines
31 KiB
Plaintext
|
|
checkpoint_time="$(date +%s%N)"
|
|
|
|
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
|
|
GSV1=${GSV1:=slave1}; # 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=600
|
|
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
|
|
DISK_FAIL_TIMEOUT=80
|
|
|
|
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 100 ] || break
|
|
sleep 0.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="$*"
|
|
start_time="$(date +%s%N)"
|
|
}
|
|
|
|
|
|
function test_footer()
|
|
{
|
|
RET=$?
|
|
local lineno=$1
|
|
local err=$2
|
|
local end_time
|
|
local elapsed1
|
|
local elapsed2
|
|
|
|
end_time="$(date +%s%N)"
|
|
elapsed1="$(((start_time - checkpoint_time) / 1000000))"
|
|
elapsed2="$(((end_time - start_time) / 1000000))"
|
|
checkpoint_time="$end_time"
|
|
if [ $RET -eq 0 ]; then
|
|
printf "ok %3d [%7d/%7d] <%4d> '%s'\n" "$t" "$elapsed1" "$elapsed2" "$lineno" "$saved_cmd";
|
|
else
|
|
printf "not ok %3d [%7d/%7d] <%4d> '%s' -> '%s'\n" "$t" "$elapsed1" "$elapsed2" "$lineno" "$saved_cmd" "$err"
|
|
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}000000000 + $(date +%s%N) ))"
|
|
|
|
# We *want* this to be globally visible.
|
|
EW_RETRIES=0
|
|
|
|
while [[ "$(date +%s%N)" < "$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 0.25;
|
|
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[@]}"
|
|
}
|
|
|
|
## Lock files should get automatically removed once "usradd" or "groupadd"
|
|
## command finishes. But sometimes we encounter situations (bugs) where
|
|
## some of these files may not get properly unlocked after the execution of
|
|
## the command. In that case, when we execute useradd next time, it may show
|
|
## the error “cannot lock /etc/password” or “unable to lock group file”.
|
|
## So, to avoid any such errors, check for any lock files under /etc.
|
|
## and remove those.
|
|
|
|
function remove_lock_files()
|
|
{
|
|
if [ ! -f /etc/passwd.lock ];
|
|
then
|
|
rm -rf /etc/passwd.lock;
|
|
fi
|
|
|
|
if [ ! -f /etc/group.lock ];
|
|
then
|
|
rm -rf /etc/group.lock;
|
|
fi
|
|
|
|
if [ ! -f /etc/shadow.lock ];
|
|
then
|
|
rm -rf /etc/shadow.lock;
|
|
fi
|
|
|
|
if [ ! -f /etc/gshadow.lock ];
|
|
then
|
|
rm -rf /etc/gshadow.lock;
|
|
fi
|
|
}
|
|
|
|
|
|
function cleanup()
|
|
{
|
|
local end_time
|
|
|
|
# Prepare flags for umount
|
|
case `uname -s` in
|
|
Linux)
|
|
flag="-l"
|
|
;;
|
|
NetBSD)
|
|
flag="-f -R"
|
|
;;
|
|
FreeBSD|Darwin)
|
|
flag="-f"
|
|
;;
|
|
*)
|
|
flag=""
|
|
;;
|
|
esac
|
|
|
|
# Clean up lock files.
|
|
remove_lock_files
|
|
|
|
# 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
|
|
}
|