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 }