#!/usr/bin/openrc-run

description="Automatic mounts of NFS shares"

. /opt/etc/functions.openrc

# /etc/conf.d/autonfs variables:
# NFS_HOSTS - list of servers to ask for NFS shares
# MNT_PREFIX - root of autogenerated imported dirs

NFS_HOSTS=${NFS_HOSTS-"localhost"}
MNT_PREFIX=${MNT_PREFIX-"/mnt/nfs"}

# TODO: properly handle recursive NFS shares.
# This is complicated, as for every server we have to construct tree
# and then traverse if from root/children for mount/umount operation.
# Currently, there is only a hack for the purpose (working one).

extra_commands="mnt umnt"

depend()
{
	need net
	provide ${SVCNAME}
}

start()
{
	ebegin "Starting \"${SVCNAME}\""
	eindent
	mnt
	eoutdent
	eend $?
}

stop()
{
	ebegin "Stopping \"${SVCNAME}\""
	eindent
	umnt
	eoutdent
	eend $?
	return 0
}

umnt()
{
	for SRV in ${NFS_HOSTS}; do
		for d in `mount | grep "$SRV" | awk '{print $1}'`
		do
			umount $d
		done
		for d in `mount | grep "$SRV" | awk '{print $1}'`
		do
			umount $d
		done
		for d in `mount | grep "$SRV" | awk '{print $1}'`
		do
			umount $d
		done
		for d in `mount | grep "$SRV" | awk '{print $1}'`
		do
			umount $d
		done
	done
}

__umnt()
{
	# Quick and dirty way to handle umount of recursive shares
	local errors= maxlevel=10 level=1 ourdir=
	while [ 1 ]; do
		errors=0
		for DIR in $(mount | grep "${SRV}" | awk '{print $1}'); do

			echo "1: DIR=$DIR"

			# Determine whether this NFS mount belongs to one of the NFS_HOSTS
			ourdir=0
			for SRV in ${NFS_HOSTS}; do

				echo "2: SRV=$SRV"
			
				(echo ${DIR} | grep "^${MNT_PREFIX}/${SRV}/" > /dev/null 2>&1) || continue
				ourdir=1
				break
			done

				echo "3: outdir=$outdir"

			[ ${ourdir} -eq 0 ] && continue

				echo "4: outdir=$outdir"

			update_me
			if (umount -f ${DIR} > /dev/null 2>&1); then
				einfo "${ME}: unmounted ${DIR}"
			else
				ewarn "${ME}: unable to unmount ${DIR}"
				errors=$(($errors+1))
			fi
		done
		if [ $errors -eq 0 ]; then
			break
		else
			update_me
			ewarn "${ME}: Pass $level, still mounted: ${errors}"
		fi
		level=$(($level+1))
		if [ $level -ge $maxlevel ]; then
			update_me
			eerror "${ME}: maximum recursion level ${maxlevel} is reached!"
			break
		fi
	done
}

mnt()
{
	update_me
	# FIXME
	echo 2 > /proc/sys/net/ipv4/ipfrag_time
	for SRV in ${NFS_HOSTS}; do
		# FIXME
		if ! (ping -c 2 ${SRV} > /dev/null 2>&1); then
			update_me
			eerror "Server ${SRV} is not pingable, skipping"
			continue
		fi
		update_me
		einfo "${ME}: mounting all NFS exports on ${SRV}..."
		EXPORTS=$(showmount -e ${SRV} | sort)
		eindent
		for EXP in ${EXPORTS}; do
			if [ $(echo $EXP | cut -c 1) != '/' ]; then
				continue;
			fi
			FS="${SRV}:${EXP}"
			MNT="${MNT_PREFIX}/${SRV}${EXP}"
			if ! [ -d ${MNT} ]; then
				einfo "Creating directory ${MNT}"
				mkdir -p ${MNT}
			else
				if (mount | grep "on ${MNT} " > /dev/null 2>&1) then
					ewarn "Something is already mounted on ${MNT}, call ${SVCNAME} umnt first."
					continue
				fi
			fi
			if (${MOUNT_NFS} ${FS} ${MNT}); then
				update_me
				einfo "${ME}: successfully mounted ${FS}"
			fi
		done
		eoutdent
	done
}

