Мини-HOWTO: Восстановление удаленных файлов с файловой системы Ext2fs в Linux |
---|
Пред. | | След. |
Восстановление блоков данных
Эта часть может быть очень легкой и довольно сложной, в зависимости от того, занимал ли удаленный файл больше 12 блоков или нет.
Короткие файлы
Если файл занимал не больше 12 блоков, то все их номера хранятся непосредственно в inode. Вы можете просмотреть их командой
stat. Более того, debugfs имеет команду, позволяющую восстановить файл автоматически. Например:
debugfs: stat <148003>
Inode: 148003 Type: regular Mode: 0644 Flags: 0x0 Version: 1
User: 503 Group: 100 Size: 6065
File ACL: 0 Directory ACL: 0
Links: 0 Blockcount: 12
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar 5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
594810 594811 594814 594815 594816 594817
TOTAL: 6 |
Файл занимает 6 блоков. Так как 6 меньше 12, даем команду
debugfs записать файл в новое место, например
/mnt/recovered.000:
debugfs: dump <148003> /mnt/recovered.000 |
Также можно это сделать с помощью fsgrab. Пример:
# fsgrab -c 2 -s 594810 /dev/hda5 > /mnt/recovered.000
# fsgrab -c 4 -s 594814 /dev/hda5 >> /mnt/recovered.000 |
В обоих случаях (как debugfs, так и fsgrab) в конце /mnt/recovered.000 будет мусор. Впрочем, это не так уж важно. Самый простой способ убрать его - использовать значение поля Size из inode с ключом bs команды dd:
# dd count=1 if=/mnt/recovered.000 of=/mnt/resized.000 bs=6065 |
Конечно существует вероятность, что один или несколько блоков вашего файла были перезаписаны. Если это так, то вам не повезло - данные этого блока навсегда потеряны.
Длинные файлы
Сложнее обстоит дело с файлами длиной более 12 блоков. Необходимо пояснить, как устроена файловая система UNIX. Данные файла хранятся в так называемых "блоках". Эти блоки пронумерованы. Для каждого файла также имеется "inode" (от английского information node), где хранится информация о владельце, правах, типе файла и т. п. Также как и блоки, inode пронумерованы (хотя нумерация ведется независимо от блоков). Каталоги файловой системы содержат имя файла и номер inode.
Кроме того, для того, чтобы ядро знало, где искать данные, соответствующие элементу каталога (файлу), в inode следующим образом размещается информация о блоках с данными файла:
Номера первых 12 блоков хранятся непосредственно в inode; их еще иногда называют блоками с прямой адресацией (direct blocks).
В inode хранится номер блока, в котором хранятся номера еще 256 блоков данных. Иногда его называют блок косвенной адресации (indirect block).
В inode хранится номер блока, в котором хранятся 256 номеров блоков косвенной адресации. Иногда этот блок называют блоком двойной косвенной адресации (doubly indirect block).
В inode хранится номер блока, в котором хранятся 256 номеров блоков двойной косвенной адресации. Его называют блоком тройной косвенной адресации (triply indirect block).
Прочтите еще раз: я знаю, что это непросто, но также и очень важно.
Версии ядра до 2.0.36 включительно при удалении файла обнуляют блоки косвенной адресации (а также блоки двойной косвенной адресации и т. д.). Так что если ваш файл был длинной более 12 блоков, нет никакой гарантии, что вы сможете выявить даже номера блоков с данными, не говоря уже о самих данных.
Единственный способ, который я нашел - это предположить, что файл не был фрагментирован; если был, то у вас проблемы. Если же предполагать, что файл не был фрагментирован, то, в зависимости от количества блоков с данными файла, возможно следующее расположение блоков, описывающих местоположение файла:
- 0 - 12
Номера блоков хранятся в inode, как описано выше.
- 13 - 268
После блоков с прямой адресацией идет блок косвенной адресации и далее 256 блоков с данными.
- 269 - 65804
Как и в прошлом случае, в начале 12 блоков с прямой адресацией, блок косвенной адресации и 256 блоков данных. Далее блок двойной косвенной адресации, за ним 256 групп блоков, состоящих из одного блока косвенной адресации и 256 блоков данных.
- 65805 и более
Расположение первых 65804 блоков указано выше. Далее один блок тройной косвенной адресации и 256 повторений групп "двойной косвенной адресации". Каждая такая группа состоит из блока двойной косвенной адресации, за которым идет 256 групп из одного блока косвенной адресации и 256 блоков данных.
Даже если номера блоков данных правильны, нет никакой гарантии, что данные
в них не перезаписывались. К тому же, чем больше файл, тем меньше шансов,
что он был записан без фрагментации (кроме некоторых особых случаев).
Заметьте, что я предполагал, что размер вашего блока 1024 байта, так как
это стандартное значение. Если ваши блоки больше, некоторые числа,
указанные выше, изменятся. В частности: так как номер блока занимает 4
байта, то количество номеров блоков, которые могут быть размещены в блоке
косвенной адресации равно размер_блока/4. Так что везде, где выше
встречается число 256, меняйте его на размер_блока/4. Количество требуемых
для размещения файла блоков также нужно изменить.
Пример восстановления длинного файла:
debugfs: stat <1387>
Inode: 148004 Type: regular Mode: 0644 Flags: 0x0 Version: 1
User: 503 Group: 100 Size: 1851347
File ACL: 0 Directory ACL: 0
Links: 0 Blockcount: 3616
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar 5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8583
TOTAL: 14 |
В данном случае шансы того, что файл не фрагментирован, довольно велики: первые 12 блоков, перечисленные в inode, (блоки с данными) идут подряд. Начнем с того, что восстановим их:
# fsgrab -c 12 -s 8314 /dev/hda5 > /mnt/recovered.001 |
Следующий блок указанный в inode (8326) - блок косвенной адресации, который мы можем игнорировать, так как предполагаем, что за ним идут блоки данных (с 8327 по 8582).
# fsgrab -c 256 -s 8327 /dev/hda5 >> /mnt/recovered.001 |
Последний блок, указанный в inode имеет номер 8583. Заметьте, если
предположить, что файл не фрагментирован, то пока все нормально: последний
блок данных, записанный нами имеет номер 8582, то есть 8327 + 255. Блок
8583 - блок двойной косвенной адресации, его можно игнорировать. За ним
идут до 256 групп состоящих из блока косвенной адресации (который мы также
игнорируем), и 256 блоков данных. Быстренько выполнив несложные
арифметические подсчеты, выполняем следующие команды (заметьте, что мы
пропускаем блок двойной косвенной адресации 8583 и следующий за ним (как мы
надеемся) блок косвенной адресации 8584 и начинаем с блока 8525):
# fsgrab -c 256 -s 8585 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 8842 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9099 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9356 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9613 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9870 /dev/hda5 >> /mnt/recovered.001 |
Итого мы записали 12 + (7 * 256) блоков, то есть 1804. В соответствие с
результатом команды "stat" число блоков в файле было равно 3616; считается,
что это блоки длиной 512 байт (пережиток с UNIX), поэтому, в
действительности, нам надо 3616/2 = 1808 блоков длиной 1024 байт. То есть,
нам нужно записать еще четыре блока. Последний записанный блок имел номер
10125. Также, как и раньше, пропускаем блок косвенной адресации (номер 10126)
и записываем последние четыре блока:
# fsgrab -c 4 -s 10127 /dev/hda5 >> /mnt/recovered.001 |
В результате, если нам повезло, то файл полностью восстановлен.
Пред. | Начало | След. |
Получение подробной информации об удаленных inode | | Прямое редактирование inodes |