[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 \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; }