fix(agent): read /proc/uptime on linux instead of sysinfo(2) - #2180
Conversation
gopsutil's host.Uptime() calls the sysinfo(2) syscall. Inside an LXC container lxcfs virtualizes /proc/uptime but cannot intercept a syscall, so every container reported the host's uptime. Reads /proc/uptime on linux and falls back to host.Uptime() if the file is missing or unparseable, so other platforms are unchanged. Fixes henrygd#1948
henrygd
left a comment
There was a problem hiding this comment.
Thanks a lot, this looks like a good approach.
One change before merge: validate the parsed float before converting it. strconv.ParseFloat accepts NaN, infinities, and values beyond the uint64 range without returning an error, which can yield a huge bogus uptime instead of using the fallback.
seconds, err := strconv.ParseFloat(fields[0], 64)
if err != nil ||
math.IsNaN(seconds) ||
math.IsInf(seconds, 0) ||
seconds < 0 ||
seconds >= 1<<64 {
return host.Uptime()
}
return uint64(seconds), nilAnd if possible, please add tests covering NaN, +Inf, negative values, and an out-of-range value such as 1e20.
Thanks for the review. Done in 666b6f6, took your validation as-is. Added fallback tests for |
henrygd
left a comment
There was a problem hiding this comment.
Perfect, thank you! Appreciate your work.
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [henrygd/beszel](https://github.com/henrygd/beszel) | minor | `0.18.8` → `0.19.0` | --- >⚠️ **Warning** > > Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/12) for more information. --- ### Release Notes <details> <summary>henrygd/beszel (henrygd/beszel)</summary> ### [`v0.19.0`](https://github.com/henrygd/beszel/releases/tag/v0.19.0) [Compare Source](henrygd/beszel@v0.18.8...v0.19.0) :warning: **Potential breaking change:** Agents now verify HTTPS certificates. If an agent connects to a hub using a self-signed or otherwise untrusted certificate, configure `CA_CERT_FILE` with the appropriate CA certificate or the connection will be rejected. #### What's Changed - Add ZFS pool and dataset monitoring ([#​2209](henrygd/beszel#2209)) - Add container health alerts with log excerpts in notifications ([#​2225](henrygd/beszel#2225)) - Add alerts for failed systemd services ([#​2173](henrygd/beszel#2173)) - Add alerts for CPU I/O wait and steal time ([#​2249](henrygd/beszel#2249)) - Add cumulative disk read and write totals to the Disk I/O sheet ([#​2179](henrygd/beszel#2179)) - Add Greek and Uzbek translations ([#​2034](henrygd/beszel#2034)) - Add custom root disk names and sort disks alphabetically ([#​2006](henrygd/beszel#2006)) - Improve alert security by enforcing system ownership and blocking additional internal notification URL ranges - Improve ATA SMART warnings for critical attributes ([#​2275](henrygd/beszel#2275)) - Fix a hub crash caused by concurrent SSH client shutdown ([#​2277](henrygd/beszel#2277)) - Fix host CPU and memory totals when Docker runs in a VM on macOS or Windows ([#​2272](henrygd/beszel#2272)) - Fix multi-line `TOKEN_FILE` loading ([#​2276](henrygd/beszel#2276)) - Fix QNAP MD RAID arrays being incorrectly reported as failed ([#​2065](henrygd/beszel#2065)) - Fix Intel GPU power data disappearing between samples ([#​2256](henrygd/beszel#2256)) - Fix swap usage calculations to include cached swap ([#​2267](henrygd/beszel#2267)) - Fix agent payload failures caused by invalid UTF-8 in battery names ([#​2241](henrygd/beszel#2241)) - Fix uptime reporting inside Linux containers ([#​2180](henrygd/beszel#2180)) - Fix fan discovery on legacy hwmon devices ([#​2238](henrygd/beszel#2238)) - Fix CPU model detection on MIPS systems ([#​2138](henrygd/beszel#2138)) - Fix machine ID generation on FreeBSD and pfSense installations ([#​2274](henrygd/beszel#2274)) - Fix agent environment variable updates during reinstall ([#​2107](henrygd/beszel#2107)) - Fix the install script reporting the wrong listen address after upgrades ([#​2243](henrygd/beszel#2243)) - Fix load average precision on macOS, BSD, and Windows ([#​2245](henrygd/beszel#2245)) - Update the Go version and Go dependencies #### New Contributors - [@​IlyaMur](https://github.com/IlyaMur) made their first contribution in [#​2238](henrygd/beszel#2238) - [@​alecrubin](https://github.com/alecrubin) made their first contribution in [#​2180](henrygd/beszel#2180) - [@​toomore](https://github.com/toomore) made their first contribution in [#​2241](henrygd/beszel#2241) - [@​mews-se](https://github.com/mews-se) made their first contribution in [#​2243](henrygd/beszel#2243) - [@​justadityaraj](https://github.com/justadityaraj) made their first contribution in [#​2245](henrygd/beszel#2245) - [@​wassupluke](https://github.com/wassupluke) made their first contribution in [#​2256](henrygd/beszel#2256) - [@​ErkinjonYusupov](https://github.com/ErkinjonYusupov) made their first contribution in [#​2034](henrygd/beszel#2034) - [@​snh](https://github.com/snh) made their first contribution in [#​2279](henrygd/beszel#2279) - [@​spatiumstas](https://github.com/spatiumstas) made their first contribution in [#​2249](henrygd/beszel#2249) - [@​martinstenrose](https://github.com/martinstenrose) made their first contribution in [#​2173](henrygd/beszel#2173) - [@​mleczakm](https://github.com/mleczakm) made their first contribution in [#​2225](henrygd/beszel#2225) - [@​santhiprakash](https://github.com/santhiprakash) made their first contribution in [#​2269](henrygd/beszel#2269) **Full Changelog**: <henrygd/beszel@v0.18.8...v0.19.0> </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTAuMSIsInVwZGF0ZWRJblZlciI6IjQzLjE1MC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://git.jfreudenberger.de/JuliusFreudenberger/nix-config/pulls/43
Fixes #1948.
host.Uptime()isunix.Sysinfo()in gopsutil, and lxcfs can't intercept a syscall, so every LXC container reports the host's uptime./proc/uptimeis virtualized correctly, it just wasn't being read.This reads
/proc/uptimeon linux and falls back tohost.Uptime()if the file is missing or unparseable. Other platforms go through a stub that callshost.Uptime()exactly as before, so nothing changes off linux.Built a small binary that calls both ways and ran it on my Proxmox 9 box (lxcfs 7.0.0-pve1), containers had been up about an hour:
Same on bare metal, correct in containers.
Tests cover the parse (typical, zero, no trailing newline, single field, large value) and the three fallback paths (missing file, empty file, unparseable).
uptimeFilePathis a package var so the tests can point it at a fixture, same asmdraidSysfsRootdoes.Ran
go buildandgo vetfor both linux and darwin, and the tests in a golang:1.26 container.