#!/bin/bash

DIRNAME=`dirname $0`
NAME=`basename $0`
SERVER="centos7"
MOUNTPOINT="/test/nested"
ITERATIONS=100
TIMEOUT=20
WAIT=`expr $TIMEOUT + 7`
VERBOSE="vvv"
INSTANCES=10

cd $DIRNAME

if [ ! -x opendir ]; then
	gcc -o opendir opendir.c
	if [ $? -ne 0 ]; then
		echo "failed to build opendir test program"
		exit 1
	fi
fi

function setup_test_tables()
{
	rm -f test_table_autofs test_table_nfs
	sed "s?/#MOUNT_POINT#?$MOUNTPOINT?" \
		submount_autofs > submount_test_autofs
	sed "s?/#MOUNT_POINT#?$MOUNTPOINT?" \
		submount_nfs > submount_test_nfs
}

function setup_test_maps()
{
	sed "s?#SERVER#?$SERVER?" auto_submount_indirect \
			> /etc/auto_submount_indirect
	sed "s?#SERVER#?$SERVER?" auto_submount > /etc/auto_submount

	chcon system_u:object_r:etc_t:s0 /etc/auto_submount
	chcon system_u:object_r:etc_t:s0 /etc/auto_submount_indirect
}

function cleanup_config()
{
	cp /etc/autofs.conf.submount_test.sav /etc/autofs.conf
	rm -f /etc/auto_submount /etc/auto_submount_indirect
	rm -f /etc/auto.submount.master
}

function kill_test_instances()
{
	test_pids=`ps -ef|grep -v grep| \
		grep submount_test|awk '{printf "%s ", $2}'`
	kill $test_pids > /dev/null 2>&1
	test_pids=`ps -ef|grep -v grep| \
		grep submount_test|awk '{printf "%s ", $2}'`
	if [ -n "$test_pids" ]; then
		kill -9 $test_pids > /dev/null 2>&1
	fi
}

function run_test()
{
	/sbin/service autofs start
	if [ $? -ne 0 ]; then
		echo "failed to start autofs"
		touch /tmp/submount_test.failed
		return 1
	fi

	echo -n "Running $INSTANCES test instances "
	echo    "using $ITERATIONS iterations with expire timeout $TIMEOUT"

	for i in `seq 1 $INSTANCES`; do
		$DIRNAME/submount_test $VERBOSE $ITERATIONS $WAIT &
	done
	echo "Started $INSTANCES test instances"

	echo "Waiting for instances to finish"

	iter_wait=`expr $WAIT + 2`
	waited=0
	waited_iters=0
	while ps -e | grep -v grep | grep submount_test > /dev/null 2>&1
	do
		if [ -e /tmp/submount_test.failed ]; then
			echo "Failure seen in at least one test instance, quiting"
			kill_test_instances
			break
		fi

		sleep 5

		waited=`expr $waited + 5`
		if [ $waited -lt $WAIT ]; then
			continue
		fi

		waited_iters=`expr $waited_iters + 1`
		if [ $waited_iters -le $ITERATIONS ]; then
			waited=0
			continue
		fi

		echo "Submount test seems to be hung"
		touch /tmp/submount_test.failed
		auto_pid=`ps -ef|grep -v grep|grep automount|awk '{print $2}'`
		if [ -z "$auto_pid" ]; then
			echo "Cannot find automount process"
		else
			gdb --eval-command="set height 0" \
				--eval-command="thread apply all backtrace" \
				--batch --pid=$auto_pid /usr/sbin/automount
		fi
		kill_test_instances
		break
	done

	echo "Test instances finished"

	/sbin/service autofs stop
	auto_pid=`ps -ef|grep -v grep|grep automount|awk '{print $2}'`
	if [ -n "$auto_pid" ]; then
		kill -9 $auto_pid
		grep "/test/nested" /proc/mounts | \
			awk '{print $2}'| \
			sort -r | xargs -n1 umount
		echo "failed to shutdown autofs"
		touch /tmp/submount_test.failed
		return 1
	fi

	return 0
}

cp /etc/autofs.conf /etc/autofs.conf.submount_test.sav
sed -e 's?.*master_map_name =.*?master_map_name = /etc/auto.submount.master?' \
	/etc/autofs.conf.submount_test.sav > /etc/autofs.conf
cat /etc/autofs.conf

setup_test_tables
setup_test_maps

echo "`date`"
echo "Running test with nobrowse map configuration"

echo "/test/nested   /etc/auto_submount --timeout=$TIMEOUT" \
		> /etc/auto.submount.master
chcon system_u:object_r:etc_t:s0 /etc/auto.submount.master
chcon unconfined_u:object_r:bin_t:s0 /etc/auto.submount.master

run_test $INTSTANCES $ITERATIONS $WAIT
if [ ! -e /tmp/submount_test.failed ]; then
	echo "Test: PASSED"
else
	echo "Test: FAILED"
	rm -f /tmp/submount_test.failed
	cleanup_config
	echo "`date`"
	exit
fi

echo
echo "`date`"
echo "Running test with browse map configuration"

echo "/test/nested   /etc/auto_submount --ghost --timeout=$TIMEOUT" \
		> /etc/auto.submount.master
chcon system_u:object_r:etc_t:s0 /etc/auto.submount.master
chcon unconfined_u:object_r:bin_t:s0 /etc/auto.submount.master

run_test $INTSTANCES $ITERATIONS $WAIT
if [ ! -e /tmp/submount_test.failed ]; then
	echo "Test: PASSED"
else
	echo "Test: FAILED"
	rm -f /tmp/submount_test.failed
	cleanup_config
	echo "`date`"
	exit
fi

cleanup_config
echo "`date`"

