#! /bin/sh -e
#
# /etc/init.d/noflushd: Control userland daemon to spin down idle disks
#

# Test whether the kernel exposes devfs-style names in /proc/partitions.
# We do this by probing for '/' in the device name. With devfs, each names
# contains slashes. Some oldstyle names (eg. ataraid) also contain slashes,
# however, so this routine is not entirely accurate. We err on the side of
# devfs because mount failures are handled gracefully anyway.
# Returns 0 for devfs, 1 for oldstyle.
check_devfs() {
	local pass="init"
	
	while read major minor block name stats; do
		case "$pass" in
		"init")
			if test "x$name" = "xname"; then
				pass="header_ok"
			else
				break
			fi
			;;
		"header_ok"|"maybe_devfs")
			# Skip empty lines
			test -n "$major" || continue
			pass="maybe_devfs"
			if echo "$name" | grep -qv "/"; then
				pass="found_oldstyle"
				break
			fi
			;;
		*)
			# Cannot happen :-)
			pass="illegal"
			break
			;;
		esac
	done < /proc/partitions

	case "$pass" in
	"maybe_devfs")
		return 0;;	# kernel talks devfs
	"found_oldstyle")
		return 1;;	# kernel talks oldstyle
	*)
		echo -n "Noflushd init: "
		echo "parse error in check_devfs/$pass--assuming devfs" 
		return 0;;	# parse error; assuming devfs is the safe bet
	esac
}

# Test whether devfs is mounted anywhere in the file system.
# If given an optional argument, the routine checks for devfs mounted
# on the given mount point.
# Parse /proc/mounts directly because a devfs mounted at boot time does not
# show up in the output of mount(8).
# Returns 0 if found, 1 if not found.
check_devfs_mounted() {
	test -r /proc/mounts || return 1
	while read device mountpoint type cruft; do
		if test "x$type" = xdevfs; then
			test -n "$1" || return 0
			test "x$mountpoint" != "x$1" || return 0
		fi
	done < /proc/mounts
	return 1
}

mount_devfs() {

	test -n "$1" || return
	test -d "$1" || mkdir -m 700 -p "$1"

	mount -t devfs none "$1"
}

umount_devfs() {
	if check_devfs_mounted "$DEVFS_MNT"; then
		echo -n "Trying to unmount private devfs tree..."
		if umount "$DEVFS_MNT" >/dev/null 2>&1; then
			echo "done."
		else
			echo "failed."
		fi
	fi
}

nfd_start() {
	start-stop-daemon --start --quiet --pidfile \
		/var/run/$NAME.pid --exec $DAEMON -- $PARAMS
}

nfd_stop() {

	case "$1" in
	"byname")
		opt="--name $NAME";;
	*)
		opt="--exec $DAEMON";;
	esac

	start-stop-daemon --stop --quiet --oknodo --pidfile \
	/var/run/$NAME.pid $opt
}

NAME=noflushd
DAEMON="/usr/sbin/$NAME"
DESC="No Flush Daemon"
DEFAULTS=/etc/default/noflushd
DEVFS_MNT=/var/lib/noflushd/devfs

test -f $DAEMON || exit 0

# Source defaults file; edit that file to configure this script.
TIMEOUT=0
DISKS=""
PARAMS=""
if [ -e "$DEFAULTS" ]; then
	. "$DEFAULTS"
fi
if [ -z "$PARAMS" ]; then
	if [ -z "$TIMEOUT" ]; then
		echo "No default timeout set. Aborting."
		echo "To correct, edit $DEFAULTS or run dpkg-reconfigure $NAME"
		exit 1
	fi
	PARAMS="-n $TIMEOUT $DISKS"
fi

case "$1" in
  start)
  	if check_devfs && ! check_devfs_mounted; then
		echo -n "Mounting private devfs tree..."
		if mount_devfs "$DEVFS_MNT"; then
			echo "done."
		else
			echo "failed (trying to go on anyway)."
		fi
	fi
	echo -n "Starting $DESC: "
	nfd_start
	echo "$NAME."
	;;
  stop)
	echo -n "Stopping $DESC: "
  	nfd_stop byname
	echo "$NAME."
	umount_devfs
	;;
  restart|force-reload)
	echo -n "Restarting $DESC: "
	nfd_stop byname
	sleep 1
	nfd_start
	echo "$NAME."
	;;
  *)
	N=/etc/init.d/$NAME
	echo "Usage: $N {start|stop|restart|force-reload}" >&2
	exit 1
	;;
esac

exit 0
