Мне нужно было сделать это на VPS, и ни одно из предложенных решений не помогло,
этот ответ помог
Итак, речь идет о чтении случайных данных с диска и оценке времени.
time for i in `seq 1 1000`; do
dd bs=4k if=/dev/sda count=1 skip=$(( $RANDOM * 128 )) >/dev/null 2>&1;
done
вот мои результаты для SSD
real 0m1.375s
user 0m0.285s
sys 0m0.944s
и HDD
real 0m14.249s
user 0m0.752s
sys 0m6.284s
Кажется, я нашел решение своей проблемы. Тем не менее, мне все еще любопытно, может ли кто-нибудь придумать более элегантное решение или, возможно, найти ошибку в моем решении.
Как оказалось, я мог записать на стандартный ввод debugfs
, поэтому мне нужно было только сгенерировать последовательность команд для debugfs
и проанализировать вывод ddrescue
.
Следующий сценарий bash предполагает, что файл с именем mapfile.ddrescue
присутствует в текущем каталоге, созданном ddrescue
.
for line in \
$(cat mapfile.ddrescue | \
grep -e "-$" | \
awk -F" " '{print $1}' | \
awk -F"0x" '{print $2}'); \
do \
position=$(( 16#$line / 512 - 91914240 )); \
result="$result $position"; \
done; \
echo -e "open /dev/sdd3\nicheck $result\nquit\n" | sudo debugfs
Вот что делает этот скрипт:
mapfile
из ddrescue
, который я назвал mapfile.ddrescue
. Ox
. $(...)
, служит входом для цикла for -, поэтому строка всегда будет содержать одну позицию. $((... ))
для математических вычислений позиции, делю позицию на 512 (, например. байт на сектор )и вычесть начало раздела, которое в моем случае равно 91914240
. Это дает позицию в секторах относительно начала раздела. $result
. debugfs
, которую запускаю с помощью sudo. Команда открывает устройство (в моем случае /dev/sdd3
). Затем он запускается icheck
на $result
и завершает работу на debugfs
. Когда я запустил этот скрипт, debugfs
потребовалось много времени, чтобы найти все inodes
для этих блоков, в моем случае он зависал несколько минут, пока не напечатал вывод.
Когда сценарий завершился, я скопировал результат в текстовый файл и проанализировал его. К счастью, большинство секторов указывало на нераспределенные блоки, а остальные указывали на одни и те же несколько inode
номеров. После удаления строк с <block not found>
и удаления дубликатов осталось только четыре inodes
, которые я мог вручную проверить с debugfs
с помощью ncheck
. Это дало мне четыре пути к файлам, это файлы, которые я сейчас попытаюсь восстановить из резервной копии.
Фон Первоначально я начал с dd
и хотел скопировать содержимое SSD на 256 ГБ на SSD большего размера. dd
прервано из-за ошибок ввода-вывода примерно на 45/185 ГБ последнего раздела. Однако с помощью ddrescue
я смог сэкономить 99,99% диска. Наконец, с помощью приведенного выше решения я смог проверить, к каким файлам относятся оставшиеся 1700 КБ или 418 поврежденных областей, и нашел только четыре файла, которые повреждены. Это значительно повысило мое доверие к восстановленным данным, поскольку теперь я знаю, какие файлы повреждены, и могу восстановить их из старой резервной копии.
Мне пришлось сделать это сегодня после того, как моя SD-карта rpi3b+ умерла. В итоге я написал скрипт на python, делающий то же, что вы делали в своем скрипте bash выше, за исключением того, что он автоматически выдает пути к файлам. Посмотреть можно здесь:https://github.com/zkrx/rescue2path
В этом решении я также проверяю наличие -еще не -очищенных фрагментов данных ('/' ). Скрапинг здесь занял очень много времени, и я просто остановился, не успев завершить его.
Эта запись в Arch wiki оказалась особенно полезной:https://wiki.archlinux.org/index.php/Identify_damaged_files