feat: full NFSv4.2 server and client in pure Go
Test / test (push) Successful in 2m4s
Release / gates (push) Successful in 2m5s
Release / build (amd64, freebsd) (push) Successful in 1m27s
Release / build (amd64, linux) (push) Successful in 1m22s
Release / build (amd64, netbsd) (push) Successful in 1m19s
Release / build (amd64, openbsd) (push) Successful in 1m20s
Release / build (arm64, darwin) (push) Successful in 1m21s
Release / build (arm64, freebsd) (push) Successful in 1m26s
Release / build (arm64, linux) (push) Successful in 1m25s
Release / build (arm64, netbsd) (push) Successful in 1m31s
Release / build (arm64, openbsd) (push) Successful in 1m27s
Release / build (loong64, linux) (push) Successful in 1m37s
Release / build (riscv64, linux) (push) Successful in 1m21s
Release / release (push) Successful in 40s
Test / test (push) Successful in 2m4s
Release / gates (push) Successful in 2m5s
Release / build (amd64, freebsd) (push) Successful in 1m27s
Release / build (amd64, linux) (push) Successful in 1m22s
Release / build (amd64, netbsd) (push) Successful in 1m19s
Release / build (amd64, openbsd) (push) Successful in 1m20s
Release / build (arm64, darwin) (push) Successful in 1m21s
Release / build (arm64, freebsd) (push) Successful in 1m26s
Release / build (arm64, linux) (push) Successful in 1m25s
Release / build (arm64, netbsd) (push) Successful in 1m31s
Release / build (arm64, openbsd) (push) Successful in 1m27s
Release / build (loong64, linux) (push) Successful in 1m37s
Release / build (riscv64, linux) (push) Successful in 1m21s
Release / release (push) Successful in 40s
Assisted-by: GLM 5.3 Flash
This commit is contained in:
+134
@@ -0,0 +1,134 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to **nfs** are documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
||||
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [development]
|
||||
|
||||
### Added
|
||||
|
||||
-
|
||||
|
||||
## [1.0.0] - 2026-09-21
|
||||
|
||||
### Added
|
||||
|
||||
The first release of a full NFSv4.2 implementation in pure Go: server and client,
|
||||
minor version 2 on the wire only, no portmapper, no mountd, no separate locking
|
||||
protocol.
|
||||
|
||||
- **Wire foundation**: the XDR codec of RFC 4506, ONC RPC record marking of
|
||||
RFC 5531 with fragment reassembly, the call and reply headers, AUTH_SYS, and
|
||||
the NFSv4.2 operation, error and attribute numbers verified against the
|
||||
standards and the Linux client header.
|
||||
- **Stateless operations**: PUTROOTFH, PUTFH, SAVEFH, RESTOREFH, GETFH, LOOKUP,
|
||||
LOOKUPP, PUTPUBFH, GETATTR, ACCESS, READ, READDIR, WRITE, CREATE, REMOVE,
|
||||
RENAME, SETATTR, LINK, READLINK, COMMIT, VERIFY, NVERIFY, SECINFO and
|
||||
SECINFO_NO_NAME, over a virtual filesystem with a local directory backend.
|
||||
- **Sessions**: EXCHANGE_ID, CREATE_SESSION, DESTROY_SESSION, BIND_CONN_TO_SESSION
|
||||
and SEQUENCE with a slot table, a reply cache per slot, and client reboot
|
||||
detection that drops the state of the previous life.
|
||||
- **Open state**: OPEN and CLOSE with real stateids, share reservations enforced
|
||||
across opens of the same file, OPEN_DOWNGRADE, and regular file creation
|
||||
through the unchecked, guarded and exclusive forms, where an exclusive create
|
||||
replays by its verifier.
|
||||
- **Ownership**: every object a client creates carries the identity the client
|
||||
presented, and the server answers the owner and owner group of every object,
|
||||
so ownership reads correctly on any conformant client.
|
||||
- **Byte range locking**: LOCK, LOCKT and LOCKU with per owner conflict
|
||||
detection, range splitting on unlock, and RELEASE_LOCKOWNER.
|
||||
- **Lease and recovery**: lease renewal on every SEQUENCE, DESTROY_CLIENTID,
|
||||
RECLAIM_COMPLETE inside the grace window, CLAIM_PREVIOUS reclamation, and
|
||||
persistent file handle maps that survive a server restart.
|
||||
- **Delegations**: read and write delegations granted on the only open of a
|
||||
file, recalled over the back channel on a conflicting open, returned through
|
||||
DELEGRETURN.
|
||||
- **Directory delegations**: GET_DIR_DELEGATION with CB_NOTIFY on create,
|
||||
rename and remove, and CB_NOTIFY_LOCK when a released range frees a denied
|
||||
lock.
|
||||
- **Back channel**: CB_COMPOUND over the same TCP connection, CB_SEQUENCE,
|
||||
CB_RECALL, and callback delivery that the client demultiplexes from replies.
|
||||
- **Optional operations of RFC 7862**: SEEK, ALLOCATE, DEALLOCATE, IO_ADVISE,
|
||||
READ_PLUS, WRITE_SAME, COPY, CLONE, COPY_NOTIFY, OFFLOAD_CANCEL,
|
||||
OFFLOAD_STATUS, LAYOUTERROR and LAYOUTSTATS.
|
||||
- **Extended attributes**: GETXATTR, SETXATTR, LISTXATTR and REMOVEXATTR of
|
||||
RFC 8276 over the user namespace of the local backend.
|
||||
- **Named attributes**: OPENATTR with create, lookup, read, write and remove
|
||||
over the synthetic attribute directory of an object.
|
||||
- **pNFS**: the metadata server role with LAYOUTGET, LAYOUTCOMMIT,
|
||||
LAYOUTRETURN, GETDEVICEINFO and GETDEVICELIST, and layout bodies for
|
||||
flexfiles (RFC 8435), files, block volumes, objects and SCSI, all over one
|
||||
emulated device that is the metadata server itself. The flexfiles version 2
|
||||
body of draft-haynes-nfsv4-flex-filesv2-00 (layout type 0x6) is served the
|
||||
same way.
|
||||
- **Migration and referrals**: the fs_locations and fs_locations_info
|
||||
attributes, referral stubs whose other operations answer NFS4ERR_MOVED.
|
||||
- **Kerberos**: RPCSEC_GSS with the krb5, krb5i and krb5p service levels, the
|
||||
AES profiles of RFC 3961 and RFC 3962 and the tokens of RFC 4121 implemented
|
||||
in pure Go, plus the version three credential of RFC 7861 with CREATE, LIST
|
||||
and assertion binding.
|
||||
- **RPC-with-TLS**: the AUTH_TLS probe and in place TLS upgrade of RFC 9289.
|
||||
- **RPC-over-RDMA framing**: the chunk lists and message assembly of RFC 8166
|
||||
over a stream transport; the verbs transport itself sits outside pure Go.
|
||||
- **The nfsd command**: the `-export` directory and the `-addr` listen
|
||||
address, a TOML configuration file through `-config` carrying the listen
|
||||
address, the operation log, the state directory, the connection cap, the
|
||||
TLS key pair and one `[[export]]`, with the flags overriding the file and a
|
||||
broken file ending the start up with the file and the line named; a read
|
||||
only export with `-ro`; RPC-with-TLS through `-tls-cert` and `-tls-key`,
|
||||
where a client that skips STARTTLS is refused with auth too weak for every
|
||||
procedure but the NULL of the probe; the operation log of `-log-ops`; the
|
||||
connection cap of `-max-connections`; persistent recovery state through
|
||||
`-state-dir`, where file handles and opens are written as they change, a
|
||||
restart loads them back and the grace window lets clients reclaim their
|
||||
opens with CLAIM_PREVIOUS; root squash with `-root-squash` or `root-squash`
|
||||
in the export, mapping a client claiming uid 0 onto nobody (65534);
|
||||
`READY=1` on $NOTIFY_SOCKET once the listener is up, so a `Type=notify`
|
||||
unit starts on real readiness; version reporting; and a clean shutdown on
|
||||
SIGINT and SIGTERM.
|
||||
- **The nfs command**: ls, cat, put, get, rm, mkdir and stat against a running
|
||||
server; the whole operation matrix as `nfs selftest`, one line per check
|
||||
plus a summary and a nonzero exit when a check fails; transfers spread over
|
||||
several session slots with `-concurrency`, measured on loopback at a 64 MiB
|
||||
put dropping from 77 ms sequential to 32 ms at four; a session owner id
|
||||
unique to the process, so two clients of the command beside each other are
|
||||
two clients, not one rebooting; and the version report.
|
||||
- **Kernel interop**: the server is verified end to end against the Linux
|
||||
kernel NFSv4.2 client, which mounts the tree over `mount -t nfs4` and reads,
|
||||
writes, creates and removes through it, with correct ownership, as root and
|
||||
non root callers alike.
|
||||
- **Interoperability stance**: strict conformance as the rule, a documented
|
||||
tolerance layer confined to the deviations of real clients, and the server
|
||||
and client pair as the strict reference of the stack.
|
||||
- **Performance**: the server answers a COMPOUND from one buffer instead of
|
||||
copying every operation result twice, READ fills the reply in place, WRITE
|
||||
hands the request's own bytes to the storage and the wire buffers recycle;
|
||||
the local backend keeps open descriptors of regular files in a bounded
|
||||
cache and revalidates the file identity on every use; READDIR pages cost
|
||||
the page against a cached sorted order of the directory; COPY and CLONE run
|
||||
through copy_file_range and the reflink of the filesystem with a fallback
|
||||
to the userspace copy; the session store locks per session instead of one
|
||||
server wide mutex and the lease check runs lock free against an atomic
|
||||
renewal stamp, six clients beside each other measured at 4.8 times the
|
||||
sequential throughput. Measured numbers: 11 percent faster reads, 19
|
||||
percent fewer allocations per COMPOUND, 27 percent fewer bytes per read,
|
||||
16.9 percent faster reads and 11.0 percent faster writes of 64 KiB chunks,
|
||||
and a READDIR page of 64 entries in a 10 000 entry directory measured 30
|
||||
times faster; the reports live in docs/_results/.
|
||||
- **Operations**: docs/DEPLOYMENT.md carries the production picture, the
|
||||
hardened systemd unit with Type=notify and the two capability model, the
|
||||
firewall note and the upgrade and monitoring story; docs/CONFIGURATION.md
|
||||
lists every configuration key; docs/BENCHMARKING.md states the measurement
|
||||
method.
|
||||
- **Platforms**: Linux on amd64, arm64, loong64 and riscv64; FreeBSD, OpenBSD
|
||||
and NetBSD on amd64 and arm64, all three verified live on amd64, OpenBSD
|
||||
and NetBSD with both ends of the project running inside the system and
|
||||
across to the Linux server because their kernel clients speak only NFSv3;
|
||||
darwin on arm64 as a cross compiled build without runtime testing. Extended
|
||||
attributes and the sparse operations answer not supported on OpenBSD,
|
||||
NetBSD and darwin, whose local backends have no system interface an
|
||||
arbitrary attribute name could use. The stack is pure Go end to end, and
|
||||
the module ships the two commands only: there is no importable package and
|
||||
no library surface.
|
||||
Reference in New Issue
Block a user