[HN Gopher] Userspace FUSE for macOS
___________________________________________________________________
Userspace FUSE for macOS
Author : freebeer2
Score : 187 points
Date : 2022-09-05 16:30 UTC (6 hours ago)
(HTM) web link (www.fuse-t.org)
(TXT) w3m dump (www.fuse-t.org)
| concerned_ctzn wrote:
| https://github.com/macos-fuse-t/fuse-t
| mdaniel wrote:
| That "repo" appears to exist solely for housing the release
| artifacts, for those who came to the comments looking for "the
| goods"
|
| Also, https://github.com/macos-
| fuse-t/fuse-t/blob/main/License.txt appears to be "playing
| lawyer"
| TimTheTinker wrote:
| > Also, https://github.com/macos-
| fuse-t/fuse-t/blob/main/License.txt appears to be "playing
| lawyer"
|
| Do you have any specific concerns with the text of the
| license? The text seems clear enough that there don't appear
| to be any potential liabilities from using the software in a
| _personal_ capacity.
|
| As I understand it, the worst that could happen is that the
| license/software author could unknowingly incur liabilities
| from statutory or implied warranties - i.e. they left out
| some important exclusions that could be brought to bear if a
| plaintiff successfully construed the license as a contract.
|
| (IANAL, but I've read a lot about software licenses over the
| years and have dealt with a legal challenge related to dual
| commercial/OSS licensing)
| rgovostes wrote:
| For one thing, they copied the clauses from the BSD
| license, including references to "the following
| disclaimer", but omitted the disclaimer itself.
| EdSchouten wrote:
| What a coincidence! For a project that I maintain (Buildbarn, a
| distributed build cluster for Bazel) I recently generalized all
| of the FUSE code I had into a generic VFS that can both be
| exposed over FUSE and NFSv4. The intent was the same: to provide
| a better out of the box experience on macOS. Here's a design doc
| I wrote on that change. Slight warning that it's written with
| some Buildbarn knowledge in mind.
|
| https://github.com/buildbarn/bb-adrs/blob/master/0009-nfsv4....
|
| Fortunately, fuse-t doesn't make any of my work unnecessary.
| Buildbarn uses go-fuse, which talks to the FUSE character
| directly instead of using libfuse. fuse-t would thus not be a
| drop-in replacement. Phew!
|
| PS: A bit unfortunate that fuse-t isn't Open Source. :-(
| justsomeadvice0 wrote:
| You might look at webdav instead, which has actual existing
| library implementations (unlike NFSv4), supports user/pass auth
| (in some cases you don't want wide-open services on loopback)
| and is based on HTTP; that would make the whole thing easier.
| Various projects offer a webdav combat layer, see cryptomator
| for one example:
| https://docs.cryptomator.org/en/latest/desktop/vault-mountin...
|
| I went down the NFS road long ago - I somewhat (??) remember
| that coaxing macOS to mount_nfs on loopback is actually a PITA
| (I remember having to activate 127.0.0.* and mount 127.0.0.2).
| skissane wrote:
| I remember, around 10 years ago, mucking around with WebDAV,
| and discovering many WebDAV clients were extremely crapulent.
| Especially on Windows.
|
| Maybe, some years later, Windows' WebDAV client has improved.
| And I can't remember whether macOS WebDAV was better or not.
| EdSchouten wrote:
| Replying to my own comment:
|
| I do wonder how this library deals with some of the fundamental
| differences beween FUSE and NFSv4. For example, with FUSE the
| kernel and server share intimate knowledge on which part of the
| file system lives in the kernel's inode cache. Only when the
| kernel issues a FORGET call, may the server drop information
| corresponding to a given nodeid.
|
| As NFSv4 is designed to be stateless, servers may need to be
| able to process requests containing arbitrary file handles,
| regardless of how long ago they were returned as part of some
| prior request. You therefore see that in-kernel implementations
| of NFS servers rely on special file system methods to resolve
| objects by file handle, in addition to being able to resolve by
| path.
|
| This means that if you implement FUSE on top of NFSv4, you will
| most likely not be able to purge any state. Your FUSE file
| system's FORGET method will probably never be called. This
| means that memory usage of fuse-t will most likely just keep on
| growing as time progresses? Or it announces itself as using
| file handle mode FH4_VOLATILE_*, but UNIX-like NFSv4 clients
| hardly ever know how to deal with that.
| boulos wrote:
| Nit: NFSv3 is stateless, V4 isn't (sessionid and clientid
| permit stateful handling of locks and shares).
|
| I would assume this person is just doing an in-memory "NFS
| server" that would keep all of that state around. So it's
| more like a FUSE-compatible layer that speaks NFSv4 as a
| "front end" (since NFS clients are better than "ha ha,
| surprise! This FUSE backend is networked and can fail on
| weird ways").
|
| I'm not sure how they chose to translate things like
| DELEGATE, SEQUENCE, and so on (probably just reply with an
| error). But for basic OPEN, READ, WRITE, etc. it's all fairly
| straightforward.
|
| I had hoped they used nfs-ganesha for the NFS server /
| frontend, but the attributions file suggests they probably
| rolled their own (and thus is going to be full of bugs and
| immature for quite some time).
| FullyFunctional wrote:
| TIL about nfs-ganesha. I have yet to digest it all, but
| ignoring the wonderful usability of sshfs, it seems you
| should be able to get the functionality of sshfs with nfs-
| ganesha? Am I missing something?
| EdSchouten wrote:
| With it being stateless, I was referring to just the part
| where I wanted to point out the difference: file handles
| are stateless, while FUSE's equivalent (nodeids) are
| stateful.
|
| Regardless of whether it's an in-memory or persistent
| solution, the problem remains: fuse-t has little choice but
| to leak resources of the underlying FUSE file system, as
| there is no valid point in time in which you can issue
| FORGET operations. This means that any file system with
| some form of churn rate will leak memory.
|
| Also note that delegation is effectively optional. If a
| server simply always replies with OPEN_DELEGATE_NONE, the
| client has to interact with the file as if it's stored
| remotely.
|
| There is no need to implement SEQUENCE, by the way. macOS
| implements NFSv4.0, while SEQUENCE is part of NFSv4.1 and
| later.
| concerned_ctzn wrote:
| I don't understand the comment about leaking memory, nfs
| file handles don't have to be persistent. Besides, how
| many FUSE filesystems implement FORGET? Anyway this is
| the reason I went with NFSv4. I started the project with
| NFS v3 but then discovered many limitations: being
| stateless, no named attributes, questionable locking
| support, etc. So Eventually I dropped it and re-
| implemented everything on NVSv4.
| EdSchouten wrote:
| > I don't understand the comment about leaking memory,
| nfs file handles don't have to be persistent.
|
| As long as the file the NFSv4 file handle refers to is
| still usable (i.e., linked into the file system), the
| NFSv4 file handle must remain usable. Note that this is
| not a universal requirement, but at least one that the
| macOS NFSv4 client enforces. It only implements
| FH4_PERSISTENT. This doesn't seem to be documented
| explicitly, but is somewhat revealed by this printf():
|
| https://github.com/apple/darwin-
| xnu/blob/main/bsd/nfs/nfs_vf...
|
| > Besides, how many FUSE filesystems implement FORGET?
|
| Any file system that wants to remove files in the
| background (meaning: not by calling unlink() through the
| FUSE mount) must likely do proper refcounting on such
| files, and provide an implementation of FORGET.
|
| For example, a file system that can give information on
| live football matches may want to remove
| files/directories belonging to matches that have already
| ended. In that case you want the node IDs to remain
| valid, but refer to files that have already been unlinked
| from the file system hierarchy. The FORGET operation
| allows you to determine when those files can be removed
| from the FUSE server's bookkeeping entirely.
|
| Here is an implementation of FORGET that I wrote for
| Buildbarn:
|
| https://github.com/buildbarn/bb-remote-
| execution/blob/master...
| concerned_ctzn wrote:
| I'm not sure I understand you point, if an inode gets
| removed, then GETATTR or LOOKUP would fail as it should
| unless you're talking about open files. In the latter
| case the inode will get removed when the last open handle
| to the file is closed
| boulos wrote:
| > macOS implements NFSv4.0, while SEQUENCE is part of
| NFSv4.1 and later.
|
| Whoa. That's a real mistake. v4.0 is widely considered a
| "oops, we shouldn't have released this". TIL!
| als0 wrote:
| In sore need of FUSE for macOS on Apple Silicon, without
| downgrading system security. Clever trick to use NFS behind the
| scenes.
| mdaniel wrote:
| I don't know what's going on with the google.com/url encoding of
| the links on the submitted article
|
| Also, one will want to be aware of the currently unsupported
| features <https://github.com/macos-
| fuse-t/fuse-t/wiki#unsupported-feat...> since the submitted
| article appears to be aspirational
| tech234a wrote:
| The page appears to be hosted on the new Google Sites.
| HHad3 wrote:
| This is great! I hope that this project enables those many FUSE-
| related applications to return to Homebrew since an open-source
| FUSE provider is now available again.
|
| I am curious though why a NFSv4 server was chosen over wrapping
| Apple's File Provider API [1], which seems to be the native
| method for providing virtual file systems from user space on
| macOS since macOS 11.5. After glancing over the API I guess it's
| because FPEs are too high-level to implement FUSE properly, but
| I'd be glad if you can share any details to satisfy my curiosity.
|
| [1] https://developer.apple.com/documentation/fileprovider
|
| EDIT: Errata, I assumed it was open-source, but it is not. Too
| bad :( -- but at least this will eventually provide a more stable
| FUSE experience on macOS.
| mdaniel wrote:
| It seems based on the associated WWDC video
| (https://developer.apple.com/videos/play/wwdc2021/10182/) that
| API appears to be for making your own Dropbox/GDrive/OneDrive
| client, and not "present this totally fake filesystem" scenario
| guruz wrote:
| ocsmount for WebDAV is also based on a local NFS server.
|
| https://ocsmount.com/
| schappim wrote:
| FUSE really demonstrates the unreasonable effectiveness of file
| systems as an interface.
| junon wrote:
| Or perhaps the unreasonable ineffectiveness of current-day IPC
| mechanisms.
| freebeer2 wrote:
| A new project aims to deliver libfuse for mac without using
| kernel extensions.
| keepquestioning wrote:
| Could this be done using DriverKit
| mdaniel wrote:
| linky: https://developer.apple.com/documentation/driverkit
|
| > The drivers you build with DriverKit run in user space,
| rather than as kernel extensions, which improves system
| stability and security. You create your driver as an app
| extension and deliver it inside your existing app.
|
| makes it seem like every consumer who wants to use something
| FUSE-y would have to ship their own impl, right?
|
| and I shudder to think of the heartache required with signing
| or whatever Apple gatekeeping is going on nowadays
| concerned_ctzn wrote:
| The author here. DriverKit is really a no-go. A while back I
| was asked to do a project based on DriverKit, it took me
| nowhere because of countless bugs and semi-implemented
| features, worse yet, it caused system crashes (and it was
| supposed to be stable).
| orangea wrote:
| Why not use the file provider API?
| https://developer.apple.com/documentation/fileprovider
| 4ad wrote:
| The File Provider API is very limited. In particular, it can't
| be used to implement file systems where the directory hierarchy
| is dynamic. It can't materialize directories on `chdir(1)`, for
| example.
|
| The design was obviously tailored for providers that implement
| real disk files, like Dropbox and Apple's own iCloud Drive.
|
| Btw, Apple also ships with an undocumented 9P implementation.
| It seems to be used for mounting the host filesystem in
| virtualized guests. It is unclear if it can be made to work
| over a normal (non-PCI) transport like TCP.
| mathiasgredal wrote:
| I found the api incredibly hard to use as someone who hasn't
| used swift or macOS API's before. Because of the way some of
| the code runs as a separate plugin from the main app, you can't
| really use traditional logging as a debug tool. There is also a
| lot of split state to be handled. You have to provide sync
| anchors and diffed tree updates to change the folder contents,
| which just aren't available with most backends.
|
| I started on a program to mount a website resource directory on
| your computer using this api, but I gave up due to the
| restrictions of the api:
| https://github.com/mathiasgredal/Itslearning
| carlhjerpe wrote:
| Because your software was written against FUSE and you don't
| wanna spend time rewriting it to accommodate Apple users.
| orangea wrote:
| I meant why not make a project like this that emulates the
| FUSE API, but use the file provider API to present the file
| system to the OS instead of NFS. It would have the advantage
| that it would be better integrated with the OS, for example
| you can display upload progress indicators on files in
| Finder. Maybe that can also be done with NFS though, I don't
| know.
| 4ad wrote:
| It's impossible, see my other reply.
| mrpippy wrote:
| macOS Ventura has moved some lesser-used file systems (FAT,
| exFAT) out of the kernel to user-space, I believe using a private
| framework developed for iOS (when that added USB mass-storage
| support).
|
| Hopefully they'll open those APIs up for 3rd party usage on the
| Mac next year.
| tambourine_man wrote:
| macOS really needs a decent FUSE implementation. That and some
| sort of container story.
|
| Such a shame that it's not really open source. The idea of using
| NFSv4 is awesome though.
| alerighi wrote:
| Awesome, to me it seems terrible, and something that can break
| anytime. You have two layers of translation, the actual FUSE
| filesystem implementation that uses the FUSE API to communicate
| with something that emulates a FUSE API in userspace to then
| talk via NFS to the kernel. NFS is broken in a lot of ways,
| especially with file locking, that could result in deadlocks.
|
| Really FUSE should be implemented in the kernel itself, it was
| meant to do so, a kernel-side layer to allow implementing a
| filesystem userspace efficiently. When they created fuse NFS
| already existed, and if they decided to create a new protocol
| and add it to the kernel, rather that something on top of NFS
| or directly exposing a NFS server in applications, a reason
| maybe existed right?
|
| Not having a stable FUSE implementation is one of the many
| reasons that made me abandon macOS and return to the
| combination of Windows and Linux. Even Windows has a mostly
| decent open-source FUSE implementation!
| tambourine_man wrote:
| You're right, a proper userspace filesystem implementation is
| the preferable route. I was mostly impressed by the neet
| hack.
| mdaniel wrote:
| > That and some sort of container story.
|
| While off-topic for this thread, I don't think that's going to
| do what you expect. If you snapped your fingers and XNU
| suddenly had cgroups and other namespace trickery required to
| make containers operate, you'd still have the grave problem of
| "containers are not virtual machines" and thus an XNU container
| would only run Darwin binaries, so you're back to the old days
| of "run one exe locally, run another in prod"
| tambourine_man wrote:
| Yeah, but easily switching between specific version of PHP,
| MySQL, Node.js, etc, without messing with /usr/local/bin and
| brew while having full speed disk access goes a long way.
|
| I could probably get by with the chroot support that macOS
| has, but I never manage to find the motivation.
| duskwuff wrote:
| You can install multiple versions of PHP and Node alongside
| each other just fine using Homebrew: brew
| install php@7.2 php@7.3 php@7.4 php@8.0 php@8.1 # and soon
| php@8.2 brew install node@18 node@16 node@14
| node@12 node@10
| tambourine_man wrote:
| Installing multiple versions is solved, changing the
| environment easily, not so much, I think
| Cyberdog wrote:
| I'm not sure of the specifics with Homebrew, but with
| MacPorts, I have both PHP 7.4 and 8.1 running via FPM and
| serving sites rather trivially. The basics: Install both
| php74-fpm and php81-fpm, configure the former to put its
| socket at /var/run/php74-fpm.sock and the latter at
| /var/run/php81-fpm.sock, configure nginx's domain-
| specific config files to look for the FastCGI socket that
| the respective path, use MacPorts to load both daemons,
| and away you go. I imagine a similar approach would be
| possible with Homebrew.
| chrisseaton wrote:
| Most people don't want to install and uninstall software
| at the system-level like that. They'd rather have nicely
| isolated disposable containers for individual projects.
| jbverschoor wrote:
| or just use asdf
| tambourine_man wrote:
| I wasn't aware of it, thanks. I'm not it's exactly what I
| want though. Can it easily start and stop daemons? Can it
| assign different ports to different versions?
| clhodapp wrote:
| You're assuming that everyone's "prod" is a Linux server. I
| would say that MacOS needs containers for developing Darwin
| software.
| mdaniel wrote:
| Yes, I think that's a perfectly reasonable assumption given
| that (AFAIK) the only current "containerization" (as GP
| used that word) strategy is on Linux. BSD has jails and
| Solaris has something similar, but as far as "fire this
| thing up with its own pid, network, and fs namespacing, and
| allow me to constrain it easily" that's just Linux. I guess
| put another way: you run Darwin in production?
|
| As for the latter, macOS actually does have what _they_
| call Containers (https://developer.apple.com/library/archiv
| e/documentation/Se...) but as best I can tell such a thing
| requires opt-in from the app, which kind of defeats the
| purpose of running untrusted software IMHO. I actually only
| learned about that Containers stuff from trying to find
| where in the hell 1Password 8 stores its actual sqlite
| file: `$HOME/Library/Group
| Containers/2BUA8C4S2C.com.1password/Library/Application
| Support/1Password/Data/1password.sqlite`
| sroussey wrote:
| Thanks for this. I have a library that uses 1Password
| files and have not updated for v8.
| mdaniel wrote:
| While digging up a link for a separate comment, I found
| (https://macoscontainers.org/) which points to:
| https://github.com/containerd/containerd/discussions/5525
| skissane wrote:
| What advantages does NFSv4 have over SMB/CIFS for this use case?
|
| I have had the same idea myself before, but with a more cross-
| platform scope (Linux and Windows too, not just macOS). Whatever
| it flaws, SMB/CIFS has the advantage of being supported out-of-
| the-box on more platforms than NFSv4 is.
| rgovostes wrote:
| Unfortunately, like macFUSE, this is not really open source. The
| license appears to be BSD-like for non-commercial use only. Also
| like macFUSE, the project uses GitHub but the source code is not
| available.
|
| https://github.com/macos-fuse-t/fuse-t/blob/main/License.txt
| skissane wrote:
| The developer says they will release source code soon -
| https://github.com/macos-fuse-t/fuse-t/issues/1#issuecomment...
| - although keeping the restrictive license.
|
| Apple is introducing user-space file system technology in macOS
| - LiveFS/UserFS/com.apple.filesystems.lifs - some of the
| infrastructure turned up in Monterey, in Ventura it is actually
| being used for mounting FAT/exFAT filesystems.
|
| It looks like for now Apple is keeping the API Apple-internal
| only (although I haven't looked at the Ventura SDK, so I could
| be wrong about that). But if Apple made the API public, it
| could be the death-knell of all these commercial FUSE-
| alternatives for macOS offerings. (Even if Apple's API isn't
| FUSE-compatible, if it is close enough, someone could easily
| open-source a translation layer - likely to be a lot simpler
| than bridging FUSE to an NFS server.)
| [deleted]
| jbverschoor wrote:
| Why does everybody use tcp ports instead of file sockets for
| local communication?
| concerned_ctzn wrote:
| tcp ports are much more versatile, you can expose it to the
| outside world as opposed to unix sockets. Now exposing an nfs
| server to the outside can lead to interesting possibilities:
| for example you can implement a local fuse file system which
| can be mounted remotely through the NFS. It's highly not
| recommended at this moment because there's no authentication
| implemented
| FullyFunctional wrote:
| Is there any fundamental reason you couldn't do both?
| Presumably local sockets have less overhead (and I do prefer
| not to open ports unless needed).
| pstuart wrote:
| 2 guesses: ignorance, and an assumption that using tcp allows
| for seamless transition to another host.
| jbverschoor wrote:
| Api is still socket api.. AF_INET vs AF_UNIX. It takes a few
| lines of code to have to option to switch between. Ignorance
| makes sense..
|
| I guess full stack developers means people who can read the
| top 5 lines of a stack trace
| klabb3 wrote:
| I guess I'm ignorant then! When I looked up domain sockets
| and so on it turned out to be different APIs for different
| OS:s, and it's significantly nicer to rely on a single API
| surface from the std lib. Maybe it's a habit thing as well,
| but to me pipes are more esoteric and harder to find docs
| about than network sockets.
| pstuart wrote:
| > I guess I'm ignorant then!
|
| We all are in our own ways ;-). I pulled that comment out
| of my ass so I'm ok with being corrected as appropriate.
| jbverschoor wrote:
| But they are not (named) pipes, it's the same api. Just
| speak http or whatever over the socket. Afaik, windows also
| seems to support it these days
| inetknght wrote:
| > _Why does everybody use tcp ports instead of file sockets for
| local communication?_
|
| In my experience it's because Windows and mac developers aren't
| _aware_ of local file sockets. Windows API, in particular,
| doesn 't have a similar concept if I recall.
| 10000truths wrote:
| Windows 10 has support for UNIX sockets.
| duped wrote:
| Windows has named pipes. MacOS has UDS and they're not
| terribly uncommon
| eptcyka wrote:
| Windows also supports UDS now.
| origin_path wrote:
| Windows added UNIX domain sockets in recent years. They work
| everywhere now.
| lxgr wrote:
| Does the built-in macOS SMB client support mounting resources
| via file socket?
| jbverschoor wrote:
| The bsd mount_nfs code uses AF_INET. Which makes sense. But I
| got triggered by the fact that is yet another app listening
| to ip
| userbinator wrote:
| Because TCP is well-known and works both locally and over the
| network, on just about every networked operating system?
| jbverschoor wrote:
| It's not almost enough for all developers to not just simply
| bind to 0.0.0.0.
|
| It's not well known enough, looking at the recent thread
| where people are amazed that the i notation is simply a 32bit
| number van can be used like that. Or even http://0xd1d8e6f0
|
| For example, even if you do vind to localhost, anyone on your
| system can access your service. Let's say an electron is
| running on port 5555. A guest user on your system can just
| access the electron app. If this app happens to be vscode,
| you now have full access.
|
| It's just plain stupid. You basically nuked multi user
| security. Better run dos then
| searealist wrote:
| Unix domain sockets have a severe limitation that the path must
| be a maximum 108 characters.
| chrismonsanto wrote:
| This limitation only applies to the file name, as you can
| chdir to the directory before bind/connect. Unfortunate but
| not a deal breaker
| 10000truths wrote:
| That's plenty for most applications, no? /var/run/*.sock
| isn't that many characters.
| searealist wrote:
| For many applications it is enough. For others, such as
| placing a UDS in a user's home directory or temp folder, it
| may not be. Often times you don't know ahead of time what
| the path may be.
| skissane wrote:
| Is anybody trying to lift that limitation? It seems like an
| obvious target for kernel devs to tackle.
|
| If Linux and *BSD did it (especially if they adopted a
| mutually compatible implementation), the POSIX
| standardisation team (Austin Group) would likely be
| interested in adding it to POSIX, and Windows/macOS/AIX/etc
| will likely follow their example sooner or later.
| jbverschoor wrote:
| Sure, but all these services listening on ports, sometimes
| not even bound to localhost is just shitty. There's no
| authentication. and it's actually a huge contributor to
| database dumped online. Besides the security, ease of
| selecting a path vs a free port, it's also faster
| searealist wrote:
| Agreed. It's just that UDS are hard to work with due to
| this limitation.
___________________________________________________________________
(page generated 2022-09-05 23:00 UTC)