4

unattended-upgrades in Ubuntu automatically installs security updates including the kernel but does not reboot automatically (and it's OK, I don't need/want automatic reboots).

How can I find out whether the running kernel = the latest installed kernel?

I can get the current kernel version by:

$ uname -r
5.4.0-104-generic

The latest installed kernel can be found out by:

$ dpkg -s linux-image-generic | awk '/Version:/{print $2}'
5.4.0.104.108

These two don't match. I can use bash sorcery to compare these two strings (and then .108 needs to go - why?) but I'd prefer to use something standard.

Artem S. Tashkinov
  • 26,392
  • 4
  • 33
  • 64

3 Answers3

5

The following is what I use, and should work across different distros.

#!/usr/bin/env bash

HIGHEST_KERNEL=`find /boot/vmlinuz-* | sort -V | tail -n 1 | sed 's|.*vmlinuz-||'`
RUNNING_KERNEL=`uname -r`
echo "Highest Kernel: $HIGHEST_KERNEL | Running Kernel: $RUNNING_KERNEL"
if [ "$HIGHEST_KERNEL" != "$RUNNING_KERNEL" ]; then
  echo "** Reboot Required **"
  exit 1
fi
bomp
  • 51
  • 1
2

In such situations, on the assumption that the system always boots the latest kernel, I compare the boot time to the kernel image’s timestamp. The simplest way to do that is to use /proc/1 as a proxy:

find /boot -newer /proc/1 -name vmlinuz\*

If that lists anything, the system needs to be rebooted (which can be done with an appropriate -exec).

If you only use packaged kernels, you can also check for the presence of /run/reboot-required; if it exists, a reboot is required. /run/reboot-required.pkgs will list the packages which requested a reboot.

You can also use needrestart from the eponymous package:

needrestart -k
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • This all looks a little bit finicky, uncertain and fuzzy. In Fedora/RHEL/OpenSuse this can be verified to a letter without any tricks. I wonder why Ubuntu/Debian make it so damn difficult. I really need a simple `if [ $version_installed = $version_running ]; then echo "We are fine"; fi` – Artem S. Tashkinov Mar 09 '22 at 21:09
  • Well, how about `if [ ! -f /run/reboot-required ]; then echo "We are fine"; fi`? – Stephen Kitt Mar 09 '22 at 21:12
  • This file may or may not exist, I may have had a FS malfunction, I may have deleted or added new kernels manually, it's inconsequential. I've found out how to verify this, I'm now penning an answer – Artem S. Tashkinov Mar 09 '22 at 21:14
  • If `/run` malfunctions, you’re in trouble anyway ;-). – Stephen Kitt Mar 09 '22 at 21:20
0

Ubuntu makes it unusually difficult for some reasons and the answer below applies only (!) to Ubuntu 20.04 LTS and may or may not work for other releases.

So, like I mentioned in the question you can get the latest installed kernel by:

$ version_installed=`dpkg -s linux-image-generic | awk '/Version:/{print $2}'`
$ echo "$version_installed"
5.4.0.104.108

The last number, #108, doesn't seem relevant, so let's trim it:

$ version_installed=`dpkg -s linux-image-generic | awk '/Version:/{print $2}'` | awk -F . '{print $1"."$2"."$3"."$4}'` # this can be improved but I'm too lazy
$ echo "$version_installed"
5.4.0.104

uname -r gives us the version with some unnecessary bits: 5.4.0-104-generic. Let's fix it:

$ version_running=`uname -r | sed 's/-generic//;s/-/\./;` # could be simplified as well
$ echo "$version_running"
5.4.0.104

Now we can

#! /bin/bash

version_installed=`dpkg -s linux-image-generic | awk '/Version:/{print $2}' | awk -F . '{print $1"."$2"."$3"."$4}'`
version_running=`uname -r | sed 's/-generic//;s/-/\./'`

if [ "$version_installed"  = "$version_running" ]; then
    echo "All Good"
else
    echo "Life is a misery"
fi
Artem S. Tashkinov
  • 26,392
  • 4
  • 33
  • 64