#!/usr/local/bin/perl -s use strict; use RCGI::Config; use vars qw( $verbose); $| = 1; my($log_file) = $RCGI::Config::path . "/sar"; my(%SAR); dbmopen(%SAR,$log_file,0664); my($do_restart) = 0; map { if (/not_responding/) { $do_restart = 1; } } (sort (keys %SAR)); dbmclose(%SAR); if ($verbose) { print "Do Restart: " . ($do_restart ? 'true' : 'false') . "\n"; } if ($verbose) { print "Kill\n"; } Kill_Defunct('sar','',$do_restart); if ($verbose) { print "Kill -9\n"; } while(Kill_Defunct('sar','-9',$do_restart)) {} if ($verbose) { print "Restart\n"; } Restart_Sard('sar'); sub Kill_Defunct { my($username) = shift; my($kill_level) = shift; my($force_restart) = shift; my($user,$pid, $ppid, $gid, $sid); my($do_kill) = ($force_restart) ? 1 : 0; my($found_kill); my(%to_kill); my($do_sleep); open(PS,"ps -fj -u $username |"); while() { s/^\s*//; s/\s+/\t/g; if (/sard/ && $_ !~ /sardcheck/) { ($user, $pid, $ppid, $gid, $sid) = split("\t"); if (//) { if ($verbose) { print "Defunct: $user $pid $ppid\n"; } $do_kill = 1; $found_kill = 1; if ($ppid == 1) { $to_kill{$pid} = 1; } else { $to_kill{$ppid} = 1; } } # kill pid if parent is 1 but gid is not pid if ($ppid == 1 && $pid != $gid) { if ($verbose) { print "Orphan: $user $pid $ppid $gid\n"; } $do_kill = 1; $found_kill = 1; $to_kill{$pid} = 1; } } } close(PS); if ($do_kill) { map { $do_sleep = 1; print STDERR "Killing $_\n"; `kill $kill_level $_ > /dev/null 2>&1`; } (keys %to_kill); if ($do_sleep) { if ($verbose) { print "kill $kill_level: Sleep: 30\n"; } sleep 30; } } return $found_kill; } sub Restart_Sard { my($username) = shift; my($user,$pid, $ppid, $gid, $sid); open(PS,"ps -fj -u $username |"); while() { if (/sard/ && $_ !~ /sardcheck/) { s/\s+/\t/g; ($user, $pid, $ppid, $gid, $sid) = split("\t"); if ($verbose) { print; } last; } } close(PS); if (!defined($ppid)) { print STDERR "Restart sard\n"; `cd /usr/rcgi ; /usr/rcgi/sard sard.conf sar > /dev/null &`; if ($verbose) { print "Sleep: 30\n"; } sleep 30; `$0`; } }