Public bug reported:
[ Impact ]
On jammy and noble, `debian/patches/04_language_handling.patch` adds this to
`configure_session()` in `src/seat.c`:
/* Only set LANGUAGE if not in a live session
https://launchpad.net/bugs/1861481 */
if (system ("df | grep -q ^/cow") != 0)
session_set_env (session, "LANGUAGE", language);
`configure_session()` runs on the lightdm daemon's single main loop at every
login
(greeter or autologin) of a user whose AccountsService `Language` is non-empty,
which
is the ordinary case. `system()` waits for the command, and `df` with no
arguments
calls statfs(2), as root, on **every** mounted filesystem. If any one of them
is slow
to answer, the whole daemon stops until it does. That includes a network
filesystem
or a FUSE mount with `allow_other` whose statfs goes over the network (rclone,
sshfs).
While it waits, lightdm does not answer the greeter, does not process seat or
session
changes, and does not switch VTs. The greeter shows its spinner and appears
frozen.
Observed on noble (lightdm 1.30.0-0ubuntu14, slick-greeter 2.0.1): after a
successful
authentication, lightdm.log shows `Greeter requests session cinnamon`, then
nothing
for 300.12 s, then `Returning to existing user session …`. The seat changes that
arrived in the meantime are all logged together at the end, so the daemon was
blocked.
The greeter's start-session request was answered 300.13 s after it was sent. The
cause was an `allow_other` rclone mount whose statfs (a Drive quota call) was
stuck
on a dead connection until rclone's default 5-minute I/O timeout.
The same line produces the `df: /sys/firmware/efi/efivars: Invalid argument`
message
at login reported in LP #2038765.
The check asks "is a filesystem with source `/cow` mounted?", which detects a
casper
live session. The kernel's mount table holds the same answer, and reading it
touches
no filesystem.
[ Fix ]
The attached debdiffs add `debian/patches/live-session-check-without-df.patch`,
which replaces the `system()` call with an in-process `getmntent(3)` scan of
`/proc/self/mounts`. The scan uses a prefix match on the source field, which is
the
first column of df's output, so the result is identical to the old `grep -q
^/cow`.
There is no shell, no subprocess and no statfs. If `/proc/self/mounts` cannot be
opened, the answer is "not live". That matches the old behaviour when df failed:
grep saw nothing, so LANGUAGE was set.
Affected: jammy (1.30.0-0ubuntu5) and noble (1.30.0-0ubuntu14). Not affected:
plucky
onward, including resolute (1.32.0-6ubuntu4). Those releases moved to Debian's
1.32
packaging and carried over only part of the old delta (LP: #2104169), and
`04_language_handling.patch` was not among the parts carried over. So this is
SRU-only. Dropping the condition outright, as the devel series effectively did,
would bring back LP #1861481 in live sessions. This change keeps that behaviour
and
removes only the hazard.
[ Test Plan ]
1. On an installed (not live) system, give a user a non-empty AccountsService
Language (e.g. `en`) and configure autologin for them. Autologin reaches the
same
`configure_session()` through `create_user_session()`, so no greeter input is
needed.
2. As root, mount a FUSE filesystem with `allow_other` whose statfs sleeps 40 s
(the script below uses python3-fusepy), and restart lightdm.
3. Measure the time in lightdm.log from `Creating user session` to
`Running command /usr/sbin/lightdm-session`.
- Expected, unpatched: about 40 s, with one 40 s silence in the log.
- Expected, patched: well under 1 s.
4. In the new session, check that `LANGUAGE` is still set (it should be `en`).
5. Live-session semantics: `mount -t tmpfs /cow /mnt/x`. The patched check must
report
"live" exactly when `df | grep -q ^/cow` does.
Results, noble (dev VM, real lightdm + Cinnamon):
- unpatched, no slow mount: 0.17 s, `LANGUAGE=en`
- unpatched, 40 s slow mount: **40.17 s**, one 40.00 s silence, `LANGUAGE=en`
- patched, 40 s slow mount: **0.20 s**, `LANGUAGE=en`
Results, both series (clean containers): the old and new checks agree with no
`/cow`
mount, with `/cow` mounted, and after it is unmounted.
On jammy, the package's own test suite (disabled in debian/rules) was also run
by hand
on the unpatched and patched trees. Both give 285 PASS and 34 FAIL with
identical
per-test results, and test-language, test-language-env and
test-language-no-accounts-service pass. On noble the suite cannot run in a
container:
lightdm under test cannot reach the test runner's system bus, identically with
and
without the patch.
Slow-statfs FUSE used in step 2:
#!/usr/bin/python3
import errno, stat, sys, time
from fusepy import FUSE, FuseOSError, Operations
class Slow(Operations):
def getattr(self, path, fh=None):
if path != "/": raise FuseOSError(errno.ENOENT)
t = time.time()
return dict(st_mode=stat.S_IFDIR | 0o755, st_nlink=2, st_ctime=t,
st_mtime=t, st_atime=t)
def readdir(self, path, fh): return [".", ".."]
def statfs(self, path):
time.sleep(float(sys.argv[2]))
return dict(f_bsize=4096, f_frsize=4096, f_blocks=1, f_bfree=1,
f_bavail=1)
FUSE(Slow(), sys.argv[1], foreground=True, allow_other=True)
[ Where problems could occur ]
- **Live-session detection.** If the new check disagreed with the old one, a
live
session would get LANGUAGE set (LP #1861481 again) or an installed system
would lose
it. The two use the same source field and the same prefix match, and the test
above
checks both directions.
- **Reading /proc/self/mounts.** `/proc` is always mounted where lightdm runs.
If
opening it fails anyway, the result is "not live", which matches the old code
when
df failed.
- **The new include.** `<mntent.h>` is glibc and adds no new build-dependency.
[ Other Info ]
Workaround on affected systems: clear the user's AccountsService Language, or
make
sure no `allow_other` or network mount can stall statfs. For rclone:
`--disable About --timeout 30s`.
** Affects: lightdm (Ubuntu)
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2168500
Title:
lightdm blocks its main loop on `system("df | grep -q ^/cow")` at
login; an unresponsive mount freezes the greeter (300 s observed)
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/lightdm/+bug/2168500/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs