summaryrefslogtreecommitdiff
path: root/dd-bench.sh
diff options
context:
space:
mode:
authorAaron Ball <nullspoon@iohq.net>2015-09-25 11:47:43 -0600
committerAaron Ball <nullspoon@iohq.net>2015-09-25 11:47:43 -0600
commitfbb342373fff256ac668e1044294568745e77b96 (patch)
tree7bab52f465f1baf99fd4b8c5afc3f46c4dbc3a12 /dd-bench.sh
downloaddd-bench-fbb342373fff256ac668e1044294568745e77b96.tar.gz
dd-bench-fbb342373fff256ac668e1044294568745e77b96.tar.xz
Initial commit of dd-bench and license
Diffstat (limited to 'dd-bench.sh')
-rwxr-xr-xdd-bench.sh153
1 files changed, 153 insertions, 0 deletions
diff --git a/dd-bench.sh b/dd-bench.sh
new file mode 100755
index 0000000..7ce79f0
--- /dev/null
+++ b/dd-bench.sh
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+
+#
+# Dd-bench uses dd with various linux devices to benchmark storage io.
+# Copyright (C) 2015 Aaron Ball <nullspoon@iohq.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+#
+# A simple logging function. Prints a pre-defined timestamped and formatted log
+# entry.
+#
+# @param msg The log message
+#
+function log {
+ msg=${1}
+ ts=$(date '+%h %d %H:%M:%S')
+ echo -e "${ts}: ${1}"
+}
+
+
+#
+# Performs a read test, reading from the specified file and writing to
+# /dev/null to avoid as many bottlenecks as possible
+#
+# @param dest Path to read data from
+# @param bs Block size
+# @param count Number of blocks to write
+#
+function read_bench {
+ src="${1}"
+ bs="${2}"
+ count="${3}"
+
+ dest="/dev/zero"
+
+ out=$(dd if=${src} of=${dest} iflag=direct bs=${bs} count=${count} 2>&1 | grep -v records)
+ # Parse out total data
+ total=$(echo ${out} | sed 's/.*(\(.*B\)).*/\1/')
+ speed=$(echo ${out} | sed 's/.*, \(.*B\/s\)/\1/')
+
+ log "Read ${bs} ${count} times. ${total} read at ${speed}."
+}
+
+
+#
+# Performs a write test, reading from /dev/zero to avoid any problems with cpu
+# bottlenecks.
+#
+# @param dest Path to write the temp file (be sure you have enough space)
+# @param bs Block size
+# @param count Number of blocks to write
+#
+function write_bench {
+ dest="${1}"
+ bs="${2}"
+ count="${3}"
+
+ src="/dev/zero"
+
+ out=$(dd if=${src} of=${dest} oflag=direct bs=${bs} count=${count} 2>&1 | grep -v records)
+ # Parse out total data
+ total=$(echo ${out} | sed 's/.*(\(.*B\)).*/\1/')
+ speed=$(echo ${out} | sed 's/.*, \(.*B\/s\)/\1/')
+
+ log "Wrote ${bs} ${count} times. ${total} written at ${speed}."
+}
+
+
+function main {
+ if [[ -z "${1}" ]]; then
+ echo "Please specify the path to a file to write tests to."
+ echo "Note that this will overwrite that file, so one that doesn't exist is"
+ echo "preferable."
+ exit 1
+ fi
+
+ # Warn the user
+ echo "This script will write up to 20 GB of data before it's done"
+ echo "benchmarking. Be sure you have that much storage to spare on the disk"
+ echo -e "being benchmarked.\n"
+ wait=5
+ echo -e "Proceeding with benchmark in ${wait} seconds...\n\n"
+ sleep ${wait}
+
+ echo -e "Benchmark started at $(date)\n"
+
+ path=${1}
+
+ # Perform benchmark tests
+ log "*** Testing 1 MB blocks"
+ write_bench "${path}" "1M" "1024"
+ read_bench "${path}" "1M" "1024"
+ write_bench "${path}" "1M" "8192"
+ read_bench "${path}" "1M" "8192"
+ write_bench "${path}" "1M" "20480"
+ read_bench "${path}" "1M" "20480"
+
+ log "*** Testing 2 MB blocks"
+ write_bench "${path}" "2M" "512"
+ read_bench "${path}" "2M" "512"
+ write_bench "${path}" "2M" "4096"
+ read_bench "${path}" "2M" "4096"
+ write_bench "${path}" "2M" "10240"
+ read_bench "${path}" "2M" "10240"
+
+ log "*** Testing 4 MB blocks"
+ write_bench "${path}" "4M" "256"
+ read_bench "${path}" "4M" "256"
+ write_bench "${path}" "4M" "2048"
+ read_bench "${path}" "4M" "2048"
+ write_bench "${path}" "4M" "5120"
+ read_bench "${path}" "4M" "5120"
+
+ log "*** Testing 1 GB blocks"
+ write_bench "${path}" "1G" "1"
+ read_bench "${path}" "1G" "1"
+ write_bench "${path}" "1G" "8"
+ read_bench "${path}" "1G" "8"
+ write_bench "${path}" "1G" "20"
+ read_bench "${path}" "1G" "20"
+
+ # Note that the 1KB block tests write 10 and 80 megabyte files rather than
+ # the previous 1G, 8G, etc due to the speed of the typical 1KB block size
+ # test. Also note that the 200 MB test is skipped because it takes far too
+ # long.
+ log "*** Testing 1 KB blocks"
+ write_bench "${path}" "1K" "10240"
+ read_bench "${path}" "1K" "10240"
+ write_bench "${path}" "1K" "81920"
+ read_bench "${path}" "1K" "81920"
+
+ # Attempt cleanup only if the destination test path is a file and not a
+ # device (no sense in trying to remove a device).
+ if [[ -f "${path}" ]]; then
+ rm "${path}"
+ fi
+}
+
+main ${@}

Generated by cgit