Package: needrestart
Version: 2.8-1
Severity: wishlist
Tags: patch

Dear Maintainer,

on a system with a perl-based daemon spawned by postfix many many times,
needrestart was very slow.

That's because it re-scans all the perl module source files over and
over again, for each PID once, even though once per script should be
enough.

The patch attached is a crude hack against the jessie version (it
applies with some offsets/fuzz to the sid version), but on said system
the runtime is improved quite a bit:

before:

real    1m34.101s
user    1m30.924s
sys     0m2.988s

afterwards:

real    0m4.838s
user    0m4.384s
sys     0m0.264s

Obviously this would need to be done properly and not only for Perl.pm.

Cheers
Wolfgang

-- Package-specific info:
needrestart output:
Your outdated processes:
ApacheDirectory[9304], at-spi-bus-laun[2309], at-spi2-registr[2346], bash[2104, 
2116, 2110, 2243, 2245, 2108, 2246, 2241], chromium[3587, 3576, 3545, 3537], 
dane-plug[3958],
 dbus-daemon[2340, 1846], dbus-launch[1845], dconf-service[19859], 
dnssec-plug[3843], gconfd-2[3638], gkrellm[2055], gvfsd[1952], 
gvfsd-metadata[20750], gvfsd-trash[19829],
 gvfs-udisks2-vo[19817], mosh-client[8020], panel-13-systra[1983], 
panel-16-action[1984], sh[1809], systemd[1796], Thunar[1881], 
thunderbird[9255], tpb[1854],
 wicd-client[2092], xfce4-panel[1883], xfce4-session[1871], 
xfce4-volumed[2100], xfconfd[1875], xfdesktop[1982], xfrun4[9247], 
xfsettingsd[1888], xfwm4[1879],
 xscreensaver[2097], xterm[2062, 2056, 2058, 2061, 2063, 2060, 2059, 2057], 
x-www-browser[3634]

checkrestart output:


-- System Information:
Debian Release: stretch/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)

Kernel: Linux 4.5.0-2-686-pae (SMP w/4 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Init: sysvinit (via /sbin/init)

Versions of packages needrestart depends on:
ii  dpkg                       1.18.7
ii  gettext-base               0.19.7-2
ii  libintl-perl               1.24-1
ii  libmodule-find-perl        0.13-1
ii  libmodule-scandeps-perl    1.21-1
ii  libproc-processtable-perl  0.53-1+b1
ii  libsort-naturally-perl     1.03-1
ii  libterm-readkey-perl       2.33-1+b1
ii  perl                       5.22.2-1
ii  xz-utils                   5.1.1alpha+20120614-2.1

needrestart recommends no packages.

Versions of packages needrestart suggests:
ii  libnotify-bin  0.7.6-2

-- no debconf information
diff -Nurp a/usr/share/perl5/NeedRestart/Interp/Perl.pm b/usr/share/perl5/NeedRestart/Interp/Perl.pm
--- a/usr/share/perl5/NeedRestart/Interp/Perl.pm	2016-06-03 16:09:21.885469436 +0200
+++ b/usr/share/perl5/NeedRestart/Interp/Perl.pm	2016-06-03 16:13:04.181830614 +0200
@@ -83,6 +83,7 @@ sub source {
 sub files {
     my $self = shift;
     my $pid = shift;
+    my $files_cache = shift;
     my $ptable = nr_ptable_pid($pid);
     unless($ptable->{cwd}) {
 	print STDERR "$LOGPREF #$pid: could not get current working directory, skipping\n" if($self->{debug});
@@ -105,6 +106,13 @@ sub files {
 	return ();
     }
     my $src = $ARGV[0];
+    if ( defined($$files_cache{$src}) && $$files_cache{$src} == 1 ) {
+        print STDERR "already know $src\n" if ($self->{debug});
+        return ();
+    } else {
+        print STDERR "remembering $src\n" if ($self->{debug});
+        $$files_cache{$src} = 1;
+    }
     unless(-r $src && -f $src) {
 	chdir($cwd);
 	print STDERR "$LOGPREF #$pid: source file not found, skipping\n" if($self->{debug});
diff -Nurp a/usr/share/perl5/NeedRestart.pm b/usr/share/perl5/NeedRestart.pm
--- a/usr/share/perl5/NeedRestart.pm	2016-06-03 16:09:29.905626777 +0200
+++ b/usr/share/perl5/NeedRestart.pm	2016-06-03 16:09:29.905626777 +0200
@@ -132,6 +132,10 @@ sub needrestart_interp_init($) {
     }
 }
 
+{
+
+    my %files_cache = ();
+
 sub needrestart_interp_check($$$) {
     my $debug = shift;
     my $pid = shift;
@@ -144,7 +148,7 @@ sub needrestart_interp_check($$$) {
 	    print STDERR "$LOGPREF #$pid is a ".(ref $interp)."\n" if($debug);
 
 	    my $ps = nr_ptable_pid($pid);
-	    my %files = $interp->files($pid);
+	    my %files = $interp->files($pid, \%files_cache);
 
 	    if(grep {$_ > $ps->start} values %files) {
 		if($debug) {
@@ -161,6 +165,8 @@ sub needrestart_interp_check($$$) {
     return 0;
 }
 
+}
+
 sub needrestart_interp_source($$$) {
     my $debug = shift;
     my $pid = shift;

Reply via email to