Unmount FUSE filesystems before suspend/hibernate#4940
Conversation
The read command had an extra _ placeholder that was swallowing the fstype field, causing the fuse.* pattern to never match.
There was a problem hiding this comment.
Pull request overview
This PR adds a systemd system-sleep hook to lazy-unmount all FUSE filesystems before suspend/hibernate, preventing FUSE daemons (primarily gvfsd-fuse from Nautilus) from blocking the kernel's process freeze and causing suspend to silently fail. This addresses battery drain issues reported on Framework 13 AMD and other laptops in #4184, #1556, and #2501.
Changes:
- New system-sleep hook (
unmount-fuse) that parses/proc/mountsfor FUSE filesystems and lazy-unmounts them before suspend/hibernate usingfusermount3/fusermountwith fallback - Migration script to install the hook on existing systems
- Integration into the hibernation setup script for fresh installs
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
default/systemd/system-sleep/unmount-fuse |
New bash hook that lazy-unmounts all FUSE filesystems on pre-suspend/hibernate |
migrations/1773012889.sh |
Migration to deploy the hook to existing Omarchy installations |
bin/omarchy-hibernation-setup |
Adds hook installation during fresh hibernation setup, alongside the existing keyboard-backlight hook |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
gvfsd-fuse is spawned by gvfsd during init and not respawned if it dies. After lazy-unmounting in pre-sleep, restart gvfs-daemon.service in post-sleep so the FUSE mount at /run/user/*/gvfs is restored.
cp -p preserves the original user ownership from ~/.local/share/omarchy, which would allow an unprivileged user to modify a script that runs as root during suspend/hibernate.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 3 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d841697 to
a89c4f8
Compare
The post-sleep hook runs before systemd thaws user.slice, so a synchronous systemctl --user restart hangs for ~90 seconds waiting for the frozen user manager to respond — blocking the entire resume. Background the restart with a short delay so it executes after user.slice is thawed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
/proc/mounts uses octal escaping for special characters (e.g. \040 for spaces). Decode with printf before passing to fusermount so paths with spaces are handled correctly. Add disown after backgrounding the gvfs restart so it survives systemd-sleep's cgroup cleanup when the hook script exits.
|
Testing these changes locally on a Framework 13 AMD (Ryzen, s2idle) before marking ready for review. Suspend/wake cycle is working — will report back after extended testing. |
Unmounting all FUSE filesystems breaks xdg-document-portal and AppImages that rely on FUSE to stay mounted. It also doesn't restart them.
dhh
left a comment
There was a problem hiding this comment.
Thanks for the PR! I've pushed a fix to restrict the unmount to fuse.gvfsd-fuse only. Unmounting all fuse.* mounts broke things like xdg-document-portal (which is used by flatpaks) and any running AppImages, because only gvfsd-daemon was being restarted. I also added env to the sudo call to ensure the environment variables are explicitly passed rather than relying on sudo's VAR=value command parsing policy. Looks good!
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 3 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@dhh I think we are ready. |
|
Think we need it somewhere else than in the hibernation setup. I think it needs its own installer, since it's relevant for suspend as well? |
The hook prevents gvfsd-fuse from blocking suspend, not just hibernation. Install it during the config phase so every system gets it, not only those that run hibernation setup.
|
Ah you're right, completely overlooked that. Pushed a commit to give it its own installer in the config phase so it's always there regardless of hibernation setup. |
|
Tested the latest changes locally. Multiple suspend/wake cycles, all clean:
|
|
Since a few days (somewhere between 2026-03-03 and 2026-03-09), I have the issue that, after suspend, the system screen turns on, shows the "enter password" dialog but it totally frozen otherwise. Could this one here be my issue or am I chasing a ghost? |
|
I saw that issue once too. Did you try with this fix in place or without? |
|
Nope, that's not my bug :/ (I upgraded again from my working snapshot to latest, verified it broke, added |
|
@siebertm I had this all the time before the fix from this PR, but completely gone after it. What is the hardware are you using? |
@alansikora nope, didnt work, even though the description is exactly what I experience:
I can reproduce this 100% of the time and I have a working state and a non-working state which I can trigger at will by using I think I'll dig deeper myself, possibly doing some bisecting - I dont think I need to "use" your time for that until I can put my finger on the thing that broke it. |
|
@siebertm I was able to reproduce something similar here — suspend works fine on its own, but I noticed freezes when suspend-then-hibernate kicks in. #5041 and #5051 should help with that. Just want to make sure I’m not missing anything on my endL would you mind checking your journals to see if hibernation is being triggered there as well? |
|
@alansikora I just updated all packages from a "broken" state (no "ormachy" release update, just normal packages) - and sleep/wake works again for me. I was not able to pinpoint the package which broke it. I suspect a linux-kernel or linux-firmware, but have no proof. |
Problem
FUSE daemons — primarily
gvfsd-fusefrom Nautilus — can block the kernel's process freeze during suspend/hibernate. The daemon gets stuck in uninterruptible sleep (D state) waiting for FUSE I/O responses, the freeze times out after 20 seconds, and suspend silently fails. The system stays fully awake while appearing suspended, draining the battery.This affects every Omarchy system since Nautilus (and therefore gvfs/fuse) is installed by default. It was confirmed as the root cause of excessive battery drain on Framework 13 AMD in #4184, and likely contributes to other suspend issues reported in #1556 and #2501.
Fix
Adds a systemd system-sleep hook that lazy-unmounts all FUSE filesystems before suspend/hibernate, following the same pattern as the existing
keyboard-backlightandforce-igpuhooks.prefor both suspend and hibernate/proc/mountsgenerically — handles all users, all FUSE types (gvfsd-fuse, portal, rclone, sshfs)fusermount3 -uzreturns immediately (lazy unmount), non-destructivepost, restarts gvfs-daemon for each logged-in user in the background (gvfsd-fuse doesn't self-restart; backgrounded with a delay to avoid blocking user.slice thaw)Blast radius
Changes
default/systemd/system-sleep/unmount-fusemigrations/1773012889.shbin/omarchy-hibernation-setupTesting
Tested on Framework 13 AMD (Ryzen, s2idle only):
References