Bug 2137935 - dnf needs-restarting always true
Summary: dnf needs-restarting always true
Alias: None
Product: Fedora
Classification: Fedora
Component: dnf-plugins-core
Version: 37
Hardware: aarch64
OS: Linux
Target Milestone: ---
Assignee: Jan Kolarik
QA Contact: Fedora Extras Quality Assurance
Whiteboard: RejectedBlocker
Depends On:
TreeView+ depends on / blocked
Reported: 2022-10-26 15:57 UTC by todd_lewis
Modified: 2023-04-08 02:36 UTC (History)
17 users (show)

Fixed In Version: dnf-plugins-core-4.4.0-1.fc37
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Last Closed: 2023-04-08 02:36:25 UTC
Type: Bug

Attachments (Terms of Use)

System ID Private Priority Status Summary Last Updated
Red Hat Bugzilla 1913962 0 medium CLOSED "dnf needs-restarting -r" work incorrectly inside systemd-nspawn containers 2023-05-29 09:31:48 UTC

Description todd_lewis 2022-10-26 15:57:56 UTC
Description of problem:
`dnf needs-restarting -r` always claims dbus, dbus-broker, dbus-daemon, glibc, kernel, linux-firmware, and systemd have been updated since boot-up, even immediately after boot-up.

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. reboot
2. run `dnf needs-restarting -r`

Actual results:
# dnf needs-restarting -r
Core libraries or services have been updated since boot-up:
  * dbus
  * dbus-broker
  * dbus-daemon
  * glibc
  * kernel
  * linux-firmware
  * systemd

Reboot is required to fully utilize these updates.
More information: https://access.redhat.com/solutions/27943

Expected results:
# dnf needs-restarting -r
No core libraries or services have been updated since boot-up.
Reboot should not be necessary.

Additional info:
Because this host is a "Raspberry Pi 3 Model B+" which has no real time clock, the initial clock value on boot apparently is being set by the compile time of some component. Pure speculation, but could dnf be grabbing the timestamp on the first record of the equivalent of `journalctl -b` -- which is demonstrably wrong b/c the clock was wrong -- instead of the first date-time shown for `journalctl --list-boots | tail -n 1` -- which is correct?

Comment 1 Fedora Blocker Bugs Application 2022-10-26 19:27:27 UTC
Proposed as a Blocker for 37-final by Fedora user coremodule using the blocker tracking app because:

 Proposing as a potential F37 as a possible violation of the "Installing, removing and updating software" criterion. [0]

[0] https://fedoraproject.org/wiki/Fedora_37_Final_Release_Criteria#Installing,_removing_and_updating_software

Comment 2 Brian Morrison 2022-10-26 19:43:08 UTC
Just tried this with the same dnf version.

[bdm@deangelis ~]$ dnf needs-restarting -r
No core libraries or services have been updated since boot-up.
Reboot should not be necessary.

Works for me.

Comment 3 todd_lewis 2022-10-26 20:17:36 UTC
determines boot time by checking st_mtime of /proc/1

    def get_boot_time():
        return int(os.stat('/proc/1').st_mtime)

which is 0 on my current system

# ls -ld /proc/1
dr-xr-xr-x. 9 root root 0 Dec 31  1969 /proc/1

Comment 4 todd_lewis 2022-10-26 20:47:36 UTC
BTW: `uptime` shows the correct values on the same system where /proc/1 st_mtime is 0.
`strace uptime` shows that "uptime" reads "/proc/uptime".
This is kernel-5.19.16-301.fc37.aarch64 on a "Raspberry Pi 3 Model B+".

Comment 5 todd_lewis 2022-10-27 11:47:53 UTC
The only reliable method of determining boot time I've found on this system is to subtract /proc/uptime's seconds from the current time. The following diff seems to do the Right Thing:
--- /usr/lib/python3.11/site-packages/dnf-plugins/needs_restarting.py-1666868784	2022-09-23 02:50:37.000000000 -0400
+++ /usr/lib/python3.11/site-packages/dnf-plugins/needs_restarting.py	2022-10-27 07:45:10.683280191 -0400
@@ -34,6 +34,7 @@
 import os
 import re
 import stat
+import time
 # For which package updates we should recommend a reboot
@@ -199,7 +200,9 @@
     def get_boot_time():
-        return int(os.stat('/proc/1').st_mtime)
+        with open('/proc/uptime') as uptime:
+            uptimes = uptime.read().strip().split()
+        return time.time() - int(uptimes[0].split('.')[0])
     def get_sc_clk_tck():

Comment 6 todd_lewis 2022-10-27 13:38:38 UTC
Paying more attention to types, that should return an int:

        return int(time.time() - float(uptimes[0]))

Comment 7 Adam Williamson 2022-10-27 16:38:13 UTC
-8 in https://pagure.io/fedora-qa/blocker-review/issue/988 , marking rejected.

Comment 8 todd_lewis 2022-10-31 03:02:49 UTC
(In reply to Brian Morrison from comment #2)
> Just tried this with the same dnf version.
> [bdm@deangelis ~]$ dnf needs-restarting -r
> No core libraries or services have been updated since boot-up.
> Reboot should not be necessary.
> Works for me.

Does that system have an Real Time Clock?

Comment 10 Brian Morrison 2022-10-31 10:29:09 UTC
Yes, it's running on an Asus H370Mplus motherboard, fairly standard PC.

Comment 11 Jan Kolarik 2022-11-03 09:56:55 UTC
As @amatej mentioned in the previous comment (https://bugzilla.redhat.com/show_bug.cgi?id=2137935#c9), this solution is already being discussed in the https://github.com/rpm-software-management/dnf-plugins-core/pull/466 PR, more comments are there. But as for now, this change seems to break the existing functionality for the systemd-nspawn containers. I've also added a linked bugzilla here: https://bugzilla.redhat.com/show_bug.cgi?id=1913962.

Comment 12 todd_lewis 2022-11-05 02:44:23 UTC
For machines which have no real time clock, such as Raspberry Pi 3 Model B+, the system boots at the beginning of the epoch:

> # stat -c %y /proc/1
> 1969-12-31 19:00:04.539999998 -0500

thus `needs-restarting` is always true.

Perhaps the better solution is to take the greater of the two values:
 -  int(os.stat('/proc/1').st_mtime)
 -  current time minus /proc/uptime's seconds (as per this patch).

That should continue to work reliably on bare metal (even after hibernation), virtual machines, podman containers, and systemd-nspawn containers, _AND_ will also start to work on machines which boot with clocks set hopelessly far into the past -- assuming of course that the current time is reasonably correct.

Comment 13 todd_lewis 2022-11-16 16:05:52 UTC
There's a PR implementing the suggestion in comment #12

Comment 14 Jan Kolarik 2022-11-23 15:19:01 UTC
Fixed by the PR mentioned in comment 13. Thanks Todd!

Comment 15 Brad Smith 2022-11-27 22:51:14 UTC
Glad to see the PR in comment #13. This "problem" has been vexing me on the 4 Pis I run in a home lab.

Comment 16 Fedora Update System 2023-04-05 13:45:29 UTC
FEDORA-2023-1b65a60b93 has been submitted as an update to Fedora 37. https://bodhi.fedoraproject.org/updates/FEDORA-2023-1b65a60b93

Comment 17 Fedora Update System 2023-04-06 02:52:20 UTC
FEDORA-2023-1b65a60b93 has been pushed to the Fedora 37 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2023-1b65a60b93`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2023-1b65a60b93

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 18 Fedora Update System 2023-04-08 02:36:25 UTC
FEDORA-2023-1b65a60b93 has been pushed to the Fedora 37 stable repository.
If problem still persists, please make note of it in this bug report.

Note You need to log in before you can comment on or make changes to this bug.