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:
@@ -0,0 +1,173 @@
|
||||
.TH NFS 1 2026-09-21 nfs "User Commands"
|
||||
.SH NAME
|
||||
nfs \- speak to an NFSv4.2 server from the command line
|
||||
.SH SYNOPSIS
|
||||
.B nfs
|
||||
.RB [ \-addr
|
||||
.IR host:port ]
|
||||
.RB [ \-concurrency
|
||||
.IR n ]
|
||||
.B version
|
||||
|
|
||||
.B ls
|
||||
.RI [ path ]
|
||||
|
|
||||
.B cat
|
||||
.I path
|
||||
|
|
||||
.B put
|
||||
.I local remote
|
||||
|
|
||||
.B get
|
||||
.I remote local
|
||||
|
|
||||
.B rm
|
||||
.I path
|
||||
|
|
||||
.B mkdir
|
||||
.I path
|
||||
|
|
||||
.B stat
|
||||
.I path
|
||||
|
|
||||
.B selftest
|
||||
.SH DESCRIPTION
|
||||
.B nfs
|
||||
runs one operation against an NFSv4.2 server over TCP, as RFC 8881 and
|
||||
RFC 7862 describe. It dials the address, establishes a session and
|
||||
speaks the operation through the internal nfsclient package, which
|
||||
carries the full protocol surface of the project. The client works
|
||||
against any NFSv4.2 server, the
|
||||
.BR nfsd (1)
|
||||
of this project included.
|
||||
.PP
|
||||
Paths address the server's NFS namespace from its root, with the
|
||||
leading slash optional: a lookup walks one component at a time, so a
|
||||
name that carries a slash is a path, never an escaped component.
|
||||
.SH COMMANDS
|
||||
.TP
|
||||
.B version
|
||||
Print the version and exit. A build made at a tag reports the tag, a
|
||||
build outside version control reports a development label.
|
||||
.TP
|
||||
.BI ls " [path]"
|
||||
List the directory
|
||||
.IR path ,
|
||||
the root by default. One line per entry: the name, the size and the
|
||||
mode in octal, separated by tabs.
|
||||
.TP
|
||||
.BI cat " path"
|
||||
Stream the file
|
||||
.I path
|
||||
to standard output, reading in megabyte chunks until the server
|
||||
reports the end of file.
|
||||
.TP
|
||||
.BI put " local remote"
|
||||
Write the local file
|
||||
.I local
|
||||
to
|
||||
.I remote
|
||||
on the server. The remote file is created if it is missing, with mode
|
||||
0644, and truncated before the first write, so a shorter file leaves
|
||||
no tail behind. On success one line reports how many bytes landed.
|
||||
.TP
|
||||
.BI get " remote local"
|
||||
Copy the remote file
|
||||
.I remote
|
||||
into the local file
|
||||
.IR local ,
|
||||
reading in megabyte chunks until the server reports the end of file.
|
||||
The local file is truncated first, so a shorter remote leaves no tail
|
||||
behind. On success one line reports how many bytes landed.
|
||||
.TP
|
||||
.BI rm " path"
|
||||
Remove the object
|
||||
.I path
|
||||
from the server. Removing a directory that still holds entries is
|
||||
refused by the server.
|
||||
.TP
|
||||
.BI mkdir " path"
|
||||
Make the directory
|
||||
.I path
|
||||
on the server. The parent directory must exist; the walk to it follows
|
||||
one component at a time.
|
||||
.TP
|
||||
.BI stat " path"
|
||||
Print the attributes of
|
||||
.IR path :
|
||||
the type, the size, the mode in octal and the modification time, one
|
||||
per line.
|
||||
.TP
|
||||
.B selftest
|
||||
Run the whole operation matrix against the server the session points
|
||||
at: the work directory, an empty file, a 64 KiB write and its byte for
|
||||
byte comparison, the listing, a rename, a symlink and its target, a
|
||||
nested directory, the ownership of a file created as another uid, a
|
||||
mode change, and the removals. One line per check and a summary at the
|
||||
end; the exit status reports whether every check passed. The work
|
||||
directory is removed on success and left in place on failure, so a
|
||||
failing server can be examined.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI \-addr " host:port"
|
||||
The server address. Defaults to
|
||||
.IR 127.0.0.1:2049 .
|
||||
.TP
|
||||
.BI \-concurrency " n"
|
||||
How many compounds of
|
||||
.B get
|
||||
and
|
||||
.B put
|
||||
run in flight at once, one to eight, each on its own session slot of
|
||||
the one connection. The default of one keeps the transfers sequential.
|
||||
.SH EXIT STATUS
|
||||
.TP
|
||||
.B 0
|
||||
The operation completed.
|
||||
.TP
|
||||
.B 1
|
||||
The operation failed: the dial, the session or the operation itself
|
||||
returned an error, or the local file of
|
||||
.B put
|
||||
could not be read.
|
||||
.TP
|
||||
.B 2
|
||||
The arguments were wrong: no subcommand, an unknown subcommand, or a
|
||||
subcommand missing its required argument.
|
||||
.SH EXAMPLES
|
||||
List the root of a server on the default port and read a file from it:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
nfs ls
|
||||
nfs cat /hello.txt
|
||||
.RE
|
||||
.PP
|
||||
Copy a local file to the server and check it landed:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
nfs put README.md /readme.md
|
||||
nfs stat /readme.md
|
||||
.RE
|
||||
.PP
|
||||
Check a server speaks the whole matrix the client exercises:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
nfs \-addr 127.0.0.1:2049 selftest
|
||||
.RE
|
||||
.PP
|
||||
Speak to a server on another host:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
nfs \-addr 192.0.2.10:2049 ls /srv
|
||||
.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 nfsd (1),
|
||||
https://sourcedock.dev/petrbalvin/nfs
|
||||
Reference in New Issue
Block a user