blob: 7ce79f06a77757a2651e89856bb19326d8832d11 (
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 log "*** Testing 1 MB blocks"
105 write_bench "${path}" "1M" "1024"
106 read_bench "${path}" "1M" "1024"
107 write_bench "${path}" "1M" "8192"
108 read_bench "${path}" "1M" "8192"
109 write_bench "${path}" "1M" "20480"
110 read_bench "${path}" "1M" "20480"
111
112 log "*** Testing 2 MB blocks"
113 write_bench "${path}" "2M" "512"
114 read_bench "${path}" "2M" "512"
115 write_bench "${path}" "2M" "4096"
116 read_bench "${path}" "2M" "4096"
117 write_bench "${path}" "2M" "10240"
118 read_bench "${path}" "2M" "10240"
119
120 log "*** Testing 4 MB blocks"
121 write_bench "${path}" "4M" "256"
122 read_bench "${path}" "4M" "256"
123 write_bench "${path}" "4M" "2048"
124 read_bench "${path}" "4M" "2048"
125 write_bench "${path}" "4M" "5120"
126 read_bench "${path}" "4M" "5120"
127
128 log "*** Testing 1 GB blocks"
129 write_bench "${path}" "1G" "1"
130 read_bench "${path}" "1G" "1"
131 write_bench "${path}" "1G" "8"
132 read_bench "${path}" "1G" "8"
133 write_bench "${path}" "1G" "20"
134 read_bench "${path}" "1G" "20"
135
136 # Note that the 1KB block tests write 10 and 80 megabyte files rather than
137 # the previous 1G, 8G, etc due to the speed of the typical 1KB block size
138 # test. Also note that the 200 MB test is skipped because it takes far too
139 # long.
140 log "*** Testing 1 KB blocks"
141 write_bench "${path}" "1K" "10240"
142 read_bench "${path}" "1K" "10240"
143 write_bench "${path}" "1K" "81920"
144 read_bench "${path}" "1K" "81920"
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 ${@}
|