При непреднамеренном удалении важных файлов незамедлительное отмонтирование раздела или хотя бы его перемонтирование в режим "только для чтения" командой
```
mount -о remount, ro /dev/partition
```
может сыграть решающую роль при спасении ваших данных!
В целом стратегия восстановления выглядит приблизительно так: сканируем таблицу индексных дескрипторов (inode tаblе) и отбираем все записи, у которых поле i_links_count равно нулю. Сортируем их по дате удаления, чтобы файлы, удаленные последними, оказались в верхних позициях списка. Как вариант, если вы помните примерное время удаления файла, можно просто наложить фильтр. Если соответствующие индексные дескрипторы еще не затерты вновь создаваемыми файлами, извлекаем список прямых/косвенных блоков и записываем их в дамп, корректируя его размер с учетом "логического" размера файла, за который отвечает поле i_size.
В ехtЗ при удалении файла ссьmка на inode уже не уничтожается, что упрощает автоматическое восстановление оригинальных имен. Тем не менее поводов для радости у нас нет, поскольку в extЗfs перед удалением файла список принадлежащих ему блоков тщательно вычищается. Нефрагменгированные файлы с более или менее осмысленным содержимым (например, исходные тексты программ) еще можно собрать по частям, но и времени на это потребуется немало. К счастью, блоки косвенной адресации не очищаются, а это значит, что мы теряем лишь первые 12 * в1ocк_srzE байт каждого файла. На типичном разделе объемом около
10 Гбайт значение в1ocк_SIZE обычно равно 4 или 8 Кбайт, т. е. реальные потери составляют менее 100 Кбайт. По современным понятиям, это сущие пустяки! Ко нечно, без этих 100 Кбайт большинство файлов просто не запустятся, однако найти на диске двенадцать недостающих блоков - вполне реальная задача. Если повезет, они окажутся расположенными в одном или двух непрерывных отрезках, но такое везение не гаранrируется. Тем не менее непрерывные отрезки из 6-12 блоков достаточно часто встречаются даже на сильно фраrменгированных разделах.
Как мы будем действовать? Необходимо найти хотя бы один блок, гарантирован но принадлежащий файлу и при этом расположенный за границей в 100 Кбайт от его начала. Это может бьпь текстовая строка, информация об авторских правах разработчика или любая другая характерная информация! Короче говоря, нам ну жен номер блока. Пусть для определенности он будет равен Ох1234. Записываем его в обратном порядке так, чтобы младший байт располагался по меньшему адресу, и выполняем поиск 34h 12h 00h 00h - именно это число будет присутствовать в косвенном блоке. Оrличить косвенный блок от всех остальных блоков (например, блоков, принадлежащих файлам данных) очень легко - он представляет собой массив 32-битовых номеров блоков, более или менее монотонно возрастающих. Блоки с двойной и тройной косвенной адресацией отыскиваются по аналогичной схеме.
Проблема состоит в том, что одни и те же блоки в разное время могли принадле жать различным файлам, а это значит, что они могли принадлежать и различным косвенным блокам. Как разобраться, какой из найденных блоков является иско мым? Да очень просто! Если хотя бы одна из ссылок косвенного блока указывает на уже занятый блок, данный косвенный блок принадлежит давно удаленному фай лу и, следовательно, не представляет для нас ингереса.
По правде говоря, debugfs обеспечивает лишь ограниченную поддержку extЗfs. В частности, команда lsdel всегда показывает отсутствие удаленных файлов, даже если удалить весь раздел. По этой причине вопрос выбора файловой системы отmодь не так прост, каким его пытаются представить некоторые руководства по Linux для начинающих. Преимущества extЗfs на рабочих станциях и домашних компьютерах далеко не бесспорны и совсем не очевидны. Поддержка транзакций реально требуется лишь серверам, да и то не всем, а вот невозможность восстанов ления ошибочно удаленных файлов зачастую приносит большие убытки, чем устойчивость файловой системы к внезапным отказам питания.
### Восстановление с помощью отладчика файловой системы debugfs
Загружаем в отладчик редактируемый раздел или его копию. Сделать это можно с помощью команд debugfs /dev/sdЫ или debugfs my_dump соответственно. Если мы планируем осуществлять запись на диск, то необходимо указать ключ -w: debugfs -w my_dшnp или debugfs -w /dev/sdЬl.
Чтобы просмотреть список удаленных файлов, подаем команду lsdel (или lsdel t_sec, где t_sec- количество секунд, истекших с момента удаления файла). На экране появится список удаленных файлов (разумеется, без имен). Файлы, удален
ные более t_sec секунд назад (если эта опция задана), в данный список не попадут.
Команда cat выводит содержимое текстового файла на терминал. Здесь - номер inode, заключенный в угловые скобки. При выводе двоичных файлов разо брать смысл отображаемой на экране информации практически невозможно. Такие файлы должны сбрасываться в дамп командой dшnp new_file_name, где new_file_name- новое имя файла (с путем), под которым он будет записан в фай ловую систему, из-под которой бьш запущен отладчик debugfs. Файловая система восстанавливаемого раздела при этом остается неприкосновенной. Иными словами, команда должна даваться без ключа --w.
При желании можно восстановить файл непосредственно на самой восстанавли ваемой файловой системе (что особенно удобно при восстановлении больших фай лов). В этом нам поможет команда undel undel_file_name, где undel file пате - имя, которое будет присвоено файлу после восстановления.
ВНИМАНИЕ/
Выполняя такую операцию, помните, что команда undel крайне "агрессивна" и дест руктивна по своей природе. Она затирает первую свободную запись в таблице катало гов, делая восстановление оригинальных имен невозможным.
Команда stat отображает содержимое inode в удобочитаемом виде, а команда mi позволяет редактировать его по своему усмотрению. Для ручного восста новления файла (откровенно говоря, этого не пожелаешь и врагу) мы должны уста новить счетчик ссьшок (link count) на единицу, а время удаления (deletion time), наоборот, сбросить в нуль. Затем отдать команду seti помечающую данный inodeкакиспользуемый,идлякаждогоизблоковфайлавыполнитькомандуsetb х, где х- номер блока.
СОВЕТ
Перечень блоков, занимаемых файлом, можно просмотреть с помощью команды stat.
Остается только дать файлу имя, что осуществляется путем создания ссылки на ка талог (directory link). Сделать это можно с помощью команды ln undel_file_ пате, где undel_file_name- имя, которое будет дано файлу после восстановления (при необходимости имя восстанавливаемого файла указывается с полным путем).
ВНИМАНИЕ
Создание ссылок на каталог необратимо затирает оригинальные имена удаленных
файлов.
После присвоения имени восстановленному файлу полезно задать команду dirty, чтобы файловая система была автоматически проверена при следующей загрузке. Как вариант, можно выйти из отладчика и вручную запустить команду fsck с клю чом -f, форсирующим проверку.
Теперь перейдем к восстановлению оригинального имени. Рассмотрим простейший случай, когда каталог, содержащий удаленный файл (также называемый родитель ским каталогом), все еще цел. В этом случае следует подать команду stat dir_name и запомнить номер inode, возвращенный этой командой. Затем нужно задать отлад чику команду dump <INODE> dir_file, где INODE- номер сообщенного индексного дескриптора, а dir_file - имя файла "родной" файловой системы, в которую будет записан дамп. Полученный дамп следует загрузить в шестнадцатеричный редактор и просмотреть его содержимое в "сыром" виде. Все имена будут там. При желании можно написать утилиту-фильтр, выводящую только удаленные имена. На Perl это не займет и десяти минут.
А как быть, если родительский каталог тоже удален? В этом случае и он будет по мечен как удаленный! Выводим список удаленных индексных дескрипторов, выби раем из этого списка каталоги, формируем перечень принадлежащих им блоков и сохраняем дамп в файл, который затем следует просмотреть вручную или с по мощью утилиты-фильтра. Как уже отмечалось, порядок расположения файлов в inode очень часто совпадает с порядком расположения файлов в каталоге, поэто му восстановление оригинальных имен в четырех случаях из пяти проходит на ура.
При тяжких разрушениях, когда восстанавливаемый файл приходится собирать по кусочкам, помогает команда dump_unused, выводящая на терминал все неиспользуе мые блоки. Имеет смысл перенаправить вывод в файл, запустить hexedit и поко паться в этой "куче хлама" - так, по крайней мере, проще, чем искать по всему диску. На дисках, заполненных более чем на три четверти, этот трюк сокращает массу времени.
Таким образом, можно сделать вывод, что отладчик debugfs в значительной мере автоматизирует восстановление удаленных файлов, однако восстановить файл с разрушенным inode он не способен.
### Восстановление удаленных файлов на разделах ext4fs