Script to find and map bad blocks

mm0nst3r

Dabbler
Joined
Sep 5, 2021
Messages
33
Tired of doing it manually, so here is the contraption. Works great for me.

#!/bin/bash
#
DISC="/dev/sdqy"
LOG="bad-blocks.txt"
LOG1="bad-blocks1.txt"
LOG2="bad-blocks2.txt"
SCRIPT_LOG="log.txt"
BAD_SECTORS="sectors.txt"
#START_FROM in percents in case badblocks stopped
START_FROM=0

> ${SCRIPT_LOG}
> ${LOG}

smartctl -X ${DISC} | tee -a ${SCRIPT_LOG}

echo | tee -a ${SCRIPT_LOG}
date | tee -a ${SCRIPT_LOG}
echo "Starting badblocks scan" | tee -a ${SCRIPT_LOG}
echo ========================== | tee -a ${SCRIPT_LOG}
echo | tee -a ${SCRIPT_LOG}
BLOCKS_COUNT=$(( $(hdparm -g ${DISC} | awk '{print $6}' | awk 'gsub(/,$/,x)') / 8 - 1 ))
MIDDLE_POINT=$(( $BLOCKS_COUNT / 2 ))
MP_INC=$(( 1 + $MIDDLE_POINT ))
START_BLOCK=$(( $BLOCKS_COUNT * $START_FROM / 100 + 500))
if [[ $START_BLOCK > $MP_INC ]]; then MP_INC=$START_BLOCK; fi
if [[ $START_BLOCK -le $MIDDLE_POINT ]]; then badblocks -sv -b 4096 -o ${LOG1} ${DISC} $MIDDLE_POINT $START_BLOCK; fi
badblocks -sv -b 4096 -o ${LOG2} ${DISC} $BLOCKS_COUNT $MP_INC
cat ${LOG1} ${LOG2} >> ${LOG}

date | tee -a ${SCRIPT_LOG}
echo "badblocks scan finished" | tee -a ${SCRIPT_LOG}
echo ========================== | tee -a ${SCRIPT_LOG}
echo | tee -a ${SCRIPT_LOG}

echo "Translating bad blocks to bad sectors"
echo
BLOCKS=$(cat $LOG)
for b in $BLOCKS; do
SECTOR=$(( $b * 8 ))
for (( s=(( $SECTOR-16 )); s <= (( $SECTOR+16 )); s++ )); do
echo "$s" >> "$BAD_SECTORS"
done
done

SECTORS=$(cat $BAD_SECTORS)

for i in $SECTORS; do
echo
echo ===========================
echo "Checking sector $i" | tee -a ${SCRIPT_LOG}
result=`hdparm --read-sector $i ${DISC} 2>&1 | grep "reading sector"`
echo "Got result: ${result}" | tee -a ${SCRIPT_LOG}
echo $result | grep -q "FAILED"
if [ $? -eq 0 ]; then
echo "Bad sector found. Attempting to correct..." | tee -a ${SCRIPT_LOG}
hdparm --yes-i-know-what-i-am-doing --write-sector $i ${DISC}
else
echo "Sector seems okay." | tee -a ${SCRIPT_LOG}
fi
done

echo | tee -a ${SCRIPT_LOG}
echo ========================== | tee -a ${SCRIPT_LOG}
echo "All done" | tee -a ${SCRIPT_LOG}
echo "Initiating SMARTCTL Long scan" | tee -a ${SCRIPT_LOG}
smartctl -t long ${DISC} | tee -a ${SCRIPT_LOG}

Don't forget to run scrub after smartctl is done
 
Last edited:
Top