Bugzilla – Bug 1215548
new coreutils-systemd breaks "uptime"
Last modified: 2024-04-04 15:34:29 UTC
The new coreutils-systemd's "uptime" command reports wrong values: wrong, newer system: raspi4c:~ # grep VERSION_ID /etc/os-release VERSION_ID="20230910" raspi4c:~ # rpm -qf `which uptime` coreutils-systemd-9.4-1.1.aarch64 raspi4c:~ # uptime 06:28:33 up 4 days 21:40, 1 user, load average: 0.16, 0.16, 0.11 raspi4c:~ # cat /proc/uptime 136079.24 225710.69 correct, older system: raspi4a:~ # grep VERSION_ID /etc/os-release VERSION_ID="20230904" raspi4a:~ # rpm -qf `which uptime` coreutils-9.3-1.2.aarch64 raspi4a:~ # uptime 06:28:51 up 1 day 13:48, 1 user, load average: 0.09, 0.16, 0.12 raspi4a:~ # cat /proc/uptime 136093.86 92370.61 These are raspberry pi4's which don't have a realtime clock, so the system clock is wrong on boot. The broken version does not consult the kernel: raspi4c:~ # strace -e file uptime execve("/usr/bin/uptime", ["uptime"], 0xffffe61bb560 /* 48 vars */) = 0 faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=26215, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2515928, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2940, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/usr/lib/locale/de_DE.utf8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=357744, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/usr/lib64/gconv/gconv-modules.cache", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=27012, ...}, AT_EMPTY_PATH) = 0 faccessat(AT_FDCWD, "/var/run/utmpx", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/var/run/utmp", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}, AT_EMPTY_PATH) = 0 06:30:05 up 4 days 21:41, 1 user, load average: 0.20, 0.18, 0.11 +++ exited with 0 +++ The working version does: raspi4a:~ # strace -e file uptime execve("/usr/bin/uptime", ["uptime"], 0xffffe5952d00 /* 48 vars */) = 0 faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=23327, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2515928, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2940, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/usr/lib/locale/de_DE.utf8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=357744, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/usr/lib64/gconv/gconv-modules.cache", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=27012, ...}, AT_EMPTY_PATH) = 0 faccessat(AT_FDCWD, "/var/run/utmpx", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/var/run/utmp", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/proc/uptime", O_RDONLY) = 3 newfstatat(3, "", {st_mode=S_IFREG|0444, st_size=0, ...}, AT_EMPTY_PATH) = 0 openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}, AT_EMPTY_PATH) = 0 06:30:40 up 1 day 13:49, 1 user, load average: 0.10, 0.15, 0.12 +++ exited with 0 +++
That's sounds like the "there is no reliable way to get the kernel boot time" workarounds in gnulib: For /proc/uptime: "Notice: This module is deprecated because the "uptime" that it helps finding does not include VM saved/sleep time. Use the module 'boot-time' instead." And the new boot-time uses timestamps on the filesystem, which of course fails with hw having no RTC.
for more than 20 years /proc/uptime was good enough. I don't care about the boottime, but uptime certainly does not include the time the machine was suspended, so /proc/uptime is a reliable source of -- uptime! :-) Worked around for now with "ln -s /usr/bin/busybox /usr/local/bin/uptime", as /usr/local/bin fortunately is in $PATH before /usr/bin and busybox uptime works just fine.
(In reply to Stefan Seyfried from comment #2) > for more than 20 years /proc/uptime was good enough. > I don't care about the boottime, but uptime certainly does not include the > time the machine was suspended, so /proc/uptime is a reliable source of -- > uptime! :-) I agree and all other uptime implementations I checked (e.g. busybox and procps) see it in the same way. But since this was an upstream gnulib/coreutils decision and I don't know the upstream bug reports and reasons why they changed it, the best way is to discuss that with them.
OK, discussing with GNU coreutils maintainers looks rather futile. How about we provide uptime via update-alternatives from different sources (busybox, procps, coreutils)? I can in fact uninstall coreutils-systemd, but I cannot install busybox-coreutils because of... Problem: the to be installed busybox-coreutils-1.36.1-30.1.noarch conflicts with 'coreutils' provided by the installed coreutils-9.4-1.2.x86_64 So maybe we can make this co-installable? Or create a busybox-uptime and a coreutils-uptime which are conflicting over only the uptime job?
New uptime(1) calls sysinfo(2): $ strace -e sysinfo uptime sysinfo({uptime=1088088, loads=[12800, 20800, 30528], totalram=20879904768, freeram=11266564096, sharedram=1854656512, bufferram=479453184, totalswap=2147479552, freeswap=2147479552, procs=946, totalhigh=0, freehigh=0, mem_unit=1}) = 0 08:44:26 up 12 days 14:14, 2 users, load average: 0.20, 0.32, 0.47 +++ exited with 0 +++ So the question is why that yields odd values on pi4.