Files
erofs-freebsd-out-tree/tests/TC131-nfs-export-basic.md
T
2026-08-13 10:44:59 +02:00

144 lines
4.3 KiB
Markdown

# Test Case: FreeBSD NFSv3 Export Basic Functionality
**Test ID**: TC131-nfs-export-basic
**Category**: NFS Export
**Priority**: Critical
**Regression**: EROFS `VOP_VPTOFH` / `VFS_FHTOVP` / export updates
## Objective
Verify that FreeBSD 15 mountd can install an export on a read-only EROFS
mount, that nfsd can resolve EROFS file handles, and that regular files,
directories, symlinks, and FIFOs are visible through a real NFSv3 client.
## Preconditions
- FreeBSD 15 amd64 server/client, optionally the same host over loopback.
- Root privilege for module, md, NFS service, `getfh`, and `fhopen` operations.
- `erofs.ko`, `test-nfs.erofs`, and `tests/nfs_fh_tool.c` available in the
guest.
- The fixture contains `basic/regular.txt`, `basic/subdir`,
`basic/link-to-regular`, and `basic/test.fifo`.
## Procedure
1. Build the module and helper:
```sh
./build.sh
cc -O2 -Wall -Wextra -std=c17 tests/nfs_fh_tool.c -o nfs_fh_tool
```
2. Load and mount EROFS on a fixed md unit:
```sh
kldload ./erofs.ko
mdconfig -a -t vnode -f test-nfs.erofs -u 42
mkdir -p /mnt/repo22-erofs
mount -t erofs -o ro /dev/md42 /mnt/repo22-erofs
mount -v | grep /mnt/repo22-erofs
```
The line must show `read-only` and must not show `NFS exported` before
mountd processes `/etc/exports`.
3. Configure the real FreeBSD mountd/nfsd flow:
```sh
cp -p /etc/exports /tmp/exports.before 2>/dev/null || true
printf '%s\n' \
'/mnt/repo22-erofs -ro -maproot=root -network 127.0.0.0 -mask 255.0.0.0' \
> /etc/exports
service rpcbind onestart
service mountd onestart
service nfsd onestart
service mountd onereload
rpcinfo -p 127.0.0.1
showmount -e 127.0.0.1
mount -v | grep /mnt/repo22-erofs
```
After reload, the EROFS mount line must show `NFS exported`. The flag is
installed by the generic FreeBSD export layer after the filesystem accepts
the export-only `MNT_UPDATE`; EROFS must not set it during the initial mount.
4. Mount the export through NFSv3 and confirm the negotiated options:
```sh
mkdir -p /mnt/repo22-nfs
mount_nfs -o nfsv3,tcp,rdirplus 127.0.0.1:/mnt/repo22-erofs \
/mnt/repo22-nfs
nfsstat -m
```
5. Verify all required vnode types and read-only behavior:
```sh
cmp /mnt/repo22-nfs/basic/regular.txt \
/mnt/repo22-erofs/basic/regular.txt
test -d /mnt/repo22-nfs/basic/subdir
test "$(readlink /mnt/repo22-nfs/basic/link-to-regular)" = regular.txt
test -p /mnt/repo22-nfs/basic/test.fifo
test "$(stat -f %i /mnt/repo22-nfs/basic/regular.txt)" = \
"$(stat -f %i /mnt/repo22-erofs/basic/regular.txt)"
! touch /mnt/repo22-nfs/write-must-fail
```
6. Exercise both shared- and exclusive-lock file-handle resolution locally:
```sh
./nfs_fh_tool capture /mnt/repo22-erofs/basic/regular.txt regular.fh
./nfs_fh_tool stat regular.fh
./nfs_fh_tool cat regular.fh regular.out
cmp regular.out /mnt/repo22-erofs/basic/regular.txt
```
`fhstat` requests a shared lock and `fhopen` requests an exclusive lock.
7. Confirm that NFSv3 used READDIRPLUS and did not issue writes:
```sh
nfsstat -c
nfsstat -s
```
## Expected Results
- mountd accepts the EROFS export-only update.
- `showmount -e` lists the EROFS path and `mount -v` shows `NFS exported` only
after mountd reloads exports.
- NFSv3 regular reads, directory traversal, symlink lookup, FIFO metadata, and
inode numbers match the direct EROFS mount.
- Writes fail with `EROFS`/`Read-only file system`.
- `fhstat` and `fhopen` both resolve the same 64-bit EROFS NID.
- NFS statistics show READDIRPLUS traffic and zero successful write RPCs.
## Cleanup
Always remove clients before stopping the loopback server:
```sh
umount /mnt/repo22-nfs
: > /etc/exports
service mountd onereload
service nfsd onestop
service mountd onestop
service rpcbind onestop
umount /mnt/repo22-erofs
mdconfig -d -u 42
kldunload erofs
rm -f /etc/exports
```
Restore a pre-existing `/etc/exports` instead of removing it when applicable.
## Notes
- The EROFS FreeBSD file-handle payload is 16 bytes:
`len`, `pad`, `nid_hi`, `nid_lo`, and a nonzero superblock-seeded per-inode
generation matching `va_gen`.
- Do not use Linux `exportfs`; FreeBSD mountd installs exports through a mount
update carrying the `export` option.
- Throughput is recorded for information only; correctness has no fixed MB/s
threshold.