# G4 xattr, ACL, and metabox manual setup

This setup is shared only by TC005, TC067-TC083, TC117, TC134-TC140, and
TC142. It does not consume an existing image or report from `/work/build`.

## Host fixture generation

The host must provide erofs-utils 1.8.6 and Linux `user.*` xattrs. The helper
creates the source trees, invokes `mkfs.erofs`, performs structured on-disk
transformations, and then reopens every output to verify its fields and hashes.

```sh
mkfs.erofs -V
run=/work/build/repo22-g4-$(date -u +%Y%m%dT%H%M%SZ)
python3 tests/g4_fixtures.py make --output "$run"
python3 tests/g4_fixtures.py verify --output "$run"
sha256sum -c "$run/IMAGE-SHA256SUMS"
```

`mkfs.erofs -V` must report 1.8.6. `SOURCE-SHA256`,
`IMAGE-SHA256SUMS`, and `fixture-manifest.json` are required evidence. The
manifest records the complete source inventory, each mkfs command, image and
provider sizes, and every transformed field as offset/size/before/after bytes.

The generated images are:

| Shape | Images |
|---|---|
| inline, shared, packed-prefix, ACL | `basic.erofs` |
| primary prefix fallback | `prefix-primary.erofs` |
| plain, compressed, fragment metabox | `metabox-plain.erofs`, `metabox-compressed.erofs`, `metabox-fragment.erofs` |
| malformed xattr | `bad-inline-entry.erofs`, `bad-shared-entry.erofs` |
| declared bounds | `bad-shared-declared-bounds.erofs`, `bad-prefix-declared-bounds.erofs` |
| superblock validation | `bad-metabox-truncated-extension.erofs`, `bad-ishare-prefix-id.erofs` |
| fragment safety | `bad-fragment-self-loop.erofs`, `bad-fragment-range.erofs`, `bad-metabox-recursive-nid.erofs`, `bad-packed-recursive-nid.erofs` |

## Module and guest

Build `src/` at the exact test commit with FreeBSD 15 kernel headers. Record
the commit, header revision/branch, compiler target, `WITH_ZSTDIO`, and KLD
SHA256. Copy only the new KLD and generated images to an isolated FreeBSD 15
guest. Load the KLD and verify guest hashes before the first case.

```sh
freebsd-version
uname -a
sha256 /tmp/repo22-g4/erofs.ko /tmp/repo22-g4/images/*.erofs
kldload /tmp/repo22-g4/erofs.ko
mkdir -p /mnt/repo22-g4 /tmp/repo22-g4/logs
```

Each Markdown case is run separately. Attach its stated image, mount read-only,
run only the stated observations, then unmount and detach before the next case.

```sh
unit=$(mdconfig -a -t vnode -f /tmp/repo22-g4/images/IMAGE.erofs)
mount -t erofs -o ro /dev/${unit} /mnt/repo22-g4
# case-specific commands
umount /mnt/repo22-g4
mdconfig -d -u "${unit#md}"
```

## FreeBSD xattr and errno rules

Linux `user.*` appears in FreeBSD namespace `user` without `user.` in the
attribute name. Linux `trusted.*`, `security.*`, and POSIX ACL xattrs appear in
FreeBSD namespace `system`; trusted/security retain their full names, while ACL
names are `posix_acl_access` and `posix_acl_default`. Use `lsextattr` and
`getextattr`, not Linux `getfattr` syntax.

Use `getextattr -qq -x` for byte-exact output. The utility's exit status is not
authoritative for all failures, so capture the kernel result with `truss` and
require errno 87 (`ENOATTR`), 97 (`EINTEGRITY`), 5 (`EIO`), or 30 (`EROFS`) as
specified by the case. Negative mounts must show `nmount(...)=ERR#97` or an
equivalent normalized `EIO` at a boundary where the VFS maps integrity errors.

## Required cleanup evidence

After every case, record zero matching mounts and zero matching md units. At
the end, require no active EROFS allocation, unload the KLD, and stop the
dedicated VM.

```sh
mount | grep repo22-g4 || true
mdconfig -l
vmstat -m | grep erofs
kldunload erofs
```
