Частный случай восстановление UFS2

Проблемы установки, настройки и работы Правильной Операционной Системы

Модератор: terminus

Правила форума
Убедительная просьба юзать теги [cоde] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Pablo
рядовой
Сообщения: 37
Зарегистрирован: 2009-12-01 20:02:56

Частный случай восстановление UFS2

Непрочитанное сообщение Pablo » 2010-07-25 21:07:50

ОТМАЗКА: Это не how-to и не know-how. Скорее, это лабораторная работа по частному случаю восстановления UFS. Может быть, кому-то и пригодится.
Итак.
Внезапно...
Внезапно система, на которой была спасена не одна дюжина миров и собрана дюжина Миров споткнулась на ровном месте, дёрнула 250Гным винтом и ушла в ребут, утянув вместе с собой в небытие UFS раздел с сорцами и торрентами.
Ступор... Single mode...
Беглый осмотр места проишествия показал: тип раздела не определяется как UFS, хотя тень раздела в виде метки /dev/gpt/work присутсутствует.
Хватаю первый попавшийся под руку микроскоп:

Код: Выделить всё

# fdisk -p ad2
# /dev/ad2
g c484518 h16 s63
p 1 0xee 1 488395054
Один GPT раздел (id=0xee) (должен быть) в наличии. Вкуриваю http://en.wikipedia.org/wiki/GUID_Partition_Table, делаю дамп первого блока диска, сличаю с дампом другого диска (тоже GPT).
Всё в порядке и соответствует спецификации.
Следующая тулза, которая первой приходит на ум - Testdisk. Проверяю:

Код: Выделить всё

# testdisk -> No Log -> Disk /dev/ad2 -> [EFI GPT] -> [Analyse]
TestDisk 6.11, Data Recovery Utility, April 2009
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org

Disk /dev/ad2 - 250 GB / 232 GiB - CHS 484518 16 63
     Partition               Start        End    Size in sectors
P Solaris /home                 66  488395053  488394988
"Solaris /home" - не совсем то, что я ожидал увидеть, да и начинается с 66-огого блока (хорошо хоть не с 666 :) вместо 34-го.
ЗЫ: если testdisk сообщает про "write protected disk", значит нужно вколоть стимулятор:

Код: Выделить всё

# sysctl kern.geom.label.debug=16
Небольшое отступление: geom постоянно ругался на испорченные GPT-таблицы, взывая к необходимости исправить их. Testdisk упорно находил и предлагал сохранить NTFS раздел, который когда-то действительно имел место быть на этом диске. Я не менее упорно отказывался от NTFS, в безуспешных попытках ткнуть testdisk носом в потерявшийся UFS раздел. В результате наших боданий были напрочь затоптаны даже те небольшие остатки патриции, которые ещё имели место спастись на диске: раздел перестал определяться как /dev/gpt/work. Увы, кривизна моих рук не даёт мне покоя...

Перво-наперво надо потренироваться на кошках:

Код: Выделить всё

dd if=/dev/zero of=/flash/d64m.raw bs=1M count=64
mdconfig -a -t vnode -f /home/pablo/flash/d64m.raw -o async -u 0
gpart create -s gpt md0
gpart add -t freebsd md0
gpart modify -i 1 -l test md0
newfs -o time /dev/md0s1
mount /dev/gpt/test /mnt/tmp/
Призвал на помощь могущественно духа -

Код: Выделить всё

# portinstall sysutils/scan_ffs
И пронаблюдал отдельно живой раздел:

Код: Выделить всё

$ scan_ffs -vs /dev/md0s1
block 128 id 4c34a367,be2d1218 size 32751
block 160 id 4c34a367,be2d1218 size 32751
ufs2 at 0 size 32751 mount /mnt/tmp time Wed Jul  7 22:55:19 2010
Целиком живой диск:

Код: Выделить всё

$ scan_ffs -vs /dev/md0
block 162 id 4c34a367,be2d1218 size 32751		<== адреса блоков смещены на 34 блока. Superblock по адресу 0x14400
block 194 id 4c34a367,be2d1218 size 32751		<== хвост Суперблока по адресу 0x18400
ufs2 at 34 size 32751 mount /mnt/tmp time Wed Jul  7 22:55:19 2010	<== UFS2 находится со смещеним 34 от начала диска
Сравнил с тем, что есть на живом (системном) диске:

Код: Выделить всё

$ scan_ffs -vs /dev/ad0    
block 290 id 4b3a8ba7,7d0b56cf size 262144		<== superblock /, смещён на 128 блоков от начала диска, на размер boot-part'а
block 322 id 4b3a8ba7,7d0b56cf size 262144		<== magic
ufs2 at 162 size 262144 mount / time Wed Dec 30 05:07:19 2009
Далее опять небольшой монтаж: многократное взятие на анализы дампов суперблоков здоровых разделов и побайтовое сравнение с дампом больного раздела, взятие у больного на анализ backup-копий суперблока, которые повторяются каждые 32768 блоков, начиная со 128 от начала раздела, (при условии форматирования раздела с дефолтными параметрами), вкуривание 'man fs' и не только...

Запускаю, медитирую:

Код: Выделить всё

> scan_ffs -v -l /dev/ad2
block 160 id 4a8f5548,f603e83e size 122098747		<== а вот нужное, с id=4a8f5548,f603e83e и size=122098747
block 162 id 0,0 size 122098747				<== здесь должен быть superblock
block 194 id 4a8f5548,f603e83e size 122098747		<== magic для UFS2 = 19 01 54 19
X: 488394988 34 4.2BSD 2048 16384 0 # 			<== строка для bsdlabel, которую подсказывает scan_ffs. Пока форматить повременю...
block 12098 id 0,0 size 122098747			<== тоже непонятно-что
block 239602 id 4b08bce0,6b8b4567 size 901552		<== какой-то старый хвост
block 376546 id 4a8f5548,f603e83e size 122098747	<== Cylinder Group 1 (если я не путаю нумерацию)
block 752898 id 4a8f5548,f603e83e size 122098747	<== Cylinder Group 2
block 1129250 id 4a8f5548,f603e83e size 122098747	<== Cylinder Group 3
... <scipped>
Даже вот так, только самое необходимое:

Код: Выделить всё

> scan_ffs  -v -b 0 -e 163 /dev/ad2
block 160 id 4a8f5548,f603e83e size 122098747		<== правильная запись в неправильном месте
block 162 id 0,0 size 122098747					<== неправильная запись в правильном месте
block 194 id 4a8f5548,f603e83e size 122098747		<== magic
ufs2 at 34 size 122098747 mount  time Sat Aug 22 09:17:44 2009	<== точка последнего монтирования не определилась
В качестве сухого экстракта: суперблок должен начинаться с адреса 0x10000 bytes (128 blocks) от начала раздела, корень файловой системы должен начинаться с адреса 0x94400, суперблок повторяется по адресам 0x1018400, 0x2018400, 0x3018400 и так далее.
Если считать от начала диска, то надо прибавить, соответственно, 0x4400 (34 blocks): адрес суперблока=0x14400, адрес корня файловой системы=0xA4400
Диагноз: в конкретном моём случае всё указывало на то, что суперблок (живой и здоровый) находится не на своём месте (testdisk всё-таки сумел записать на диск правильный superblock в неправильное место).

Небольшое отступление: здесь можно было выбрать иной путь: взять backup GPT header из последнего блока диска

Код: Выделить всё

# dd if=/dev/ad2 of=ad2_lbaB bs=512 count=1 iseek=488395054; chexedit ad2_lbaB
00000000  45 46 49 20 50 41 52 54 00 00 01 00 5C 00 00 00 6F DD A8 4B 00 00 00 00 2E 51 1C 1D EFI PART....\...o..K.....Q..
0000001C  00 00 00 00 01 00 00 00 00 00 00 00 22 00 00 00 00 00 00 00 0D 51 1C 1D 00 00 00 00 ............"........Q......
00000038  EE 23 D1 D7 89 FB 43 CF AC 3D 3F 7C E8 1D 4A 53 0E 51 1C 1D 00 00 00 00 80 00 00 00 .#....C..=?|..JS.Q..........
00000054  80 00 00 00 22 F8 63 99 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ....".c.....................
поменять местами "Current LBA" и "Backup LBA", "Partition entries starting LBA" исправить с 0x1D1C510E на 0x2, пересчитать CRC32,
и вписать во 2-ой блок диска, но... Это было слишком сложно для меня и я поступил просто, но решительно:

Код: Выделить всё

# gpart destroy ad2					<== мёртвой водой
# gpart create -s GPT ad2			<== живой водой
# gpart add -t freebsd-ufs ad2		<== определил
# gpart modify -i 1 -l work ad2		<== пометил
Проверил:

Код: Выделить всё

# gpart show -l ad2
=>       34  488394988  ad2  GPT  (233G)
         34  488394988    1  work  (233G)
В соответствии с диагнозом, было принято решение о пересадке superblocka через промежуточный контейнер:

Код: Выделить всё

# dd if=/dev/ad2 of=ad2_superblock skip=194 bs=512 count=4 
# dd if=/dev/zero of=/dev/ad2 bs=512 count=6 oseek=160
# dd if=ad2_superblock of=/dev/ad2 bs=512 count=4 oseek=162
Итак, пришло время взглянуть в глаза действительности:

Код: Выделить всё

# scan_ffs /dev/ad2      
ufs2 at 34 size 122098747 mount  time Sat Aug 22 09:17:44 2009
Что-то уже прорисовывается! Но, прежде чем довериться fsck'у, небольшая пальпация:

Код: Выделить всё

# fsdb -d /dev/gpt/work
** /dev/gpt/work
Editing file system `/dev/gpt/work'
Last Mounted on 
current inode: directory
I=2 MODE=40755 SIZE=512
        BTIME=Aug 22 09:17:44 2009 [0 nsec]
        MTIME=Dec 11 22:05:25 2009 [0 nsec]
        CTIME=Dec 11 22:05:25 2009 [0 nsec]
        ATIME=Jun 13 00:26:01 2010 [0 nsec]
OWNER=root GRP=wheel LINKCNT=8 FLAGS=0 BLKCNT=4 GEN=206f2c6
fsdb (inum: 2)> ls
command `ls
'
slot 0 ino 2 reclen 12: directory, `.'
slot 1 ino 2 reclen 12: directory, `..'
slot 2 ino 3 reclen 16: directory, `.snap'
slot 3 ino 24541184 reclen 16: directory, `backup'
slot 4 ino 6571008 reclen 16: directory, `torrent'
slot 5 ino 21879808 reclen 16: directory, `public'
slot 6 ino 21903360 reclen 20: directory, `lost+found'
slot 7 ino 17805312 reclen 404: directory, `conf'
fsdb (inum: 2)> quit
Теперь, для успокоения душевных мук, можно полюбоваться на отсутствие различий между primary и backup копиями суперблока (что является первым признаком наметившегося выздоровления):

Код: Выделить всё

# diff <(ffsinfo -g 0 -i 2 -l 0x1 /dev/gpt/work) <(ffsinfo -g -1 -i 2 -l 0x1 /dev/gpt/work)
И это один из немногих случаев, когда можно радоваться тому, что ничего не видишь.
Затаив дыхание, запустил:

Код: Выделить всё

# fsck -y -t ufs /dev/gpt/work
и ушёл нервно курить в сторонке, взывая к Великому и Ужасному Рэндому, чтобы по окончании проверки лицезреть кучу исправлений :( в lost+found оказалось полсотни файлов, общим размером ~800 Мб)
Отступать некуда, монтирую:

Код: Выделить всё

# mount -o noatime /dev/gpt/work /work/
# ll /work
total 32
drwxr-xr-x   8 root   wheel     -   512 11 дек  2009 ./
drwxr-xr-x  23 root   wheel     -   512 15 июл 12:02 ../
drwxrwx---   2 root   operator  -   512 18 сен  2009 .snap/
drwxr-xr-x   8 root   wheel     -   512 12 июн 21:28 backup/
drwxr-xr-x   3 root   wheel     -   512 14 дек  2009 conf/
drwx------   6 root   wheel     - 16896 22 авг  2009 lost+found/
drwxrwxr-x   2 pablo  pablo     -   512 14 июн 13:37 public/
drwxr-xr-x   9 pablo  pablo     -   512 28 фев 13:39 torrent/
Кажысь, всё на месте :)
И последнее наведение гламурного глянца - зачистка хвостов NTFS, boot record которой начинается с адреса 0x7E00(=32256) и тянется примерно до 0x8B75(=40448), т.е., общим размером 8192:

Код: Выделить всё

# dd if=/dev/zero of=/dev/ad2 oseek=63 bs=512 count=16
Возвращаю в прежний вид /etc/fstab, контрольный ребут, transmission, 3 Мбайта потерянных данных в одном торренте из 50-ти (хм, всего-то)...
Радостный возглас !$@#
Холодный Guiness 1,2,3...
Занавес...

Небольшой ИТОГО:
- Для более-менее надёжной очистки диска от предыдущих разделов, надо обнулять 65,5 Кбайт в начале и в конце диска. Потом будет проще выковыривать.
- Сохранять расклад. Сохранять тем же dd'ом те же самые 65,5 Кбайт начала и конца диска. Чтоб было от чего плясать, в случае чего.
- GUID для Unix File System (UFS) partition вот такой 516E7CB6-6ECF-11D6-8FF8-00022D09712B, но первые три группы цифр идут в обратном порядке,
поэтому на диске они видятся вот так:

Код: Выделить всё

B6 7C 6E 51 CF 6E D6 11 8F F8 00 02 2D 09 71 2B
- В UFS2 по сравнению с UFS много неиспользуемых полей. Если кому интересно, вот ссылка http://flylib.com/books.php?ln=en&n=2&p ... 184&view=1
Использованные программы: c dd_rescue и ddrescue лично у меня не срослось. Пытался сделать образ диска, но скорость копирования была менее 1 Мб/с.
С dd тоже не срослось - образ писал на внешний USB, смонтированный fusefs-ntfs'ом и система не справлялась. Пока сижу смотрю, копируется. Ушёл спать - всё терминулось. Больше 92 Гб не смог скопировать - бросил эту затею.
Sleuthkit - могутный пакет, в пару к нему идёт Autopsy, перловый Веб-ГУЙ, особенно хорош для начинающих. Одно "НО" - работает только с образами диском (в моём случае не стали работать с /dev/ad2p1).
С ним у меня тоже не срослось, ввиду отсутствия полноценного образа. Хотя образ можно разбивать на части и грузить списком.
HEX-редакторы: lfhex - требует что-то из QT4, ghex - требует Gnoma, судя по всему, всё и сразу. Поскольку я сижу под XFCE4, ни QT4 ни Gnome у меня нет, поэтому отказался. Для любителей VI могу порекомендовать bvi (binary vi), полный аналог vi.
hexedit, chexedit - простые консольные, работают на ncurses, примерно одинаково функциональны. Я остановился на chexedit.
Пришлось много конвертировать hex-dec. Не придумал ничего лучшего, кроме пары алиасов:

Код: Выделить всё

alias dec='printf "%d\n" $1'
alias hex='printf "0x%x\n" $1'
Unix is simple. It just takes a genius to understand its simplicity – D. Ritchie

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35477
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: Частный случай восстановление UFS2

Непрочитанное сообщение Alex Keda » 2010-07-25 21:17:01

зачёт!
=======
я бы даже не пошевелился, ради музыки да кина =)))
Убей их всех! Бог потом рассортирует...

Аватара пользователя
gloom
лейтенант
Сообщения: 738
Зарегистрирован: 2008-03-13 16:29:12
Откуда: UA

Re: Частный случай восстановление UFS2

Непрочитанное сообщение gloom » 2010-07-26 2:51:08

круто :Yahoo!: :good:
Alex Keda писал(а): я бы даже не пошевелился, ради музыки да кина =)))
аналогично все можно перекачять...

Pablo
рядовой
Сообщения: 37
Зарегистрирован: 2009-12-01 20:02:56

Re: Частный случай восстановление UFS2

Непрочитанное сообщение Pablo » 2010-07-26 9:52:58

Эх, у меня безлимитки только 45 Гб в месяц, потом идёт ограничение по скорости. А с учётом того, что я уже не помнил, что же там у меня лежало - возникло желание всё это добро восстановить.
ЗЫ: Открою небольшой секрет - в первый же вечер диск был вставлен на второй комп и там, под проприетарной операционный системой проприетарной программой, всё было успешно восстановленно и к утру уже лежало на внешнем usb-драйве. Но, мне это показалось идеологически неверным решением. Если могут они, значит могу и я. Процесс занял несколько больше времени, чем может показаться из описания ;) , но оно того стоило. Кое чему научился за это время.
Unix is simple. It just takes a genius to understand its simplicity – D. Ritchie