Files
erofs-freebsd-out-tree/tests/results/manual/2026-08-09T1343Z-g8/manual-test-report.md
T
2026-08-13 10:44:59 +02:00

12 KiB

repo22 G8 Documentation, NFS, and Integrity Manual Regression

Date: 2026-08-09 13:07-13:56 UTC

Executor: G8 manual agent

Source baseline: f11fff5b8e8050e1017ed86f0bcf71042b2b45aa

Exact scope: TC111, TC131-TC133, TC154-TC156 (7 IDs)

Result

All seven requested test cases passed. There are no KFAIL, SHELVED, or ENV results, no duplicate IDs, and no omitted IDs.

Status Count
PASS 7
KFAIL 0
SHELVED 0
ENV 0
Duplicate 0
Omitted 0
Test ID Status Manual evidence
TC111 PASS Audited current source and documentation against real generic /sbin/mount; corrected helper and writable-request claims.
TC131 PASS Real mountd/nfsd NFSv3 export, four vnode types, read-only behavior, 16-byte handle resolution, and RPC statistics.
TC132 PASS Handle ABI/classes, stable remount, replacement ESTALE, metabox and external-provider regressions, and nfsd restart.
TC133 PASS Exact 12,050-name READDIRPLUS lists, five cold remounts, 20 individually waited workers, and zero RPC errors.
TC154 PASS Same-superblock/UUID/NID replacement changed per-inode generation; unchanged remount stayed stable.
TC155 PASS Explicit-extent physical-address wrap returned EINTEGRITY on both direct reads and in truss.
TC156 PASS Compact/extended epoch, time_t, and nanosecond boundary corruptions returned EINTEGRITY.

No kernel source changed. No kernel failure remained, so no issue file was created.

Isolated Environment

  • Worktree: /work/build/repo22-manual-g8-20260809T130723Z, branch manual-g8-20260809T130723Z, created directly from the source baseline.
  • VM: independent qcow2 overlay backed by the clean FreeBSD development base; QEMU TCG, 6144 MB, 4 vCPUs, SSH only on 127.0.0.1:9228.
  • Guest: FreeBSD 15.0-RELEASE-p8 amd64, releng/15.0-n281036-53054229dcb3, OSREL 1500068.
  • Guest kernel SHA256: b9abf7b58f9dd4d87f14d2fbc306cf255e6eadc47b8ae885a230f65e28be4562.
  • Host erofs-utils: 1.8.6.
  • No CI, runner, or test wrapper was used. Markdown procedures were issued manually through SSH, with direct command status kept separate from tracing tool status.

Exact Build

The repo22 source archive came from the exact baseline commit. The matching tracked FreeBSD build input was dev-freebsd-releng/sys, identified by REVISION="15.0" and BRANCH="RELEASE-p9". The build ran natively in the guest as:

FREEBSD_SRC=/root/freebsd-src WITH_ZSTDIO=1 ./build.sh

The compile command contained -DZSTDIO and kernel -Werror. The module had the five expected ZSTD_* kernel references and no unresolved bcmp.

Object SHA256
repo22 source archive 2f76ef7df9117c6e7d62ad41809638ad306e676191346083bf95fe551f7df515
FreeBSD 15 sys archive cd806ac4d6aee5d7ceb6a2f9603020b48b5012835bc8c7f2ec0985572fcd0262
erofs.ko e8cd4839328de089355505efb1629c835d2f93faad2e14f63c6e6cb844ce9589
nfs_fh_tool db704f67d718d04b84ed32b5cdbecb93a99c5fe3b4ab238d603a10e005d790e3

The guest kernel is p8 and the tracked source is p9, but both use the FreeBSD 15.0 OSREL ABI. The exact module loaded and unloaded successfully.

Fixture Qualification

tests/review_fixtures.py generated two independent output directories. Their manifests and checksum inventories were byte-identical, and all nine image checksums self-verified. Its structured assertions recorded:

  • target NID 452 at inode offset 14464 after checksum block 4096;
  • identical complete superblock block and UUID for NFS images A and B;
  • generations 3895653226 -> 548470773 from the changed raw inode;
  • explicit extent base 0xfffffffffffff000, plen0=8192, plen1=4096, and wrap before logical cluster 4096;
  • compact epoch wrap/range, compact nanoseconds 1000000000, extended nanoseconds 1000000000, and extended seconds INT64_MAX+1.

Review generator SHA256 was b92fd6b6122d55882998138efc0109e24b236f9e877405dbff7914284a18c124; manifest SHA256 was be0836043d172b34eb625e5259f7e6cb9a8992ff74e7d1a5cdc10d69282e2335.

The NFS stress image was generated from a fresh deterministic tree containing 12,050 bigdir files, 256 concurrent-read files, four basic vnode types, and a 22,020,096-byte throughput file. Image A SHA256 was 88721877dc3762c8eafdf3bcca2653787cdcf41983978ab159705761abefac37; image B was 964b3d75579740c9b08bc9cae8329e3d641d3c505e9391de3ab9f5d24fbecd17. The expected sorted-name list SHA256 was 4fbf1b6103e8884223629c3fd03f4ec36061e65cd2a1becfc96670daa96f9d71.

Fresh structured metabox and multidevice helpers also self-verified the two TC132 regression inputs. The metabox image SHA256 was dd7b04097d1bfe283b65c95d759acd2176beb7cb0f1fe9d5ddbc0694b5acba9d; the multidevice primary/slot hashes were 918aa3a64e8861011914d967912909ce9de98418cff711cfbf8f91c0c7717f72, 4e31d95a12405f2f1396fb926a6854c591fc335eade8944f73fdc7fe6758aee6, and 355a74880bd3648dea22ad18e19f809cee12303ceed2a99f53094c2b66563a11.

TC111

/sbin/mount_erofs was absent and command -v mount_erofs returned 127. Generic /sbin/mount -t erofs mounted the image successfully without -o ro. The following real behavior was recorded:

  • the default mount was read-only and touch failed with EROFS;
  • -o rw returned 0 but the resulting mount was still read-only;
  • -o ro,noexec,nosuid returned 0 and all three flags appeared;
  • non-export mount -u returned EOPNOTSUPP;
  • an unknown filesystem option returned direct rc 1, with nmount(..., MNT_RDONLY) ERR#22, and created no mount.

Current src, README.md, docs/features.md, docs/architecture.md, docs/erofs.5, and current progress material were checked. README.md, docs/erofs.5, and the test procedure now describe the generic frontend and the forced-read-only rw behavior accurately. The man page's split-device example was also exercised by the TC132 multidevice mount. SEE ALSO entries absent from the qualified guest were removed; mandoc -Tlint -Werror and ASCII rendering both returned 0 in that guest.

TC131

The direct EROFS line lacked NFS exported before mountd. After installing the loopback export and reloading mountd, showmount -e listed the exact path and the direct mount gained NFS exported. rpcinfo showed NFSv3 and mountd over TCP and UDP.

The NFSv3 TCP client negotiated rdirplus. Regular file content, directory, symlink target, FIFO type, and inode number matched the direct EROFS mount. touch failed with Read-only file system. Local fhstat and fhopen resolved the regular handle with len=16, pad=0, NID 116, and generation 2068234290.

After basic operations client READDIRPLUS was 2. Server Write and Create were both 0. TimedOut, Invalid, X Replies, and Retries were all 0.

TC132

Regular, directory, symlink, and FIFO handles all had len=16, pad=0, full 64-bit NIDs, and nonzero generations matching st_gen. Bad length/pad returned EINVAL; bad generation/NID returned ESTALE through both fhstat and fhopen.

The unchanged image remounted on md80 preserved the complete handle SHA256 9e1df1952b43d383fea295301525ede7a69b7d57e5f60a75a6d7f1531e13df0a, and the old handle still read the file. Replacement B retained fsid and NID 116 but changed generation 2068234290 -> 857800581; both old-handle paths returned ESTALE while B resolved.

The metabox handle preserved NID 0x8000000000000010; invalid metabox NID and generation returned ESTALE. After forced orphaning of external slot 2, the valid file handle still resolved metadata and the read returned ENXIO(6), not ESTALE.

An NFS client descriptor remained open across service nfsd onerestart 3<&-. The old descriptor and a new path read both returned SHA256 3e2d0b4971e1f4bf00c3562a8bf9c5d85378c9de054f3da89541f49f2b449a7b; the export and all RPC registrations remained live.

TC133

Requested readdir sizes 512, 1024, and 4096 were all clamped by the FreeBSD client to 8192; the default remained 65536. This is the recorded client floor.

Every one of the four mounts returned exactly 12,050 unique expected names. Every sorted list, plus all five cold-remount lists, had SHA256 4fbf1b6103e8884223629c3fd03f4ec36061e65cd2a1becfc96670daa96f9d71. The ls -a1 list contained 12,052 entries, with . and .. exactly once.

All 12 traversal workers were waited by PID and returned 0. All four parallel cat workers and four parallel stat workers were also waited by PID and returned 0. The informational 22,020,096-byte read completed in 14.51 seconds.

Final client/server READDIRPLUS was 3420. TimedOut, Invalid, X Replies, and Retries remained 0. Server Write, WriteRPC, Create, and Commit remained 0. There were no new stale-handle, timeout, retry, panic, trap, assertion, watchdog, or EROFS error lines.

TC154

Image A produced fsid 00000034:000000e0, len=16, pad=0, NID 452, and generation 3895653226. nfs_fh_tool, stat st_gen, and the fixture manifest agreed. The unchanged remount preserved complete handle SHA256 79f2f4b8e354af0ae369849d7f66a739162ffadc4a5689c09643c9949b548de1 and the old handle remained readable.

Image B retained the complete superblock block, UUID, fsid, NID, and content, but generation became 548470773. Both old-handle paths returned ESTALE; B's handle resolved. The malformed same-NID replacement returned positive errno 45 through both paths.

TC155

The self-checked fixture SHA256 was 1e49ecf1917265fde9b606e80f7dbae8b14aca8c6f149128b31d6c825da546dd. The image mounted and target stat reported inode 40, size 1,048,576. Two direct one-byte reads at logical offset 4096 returned rc 1 and Integrity check failed; the traced read was ERR#97. The repeat exercised the cached vnode. A DTrace io:::start positive control observed one raw md90 offset=4096 bytes=4096 event. A separate trace around the failing EROFS read observed zero md90 events, proving the wrapped address did not reach the provider. No panic or resource remained.

TC156

Both compact root corruptions failed nmount with ERR#97. The compact range image mounted with root mtime INT64_MAX; target stat returned ERR#97 for INT64_MAX+1. Both extended images mounted, and target stat returned ERR#97 for nanoseconds 1000000000 and seconds INT64_MAX+1. Every failure was run directly and again under truss; no panic or resource remained.

Cleanup and Restoration

Before NFS setup, /etc/exports did not exist; rpcbind, mountd, and nfsd were stopped; and rpcbind_enable, mountd_enable, and nfs_server_enable were all NO. Cleanup unmounted every loopback client while nfsd was alive, cleared and reloaded exports, stopped nfsd/mountd/rpcbind, then removed the direct EROFS mount, md42, and the module.

Final state exactly matched the baseline: /etc/exports absent, all three services stopped with rc 1, all three rc settings NO, zero NFS/EROFS mounts, zero md providers, no EROFS KLD, no service process, and rpcinfo refused the connection because rpcbind was stopped. The complete NFS-period dmesg delta had zero anomaly lines.

The retained guest evidence archive is outside the repository at /work/build/repo22-manual-g8-20260809T130723Z-vm/evidence/:

Artifact SHA256
final-guest-evidence.txt eb67210818e663c15e4670ada9ba63b82b44e9ed3a9486c575df3a71ed3f0522
TC155-dtrace-assert.txt f8b52985a74c8c777b3b830c39749be65c613165ffbcde6d0018dc471018c433
final-post-dtrace-cleanup.txt 90f04d8f5a4ae35c87cc3adb1aeb939c7cc5534233ed63e9ff4501c83fd857d2
repo22-g8-evidence.tar.gz 9a378fd619f9bca21f40689d746308933aa22e440f7201104732f91634c21290

Non-Qualified Attempts

One TC131 setup command stopped at the expected nonzero service-status probe because that probe was mistakenly under set -e; it occurred before module, exports, or service changes. One TC133 attempt stopped after the four exact lists because a shell-quoted dot assertion matched zero; the three added clients were unmounted and the complete procedure was rerun from the start. Tracing wrappers returned 0 even when their child failed, so all error claims use separate direct statuses plus syscall errno. None of these discarded attempts is counted as PASS evidence.

Two initial DTrace specifications used field names from other provider ABIs and failed at compile time before any probe I/O. The qualified specification used FreeBSD struct devstat and struct bio fields. Its first assertion used a line anchor even though the format emitted a literal \\n; substring counts then proved one positive md90 event and zero failing-read md90 events. DTrace's automatically loaded module set was unloaded as a unit and the original KLD set was reverified.

Issues

None.