summaryrefslogtreecommitdiff
path: root/dd-bench.sh
blob: b2d611cb3885a24dfb7406746e7d7211be5a17ba (plain)
    1 #!/usr/bin/env bash
    2 
    3 #
    4 # Dd-bench uses dd with various linux devices to benchmark storage io.
    5 # Copyright (C) 2015  Aaron Ball <nullspoon@iohq.net>
    6 #
    7 # This program is free software: you can redistribute it and/or modify
    8 # it under the terms of the GNU General Public License as published by
    9 # the Free Software Foundation, either version 3 of the License, or
   10 # (at your option) any later version.
   11 #
   12 # This program is distributed in the hope that it will be useful,
   13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15 # GNU General Public License for more details.
   16 #
   17 # You should have received a copy of the GNU General Public License
   18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
   19 #
   20 
   21 
   22 #
   23 # A simple logging function. Prints a pre-defined timestamped and formatted log
   24 # entry.
   25 #
   26 # @param msg The log message
   27 #
   28 function log {
   29   msg=${1}
   30   ts=$(date '+%h %d %H:%M:%S')
   31   echo -e "${ts}: ${1}"
   32 }
   33 
   34 
   35 #
   36 # Performs a read test, reading from the specified file and writing to
   37 # /dev/null to avoid as many bottlenecks as possible
   38 #
   39 # @param dest  Path to read data from
   40 # @param bs    Block size
   41 # @param count Number of blocks to write
   42 #
   43 function read_bench {
   44   src="${1}"
   45   bs="${2}"
   46   count="${3}"
   47 
   48   dest="/dev/zero"
   49 
   50   out=$(dd if=${src} of=${dest} iflag=direct bs=${bs} count=${count} 2>&1 | grep -v records)
   51   # Parse out total data
   52   total=$(echo ${out} | sed 's/.*(\(.*B\)).*/\1/')
   53   speed=$(echo ${out} | sed 's/.*, \(.*B\/s\)/\1/')
   54 
   55   log "Read ${bs} ${count} times. ${total} read at ${speed}."
   56 }
   57 
   58 
   59 #
   60 # Performs a write test, reading from /dev/zero to avoid any problems with cpu
   61 # bottlenecks.
   62 #
   63 # @param dest  Path to write the temp file (be sure you have enough space)
   64 # @param bs    Block size
   65 # @param count Number of blocks to write
   66 #
   67 function write_bench {
   68   dest="${1}"
   69   bs="${2}"
   70   count="${3}"
   71 
   72   src="/dev/zero"
   73 
   74   out=$(dd if=${src} of=${dest} oflag=direct bs=${bs} count=${count} 2>&1 | grep -v records)
   75   # Parse out total data
   76   total=$(echo ${out} | sed 's/.*(\(.*B\)).*/\1/')
   77   speed=$(echo ${out} | sed 's/.*, \(.*B\/s\)/\1/')
   78 
   79   log "Wrote ${bs} ${count} times. ${total} written at ${speed}."
   80 }
   81 
   82 
   83 function main {
   84   if [[ -z "${1}" ]]; then
   85     echo "Please specify the path to a file to write tests to."
   86     echo "Note that this will overwrite that file, so one that doesn't exist is"
   87     echo "preferable."
   88     exit 1
   89   fi
   90 
   91   # Warn the user
   92   echo -e "\nThis script will write up to 20 GB of data before it's done"
   93   echo -e "benchmarking. Be sure you have that much storage to spare on the"
   94   echo -e "disk being benchmarked.\n"
   95   echo -e -n "\nPress enter to continue... "
   96   read
   97 
   98   echo -e "\n\nBenchmark started at $(date)\n"
   99 
  100   path="${1}"
  101 
  102   # Perform benchmark tests
  103 
  104   # Note that the 1KB block tests write 10 and 80 megabyte files rather than
  105   # the previous 1G, 8G, etc due to the speed of the typical 1KB block size
  106   # test. Also note that the 200 MB test is skipped because it takes far too
  107   # long.
  108   log "*** Testing 1 KB blocks"
  109   write_bench "${path}" "1K" "10240"
  110   read_bench  "${path}" "1K" "10240"
  111   write_bench "${path}" "1K" "81920"
  112   read_bench  "${path}" "1K" "81920"
  113 
  114   log "*** Testing 1 MB blocks"
  115   write_bench "${path}" "1M" "1024"
  116   read_bench  "${path}" "1M" "1024"
  117   write_bench "${path}" "1M" "8192"
  118   read_bench  "${path}" "1M" "8192"
  119   write_bench "${path}" "1M" "20480"
  120   read_bench  "${path}" "1M" "20480"
  121 
  122   log "*** Testing 2 MB blocks"
  123   write_bench "${path}" "2M" "512"
  124   read_bench  "${path}" "2M" "512"
  125   write_bench "${path}" "2M" "4096"
  126   read_bench  "${path}" "2M" "4096"
  127   write_bench "${path}" "2M" "10240"
  128   read_bench  "${path}" "2M" "10240"
  129 
  130   log "*** Testing 4 MB blocks"
  131   write_bench "${path}" "4M" "256"
  132   read_bench  "${path}" "4M" "256"
  133   write_bench "${path}" "4M" "2048"
  134   read_bench  "${path}" "4M" "2048"
  135   write_bench "${path}" "4M" "5120"
  136   read_bench  "${path}" "4M" "5120"
  137 
  138   log "*** Testing 1 GB blocks"
  139   write_bench "${path}" "1G" "1"
  140   read_bench  "${path}" "1G" "1"
  141   write_bench "${path}" "1G" "8"
  142   read_bench  "${path}" "1G" "8"
  143   write_bench "${path}" "1G" "20"
  144   read_bench  "${path}" "1G" "20"
  145 
  146   # Attempt cleanup only if the destination test path is a file and not a
  147   # device (no sense in trying to remove a device).
  148   if [[ -f "${path}" ]]; then
  149     rm "${path}"
  150   fi
  151 }
  152 
  153 main ${@}

Generated by cgit