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

Оригинал статьи расположен на сервере: Восстановление данных R.LAB

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

Несмотря на упорное сопротивление некоторых производителей "очень маленького программного обеспечения" :) вкупе с анонимусами с 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 (ядро .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'ом имён файлов устройств будем продолжать дальнейшую работу.

Чем же копировать? Вот вопрос. Линукс-гуру настойчиво предлагают не изобретать велосипед и использовать всё тот же

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 
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 
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 
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 
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 
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 
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 
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 
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 
http://www.cgsecurity.org

Write partition table, confirm ? (Y/N)

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

TestDisk 6.3, Data Recovery Utility, March 2006
Christophe GRENIER 
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 
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 
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 :) !

Виталий Розизнаный AKA Rozik специально для rlab.ru


Перепечатка или цитирование разрешены при условии указания ссылки вида Восстановление данных R.LAB на первоисточник.