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.confor 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.
- Systemd Services: It queries systemd by inspecting
the cgroup path of the process via
/proc/[PID]/cgroupto map the PID directly to a corresponding.serviceunit. - SysVinit / Init Scripts: For legacy or alternate
init systems, it cross-references the executable path found in
/proc/[PID]/exeagainst 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.