skip to content

On a RHEL 9 host, `dnf upgrade` has installed patched openssl and glibc packages, but a scanner still reports the vulnerable versions in running processes. Why, and which dnf command tells you what to restart or whether to reboot?

level: seniorimportance: should knowfreq 42%

answer

  1. files replaced, running processes untouched
  2. restart is the missing step
  3. a dnf plugin answers this
  4. -s for services, -r for reboot
  5. the exit status drives automation

basics

~20 s

Upgrading a package replaces files on disk; processes already running keep using the code they loaded at start-up, so they stay vulnerable until restarted. dnf needs-restarting lists those processes, -s maps them to systemd services, and -r says whether a reboot is recommended.

solid answer

~50 s

Installing a package is a filesystem operation — the new library is on disk, but every process that started before the upgrade continues running the code it loaded then, so a scanner looking at running processes is right and the patch is genuinely not in effect. The tool for this is `dnf needs-restarting`, from `dnf-plugins-core`: bare, it lists the running processes whose files have been replaced since they started; `dnf needs-restarting -s` gives the systemd services to restart, which is the form you actually act on; and `dnf needs-restarting -r` answers the different question of whether a full reboot is recommended, signalling it through the exit status so you can drive automation from it. Core packages like the kernel, glibc and systemd mean a reboot rather than a service restart. My patch runbook is upgrade, `-r`, then either reboot or `systemctl restart` the units from `-s`, then re-scan.

code

bash · 10 lines
bash
sudo dnf -y upgrade

# Which running processes are still using replaced files?
dnf needs-restarting

# Which systemd services should be restarted?
dnf needs-restarting -s

# Is a full reboot recommended? (exit status signals the verdict)
dnf needs-restarting -r || sudo systemctl reboot

go deeper

for a junior

Know that installing a package updates files on disk and that services already running keep using the old code until they are restarted, so a patch is not live until something restarts.

for a middle

Explain the mechanics and the tool: dnf needs-restarting from dnf-plugins-core, what its bare output means, and that -s lists services while -r answers the reboot question.

for a senior

Show the runbook — upgrade, check the reboot hint, roll restarts of the listed units with draining, then re-verify — and be able to say why the kernel and glibc land on the reboot side of that decision.

for a principal

Own the patch policy: what triggers a fleet reboot versus a rolling restart, how the reboot hint's exit status drives automation, and how host patching and container image rebuilds are kept as two tracked pipelines rather than one assumed one.

## Why the patch is on the box but not in effect A package upgrade is a file operation. dnf lays down the new `libcrypto` or `libc` and updates the RPM database, and from that moment anything *newly started* uses the patched code. What it cannot do is reach into a process that is already running: that process loaded its executable and its shared libraries when it started and goes on using them for its whole lifetime. So a service that has been up for forty days is still running the vulnerable code, and a scanner that inspects running processes rather than the package database is telling you the truth. This is the gap between "patched" and "remediated", and it is the whole point of the question. Reporting a patch window as complete on the strength of `dnf upgrade` exiting zero is the mistake being probed for. ## The tool `dnf needs-restarting`, provided by the `dnf-plugins-core` package, exists exactly for this. Three forms matter: ```bash dnf needs-restarting # running processes whose files were replaced dnf needs-restarting -s # the systemd services to restart dnf needs-restarting -r # is a full reboot recommended? ``` The bare form prints PIDs with their command lines — every process started before the files it uses were updated. It is the raw evidence, useful when you want to see that it is a long-lived worker rather than something that will cycle on its own. `-s` is the form you act on, because it translates those processes into the systemd units that own them, and units are what you restart. Restarting the unit starts a fresh process which maps the patched libraries, and that is remediation for a userspace library. `-r` answers a different question: whether the update touched something that cannot be fixed by restarting a service — the kernel above all, but also core userspace like glibc, systemd or dbus, where restarting every dependent process is neither practical nor safe. It reports its verdict in the exit status as well as in text, which is what makes it usable in a script or a configuration-management run: check it, and reboot the host only when it says so. ## Turning it into a patch procedure A defensible sequence for a patch window looks like this: 1. `dnf upgrade` (or a security-only variant of it) and record the transaction ID from `dnf history` so you know what changed. 2. `dnf needs-restarting -r`. If it says reboot, schedule the reboot and stop — a reboot subsumes every service restart. 3. Otherwise take the unit list from `dnf needs-restarting -s` and restart those units, respecting whatever ordering or draining your service needs. This is where a load balancer and rolling restarts matter more than the dnf command does. 4. Re-run the check, and re-scan. If a process still shows up, something restarted it into the old state or the unit was not the owner you thought. The kernel deserves its own line. A kernel package installs alongside the running one rather than replacing it, so nothing about the running system changes until you boot into it. `needs-restarting -r` is the honest reporter of that fact. ## The judgment part The interesting disagreement in real organisations is not which flag to use, it is what you do with the answer. Restarting services individually keeps uptime but leaves you reasoning about a long tail of processes — cron-spawned children, forked workers, an agent nobody owns. Rebooting is coarse, costs a maintenance window, and is completely unambiguous: after a reboot, nothing is running old code. Many teams settle on "reboot on kernel or core-library updates, rolling service restarts otherwise", which is exactly the policy `-r` is designed to drive. The containerised case flips the burden. You do not restart a process inside a container to patch it; you rebuild the image with the updated packages and replace the container. `needs-restarting` is a host tool, and on a container host it is telling you about host processes — the containers running on it are a separate patching path entirely. ## What a weak answer sounds like "dnf handles it" — it does not; nothing in a package transaction restarts your services for you. Or the opposite overcorrection, that only a reboot can ever apply a library patch, which is not true either: restarting the service is sufficient for a userspace library and is the reason `-s` exists as a separate answer from `-r`.

  • When is restarting the service enough, and when do you actually have to reboot?
    Restarting is enough for userspace libraries and the binaries a service loads: the new process maps the patched code. A reboot is required for the kernel, since a kernel package installs alongside the running one and changes nothing until you boot it, and it is the practical answer for core userspace such as glibc, systemd or dbus, where essentially everything on the box is a dependent process. `dnf needs-restarting -r` is what makes that call for you.
  • How does this change on a host that only runs containers?
    It splits into two patching paths. `dnf needs-restarting` on the host reports host processes — the container runtime, the SSH daemon, agents — and those you restart or reboot normally. The packages inside a container are not patched by the host's dnf at all: you rebuild the image with updated packages and replace the running container. Treating the host upgrade as covering the workloads is the classic mistake.
  • You restarted the units from `-s`, but the same process still appears afterwards. What would you check?
    Either the unit you restarted is not the one that owns that process — something else respawns it, such as a supervisor, a cron job or a container runtime — or the process was started outside systemd entirely, so no unit restart will touch it. Check the PID's parent and cgroup, and if nothing owns it cleanly, that is an argument for rebooting rather than continuing to chase it.

Patching the library on disk is like putting a corrected edition on the shelf: everyone already reading the old copy in their hands keeps reading the old text until they go back and pick up the new one.

saying these in an interview costs you the question

  • Assuming dnf restarts affected services automatically
  • Reporting a patch complete because dnf upgrade exited zero
  • Claiming only a reboot can ever apply a library patch
  • Believing a kernel package takes effect without a reboot
  • Thinking a host upgrade patches the containers running on it

context