Files
erofs-freebsd-out-tree/docs/pre8-completion-and-validation.md
T
2026-08-13 10:44:59 +02:00

315 lines
16 KiB
Markdown

# Pre8 Completion and Validation
## Final Verdict
Pre8 overall status is **FAIL**.
The required implementation, static review, revert review, build matrix, basic
plain/LZ4 smoke, and selected test suite were all executed. The selected suite
did not pass its required gate. In particular, TC004 produced a definite DUT
failure while twelve other DUT verdicts were blocked by test-harness defects or
prior test residue. Under the status definition in `planning/pre8`, a required
action that ran and failed a gate is `FAIL`, not `PASS` or `PARTIAL`.
This overall verdict does not erase the narrower successful results:
| Validation layer | Verdict | Scope |
| --- | --- | --- |
| Source implementation | PASS | Planned loader placement and xattr iterator work is present in the final source tree. |
| Static source review | PASS | Allowlist, token-equivalence, references, xattr invariants, and protected paths passed review. |
| Revert and history review | PASS | Accepted replacement commits passed their defined direct-parent and final-HEAD checks; historical failures remain disclosed. |
| Four build configurations | PASS | `default`, `debug`, `zstdio0`, and `zstdio1` built and passed module load/unload smoke. |
| Basic plain/LZ4 smoke | PASS | Independent run `20260812T210345.913633Z-770842-a2868dd9`. |
| Selected 19-case suite | FAIL | Automation: 5 PASS / 9 FAIL / 4 ERROR / 1 NOT_RUN. Audited DUT: 6 PASS / 1 FAIL / 12 BLOCKED. |
| Pre8 overall | **FAIL** | A required selected-suite gate ran and failed. |
No claim is made that Pre8, repo22, the LZMA issue, or the test harness was
fixed by this validation work.
## Final DUT Identity
The final repository identity used by both selected-suite and basic-smoke
evidence is:
```text
parent repository commit: d1f5b686e8945d06b6e8c0a0188b2262de0b4ac2
parent repository tree: 19f450085cad49d06f6fe05d180313f13d4347f0
repo-pre-8 tree: 497736695fcc4285760b24c5954c34d32b8af49f
repo-pre-8/src tree: cbf93a19df8d1ce2fb66e2aeb7276a4ea6d4dcc2
```
Selected-suite DUT archive:
```text
bbcfd8a6a28faba3f7c5c7e827bde5578774be6e08b83d05485d58ee16a7fb6f
```
Basic-smoke DUT archive:
```text
402459ba6a6f55696d06474f7494a69ef1a5fe49063d565cacadece37e8b9ce1
```
The different archive hashes belong to different runners and archive
procedures. Both reports bind their run to the same final repository commit
and `repo-pre-8/src` tree.
## Source Delivery
### Accepted implementation
The final accepted source changes are:
1. `3d28d96fc48753231b1899fce6189e586cf988c6`
(`erofs: unify inline and shared xattr iteration`)
2. `aac1412056f9ae7269f7c0f85c0233ade8cc662a`
(`erofs: move codec config loaders atomically`)
The xattr commit introduces common private inline/shared iteration while
preserving the reviewed lookup order, list order, namespace and errno timing,
inline/shared validation differences, buffer ownership, and output accounting.
The atomic loader replacement moves the LZMA, DEFLATE, and ZSTD configuration
loaders to their backend files. The loader bodies remain token-equivalent to
the baseline, dispatch calls remain in the core, decode functions are not
changed, and no Linux page/folio or descriptor ABI was introduced.
### Superseded split-loader history
The following pushed commits remain in history and must not be described as
accepted independent delivery units:
| Commit | Historical final-HEAD inverse result | Final disposition |
| --- | --- | --- |
| `dd7f2483d468ec4397a863c7a871391ea1bc2c4c` | FAIL: conflict in `decompressor.c`; `internal.h` auto-merged as staged content | Superseded by `aac1412`; failure permanently retained. |
| `0dba0ea223bee8626b8cd3371562f87ed975a99f` | FAIL: conflict in `decompressor.c`; `internal.h` auto-merged as staged content | Superseded by `aac1412`; failure permanently retained. |
| `7c47f6d` | PASS | Superseded with the split-loader group by `aac1412`. |
All three split commits passed direct-parent restoration at the point where
they were introduced. That fact does not overwrite the two final-HEAD inverse
failures. The split group was reverted by `96f041f`, then replayed as the one
accepted atomic commit `aac1412`. Commit `3d28d96` was not superseded.
### Static and revert verdict
Final static and revert status is **PASS**:
- the implementation remained within the planned source allowlist;
- protected trees and unrelated paths were unchanged;
- all three moved loader bodies matched their baseline implementations;
- declaration, definition, and dispatch-call closure was correct;
- the ZSTD availability and `windowlog > 10` rejection order was preserved;
- codec decode bodies were unchanged;
- the xattr iterator behavior and ownership matrix passed independent review;
- `aac1412` restored its direct parent exactly when reverted;
- `aac1412` independently reverted from final HEAD without changing xattr;
- `3d28d96` independently reverted from final HEAD without changing the
accepted loader layout;
- final `repo-pre-8/src` matched the reviewed functional source tree;
- `git diff --check` and worktree cleanliness checks passed at static handoff.
The detailed history record is
`repo-pre-8/docs/pre8-loader-history-correction.md`.
## Build Validation
The selected-suite runner built four module configurations. Every
configuration passed build completion, SHA256 recording, unresolved-symbol
checks, and an actual `kldload`/`kldunload` smoke before case execution.
| Configuration | Verdict | SHA256 | Size |
| --- | --- | --- | --- |
| `default` | PASS | `348cb1f5a91d47e1412747d285c795c49375a61a66cfb3d35d22f38ecfde6ea0` | 47,272 bytes |
| `debug` | PASS | `274189804511d249b34fbb3c223e9525b07c7c6266ec39d016ad2f33185001c7` | **UNKNOWN**; the harness did not persist size evidence before VM destruction |
| `zstdio0` | PASS | `348cb1f5a91d47e1412747d285c795c49375a61a66cfb3d35d22f38ecfde6ea0` | 47,272 bytes; byte-identical to `default` |
| `zstdio1` | PASS | `6cdb8e01fdac7805cb7ae12a9d1804b00d3e5cf37ef8b2f583137d36ee70426e` | 51,368 bytes |
The missing debug size is not reconstructed or inferred. No KLD or other
binary was committed.
## Basic Plain/LZ4 Smoke
Independent basic smoke run:
```text
run ID: 20260812T210345.913633Z-770842-a2868dd9
automation: PASS
runner exit: 0
DUT result: PASS for plain and LZ4 basic differential scope
guest: FreeBSD 15.0-RELEASE-p8 amd64
KLD SHA256: 527fe80ad7307d0200cfc4fec84c6fb86b914e89889e4a42ff0613fc24465015
KLD size: 47,272 bytes
```
All twelve runner stages passed. The run created a deterministic corpus with
256 regular files, 9 symlinks, and 43 directories. Both the plain and LZ4
images mounted read-only, passed a 307-entry differential preflight, completed
all four workers, and unmounted cleanly. The test QEMU exited gracefully, its
overlay and large temporary data were removed, and ports 10000 and 10001 were
released.
This result covers only plain/LZ4 basic mount, traversal, read, differential,
unmount, and cleanup behavior. It does not override the selected-suite
failures or blocked verdicts.
Evidence:
- `/work/tests-dev/erofsstress/demo-result/repo-pre-8-smoke-20260812/20260812T210345.913633Z-770842-a2868dd9/audit-report.md`
- `/work/tests-dev/erofsstress/demo-result/repo-pre-8-smoke-20260812/20260812T210345.913633Z-770842-a2868dd9/result.json`
- tests-dev commit `374b8e3ab4b0df24d6761802b70c694e2896d5fd`
## Selected Suite
Primary run:
```text
run ID: pre8-required-20260812T194817Z
cases: 19
automation: 5 PASS / 9 FAIL / 4 ERROR / 1 NOT_RUN
runner exit: 3
duration: 1892.44 seconds
audited DUT: 6 PASS / 1 FAIL / 12 BLOCKED
```
The automation status is the runner's result. The DUT status is a separate
evidence audit. An automation failure caused by a harness defect is not changed
to automation PASS. Likewise, a positive command observed before a missing
negative check does not make the full DUT case PASS.
### Per-case matrix
| Case | Automation | DUT | Audited observation |
| --- | --- | --- | --- |
| TC005 | FAIL | BLOCKED | Inline listing and both requested user xattr values succeeded. The missing-xattr `ENOATTR` assertion was never invoked because the truss output directory did not exist. |
| TC013 | PASS | PASS | Invalid NID returned `EINTEGRITY` (`ERR#97`) twice; mount, unmount, and zero-state checks passed. |
| TC079 | PASS | PASS | Packed user and trusted prefix values matched expected data and cleanup passed. |
| TC080 | FAIL | BLOCKED | Four packed-prefix values were correct. The missing-suffix `ENOATTR` assertion was not invoked because the truss output directory was absent. |
| TC082 | FAIL | BLOCKED | ACL bytes and ordering were observed, but automation compared spaced hex against an unspaced prefix; the user-namespace negative assertion also was not invoked. |
| TC067 | FAIL | PASS | Both shared files, the local xattr, and listing matched the fixture. Automation incorrectly expected one additional trailing `!`. |
| TC068 | FAIL | BLOCKED | Shared listing succeeded. The nonexistent lookup was not invoked because truss could not create its output file. |
| TC069 | PASS | PASS | Three shared xattrs were listed and all exact values were read; cleanup passed. |
| TC081 | PASS | PASS | Metabox shared, shared-prefix, and packed-prefix xattrs were listed and read from both files; cleanup passed. |
| TC117 | FAIL | BLOCKED | Both corrupt fixtures mounted and valid local shared data remained readable. Corrupt-entry errno assertions were not invoked because truss failed first. |
| TC135 | PASS | PASS | Metabox, packed, and primary-prefix fallback values matched expected data. |
| TC138 | FAIL | BLOCKED | Valid unordered and empty-header ACLs were read. Three malformed ACL assertions were not invoked because the scratch directory was absent. |
| TC140 | FAIL | BLOCKED | Positive compressed and fragment metabox carrier hashes and xattrs passed. Four negative mount commands were not invoked because truss failed opening its trace. |
| TC142 | FAIL | BLOCKED | Positive fragment-backed compressed metabox hash and xattrs passed. Four negative mount commands were not invoked for the same reason. |
| TC004 | ERROR | **FAIL** | LZMA image mounted, but SHA256 of the mounted 8 MiB `level.dat` timed out after 30 seconds. The process remained running and left the mount and `md0` busy. |
| TC084 | ERROR; follow-up FAIL | BLOCKED | Primary run was contaminated by TC004 residue. Fresh follow-up mounted LZ4 and found the target, but guest `dump.erofs` was absent before content verification. |
| TC102 | ERROR; follow-up FAIL | BLOCKED | Primary run was contaminated by TC004 residue. Fresh follow-up mounted DEFLATE, but missing guest `dump.erofs` prevented algorithm and content verification. |
| TC105 | ERROR; follow-up FAIL | BLOCKED | Primary run was contaminated by TC004 residue. Fresh follow-up mounted ZSTD with `zstdio1`, but missing guest `dump.erofs` prevented verification. |
| TC145 | NOT_RUN; follow-up ERROR | BLOCKED | Both zstdio modules built and initial load smoke passed. The follow-up queried and unloaded module name `erofs` instead of the loaded artifact name, so functional mount/read gates were not reached. |
### Definite DUT failure
TC004 is a definite observed DUT failure for this test run:
1. `lzma-level6.erofs` attached as `md0`.
2. The read-only EROFS mount succeeded.
3. The mounted `level.dat` existed.
4. SHA256 of the source file completed and returned
`ddda39737f0f6093e828a032ec161511fefbb1fa361bc6cbffdbc91e48e4c461`.
5. SHA256 of the mounted 8 MiB file did not finish within 30 seconds.
6. The timed-out `sha256` process remained alive.
7. Unmount and `mdconfig -d` returned `Device busy`.
This evidence does **not** prove that Pre8 introduced the problem. No matching
Pre7 or pre-change comparison run with the same image, guest, module build,
and command is available. The issue is recorded separately in
`issues/pre8-lzma-read-timeout.md` without an attribution claim.
### Codec follow-up
Fresh follow-up run:
```text
run ID: pre8-codec-followup-20260812T202059Z
cases: TC084, TC102, TC105, TC145
automation: 3 FAIL / 1 ERROR
runner exit: 1
duration: 1136.92 seconds
audited DUT: 4 BLOCKED
```
The follow-up isolated these cases from TC004 residue, but it did not produce
codec functional PASS verdicts. TC084, TC102, and TC105 were blocked by absent
guest `dump.erofs`. TC145 was blocked by incorrect module-name lookup/unload
and cleanup behavior in the harness. These results remain FAIL/ERROR in
automation and BLOCKED for the DUT.
The harness findings are recorded in
`issues/pre8-test-harness-blockers.md`. No harness modification is part of
Pre8 source delivery.
Selected-suite evidence:
- `/work/tests-dev/demo-result/repo-pre-8-smoke-20260812/summary.md`
- `/work/tests-dev/demo-result/repo-pre-8-smoke-20260812/summary.json`
- `/work/tests-dev/demo-result/repo-pre-8-smoke-20260812/pre8-required-20260812T194817Z/summary.json`
- `/work/tests-dev/demo-result/repo-pre-8-smoke-20260812/pre8-required-20260812T194817Z/evidence/`
- `/work/tests-dev/demo-result/repo-pre-8-smoke-20260812/pre8-codec-followup-20260812T202059Z/summary.json`
- `/work/tests-dev/demo-result/repo-pre-8-smoke-20260812/pre8-codec-followup-20260812T202059Z/evidence/`
- tests-dev commit `46e6840f1b8918414af76c9a5731322c697eee8b`
## Fixtures and Immutable Inputs
The common base image was not modified:
```text
path: /work/tests-dev/lfs/freebsd-15-dev-src-20260811.bp
format: qcow2
mode: 0444
size: 16,515,530,752 bytes
SHA256: 67f359621f23a1d745f0889370cbb99a096cee3e99a0b2f3bb18fc7a91bf6fef
```
Selected primary fixture deployment identities:
| Group | Manifest SHA256 | Checksum-list SHA256 |
| --- | --- | --- |
| G1 | `9ffe9e695a6544cb010a5d4ba1e0c2c09d7455e6d7e28cc81da54d2dd954f2f2` | `db416004ff6b00ad286e50da506168b35a544a7da5619042225198843e4c741c` |
| G4 | `6200842757dae30f3a5b0683d726d339a24e55dff98cd084597462289a9308aa` | `229c84c5436cf9b5b659ded375097fba13621c20a2cf2d845f146df737836622` |
| G5 | `c9540baafb53b3783233c3950f4d8548c28585cd32335dadc14db613692a8978` | `d08138b1bd51579cbf5461a73abce9d7fddc9cdb8ace1329c9f1581d41e1095f` |
Follow-up G5 deployment identities:
```text
manifest: 9be85e48115f2dd2cae058f2a4ea7438512f28e647c30476d049d6b8025b02fd
checksum list: 7513425c98400f641523083bf0d06b2d548aa3163dfcdfe980dca2b0e1900acd
```
Deployment hashes can include run-specific metadata. Image, source, generator,
and checksum evidence remains beneath each run's `fixture-evidence/` and
per-case evidence directories.
## Cleanup and Guard Integrity
- The selected primary and follow-up QEMUs were force-destroyed by the runner
after their final errors.
- Their run-owned overlays were deleted.
- Ports 10000 and 10001 were released and closed.
- The independent basic-smoke QEMU shut down gracefully and its overlay was
removed.
- Guard PID 26318 retained its identity and TCP port 9222 remained active.
- Base-image SHA256, mode, and size were unchanged before and after the runs.
- The DUT commit and source tree remained unchanged and clean.
- No DUT source, repo22 source, base image, test source, fixture generator, or
`oldtests` content was modified during validation.
Cleanup of the disposable VM does not change TC004's case-level cleanup result:
the case itself failed to terminate its read process and could not unmount or
detach `md0`. VM destruction only removed the run environment afterward.
## Final Handoff
Pre8 delivers the planned source-responsibility changes and passes static,
revert, build, and basic plain/LZ4 smoke validation. It does not satisfy the
full required validation gate because the selected suite contains one definite
DUT failure and twelve blocked DUT cases. The honest final status is therefore
**FAIL**.
Open follow-up records:
- `issues/pre8-lzma-read-timeout.md`
- `issues/pre8-test-harness-blockers.md`