How checkrestart Finds Services to Restart on Debian

When packages are upgraded on a Debian system, libraries and binaries on disk are replaced, but running processes continue executing the old code held in memory. The checkrestart utility, part of the debian-goodies package, solves this problem by identifying active processes that still reference deleted files and determining which system services need to be restarted. This article explains the underlying mechanism checkrestart uses to inspect the Linux process table, detect stale file descriptors, filter false positives, and map affected processes back to system services.

Inspecting the /proc Filesystem

The primary mechanism behind checkrestart relies on the Linux virtual /proc filesystem. When checkrestart runs, it iterates through all numeric directories in /proc, where each directory corresponds to an active Process ID (PID).

For each process, the tool reads the memory mappings located at /proc/[PID]/maps and checks the open file descriptors in /proc/[PID]/fd/.

Detecting Deleted Inodes

In Unix-like systems such as Debian, upgrading a package replaces files on disk using an atomic unlink-and-replace operation. If a daemon is actively running during an apt upgrade, its open handles to shared libraries (such as libc.so or libssl.so) or the executable binary remain valid in memory, even though the original files on the filesystem have been unlinked.

When a file mapped into a process's address space is unlinked, the Linux kernel appends the string (deleted) to the file path in /proc/[PID]/maps. For example:

7f1a2b3c0000-7f1a2b3d0000 r-xp ... /usr/lib/x86_64-linux-gnu/libssl.so.3 (deleted)

checkrestart parses these entries, searching for any path marked with (deleted). The presence of this flag indicates that the process is running on an outdated version of that file.

Filtering False Positives

Not every deleted file indicates that a service needs a restart. Applications frequently create and unlink temporary files, shared memory segments, or log files by design.

To prevent incorrect warnings, checkrestart employs internal exclusion rules and filters:

  • It ignores paths in temporary or virtual filesystems, such as /tmp, /var/tmp, /dev/shm, and /dev/zero.
  • It excludes common process types that allocate memory using unlinked anonymous files.
  • It checks configuration files (such as /etc/checkrestart.conf or custom blacklist flags) to suppress expected deletions.

Mapping Files to Debian Packages

Once stale files are detected, checkrestart verifies whether the deleted files originated from managed Debian packages. It cross-references the file paths against the dpkg database (similar to running dpkg -S <path>). This step ensures that manual file modifications or non-packaged custom scripts do not trigger false alerts for package-managed daemons.

Associating Processes with Init Scripts and Systemd Units

After isolating the PIDs holding outdated code, checkrestart identifies which background services own them.

  1. Systemd Services: It queries systemd by inspecting the cgroup path of the process via /proc/[PID]/cgroup to map the PID directly to a corresponding .service unit.
  2. SysVinit / Init Scripts: For legacy or alternate init systems, it cross-references the executable path found in /proc/[PID]/exe against scripts registered in /etc/init.d/.

Finally, checkrestart consolidates the output, grouping affected processes by service name and presenting the administrator with the exact service restart commands required to ensure the updated code is loaded into memory.