Hi Axel,
On 05/01/2014 12:13 PM, Axel Beckert wrote:
The problem is the second scanning pass which looks for the parent
processes. It seems to happen if a process is a child of a kernel
thread... sadly I could not reproduce it, yet.
Strange. I really wonder what's so different on my boxes. Did you try
it with Debian Unstable kernels? Or rather with Debian Stable kernels?
Maybe there changed something which causes this behaviour. (I haven't
tried 0.8 on Stable yet.)
another trigger to break readlink /proc/<pid>/exe seems to be a
permission issue. Example:
$ stat /proc/`pidof -s kdm`/exe
File: ‘/proc/28931/exe’stat: cannot read symbolic link
‘/proc/28931/exe’: Permission denied
Size: 0 Blocks: 0 IO Block: 1024 symbolic link
Device: 3h/3d Inode: 3131274 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2014-05-05 20:39:01.701539207 +0200
Modify: 2014-05-05 20:15:58.193830135 +0200
Change: 2014-05-05 20:15:58.193830135 +0200
Birth: -
Does the system has any enhanced security mechanism established?
I've attached a small debug script (modified needrestart script) which
analysis the processes and looks for non-readable /proc/<pid>/exe
symlinks. Could you please run it once and provide it's output?
TIA,
Thomas
--
:: WWW: http://fiasko-nw.net/~thomas/ ::
::: Jabber: xmpp:tho...@jabber.fiasko-nw.net :::
:: flickr: http://www.flickr.com/photos/laugufe/ ::
#!/usr/bin/perl
use Getopt::Std;
use NeedRestart;
use NeedRestart::UI;
use NeedRestart::Utils;
use warnings;
use strict;
our %nrconf = (
verbose => 1,
hook_d => '/etc/needrestart/hook.d',
restart => 'l',
defno => 0,
blacklist => [],
interpscan => 1,
kernelhints => 1,
);
$nrconf{ui} = qq(NeedRestart::UI::stdio);
warn "WARNING: This program should be run as root!\n" if($< != 0);
# get UI
my $ui = needrestart_ui($nrconf{verbose}, $nrconf{ui});
die "Error: no UI class available!\n" unless(defined($ui));
# inspect only pids
my $ptable = nr_ptable();
$ui->progress_prep(scalar keys %$ptable, 'Scanning processes', 1);
my %stage2;
for my $pid (sort {$a <=> $b} keys %$ptable) {
my $restart = 0;
# get executable (Linux 2.2+)
$ui->progress_step($ptable->{$pid}->{exec});
# ignore kernel threads
next unless(defined($ptable->{$pid}->{exec}));
# orphaned binary
$restart++;
# find parent process
my $ppid = $ptable->{$pid}->{ppid};
if($ppid != $pid && $ppid > 1) {
print STDERR "#$pid is a child of #$ppid\n" if($nrconf{verbose});
unless(exists($stage2{$ppid})) {
# ignore kernel threads
unless(defined($ptable->{$ppid}->{exec})) {
warn "#$pid is a child of a kernel process!\n";
use Data::Dumper;
print Dumper($ptable->{$pid}, $ptable->{$ppid});
}
$stage2{$ppid} = $ptable->{$pid}->{exec};
}
}
else {
print STDERR "#$pid is not a child\n" if($nrconf{verbose});
$stage2{$pid} = $ptable->{$pid}->{exec};
}
}
$ui->progress_fin(1);