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:
+177
@@ -0,0 +1,177 @@
|
||||
.TH NFSD 1 2026-09-21 nfs "User Commands"
|
||||
.SH NAME
|
||||
nfsd \- serve a local directory tree over NFSv4.2
|
||||
.SH SYNOPSIS
|
||||
.B nfsd
|
||||
.RB [ \-addr
|
||||
.IR addr ]
|
||||
.RB [ \-export
|
||||
.IR dir ]
|
||||
.RB [ \-ro ]
|
||||
.RB [ \-tls-cert
|
||||
.IR file ]
|
||||
.RB [ \-tls-key
|
||||
.IR file ]
|
||||
.RB [ \-log-ops ]
|
||||
.RB [ \-max-connections
|
||||
.IR n ]
|
||||
.RB [ \-state-dir
|
||||
.IR dir ]
|
||||
.RB [ \-config
|
||||
.IR file ]
|
||||
.RB [ \-version ]
|
||||
.SH DESCRIPTION
|
||||
.B nfsd
|
||||
exports one local directory tree over NFSv4.2 on a single TCP port, as
|
||||
RFC 8881 and RFC 7862 describe and RFC 8276, RFC 7861 and RFC 9289
|
||||
extend. NFSv4 carries everything on the one port: there is no
|
||||
portmapper, no mountd and no separate locking protocol.
|
||||
.PP
|
||||
The tree is served read and write. Every request is evaluated against
|
||||
the identity the client presents, so the permission bits of the served
|
||||
files decide what each caller may do, and the objects a client creates
|
||||
carry the identity it presented. The server keeps its open, lock and
|
||||
delegation state across the connections of a client and drops it when
|
||||
the client reboots or its lease lapses.
|
||||
.PP
|
||||
On
|
||||
.B SIGINT
|
||||
or
|
||||
.B SIGTERM
|
||||
the listener closes and the process exits cleanly; clients recover
|
||||
through their session replay caches, so a stopped server costs no
|
||||
state.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI \-addr " addr"
|
||||
The TCP address to listen on. Defaults to
|
||||
.IR :2049 .
|
||||
.TP
|
||||
.BI \-export " dir"
|
||||
The directory to serve, relative or absolute. The directory must exist;
|
||||
a missing or non directory path ends the start up. Required: without it
|
||||
the server prints a reminder and exits.
|
||||
.TP
|
||||
.B \-ro
|
||||
Serve the export read only. Every operation that would change the tree
|
||||
answers NFS4ERR_ROFS; the reads of every half, the attributes, the
|
||||
extended attributes and the hole seeking included, work unchanged.
|
||||
.TP
|
||||
.B \-root-squash
|
||||
Map a client claiming uid 0 onto nobody: the credential acts as uid
|
||||
65534 with group 65534, the superuser grant is gone, and the objects
|
||||
root creates carry nobody. The default keeps the trust AUTH_SYS hands
|
||||
to the claim; an operator serving untrusted clients turns this on.
|
||||
.TP
|
||||
.BI \-tls-cert " file"
|
||||
The certificate chain in PEM that enables RPC-with-TLS of RFC 9289.
|
||||
A client probes with AUTH_TLS, the connection upgrades in place, and a
|
||||
client that skips the upgrade is refused with auth too weak for every
|
||||
procedure but the NULL of the probe. Goes together with
|
||||
.BR \-tls-key ;
|
||||
either alone ends the start up.
|
||||
.TP
|
||||
.BI \-tls-key " file"
|
||||
The private key in PEM for RPC-with-TLS, matching
|
||||
.BR \-tls-cert .
|
||||
.TP
|
||||
.B \-log-ops
|
||||
Log one line per operation to standard error: the operation, the status
|
||||
it answered and the time it took, as
|
||||
.BR "nfs: LOOKUP status 0 84\es" .
|
||||
Off by default: a quiet server answers nothing on the log.
|
||||
.HP
|
||||
.B \-config
|
||||
.I file
|
||||
The configuration file in TOML, described under
|
||||
.B CONFIGURATION
|
||||
below. Never read unless the flag names it; the flags override the
|
||||
file. A file that fails the read, the schema or the validation ends
|
||||
the start up with the file and the line named.
|
||||
.TP
|
||||
.BI \-max-connections " n"
|
||||
The cap on connections served at once. A connection offered above the
|
||||
cap closes at once and the client sees an immediate end of file; the
|
||||
server answers nothing on it. Zero, the default, means no cap.
|
||||
.TP
|
||||
.BI \-state-dir " dir"
|
||||
The directory for the persisted client state. The file handle map and
|
||||
the open state are written there as they change, a restart loads them
|
||||
back, and the grace window after a start lets a client reclaim its
|
||||
opens with CLAIM_PREVIOUS. The directory is created with owner only
|
||||
permissions when it is missing. Without the flag nothing persists and
|
||||
a restart starts from an empty state, as before.
|
||||
.TP
|
||||
.B \-version
|
||||
Print the version and exit. A build made at a tag reports the tag, a
|
||||
build outside version control reports
|
||||
.IR devel .
|
||||
.SH CONFIGURATION
|
||||
The server reads a TOML configuration file when
|
||||
.B \-config
|
||||
names one, and never otherwise. The file carries
|
||||
.BR listen ,
|
||||
.BR log-ops ,
|
||||
.BR state-dir ,
|
||||
.BR max-connections ,
|
||||
a
|
||||
.B [tls]
|
||||
table with
|
||||
.B cert
|
||||
and
|
||||
.BR key ,
|
||||
and one
|
||||
.B [[export]]
|
||||
table with
|
||||
.BR path ,
|
||||
.B read-only
|
||||
and
|
||||
.BR root-squash .
|
||||
The flags override the file; every key, type, default and effect is
|
||||
described in docs/CONFIGURATION.md of the repository. A file that
|
||||
breaks the schema or the syntax ends the start up with the file and
|
||||
the line of the fault.
|
||||
.SH EXIT STATUS
|
||||
.TP
|
||||
.B 0
|
||||
The version was printed, or the server shut down cleanly on
|
||||
.B SIGINT
|
||||
or
|
||||
.BR SIGTERM .
|
||||
.TP
|
||||
.B 1
|
||||
The start up or the service failed: no export was given, the export
|
||||
path is missing or is not a directory, the listen address could not be
|
||||
bound, or the listener failed.
|
||||
.SH EXAMPLES
|
||||
Serve
|
||||
.I /srv/demo
|
||||
on the default port:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
nfsd \-export /srv/demo
|
||||
.RE
|
||||
.PP
|
||||
Serve on a loopback address and print the version first:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
nfsd \-version
|
||||
nfsd \-export /srv/demo \-addr 127.0.0.1:2049
|
||||
.RE
|
||||
.PP
|
||||
Read the tree with
|
||||
.BR nfs (1):
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
nfs \-addr 127.0.0.1:2049 ls
|
||||
.RE
|
||||
.SH AUTHOR
|
||||
Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
.SH LICENCE
|
||||
MIT. See the LICENSE file in the repository.
|
||||
.SH SEE ALSO
|
||||
.BR nfs (1),
|
||||
https://sourcedock.dev/petrbalvin/nfs
|
||||
Reference in New Issue
Block a user