4.1 KiB
Test Case: Missing, Invalid, and Orphaned External Device
Test ID: TC118-device-not-found
Category: Multi-Device / Error Handling
Priority: Critical
Objective
Verify exact missing/short/duplicate/path errors, forced GEOM orphan behavior, concurrent provider ownership, and complete vnode/cdev/consumer cleanup.
Fixture qualification
Use the fresh multi2 set. The manifest must show /cold-slot2.bin has one
chunk with device ID 2; do not read it before the orphan step.
multi2-slot2-short.blob is exactly one block below slot 2's declared size.
Mount-time errors
Set up the test directory and load the exact KLD once:
I=/root/repo22-g6/images
mkdir -p /mnt/g6 /mnt/g6b
kldload /root/repo22-g6/erofs.ko
Run each case separately with truss, detaching all attached md units after
each failure:
- Split primary with no
device.N:ENXIO. - Only
device.1:ENXIO. - Valid slot 1 plus
multi2-slot2-short.blob:ENXIO. - The same md91 assigned to slots 1 and 2:
EINVAL. - Primary md90 also assigned as slot 1, with valid md92 for slot 2:
EINVAL.
The short-media command is:
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-short.blob" -u 92
truss -f -o /tmp/tc118-short.truss mount -t erofs -o ro \
-o device.1=/dev/md91 -o device.2=/dev/md92 /dev/md90 /mnt/g6
tail -20 /tmp/tc118-short.truss
mdconfig -d -u 92
mdconfig -d -u 91
mdconfig -d -u 90
After every case, mount -p | awk '$3 == "erofs"' and matching
kern.geom.conftxt consumer output must be empty.
Forced orphan
Attach fresh providers and mount without reading cold-slot2.bin:
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.1=/dev/md91 -o device.2=/dev/md92 \
/dev/md90 /mnt/g6
truss -f -o /tmp/tc118-ebusy.truss mdconfig -d -u 92
tail -20 /tmp/tc118-ebusy.truss
mdconfig -d -u 92 -o force
truss -f -o /tmp/tc118-orphan-read.truss sha256 \
/mnt/g6/cold-slot2.bin
tail -20 /tmp/tc118-orphan-read.truss
Normal detach must return EBUSY; forced detach must complete; the first cold
slot-2 read must return exactly ENXIO without panic, hang, or leaked vnode.
umount /mnt/g6
mdconfig -d -u 91
mdconfig -d -u 90
Concurrent mount ownership
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.1=/dev/md91 -o device.2=/dev/md92 \
/dev/md90 /mnt/g6
truss -f -o /tmp/tc118-concurrent.truss mount -t erofs -o ro \
-o device.1=/dev/md91 -o device.2=/dev/md92 /dev/md90 /mnt/g6b
tail -20 /tmp/tc118-concurrent.truss
sha256 /mnt/g6/tc006.bin
The second mount must return exactly EBUSY, and the first mount must remain
readable. Record a kernel failure and do not edit src/ if FreeBSD permits a
second mount of an already-open provider set.
umount /mnt/g6
mdconfig -d -u 92
mdconfig -d -u 91
mdconfig -d -u 90
Pathname preservation
truss -f -o /tmp/tc118-primary-enoent.truss mount -t erofs -o ro \
/no/such/repo22-g6-primary /mnt/g6
tail -20 /tmp/tc118-primary-enoent.truss
mdconfig -a -t vnode -f "$I/multi2-primary.erofs" -u 90
mdconfig -a -t vnode -f "$I/multi2-slot1.blob" -u 91
truss -f -o /tmp/tc118-slot-enoent.truss mount -t erofs -o ro \
-o device.1=/dev/md91 -o device.2=/no/such/repo22-g6-slot2 \
/dev/md90 /mnt/g6
tail -20 /tmp/tc118-slot-enoent.truss
Both operations must preserve exactly ENOENT; the external failure must also
release the already-open slot-1 consumer.
Cleanup and zero-state check
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
dmesg | tail -120
All four final lifecycle outputs must be empty. The dmesg suffix must contain no panic, trap, assertion, watchdog, or unexpected EROFS error.