144 lines
4.3 KiB
Markdown
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.
|