All pastes #763854 Raw Edit

Someone

public text v1 · immutable
·published 2007-11-06 20:14 UTC
rendered paste body
[root@host14 bin]# cat vpsd
#!/usr/bin/perl

eval 'exec /usr/bin/perl  -S $0 ${1+"$@"}'
    if 0; # not running under some shell

use strict;
use warnings;

use VPSHost;
use POSIX;
use Getopt::Long;

my $vpshost = new VPSHost('config_file' => '/usr/local/vpshost/etc/vpshost.conf','manager_connect' => 0);

unless(defined($vpshost)) {
        print "Failed to initalize VPSHost Module\n";
        exit(2);
}

my %options;
GetOptions (
        'v'     =>      \$options{'version'},
        'f'     =>      \$options{'forground'},
        'help'=>        \$options{'help'},
        'h'     => \$options{'help'}
);
$0 = 'vpsd';
my %children;

&showHelp if $options{'help'};

&daemonize unless $options{'forground'};
&setHandlers unless $options{'forground'};
&main;



sub showHelp {
        print "$0 <vfh>\n\n";
        print "\t-v\tVersion\n";
        print "\t-f\tRun in forground (logs dump to forground as well) \n";
        print "\t-h\tHelp\n";
        exit;
}

sub daemonize {
        chdir '/' or die "Can't chdir to /: $!";
        my $pid = fork;
        defined ($pid) or die "Cannot start deamon: $!";
        exit if $pid;

        POSIX::setsid();

        open( LOGFILE, '>>', "/var/log/vpsd.log" );
        open( STDOUT, ">&", \*LOGFILE );
        open( STDERR, ">&", \*LOGFILE );
        for(my $i=3;$i<1024;$i++) {
                POSIX::close($i);
        }
}

sub setHandlers {

        $SIG{__WARN__} = sub {
                $vpshost->logger('vpsd',2,"WARNING!" . join(" ", @_));
        };

        $SIG{__DIE__} = sub {
                $vpshost->logger('vpsd',3,"FATAL! " . join(" ", @_));
                exit;
        };

        $SIG{HUP} = $SIG{INT} = $SIG{TERM} = sub {
                my $sig = shift;
                $SIG{$sig} = 'IGNORE';
                kill 'INT' => values %children;
                $vpshost->logger('vpsd',3,"Killed by " . $sig);
                exit;
        };
        $SIG{CHLD} = \&REAPER;

}

sub REAPER {
        my $stiff;


        while(($stiff = waitpid(-1, &WNOHANG)) > 0) {
                if($? eq 0) {
                        $vpshost->logger('vpsd',1,"child process $stiff shutdown clean -- status $?");
                } else {
                        $vpshost->logger('vpsd',3,"child process $stiff shutdown with error -- status $?");
                }
                delete $children{$stiff};
        }

        $SIG{CHLD} = \&REAPER;
}

sub main {
        my %timers;
        while (1) {
                ## Queue Runner
                if( !$timers{'queuerunner'} or $timers{'queuerunner'} lt time() and !&childAlive('queuerunner') ) {
                        &newChild('queuerunner','run_queue',1);
                        $timers{'queuerunner'} = (time() + 30);
                }

                ## VPS State Monitor
                if( !$timers{'vps_status'} or $timers{'vps_status'} lt time() and !&childAlive('vps_status') ) {
                        &newChild('vps_status','check_vps_status',1);
                        $timers{'vps_status'} = (time() + 30);
                }

                ## Update Host Info
                if( !$timers{'update_host_info'} or $timers{'update_host_info'} lt time() and !&childAlive('update_host_info') ) {
                        &newChild('update_host_info','update_host_info',1);
                        $timers{'update_host_info'} = (time() + 3600);
                }

                ## CPU Usage Stats
                if( !$timers{'poll_cpu_stats'} or $timers{'poll_cpu_stats'} lt time() and !&childAlive('poll_cpu_stats') ) {
                        &newChild('poll_cpu_stats','poll_cpu_stats',1);
                        $timers{'poll_cpu_stats'} = (time() + 300);
                }

                ## Bandwidth Usage Stats
                if( !$timers{'poll_bandwidth_stats'} or $timers{'poll_bandwidth_stats'} lt time() and !&childAlive('poll_bandwidth_stats') ) {
                        &newChild('poll_bandwidth_stats','poll_bandwidth_stats',1);
                        $timers{'poll_bandwidth_stats'} = (time() + 300);
                }

                ## Sync Time/Date
                if( !$timers{'sync_datetime'} or $timers{'sync_datetime'} lt time() and !&childAlive('sync_datetime') ) {
                        &newChild('sync_datetime','sync_datetime',0);
                        $timers{'sync_datetime'} = (time() + 3600);
                }

                ## sleep to keep CPU sane...
                sleep 1;
        }
}


sub childAlive {
        my ($childname) = @_;

        if ( $children{$childname} and kill 0, $children{$childname} ) {
                return 1;
        } else {
                return 0;
        }
}


sub newChild {
        my ($childhandle,$childfunc,$manager_connect) = @_;

        my $pid;
        die "Cannot fork child: $!\n" unless defined($pid = fork);
        if($pid) {
                $children{$childhandle} = $pid;
                $vpshost->logger('vpsd',1,"Started child [".$childhandle."] pid(".$pid.")");
                return;
        }

        $SIG{HUP} = $SIG{CHLD} = $SIG{INT} = $SIG{TERM} = 'DEFAULT';
        $SIG{PIPE} = 'IGNORE';

        sleep 1;
        my $vpshost = new VPSHost('config_file' => '/usr/local/vpshost/etc/vpshost.conf','manager_connect' => $manager_connect);
        unless(defined($vpshost)) { print "$0 :: Failed to initialize VPSHost Module\n"; exit (2); }
        $0 = $childhandle;
        $vpshost->$childfunc;
        exit;
}