# start or stop laptop_mode, best run by a power management daemon when
# ac gets connected/disconnected from a laptop
#
# install as /sbin/laptop_mode
#
# Contributors to this script:   Kiko Piris
#				 Bart Samwel
#				 Dax Kelson
# Original Linux 2.4 version by: Jens Axboe

parse_mount_opts () {
	echo "$*"			| \
	sed 's/commit=[0-9]*//g'	| \
	sed 's/,,*/,/g'			| \
	sed 's/^,//'			| \
	sed 's/,$//'			| \
	cat -
}

KLEVEL="$(uname -r | cut -c1-3)"
case "$KLEVEL" in
	"2.4")
		true
		;;
	"2.6")
		true
		;;
	*)
		echo "Unhandled kernel level: $KLEVEL ('uname -r' = '$(uname -r)')"
		exit 1
		;;
esac

# Shall we remount journaled fs. with appropiate commit interval? (1=yes)
DO_REMOUNTS=1

# age time, in seconds. should be put into a sysconfig file
MAX_AGE=600

# Allowed dirty ratio, in pct. should be put into a sysconfig file as well.
DIRTY_RATIO=40

# kernel default dirty buffer age
DEF_AGE=30
DEF_UPDATE=5
DEF_DIRTY_BACKGROUND_RATIO=10
DEF_DIRTY_RATIO=40


if [ ! -e /proc/sys/vm/laptop_mode ]; then
	echo "Kernel is not patched with laptop_mode patch."
	exit 1
fi

if [ ! -w /proc/sys/vm/laptop_mode ]; then
	echo "You do not have enough privileges to enable laptop_mode."
	exit 1
fi

case "$1" in
	start)
		AGE=$((100*$MAX_AGE))
		echo -n "Starting laptop_mode"
		case "$KLEVEL" in
			"2.4")
				echo "1"				> /proc/sys/vm/laptop_mode
				echo "30 500 0 0 $AGE $AGE 60 20 0"	> /proc/sys/vm/bdflush
				;;
			"2.6")
				echo "1"				> /proc/sys/vm/laptop_mode
				echo "$AGE"				> /proc/sys/vm/dirty_writeback_centisecs
				echo "$AGE"				> /proc/sys/vm/dirty_expire_centisecs
				echo "$DIRTY_RATIO"			> /proc/sys/vm/dirty_ratio
				echo "$DIRTY_RATIO"			> /proc/sys/vm/dirty_background_ratio
				;;
		esac
		if [ $DO_REMOUNTS -eq 1 ]; then
			cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
				PARSEDOPTS="$(parse_mount_opts "$OPTS")"
				case "$FST" in
					"ext3")		mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE ;;
					"reiserfs")	mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE ;;
					"xfs")		mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE ;;
				esac
			done
		fi
		echo "."
		;;
	stop)
		U_AGE=$((100*$DEF_UPDATE))
		B_AGE=$((100*$DEF_AGE))
		echo -n "Stopping laptop_mode"
		case "$KLEVEL" in
			"2.4")
				echo "0"				> /proc/sys/vm/laptop_mode
				echo "30 500 0 0 $U_AGE $B_AGE 60 20 0"	> /proc/sys/vm/bdflush
				;;
			"2.6")
				echo "0"				> /proc/sys/vm/laptop_mode
				echo "$U_AGE"				> /proc/sys/vm/dirty_writeback_centisecs
				echo "$B_AGE"				> /proc/sys/vm/dirty_expire_centisecs
				echo "$DEF_DIRTY_RATIO"			> /proc/sys/vm/dirty_ratio
				echo "$DEF_DIRTY_BACKGROUND_RATIO"	> /proc/sys/vm/dirty_background_ratio
				;;
		esac
		if [ $DO_REMOUNTS -eq 1 ]; then
			cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
				PARSEDOPTS="$(parse_mount_opts "$OPTS")"
				case "$FST" in
					"ext3")		mount $DEV -t $FST $MP -o remount,$PARSEDOPTS ;;
					"reiserfs")	mount $DEV -t $FST $MP -o remount,$PARSEDOPTS ;;
					"xfs")		mount $DEV -t $FST $MP -o remount,$PARSEDOPTS ;;
				esac
			done
		fi
		echo "."
		;;
	*)
		echo "$0 {start|stop}"
		;;

esac

exit 0
