Skip to content

bwrap sandbox fails on Bazzite/ostree hosts: "Can't mount on symlink destination /home" #199

Description

@aradanmn

Summary

Every splitscreen instance spawn fails immediately on Bazzite (ostree-based) hosts. bwrap aborts on launch with:

bwrap: Can't mount on symlink destination /home

Found during #198 hardware validation on a Framework Desktop freshly rebased to bazzite-deck:stable, real Game Mode (gamescope-session-plus), 2 controllers connected and correctly acquired by docked_flow's startup-acquisition loop (both CONTROLLER_ADD → SPAWN fired immediately, as designed — this is not a controller-detection issue). Both slot spawns then failed identically:

[spawn_instance] bwrap PID: 19870
[spawn_instance] ERROR: bwrap PID 19870 died immediately after launch — aborting (skipping the 60s java poll)
[orchestrator] spawn_instance failed for slot 1 — slot released

with the actual bwrap stderr (captured in the same debug log, since bwrap's stdout/stderr redirect to "${LOG}" per instance_lifecycle.sh:1053) reading Can't mount on symlink destination /home.

Root cause

modules/instance_lifecycle.sh:429:

--dev-bind /home /home

This assumes /home is a real mount point. On Bazzite (Fedora Silverblue/Kinoite-derived), it is a symlink:

$ ls -la /
lrwxrwxrwx. 1 root root 8 ... home -> var/home
$ readlink -f /home/sdean
/var/home/sdean

bwrap deliberately refuses to mount onto a symlinked destination (ambiguous/unsafe mount target), so it exits immediately, every time, for every slot.

This is a Bazzite-specific gap, not something the Deck exposed — verified directly on both machines tonight:

  • Steam Deck (SteamOS): /home is a real, separately-mounted partition (drwxr-xr-x ... home), even though SteamOS does symlink other top-level dirs through /var (e.g. mnt -> var/mnt). Valve appears to have deliberately kept /home as its own real partition, likely so user data survives A/B OS reimages independently of the rest of the filesystem.
  • Bazzite (Fedora Silverblue/Kinoite convention): /home, /opt, /mnt, /srv, /root are all uniformly symlinked through /var, with no special case for /home.

So both are atomic/immutable systems, but they differ in this one specific implementation detail — that's why the Deck never hit this and Bazzite hosts always will.

Proposed fix

Detect the symlink and bind the real target instead, recreating the /home symlink inside the sandbox so anything referencing /home/$USER from inside still resolves:

if [[ -L /home ]]; then
    local _home_real
    _home_real="$(readlink -f /home)"
    cmd+=(--dev-bind "$_home_real" "$_home_real" --symlink "$_home_real" /home)
else
    cmd+=(--dev-bind /home /home)
fi

Deck behavior (non-symlink /home) is unchanged by the else branch.

Impact

Blocks splitscreen entirely — every instance spawn fails — on any Bazzite/Fedora-atomic-desktop host. Not encountered on the Deck. Not related to #198 (that fix — MCSS_NESTED_KWIN_NNP / mangoapp crash-loop — is independently confirmed working on this same hardware/session; this bug was found immediately after, one layer deeper, while validating #198's fix live).

Environment

  • Framework Desktop, ghcr.io/ublue-os/bazzite-deck:stable 44.20260921, real gamescope Game Mode (gamescope-session-plus)
  • 8BitDo Ultimate 2 Wireless + Sony DualShock/DualSense controllers, both correctly acquired at startup

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions