This commit is contained in:
2026-08-18 09:20:44 +02:00
commit b826cd721a
522 changed files with 93730 additions and 0 deletions
+217
View File
@@ -0,0 +1,217 @@
#!/bin/sh
set -eu
: "$PRE15_DUT"
: "$PRE15_ROOT"
: "$PRE15_CASE_TMP"
: "$PRE15_RUN_DIR"
: "$PRE15_LIB_DIR"
. "$PRE15_LIB_DIR/runner.sh"
test "$PRE15_MODE" = qemu || pre15_infra_blocked \
'B19a focused case requires exact-ABI QEMU mode'
fixture_dir=$PRE15_DUT/tests/pre15/fixtures
generator=$fixture_dir/B19a-xattr-generate.py
spec=$fixture_dir/B19a-xattr-spec.json
probe=$fixture_dir/B19a-xattr-probe.c
kld_builder=$fixture_dir/B28-build-kld.sh
artifacts=$PRE15_RUN_DIR/artifacts
first=$PRE15_CASE_TMP/fixtures-first
second=$PRE15_CASE_TMP/fixtures-second
module=$PRE15_CASE_TMP/B19a-erofs.ko
for tool in cc cmp diff file mkfs.erofs nm python3 scp sha256sum tar timeout; do
command -v "$tool" >/dev/null 2>&1 || \
pre15_infra_blocked "missing B19a QEMU tool: $tool"
done
for value in PRE15_QEMU_CONTROL_PATH PRE15_QEMU_SSH_KEY \
PRE15_QEMU_SSH_PORT PRE15_QEMU_SSH_USER; do
test -n "$(eval "printf '%s' \"\$$value\"")" || \
pre15_runner_fail "$value is required"
done
for fixture in "$generator" "$spec" "$probe" "$kld_builder"; do
pre15_record_fixture "b19a-$(basename "$fixture")" "$fixture"
done
for source in erofs_vnops.c internal.h xattr.c; do
pre15_record_fixture "b19a-$source" "$PRE15_DUT/src/$source"
done
mkdir -p "$artifacts"
if ! timeout -k 5 180 python3 -B "$generator" --spec "$spec" \
--output "$first" --work "$PRE15_CASE_TMP/generate-first" \
>"$artifacts/generate-first.json" 2>"$artifacts/generate-first.stderr"; then
pre15_runner_fail 'B19a first fixture generation failed'
fi
if ! timeout -k 5 180 python3 -B "$generator" --spec "$spec" \
--output "$second" --work "$PRE15_CASE_TMP/generate-second" \
>"$artifacts/generate-second.json" 2>"$artifacts/generate-second.stderr"; then
pre15_runner_fail 'B19a second fixture generation failed'
fi
if ! diff -qr "$first" "$second" >"$artifacts/fixture-repeat.diff"; then
pre15_runner_fail 'B19a focused fixtures are not byte reproducible'
fi
pre15_record_fixture b19a-valid-image "$first/valid.erofs"
tar -C "$first" -czf "$PRE15_CASE_TMP/B19a-fixtures.tar.gz" .
if ! timeout -k 10 600 /bin/sh "$kld_builder" "$PRE15_DUT" \
"$PRE15_FREEBSD_SRC" "$module" "$PRE15_CASE_TMP/kld-work" 0 \
>"$artifacts/kld-build.stdout" 2>"$artifacts/kld-build.stderr"; then
pre15_dut_fail 'B19a exact-ABI KLD build failed'
fi
pre15_record_module "$module"
file "$module" >"$artifacts/kld-file.txt"
sha256sum "$module" >"$artifacts/kld-sha256.txt"
nm -u "$module" | LC_ALL=C sort >"$artifacts/kld-nm-u.txt"
pre15_scp()
{
timeout -k 5 60 scp -O -q \
-o BatchMode=yes -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 \
-o "ControlPath=$PRE15_QEMU_CONTROL_PATH" \
-i "$PRE15_QEMU_SSH_KEY" -P "$PRE15_QEMU_SSH_PORT" \
"$1" "$PRE15_QEMU_SSH_USER@127.0.0.1:$2"
}
if ! pre15_scp "$PRE15_CASE_TMP/B19a-fixtures.tar.gz" \
/root/B19a-fixtures.tar.gz || ! pre15_scp "$probe" /root/B19a-xattr-probe.c ||
! pre15_scp "$module" /root/B19a-erofs.ko; then
pre15_infra_blocked 'could not transfer B19a module, probe, or fixtures'
fi
pre15_guest_ssh_bounded \
'rm -rf /root/pre15-b19a-fixtures && mkdir /root/pre15-b19a-fixtures && tar -xzf /root/B19a-fixtures.tar.gz -C /root/pre15-b19a-fixtures' ||
pre15_infra_blocked 'could not prepare B19a guest fixtures'
pre15_guest_ssh_bounded cc -std=c11 -Wall -Wextra -Werror \
-o /root/B19a-xattr-probe /root/B19a-xattr-probe.c ||
pre15_infra_blocked 'could not compile the B19a guest probe'
if pre15_guest_ssh_bounded kldstat -n B19a-erofs >/dev/null 2>&1; then
pre15_infra_blocked 'guest already has an EROFS KLD loaded'
fi
pre15_guest_ssh_bounded dmesg >"$artifacts/dmesg-before-load.txt"
if ! pre15_guest_ssh_bounded kldload /root/B19a-erofs.ko \
>"$artifacts/kldload.stdout" 2>"$artifacts/kldload.stderr"; then
pre15_dut_fail 'B19a exact-ABI KLD load failed'
fi
pre15_own_guest_kld B19a-erofs 'B19a exact-source KLD'
pre15_guest_ssh_bounded kldstat >"$artifacts/kldstat-after-load.txt"
b19a_unown()
{
tmp=$PRE15_CASE_TMP/ownership.$$
awk -F ' ' -v kind="$1" -v value="$2" \
'!($1 == kind && $2 == value)' "$PRE15_OWNERSHIP_FILE" >"$tmp"
mv "$tmp" "$PRE15_OWNERSHIP_FILE"
}
b19a_mount()
{
image=$1
mountpoint=$2
label=$3
md=$(pre15_guest_ssh_bounded mdconfig -a -t vnode \
-f "/root/pre15-b19a-fixtures/$image") ||
pre15_dut_fail "$label provider attach failed"
case "$md" in
md[0-9]*) ;;
*) pre15_runner_fail "unexpected B19a md unit: $md" ;;
esac
pre15_own_guest_md "$md" "$label provider"
pre15_guest_ssh_bounded mkdir -p "$mountpoint"
if ! pre15_guest_ssh_bounded mount -t erofs -o ro "/dev/$md" \
"$mountpoint"; then
pre15_dut_fail "$label mount failed"
fi
pre15_own_guest_mount "$mountpoint" "$label mount"
printf '%s\n' "$md"
}
b19a_detach()
{
mountpoint=$1
md=$2
pre15_guest_ssh_bounded umount "$mountpoint" ||
pre15_dut_fail "B19a unmount failed: $mountpoint"
b19a_unown guest-mount "$mountpoint"
pre15_guest_ssh_bounded mdconfig -d -u "$md" ||
pre15_dut_fail "B19a md detach failed: $md"
b19a_unown guest-md "$md"
}
valid_md=$(b19a_mount valid.erofs /mnt/pre15-b19a-valid 'B19a valid')
valid=/mnt/pre15-b19a-valid/target.bin
pre15_guest_ssh_bounded /root/B19a-xattr-probe valid "$valid" \
>"$artifacts/valid-first.txt"
pre15_guest_ssh_bounded /root/B19a-xattr-probe concurrent "$valid" 16 10 \
>"$artifacts/valid-concurrent.txt"
pre15_guest_ssh_bounded /root/B19a-xattr-probe valid "$valid" \
>"$artifacts/valid-repeat.txt"
b19a_detach /mnt/pre15-b19a-valid "$valid_md"
for image in corrupt-shared-count.erofs corrupt-shared-id.erofs corrupt-inline-name.erofs; do
label=$(basename "$image" .erofs)
mountpoint=/mnt/pre15-b19a-$label
md=$(b19a_mount "$image" "$mountpoint" "B19a $label")
if ! pre15_guest_ssh_bounded /root/B19a-xattr-probe corrupt \
"$mountpoint/target.bin" >"$artifacts/$label.txt" 2>&1; then
pre15_dut_fail "$label did not return EINTEGRITY"
fi
pre15_guest_ssh_bounded umount "$mountpoint" ||
pre15_dut_fail "$label unmount failed"
b19a_unown guest-mount "$mountpoint"
pre15_guest_ssh_bounded mdconfig -d -u "$md" ||
pre15_dut_fail "$label md detach failed"
b19a_unown guest-md "$md"
done
normal_md=$(b19a_mount valid.erofs /mnt/pre15-b19a-normal \
'B19a normal-unmount')
normal_pid=$(pre15_guest_ssh_bounded \
'cd /mnt/pre15-b19a-normal && sleep 60 >/tmp/B19a-normal.sleep 2>&1 & echo $!')
if pre15_guest_ssh_bounded umount /mnt/pre15-b19a-normal \
>"$artifacts/normal-unmount.stdout" 2>"$artifacts/normal-unmount.stderr"; then
pre15_dut_fail 'normal unmount unexpectedly ignored a held vnode'
fi
pre15_guest_ssh_bounded kill "$normal_pid" || true
pre15_guest_ssh_bounded umount /mnt/pre15-b19a-normal ||
pre15_dut_fail 'normal unmount failed after releasing held vnode'
b19a_unown guest-mount /mnt/pre15-b19a-normal
pre15_guest_ssh_bounded mdconfig -d -u "$normal_md" ||
pre15_dut_fail 'normal-unmount md detach failed'
b19a_unown guest-md "$normal_md"
forced_md=$(b19a_mount valid.erofs /mnt/pre15-b19a-forced \
'B19a forced-unmount')
forced_pid=$(pre15_guest_ssh_bounded \
'cd /mnt/pre15-b19a-forced && sleep 60 >/tmp/B19a-forced.sleep 2>&1 & echo $!')
pre15_guest_ssh_bounded umount -f /mnt/pre15-b19a-forced ||
pre15_dut_fail 'forced unmount failed'
b19a_unown guest-mount /mnt/pre15-b19a-forced
pre15_guest_ssh_bounded kill "$forced_pid" || true
pre15_guest_ssh_bounded mdconfig -d -u "$forced_md" ||
pre15_dut_fail 'forced-unmount md detach failed'
b19a_unown guest-md "$forced_md"
pre15_guest_ssh_bounded dmesg >"$artifacts/dmesg-after.txt"
diff -u "$artifacts/dmesg-before-load.txt" "$artifacts/dmesg-after.txt" \
>"$artifacts/dmesg.diff" || true
sed -n '/^+++ /d; /^+/s/^+/ /p' "$artifacts/dmesg.diff" \
>"$artifacts/dmesg-added.txt"
if grep -Eqi 'panic:|fatal trap|lock order reversal|witness.*warning|use-after-free|pager fault|undefined symbol|linker.*error' \
"$artifacts/dmesg-added.txt"; then
pre15_dut_fail 'B19a QEMU produced a kernel diagnostic'
fi
pre15_guest_ssh_bounded kldunload B19a-erofs ||
pre15_dut_fail 'B19a KLD unload failed'
b19a_unown guest-kld B19a-erofs
if pre15_guest_ssh_bounded kldstat -n B19a-erofs >/dev/null 2>&1; then
pre15_dut_fail 'B19a KLD remained loaded after cleanup'
fi
pre15_guest_ssh_bounded mount >"$artifacts/mount-after.txt"
pre15_guest_ssh_bounded mdconfig -l >"$artifacts/md-after.txt"
if grep -q 'pre15-b19a-' "$artifacts/mount-after.txt" ||
grep -q 'B19a' "$artifacts/md-after.txt"; then
pre15_dut_fail 'B19a guest mount or md resource remained after cleanup'
fi
pre15_target_reached
printf '%s\n' 'B19a exact-ABI xattr cache lifecycle PASS'