-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[host][freebsd] Users() returns incorrect "Started" timestamp #709
Comments
Thank you! I will check in this weekend. |
Thanks for this excellent report. I can reproduce indeed. I tried to regenerate |
From this great report, I can create a fix PR #712. please check it and if it works on your environment, I can merge the PR. Thanks! |
@shirou Thank you very much! I have commented on the PR regarding my test results and can confirm that it does fix this specific issue. |
#712 is merged. Big thanks for this report and your contribution! |
Describe the bug
Calling
host.Users()
on a FreeBSD system which uses theutmpx
POSIX standard (default since FreeBSD 9.0) returns a slice ofUserStat
structs, which contains an incorrect value for theStarted
attribute. Instead of containing a UNIX timestamp representing the start time of the user session, a seemingly random timestamp is being returned.To Reproduce
Start a new user session at a FreeBSD system (e.g. SSH to the machine), then run the following code snippet:
As an example, this resulted in the following output on my system:
root@pts/0@<my reverse dns> - 1732593154
- converting the supposed UNIX timestamp to a human-readable date results in11/26/2024 @ 3:52am (UTC)
, which is obviously way off as I am unable to start sessions in the future :)Expected behavior
Calling
host.Users()
on a FreeBSD system should return a correct UNIX timestamp specifying when the session got started. This behavior would be equivalent to the other supported operating systems, e.g. Linux.Environment (please complete the following information):
12.0-RELEASE-p6 / FreeBSD gopsutil-devel 12.0-RELEASE-p6 FreeBSD 12.0-RELEASE-p6 GENERIC amd64
Root cause
gopsutil is currently using the C struct declaration
utmpx
, which is incompatible with the format used by FreeBSD for/var/run/utx.active
. Whilestruct utmpx
is being represented according to the POSIX standards and used internally in the kernel, FreeBSD chose to use a different representation for theutx.active
file.This can be read in the initial commit which introduced the utmpx implementation to FreeBSD in 2010:
The correct structure which should be used for parsing the file is present in lib/libc/gen/utxdb.h, which has some notable differences:
gopsutil/host/host_freebsd_amd64.go
:// TODO: why should 197, not 0x118
fu_type
is auint8_t
instead of ashort
, so only one byte is being used instead of two as currently implemented in gopsutil.fu_tv
is auint64_t
instead of astruct timeval
, which consumes 8 bytes instead of 7 bytes.secs * 1_000_000 + usecs
, which can also be seen in the kernel sources.secs
represents the UNIX timestamp andusecs
gives additional precision.I have already verified that using
struct futx
would result in the correct timestamp by analyzing a copy ofutx.active
in a hex editor, which can be seen here: https://zig.pw/3916bfaca6116fe1e5d67b314e6de03c.pngUnfortunately this structure is not being included in the regular header files available in a base FreeBSD installation, so this structure would either have to be manually replicated (without Cgo) or we would have to use the actual C functions to retrieve
struct utmpx
instances. I couldn't think of a satisfying solution so far, which is why I am opening this as an issue.The text was updated successfully, but these errors were encountered: