Files
Gabriel Brown 5f09c5ee38 The document portal may not claim started until its mount exists
Third recurrence of the stale-mount bug: the ExecStartPre cleanup ran on
clean ground and the portal still came up mountless, sitting active while
every fresh flatpak sandbox failed to build. Add an ExecStartPost that
polls for the fuse mount and fails the start after five seconds without
one, so a mountless portal shows up failed in the journal and the next
bus activation retries from the cleanup instead of lingering broken.

Claude-Session: https://claude.ai/code/session_01CTL7G5u3iDf1NCM6rTyCES
2026-08-26 10:48:47 -04:00

36 lines
2.1 KiB
Plaintext

# Clear the mountpoint before starting, so a start that follows a crash lands
# on clean ground.
#
# This service provides the fuse mount at /run/user/$UID/doc, and bwrap binds
# doc/by-app/<id> into every flatpak sandbox it builds. No mount, no sandbox,
# no application -- all of them, not one, because they all share this.
#
# The shipped unit is Type=dbus with Restart=no, so nothing restarts it on
# failure: it comes back only when something next calls its bus name. On this
# machine that was a flatpak launching two seconds after the daemon exited
# 21, and the activation raced the dying instance's fuse state and came up
# with no mount at all. systemctl then reports active (running) -- the
# fusermount3 helper is even still there as a child -- while every new sandbox
# fails. Nothing running at the time notices, because a sandbox needs the
# mount only while it is being built, so the breakage surfaces whenever you
# next open something you had not opened yet. Here that was three days later,
# and it was the second time: the first was written off as a one-off.
#
# `-` because a clean start has nothing to unmount and fusermount3 exits 1
# saying so, which is not a failure to start on.
#
# The unmount alone did not close the hole: the third recurrence (2026-08-26)
# started on ground the ExecStartPre had cleaned and still came up with no
# mount, sitting active-and-broken for fourteen hours until the next fresh
# flatpak launch found it. Hence ExecStartPost: the unit is not "started"
# until the mount it exists to provide actually exists. Type=dbus declares
# readiness at bus-name acquisition, which can land before the fuse thread
# has the mount up, so this polls rather than checks once. If five seconds
# pass without a mount, the start fails -- loudly, in the journal, as failed
# -- and the next bus activation retries from the ExecStartPre cleanup
# instead of every sandbox build failing against a unit that claims to be
# fine.
[Service]
ExecStartPre=-/usr/bin/fusermount3 -u /run/user/%U/doc
ExecStartPost=/usr/bin/timeout 5 /bin/sh -c 'until /usr/bin/mountpoint -q /run/user/%U/doc; do /usr/bin/sleep 0.2; done'