/etc/xymon/misc.d/zombies is in hobbit-plugins 20131022.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #!/usr/bin/perl -w
use strict;
use File::Basename qw(dirname);
# Function to parse config file; splits at first blanks.
sub file_to_hash_of_regexp_keys_and_values($) {
my %regexps = ();
my $filename = shift;
open(my $fh, '<', $filename) or return %regexps;
while(<$fh>) {
unless (/^#|^\s*$/) {
chomp;
my ($key, $value) = split(/\s+/, $_, 2);
$regexps{$key} = $value;
}
}
return %regexps;
}
my $ext_apt_config = dirname($0).'/..';
my $ignore_file = $ext_apt_config."/zombies_ignore";
my %ignore = file_to_hash_of_regexp_keys_and_values($ignore_file);
chdir ("/proc");
my $zombies = 0;
foreach my $pid (glob ("[1-9]*")) {
open(F, '<', "$pid/status") or next;
my $maybe_zombie = 0;
while (<F>) {
if (/^State:\s+Z/) {
my $mtime = (stat ($pid))[9];
# Don't report zombies which are younger than 1 minute
last if not defined $mtime or time - $mtime < 60;
$maybe_zombie++;
last;
}
}
close F;
next unless $maybe_zombie;
# Check after 1 second if the process in question is still a
# zombie. Only report if that's the case.
sleep 1;
my $ignored = undef;
my $userignored = undef;
my $name = '';
open(F, '<', "$pid/status") or next;
my $zombie = 0;
while (<F>) {
if (/^Name:\s+(.*?)$/) {
$name = $1;
foreach my $regexp (keys %ignore) {
next if $regexp =~ /:\^/;
if ($name =~ /^$regexp$/) {
$ignored = $ignore{$regexp};
}
}
}
if (/^State:\s+Z/) {
my $mtime = (stat ($pid))[9];
last if not defined $mtime or time - $mtime < 60;
$zombie = 1;
}
if (/^Uid:\s+(\d+)\s/) {
my $username = getpwuid($1);
foreach my $regexp (keys %ignore) {
next unless $regexp =~ /:\^/;
my ($user_re, $process_re) = split(/:\^/, $regexp, 2);
if ($username =~ /^$user_re$/ and
$name =~ /^$process_re$/) {
$userignored = "$username: $ignore{$regexp}";
}
}
last;
}
}
close F;
if ($zombie) {
system "ps u $pid";
if ($ignored) {
print "($name zombies ignored: $ignored)\n";
} elsif ($userignored) {
print "($name zombies ignored under user $userignored)\n";
} else {
$zombies++;
}
}
}
if ($zombies) {
exit 1;
} else {
print "No zombie processes\n";
exit 0;
}
|