#! /bin/sh
### BEGIN INIT INFO
# Provides:          cpushare
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: CPUShare daemon
# Description:       Idle CPU cycle sharing daemon.
### END INIT INFO

# Author: Sam Hocevar <sam@zoy.org>

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="CPUShare daemon"
NAME=cpushare
DAEMON=/usr/bin/twistd
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "/usr/lib/cpushare/seccomp-loader" ] || exit 0

# Read configuration variable file if it is present
CPUSHARE_NICE=19
CPUSHARE_USER=cpushare
CPUSHARE_GROUP=nogroup
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

case "$1" in
  start)
	log_begin_msg "Starting CPUShare daemon..."
	if ! su nobody -c /usr/lib/cpushare/seccomp-test >/dev/null 2>&1; then
	    log_begin_msg " kernel was not built with CONFIG_SECCOMP=y"
	    log_end_msg 1
	    exit 0
	fi
	if [ ! -d "/var/run/cpushare" ]; then
	    mkdir -p /var/run/cpushare
	    chown cpushare:nogroup /var/run/cpushare
	fi
	FAIL=0
	# Start one instance of the daemon for each .cpu file in /etc/cpushare
	# and do not complain about already running processes (because the user
	# may be running "$0 start" after having simply added one file). Also,
	# only start for sell orders; buy orders should not be run in the
	# background.
	for order in `find /etc/cpushare -name '*.cpu'`; do
	    BASE="`basename "$order" | sed 's/[.]cpu$//'`"
	    PIDFILE="/var/run/cpushare/$BASE.pid"
	    TAPFILE="/var/run/cpushare/$BASE.tap"
	    LOGFILE="/var/log/cpushare/$BASE.log"
	    if [ -f "$PIDFILE" ]; then
	        continue # already running
	    fi
	    if [ -f "$TAPFILE" ]; then
	        rm -f "$TAPFILE"
	    fi
	    if ! grep -q '^sell_[0-9]\{1,\}_' "$order"; then
	        continue # not a sell order
	    fi
	    if python -c 'from twisted.application.service import IServiceMaker' >/dev/null 2>&1; then
		# python-twisted-core does not need a .tap file
		nice -n "$CPUSHARE_NICE" python -W ignore $DAEMON -r poll -u "$CPUSHARE_USER" -g "$CPUSHARE_GROUP" --logfile "$LOGFILE" --pidfile "$PIDFILE" cpushare --order "$order"
	    else
		# Fallback for older (< 2.5) versions of python-twisted-core
		(cd /var/run/cpushare; mktap -u "$CPUSHARE_USER" -g "$CPUSHARE_GROUP" cpushare --order "$order" 2>/dev/null; mv cpushare.tap "$TAPFILE")
		nice -n "$CPUSHARE_NICE" python -W ignore $DAEMON -r poll --logfile "$LOGFILE" --pidfile "$PIDFILE" -of "$TAPFILE"
	    fi
	    case "$?" in
		1|2) FAIL=1 ;;
	    esac
	    log_begin_msg " $BASE"
	done
	log_end_msg $FAIL
	;;
  stop)
	log_begin_msg "Stopping CPUShare daemon..."
	FAIL=0
	# Stop running processes. Do not trust the information in /etc/cpushare
	# because the user may have removed files.
	for pidfile in `find /var/run/cpushare -name '*.pid'`; do
	    BASE="`basename "$pidfile" | sed 's/[.]pid$//'`"
	    TAPFILE="/var/run/cpushare/$BASE.tap"
	    PID="`cat $pidfile 2>/dev/null`"
	    kill "$PID" 2>/dev/null >/dev/null
	    rm -f "$TAPFILE"
	    case "$?" in
		1|2) FAIL=1 ;;
	    esac
	    log_begin_msg " $BASE"
	done
	# Wait for remaining daemons to die.
	for pidfile in `find /var/run/cpushare -name '*.pid'`; do
	    for sleep in 0.1 0.2 0.5 1 2 3; do
		if [ ! -f "$pidfile" ]; then break; fi
		sleep $sleep >/dev/null 2>&1 || sleep 1
	    done
	    if [ -f "$pidfile" ]; then FAIL=1; fi
	done
	log_end_msg $FAIL
	;;
  #reload)
	# Properly implementing "reload" is tricky. We need to stop processes
	# that no longer have an associated .cpu file, start processes for new
	# .cpu files and restart processes that may have changed their .cpu
	# file. As it is not easy to detect which files have changed, let's
	# just stick with "force-reload".
	#;;
  force-reload)
	$0 restart
	;;
  restart)
	$0 stop
	$0 start
	;;
  *)
	echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
	exit 3
	;;
esac

:
