Files
erofs-freebsd-out-tree/tests/G6-MANUAL-SETUP.md
T
2026-08-18 09:20:44 +02:00

5.8 KiB

G6 Chunk and Multi-Device Manual Setup

This setup applies only to TC006, TC093 through TC101, and TC118. There are exactly 11 test cases. The commands below generate new inputs; no fixture or result from an earlier run is an input.

Host prerequisites

  • Linux host with erofs-utils 1.8.6 (mkfs.erofs and fsck.erofs).
  • Python 3.11 or newer.
  • QEMU with qcow2 support.
  • A clean FreeBSD 15 amd64 base disk used only as the backing file for a new per-run overlay.

Set a new run directory and generate the fixtures twice:

REPO=/path/to/worktree/repo-community/repo22
RUN=/work/build/repo22-g6-$(date -u +%Y%m%dT%H%M%SZ)
mkdir -p "$RUN"
cd "$REPO"
python3 -B tests/g6_multidev_fixtures.py generate \
  --output "$RUN/fixtures-a"
python3 -B tests/g6_multidev_fixtures.py generate \
  --output "$RUN/fixtures-b"
cmp "$RUN/fixtures-a/manifest.json" "$RUN/fixtures-b/manifest.json"
cmp "$RUN/fixtures-a/SHA256SUMS" "$RUN/fixtures-b/SHA256SUMS"
python3 -B tests/g6_multidev_fixtures.py verify "$RUN/fixtures-a"

generate refuses an existing output directory, fixes source bytes, UUIDs, timestamps, worker count, and every binary transformation, and asserts the old field before each patch. verify checks every artifact size and SHA256, then reparses superblock, device-table, and chunk-index fields from disk.

The manifest records two erofs-utils 1.8.6 limitations. Its fsck qualifies the mkfs split image, single-index image, explicit 2/3-slot images, table-at-0, uniaddr=0, fragment image, and original two-block LZ4 pcluster. Flatdev and device-ID-0 unified relocation are qualified by the FreeBSD kernel reads in TC094 and TC101 because this fsck release does not implement those mappings.

Dedicated FreeBSD 15 VM

Create a new overlay and use only SSH port 9226 for this run:

qemu-img create -f qcow2 -F qcow2 \
  -b /work/build/vm-freebsd-dev-base.qcow2 \
  "$RUN/freebsd15-overlay.qcow2"
qemu-system-x86_64 -accel tcg,thread=multi -cpu qemu64 \
  -m 6144 -smp 4 \
  -drive file="$RUN/freebsd15-overlay.qcow2",if=virtio,format=qcow2 \
  -netdev user,id=net0,hostfwd=tcp:127.0.0.1:9226-:22 \
  -device virtio-net-pci,netdev=net0 -display none \
  -serial file:"$RUN/freebsd15-serial.log" -monitor none \
  -pidfile "$RUN/freebsd15-qemu.pid" \
  -D "$RUN/freebsd15-qemu.log" -daemonize

Record the guest identity before installing test artifacts:

uname -a
freebsd-version -ku
sysctl -n kern.osreldate
sha256 /boot/kernel/kernel
mdconfig -l
mount -p | awk '$3 == "erofs"'

The initial mdconfig and EROFS mount outputs must be empty.

Exact-source KLD

On the host, record and archive the exact worktree source:

git rev-parse HEAD | tee "$RUN/source.commit"
git status --short
git archive --format=tar HEAD repo-community/repo22 | \
  gzip -n > "$RUN/repo22-source.tar.gz"
git archive --format=tar HEAD dev-freebsd-releng/sys | \
  gzip -n > "$RUN/freebsd-sys-source.tar.gz"
tar -C "$RUN/fixtures-a" -czf "$RUN/g6-fixtures.tar.gz" \
  SHA256SUMS manifest.json images sources

Transfer both archives to the new guest. Authentication details remain outside the repository:

scp -O -P 9226 "$RUN/repo22-source.tar.gz" \
  "$RUN/freebsd-sys-source.tar.gz" \
  "$RUN/g6-fixtures.tar.gz" [email protected]:/root/

Build natively in the guest, with no source edits:

mkdir -p /root/freebsd-src /root/repo22-g6-src /root/repo22-g6
tar -xzf /root/freebsd-sys-source.tar.gz -C /root/freebsd-src \
  --strip-components 1
tar -xzf /root/repo22-source.tar.gz -C /root/repo22-g6-src \
  --strip-components 2
tar -xzf /root/g6-fixtures.tar.gz -C /root/repo22-g6
cd /root/repo22-g6-src
grep -E '^(REVISION|BRANCH)=' /root/freebsd-src/sys/conf/newvers.sh
env WITH_ZSTDIO=1 FREEBSD_SRC=/root/freebsd-src ./build.sh
sha256 build/erofs.ko
file build/erofs.ko
cp build/erofs.ko /root/repo22-g6/erofs.ko

At baseline 6b33b4afb490be7d6fec70e499469c306a58435d, the tracked sys tree is 15.0-RELEASE-p9 and the clean guest is p8; both report OSREL 1500068. Record this source/guest distinction rather than claiming they are the same patch level. Also record source.commit, WITH_ZSTDIO=1, FreeBSD source archive SHA256, KLD SHA256, kernel SHA256, and all guest values in the report.

Manual evidence rules

Run the commands in each TC Markdown directly. Do not use a runner, CI job, or test wrapper. Before each test:

mkdir -p /mnt/g6
kldload /root/repo22-g6/erofs.ko
dmesg | tail -40 > /tmp/g6-dmesg-before

For a negative mount or read, capture the syscall result with truss and record the named errno, not only command exit status:

truss -f -o /tmp/operation.truss command arguments
tail -20 /tmp/operation.truss

After every TC, unmount first, detach external providers in descending slot order, detach the primary, and unload the module. All four checks must report zero:

mount -p | awk '$3 == "erofs" { print }'
mdconfig -l
kldstat -n erofs 2>/dev/null || true
sysctl -n kern.geom.conftxt | \
  awk '/Geom name: md9[0-3]$|Consumers:|Providers:|erofs/ { print }'

Also compare the new dmesg suffix and reject any panic, trap, assertion, watchdog, or EROFS error not expected by the current negative operation.

FreeBSD and Linux behavior

Linux EROFS accepts a device table at byte offset zero and excludes a slot whose uniaddr is zero from device-ID-0 unified lookup; a nonzero device ID still selects that slot. FreeBSD uses explicit device.<slot>=/dev/<provider> mount options because GEOM providers are not discovered from Linux block device tags. FreeBSD also holds one read-only GEOM consumer per provider, so normal mdconfig -d returns EBUSY while mounted. A forced GEOM orphan makes later cold I/O return ENXIO; unmount must still release vnode, cdev, and GEOM references. These lifecycle details have no direct Linux loop-device equivalent and are checked in TC006 and TC118.