.png)
Я допустил глупую ошибку, указав неправильное имя выходного файла при возобновлении работы ddrescue. Вот что произошло:
ddrescue -b 2048 -d -v /dev/sr1 IDTa.img IDTa.ddrescue.log
Затем компьютер завис, и я по ошибке продолжил работу со следующим текстом:
ddrescue -b 2048 -d -v /dev/sr1 IDTa.iso IDTa.ddrescue.log
Я так понимаю, что оба файла изображений изначально будут обнулены, поэтому предполагаю, что если бы я выполнил логическое ИЛИ для обоих файлов, то результат был бы таким, какой вывел бы ddrescue, если бы я не допустил ошибку?
Файлы не являются продолжением друг друга (какКак объединить два образа ddrescue?), поскольку я уже запускал его ddrescue -n
ранее, что завершилось успешно. т. е. IDTa.img содержит большую часть данных, IDTa.iso содержит разбросанные блоки со всего изображения (и эти блоки будут равны нулю в IDTa.img).
Есть ли простой способ CLI сделать это? Я, вероятно, мог бы сделать это на C, но я очень заржавел! Также это может быть хорошим первым упражнением в Python, который я так и не изучил! Тем не менее, не особо хочу изобретать велосипед, если что-то уже существует. Не слишком заморачиваюсь по поводу производительности.
Обновлять:(извините, если это не то место, где можно разместить ответ на ответ. Похоже, опция «комментарий» допускает слишком мало символов, поэтому я отвечу здесь!)
Я также пробовал ddrescue с '--fill-mode=?' как решение вышеизложенного, но это не сработало. Вот что я сделал:
ddrescue --generate-mode -b 2048 -v /dev/sr1 IDTa.img IDTa.img.log
cp IDTa.img IDTa.img.backup
ddrescue '--fill-mode=?' -b 2048 -v IDTa.iso IDTa.img IDTa.img.log
Для проверки я нашел первую позицию, в которой есть данные IDTa.iso:
hexdump -C IDTa.iso |less
результат был следующим:
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
001da800 00 00 01 ba 21 00 79 f3 09 80 10 69 00 00 01 e0 |....!.y....i....|
...
001db000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
...
Я посмотрел 001da800 в IDTa.img:
hexdump -C IDTa.img |less
/001da800
Выход:
001da800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
001db000 00 00 01 ba 21 00 7b 00 bf 80 10 69 00 00 01 e0 |....!.{....i....|
...
Итак, данные в позиции 001da800 не скопировались из файла IDTa.iso в IDTa.img?
Проверка IDTa.img.log:
# Mapfile. Created by GNU ddrescue version 1.22
# Command line: ddrescue --fill-mode=? -b 2048 -v IDTa.iso IDTa.img IDTa.img.log
# Start time: 2021-06-28 13:52:39
# Current time: 2021-06-28 13:52:46
# Finished
# current_pos current_status current_pass
0x299F2000 + 1
# pos size status
0x00000000 0x00008000 ?
0x00008000 0x001D2800 +
0x001DA800 0x00000800 ?
0x001DB000 0x00049000 +
...
и проверка реальности:
diff -q IDTa.img IDTa.img.backup
не возвращает никакой разницы.
Обновление 2:
@Kamil отредактировал решение (см. ниже), удалив --fill-mode=?
аргумент. Кажется, работает!
решение1
Я думаю, это можно сделать с ddrescue
самим собой. Вам нужно --generate-mode
.
При
ddrescue
вызове с опцией--generate-mode
он работает в "режиме генерации", который отличается от "режима спасения" по умолчанию. То есть в "режиме генерации"ddrescue
ничего не спасает. Он только пытается сгенерироватьmapfile
для последующего использования.[…]
ddrescue
может в некоторых случаях генерировать приблизительныйmapfile
, изinfile
и (частичную) копию вoutfile
, которая почти так же хороша, как точнаяmapfile
. Это делается просто путем предположения, что сектора, содержащие все нули, не были спасены.[…]
ddrescue --generate-mode infile outfile mapfile
(источник)
Сделайте копии двух образов, на всякий случай. Если ваша файловая система поддерживает CoW-copy, то используйте cp --reflink=always
для каждого образа, чтобы сделать копии практически мгновенно.
Вам нужно убедиться, что оба изображения имеют одинаковый размер. Если одно из них меньше, то его следует увеличить, т.е. добавить нули (возможно, редкие нули). Этот код сделает это автоматически ( truncate
обязательно):
( f1=IDTa.img
f2=IDTa.iso
s1="$(wc -c <"$f1")"
s2="$(wc -c <"$f2")"
if [ "$s2" -gt "$s1" ]; then
truncate -s "$s2" "$f1"
else
truncate -s "$s1" "$f2"
fi
)
(Я использовал подоболочку, поэтому переменные исчезают вместе с ней, а основная оболочка остается нетронутой.)
Теперь позвольте инструменту проанализировать ваше первое изображение и выяснить, какие сектора, вероятно, не были восстановлены:
ddrescue --generate-mode -b 2048 -v /dev/sr1 IDTa.img new_mapfile
Обратите внимание new_mapfile
, что это новый файл,нетваш IDTa.ddrescue.log
. Не трогай IDTa.ddrescue.log
.
После new_mapfile
генерации строки в нем должны показывать статус +
или ?
, в зависимости от того, считался ли соответствующий фрагмент «спасенным» или «неиспытанным».
Теперь вы хотите заполнить якобы "непроверенный" блок IDTa.img
данными из IDTa.iso
. Следующая команда изменит IDTa.img
.
Спасите якобы «неиспытанный» блок, IDTa.img
прочитав данные из IDTa.iso
:
ddrescue -b 2048 -v IDTa.iso IDTa.img new_mapfile
Теперь измененное IDTa.img
вместе с нетронутым IDTa.ddrescue.log
должно быть так же хорошо, как если бы вы не совершили ошибку.
Примечания:
- Может случиться так, что некоторые сектора, содержащие все нули, были фактически спасены.
--generate-mode
классифицирует их как?
. Они будут заполнены данными, взятыми изIDTa.iso
"напрасно". Это не имеет значения для конечного результата, потому что они все нули и в этом другом файле. - Результат должен быть таким же, если вы поменяете местами
IDTa.iso
иIDTa.img
во всей процедуре (но имейте в виду, если вы сделаете это, то результат будет вIDTa.iso
). Так что есть выбор. С--generate-mode
я бы использовал файл, от которого ожидаю меньше секторов, содержащих все нули, потому что это должно минимизировать объем работы для последней команды. - Метод работает для обычных файлов
IDTa.iso
иIDTa.img
. Если вместо любого из них у вас было блочное устройство, его «случайное» содержимое, оставшееся до начала работы,ddrescue
будет мешать и портить результат (поэтому нет смысла решать потенциальную проблему с разными размерами изначально, гдеtruncate
это не помогает). - Я проверил процедуру, повторив вашу ошибку при попытке спастиненадежное устройство.