Skip to content

Instantly share code, notes, and snippets.

@jimmygle
Created April 28, 2021 20:10
Show Gist options
  • Save jimmygle/efde6e6601b990fdac60b5b35418110d to your computer and use it in GitHub Desktop.
Save jimmygle/efde6e6601b990fdac60b5b35418110d to your computer and use it in GitHub Desktop.
Facilitate running tests on a drive to verify integrity.
#!/bin/bash
# NOTE: THIS IS A WORK IN PROGRESS
LOG_DIR="~/scripts/logs"
text_header() {
cat <<- EOHT
JIMMYS.TECH DRIVE TESTER KIT
WHAT:
Facilitate running tests on a drive to verify integrity.
Available Tests:
* SMART short test
* SMART long test
* badblocks write/read verification test (data destructive!)
* diskscan read latency test
WHY:
Automate the process of testing a new hard drive's integrity. I want to be
able to plug a drive in via a USB dock and run one command to do all the
tests I want to perform.
Test Rationale:
* SMART short test Quickly determines if any issues are present
* SMART long test Lower level full disk read test
* badblocks write/read Does a full write and verification of every block
* diskscan Helps determine if a drive is close to failure
HOW:
This script is intended to be ran in a bash shell.
Requirements:
* linux (tested on Debian)
* bash (tested on v4)
* badblocks (https://en.wikipedia.org/wiki/Badblocks)
* smartctl (https://en.wikipedia.org/wiki/Smartmontools)
* diskscan (https://github.com/baruch/diskscan)
Usage:
jt-dtester ss <device> Runs (s)MART (s)hort test
Useful for a quick health check of drive
jt-dtester sl <device> Runs (s)MART (l)ong self test
Useful for a full low level read drive check
jt-dtester bb <device> Runs (b)ad(b)locks write/read test
Useful for full write/read verification
Invoked with: "-wsv -b 4096 -o \$LOG_FILE" options
NOTE: This test is data destructive!
jt-dtester ds <device> Runs (d)isk(s)can read latency test
Useful for predicting upcoming disk issues
jt-dtester fi <device> Runs (fi)o mechanical test
Useful for testing the mechanics of the drive
jt-dtester all Runs (all) tests (order: ss, bb, sl, ds)
Recommended for new disks before adding to NAS
Example:
jt-dtester bb /dev/sdf Runs BadBlocks test on /dev/sdf
WHO: Jimmy Gleason <github.com/jimmygle>
RESOURCES:
* Discussion about SMART and badblocks tests:
https://serverfault.com/questions/506281/how-are-smart-selftests-related-to-badblocks
* Discussion about drive testing best practices:
https://www.reddit.com/r/DataHoarder/comments/5et35o/what_tool_do_you_use_to_test_your_new_hard_drives/
TODO:
* Look at implementing fio for testing drive mechanics
https://fio.readthedocs.io/en/latest/fio_doc.html
* Do research to determine which combination of tests is most efficient
* Capture reallocated sectors before and after
* Log the output in a digestible way
EOHT
}
# Replaces drive path slashes with underscores
drive_slug() {
local escaped="${1//\//\_}"
printf "${escaped/_/}"
}
# Runs badblocks tests
# TODO: Verify drive exists
# TODO: Verify drive is not mounted
# TODO: Ask for user confirmation and add a force flag
# TODO: Make block size a parameter
# TODO: Make number of passes a parameter
# TODO: Verify badblocks is installed
badblocks_runner() {
local bb_log_file="$LOG_DIR/$(drive_slug $1)/badblocks"
printf "\nRunning badblocks...\n"
printf "Outputting log to: $bb_log_file\n"
printf "$bb_log_file\n"
# badblocks -wsv -b 4096 -o $bb_log_file $1
}
# Runs short SMART test
# TODO: Verifiy drive exists
# TODO: Verify drive is not mounted? Does this matter?
# TODO: Verify smartctl is installed
smartshort_runner() {
printf "\nRunning SMART short test...\n"
smartctl -t short -C $1
exit 1
}
# Runs long SMART test
# TODO: Verifiy drive exists
# TODO: Verify drive is not mounted? Does this matter?
# TODO: Verify smartctl is installed
smartlong_runner() {
printf "\nRunning SMART long test...\n"
printf "NOT IMPLEMENTED\n"
exit 1
}
# Runs diskscan test
# TODO: Verifiy drive exists
# TODO: Verify drive is not mounted? Does this matter?
# TODO: Verify diskscan is installed
diskscan_runner() {
printf "\nRunning diskscan test...\n"
printf "NOT IMPLEMENTED\n"
exit 1
}
# Runs fio test
# TODO: Implement
fio_runner() {
printf "\nRunning fio test...\n"
printf "NOT IMPLEMENTED\n"
exit 1
}
# Runner - Handles input
case "$1" in
"bb")
badblocks_runner $2
;;
"ss")
smartshort_runner $2
;;
"sl")
smartlong_runner $2
;;
"ds")
diskscan_runner $2
;;
"fi")
fio_runner $2
;;
"all")
printf "\nRunning all tests...\n"
printf "NOT IMPLEMENTED\n"
exit 1
;;
*)
text_header
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment