Восстановление данных под Linux

Несколько вступительных слов.

Несмотря на упорное сопротивление некоторых производителей "очень маленького программного обеспечения" :) вкупе с анонимусами с linux.org.ru :) , Linux не спеша, но уверенно занимает места на десктопах пользователей. Как только не отговаривали среднестатистического юзера от знакомства с желтопятым Туксом: и что, мол, Линукс - это ОС для "красноглазых программистов" (и таки правда - Линукс замечательная свободная платформа для разработчика ПО с уймой этих самых средств разработки), что Линукс - это сугубо серверная ОС (и таки да - Линукс отлично зарекомендовал себя и на тяжелых веб-серверах и на примитивных роутерах) и т. д., и т. п. И помимо этого, благодаря усилиям тысяч энтузиастов при поддержке хардверных и софтверных гигантов (один IBM чего стоит), пингвин уверенно взгромоздился на десктоп и в качестве офисного рабочего места, и в качестве игровой машины, и в качестве мультимедийного центра "из коробки". Эта тенденция не может не радовать. Но что может дать Линукс, к примеру, в столь специфической сфере, как восстановление данных с неисправных HDD? Автор, исходя из специфики своей трудовой деятельности :) , решил задаться этим вопросом.

Решив не размениваться на мелочи, автор сразу поставил достаточно сложную и нетривиальную для Линукса задачу: снятие данных исключительно свободными средствами Линукс с сильно забэдовавшегося винчестера Samsung объемом 200 ГБ, на котором, к тому же, было установлено юзер-френдли поделие Microsoft Windows XP. Требование заказчика - скопировать "всего 2 папки с диска D". Текущие симптомы со слов заказчика: Windows не грузится, винчестер долго "чухается"... и ничего не происходит - черный экран. При попытке подключить его к другой исправной машине, установленный на ней Windows грузится минут 20, нещадно шкарябая полудохлым винчестром в попытке что-то там найти и автоматически смонтировать. В результате загрузка таки происходит, в Проводнике виден только один раздел неизвестного размера, который "умный" Виндовз тут же предлагает "дружественно" форматнуть; в PartitionMagic после тугого зависона виден 1 раздел, покрашенный желтым цветом :) "с какой-то там ошибкой" и непотребным размером в 400 гигабайт.

Сейчас последует стандартный отказ от каких-либо гарантий. Автор не отвечает за то, что с правами суперпользователя вы легко можете стереть и свои и чужие данные без какой-либо возможности восстановления. Автор снимает с себя ответственность за то, что вы, не имея опыта, неверно оценили состояние своего или чужого накопителя и добили ему полуживые головы, устроили запилы на поверхностях дисков, дожгли глюкавую плату контроллера винчестера. Автор не несет ответственности за то, что по этим причинам его собратья по восстановлению данных выставили вам круглые счета за работу :) . Как всякий нормальный человек вы конечно же подумали, взвесили все риски и лишь потом приступили к чтению и применению описанного ниже алгоритма. Удачи!

Ну а теперь за работу, товарищи!
В распоряжении автора IBM-PC совместимый компьютер на процессоре AMD Sempron 2800+, установленном в материнскую плату Gigabyte GA-K8NE на логике nForce4-4x. На компьютере установлен совершенно недружественный к пользователю :) , вручную локализованный, Slackware-10.2 (ядро 2.4.32) в полной инсталляции. Из дополнительных программ установлены: ddrescue, dd_rescue, testdisk и, на всякий случай, пакет ntfsprogs и ntfs-3g. Для начала договоримся, что ни в какие иксы мы грузиться не будем и попробуем обойтись даже без mc :) (это по желанию).

Небольшое примечание. У кого нет установленного на HDD Линукса, либо нет желания его устанавливать, может воспользоваться Slackware-based (sic!) LiveCD RIPLinux-2.9 (ядро 2.6.21). В нем уже предустановлены основные нужные нам программы, как то: ddrescue, dd_rescue, testdisk. Единственный минус - не собрана поддержка koi8-r, поэтому кириллический раздел монтировать придется -o nls=utf8 и копировать данные придется уже из-под иксового файл-менеджера, т. к. поддержки utf8 в консоли нет, что, впрочем, не проблема, хоть и идеологически неправильно :) .

Применим профессиональный подход к проблеме. А профессиональный подход подразумевает, что перво-наперво необходимо скопировать проблемный винчестер на исправный и дальнейшие работы вести уже с исправным, дабы глюки и подвисания инвалида не мешали нам. Достанем с полки (приобретем в магазине, одолжим у друзей) накопитель, равный по объему, либо больший, чем проблемный. У нас под рукой случайно :) оказался 500-гигабайтный WD с SATA интерфейсом. Подготовим его к работе. Несмотря на то, что диск-приёмник вроде бы чист, перед началом процесса копирования хорошим тоном считается всё ж гарантированно его очистить с помощью того же dd. Для максимально быстрого стирания выставляем blocksize не менее 16 секторов накопителя, т. е 16*512B=8KB. Можно и больше.

root@rozik3:~# dd if=/dev/zero of=/dev/sda bs=8K

Процесс стирания 500-гигабайтного винта займет около 2-х часов. Пока что можно выйти покурить сигарет, поиграть с компьютером в шахматы, сходить на linux.org.ru пофлеймить :) .

Периодически вводя от рута на втором терминале killall -SIGUSR1 dd наблюдаем на первом ход стирания.

8034929+0 записей считано
8034929+0 записей написано
скопировано 65822138368 байт (66 GB), 832,959 секунд, 79,0 MB/s
52809917+0 записей считано
52809917+0 записей написано
скопировано 432618840064 байт (433 GB), 6286,23 секунд, 68,8 MB/s
#К концу диска, как и полагается, линейная скорость записи несколько уменьшается
dd: запись `/dev/sda': No space left on device
61048324+0 записей считано
61048323+0 записей написано
скопировано 500107862016 байт (500 GB), 7750,36 секунд, 64,5 MB/s

Вот и чудненько. Выключаем компьютер, дабы только теперь подключить инвалида. Включились. БИОС тут же ругнулся на SMART проблемного Samsung'а: что, мол, немедленно сбэкапьтесь, после чего выкиньте его в окошко :) . Сейчас, сейчас. Именно сбэкапиться и хотим :) . Раз даже глупая материнка ругается на СМАРТ, то посмотрим и мы его :) для оценки ситуации.

root@rozik3:~# smartctl -i -A /dev/hdc
smartctl version 5.36 [i486-slackware-linux-gnu] Copyright (C) 2002-6 Bruce Allen
Home page is http://smartmontools.sourceforge.net/

=== START OF INFORMATION SECTION ===
Device Model: SAMSUNG SP2014N
Serial Number: S088J1NL203227
Firmware Version: VC100-33
User Capacity: 200.049.647.616 bytes
Device is: In smartctl database [for details use: -P show]
ATA Version is: 7
ATA Standard is: ATA/ATAPI-7 T13 1532D revision 4a
Local Time is: Tue Sep 18 00:12:19 2007 EEST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
1 Raw_Read_Error_Rate 0x000f 253 099 051 Pre-fail Always - 0
3 Spin_Up_Time 0x0007 038 033 025 Pre-fail Always - 12800
4 Start_Stop_Count 0x0032 100 100 000 Old_age Always - 272
5 Reallocated_Sector_Ct 0x0033 001 001 010 Pre-fail Always FAILING_NOW 32267
7 Seek_Error_Rate 0x000f 253 253 051 Pre-fail Always - 0
8 Seek_Time_Performance 0x0025 253 253 015 Pre-fail Offline - 0
9 Power_On_Half_Minutes 0x0032 097 097 000 Old_age Always - 17476h+42m
10 Spin_Retry_Count 0x0033 253 253 051 Pre-fail Always - 0
11 Calibration_Retry_Count 0x0012 253 002 000 Old_age Always - 0
12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 13
190 Unknown_Attribute 0x0022 166 127 000 Old_age Always - 24
194 Temperature_Celsius 0x0022 166 127 000 Old_age Always - 24
195 Hardware_ECC_Recovered 0x001a 100 100 000 Old_age Always - 1228
196 Reallocated_Event_Count 0x0032 001 001 000 Old_age Always - 32267
197 Current_Pending_Sector 0x0012 253 001 000 Old_age Always - 4294935023
198 Offline_Uncorrectable 0x0030 253 001 000 Old_age Offline - 4294935631
199 UDMA_CRC_Error_Count 0x003e 200 200 000 Old_age Always - 0
200 Multi_Zone_Error_Rate 0x000a 253 253 000 Old_age Always - 0
201 Soft_Read_Error_Rate 0x000a 253 089 000 Old_age Always - 0

Имеем скачущие параметры с ID 1, 197, 198, 201, говорящие о нестабильном чтении и имеющихся дефектах и рухнувший параметр с ID 5, явно говорящий нам, что винчестер щедро просыпал бэдами и полностью забил ремапами G-List.

С помощью fdisk сориентируемся в пространстве, чтоб случайно не потереть что-нибудь не то :) .

root@rozik3:~# fdisk -l

#Это наш чистый накопитель-приемник. На нем ничего нет.
Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sda doesn't contain a valid partition table

#
Это наш инвалид.
#Вместо внятной логической структуры - какое-то месиво - источник желтого цвета в PartitionMagic и 400 ГБ размера.
Disk /dev/hdc: 200.0 GB, 200049647616 bytes
255 heads, 63 sectors/track, 24321 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

This doesn't look like a partition table
Probably you selected the wrong device.

Device Boot Start End Blocks Id System
/dev/hdc1 ? 13578 119522 850995205 72 Unknown
Partition 1 does not end on cylinder boundary.
/dev/hdc2 ? 45382 79243 271987362 74 Unknown
Partition 2 does not end on cylinder boundary.
/dev/hdc3 ? 10499 10499 0 65 Novell Netware 386
Partition 3 does not end on cylinder boundary.
/dev/hdc4 167628 167631 25817+ 0 Empty
Partition 4 does not end on cylinder boundary.

Partition table entries are not in disk order

#
Это, собственно, наш системный винчестер
Disk /dev/hda: 120.0 GB, 120059362816 bytes

Disk /dev/hda: 120.0 GB, 120059362816 bytes
255 heads, 63 sectors/track, 14596 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System
/dev/hda1 1 65 522081 82 Linux swap
/dev/hda2 66 1340 10241437+ 83 Linux
/dev/hda3 * 1341 14468 105450660 7 HPFS/NTFS
/dev/hda4 14469 14596 1028160 c W95 FAT32 (LBA)

Исходя из выданных fdisk'ом имён файлов устройств будем продолжать дальнейшую работу.

Чем же копировать? Вот вопрос. Линукс-гуру настойчиво предлагают не изобретать велосипед и использовать всё тот же dd
root@rozik3:~# dd if=/dev/hdc of=/dev/sda bs=8K conv=noerror,sync
где bs=8K опять же для пущей скорости, noerror не дает вылетать на ошибках, sync дописывает проблемные блоки нулями, чтоб не возникло смещений на приемнике.

На сайте testdisk'а рекомендуют использовать ddrescue в два прохода:
root@rozik3:~# ddrescue -n /dev/hdc /dev/sda samsung200.log
где n - не разбивать на исходном диске проблемные блоки для вычитки, в лог же ведется запись сессии для исключения успешно скопированных секторов из второго прохода:
root@rozik3:~# ddrescue -r 1 /dev/hdc /dev/sda samsung200.log
где -r 1 - однократная попытка чтения дефектного сектора при вычитывании с использованием сохраненного лога.

Хорошие программы, правильные методы. Только, как выяснилось впоследствии, на инвалидном Samsung'е приблизительно на 11-ом ГБ имеет место значительная дефектная зона, где при прямом копировании и вычитке головы начинают терять сервометки с логично вытекающим отсюда стуком. И если оставить винчестер копироваться на ночь, то на утро есть все шансы получить только первые 11 ГБ копии и монотонно стучащий трупик с дохлыми головами. Это нас совершенно не устраивает. Поэтому мы обратимся к не так сильно разрекламированной dd_rescue. Фичности у нее поменее будет, чем у ddrescue - она не умеет обрабатывать лог сессии и каждый запуск будет начинать, как буд-то ничего не происходило. Но реверсное копирование с лихвой перекрывает её недостаточную интеллектуальность и автоматичность. Итак, решено! В данном случае наш выбор - dd_rescue.

Как водится, перед самым стартом на Луну :) покурим хелп на предмет управления звездолетом :) .

root@rozik3:~# dd_rescue -h

dd_rescue Version 1.14, garloff@suse.de, GNU GPL
($Id: dd_rescue.c,v 1.59 2007/08/26 13:42:44 garloff Exp $)
dd_rescue copies data from one file (or block device) to another.
USAGE: dd_rescue [options] infile outfile
Options: -s ipos start position in input file (default=0),
#
начальный сектор на исходном файле-устройстве (по ум.=0)
-S opos start position in output file (def=ipos),
#начальный сектор на результирующем файле-устройстве (по ум.=как на исходном)
-b softbs block size for copy operation (def=65536),
#размер блока при нормальном копировании (по ум.=64 КБ)
-B hardbs fallback block size in case of errs (def=512),
#размер блока при копировании на дефектах (по ум.=512 Б)
-e maxerr exit after maxerr errors (def=0=infinite),
#завершить работу при определенном количестве ошибок (по ум.=0=не завершать)
-m maxxfer maximum amount of data to be transfered (def=0=inf),
#максимальный скопированный объем данных, по достижении которого завершить работу (по ум.=0=не завершать)
-y syncfrq frequency of fsync calls on outfile (def=512*softbs),
#частота вызова fsync для синхронизации результирующего файла с исходным (маленькое значение замедляет работу) (по ум.=каждые 32 МБ)
-l logfile name of a file to log errors and summary to (def=""),
#файл, в который захватывается вывод программы в терминал (полезно для анализа) (по ум.=не создается)
-o bbfile name of a file to log bad blocks numbers (def=""),
#файл, в который пишутся номера дефектных секторов (полезно для анализа) (по ум.=не создается)
-r reverse direction copy (def=forward),
#реверсное копирование (!!!) (по ум.=выключено, копируем вперед)
-t truncate output file (def=no),
#очищать результирующий файл (как это делает dd) (по ум.=не очищать)
-d/D use O_DIRECT for input/output (def=no),
-w abort on Write errors (def=no),
#завершать работу при ошибках записи (по ум.=не завершать)
-a spArse file writing (def=no),
-A Always write blocks, zeroed if err (def=no),
#записывать на приемник нули вместо ошибок (полезно, если не очистили приемник; несколько замедляет копирование на дефектах) (по ум.=не записывать)
-i interactive: ask before overwriting data (def=no),
#интерактивный режим: спрашивать при перезаписи данных (по ум.=отключен)
-f force: skip some sanity checks (def=no),
-p preserve: preserve ownership / perms (def=no),
-q quiet operation,
#
копировать молча
-v verbose operation,
#копировать с максимумом подробностей
-V display version and exit,
#показать версию программы и выйти
-h display this help and exit.
#показать эту справку и выйти
Note: Sizes may be given in units b(=512), k(=1024), M(=1024^2) or G(1024^3) bytes
This program is useful to rescue data in case of I/O errors, because
it does not necessarily abort or truncate the output.

Осмыслив написанное, взлетаем :) .

root@rozik3:~# dd_rescue -v -y 1G -l samsung200.log -o samsung200.bb /dev/hdc /dev/sda
# -v - пусть пишет, что делает; -y 1G - синхронизация раз в гигабайт, иначе тормозит прилично; -l, -o - пусть ведет логи... для истории :)
dd_rescue: (info): about to transfer 0.0 kBytes from /dev/hdc to /dev/sda
dd_rescue: (info): blocksizes: soft 65536, hard 512
dd_rescue: (info): starting positions: in 0.0k, out 0.0k
dd_rescue: (info): Logfile: samsung200.log, Maxerr: 0
dd_rescue: (info): Reverse: no , Trunc: no , interactive: no
dd_rescue: (info): abort on Write errs: no , spArse write: never
dd_rescue: (info): ipos: 2283520.0k, opos: 2283520.0k, xferd: 2283520.0k
errs: 0, errxfer: 0.0k, succxfer: 2283520.0k
+curr.rate: 54010kB/s, avg.rate: 50720kB/s, avg.load: 16.9%
------skip-------
dd_rescue: (info): ipos: 10801400.5k, opos: 10801400.5k, xferd: 10801400.5k
* errs: 449, errxfer: 224.5k, succxfer: 10801176.0k
+curr.rate: 0kB/s, avg.rate: 10586kB/s, avg.load: 3.6%
dd_rescue: (warning): /dev/hdc (10801400.5k): Input/output error!

dd_rescue: (info): ipos: 10801401.0k, opos: 10801401.0k, xferd: 10801401.0k
* errs: 450, errxfer: 225.0k, succxfer: 10801176.0k
+curr.rate: 0kB/s, avg.rate: 10544kB/s, avg.load: 3.6%
dd_rescue: (warning): /dev/hdc (10801401.0k): Input/output error!

dd_rescue: (info): ipos: 10801401.5k, opos: 10801401.5k, xferd: 10801401.5k
* errs: 451, errxfer: 225.5k, succxfer: 10801176.0k
+curr.rate: 0kB/s, avg.rate: 10502kB/s, avg.load: 3.6%
dd_rescue: (warning): /dev/hdc (10801401.5k): Input/output error!

Bad block: 21602803
dd_rescue: (fatal): Caught signal 2 "Interrupt". Exiting!
Summary for /dev/hdc -> /dev/sda:
dd_rescue: (info): ipos: 10801402.0k, opos: 10801402.0k, xferd: 10801402.0k
errs: 452, errxfer: 226.0k, succxfer: 10801176.0k
+curr.rate: 0kB/s, avg.rate: 10461kB/s, avg.load: 3.6%

Вот оно! На 11 гигабайте винт бешено захрюкал и затикал значительно громче, чем на предыдущих дефектах. По Ctrl+C выходим. Теперь будем копировать задом наперед.

root@rozik3:~# dd_rescue -r -v -y 1G -l samsung200.log -o samsung200.bb /dev/hdc /dev/sda
# -r - реверс; логи дописываются
dd_rescue: (info): ipos set to the end: 195360984.0k
dd_rescue: (info): about to transfer 0.0 kBytes from /dev/hdc to /dev/sda
dd_rescue: (info): blocksizes: soft 65536, hard 512
dd_rescue: (info): starting positions: in 195360984.0k, out 195360984.0k
dd_rescue: (info): Logfile: samsung200.log, Maxerr: 0
dd_rescue: (info): Reverse: yes, Trunc: no , interactive: no
dd_rescue: (info): abort on Write errs: no , spArse write: never
dd_rescue: (info): ipos: 195225816.0k, opos: 195225816.0k, xferd: 135168.0k
- errs: 0, errxfer: 0.0k, succxfer: 135168.0k
+curr.rate: 14083kB/s, avg.rate: 14083kB/s, avg.load: 4.3%

И идем спать :) . Начало мы уже получили. Теперь будет вычитываться с конца. Если даже и стукнет на проблемной зоне, то львиную долю копии мы получим. Копирование в реверс идет приблизительно втрое медленней прямого. Так и должно быть :) .

------------------------
Ситуация на утро: dd_rescue прочесал проблемную зону и с 11-ю тысячами ошибок успешно завершил работу:

dd_rescue: (info): ipos 7539736.0k promote to large bs again!
dd_rescue: (info): ipos: 216.0k, opos: 216.0k, xferd: 195360768.0k
- errs: 11016, errxfer: 5508.0k, succxfer: 195355260.0k
+curr.rate: 18205kB/s, avg.rate: 6161kB/s, avg.load: 2.3%
Summary for /dev/hdc -> /dev/sda:
dd_rescue: (info): ipos: 0.0k, opos: 0.0k, xferd: 195360984.0k
- errs: 11016, errxfer: 5508.0k, succxfer: 195355476.0k
+curr.rate: 17705kB/s, avg.rate: 6161kB/s, avg.load: 2.3%

Ура! Выключаем компьютер, отсоединяем инвалида.

Кстати, вполне трезвой мыслью является сделать бэкап посекторной копии уже с живого накопителя. Если есть в запасе еще один винт, то очень нелишне будет это сделать тем же dd.

Включаемся опять. Еще раз запустим fdisk. Может быть в процессе переезда что-то изменилось к лучшему :) ?

root@rozik3:~# fdisk -l

Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

This doesn't look like a partition table
Probably you selected the wrong device.

Device Boot Start End Blocks Id System
/dev/sda1 ? 13578 119522 850995205 72 Unknown
Partition 1 does not end on cylinder boundary.
/dev/sda2 ? 45382 79243 271987362 74 Unknown
Partition 2 does not end on cylinder boundary.
/dev/sda3 ? 10499 10499 0 65 Novell Netware 386
Partition 3 does not end on cylinder boundary.
/dev/sda4 167628 167631 25817+ 0 Empty
Partition 4 does not end on cylinder boundary.

Partition table entries are not in disk order

Disk /dev/hda: 120.0 GB, 120059362816 bytes
255 heads, 63 sectors/track, 14596 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System
/dev/hda1 1 65 522081 82 Linux swap
/dev/hda2 66 1340 10241437+ 83 Linux
/dev/hda3 * 1341 14468 105450660 7 HPFS/NTFS
/dev/hda4 14469 14596 1028160 c W95 FAT32 (LBA)

Всё по-старому. Несмотря на то, что в MBR ничего, похожего на правду не обнаруживается, на всякий случай бекапим её.

root@rozik3:~# dd if=/dev/sda of=samsung200.mbr.old count=1
1+0 записей считано
1+0 записей написано
скопировано 512 байт (512 B), 0,000281 секунд, 1,8 MB/s

Запускаем testdisk. Хоть он и консольный, но обладает интуитивно понятным интерфейсом с кнопками и менюшками :) .

root@rozik3:~# testdisk
TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org
Please wait...

После чего вылезает менюшка с выбором устройств:

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

TestDisk is free software, and
comes with ABSOLUTELY NO WARRANTY.

Select a media (use Arrow keys, then press Enter):
Disk /dev/hda - 120 GB / 111 GiB
Disk /dev/sda - 500 GB / 465 GiB

[Proceed ] [ Quit ]

Note: Disk capacity must be correctly detected for a successful recovery.
If a disk listed above has incorrect size, check HD jumper settings, BIOS
detection, and install the latest OS patches and disk drivers.

Выбираем стрелками на клавиатуре нужный девайс /dev/sda и жмем Proceed

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/sda - 500 GB / 465 GiB

Please select the partition table type, press Enter when done.
[Intel ] Intel/PC partition
[Mac ] Apple partition map
[None ] Non partioned media
[Sun ] Sun Solaris partition
[XBox ] XBox partition
[Return ] Return to disk selection

Note: Do NOT select 'None' for media with only a single partition. It's very
rare for a drive to be 'Non-partitioned'.

Несмотря на то, что у нас AMD :) , выбираем Intel

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/sda - 500 GB / 465 GiB - CHS 60801 255 63

[ Analyse ] Analyse current partition structure and search for lost partitions
[ Advanced ] Filesystem Utils
[ Geometry ] Change disk geometry
[ Options ] Modify options
[ MBR Code ] Write TestDisk MBR code to first sector
[ Delete ] Delete all data in the partition table
[ Quit ] Return to disk selection

Note: Correct disk geometry is required for a successful recovery. 'Analyse'
process may give some warnings if it thinks the logical geometry is mismatched.

Жмем Analyse

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/sda - 500 GB / 465 GiB - CHS 60801 255 63
Current partition structure:
Partition Start End Size in sectors
1 * Sys=72 13577 238 11 119521 238 60 1701990410

Bad relative sector.
2 * Sys=74 45381 70 3 79242 34 29 543974724

Bad relative sector.
3 * NetWare 3.11+ 10498 56 41 10498 56 40 0

Bad relative sector.
Only one partition must be bootable
Space conflict between the following two partitions
1 * Sys=72 13577 238 11 119521 238 60 1701990410
2 * Sys=74 45381 70 3 79242 34 29 543974724

*=Primary bootable P=Primary L=Logical E=Extended D=Deleted

[Proceed ] [ Save ]
Try to locate partition

По результатам анализов наблюдаем то же безобразие, что и выдал нам fdisk. Жмем Proceed, дабы попытаться обнаружить живые разделы.

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/sda - 500 GB / 465 GiB - CHS 60801 255 63
Partition Start End Size in sectors
* HPFS - NTFS 0 1 1 5182 254 63 83264832 [WIN_XP]
L HPFS - NTFS 5183 1 1 24320 254 63 307451907 [ARCHIVE]

Structure: Ok. Use Up/Down Arrow keys to select partition.
Use Left/Right Arrow keys to CHANGE partition characteristics:
*=Primary bootable P=Primary L=Logical E=Extended D=Deleted
Keys A: add partition, L: load backup, T: change type, P: list files,
Enter: to continue
NTFS, 42 GB / 39 GiB

Жмем Enter

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/sda - 500 GB / 465 GiB - CHS 60801 255 63

Partition Start End Size in sectors
1 * HPFS - NTFS 0 1 1 5182 254 63 83264832 [WIN_XP]
2 E extended LBA 5183 0 1 24320 254 63 307451970
5 L HPFS - NTFS 5183 1 1 24320 254 63 307451907 [ARCHIVE]

[ Quit ] [Search! ] [ Write ] [Extd Part]
Return to main menu

По оставшимся в живых бутсекторам testdisk обнаружил разделы. На этом можно было бы, нажав Write, и завершить, тем более, что со слов заказчика размеры найденных разделов совпадают с предполагаемыми размерами утерянных. Но в целях повышения эрудиции пройдем всю цепочку до конца. Выбираем всё ж таки Search!

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/sda - 500 GB / 465 GiB - CHS 60801 255 63
Partition Start End Size in sectors
D HPFS - NTFS 0 1 1 2233 254 63 35889147
D HPFS - NTFS 0 1 1 5182 254 63 83264832 [WIN_XP]
D HPFS - NTFS 0 1 32 5182 254 63 83264801
D HPFS - NTFS 2234 1 1 21371 254 63 307451907 [ARCHIVE]
D HPFS - NTFS 5183 1 1 24320 254 63 307451907 [ARCHIVE]

Structure: Ok. Use Up/Down Arrow keys to select partition.
Use Left/Right Arrow keys to CHANGE partition characteristics:
*=Primary bootable P=Primary L=Logical E=Extended D=Deleted
Keys A: add partition, L: load backup, T: change type, P: list files,
Enter: to continue
NTFS, 42 GB / 39 GiB

Обнаружены записи о некоторых разделах, оставшихся, по-видимому, от предыдущей установки винды. Пораскинув мозгами, стрелками на клавиатуре выбираем интересующие нас разделы и в соответсвии с (выделенной мною) подсказкой внизу обозначаем их.

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/sda - 500 GB / 465 GiB - CHS 60801 255 63
Partition Start End Size in sectors
D HPFS - NTFS 0 1 1 2233 254 63 35889147
* HPFS - NTFS 0 1 1 5182 254 63 83264832 [WIN_XP]
D HPFS - NTFS 0 1 32 5182 254 63 83264801
D HPFS - NTFS 2234 1 1 21371 254 63 307451907 [ARCHIVE]
L HPFS - NTFS 5183 1 1 24320 254 63 307451907 [ARCHIVE]

Structure: Ok. Use Up/Down Arrow keys to select partition.
Use Left/Right Arrow keys to CHANGE partition characteristics:
*=Primary bootable P=Primary L=Logical E=Extended D=Deleted
Keys A: add partition, L: load backup, T: change type, P: list files,
Enter: to continue
NTFS, 157 GB / 146 GiB

Жмем Enter.

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/sda - 500 GB / 465 GiB - CHS 60801 255 63

Partition Start End Size in sectors
1 * HPFS - NTFS 0 1 1 5182 254 63 83264832 [WIN_XP]
2 E extended LBA 5183 0 1 24320 254 63 307451970
5 L HPFS - NTFS 5183 1 1 24320 254 63 307451907 [ARCHIVE]

[ Quit ] [ Write ] [Extd Part]
Write partition structure to disk

Testdisk вывел структуру PT, которую нам предстоит записать в MBR. Write!

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Write partition table, confirm ? (Y/N)

Нас в последний раз спрашивают, хорошо ли мы подумали? Да, то есть Y.

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

You will have to reboot for the change to take effect.

[Ok]

Чтобы всё заработало, надо будет перезагрузиться. Жмем OK. Выходим на уровень вверх.

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org


Disk /dev/sda - 500 GB / 465 GiB - CHS 60801 255 63

[ Analyse ] Analyse current partition structure and search for lost partitions
[ Advanced ] Filesystem Utils
[ Geometry ] Change disk geometry
[ Options ] Modify options
[ MBR Code ] Write TestDisk MBR code to first sector
[ Delete ] Delete all data in the partition table
[ Quit ] Return to disk selection

Note: Correct disk geometry is required for a successful recovery. 'Analyse'
process may give some warnings if it thinks the logical geometry is mismatched.

Жмем Quit.

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

TestDisk is free software, and
comes with ABSOLUTELY NO WARRANTY.

Select a media (use Arrow keys, then press Enter):
Disk /dev/hda - 120 GB / 111 GiB
Disk /dev/sda - 500 GB / 465 GiB

[Proceed ] [ Quit ]

Note: Disk capacity must be correctly detected for a successful recovery.
If a disk listed above has incorrect size, check HD jumper settings, BIOS
detection, and install the latest OS patches and disk drivers.

Quit program

И еще раз Quit.

TestDisk exited normally.
You have to reboot for the change to take effect.
root@rozik3:~# reboot

Перезагружаемся... Еще раз ориентируемся на местности:

root@rozik3:~# fdisk -l

Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System
/dev/sda1 * 1 2234 17944573+ 7 HPFS/NTFS
/dev/sda2 2235 21372 153725985 f W95 Ext'd (LBA)
/dev/sda5 2235 21372 153725953+ 7 HPFS/NTFS

Disk /dev/hda: 120.0 GB, 120059362816 bytes
255 heads, 63 sectors/track, 14596 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System
/dev/hda1 1 65 522081 82 Linux swap
/dev/hda2 66 1340 10241437+ 83 Linux
/dev/hda3 * 1341 14468 105450660 7 HPFS/NTFS
/dev/hda4 14469 14596 1028160 c W95 FAT32 (LBA)

Похоже на правду. Нам нужен /dev/sda5 - там лежат каталоги, нужные заказчику. Пробуем смонтировать /dev/sda5, не забывая, что раздел виндовый, и юзер обыкновенный не брезгует кириллицей в именах каталогов, поэтому:

root@rozik3:~# mount -o iocharset=koi8-r /dev/sda5 /mnt/hd

Mount не ругается. Наши шансы стремительно растут :)

root@rozik3:~# cd /mnt/hd
root@rozik3:/mnt/hd# ls
Book/ GAMES/ Install/ Office 2003/ RECYCLER/ WindowsXP/ Хранение документов/
Film/ ImageDrive/ Music/ Pictures/ System Volume Information/ ДОКУМЕНТАЦИЯ/

Yes!

root@rozik3:/mnt/hd# cp -R ДОКУМЕНТАЦИЯ /root
root@rozik3:/mnt/hd# cp -R Хранение документов /root

Собственно, всё :) .

Итоги или послесловие.
Можно было бы возрадоваться успеху свободного ПО в деле датарековери на неродном для Линукса поле боя, но на всякую цистерну мёда найдется своё ведро дёгтя :) . Мы недаром вели логи копирования. Впоследствии, при изучении логов мы увидели, что львиная доля дефектов на исследуемом накопителе пришлась на системный раздел, в том числе крепко досталось и MFT. Все попытки ради эксперимента смонтировать или фиксануть /dev/sda1 окончились неуспехом с соответствующими пожеланиями :) используемых в этом нелегком деле программ.

root@rozik3:~# mount -o iocharset=koi8-r /dev/sda1 /mnt/hd
mount: wrong fs type, bad option, bad superblock on /dev/sda1,
missing codepage or other error
In some cases useful info is found in syslog - try
dmesg | tail or so

root@rozik3:~# ntfs-3g /dev/sda1 /mnt/hd -o force
Failed to load $MFT: Input/output error
Failed to startup volume: Input/output error
Failed to mount '/dev/sda1': Input/output error
NTFS is inconsistent. Run chkdsk /f on Windows then reboot it TWICE!
The usage of the /f parameter is very IMPORTANT! No modification was
made to NTFS by this software.

root@rozik3:~# ntfsfix /dev/sda1
Mounting volume... Failed to load $MFT : Input/output error
Failed to startup volume : Input/output error
FAILED
Attempting to correct errors... Failed to load $MFT : Input/output error
FAILED
Failed to startup volume : Input/output error
Volume is corrupt.
You should run chkdsk.

Использование же обычного chkdsk уже в "самой дружественной ОС" восстановило валидность раздела и дало доступ к большинству файлов с остальными пользовательскими данными (системные файлы в таких ситуациях зачастую повреждаются, но и ценности они особой не представляют), даже без применения сторонней датарековери проприетарщины.

Не следует забывать, что в нашей ситуации копировщики работают через системные драйверы того же IDE-контроллера хоста с включенным на всю катушку UDMA, что в данной ситуации зачастую ведет к неправильной интерпретации зависаний или таймаутов дефектного накопителя как однозначных ошибок. Что и подтверждается сравнительным копированием платным копировщиком, написанным для DOS, работающим непосредственно через порты IDE-контроллера хоста и использующим свои алгоритмы управления скоростью копирования (в том числе и в UDMA режимах) и вычитыванием. Платный копировщик дал вчетверо меньше ошибок. Кроме того, автор ничего не знает о средствах первичной диагностики винчестеров под Линукс, способных выводить карту диска или хотя бы график чтения, аналогичных тем же MHDD, Victoria и Vivard для DOS. Поэтому в описанном случае пришлось опираться сугубо на значения SMART-атрибутов и собственный опыт и вносить корректировки в процесс снятия данных уже по ходу работы, что в отдельных случаях может быть довольно рискованным.

Тем не менее, в завершение, хочется с удовлетворением отметить, что, в отличие от "дружественной ОС" под котрую и за деньги мало чего надёшь путного, для Линукса существуют мощные, явно написанные со знанием дела, открытые и свободные приложения, способные бороться с весьма тяжелыми физповреждениями накопителей, а также софт с быстрыми и грамотно разработанными алгоритмами поиска утерянных первичных логических стуктур накопителей, вовсе не являющихся нативными для Линукс.

Автор не ставил перед собой задачи показать, что под Линуксом можно "рубать капусту" :) (хотя мы предметно увидели, что и это возможно :) ) , а хотел поделиться с сообществом себе подобных :) некоторыми наработками в правильном профессиональном подходе к восстановлению данных и показать, что в Линуксе RIP значит вовсе не Rest In Peace, а Recovery Is Possible :) !

Обновлено: 13.03.2015