fuser icon indicating copy to clipboard operation
fuser copied to clipboard

Extract `Channel` FD and self-mount

Open colinmarc opened this issue 1 year ago • 9 comments

Hi, I have a use case (containers) where I need to get the session FD and do the mounting myself. I took a look at changing the API to support this, but unfortunately, it seems like mnt::Mount and Session are pretty tied together at the moment.

Before I propose any significant API changes, do you have an idea how I could achieve this?

Thanks!

colinmarc avatar Oct 06 '24 12:10 colinmarc

I poked around a bit more. First, let me clarify roughly what I'd like to do:

  1. Create a Session with my FileSystem.
  2. Call AsFd::as_fd on the Session. Then, take that FD, and pass it into my own mount(2) call with fd=123.
  3. Call Session::run to proceed as normal.

Fundamentally, this seems like it would require splitting Session into two types: one which holds the /dev/fuse FD (the Channel), and one which knows the mountpoint and calls umount when it's dropped.

However, The fact that a session is also a mountpoint, as far as the API is concerned, seems to stem from libfuse. That's because fuse_session_new takes the mount args already. So while the above change would be fairly trivial with fuse_pure, it's not easy with libfuse.

I don't suppose you'd consider dropping support for libfuse? :sweat_smile:

colinmarc avatar Oct 06 '24 13:10 colinmarc

Huh, there's also a (very wacky) libfuse3 way to do this: https://github.com/libfuse/libfuse/pull/291

colinmarc avatar Oct 06 '24 15:10 colinmarc

Can you tell me more about the use case? I'm trying to understand if this is common enough that it should be support in fuser

cberner avatar Oct 08 '24 02:10 cberner

Can you tell me more about the use case? I'm trying to understand if this is common enough that it should be support in fuser

FUSE plays a special role in containers, where it can be used to simulate kernel-level stuff like sysfs or character devices. This is specifically permitted for unprivileged container runtimes by the kernel. However, various security safeguards mean that it requires a very specific dance:

  1. /dev/fuse has to be opened inside the container (inside the user namespace where the mount call happens)
  2. The mount (or fsconfig/move_mount) syscalls have to be done inside the container as well
  3. If the fuse daemon wants to run outside the container (e.g. in the runtime), the FD has to be passed back out to the supervisor process (using a socket or something)
  4. The channel can then be polled for requests normally (Session::run)

colinmarc avatar Oct 08 '24 11:10 colinmarc

One less-invasive way achieve this would be to offer a way to just iterate the Requests given a /dev/fuse FD. That would mean users wouldn't have access to the Filesystem abstraction, however.

colinmarc avatar Oct 08 '24 11:10 colinmarc

We also have a similar use-case in https://github.com/awslabs/mountpoint-s3-csi-driver. We want to run FUSE/fuser process inside an unprivileged Kubernetes Pod (so we can't do mount syscall). We already have a privileged Pod for doing the mount (i.e., opening /dev/fuse and performing mount syscall), and we want to pass obtained file descriptor to our unprivileged Pod where FUSE/fuser process lives.

unexge avatar Oct 08 '24 13:10 unexge

I see, thanks for the links! It sounds to me like the best thing to do is to add a method like Session::from_raw_fd. You can then open /dev/fuse and call mount() anyway that you want, pass the resulting fd to the correct process, and then call Session::from_raw_fd to create a fuser Session which can run and serve the fuse operations.

Does that sound like it will work for both of your use cases?

cberner avatar Oct 13 '24 23:10 cberner

It sounds to me like the best thing to do is to add a method like Session::from_raw_fd.

Yes, that's what #301 does :)

Edit: and also #304, if you prefer less refactoring.

colinmarc avatar Oct 14 '24 18:10 colinmarc

Ah, great. I left some comments on #304. I'd rather not remove the libfuse support right now

cberner avatar Oct 14 '24 22:10 cberner

Hey @cberner, is there any reason for not dropping support for libfuse? Are there any known limitations of pure-Rust mounting?

unexge avatar Oct 21 '24 09:10 unexge

Just unknown unknowns. libfuse is enabled in the default features, and I don't know what the limitations of the pure Rust implementations are. I think it might not work with some of the mac kernel extensions, but haven't tested them. If you're interested in researching and testing all the different platforms and configs, that'd be great!

cberner avatar Oct 21 '24 14:10 cberner

Thanks for the context @cberner! We'll be sharing if we find any limitations.

unexge avatar Oct 22 '24 12:10 unexge