update
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
# 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:
|
||||
|
||||
```sh
|
||||
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.
|
||||
Reference in New Issue
Block a user