Skip to content

Instantly share code, notes, and snippets.

@jasontbradshaw
Last active December 13, 2018 05:46
Show Gist options
  • Save jasontbradshaw/3ca8abeee59a961b5b8a to your computer and use it in GitHub Desktop.
Save jasontbradshaw/3ca8abeee59a961b5b8a to your computer and use it in GitHub Desktop.
Hard Drive burn-in script. Useful for testing new drives to make sure they're up-to-snuff, and to prepare them for subsequent full-disk encryption.
#!/usr/bin/env bash
if [ "${EUID}" -ne 0 ]; then
echo "This script must be run as root!" 1>&2
exit 1
fi
# Gets the progress of a running SMART test as a string, or outputs nothing if
# no test is currently running.
function get_smart_progress {
local device="${1}"
smartctl -a "${device}" \
| grep 'of test remaining' \
| sed 's/^[[:blank:]]*//' \
| sed 's/\.$//'
}
# Run a SMART test in offline mode and wait until it's done, printing remaining
# progress every minute.
function smart_test {
local test_name="${1}"
local device="${2}"
smartctl --test="${test_name}" "${device}"
# Wait for the progress remaining to disappear, signaling the end of the test.
local result="Running '${test_name}' SMART test on $(date)"
while [ -n "${result}" ]; do
echo "${result}"
sleep 60
result="$(get_smart_progress "${device}")"
done
}
# Run a succession of SMART tests and badblocks on a device, and output the
# final results when complete.
function burnin {
local device="${1}"
echo
echo "Starting burn-in test for ${device} on $(date)"
echo
echo "Aborting any running SMART tests on ${device}"
smartctl -X "${device}"
echo
echo "Current SMART status for ${device}:"
smartctl -a "${device}"
# This allows FreeBSD systems to overwrite the MBR. It has no effect on Linux,
# which (I presume) allows that by default.
echo
echo "Putting kernel in raw mode"
sysctl kern.geom.debugflags=0x10
echo
smart_test 'short' "${device}"
echo
smart_test 'conveyance' "${device}"
echo
smart_test 'long' "${device}"
# Make double, extra sure the user really meant to overwrite the given device!
if [ "${DESTROY_MY_DATA}" = 'please' ]; then
# This section runs a _destructive_ write/read test on the device,
# exercising its memory cells and attempting to cause an early failure.
echo
echo "Running destructive badblocks test on $(date):"
badblocks -ws "${device}"
else
echo 'Skipping destructive tests. If you want to run them, specify DESTROY_MY_DATA=please.'
fi
echo
smart_test 'long' "${device}"
echo
echo "Burn-in test completed on $(date)"
echo
echo "Final burn-in test results:"
smartctl -a "${device}"
}
if [ -z "${1}" ]; then
echo "A device is required as the first argument."
exit 1
fi
# Run the burn-in and see how long it takes, just for fun.
time burnin "${1}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment