Repository navigation
dmesg: get the boot time from CLOCK_BOOTTIME on Linux instead of a utmp record - #672
jayhemnani9910 wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.
| #[cfg(not(any(target_os = "openbsd", target_os = "linux", target_os = "android")))] | ||
| fn boot_time() -> DateTime<FixedOffset> { | ||
| *BOOT_TIME.get_or_init(|| boot_time_from_utmpx().unwrap()) | ||
| } |
There was a problem hiding this comment.
this still panics on macOS/freebsd without a boot record, no?
There was a problem hiding this comment.
Yes. In efc8d5d macOS and FreeBSD read kern.boottime with sysctl instead of utmp. When no boot time can be found, on any system, dmesg now exits 1 with dmesg: cannot get the system boot time instead of panicking. With --since or --until it fails before reading any records.
| }; | ||
| // SAFETY: `uptime` is a valid timespec for clock_gettime to write. | ||
| unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut uptime) }; | ||
| let uptime = TimeDelta::new(uptime.tv_sec, uptime.tv_nsec as u32).unwrap_or_default(); |
There was a problem hiding this comment.
tv_sec is i32 on 32-bit android, does this build there?
There was a problem hiding this comment.
It didn't: cargo check --target armv7-linux-androideabi failed with expected i64, found i32 on tv_sec. efc8d5d converts it when the pointer width isn't 64, as uucore's uptime does. cargo clippy -p uu_dmesg --all-targets is now clean for armv7-linux-androideabi, x86_64-apple-darwin, x86_64-unknown-freebsd and i686-unknown-freebsd.
| tv_nsec: 0, | ||
| }; | ||
| // SAFETY: `uptime` is a valid timespec for clock_gettime to write. | ||
| unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut uptime) }; |
There was a problem hiding this comment.
please check the return value
if it fails, the boot time silently becomes now
There was a problem hiding this comment.
Done in efc8d5d: if clock_gettime returns nonzero there is no boot time, so dmesg reports the error instead of using now.
| use super::*; | ||
|
|
||
| #[test] | ||
| fn boot_time_matches_proc_uptime() { |
There was a problem hiding this comment.
this test never runs in CI, cargo test enables fixed-boot-time
could you please add a cargo test -p uu_dmesg step?
There was a problem hiding this comment.
Added cargo test -p uu_dmesg to the test job in efc8d5d, after the workspace cargo test, so it runs on all three OSes. On macOS it runs the new boot_time_comes_from_kern_boottime.
…cking without a boot time
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.
| if res != 0 { | ||
| return None; | ||
| } | ||
| #[cfg(target_pointer_width = "64")] |
There was a problem hiding this comment.
same 4 lines as in the linux version, could be a small helper, no?
There was a problem hiding this comment.
Done in 440d4b8: time_t_secs does the conversion for both. A plain .into() covers 32 and 64-bit time_t, with useless_conversion allowed for the 64-bit case. cargo clippy -p uu_dmesg --all-targets -- -D warnings is clean for x86_64 Linux, macOS and FreeBSD, i686 FreeBSD and armv7 Android.
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.
dmesgpanics for every time format that needs the boot time when utmp has no boot record. That is the case on systems without/run/utmp, such as recent Ubuntu and most containers:The same panic hits
--time-format=isoandreltime,--sinceand--until. The tests don't catch it because they build withfixed-boot-time.On Linux the boot time is now the current time minus
CLOCK_BOOTTIME, so no utmp is needed. macOS and FreeBSD readkern.boottime, and other Unix systems keep the utmp lookup. When no boot time can be found, dmesg exits 1 withcannot get the system boot timeinstead of panicking.uu_dmesgalready useduucore::libcwithout enabling uucore'slibcfeature, so the crate only built next to another tool that enabled it. The feature is now enabled in its Cargo.toml.New unit test
boot_time_matches_proc_uptimechecks the boot time against/proc/uptime. It needs a build withoutfixed-boot-time, so CI now also runscargo test -p uu_dmesg; on macOS that runsboot_time_comes_from_kern_boottime. The uptime test fails on the old code on a system without a utmp boot record.cargo clippy -p uu_dmesg --all-targetsis clean for armv7-linux-androideabi, x86_64-apple-darwin, x86_64-unknown-freebsd and i686-unknown-freebsd.cargo testfor the tools that build here (all but lsipc, lslocks and lsns, which need libsmartcols): 232 passed, same as main. clippy and fmt are clean. With a kmsg file,--time-format=ctime,isoandreltimeprint the same times as util-linux 2.41.3 (iso differs by 1 µs of rounding).