teknoraver

maxrw

Dec 22nd, 2025 (edited)
3,827
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 2.69 KB | None | 0 0
  1. #!/bin/sh
  2. #
  3. # Find the maximum I/O size for a single read/write syscall
  4. # Uses binary search after detecting the approximate limit by doubling
  5. #
  6. # Works on Linux, BSD, and other POSIX systems
  7.  
  8. set -eu
  9.  
  10. # Start with 1 MB
  11. size=$((1024 * 1024))
  12. prev_size=0
  13.  
  14. echo 'Finding maximum syscall I/O size...'
  15. echo 'Starting from 1 MB and doubling until limit is reached'
  16. echo
  17.  
  18. while true; do
  19.     # Convert size to human-readable format
  20.     if [ "$size" -lt $((1024 * 1024)) ]; then
  21.         size_kb=$((size / 1024))
  22.         size_str="$size_kb KB"
  23.     elif [ "$size" -lt $((1024 * 1024 * 1024)) ]; then
  24.         size_mb=$((size / 1024 / 1024))
  25.         size_str="$size_mb MB"
  26.     else
  27.         size_gb=$((size / 1024 / 1024 / 1024))
  28.         size_str="$size_gb GB"
  29.     fi
  30.  
  31.     printf "Testing size: $size_str ... "
  32.  
  33.     # Read 'size' bytes in one syscall and count actual bytes read
  34.     # Check if we got fewer bytes than requested (short read)
  35.     if dd status=noxfer if=/dev/zero of=/dev/null count=1 bs="$size" 2>&1 | grep -q '^0+[0-9]'; then
  36.         echo 'LIMIT REACHED'
  37.         break
  38.     fi
  39.  
  40.     echo OK
  41.  
  42.     # Save current size for next iteration
  43.     prev_size=$size
  44.  
  45.     # Double the size for next iteration
  46.     new_size=$((size * 2))
  47.  
  48.     # Check for overflow (when doubling causes a negative number or smaller value)
  49.     if [ "$new_size" -le "$size" ]; then
  50.         echo
  51.         echo 'Reached maximum representable size without hitting limit'
  52.         echo "Maximum tested size: $size bytes ($size_str)"
  53.         exit 0
  54.     fi
  55.  
  56.     size=$new_size
  57. done
  58.  
  59. echo
  60. echo "Starting binary search between $prev_size and $size bytes..."
  61. echo
  62.  
  63. # Binary search for exact limit
  64. low=$prev_size
  65. high=$size
  66. initial_high=$high
  67.  
  68. # Calculate human-readable format for initial_high
  69. if [ "$initial_high" -lt $((1024 * 1024)) ]; then
  70.     initial_high_kb=$((initial_high / 1024))
  71.     initial_high_str="${initial_high_kb} KB"
  72. elif [ "$initial_high" -lt $((1024 * 1024 * 1024)) ]; then
  73.     initial_high_mb=$((initial_high / 1024 / 1024))
  74.     initial_high_str="${initial_high_mb} MB"
  75. else
  76.     initial_high_gb=$((initial_high / 1024 / 1024 / 1024))
  77.     initial_high_str="${initial_high_gb} GB"
  78. fi
  79.  
  80. while [ $((high - low)) -gt 1 ]; do
  81.     mid=$(((low + high) / 2))
  82.  
  83.     # Calculate how much we subtracted from initial_high
  84.     subtracted=$((initial_high - mid))
  85.  
  86.     printf "  Trying $initial_high_str - $subtracted bytes ... "
  87.  
  88.     # Test if this size works - check if we get all bytes
  89.     if dd status=noxfer if=/dev/zero of=/dev/null count=1 bs="$mid" 2>&1 | grep -q '^0+[0-9]'; then
  90.         echo FAIL
  91.         high=$mid
  92.     else
  93.         echo OK
  94.         low=$mid
  95.     fi
  96. done
  97.  
  98. echo
  99. echo '======================================='
  100. echo " MAXIMUM SYSCALL I/O SIZE: $low bytes"
  101. echo '======================================='
  102. echo "  Decimal: $low"
  103. printf "  Hex:     0x%x\n" "$low"
  104. echo
Advertisement