Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
executable file 236 lines (208 sloc) 5.48 KB
#!/bin/bash
#
# REDEEMER - Hard Disk Drive slaughtering shell script.
# Author: Stefano Enrico Mendola (aka Hyd3L, STE col teschio)
#
# 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/>.
# Operational parameters
CHECK=false
SHUTDOWN=false
NO_SYNC=false
DRY_RUN=false
LAVIANO=false
DD_PATH=dd
# Variables for DRY_RUN
SHUTDOWN_PATH=shutdown
BADBLOCKS_PATH=badblocks
CONV="conv=fsync"
VERSION="1.3"
function tellusage {
echo "usage: $0 [OPTIONS] [DEVICES]"
exit 4
}
# ToDo: some format to specify via command line how many
# zeros/ones/random/urandom passes to do and in which order? (LTP)
function zerofill {
echo "===> Filling $1 with zeros... (pass $2)"
echo $($DD_PATH if=/dev/zero of=$1 status=progress bs=16M $CONV)
#syncdisks
}
function onefill {
echo "===> Filling $1 with ones... (pass $2)"
echo $(tr '\0' '\377' < /dev/zero | $DD_PATH of=$1 status=progress bs=16M $CONV)
#syncdisks
}
function urandomfill {
echo "===> Filling $1 with pseudo-random values... (pass $2)"
echo $($DD_PATH if=/dev/urandom of=$1 status=progress bs=16M $CONV)
#syncdisks
}
function redemption {
echo "===> Redeeming $1 from its sins..."
echo $($DD_PATH if=/dev/zero of=$1 status=progress bs=16M $CONV)
#syncdisks
}
function shutdownifnecessary {
# Shutdown the system at the end of redemption
if $SHUTDOWN; then
echo "===> Shutting down"
echo $( $SHUTDOWN_PATH -h now )
fi
}
# https://stackoverflow.com/a/29754866
getopt --test > /dev/null
if [[ $? -ne 4 ]]; then
echo "error: 'getopt --test' failed in this environment."
exit 1
fi
options=$(getopt --options cslndh --longoptions check,shutdown,laviano,no-sync,dry-run,help --name "$0" -- "$@")
if [[ $? -ne 0 ]]; then
echo "error: getopt failed."
exit 2
fi
# Still https://stackoverflow.com/a/29754866
eval set -- "$options"
# now $1 $2 $... is " -o -p --tions -- /other/parameters"
parameters=""
while true; do
case "$1" in
-c|--check)
CHECK=true
parameters="$parameters $1"
shift
;;
-s|--shutdown)
SHUTDOWN=true
# do not add to $parameters!
shift
;;
-l|--laviano)
LAVIANO=true
parameters="$parameters $1"
shift
;;
-n|--no-sync)
NO_SYNC=true
parameters="$parameters $1"
shift
;;
-d|--dry-run)
DRY_RUN=true
parameters="$parameters $1"
shift
;;
-h|--help)
echo "REDEEMER v${VERSION} - Hard Disk Drive slaughtering shell script."
echo "Author: Stefano Enrico Mendola (aka Hyd3L, STE col teschio)"
echo "Copyright (C) 2017 WeeeOpen - Politecnico di Torino"
echo "This program comes with ABSOLUTELY NO WARRANTY."
echo "Since this is a free software, you are welcome to"
echo "redistribute it under the terms of the GNU GPLv3."; echo
echo "usage: $0 [OPTIONS] [DEVICES]"
echo "options:"
echo " -c --check : execute badblocks before redemption"
echo " -s --shutdown : halt after the end of the redemption."
echo " -l --laviano : execute only a zerofill pass."
echo " -n --no-sync : execute steps without syncing disks."
echo " -d --dry-run : print output only, no write operations."
echo " -h --help : show this screen and quit."
exit
;;
--)
parameters="$parameters $1"
shift
break
;;
*)
echo "error that should never happen"
exit 42
;;
esac
done
if [[ $# -lt 1 ]]; then
tellusage
fi
if $DRY_RUN; then
DD_PATH='echo dd'
SHUTDOWN_PATH='echo shutdown'
BADBLOCKS_PATH='echo badblocks'
fi
if $CHECK; then
if ! which badblocks > /dev/null; then
echo "error: badblocks not found in \$PATH"
exit 3
fi
fi
# Must run as root
if ( !($DRY_RUN) && [[ $EUID -ne 0 ]] ); then
echo "error: You must run $0 as root!"
exit 1
fi
if $NO_SYNC; then
CONV=""
fi
if !($DRY_RUN); then
for hdd in "$@"; do
if ! [[ -b $hdd ]]; then
echo "error: $hdd isn't a valid block device"
exit 5
fi
done
fi
# Execute badblocks before redemption
# This instruction even saves the output of badblocks to
# a file, in order to determine if the disk is ready for
# redemption.
if [[ $# -gt 1 ]]; then
for hdd in "$@"; do
$0 $parameters $hdd &
done
wait
# synchronization point (end parallel execution)
# also, run sync fon completely unrelated reasons
echo "===> Sync all disks"
sync
echo "===> [OK] All jobs completed successfully."
shutdownifnecessary
exit
fi
if $CHECK; then
for hdd in "$@"; do
echo "===> Running badblocks on $hdd"
device=$( echo $hdd | tr -d '/' )
echo $( $BADBLOCKS_PATH -s -o ${device}.out $hdd )
done
echo "===> DONE! [ badblocks $hdd ]"
fi
# Hard Drive Redemption
for hdd in "$@"; do
device=$( echo $hdd | tr -d '/' )
badfile="./${hdd}.out"
if [[ !( -s $badfile ) ]]; then
if $CHECK && !($DRY_RUN); then
rm "${device}.out"
fi
if !($LAVIANO); then
zerofill $hdd 1
onefill $hdd 2
fi
urandomfill $hdd 3
redemption $hdd
echo "===> [OK] $hdd is now clean!"
else
echo "error: $hdd is broken."
echo " Check the file ${device}.out for more details."
fi
done
shutdownifnecessary