#1112334 coreutils: systemd integration broke "who" in trixie/sysvinit --- workaround

Package:
coreutils
Source:
coreutils
Description:
GNU core utilities
Submitter:
g1
Date:
2025-08-28 18:37:01 UTC
Severity:
normal
Tags:
#1112334#5
Date:
2025-08-28 15:18:12 UTC
From:
To:
TLDR

$ who | wc -l
0
$ who /var/run/utmp | wc -l
0
$ who /var/run/./utmp | wc -l
10
$ alias who='who /run/utmp'
$ who /run/utmp | wc -l
10

/TLDR

In lib/readutmp.c (gnulib), read_utmp() invokes read_utmp_from_systemd()
instead of read_utmp_from_file() when the <file> parameter equals the
default utmp filename "/var/run/wtmp":

 1  int
 2  read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
 3             int options)
 4  {
 5  # if READUTMP_USE_SYSTEMD
 6      if (strcmp (file, UTMP_FILE) == 0)
 7          /* Imitate reading UTMP_FILE, using systemd and Linux APIs.  */
 8          return read_utmp_from_systemd (n_entries, utmp_buf, options);
 9  # endif

In turn read_utmp_from_systemd() ignores all entries from the utmp file,
at least when no seat manager is running, and possibly also in other
scenarios.

The READUTMP_USE_SYSTEMD macro is defined during the configure phase
(m4/readutmp.m4), depending on the test program

    #include <stdint.h>
    #include <systemd/sd-login.h>
    int main() {
	uint64_t st;
	sd_session_get_start_time ("1", &st);
    }

which fails to compile in bookworm (because sd_session_get_start_time()
is not available in libsystemd 252.38), but unfortunately succeeds in
trixie (libsystemd 257.7).

However, line 6 above permits a workaround: use a different filename
from the predefined UTMP_FILE.

RANT

Upstream made a number of decisions that IMHO are not very brilliant:

- entangle core utilities with a library belonging to a specific
  init/service-manager implementation

- change the behaviour of the (POSIX standard) "who" utility without making
  the change opt-in, or at least providing an option/env-var to restore the
  classic behaviour

- ignore user intent on "who <filename>" if filename happens to be the
  usual one or empty (default)

- accept the fact that `"who" needs to ask seat manager', because
  of course the best way to read a file is through an IPC to a daemon that
  might not be running on the system.

/RANT

Best regards,
	g.b. (a greybeard)

#1112334#10
Date:
2025-08-28 16:27:03 UTC
From:
To:
upstream didn't have a lot of options. I was in the same position,
because even though I thought dropping utmp for trixie was a mistake, it
happened anyway and even though some utilities are still writing utmp
entries, most are not. I really wish that trixie had supported both
options, but when systemd changed unilaterally this outcome was forced.

#1112334#15
Date:
2025-08-28 18:24:03 UTC
From:
To:
Upstream _had_ options, some very simple to implement, like this
--- lib/readutmp.c.bak 2025-08-28 19:50:43.489848372 +0200 +++ lib/readutmp.c 2025-08-28 19:51:13.523664432 +0200 @@ -982,7 +982,7 @@ int options) { # if READUTMP_USE_SYSTEMD - if (strcmp (file, UTMP_FILE) == 0) + if (strcmp (file, UTMP_FILE) == 0 && getenv("WHO_USE_FILE") == NULL) /* Imitate reading UTMP_FILE, using systemd and Linux APIs. */ return read_utmp_from_systemd (n_entries, utmp_buf, options); # endif or this
--- lib/readutmp.c.bak 2025-08-28 19:50:43.489848372 +0200 +++ lib/readutmp.c 2025-08-28 19:59:17.748453546 +0200 @@ -982,7 +982,8 @@ int options) { # if READUTMP_USE_SYSTEMD - if (strcmp (file, UTMP_FILE) == 0) + struct stat sb; + if (strcmp (file, UTMP_FILE) == 0 && stat("/run/systemd/system", &sb) == 0) /* Imitate reading UTMP_FILE, using systemd and Linux APIs. */ return read_utmp_from_systemd (n_entries, utmp_buf, options); # endif Of course, once one accepts that the only way to look at Linux is through the Systemd lens, are bets are off. The outcome is not just that a bunch of utilities that people used to rely on don't work anymore or are defective: a lot of things that once were trivial have become unnecessarily complex, with a much wider attack surface. The lesson from the xz incident has been forgotten. Would you mind to reopen this bug and keep it open for a while, so that people can at least see there's a workaround? Regards, g.b.
#1112334#20
Date:
2025-08-28 18:35:32 UTC
From:
To:
No, people can find it whether it's closed or not. There aren't really
workarounds in debian because the information will be inaccurate.