202 lines
5.6 KiB
Bash
Executable File
202 lines
5.6 KiB
Bash
Executable File
#!/bin/sh
|
|
set -u
|
|
|
|
test_dir=/root/repo22-namei
|
|
mount_dir=/mnt/repo22-namei
|
|
module_id=
|
|
md_device=
|
|
|
|
fail()
|
|
{
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
cleanup()
|
|
{
|
|
set +e
|
|
if mount | grep -q " on $mount_dir "; then
|
|
umount "$mount_dir"
|
|
fi
|
|
if [ -n "$md_device" ]; then
|
|
mdconfig -d -u "${md_device#md}"
|
|
fi
|
|
if [ -n "$module_id" ] && kldstat -q -i "$module_id"; then
|
|
kldunload -i "$module_id"
|
|
fi
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
mount_image()
|
|
{
|
|
image=$1
|
|
md_device=$(mdconfig -a -t vnode -f "$test_dir/$image") ||
|
|
fail "mdconfig $image"
|
|
mount -t erofs "/dev/$md_device" "$mount_dir" ||
|
|
fail "mount $image"
|
|
echo "mounted image=$image device=$md_device"
|
|
}
|
|
|
|
unmount_image()
|
|
{
|
|
umount "$mount_dir" || fail "umount $md_device"
|
|
mdconfig -d -u "${md_device#md}" || fail "detach $md_device"
|
|
md_device=
|
|
}
|
|
|
|
expect_integrity_failure()
|
|
{
|
|
image=$1
|
|
lookup_path=$2
|
|
readdir_path=$3
|
|
label=${image%.erofs}
|
|
|
|
mount_image "$image"
|
|
attempt=1
|
|
while [ "$attempt" -le 2 ]; do
|
|
output="$test_dir/$label-lookup-$attempt.txt"
|
|
if stat "$mount_dir/$lookup_path" >"$output" 2>&1; then
|
|
fail "$image lookup attempt $attempt unexpectedly succeeded"
|
|
fi
|
|
if grep -qi "No such file" "$output"; then
|
|
fail "$image lookup attempt $attempt became ENOENT"
|
|
fi
|
|
attempt=$((attempt + 1))
|
|
done
|
|
output="$test_dir/$label-readdir.txt"
|
|
if ./readdir_probe "$mount_dir/$readdir_path" 0 512 2 \
|
|
>"$output" 2>&1; then
|
|
fail "$image readdir unexpectedly succeeded"
|
|
fi
|
|
unmount_image
|
|
echo "integrity image=$image repeated-lookup=error readdir=error"
|
|
}
|
|
|
|
cd "$test_dir" || exit 1
|
|
mkdir -p "$mount_dir"
|
|
|
|
if mount | grep -qi erofs; then
|
|
fail "pre-existing EROFS mount"
|
|
fi
|
|
if kldstat | grep -qi erofs; then
|
|
fail "pre-existing EROFS module"
|
|
fi
|
|
if [ -n "$(mdconfig -l)" ]; then
|
|
fail "pre-existing md device"
|
|
fi
|
|
|
|
echo "== guest =="
|
|
uname -a
|
|
date -u
|
|
|
|
echo "== module load =="
|
|
kldload "$test_dir/erofs.ko" || fail "kldload"
|
|
module_id=$(kldstat | awk '$NF == "erofs.ko" { print $1 }')
|
|
[ -n "$module_id" ] || fail "loaded module not found"
|
|
kldstat -v -i "$module_id"
|
|
|
|
echo "== cold nested lookup =="
|
|
mount_image nested.erofs
|
|
payload=$(cat "$mount_dir/alpha/bravo/charlie/payload.txt") ||
|
|
fail "cold nested lookup"
|
|
[ "$payload" = "cold nested lookup payload" ] || fail "cold payload mismatch"
|
|
payload=$(cat "$mount_dir/alpha/bravo/charlie/payload.txt") ||
|
|
fail "repeated nested lookup"
|
|
[ "$payload" = "cold nested lookup payload" ] || fail "repeat payload mismatch"
|
|
payload=$(cat "$mount_dir/alpha/bravo/repeat.txt") ||
|
|
fail "sibling nested lookup"
|
|
[ "$payload" = "repeat lookup payload" ] || fail "sibling payload mismatch"
|
|
|
|
attempt=1
|
|
while [ "$attempt" -le 2 ]; do
|
|
output="$test_dir/missing-$attempt.txt"
|
|
if stat "$mount_dir/alpha/bravo/missing" >"$output" 2>&1; then
|
|
fail "missing lookup attempt $attempt unexpectedly succeeded"
|
|
fi
|
|
grep -qi "No such file" "$output" || fail "missing lookup was not ENOENT"
|
|
attempt=$((attempt + 1))
|
|
done
|
|
payload=$(cat "$mount_dir/alpha/bravo/charlie/payload.txt") ||
|
|
fail "existing lookup after negative cache"
|
|
[ "$payload" = "cold nested lookup payload" ] || fail "post-negative payload mismatch"
|
|
echo "cold lookup=pass repeat=pass negative-cache=pass"
|
|
|
|
echo "== large readdir and cookies =="
|
|
wide_count=$(ls -A1 "$mount_dir/wide" | wc -l | tr -d ' ')
|
|
[ "$wide_count" = 320 ] || fail "wide entry count $wide_count"
|
|
./readdir_probe "$mount_dir/wide" 0 128 400 > wide-probe.txt ||
|
|
fail "wide readdir probe"
|
|
awk '/^ off=/ {
|
|
off = $1; sub(/^off=/, "", off);
|
|
name = $5; sub(/^name=/, "", name);
|
|
print off, name;
|
|
}' wide-probe.txt > wide-cookies.txt
|
|
wide_dirents=$(wc -l < wide-cookies.txt | tr -d ' ')
|
|
[ "$wide_dirents" = 322 ] || fail "wide dirent count $wide_dirents"
|
|
awk '{ cookie[NR] = $1; name[NR] = $2 }
|
|
END {
|
|
for (i = 1; i <= NR; i++)
|
|
print cookie[i], (i < NR ? name[i + 1] : "<EOF>");
|
|
}' wide-cookies.txt > wide-resume-cases.txt
|
|
while read -r cookie expected; do
|
|
./readdir_probe "$mount_dir/wide" "$cookie" 128 1 > wide-resume.txt ||
|
|
fail "resume cookie $cookie"
|
|
if [ "$expected" = "<EOF>" ]; then
|
|
grep -q 'bytes=0$' wide-resume.txt || fail "cookie $cookie not EOF"
|
|
else
|
|
actual=$(awk '/^ off=/ {
|
|
name = $5; sub(/^name=/, "", name); print name; exit;
|
|
}' wide-resume.txt)
|
|
[ "$actual" = "$expected" ] ||
|
|
fail "cookie $cookie expected $expected got $actual"
|
|
fi
|
|
done < wide-resume-cases.txt
|
|
echo "wide entries=$wide_dirents all-resume-cookies=pass"
|
|
unmount_image
|
|
|
|
echo "== dot omitted cookies =="
|
|
mount_image dot-omitted.erofs
|
|
./readdir_probe "$mount_dir" 0 512 8 > dot-probe.txt || fail "dot probe"
|
|
awk '/^ off=/ {
|
|
off = $1; sub(/^off=/, "", off);
|
|
name = $5; sub(/^name=/, "", name);
|
|
print off, name;
|
|
}' dot-probe.txt > dot-cookies.txt
|
|
cat > dot-expected.txt <<'EOF'
|
|
12 ..
|
|
24 alpha
|
|
47 wide
|
|
48 .
|
|
EOF
|
|
cmp dot-cookies.txt dot-expected.txt || fail "dot cookie sequence"
|
|
./readdir_probe "$mount_dir" 47 128 1 > dot-resume-47.txt || fail "dot resume 47"
|
|
grep -q '^ off=48 .* name=\.$' dot-resume-47.txt || fail "dot resume 47 result"
|
|
./readdir_probe "$mount_dir" 48 128 1 > dot-resume-48.txt || fail "dot resume 48"
|
|
grep -q 'bytes=0$' dot-resume-48.txt || fail "dot resume 48 not EOF"
|
|
echo "dot cookies=12,24,47,48 resume=pass"
|
|
unmount_image
|
|
|
|
echo "== corrupted directories =="
|
|
expect_integrity_failure corrupt-short-block.erofs alpha .
|
|
expect_integrity_failure corrupt-nameoff.erofs alpha .
|
|
expect_integrity_failure \
|
|
corrupt-padding.erofs \
|
|
wide/entry-000-abcdefghijklmnopqrstuvwxyz.txt \
|
|
wide
|
|
|
|
echo "== module unload =="
|
|
kldunload -i "$module_id" || fail "kldunload"
|
|
module_id=
|
|
if kldstat | grep -qi erofs; then
|
|
fail "module remains loaded"
|
|
fi
|
|
if mount | grep -qi erofs; then
|
|
fail "mount remains"
|
|
fi
|
|
if [ -n "$(mdconfig -l)" ]; then
|
|
fail "md remains"
|
|
fi
|
|
|
|
dmesg | tail -120 > dmesg-tail.txt
|
|
echo "PASS: all VM regressions"
|