Which services need restarting after an upgrade?

After you’ve run yum update to upgrade libraries, there may be services running which are still using the old copies of libraries. Such services might still be vulnerable to security bugs in the old libraries.

It’s relatively easy to discover which processes are affected using lsof to list processes using deleted files:

# lsof | awk '$5 == "DEL" { print }'
auditd     1001  1001 root DEL REG /usr/lib64/libnss_files-2.18.so;53bd9626
libvirtd   1468  1509 root DEL REG /usr/lib64/libnss_files-2.18.so;53bd9626
[lots more output]

If you actually run this command after updating (say) glibc, you’ll get pages and pages of output which is hard to sift through.

However with systemd we can map the process IDs to services and user sessions.

That’s what the following script does:

http://oirase.annexia.org/rwmj.wp.com/needs-restart.pl

Typical output looks like this:

In order to complete the installation of glibc-2.18-11.fc20.x86_64,
you should restart the following services:

    - accounts-daemon.service - Accounts Service   
    - console-kit-daemon.service - Console Manager
    - udisks2.service - Disk Manager
    - auditd.service - Security Auditing Service
    - dbus.service - D-Bus System Message Bus
    - rtkit-daemon.service - RealtimeKit Scheduling Policy Service
    - upower.service - Daemon for power management
    - colord.service - Manage, Install and Generate Color Profiles
    - firewalld.service - firewalld - dynamic firewall daemon
    - polkit.service - Authorization Manager
    - rsyslog.service - System Logging Service 
    - NetworkManager.service - Network Manager   
    - libvirtd.service - Virtualization daemon
    - gdm.service - GNOME Display Manager

In order to complete the installation of glibc-2.18-11.fc20.x86_64,
you should tell the following users to log out and log in:

    - session-1.scope - Session 1 of user rjones

18 Comments

Filed under Uncategorized

18 responses to “Which services need restarting after an upgrade?

    • rich

      And that’s fine, although it doesn’t do much more than the first “lsof” command I posted. In particular, it doesn’t map the PIDs to systemd services and give you a nice report about what needs to be restarted in order to complete the upgrade of what package.

  1. dominik

    Wow, really cool! Thanks! It would be great to have this added as a yum/dnf plugin!

    • Conrad

      Just came here to say the same — looks very helpful, definitely something I hit a fair amount. Thanks for sharing.

  2. This must be part of systemd. Outstanding.

    • rich

      I don’t know if you mean it is already part of systemd, or it should be part of systemd, but yes I think systemd could incorporate something like this. At the very least systemd could make this feature a bit easier to implement by having an implementation of systemctl show which takes a PID as argument.

  3. Hi Rich,
    I noticed that that your script can sometimes output some errors such as:
    “lsof: WARNING: can’t stat() fuse.gvfsd-fuse […]”
    and others about some missing “*.#prelink#.*” files
    BTW today I stumbled upon /usr/bin/needs-restarting provided by yum-utils; another (python) script which performs a task similar to “lsof | awk ‘$5 == “DEL” { print }’”.

  4. Fedora already has the needs-restarting command in the yum-utils package.

    • rich

      Sure, but it just produces a big list of processes. Mapping them to systemd cgroups is the key to making the output useful.

      • By the way, D-Bus for the win:

        
        # gdbus call --system --dest org.freedesktop.systemd1 \
          --object-path /org/freedesktop/systemd1 \
          --method org.freedesktop.systemd1.Manager.GetUnitByPID \
          `pidof sshd`
        (objectpath '/org/freedesktop/systemd1/unit/sshd_2eservice',)
        
        

        (I hope that got formatted correctly)

  5. mysqld seems to have a lot of results that aren’t cleared by restarting it:

    mysqld 477 505 mysql DEL REG 0,10 1922471 /[aio]
    mysqld 477 505 mysql DEL REG 0,10 1922470 /[aio]
    mysqld 477 505 mysql DEL REG 0,10 1922469 /[aio]
    mysqld 477 505 mysql DEL REG 0,10 1922479 /[aio]
    mysqld 477 505 mysql DEL REG 0,10 1922468 /[aio]

    (and many more, I just copied a few mines).

  6. Hello,
    I am working on similar project called tracer. It prints list of applications you should restart. It also suggests the way, how to restart them. And bonus: it has dnf plugin so you can see the list after every dnf transaction. There is examples how it looks like in User Guide linked below.

    Unlike needs-restarting from yum-utils it is more user-friendly and easily portable to another distributions.

    If you are interested you can see:
    Github – https://github.com/FrostyX/tracer
    Wiki – https://github.com/FrostyX/tracer/wiki
    User Guide – https://github.com/FrostyX/tracer/wiki/User-Guide

  7. I started using tracer last week (and am generally averse to perl), but just came across this and … damn that is one sweet script Richard.

  8. Orion Poplawski

    Just some minor cleanup for when the updated filename changes:

    diff --git a/roles/server/files/needs-restart.pl b/roles/server/files/needs-restart.pl
    index ee1aa9e..a4f4eaf 100755
    --- a/roles/server/files/needs-restart.pl
    +++ b/roles/server/files/needs-restart.pl
    @@ -42,9 +42,9 @@ foreach $proc (@procs) {
         my $service = $services_cache{$proc->{pid}};
    
         unless (exists $pkgs_cache{$proc->{file}}) {
    -        my $pkg = `rpm -qf $proc->{file}`;
    +        my $pkg = `rpm -qf $proc->{file} 2>&-`;
             chomp $pkg;
    -        $pkgs_cache{$proc->{file}} = $pkg;
    +        $pkgs_cache{$proc->{file}} = $pkg ? $pkg : "";
         }
         my $pkg = $pkgs_cache{$proc->{file}};
    
  9. Orion Poplawski

    Even more problematic – lsof output often as the TID field blank. This should fix:

    diff --git a/roles/server/files/needs-restart.pl b/roles/server/files/needs-restart.pl
    index a4f4eaf..8e99e68 100755
    --- a/roles/server/files/needs-restart.pl
    +++ b/roles/server/files/needs-restart.pl
    @@ -10,19 +10,34 @@
     use strict;
    
     # Parse lsof output.
    -my @lines = qx{ lsof };
    +my @lines = qx{ lsof -F cpLfn };
     my @procs = ();
    +my $pid;
    +my $comm;
    +my $user;
    +my $fd;
    +my $file;
     foreach (@lines) {
         chomp;
    -    my @fields = split;
    -    if ($fields[4] eq "DEL" && $fields[8] =~ /\.so/) {
    -        my $comm = $fields[0];
    -        my $pid = $fields[1];
    -        my $user = $fields[3];
    -        my $file = $fields[8];
    +    if (/^p(\d+)/) {
    +        $pid = $1;
    +        next;
    +    } elsif (/^c(.*)/) {
    +        $comm = $1;
    +        next;
    +    } elsif (/^L(.*)/) {
    +        $user = $1;
    +        next;
    +    } elsif (/^f(.*)/) {
    +        $fd = $1;
    +        next;
    +    } elsif (/^n(.*)/) {
    +        $file = $1;
             $file =~ s/;[a-f0-9]{8}//;
    -        push @procs,
    -        { comm => $comm, pid => $pid, user => $user, file => $file };
    +        if ($fd eq "DEL" && $file =~ /\.so/) {
    +            push @procs,
    +            { comm => $comm, pid => $pid, user => $user, file => $file };
    +        }
         }
     }
    
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s