Files
erofs-freebsd-out-tree/tests/TC096-device-table-parse.md
T
2026-08-18 09:20:44 +02:00

3.3 KiB

Test Case: Device Table Parse

Test ID: TC096-device-table-parse
Category: Multi-Device
Priority: Critical

Objective

Verify extra_devices, devt_slotoff, 48-bit blocks/uniaddr, table offset zero, uniaddr=0, statfs aggregation, and out-of-primary table rejection.

Generator field self-check

Run python3 -B tests/g6_multidev_fixtures.py verify OUTPUT on the host. The manifest must contain these independently reparsed values:

Fixture primary blocks extra slot offset slots (blocks, uniaddr)
multi2 2 2 32 (137,2), (90,139)
multi2-devt0 2 2 0 (137,2), (90,139)
multi2-uniaddr0 2 2 32 (137,0), (90,139)
multi2-unified48 2 2 32 high-word unified ranges

The exact slot sizes are generated values and must also match the current manifest if the source changes.

Standard table and statfs

I=/root/repo22-g6/images
S=/root/repo22-g6/sources/chunk
mkdir -p /mnt/g6
kldload /root/repo22-g6/erofs.ko
mdconfig -a -t vnode -f "$I/multi2-primary.erofs" -u 90
mdconfig -a -t vnode -f "$I/multi2-slot1.blob" -u 91
mdconfig -a -t vnode -f "$I/multi2-slot2.blob" -u 92
mount -t erofs -o ro -o device.2=/dev/md92 -o device.1=/dev/md91 \
  /dev/md90 /mnt/g6
df -k /mnt/g6
cmp "$S/cross-device.bin" /mnt/g6/cross-device.bin

The manifest f_blocks basis is 2 + 137 + 90 = 229 at 4096 bytes, so df -k must report 916 one-kilobyte blocks.

Positive table variants

Unmount and detach units 92, 91, and 90 before each replacement primary. Mount each row with its two matching providers and compare the listed file:

Primary/provider prefix Required check
multi2-devt0 table bytes at image offset 0; full cross-device.bin cmp
multi2-uniaddr0 slot 1 selected by nonzero ID; full cross-device.bin cmp
multi2-unified48 nonzero uniaddr_hi and startblk_hi; full unified-address.bin cmp

Use this direct command shape for each row, changing only PREFIX:

PREFIX=multi2-devt0
umount /mnt/g6
mdconfig -d -u 92
mdconfig -d -u 91
mdconfig -d -u 90
mdconfig -a -t vnode -f "$I/$PREFIX-primary.erofs" -u 90
mdconfig -a -t vnode -f "$I/$PREFIX-slot1.blob" -u 91
mdconfig -a -t vnode -f "$I/$PREFIX-slot2.blob" -u 92
mount -t erofs -o ro -o device.1=/dev/md91 -o device.2=/dev/md92 \
  /dev/md90 /mnt/g6
cmp "$S/cross-device.bin" /mnt/g6/cross-device.bin

For multi2-unified48, compare unified-address.bin instead. Execute the block separately for all three prefixes; it is not a test runner.

Table outside the primary image

After detaching the prior variant:

mdconfig -a -t vnode -f "$I/bad-table-oob.erofs" -u 90
mdconfig -a -t vnode -f "$I/multi2-slot1.blob" -u 91
mdconfig -a -t vnode -f "$I/multi2-slot2.blob" -u 92
truss -f -o /tmp/tc096-oob.truss mount -t erofs -o ro \
  -o device.1=/dev/md91 -o device.2=/dev/md92 /dev/md90 /mnt/g6
tail -20 /tmp/tc096-oob.truss

Mount must return exactly EINTEGRITY before root vnode creation.

Cleanup and zero-state check

umount /mnt/g6 2>/dev/null || true
mdconfig -d -u 92
mdconfig -d -u 91
mdconfig -d -u 90
kldunload erofs
mount -p | awk '$3 == "erofs" { print }'
mdconfig -l
kldstat -n erofs 2>/dev/null || true
sysctl -n kern.geom.conftxt | grep -E 'md9[0-2]|erofs' || true

All four final outputs must be empty.