How Ubuntu Tracks “System Restart Required” Flag and Programmatic Detection Methods


3 views

Ubuntu systems track the need for a reboot through a simple but effective mechanism. When security updates requiring a reboot are installed, the system creates a flag file at /var/run/reboot-required. This triggers the dynamic MOTD system to display the "*** System restart required ***" message.

Instead of parsing MOTD (which can be unreliable), here are the professional methods:

# Method 1: Check for the existence of the flag file
if [ -f /var/run/reboot-required ]; then
    echo "System needs reboot"
fi

# Method 2: Using the needrestart tool (more detailed)
sudo apt install needrestart
needrestart -r l

Here's a complete Python solution you can integrate with Nagios:

#!/usr/bin/env python3
import os
import sys

REBOOT_REQUIRED_FILE = '/var/run/reboot-required'
REBOOT_PKGS_FILE = '/var/run/reboot-required.pkgs'

def check_reboot_needed():
    if not os.path.exists(REBOOT_REQUIRED_FILE):
        print("OK - No reboot required")
        return 0
    
    with open(REBOOT_REQUIRED_FILE, 'r') as f:
        reboot_reason = f.read().strip()
    
    packages = []
    if os.path.exists(REBOOT_PKGS_FILE):
        with open(REBOOT_PKGS_FILE, 'r') as f:
            packages = [line.strip() for line in f.readlines()]
    
    print(f"CRITICAL - Reboot required: {reboot_reason} | packages={','.join(packages)}")
    return 2

if __name__ == '__main__':
    sys.exit(check_reboot_needed())

Sometimes you need to specifically check for kernel updates:

#!/bin/bash
current_kernel=$(uname -r)
latest_kernel=$(find /boot -name 'vmlinuz-*' | sort -V | tail -n1 | sed 's|/boot/vmlinuz-||')

if [ "$current_kernel" != "$latest_kernel" ]; then
    echo "Kernel update pending (current: $current_kernel, latest: $latest_kernel)"
fi

For Ansible users, here's a playbook snippet to check reboot status:

- name: Check if reboot is required
  stat:
    path: /var/run/reboot-required
  register: reboot_required

- name: Report reboot status
  debug:
    msg: "System requires reboot"
  when: reboot_required.stat.exists

The companion file /var/run/reboot-required.pkgs lists which packages triggered the reboot requirement. This is valuable for logging and reporting:

#!/bin/bash
if [ -f /var/run/reboot-required.pkgs ]; then
    echo "Packages requiring reboot:"
    cat /var/run/reboot-required.pkgs
fi

For consistency across distros, you can use a similar approach to RHEL's needs-restarting:

#!/bin/bash
# Check if any services need restart (like daemons)
if which needs-restarting &>/dev/null; then
    needs-restarting -r
    if [ $? -eq 1 ]; then
        echo "Services need restart"
    fi
fi

When Ubuntu systems receive updates that require a reboot (particularly kernel updates), the system creates a flag file at:

/var/run/reboot-required

This is the primary mechanism that generates the "System restart required" message in MOTD. The presence of this file indicates a pending reboot.

Instead of parsing MOTD (which can be unreliable), here are better methods:

Method 1: Check the Flag File Directly

if [ -f /var/run/reboot-required ]; then
    echo "System needs reboot"
    exit 1
else
    echo "No reboot needed"
    exit 0
fi

Method 2: Using needrestart (More Comprehensive)

Install the package:

sudo apt install needrestart

Then check status:

needrestart -b

Nagios Plugin Example

#!/bin/bash

if [ -f /var/run/reboot-required ]; then
    REASON=$(cat /var/run/reboot-required.pkgs 2>/dev/null)
    echo "CRITICAL: Reboot required - $REASON"
    exit 2
else
    echo "OK: No reboot required"
    exit 0
fi

Prometheus Exporter Snippet

import os
from prometheus_client import Gauge

reboot_required = Gauge('system_reboot_required', 'System needs reboot')
if os.path.exists('/var/run/reboot-required'):
    reboot_required.set(1)
else:
    reboot_required.set(0)

For Ubuntu 14.04+ systems, you can also check:

/var/run/reboot-required.pkgs

This file lists which packages triggered the reboot requirement.

With Canonical Livepatch Service enabled, some kernel updates might not require immediate reboots. You can check livepatch status:

sudo canonical-livepatch status