summaryrefslogtreecommitdiff
path: root/dd-bench.sh
blob: 094782e47c1dc371ae38e643618656722cfab148 (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 "This script will write up to 20 GB of data before it's done"
   93   echo "benchmarking. Be sure you have that much storage to spare on the disk"
   94   echo -e "being benchmarked.\n"
   95   wait=5
   96   echo -e "Proceeding with benchmark in ${wait} seconds...\n\n"
   97   sleep ${wait}
   98 
   99   echo -e "Benchmark started at $(date)\n"
  100 
  101   path="${1}"
  102 
  103   # Perform benchmark tests
  104 
  105   # Note that the 1KB block tests write 10 and 80 megabyte files rather than
  106   # the previous 1G, 8G, etc due to the speed of the typical 1KB block size
  107   # test. Also note that the 200 MB test is skipped because it takes far too
  108   # long.
  109   log "*** Testing 1 KB blocks"
  110   write_bench "${path}" "1K" "10240"
  111   read_bench  "${path}" "1K" "10240"
  112   write_bench "${path}" "1K" "81920"
  113   read_bench  "${path}" "1K" "81920"
  114 
  115   log "*** Testing 1 MB blocks"
  116   write_bench "${path}" "1M" "1024"
  117   read_bench  "${path}" "1M" "1024"
  118   write_bench "${path}" "1M" "8192"
  119   read_bench  "${path}" "1M" "8192"
  120   write_bench "${path}" "1M" "20480"
  121   read_bench  "${path}" "1M" "20480"
  122 
  123   log "*** Testing 2 MB blocks"
  124   write_bench "${path}" "2M" "512"
  125   read_bench  "${path}" "2M" "512"
  126   write_bench "${path}" "2M" "4096"
  127   read_bench  "${path}" "2M" "4096"
  128   write_bench "${path}" "2M" "10240"
  129   read_bench  "${path}" "2M" "10240"
  130 
  131   log "*** Testing 4 MB blocks"
  132   write_bench "${path}" "4M" "256"
  133   read_bench  "${path}" "4M" "256"
  134   write_bench "${path}" "4M" "2048"
  135   read_bench  "${path}" "4M" "2048"
  136   write_bench "${path}" "4M" "5120"
  137   read_bench  "${path}" "4M" "5120"
  138 
  139   log "*** Testing 1 GB blocks"
  140   write_bench "${path}" "1G" "1"
  141   read_bench  "${path}" "1G" "1"
  142   write_bench "${path}" "1G" "8"
  143   read_bench  "${path}" "1G" "8"
  144   write_bench "${path}" "1G" "20"
  145   read_bench  "${path}" "1G" "20"
  146 
  147   # Attempt cleanup only if the destination test path is a file and not a
  148   # device (no sense in trying to remove a device).
  149   if [[ -f "${path}" ]]; then
  150     rm "${path}"
  151   fi
  152 }
  153 
  154 main ${@}

Generated by cgit