diff options
Diffstat (limited to 'tests/include.rc')
| -rw-r--r-- | tests/include.rc | 1267 |
1 files changed, 1186 insertions, 81 deletions
diff --git a/tests/include.rc b/tests/include.rc index bb541eaa1e4..0dc7d830449 100644 --- a/tests/include.rc +++ b/tests/include.rc @@ -1,126 +1,355 @@ + +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 -H0=${H0:=`hostname --fqdn`}; # hostname +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"; +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))" -mkdir -p $B0; -mkdir -p $M0 $M1; -mkdir -p $N0 $N1; + $* + 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|TEST|EXPECT_WITHIN|EXPECT_KEYWORD)[[:space:]]' $0 | wc -l` +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` + expect_tests=`echo $line | cut -f 2 -d =` + testcnt=`expr $testcnt + $expect_tests` done IFS=$x_ifs -echo 1..$testcnt +echo "1..`echo $testcnt`" t=1 function dbg() { - [ "x$DEBUG" = "x0" ] || echo "$*" >&2; + [ "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): $*"; + dbg "========================="; + dbg "TEST $t (line $TESTLINE): $*"; + saved_cmd="$*" + start_time="$(date +%s%N)" } function test_footer() { - RET=$? - local err=$1 + RET=$? + local lineno=$1 + local err=$2 + local end_time + local elapsed1 + local elapsed2 - if [ $RET -eq 0 ]; then - echo "ok $t"; - else - echo "not ok $t $err"; - if [ "$EXIT_EARLY" = "1" ]; then - exit $RET - fi - fi + 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"; + dbg "RESULT $t: $RET"; - t=`expr $t + 1`; + t=`expr $t + 1`; } function test_expect_footer() { - local e=$1 - local a=$2 + local lineno=$1 + local e=$2 + local a=$3 local err="" - if [ "x${e}" != "x${a}" ]; then + if ! [[ "$a" =~ $e ]]; then err="Got \"$a\" instead of \"$e\"" fi - [[ "x${e}" == "x${a}" ]]; - test_footer "$err"; + [[ "$a" =~ $e ]]; + + test_footer "$lineno" "$err"; } function _EXPECT() { - TESTLINE=$1; - shift; + TESTLINE=$1; + shift; local a="" - test_header "$@"; + G_LOG $TESTLINE "$@"; + test_header "$@"; - e="$1"; - shift; - a=$("$@" | tail -1) + e="$1"; + shift; + a=$("$@" | tail -1) - test_expect_footer "$e" "$a"; + if [ "x$e" = "x" ] ; then + test_expect_footer "$TESTLINE" "x$e" "x$a"; + else + test_expect_footer "$TESTLINE" "$e" "$a"; + fi } -function _EXPECT_KEYWORD() +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; + TESTLINE=$1; + shift; + local a="" - test_header "$@"; + G_LOG $TESTLINE "$@"; + test_header "$@"; - e="$1"; - shift; - "$@" | tail -1 | grep -q "$e" + e="$1"; + shift; + a=$("$@" | tail -1) - test_footer; + 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; + TESTLINE=$1; + shift; local redirect="" - test_header "$@"; + G_LOG $TESTLINE "$@"; + test_header "$@"; if [ "$1" = "!" ]; then redirect="2>&1" fi - eval "$@" >/dev/null $redirect + eval "$@" >/dev/null $redirect - test_footer; + 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 @@ -129,39 +358,37 @@ function _EXPECT_WITHIN() local timeout=$1 shift; + G_LOG $TESTLINE "$@"; test_header "$@" e=$1; + a=""; shift; - local endtime=$(( ${timeout}+`date +%s` )) + local endtime="$(( ${timeout}000000000 + $(date +%s%N) ))" - local success=0 - while [ `date +%s` -lt $endtime ]; do - ("$@") | tail -1 | egrep -q "^${e}\$" - - local pipestatus=(${PIPESTATUS[@]}) + # 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 [ ${pipestatus[0]} -ne 0 ]; then + if [ $? -ne 0 ]; then break; fi - ## Check match success - if [ ${pipestatus[2]} -eq 0 ]; then - success=1; + if [[ "$a" =~ $e ]]; then break; fi - sleep 1; + sleep 0.25; + EW_RETRIES=$((EW_RETRIES+1)) done - if [ $success -eq 1 ]; then - true; + if [ "x$e" = "x" ] ; then + test_expect_footer "$TESTLINE" "x$e" "x$a"; else - false; + test_expect_footer "$TESTLINE" "$e" "$a"; fi - - test_footer; } @@ -176,38 +403,348 @@ function SKIP_TESTS() function _TEST_IN_LOOP() { - testcnt=`expr $testcnt + 1`; - _TEST $@ + 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() { - killall -15 glusterfs glusterfsd glusterd 2>/dev/null || true; - killall -9 glusterfs glusterfsd glusterd 2>/dev/null || true; + 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 $m + umount $flag $m done + # Cleanup lvm + type cleanup_lvm &>/dev/null && cleanup_lvm || true; - LOOPDEVICES=`losetup -a | grep "$B0/" | awk '{print $1}' | tr -d :` - for l in $LOOPDEVICES; - do - losetup -d $l + # 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. - rm -rf /var/lib/glusterd/* $B0/* /etc/glusterd/*; + return 0 +} - umount -l $M0 2>/dev/null || true; - umount -l $M1 2>/dev/null || true; - umount -l $N0 2>/dev/null || true; - umount -l $N1 2>/dev/null || true; +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; @@ -228,7 +765,13 @@ function build_tester () local fname=$(basename "$cfile") local ext="${fname##*.}" local execname="${fname%.*}" - gcc -g -o $(dirname $cfile)/$execname $cfile + 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 () @@ -237,9 +780,571 @@ function process_leak_count () 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 TEST='_TEST $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 +} |
