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.erofsandfsck.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.