#!/usr/local/bin/perl # # Name: # sdps (super duper pooper scooper) # # Synopsis # cleans up some of the droppings that the watchdog leaves behind # # Options # see definition of &usage, or guess. # # History: # 0202.11 by David Mackintosh # initial revision # # Usefull Values. $BASENAME = $0; $BASENAME =~ s|\\|/|g; if ($BASENAME =~ m|(.*/)(.*)|) { $BASENAME = $2; } $| = 1; $SNOOZE = 100; # # code here. while ($#ARGV > -1) { $_ = shift @ARGV; if (!$command) { if (/^-DEBUG$/) { $DEBUG = 1; &debug("Debugging on"); next; } if (/^-SNOOZE$/) { $SNOOZE = shift @ARGV; next; } if (/^-SAFETY-OFF$/) { $SAFETY_OFF=1; next; } if (/^--HELP$/) { &usage("__SHOW_HELP"); } } $command = $command . " $_"; # &usage("$_"); } &usage("__SHOW_HELP") if (!$command); # # display the help message. # I find it usefull to leave this subroutine here, next to the parameter # parsing, as it makes it much easer to keep the help and the # actual parsing in sync. sub usage { $gripe = shift @_; print <<"EO_USAGE"; $BASENAME [options] command args Trims dead processes on Solaris by name -- MIND-BOGGLINGLY DANGEROUS -SNOOZE x sleep x seconds between cpu time tests, default 100 -SAFETY-OFF actually kill things --HELP print this screen Examples: $BASENAME command $BASENAME -SNOOZE 30 command EO_USAGE exit 0 if ($gripe eq "__SHOW_HELP"); &die("Don't understand:$gripe"); } &debug("command:$command"); $command =~ s/^\s*//; undef($unused); # collect # warning -- this PS line is for suns $PS = `/usr/bin/ps -eo pid,ppid,time,args| egrep \"$command\"`; @PSL = split (/\n/, $PS); foreach $ps (@PSL) { $_ = $ps; chop; s/^\s+//g; ($tpid, $tppid, $rtime, @junk) = split (/\s+/, $_); if ($tpid == $$) { $myParent=$tppid; next; } ($min, $sec) = split (/:/, $rtime); $rtime = ($min * 60) + $sec; &debug("$ps"); &debug("$tpid -> $rtime"); $Data{"$tpid"} = 1; $Data{"$tpid.time"} = $rtime; } close PS; &debug("sleeping..."); sleep($SNOOZE); $PS = `/usr/bin/ps -eo pid,ppid,time,args| egrep \"$command\"`; @PSL = split (/\n/, $PS); foreach $ps (@PSL) { next if ($ps == $myParent); $_ = $ps; chop; s/^\s+//g; ($tpid, $tppid, $rtime, @junk) = split (/\s+/, $_); next if (!$Data{$tpid}); ($min, $sec) = split (/:/, $rtime); $rtime = ($min * 60) + $sec; $time = $Data{"$tpid.time"}; &debug("$tpid: comparing $time to $rtime"); if ($rtime == $time) { &debug("killing $_"); kill(9, $tpid) if ($SAFETY_OFF); } } # # an easy way to change those back-ticks into # system() calls when we fuck up. sub doThis { local ($result); local ($thing) = pop @_; &debug("doing [$thing]"); # $result=system($thing); $result = `$thing`; &debug("finished shelling; output:\n$result"); &debug("output ends"); return $result; } # # Open our log file. sub openLog { if (!$LOGPATH) { &die("Set logpath in script"); } if (!open(LOG, ">$LOGPATH$BASENAME.$$.log")) { &die("log $LOGPATH$BASENAME.$$.log"); } } # # Add an item to the open log sub logItem { local ($gripe); $gripe = pop (@_); print LOG "$gripe\n" if ($LOGPATH); } # # A (braindead) undertaker. sub die { local ($gripe); $gripe = pop (@_); &warn("fatal:$gripe"); &logItem("fatal:$gripe"); exit 1; } # # A (braindead) friend for our undertaker. sub warn { local ($gripe); $gripe = pop (@_); print STDERR "$BASENAME:$gripe\n"; &logItem($gripe); } # # A simple debug outputer. sub debug { local ($gripe); $gripe = pop (@_); $DEBUG && print STDERR "DEBUG:$gripe\n"; $DEBUG && &log("DEBUG:$gripe"); } # a simple debug logger. sub log { local ($gripe); if ($LOG) { $gripe = shift @_; open(LOG, ">>$LOG"); print LOG "$$:$gripe\n"; close(LOG); } }