#!/bin/bash

if [ $# != 2 ]; then
	echo "usage: $0 [start|stop] /path_to_chrdir"
	exit 3
fi

STST=$1
CHRDIR=$2

if [ "${STST}" != "stop" -a "${STST}" != "start" ]; then
	echo "usage: $0 [start|stop] /path_to_chrdir"
	exit 3
fi

if [ "$CHRDIR" != "all" ]; then
	if ! [ -d "$CHRDIR" ]; then
		echo "$CHRDIR doesn't exist"
		exit 13
	fi
fi

initscripts=`find /etc/init.d/ -type f |grep -ve '\/etc\/init\.d\/.*\..*'`


############################################

function chr_pids () {
	if [ $# -lt 1 ]; then
		echo "Programming error"
		exit 13
	fi

	chr_dir=$1

	chr_pids=""

	ALLPS=`ps -o pid -A`

	for p in $ALLPS; do
		jail=`readlink /proc/${p}/root`
		if [ "${jail}" == "${chr_dir}" ]; then
			echo "${p}"
		fi
	done
}

function pids2names () {

	ppids="$@"

	ALLPROCS=`ps ax`

	for ppid in $ppids; do
		echo "$ALLPROCS" | grep -e "^[ ]*$ppid"
	done
}

function chr_daemon
{

	CHRD=$1
	WTD=$2

	[ -d $CHRD ] || return 21

	for script in $initscripts; do

		if (grep -e "^CHRDIR="${CHRD}"$" $script >/dev/null); then
			echo "*** $script ${WTD}..."
			$script ${WTD}
		fi
	done
}

function chr_umount
{

	CHRD=$1
	[ -d $CHRD ] || return 21

	allchrmnts=`cat /proc/self/mountinfo |awk '{print $4 " " $5}' |grep "${CHRD}"`

	chrmntss=`echo -n "$allchrmnts" |grep "^${CHRD}" |awk '{print $2}' |sort -r`
	chrmntsd=`echo -n "$allchrmnts" |awk '{print $2}' |grep "^${CHRD}" |sort -r`

	for chrmnt in $chrmntss; do
		echo "*** Unmounting (src) ${chrmnt}"
		umount ${chrmnt}
	done
	for chrmnt in $chrmntsd; do
		echo "*** Unmounting (dst) ${chrmnt}"
		umount ${chrmnt}
	done

}

function do_process_check
{
	STST=$1
	CHRD=$2
	PANIC=$3

	ERR=0

	echo
	echo "Process sanity check..."
#	stillrun=`ps-chroot ${CHRD} 2>/dev/null`
	stillrun=`chr_pids ${CHRD}`
	stillrno=`echo -n "$stillrun" | wc -l`
	if [ "$STST" == "stop" ]; then
		if [ $stillrno -gt 0 ]; then
			echo "Some processes ($stillrno) are still running in $CHRD:"
			pids2names $stillrun
			ERR=1
		fi
	elif [ "$STST" == "start" ]; then
		if [ $stillrno -lt 1 ]; then
			echo "Nothing is running in $CHRD"
			ERR=1
		else
			echo "OK, Running processes in $CHRD:"
			pids2names $stillrun
		fi
	fi
	echo

	if [ "$STST" == "start" ]; then
		if [ -d /etc/daemon-watchdog ]; then
			/etc/daemon-watchdog/daemon-watchdog test
		fi
	fi

	if [ "$PANIC" == "1" -a "$ERR" == 1 ]; then
		echo "*** ERROR *** EXITING ***"
		exit 33
	else
		echo "=== PROCESS CHECK OK ==="
		echo
	fi

}


function do_mount_check
{
	STST=$1
	CHRD=$2
	PANIC=$3

	ERR=0

	echo
	echo "Mount sanity check..."
	stillmnt=`cat /proc/self/mountinfo |awk '{print $4 " on " $5}' |grep "${CHRD}"`
	#stillmnt=`mount |grep "on ${CHRD}"`
	stillmno=`echo -n "$stillmnt" | wc -l`
	fstablines=`grep "${CHRD}" /etc/fstab |grep -vE "^[[:space:]]*#"`
	fstablno=`echo -n "$fstablines" |wc -l`

	if [ "$STST" == "stop" ]; then
		if [ $stillmno -gt 0 ]; then
			echo "Some dirs ($stillmno) are still mounted in $CHRD:"
			echo "$stillmnt"
			ERR=1
		fi
	elif [ "$STST" == "start" ]; then
		if [ $stillmno -lt 1 ]; then
			echo "Nothing is mounted in $CHRD"
			ERR=1
		elif [ $stillmno -lt $fstablno ]; then
			echo "WARNING: fstab differs from mounted, please check"
			echo "mounted:"
			echo "$stillmnt"
			echo "fstab:"
			echo "$fstablines"
			ERR=1
		else
			echo "OK, Check mounted FS's:"
			echo "# mounted:"
			echo "$stillmnt"
			echo
			echo "# fstab:"
			echo "$fstablines"
		fi
	fi
	echo

	if [ "$PANIC" == "1" -a "$ERR" == 1 ]; then
		echo "*** ERROR *** EXITING ***"
		exit 33
	else
		echo "=== MOUNT CHECK OK ==="
		echo
	fi

}

function do_stop
{
	CHRD=$1

	echo "STOPPING CHROOT $CHRD"

	fstab_check

	if [ -d /etc/daemon-watchdog ]; then
		echo "Suspending daemon-watchdog..."
		touch /etc/daemon-watchdog/disable
		echo
	fi

	echo "Stopping all daemons in $CHRD..."
	chr_daemon $CHRD stop
	echo

	sleep 1

	do_process_check stop $CHRD 1

	echo "Unmounting bindmounts in $CHRD..."
	chr_umount $CHRD
	echo

	sleep 1

	do_mount_check stop $CHRD 1
}

function do_start
{
	CHRD=$1

	fstab_check

	do_process_check stop $CHRD 1
	do_mount_check stop $CHRD 1

	echo "STARTING CHROOT $CHRD"

	echo "Mounting all filesystems in fstab"
	mount -v -a |grep success
	echo
	sleep 1

	do_mount_check start $CHRD 1

	chr_daemon $CHRDIR start
	echo

	if [ -f /etc/init.d/rsyslog ]; then
		/etc/init.d/rsyslog restart
		echo
	fi

	sleep 3

	do_process_check start $CHRD 1

	if [ -f /etc/daemon-watchdog/disable ]; then
		echo "Re-arming daemon-watchdog..."
		rm /etc/daemon-watchdog/disable
		echo
	fi

}

function fstab_check()
{
	# sanity check
	echo "Can't check fstab yes"
#	echo "Checking fstab"
#	if ! (findmnt --verify); then
#		echo "FSTAB ERROR, exiting before doing anything"
#		exit 23
#	fi
}

############################################

if [ "x$CHRDIR" == "xall" ]; then
	chrd=`find /chroot/ -mindepth 1 -maxdepth 1 -type d`
else
	chrd=$CHRDIR
fi

for chd in $chrd; do
	if [ "${STST}" == "stop" ]; then
		do_stop $chd
	elif [ "${STST}" == "start" ]; then
		do_start $chd
	fi
done

exit 0
