NFS > FUSE: Why We Built Our Own NFS Server in Rust
about.xethub.com
about.xethub.com
It’s part of Buildbarn, a distributed build cluster for Bazel, but it can also easily be used outside that context.
Details: https://github.com/buildbarn/bb-adrs/blob/master/0009-nfsv4....
My recommendation to the authors would be to use NFSv4 instead of NFSv3. No need to mess around with that separate MOUNT protocol. Its semantics are also a lot closer to POSIX.
~20 years ago I was using SFS (Self-certifying file system), which was a SSH-like Internet-usable TOFU filesystem, using NFS as the "backend" for talking to the host OS. The site has since disappeared, but is archived at https://web.archive.org/web/20080330201843/http://www.fs.net....
Not really world's first. CERN has developed EOS (https://eos-web.web.cern.ch/) for many years, and even though it's not available natively on Windows, it is available on Linux and macOS. EOS uses FUSE, though, not NFS.
> This enables you to, in just a few seconds, locally mount ~660 GB of Llama 2 models or write DuckDB queries to analyze large parquet files and scan just the data you need.
If you mount all instances of EOS at CERN on your machine with the FUSE client, that in principle mounts hundreds of PB of data from LHC experiments, although much of this data requires special permissions to be accessed. However, there's also a lot of open data. See https://opendata.cern.ch/.
I've been toying with 9p+Wireguard lately, as an alternative to SMB/Webdav/sftp/etc for sharing files with friends over the Internet. Wireguard+NFS works well enough, but it's relatively hard to integrate in userspace. Toying with rust-9p[1], I obtained acceptable performance. I still have to experiment with putting Wireguard in userspace as well (probably with Tailscale's implementation), but I come back to the difficulty of mounting 9p and NFS shares as a user. I also wish it was simpler to export directories over both protocols, on an unprivileged port, with access rights limited by those of the user.
Regarding the article content, I find 9p to be even simpler and probably more ubiquitous than NFS, though I don't know if MacOS and Windows natively support it.
Add e.g. foo.bar.com:/path /net/foo.bar.com nfs to /etc/fstab with options=user ?
> Regarding the article content, I find 9p to be even simpler and probably more ubiquitous than NFS, though I don't know if MacOS and Windows natively support it.
Windows certainly does not. MacOS I don't know, but if you mean "natively" as "stock install without third-party software", then probably not.
Actually, scratch that, comments below suggest that WSL2 uses 9P for file sharing with the host, so it's possible that a version of Windows with the WSL2 bits installed will support 9P.
For reference, another Rust project that depends on Boringtun is Onetun [1], which uses it to encrypt packets sent over a virtual smoltcp interface. I imagine you could follow a similar approach to integrating rust-9p with Boringtun, and you wouldn't need to leave the Rust ecosystem (whereas you might face more obstacles integrating it with Tailscale's wgengine, which is written in Go).
Wait, what......
.. So not only is it an easy-to-run Rust NFS server and client (I gave up on NFS some years ago because I couldn't figure out how to run Samba) but it's also meant to use as a _substitute_ for FUSE in stacks like SSHFS or an app wanting to serve debug data as files?
Awesome!
Edit: Oh. It's async. The other bit that I liked from fuser: the default implementations in the trait cut down on the boiler plate. Setting the RO mount option got you defaults that DTRT.
Btw, why did you decide to use NFS instead of WebDAV? WebDAV should be easier to implement and is also supported on all platforms.
Also did you look at NFSv4 / what made you decide to go with NFSv3? My (superficial) impression was that NFSv4 did a lot of simplifying and throwing out legacy stuff (e.g. rpcbind), but I don't know too many details on this…
[edit: NFSv4 answered on parent / https://news.ycombinator.com/item?id=37575304 ]
FWIW I think NFSv4 would be a rewrite rather than an extension :D
NFSv4 did throw out a lot of the legacy stuff, but also added a bunch of other state information like locks and delegation which is quite a bit more annoying to implement. Technically cos this is meant for "localhost-mounting-only", delegation should be easy to build (since we are expecting only exactly 1 mount). But v3 had far fewer APIs to implement, and so is a good starting point.
I know from lore that there are compliance-test suites for the POSIX file system API, but I believe those are commercial products :(
/// /*
/// * Remote file service routines
/// */
/// program NFS4_PROGRAM {
/// version NFS_V4 {
/// void
/// NFSPROC4_NULL(void) = 0;
///
/// COMPOUND4res
/// NFSPROC4_COMPOUND(COMPOUND4args) = 1;
///
/// } = 4;
/// } = 100003;The fact you just need to impl one trait is amazing. I will definitely be testing this out
I'm not sure what value of "much adoption" you're using, but I think it's had great adoption.
All the operating systems I names have fully implemented and mature NFSv4 stacks. Definitely not a MVP to tick a box.
All my file access is over NFSv4 (in a mix of 10 GbE and 100 GbE).
Having GP’s crate expand to support NFSv4 would be welcome but a nontrivial bit of work.
For example, NFSv4 supports accessing files that have been unlinked, but still have one or more open file descriptors. NFSv3 does not. It needs to resort to a technique named ‘silly renames’.
http://linux-nfs.org/wiki/index.php/Server-side_silly_rename
NFS3 is small (I wouldn't say "elegant" but by comparison...), works, and doesn't have anything wrong with it.
(Correct NFSv3 implementations block forever, which is the best of three bad alternatives.)
Maybe newer NFS revisions allow for the NFS server to notify clients of changes like this, which would be really open things up here.
IIRC the statelessness of nfs was largely considered a design mistake, and there usually are a large number of hacks to overcome the consequences.
So much so that nfsv4 moved to a stateful protocol…
NFSv3+wireguard is approximately the perfect network filesystem protocol.
Writing FUSE drivers is pretty frustrating, though, and not well supported by all OSs.
My takeaway is that this project discards FUSE in favour of making an NFS server that can be easily extended to do the same thing: present non-file system systems as mountable nfs remote file systems.
It’s a neat idea, and does avoid any extra kernel drivers, etc. A safer abstraction at the cost of adding a network stack and NFS’s sometimes wonky effects (especially with hard mounts).
Who doesn't?