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 ${@}
|