Ключевые слова:disk, file, freebsd, partition, trouble, (найти похожие документы)
From: tin <tin at gisp.com.ua>
Newsgroups: openforum
Date: Mon, 2 Aug 2004 14:31:37 +0000 (UTC)
Subject: Восстановление partition table в FreeBSD
Оригинал: http://www.opennet.dev/openforum/vsluhforumID1/35153.html
Понадобилось поднять еще один комп старенький для tftpd, bootpd и разной мелочи
Я присобачил винт в FreeBSD, зашел в sysinstall, разбил разделы на новом винте
(немного помучался с ad2s1e <-> ad2s1a пока не додумался поменять mountpoint)
Вышел, проверил disklabel -r ad2, disklabel -r ad2s1 - все в порядке
Сделал dump/restore из / в /mnt/root и проч разделы.
поскольку новый винт маленький - решил порты там не держать а монтировать по NFS.
подмонтировал /usr/ports в /mnt/root/usr/ports сделал chroot в /mnt/root
там собрал необходимый софт и поменял конфиги вышел, размонтировал, выключил,
переставил, включил новую машину, посмотрел на загрузку, дождался загрузки sshd,
посмотрел на интерфейсы, залогинился локально, попинговал разные хосты
Посмотрел на часы и решил доделать на след. день
Сегодня пришел - новая машина грузится и работает а старая нет!
Подключил вчера_сделанный_винт, загрузился с него - а на старом
MBR и Partition table пустые и чистые!!! :(((
если бы винты были бы одинаково побитые я бы копию слил а так не
знаю как можно восстановить
Жалко все дистфайлы по новой тянуть
Можно ли таблицу разделов ручками восстановить???
Сообщение от idLe:
К сожалению, дельного совета дать не смогу, пожалуй только поделюсь
печальным опытом. Как-то я тоже умудрился запортачить таблицу
разделов на домашнем компе, скопировав загрузчик с обычного раздела
в MBR. Часа три потом мы маялись, пытаясь его восстановить, только
потом случайно наткнулись на дискетку с старым backup-ом mbr,
который делает винда при установке. Не знаю, что бы без нее делали
;).
> MBR я на место засун
Таблица разделов находится _внутри_ 512-байтной MBR, со смещением
1BEh и длиной 65 (41h) байт. Поэтому по логике, если вы
восстановили MBR, то и таблицу разделов.
Сообщение от Alex_M:
Впринципе восстановить данные можно, но надо знать формат таблицы
разделов (это не проблема - описано во многих местах, например
http://www.microsoft.com/TechNet/prodtechnol/windows2000serv/reskit/serverop/part1/sopch01.asp?frame=true#b
) и примерно помнить как был разбит диск.
Предположим спасать будем /dev/ad2.
Нам потребуется какой нибудь HEX-редактор - можно воспользоваться
hexedit или миднайт коммандером (F3 -> F4 -> F2)
Во первых надо найти начало FreeBSDшного слайса. Это можно сделать
зная, что в начале находится загрузочный сектор раздела (его копия
находится в /boot/boot1).
hexdump -C boot1
00000000 eb 3c 00 00 00 00 и т.д. (Внимание! Это - у меня на
FreeBSD-5.1, но есть вероятность,что в другой версии boot1 будет
слегка отличаться.)
Теперь поищем где находятся первые несколько байт в теле нашего
пациента:
hexdump -C /dev/ad2 | grep "eb 3c 00"
Как только на экране появится строчка вроде этой
00007e00 eb 3c 00 00 00 00 00 00 00 00 00 00 02 00 00 00 |К<..............|
жмём CTRL-C - остальное нам не интересно.
Итак, обнаружили, что начало фришного слайса находится по смещению
00007e00 байт от начала диска. Разделим на размер сектора 512 байт
(шестнадцатеричное - 200).
0x7E00 / 0x200 = 0x3F (т.е. сектор номер 63)
Теперь примемся за создание нового MBR.
Вернее его жалкого подобия т.к. восстановить информацию о разделах
в формате CHS весьма и весьма затруднительно, не имея точной копии
правильного MBR. А имея - не нужно всё остальное (диалектика, блин
:-)). Поэтому мы ограничимся восстановлением записи в фришном
слайсе только в формате LBA, что не даст нам возможности
загрузиться с этого диска, но по крайней мере мы сможем его
подмонтировать и спасти информацию.
Для этого нам необходимо вспомнить какой был номер у раздела и его
размер (если точный размер забыт навсегда, то хотя бы
приблизительный плюс добавим ещё немного для гарантии, что в этот
размер влезет весь слайс. Нам ведь не надолго надо - только спасти
файлы ;-], а потом всё равно нужно будет переразбить правильным
образом).
Таблица разделов находится в MBR по смещению 0x01BE (446) и состоит
из 4 записей по 16 байт.
В таблице разделов нас интересует следующее:
Таблица 1
Смещение Размер_поля
0x01BE BYTE #Указывает, что запись является загрузочной (0x80). Нам
это не нужно, поэтому поставим 0.
0x01C2 BYTE #Номер раздела. FreeBSD слайс = 0xA5
0x01C6 DWORD #Номер первого сектора раздела. У нас 0x0000003F
0x01CA DWORD #Размер раздела (слайса) в секторах.
Предположим мы приняли размер слайса = 20 000 000 000
20 000 000 000 байт / 512 = 39062500 секторов (шестнадцатиричное
0x02540BE4).
Важное замечание: В таблице разделов все многобайтовые числа
записываются в формате little endian, т.е. младший байт
записывается слева, старший - справа. В нашем случае:
Номер первого сектора раздела (0x0000003F) => 3F 00 00 00.
размер слайса (0x02540BE4) => E4 0B 54 02
Последние 2 байта MBR должны быть всегда равны 0xaa55 (little
endian => 55 aa) (не забудем в этом убедиться).
В качестве заготовки возьмём стандартный MBR, копия которого
находится в /boot/mbr
cd /boot
cp mbr ad2.mbr
Теперь займемся собственно редактированием ad2.mbr. Я предпочёл
воспользоваться клавишей F3 в мид. коммандере. F3 -> F4 -> F2.
Должно получиться что-то вроде этого (в предположении, что FreeBSD
слайс находится в первой записи таблицы разделов. Если это не так -
ко всем смещениям из таблицы 1 прибавить нужное колличество
16-байтовых блоков!
...
пропущено
...
000001A0 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 ................
000001B0 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 ................
000001C0 00 00 A5 00 │ 00 00 3F 00 │ 00 00 E4 0B | 54 02 00 00 ..╔...?...ДkT...
000001D0 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 ................
000001E0 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 ................
000001F0 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 55 AA ..............U╙
Здесь 000001BE => 00 и т.д в соответствии с таблицей 1
Отредактировали - записываемся/выходим.
Остался последний штрих - заливка ad2.mbr в MBR пациента :
dd if=ad2.mbr of=/dev/ad2 bs=512 count=1
Убеждаемся что слайс восстановился:
fdisk /dev/ad2
******* Working on device /dev/ad2 *******
parameters extracted from in-core disklabel are:
cylinders=4960 heads=16 sectors/track=63 (1008 blks/cyl)
Figures below won't work with BIOS for partitions not in cyl 1
parameters to be used for BIOS calculations are:
cylinders=4960 heads=16 sectors/track=63 (1008 blks/cyl)
Media sector size is 512
Warning: BIOS sector numbering starts with sector 1
Information from DOS bootblock is:
The data for partition 1 is:
sysid 165 (0xa5),(FreeBSD/NetBSD/386BSD)
start 63, size 5078125 (2479 Meg), flag 0
beg: cyl 0/ head 0/ sector 0;
end: cyl 0/ head 0/ sector 0
The data for partition 2 is:
<UNUSED>
The data for partition 3 is:
<UNUSED>
The data for partition 4 is:
<UNUSED>
(числа будут другими!)
disklabel /dev/ad2s1
# /dev/ad2s1:
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 524288 0 4.2BSD 2048 16384 32776
b: 1022688 524288 swap
c: 4999617 0 unused 0 0 # "raw"
part, don't edit
d: 524288 1546976 4.2BSD 2048 16384 32776
e: 524288 2071264 4.2BSD 2048 16384 32776
f: 2404065 2595552 4.2BSD 2048 16384 28552
disklabel: partition c doesn't cover the whole unit!
disklabel: An incorrect partition c may cause problems for standard system utilities
(числа будут другими! На предупреждения внимания не обращаем!)
Всё! Вуаля!
Монтируем что нибудь:
mount /dev/ad2s1f /mnt/test
Спасаем файлы ...
Удачи...
Сообщение от tin:
Всем огрогмное спасибо..
Все оказалось проще, чем я мог предположить
Как известно kernel хранит копию partition_table в памяти
я подумал, что может он ее когда-нть в своп ложил и захотел
проверить
Я помню что
ad0s1a у меня был 256М размером, или 512000 блоков
ad0s1e - 256M столько-же
ad0s1f - 2G или 1024*1024*4 = 4194304 блоков
ad0s1g я добавлял позже и лежит он после свопа
в принципе этого бы хватило чтоб восстановить разделы
считаю смещение свопа 512000*2+4194304=5218304
логично, что ad0s1b (swap) лежит на винте со смещением 5218304 или
около того.
Дальше проще
dd if=/dev/ad0 of=/tmp/swap_img bs=512 count=2000 iseek=10192
strings /tmp/swap_img | grep "disk: ad0s1" -A25 -B25 > /tmp/result
теперь смотрю в /tmp/result и нахожу там мою таблицу в виде
type: ESDI
disk: ad0s1
label:
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 185
sectors/cylinder: 11655
cylinders: 5152
sectors/unit: 60046560
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0 # milliseconds
track-to-track seek: 0 # milliseconds
drivedata: 0
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 512000 0 4.2BSD 0 0 0 # (Cyl. 0 - 43*)
b: 512000 5218304 swap # (Cyl. 447*- 491*)
c: 60046560 0 unused 0 0 # (Cyl. 0 - 5151)
e: 512000 512000 4.2BSD 0 0 0 # (Cyl. 43*- 87*)
f: 4194304 1024000 4.2BSD 0 0 0 # (Cyl. 87*- 447*)
g: 54316256 5730304 4.2BSD 0 0 0 # (Cyl. 491*- 5151*)
Смотрю на смещения и размеры и понимаю что не ошибся
теперь disklabel-ом ее впихиваю
делаю fsck и все работает...
в общем не пришлось и систему переставлять
ps: правда корень пришлось-таки забрать с винтаб на который
я его в свое время записывал (вчера) и MBR вкатать стандартный из
sysinstall
The size of the partition in sectors, K (kilobytes - 1024), M (megabytes - 1024*1024), G (gigabytes - 1024*1024*1024), [...]. Lowercase versions of K, M, and G are allowed. Size and type should be specified without any spaces between them.