#!/bin/sh
#
# Copyright (C) 2006-2007  Andrea Arcangeli <andrea@cpushare.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation;
# only version 2.1 of the License.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

DIR=`dirname $0`
cd $DIR

case "$1" in
    start)
	ORDER_CPU='order.cpu'
	if [ "$2" ]; then
	    ORDER_CPU=$2
	fi

	if [ ! -f $ORDER_CPU ]; then
	    echo
	    echo The file \"$ORDER_CPU\" is missing. Please log in http://www.cpushare.com/
	    echo to create it, and then save it in the following location:
	    echo \"`pwd`/$ORDER_CPU\".
	    echo
	    exit 1
	fi

	if [ ! -x seccomp-loader ] && ! which gcc >/dev/null 2>&1; then
	    echo
	    echo GCC is not installed, you can download it from http://gcc.gnu.org/ .
	    echo Most Linux distributions ships with a gcc package.
	    echo
	    exit 1
	fi

	if ! which python >/dev/null 2>&1; then
	    echo
	    echo Python is not installed, you can download it from http://www.python.org/ .
	    echo Most Linux distributions ships with a python package.
	    echo
	    exit 1
	fi

	if ! which twistd >/dev/null 2>&1; then
	    echo
	    echo Twisted is not installed, you can download it from http://twistedmatrix.com/ .
	    echo Most Linux distributions ships with a python-twisted package.
	    echo
	    exit 1
	fi

	if ! python -c 'from twisted.application.service import IServiceMaker' >/dev/null 2>&1; then
	    # backwards compatibility with twisted < 2.5.0
	    OLD_MKTAP=1
	    MKTAP="python -W ignore `which mktap`"
	else
	    OLD_MKTAP=0
	fi

	if ! python -c 'import OpenSSL' >/dev/null 2>&1; then
	    echo
	    echo pyOpenSSL is not installed, you can download it from
	    echo http://pyopenssl.sourceforge.net/ .
	    echo Most Linux distributions ships with a python-openssl package.
	    echo
	    exit 1
	fi

	if ! ulimit -s 8192 2>/dev/null; then
	    echo
	    echo Stack limit too small, needs 8M of stack available \(see \"man ulimit\"\).
	    echo
	    exit 1
	fi

	if [ -x `which id` ] && [ "$UID" = "" ]; then
	    UID=`id -u`
	fi
	if [ "$UID" = 0 ]; then
	    echo
	    echo "You shouldn't run CPUShare as root"
	    echo
	    exit 1
	fi

	TWISTD="python -W ignore `which twistd` -r poll"

	if [ -x seccomp-loader ] || make seccomp-loader; then
	    echo -n "Starting CPUShare..."
	else
	    exit 1
	fi

	if egrep -q '^buy_[0-9]+_' $ORDER_CPU; then
	    NR_CPUS=1
	    TYPE='buy'
	else
	    NR_CPUS=`egrep '^cpu[0-9]+' /proc/stat | wc -l`
	    if [ "$3" ]; then
		NR_CPUS=$3
	    fi
	    TYPE='sell'
	fi

	export TZ=UTC # universal timing for the cpushare logs
	if [ $OLD_MKTAP = 0 ]; then
	    for i in `seq 0 $(python -c "print $NR_CPUS-1")`; do
		echo -n "CPU $i..."
		nice -n 19 $TWISTD --logfile cpushare-$TYPE-$i.log --pidfile cpushare-$TYPE-$i.pid cpushare --order $ORDER_CPU
	    done && echo done.
	else
	    # backwards compatibility with twisted < 2.5.0
	    $MKTAP cpushare --order $ORDER_CPU &&
	    for i in `seq 0 $(python -c "print $NR_CPUS-1")`; do
		echo -n "CPU $i..."
		nice -n 19 $TWISTD --logfile cpushare-$TYPE-$i.log --pidfile cpushare-$TYPE-$i.pid -of cpushare.tap
	    done && echo done.
	fi
	;;
    stop)
	SLEEP=0.1

	nr=0
	for pid in cpushare-*.pid; do
	    if [ -r $pid ]; then
		if [ $nr = 0 ]; then
		    echo -n "Stopping CPUShare..."
		fi
		echo -n "CPU $nr..."
		nr=`python -c "print $nr + 1"`

		kill `cat $pid 2>/dev/null` 2>/dev/null >/dev/null
		while [ -f $pid ]; do
		    if ! sleep $SLEEP 2>/dev/null; then
			# busybox doesn't support < 1sec
			sleep 1
		    fi
		done
	    fi
	done
	if [ $nr != 0 ]; then
	    echo done.
	fi
	;;
    *)
	echo "Start:	$0 start [order.cpu]"
	echo "Stop:	$0 stop"
	exit 1
	;;
esac
