#!/usr/bin/perl -w
use POSIX qw(setsid);
sub checkconfig;
sub daemonize;
sub usage;

# this should take a -C for a different config file at some point
%c=checkconfig("/etc/slicehostd.conf");

$| = 1;
daemonize;

open(OFP,">>".$c{'logfile'}) or die "couldn't open ".$c{'logfile'}." : $!";
$count=0;
while(1){
        if($count > 0){ $count--; }
        open(IFP,"/proc/loadavg") or die "$!";
        $l=<IFP>;
        close(IFP);
        chomp($l);
        $l=~s/ .*//;
        (undef,$m,$h,$day,$mon,$yr)=localtime();
        $mon++;
        $yr+=1900;
        $date=sprintf("%d-%02d-%02d %02d:%02d ",$yr, $mon, $day, $h,$m);
        if($l > $c{'killload'} and $count == 0){
                print OFP "$date load = $l WHOA! killing/restarting ".$c{'procs'}."\n";
                foreach $p (split(/,/,$c{'procs'})){
                        system("killall -TERM $p");
                        }
                sleep($c{'killsleep'});
                foreach $p (split(/,/,$c{'procs'})){
                        system("/etc/init.d/$p restart");
                        }
                $count=2;
                }
        elsif($l > $c{'restartload'} and $count == 0){
                print OFP "$date load = $l restarting ".$c{'procs'}."\n";
                foreach $p (split(/,/,$c{'procs'})){
                        system("/etc/init.d/$p restart");
                        }
                $count=2;
                }
        sleep($c{'stdsleep'});
        }
exit 0; # NOTREACHED

sub checkconfig {
        my $line;
        my %ret;
        my $file=shift;
        my $matched;

        my @c=qw(logfile stdsleep killsleep killload restartload procs);
        # sensible defaults for these things
        $ret{'logfile'}="/var/log/slicehostd.log";
        $ret{'stdsleep'}=60;
        $ret{'killsleep'}=20;
        $ret{'killload'}=10.0;
        $ret{'restartload'}=3.0;
        $ret{'procs'}="apache2,mysql";

        open(IFP,$file) or die "couldn't open config file $file : $!";
        while($line=<IFP>){
                $line=~s/#.*//;
                chomp $line;
                if($line=~/^\s*$/){ next; }
                $matched=0;
                foreach $w (@c){
                        chomp $w;
                        if($line=~/^$w=/){
                                $ret{$w}=$line;
                                $ret{$w}=~s/.*=//;
                                $matched=1;
                                }
                        }
                if(!$matched){
                        print STDERR "unknown config line $line\n";
                        }
                }
        close(IFP);
        return %ret;
}

sub daemonize {
    chdir '/'                 or die "Can't chdir to /: $!";
    open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
    open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
    open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
    defined(my $pid = fork)   or die "Can't fork: $!";
    exit if $pid;
    setsid                    or die "Can't start a new session: $!";
    umask 0;
}

sub usage {
print<<EOF;
slicehostd : daemon for running on a slicehost (or any low-RAM machine)
that restarts services when the load gets too high.  Config file is in
/etc/slicehostd.conf by default.  Config file should have comments in
it that explain what to do and how to do it.

Not quite finished; doesn't take any options yet.  Sorry.
EOF
exit 1;
}