#! /usr/bin/perl # use Getopt::Long; use Sys::Syslog; $opt_u=99; $opt_a=0; $opt_k=0; $opt_n=0; $opt_s=0; &GetOptions(qw(u:i a n s k|kill=i)); my $MOMCTL = '/usr/sbin/momctl'; my $PBSMOM = '/usr/sbin/pbs_mom'; @lines=`ps -efl`; $opt_a and do { open MOMCTL,"$MOMCTL -h localhost -d 0 |" or die "Cannot run momctl: $!\n"; while() { chomp; /sidlist=/ and do { split(/=/); push @ARGV,$_[$#_]; }; } close MOMCTL; }; foreach ( @lines ) { ! /\d+/ && next; # remove header from ps -efl, which contains no number (PID!) chomp; split(/\s+/,$_,15); $opt_n and ($_[12] =~ /(tty|pts)/) and next; ( $_[14] eq "$PBSMOM" ) and $mompid=$_[3]; $children{$_[4]}.=" $_[3]"; $name{$_[3]} = $_[14]; $owner{$_[3]} = (getpwnam($_[2]))[2]; } @ARGV[0] or push @ARGV,$mompid; sub prunebranch($) { my ($pid) = @_; foreach ( split(/\s+/,$children{$pid}) ) { ($_ =~ /\d+/ ) and &prunebranch($_); } $name{$pid}=undef if $owner{$pid}; return; } sub removebranch($) { my ($pid) = @_; foreach ( split /\s+/, $children{$pid} ) { ($_ ne "") and &removebranch($_); } $children{$pid} = undef; $owner{$pid} = undef; $name{$pid} = undef; } foreach ( @ARGV ) { &prunebranch($_); } foreach ( keys %name ) { # Do not kill $PBSMOM if ($name{$_} =~ m!^\s*$PBSMOM\s*!) { &removebranch($_); } # option -s also forces removal of branches starting at an sshd if (! $opt_s and $name{$_} =~ /sshd: \w+\@pts/) { &removebranch($_); } } openlog("prune_userprocs", 'pid', 'user') or warn "Sys::Sylog:openlog failed\n"; foreach ( keys %name ) { ($owner{$_} > $opt_u) and $name{$_} and do { syslog('notice', "killing pid=%d uid=%s cmd=%s\n", $_, $owner{$_}, $name{$_}); if($opt_k) { kill $opt_k,$_; } }; } closelog();