115 lines
3.8 KiB
Markdown
115 lines
3.8 KiB
Markdown
# Test Case: Controlled Memory Pressure
|
|
|
|
**Test ID**: TC127-memory-pressure
|
|
**Category**: Boundary & Stress
|
|
**Priority**: High
|
|
**Regression**: None
|
|
|
|
## Objective
|
|
|
|
Verify correct EROFS reads while three synchronized FreeBSD processes touch
|
|
memory up to per-process RCTL virtual-memory denial, then prove allocation
|
|
failure, release, recovery, PID exit, and read integrity.
|
|
|
|
## Preconditions
|
|
|
|
- Complete `G7-MANUAL-SETUP.md`.
|
|
- `sysctl -n kern.racct.enable` must print 1. Record an ENV result instead of
|
|
inventing pressure if this loader facility cannot be enabled.
|
|
- Use `rctl vmemoryuse:deny`; do not use the invalid `jail -m 256M` command.
|
|
|
|
## Manual Steps
|
|
|
|
```sh
|
|
G7=/root/repo22-g7
|
|
FIX=$G7/fixtures
|
|
SRC=$FIX/sources/workloads/pressure/pressure.bin
|
|
IMAGE=$FIX/images/workloads.erofs
|
|
MNT=/mnt/repo22-g7-tc127
|
|
E=$G7/evidence/TC127
|
|
mkdir -p "$MNT" "$E"
|
|
test "$(sysctl -n kern.racct.enable)" -eq 1
|
|
sysctl kern.racct.enable | tee "$E/racct.txt"
|
|
rctl | tee "$E/rctl-before.txt"
|
|
vmstat -H 1 5 | tee "$E/vmstat-before.txt"
|
|
unit=$(mdconfig -a -t vnode -f "$IMAGE")
|
|
mount -t erofs -o ro "/dev/$unit" "$MNT"
|
|
: > "$E/pids.tsv"
|
|
index=1
|
|
while [ "$index" -le 3 ]; do
|
|
rm -f "$E/go-$index" "$E/stop-$index" "$E/pressure-$index.log"
|
|
"$G7/g7_probe" pressure "$E/go-$index" "$E/stop-$index" 1024 \
|
|
> "$E/pressure-$index.log" 2>&1 &
|
|
pid=$!
|
|
printf '%s\t%s\n' "$index" "$pid" >> "$E/pids.tsv"
|
|
index=$((index + 1))
|
|
done
|
|
attempt=0
|
|
while [ "$attempt" -lt 30 ]; do
|
|
ready=$(grep -l '^state=waiting ' "$E"/pressure-*.log 2>/dev/null \
|
|
| wc -l | tr -d ' ')
|
|
test "$ready" -eq 3 && break
|
|
sleep 1
|
|
attempt=$((attempt + 1))
|
|
done
|
|
test "$ready" -eq 3
|
|
: > "$E/rctl-rules.txt"
|
|
while IFS="$(printf '\t')" read -r worker pid; do
|
|
rctl -a "process:$pid:vmemoryuse:deny=640M"
|
|
rctl -l "process:$pid" >> "$E/rctl-rules.txt"
|
|
touch "$E/go-$worker"
|
|
done < "$E/pids.tsv"
|
|
attempt=0
|
|
while [ "$attempt" -lt 120 ]; do
|
|
holding=$(grep -l '^state=holding .*allocation_failure=ENOMEM ' \
|
|
"$E"/pressure-*.log 2>/dev/null | wc -l | tr -d ' ')
|
|
test "$holding" -eq 3 && break
|
|
sleep 1
|
|
attempt=$((attempt + 1))
|
|
done
|
|
test "$holding" -eq 3
|
|
vmstat -H 1 10 | tee "$E/vmstat-pressure.txt"
|
|
rctl -hu process:$(awk 'NR == 1 { print $2 }' "$E/pids.tsv") \
|
|
| tee "$E/rctl-utilization.txt"
|
|
source_hash=$(sha256 -q "$SRC")
|
|
target_hash=$(sha256 -q "$MNT/pressure/pressure.bin")
|
|
printf 'source=%s\ntarget=%s\n' "$source_hash" "$target_hash" \
|
|
| tee "$E/hashes.txt"
|
|
test "$source_hash" = "$target_hash"
|
|
cmp "$SRC" "$MNT/pressure/pressure.bin"
|
|
while IFS="$(printf '\t')" read -r worker pid; do
|
|
touch "$E/stop-$worker"
|
|
done < "$E/pids.tsv"
|
|
failed=0
|
|
: > "$E/waits.tsv"
|
|
while IFS="$(printf '\t')" read -r worker pid; do
|
|
wait "$pid"
|
|
rc=$?
|
|
printf '%s\t%s\t%s\n' "$worker" "$pid" "$rc" >> "$E/waits.tsv"
|
|
test "$rc" -eq 0 || failed=$((failed + 1))
|
|
rctl -r "process:$pid:vmemoryuse:deny=640M" 2>/dev/null || true
|
|
done < "$E/pids.tsv"
|
|
test "$failed" -eq 0
|
|
grep '^state=released .*recovery=ok exit=0$' "$E"/pressure-*.log
|
|
vmstat -H 1 10 | tee "$E/vmstat-after.txt"
|
|
rctl | tee "$E/rctl-after.txt"
|
|
rm -f "$E"/go-* "$E"/stop-*
|
|
cat "$E/pids.tsv" "$E/waits.tsv" "$E"/pressure-*.log
|
|
umount "$MNT"
|
|
mdconfig -d -u "${unit#md}"
|
|
test -z "$(mount -p | awk -v m="$MNT" '$2 == m { print }')"
|
|
test -z "$(mdconfig -l | tr ' ' '\n' | grep -x "$unit")"
|
|
```
|
|
|
|
## PASS Gate
|
|
|
|
- RACCT/RCTL availability and before/pressure/after `vmstat` are recorded.
|
|
- Three persisted PIDs each report `allocation_failure=ENOMEM`, later report
|
|
exact released bytes and `recovery=ok`, and exit 0 when waited.
|
|
- The mounted 96 MiB file SHA256 and full bytes match the source while pressure
|
|
is held.
|
|
- G7 RCTL rules, synchronization files, mount, and provider are removed.
|
|
|
|
Different page counts or allocation totals are recording-only. Read mismatch,
|
|
panic, hang, unreclaimed process, or unexpected kernel error is KFAIL.
|