Page MenuHomeFreeBSD

fusefs: Support for the auto_unmount FUSE option
AcceptedPublic

Authored by arrowd on Jul 26 2025, 11:03 AM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Oct 7, 12:47 PM
Unknown Object (File)
Tue, Oct 7, 11:11 AM
Unknown Object (File)
Sat, Oct 4, 12:37 AM
Unknown Object (File)
Fri, Oct 3, 9:43 PM
Unknown Object (File)
Fri, Oct 3, 9:25 PM
Unknown Object (File)
Fri, Oct 3, 7:59 PM
Unknown Object (File)
Fri, Oct 3, 7:48 PM
Unknown Object (File)
Fri, Oct 3, 4:31 PM
Subscribers

Details

Reviewers
asomers
kib
Summary

If the FUSE daemon exits abnormally its mountpoint will not be unmounted.
To counter that the libfuse client may pass -o auto_unmount asking the library
to properly cleanup the mointpoint. This is achieved by starting a watchdog
process that first waits for the daemon process to finish and then unmointing
the FS if it is still there.

This change introduces the --auto-unmount option for mount_fusefs, an internal
hidden option inteded to be used only by libfuse.

The complementing libfuse part of changes is at https://github.com/libfuse/libfuse/compare/master...arrowd:libfuse:bsd-auto-unmount

Test Plan

hello_ll from libfuse/examples can be used to demonstrate the
initial problem and how it is fixed by this patch.

  • example/hello_ll -d -o auto_unmount /tmp/foo
  • killall -KILL hello_ll
  • mount | grep foo

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 67566
Build 64449: arc lint + arc unit

Event Timeline

Ping. Alan, could you please take a look?

I have a few thoughts:

Firstly, I think there might be an easier way to implement this. If you pass the auto_unmount option to the kernel, then you could add a .d_close method to fuse_device_cdevsw. That method would check for the auto_unmount mount option. If it's set, and the file system isn't already dead (fdata_get_dead), then it would call VOP_UNMOUNT. I think it would work.

Secondly, if the daemon is truly dead, then I think it would make sense to use MNT_FORCE

Thirdly, in the libfuse component, I think that you could move the statfs and snprintf calls to be before the rfork. Then you could use posix_spawn, which IMHO is less error-prone than rfork. Of course, this point would be moot if my first suggestion works.

sbin/mount_fusefs/mount_fusefs.c
144–147

Can you use process descriptors instead of pid,ki_start ? Use pdgetpid to get the pid, and pdkill to kill it.

Thirdly, in the libfuse component, I think that you could move the statfs and snprintf calls to be before the rfork. Then you could use posix_spawn, which IMHO is less error-prone than rfork.

The reason for rfork is RFCFDG - I wanted the autounmounter process to inherit nothing from the caller, because we might being called from the libfuse library.

From what I gather, posix_spawn would still inherit all the descriptors and I'll have to clean them up manually.

sbin/mount_fusefs/mount_fusefs.c
144–147

Because of RFCFDG usage, the child process does not inherit any fds. We can still pass the procdesc fd via unix socket if you insist, but pid+starting time looks enough to me.

Firstly, I think there might be an easier way to implement this. If you pass the auto_unmount option to the kernel, then you could add a .d_close method to fuse_device_cdevsw. That method would check for the auto_unmount mount option. If it's set, and the file system isn't already dead (fdata_get_dead), then it would call VOP_UNMOUNT. I think it would work.

When we first talked about auto_unmount you mentioned that it is implemented entirely in userspace on Linux, which is why I followed this route.

My kernel knowledge is limited, what would happen in the filesystem make a fork and then close the fuse device descriptor? Is .d_close called when the last descriptor gets closed or whenever any descriptor gets closed?

kib added inline comments.
sbin/mount_fusefs/mount_fusefs.c
144
154

return after errx is excessive, and I suspect that compiler is aware of it due to annotations.
In fact, I suspect that you meant warnx

162
163
168

This should be warn() (without x)

174

You do understand that if the process exits before kevent() is armed, you probably would wait forever.

175

Same comments, not retyping anymore

184
194
201

Why strncmp()? The fstypename buffer is large enough to have terminating nul. You would also match e.g. "fusesfsnotreally" fs type.

arrowd marked 8 inline comments as done.

Address kib's comments

I did not try the in-kernel approach yet which was suggested by Alan.

sbin/mount_fusefs/mount_fusefs.c
41

Order alphabetically

129

everywhere

144

Still not fixed

197

Do ... else FS.

I am told always that comments should be full sentences.

203

and so on

arrowd marked 5 inline comments as done.

Style fixes.

sbin/mount_fusefs/mount_fusefs.c
41

But param.h should go first, it is special.

144

Are you ignoring me for a reason?

208
215

After seeing this code in practice it seems quite complicated. I do think that the kernel based approach would be simpler. But an important question is: what file systems already use this option on Linux? How many of them would work with either this implementation, or the hypothetical kernel-based one?

But an important question is: what file systems already use this option on Linux?

I'm not aware of any "conventional" filesystems that use this option. Rather, it is employed by some unconventional fuse daemons.
I first stumbled upon this option when porting https://github.com/flatpak/xdg-desktop-portal/
Another major consumers of this flag is AppImage runtime https://github.com/AppImage/type2-runtime

How many of them would work with either this implementation, or the hypothetical kernel-based one?

Not sure what you mean. I expect any fuse daemon to work with whatever implementation.

sbin/mount_fusefs/mount_fusefs.c
144

Nope, just missed this one. But I did not mark this one as "Done" though, so I'm aware that the comment stays open.

201

This is intended. Filesystems mounted by FUSE servers have names "fusefs.something" but it also may be just "fusefs".

arrowd marked 4 inline comments as done.
  • More style fixes
sbin/mount_fusefs/mount_fusefs.c
201

Might be a new MNT_FUSE or similar flag would make it more reliable.

sbin/mount_fusefs/mount_fusefs.c
166

And there (close(kq) ?)

184

Should you close kq there and in NOTE_EXIT check below?

[I do not think it is important since the utility is one-run, but you do close kq in the unmount case]

  • Add missing close(kq) calls
This revision is now accepted and ready to land.Sun, Oct 5, 10:03 PM