The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги ]

Восстановление файла с поврежденного ext3-раздела (ext3 recover fs partition)


<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>
Ключевые слова: ext3, recover, fs, partition,  (найти похожие документы)
From: grislock <opennet@icqlog.net.> Date: Mon, 23 Oct 2010 17:02:14 +0000 (UTC) Subject: Восстановление файла с поврежденного ext3-раздела Оригинал: root.blogz.name Представьте себе ситуацию: файловая система повреждена, раздел не монтируется, вместо корневого каталога нули. # mount /dev/md1 /mnt mount: wrong fs type, bad option, bad superblock on /dev/md1, missing codepage or other error In some cases useful info is found in syslog - try dmesg | tail or so Хорошо, что есть бэкап. Вы смотрите как дела обстоят с бэкапом, и тут вдруг обнаруживаете, что в бэкапе нет одного очень нужного файла. И если можно где-то найти этот файл - то только в недрах погибшего раздела. Оказавшись в подобной ситуации я сразу пожалел, о том что, ранее не интересовался внутренним устройством ext3fs. Что я собственно знаю о ней? Да похоже ничего, иноды там какие-то... Но делать что-то надо. Детально разбираться времени уже нет, так что погуглив на тему ext3fs, выясняю следующее: Основные составляющие ext3fs: * каталоги * указатели inode * блоки данных И есть еще суперблок, в котором хранится важнейшая информация о ФС, такая как, размер блока, количество инодов, и многое другое. Самое важное, что хранит в себе inode: * размер файла * id владельца * id группы * даты модификации/доступа * список блоков данных, где собственно и хранится файл Жаль имени файла нет, было бы удобнее, но почему нет - понятно, имен-то (hardlink-ов) может быть много. А хранятся имена, естественно, в каталогах. Каталог по сути тот же inode, только другого типа, в нем есть та же самая информация о владельце и датах, а главное, в блоках данных хранится список имен файлов и каталогов с номерами соотвествующих inode. Так же, особо надо отметить, что в списке есть и ссылка на родительский каталог, таким образом, если найти какой-либо каталог на диске, то по ссылкам на родительский каталог, можно будет перемещатся по структуре каталогов. Если конечно структура эта не повреждена. Это несколько упрощенный взгляд на ext3fs, но сейчас не до деталей и подробностей, файл нужно доставать. Главный инструмент который нам поможет - debugfs. debugfs -c /dev/md1 debugfs 1.39 (29-May-2006) /dev/md1: catastrophic mode - not reading inode or group bitmaps Посмотрим что там в суперблоке: debugfs: stats Filesystem volume name: Last mounted on: Filesystem UUID: 24c5e529-02c4-4775-bb9f-e0c1f1b4a676 Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: resize_inode dir_index filetype sparse_super large_file Default mount options: user_xattr acl Filesystem state: not clean with errors Errors behavior: Continue Filesystem OS type: Linux Inode count: 121831424 Block count: 121806816 Reserved block count: 6090340 Free blocks: 117940889 Free inodes: 121831413 First block: 0 Block size: 4096 В данном случае, размер блока 4096, кол-во инодов - 121831424 Теперь вполне можно было бы проитерировать все иноды, найти все каталоги, и в каком-то из них и будет ссылка на искомый файл. Создадим файл stat.cmd с содержимым вида: stat <1> stat <2> ... stat <кол-во inode> Выполним: # debugfs -f stat.cmd -c /dev/md1 | grep 'Type: dir' Получим список каталогов: ... Inode: 32957 Type: directory Mode: 0755 Flags: 0x0 Generation: 1325685135 Inode: 32987 Type: directory Mode: 0755 Flags: 0x0 Generation: 1325685176 Inode: 33025 Type: directory Mode: 0755 Flags: 0x0 Generation: 1325685227 ... Теперь можем посмотреть содержимое каталога: # debugfs -f stat.cmd -c /dev/md1 debugfs: ls <32957> 32957 (12) . 2590762 (44) .. 32956 (24) china-util.elc 32958 (20) chinese.elc 32959 (24) cyril-util.elc ... Видим список файлов и что очень важно, видим inode родительского каталога - 2590762, т.е. можем просмотреть его содержимое: debugfs: ls <2590762> 2590762 (12) . 2590642 (4084) .. 2590760 (20) abbrev.elc 2590765 (20) align.elc 2590771 (20) autoarg.elc ... Т.о. фактически мы можем перемещатся по структуре каталогов, лишь бы ветвь директорий в которой лежит искомый файл не была повреждена. Это уже дает неплохие шансы найти файл. Но к сожалению, не все так просто когда структура каталогов повреждена, да и посмотрите на кол-во inode в данном случае, поиск всех директорий для 500Gb диска времени займет слишком много. Другой путь - найти блок данных принадлежащий искомому файлу, с помощью debugfs узнать номер inode, и если все сложилось удачно, вытащить содержимое файла. Например, нам удалось выяснить что блок 94844 принадлежит искомому файлу, спросим у debugfs номер inode c помошью команды icheck: debugfs: icheck 94844 Block Inode number 94844 69267 Подумав некоторое время debugfs сказал что inode - 69267. Запросим информацию об этом inode: debugfs: stat <69267> Inode: 69267 Type: regular Mode: 0444 Flags: 0x0 Generation: 2933723684 User: 0 Group: 0 Size: 15214 File ACL: 0 Directory ACL: 0 Links: 1 Blockcount: 32 Fragment: Address: 0 Number: 0 Size: 0 ctime: 0x47f3754b -- Wed Apr 2 16:00:11 2008 atime: 0x48002a85 -- Sat Apr 12 07:20:37 2008 mtime: 0x47f3754b -- Wed Apr 2 16:00:11 2008 BLOCKS: (0-3):94844-94847 TOTAL: 4 Скорее всего по владельцу, группе и размеру уже станет ясно, искомый файл это или нет. Теперь попросим debugfs вытащить содержимое файла, с помощю команды dump: debugfs: dump <69267> /tmp/69267.file Если все сложилось удачно, в /tmp/69267.file лежит то, что мы искали. Остается открытым вопрос, как найти блок данных, принадлежащий файлу. Естественно, придется искать по какой-то подстроке, которую как мы предполагаем, содержит файл. Первое что приходит в голову - воспользоватся hexdump и grep, например вот так: cat /dev/sda1 | hexdump -C | grep Linux ... 001fc830 64 69 74 0a 23 20 4c 69 6e 75 78 20 6b 65 72 6e |dit.# Linux kern| 00205470 20 49 53 44 4e 34 4c 69 6e 75 78 0a 23 0a 43 4f | ISDN4Linux.#.CO| 002092d0 63 65 64 20 4c 69 6e 75 78 20 53 6f 75 6e 64 20 |ced Linux Sound | ... Если нам повезет и искомая подстрока будет внтури 16-байтного блока, то вполне может быть и найдем. Но скорость поиска очень низкая, годится только для совсем небольших разделов. В моем же случае для поиска пришлось набросать небольшую програмку, которую я обозвал bfind. Работает она примерно вот так: cat /dev/sda1 | ./bfind Linux ... 5214 +300 20 2e 63 6f 6d 70 2e 73 6f 66 74 2e 6c 69 6e 75 | .comp.soft.linu| 5214 +376 6d 70 2e 73 6f 66 74 2e 6c 69 6e 75 78 2e 6e 69 |mp.soft.linux.ni| 5214 +423 70 2e 73 6f 66 74 2e 6c 69 6e 75 78 2e 6e 69 78 |p.soft.linux.nix| ... И главное, работает быстро. Первый столбец - это и есть номер 4k-блока данных. Если понадобится уточнить содержимое найденных блоков, можно воспользоваться утилитой fsgrab. fsgrab -b 4096 -c 4 -s 105633828 -f /dev/md1 > /tmp/105633828.block В данном случае 4 блока по 4096 байта, начиная с 105633828-го будут сохранены в указанный файл. Ну и в заключение хочу пожелать, чтобы все вышеописанное не пригодилось Вам ни разу.

<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>

Ваш комментарий
Имя:         
E-Mail:      
Заголовок:
Текст:





  Закладки на сайте
  Проследить за страницей
Created 1996-2017 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
Hosting by Ihor