blob: 73f1b4d45ced0fc831481ffa72bdd6913115967f [file] [log] [blame]
#!/bin/selfclean /bin/sh
main_pid=$$
log()
{
echo "$@" >&2
}
fs_writable()
{
local dir="$1"
if ( : >"$dir/.check.tmp" ) 2>/dev/null; then
rm -f "$dir/.check.tmp"
return 0
else
return 1
fi
}
label()
{
"$@" 2>&1 | (
shift
while read line; do
echo "$*: $line"
done
)
}
abort()
{
if [ -z "$DONT_ABORT" ]; then
log 'Error encountered and $DONT_ABORT is not set: aborting.'
sleep 1
kill -TERM $main_pid
exit 98
else
log 'Not aborting - $DONT_ABORT is set.'
sleep 10
fi
}
retry()
{
while :; do
if "$@"; then
sleep 5
log "restarting '$*'"
else
log
log "FATAL: process ($*) died unexpectedly with code $?"
abort
fi
done
}
should_never_die()
{
while :; do
"$@"
log
log "FATAL: process ($*) died unexpectedly with code $?"
abort
log "restarting '$*'"
done
}
main()
{
# We originally tried to stress *both* ethernet and MoCA here, but that's
# too hard if the bridge device is configured (which is the normal case).
# So let's just send packets out the bridge interface, if it exists, or
# eth0, otherwise. The net effect is we'll end up sending packets over
# MoCA if the thin bruno is connected over MoCA, or ethernet if it's
# connected over ethernet, which is a lot like what should happen in real
# life.
if is-storage-box; then
log "Fat bruno: operating in server mode."
label should_never_die iperf -s &
label should_never_die iperf -s -u &
else
if [ -z "$SERVER_IP" ]; then
while :; do
log "Thin bruno: broadcasting for servers..."
SERVERS=$(find-servers)
[ -n "$SERVERS" ] && break
done
log "Found servers: " $SERVERS
else
SERVERS=$SERVER_IP
log "Hardcoded \$SERVER_IP: $SERVERS"
fi
for server in $SERVERS; do
while ! nc $server 5001 </dev/null; do
log "Waiting for iperf server to listen on $server:5001..."
sleep 2
done
done
for server in $SERVERS; do
if [ -n "$MAX_BANDWIDTH" ]; then
# iperf can't explicitly limit bandwidth in TCP mode. Sigh. So
# skip TCP and use fast UDP instead.
log "MAX_BANDWIDTH=$MAX_BANDWIDTH; testing UDP only."
label retry iperf -t60 -i10 -u -c $server -b "${MAX_BANDWIDTH}M" -d &
else
log "MAX_BANDWIDTH not set; testing max rate TCP and slow UDP."
label retry iperf -t60 -i10 -u -c $server -d &
label retry iperf -t60 -i10 -c $server -d &
fi
done
fi
if fs_writable /var/media; then
# fast random writes
should_never_die stress-disk -p10 --random --write /var/media &
else
log "No /var/media; skipping disk-write test."
fi
# raw disk/usb reads
for d in /dev/sd?; do
if [ -e "$d" ]; then
# fast sequential read (to force some seeks)
should_never_die stress-disk -p10 "$d" &
# slow small random read
should_never_die stress-disk -p0 -c4096 -m10 --random "$d" &
fi
done
# NAND reads
#TODO(apenwarr): -c65536 causes memory allocation problems.
# This seems to be because the MTD driver tries to allocate kernel memory
# the same size as the read() parameter as a single contiguous block,
# which, under heavy load, might not be available. There's no good reason
# for MTD to do this, afaik, so we could try to debug the kernel so we
# can increase this parameter. It could theoretically cause problems on
# a normal system under high load, not just one being stresstested.
if [ -e /dev/mtd/rootfs0 ]; then
should_never_die stress-disk -p10 -c4096 /dev/mtd/rootfs0 &
fi
# NOR reads
#TODO(apenwarr): see above about -c65536.
if [ -e /dev/mtd/hnvram ]; then
should_never_die stress-disk -p10 -c4096 /dev/mtd/hnvram &
fi
sleep 5
#TODO(apenwarr): actually bind the following to cpu0 and cpu1
should_never_die nice -n 19 spin cpu0-idle &
should_never_die nice -n 19 spin cpu1-idle &
wait
}
main 2>&1 | tee /proc/self/fd/2 | logos stresstest