Thorsten Kukuk wrote: > > What API do you suggest we use instead? > > For me clock_gettime works very well: > https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md#determine-boot-time
Now that I've implemented this method in gnulib's 'readutmp' module and built coreutils with that, I see that it does not work "very well" at all. I have a VM running in VirtualBox, that I booted 6 days ago, then "saved" it (i.e. all the state gets frozen) and resumed it today around 20:30 UTC. In this VM, the test-readutmp program produces this output: ==================================================================================== Here are the read_utmp results. Flags: B = Boot, U = User Process Termiā Flags Time (GMT) User Device PID nation Exit B U Host ------------------- ------------------ ----------- ---------- ------ ---- - - ---- 2023-08-02 16:56:15 bruno seat0 1511 0 0 X :0 2023-08-08 15:47:48 reboot ~ 0 0 0 X ==================================================================================== Similarly, ==================================================================================== $ TZ=UTC ./who -a /var/run/utmp system boot 2023-08-08 15:47 bruno ? seat0 2023-08-02 16:56 ? 1511 (:0) ==================================================================================== So, both programs show a "boot time" that is just 5 hours ago, at a moment when the VM was in fact frozen. Whereas the 'who' program, when it actually reads the /var/run/utmp file (via the symlink /run/utmp), produces the correct time: ==================================================================================== $ TZ=UTC ./who -a /run/utmp system boot 2023-08-02 16:55 run-level 5 2023-08-02 16:56 bruno + tty1 2023-08-02 16:56 old 1558 (:0) pts/1 2023-08-02 17:31 2815 id=ts/1 term=0 exit=0 ==================================================================================== All three methods from get_boot_time_uncached produce this wrong "boot time", because they are all three based on 1) the kernel's ktime_get_boottime or ktime_get_boottime_ts64 function, 2) subtracting the returned value from the current time. The description CLOCK_BOOTTIME in glibc's <bits/time.h> is: /* Monotonic system-wide clock that includes time spent in suspension. */ # define CLOCK_BOOTTIME 7 Maybe that includes time spent in suspension. But it does not include time spent in "saved" state of virtual machines. Thus is won't work right in cloud environments. I can't really argue that it's a kernel bug, since VirtualBox and VMs exist for more than 10 years, and /proc/uptime and sysinfo() as well. Therefore I think that - The readutmp module should better pick the boot time from the real /var/run/utmp file, and ignore the rest of this file (in systemd mode). - We still don't have a reliable way of getting the boot time on Alpine Linux, since the /var/run/utmp file there is empty. - The effort to get rid of /var/run/utmp has encountered a stumbling block. Bruno