Created
November 14, 2021 23:52
-
-
Save hackman/e67008769ceee13f28827745ec2204f8 to your computer and use it in GitHub Desktop.
Script to copy data from broken hard drive with DD :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
dst_drive=/dev/sda | |
src_drive=sdd | |
skip_drive=sdb | |
dd_status=/tmp/dd | |
log_file=/tmp/dd.log | |
size_file=/tmp/last_size | |
slot=32:1 | |
reactivate_drive() { | |
while true; do | |
# Firmware state: Online, Spun Up | |
if MegaCli -pdInfo -PhysDrv[$slot] -a0|grep -q 'Online'; then | |
break | |
fi | |
# Foreign State: Foreign | |
if MegaCli -pdInfo -PhysDrv[$slot] -a0|grep -q ': Foreign'; then | |
MegaCli -CfgForeign -Clear -a0 >> $log_file 2>&1 | |
sleep 1 | |
fi | |
# Firmware state: Unconfigured(good), Spun Up | |
if MegaCli -pdInfo -PhysDrv[$slot] -a0|grep -q 'Unconfigured(good)'; then | |
MegaCli -CfgLdAdd -r0[$slot] WT NORA Direct -a0 >> $log_file 2>&1 | |
break | |
fi | |
sleep 2 | |
done | |
} | |
start_copy() { | |
skip_size=0 | |
skip_file_size=0 | |
if [[ -f $size_file ]]; then | |
skip_size=$(<$size_file) | |
skip_file_size=$skip_size | |
fi | |
# Get the last drive name :) | |
src_drive=$(awk '/sd.$/{a=$4}END{print a}' /proc/partitions) | |
if [[ $src_drive =~ sd[ab] ]]; then | |
echo "Wrong drive: $src_drive" | |
return 1 | |
fi | |
if [[ -f $dd_status ]]; then | |
# dd: error reading '/dev/sdd': Input/output error | |
# 2926+1 records in | |
# 2926+1 records out | |
# 30687887360 bytes (31 GB, 29 GiB) copied, 242 s, 127 MB/s | |
# MB/10 because of the bs=10M. So we get the value of the MB copied and then devide it by 10 | |
skip_size=$(awk '/copied/{a=$1}END{a=int(a);a=a/104858;a=int(a);if(a>400){a-=200}else{if(a>200){a-=100}};print a}' $dd_status) | |
skip_size=$(($skip_size + $skip_file_size)) | |
echo $skip_size > $size_file | |
fi | |
echo "dd if=/dev/$src_drive of=$dst_drive bs=10M skip=$skip_size seek=$skip_size> $dd_status 2>&1" >> $log_file | |
dd if=/dev/$src_drive of=$dst_drive bs=10M skip=$skip_size seek=$skip_size > $dd_status 2>&1 | |
dd_code=$? | |
cat $dd_status | |
if [[ $dd_code == 0 ]]; then | |
echo "DD finished successfully" | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
count=0 | |
start=$(date +%s) | |
elapsed_time=0 | |
while true; do | |
let count++ | |
now=$(date +%s) | |
elapsed_time=$(($now - $start)) | |
size=0 | |
if [[ -f $size_file ]]; then | |
size=$(<$size_file) | |
fi | |
printf "%s Starting run %4d - %12d GB copied - elapsed time: %d\n" "$(date +'%d.%b %T')" $count $size $elapsed_time | |
reactivate_drive | |
if start_copy; then | |
break | |
fi | |
sleep 20 | |
done | |
printf "%s Finished in %4d runs. Total time: %d\n" "$(date +'%d.%b %T')" $count $elapsed_time |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment