Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- #
- # Find the maximum I/O size for a single read/write syscall
- # Uses binary search after detecting the approximate limit by doubling
- #
- # Works on Linux, BSD, and other POSIX systems
- set -eu
- # Start with 1 MB
- size=$((1024 * 1024))
- prev_size=0
- echo 'Finding maximum syscall I/O size...'
- echo 'Starting from 1 MB and doubling until limit is reached'
- echo
- while true; do
- # Convert size to human-readable format
- if [ "$size" -lt $((1024 * 1024)) ]; then
- size_kb=$((size / 1024))
- size_str="$size_kb KB"
- elif [ "$size" -lt $((1024 * 1024 * 1024)) ]; then
- size_mb=$((size / 1024 / 1024))
- size_str="$size_mb MB"
- else
- size_gb=$((size / 1024 / 1024 / 1024))
- size_str="$size_gb GB"
- fi
- printf "Testing size: $size_str ... "
- # Read 'size' bytes in one syscall and count actual bytes read
- # Check if we got fewer bytes than requested (short read)
- if dd status=noxfer if=/dev/zero of=/dev/null count=1 bs="$size" 2>&1 | grep -q '^0+[0-9]'; then
- echo 'LIMIT REACHED'
- break
- fi
- echo OK
- # Save current size for next iteration
- prev_size=$size
- # Double the size for next iteration
- new_size=$((size * 2))
- # Check for overflow (when doubling causes a negative number or smaller value)
- if [ "$new_size" -le "$size" ]; then
- echo
- echo 'Reached maximum representable size without hitting limit'
- echo "Maximum tested size: $size bytes ($size_str)"
- exit 0
- fi
- size=$new_size
- done
- echo
- echo "Starting binary search between $prev_size and $size bytes..."
- echo
- # Binary search for exact limit
- low=$prev_size
- high=$size
- initial_high=$high
- # Calculate human-readable format for initial_high
- if [ "$initial_high" -lt $((1024 * 1024)) ]; then
- initial_high_kb=$((initial_high / 1024))
- initial_high_str="${initial_high_kb} KB"
- elif [ "$initial_high" -lt $((1024 * 1024 * 1024)) ]; then
- initial_high_mb=$((initial_high / 1024 / 1024))
- initial_high_str="${initial_high_mb} MB"
- else
- initial_high_gb=$((initial_high / 1024 / 1024 / 1024))
- initial_high_str="${initial_high_gb} GB"
- fi
- while [ $((high - low)) -gt 1 ]; do
- mid=$(((low + high) / 2))
- # Calculate how much we subtracted from initial_high
- subtracted=$((initial_high - mid))
- printf " Trying $initial_high_str - $subtracted bytes ... "
- # Test if this size works - check if we get all bytes
- if dd status=noxfer if=/dev/zero of=/dev/null count=1 bs="$mid" 2>&1 | grep -q '^0+[0-9]'; then
- echo FAIL
- high=$mid
- else
- echo OK
- low=$mid
- fi
- done
- echo
- echo '======================================='
- echo " MAXIMUM SYSCALL I/O SIZE: $low bytes"
- echo '======================================='
- echo " Decimal: $low"
- printf " Hex: 0x%x\n" "$low"
- echo
Advertisement