An in-flight TV restore raced a reconnect's takeover and resurrected sddm under the mask #246

Merged
enricobuehler merged 1 commits from worktree-dm-restore-reconnect-race into main 2026-08-15 10:57:05 +00:00
1 Commits
Author SHA1 Message Date
enricobuehler 054bf26393 fix(vdisplay): an in-flight TV restore raced a reconnect's takeover and resurrected sddm under the mask
ci / docs-site (pull_request) Successful in 1m18s
ci / bun-nix (pull_request) Successful in 1m31s
ci / web (pull_request) Successful in 5m11s
android / android (pull_request) Successful in 5m18s
ci / rust-arm64 (pull_request) Successful in 7m34s
ci / rust (pull_request) Failing after 18m40s
Under keep_alive=off the restore debounce is 0 s, so the worker pops the
deadline before a reconnect's cancel arrives — clearing PENDING_RESTORE
then cancels nothing, and the restore runs concurrently with the new
takeover. Field trace (.41, 2026-08-15): the new takeover listed the
autologin unit inactive (the restore hadn't restarted it yet), so
dm_plan correctly refused to stop the DM for a dead unit and went
mask-only — and the in-flight restore then restarted sddm underneath
that mask at 10:36:39.638. SDDM's helper execs the session script
directly, so the mask stops only the final unit start, never the retry:
1272 relogins in ~4 minutes, a fresh Steam launch each round, load 7+,
until a manual 'systemctl stop sddm'.

RESTORE_FLIGHT now serializes the two: the worker pops the deadline and
runs do_restore_tv_session under it, and cancel_pending_restore (which
create_managed_session now routes through instead of clearing
PENDING_RESTORE bare) blocks until an in-flight restore completes. Either
the cancel wins — no restore starts, warm reuse as before — or the
restore wins and the connect takes over a fully restored box, where the
autologin unit is live again and the DM stop engages through the
ordinary plan. restore_takeover_now (host shutdown) takes the same lock
so the two restore entry points can't interleave either.

Gate: xcheck linux check+clippy clean; pf-vdisplay 237/237 in the
rust:1.96 container, including the new regression test.
2026-08-15 12:43:26 +02:00