Немного подробнее. Прежде всего стоит заметить, что теперь при обнаружении повреждений метаданных таблица GPT будет помечена как corrupt и с ней будут запрещены любые действия. Т.е. если раньше вы получали в консоль сообщения о повреждённой GPT и могли по-просту не обращать на них внимания, то теперь игнорировать не получится :)
Запрещать любые действия было бы не логично, если не предложить что-то взамен. Взамен предлагается своего рода гарантия, что вы ничего случайно не сломаете, а так же возможность починить таблицу разделов, либо, если она вам не нужна - уничтожить её совсем. Для возможности уничтожения таблицы пришлось переделать "gpart destroy -F". Теперь форсированное уничтожение выполняется внутри ядра, а не в userspace как раньше.
Что бы знать какие типы повреждений возможно восстановить в GPT при помощи gpart, нужно иметь представление о том, как устроена GPT. Если коротко, то состоит она из заголовка и самой таблицы разделов. Всё это дублируется. Заголовок основной таблицы находится во втором секторе диска, за ним следует таблица разделов, её размер может быть различным. Заголовок резервной таблицы находится в последнем секторе, таблица располагается в предшествующих ему секторах. Содержание таблиц идентично и должно иметь одинаковую контрольную сумму. А вот заголовки отличаются, в них сохраняются номера секторов, в которых находится сам заголовок и его копия, номер начального сектора таблицы и границы пространства для использования партициями. Часть этой информации отображается в выводе команды gpart list:
> gpart list ada1 Geom name: ada1 state: OK fwheads: 16 fwsectors: 63 last: 320173022 first: 34 entries: 128 scheme: GPTЗдесь first и last - номера секторов, ограничивающих доступное пространство для разделов GPT, entries - максимальное количество записей в таблице, другими словами максимальное количество партиций.
Так же, ещё одним обязательным условием для работы с GPT является наличие PMBR, который занимает первый сектор. Если повредить содержимое PMBR, то класс PART не будет даже искать GPT на диске. Такова особенность. Поэтому если ваша GPT не обнаруживается совсем, ядро не выдаёт никаких сообщений, связанных с GPT, первым делом стоит восстановить PMBR. Его копию можно найти в файле /boot/pmbr. Нужно всего лишь записать его в первый сектор диска. Это автоматически инициирует поиск метаданных различными GEOM классами, в том числе и GEOM_PART_GPT.
Теперь о возможных повреждениях. Первое - это повреждение основного заголовка или таблицы GPT. При обнаружении такого повреждения ядро выдаст сообщение:
GEOM: provider: the primary GPT table is corrupt or invalid. GEOM: provider: using the secondary instead -- recovery strongly advised.Здесь provider - это имя диска, например ad0. Кроме этого сообщения, которое обычно можно увидеть только во время загрузки системы, о том что ваша GPT повреждена могут расказать команды gpart show, list и status.
> gpart show => 34 1250263661 ada0 GPT (596G) [CORRUPT] 34 256 1 freebsd-boot (128K) 290 8388608 2 freebsd-swap (4.0G) 8388898 1241874797 3 freebsd-zfs (592G) > gpart list ada0 | grep state state: CORRUPTСледующий тип - повреждение резервной копии заголовка или таблицы GPT. Как частный случай сюда же относится вариант несоответствия резервной и основной копий (например, когда в основной копии заголовок и таблица с одними данными, а в резервной - с другими, но сами по себе они являются вполне корректными). В это случае GPART просто воспользуется данными из основной копии. Сообщение от ядра в этом случае будет таким:
GEOM: provider: the secondary GPT table is corrupt or invalid. GEOM: provider: using the primary only -- recovery suggested.Третий случай, когда таблица GPT будет помечена как повреждённая - это неверное расположение заголовка резервной копии GPT. Такое может случится, например если у вас GPT создана на каком-то виртуальном носителе, который умеет расширяться путём добавления новых дисков. Либо, просто, например, вы создали GPT на gmirror устройстве, но забыли загрузить класс geom_mirror. В этом случае размер провайдера увеличится, так как gmirror резервирует пространство под свои метаданные.
Теперь, собственно про восстановление. Всё что нужно сделать - правильно выбрать носитель, на котором восстанавливать GPT и выполнить команду:
# gpart recover ada0В моём примере это ada0. Почему я выделил слово "правильно"? Вернёмся к примеру, в котором GPT создана поверх gmirror. Так вот, если забыть загрузить gmirror, то GPT будет найдена на том диске, на котором создан gmirror. И соответсвенно, если выполнить gpart recover для этого диска, то все параметры заголовка GPT будут перерасчитаны, а значит изменится и значение last - границы последнего доступного сектора, а так же, в последний сектор диска будет записан заголовок резервной копии GPT, который уничтожит метаданные gmirror. Хорошо, если это именно то, чего вы хотели :)
Подитожив всё написанное выше, хочется ещё раз напомнить, что восстановление данных это ответственный процесс, нельзя делать его не обдумав. Это относится не только к теме данной заметки.
Подскажите, пожалуйста, каким образом добавить опцию "recovery" в рабочей системе? Имею:
ОтветитьУдалить# uname -a
FreeBSD 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Sat Nov 21 15:02:08 UTC 2009 root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64
Думаю, что вам можно загрузиться с live cd и выполнить восстановление.
ОтветитьУдалитьдиск - почти 28Tb, 8.2 release x64
ОтветитьУдалитьсделал по мануалу man gpart
gpart create -s GPT da0
gpart bootcode -b /boot/pmbr da0
gpart add -b 34 -s 128 -t freebsd-boot da0
gpart bootcode -p /boot/gptboot -i 1 da0
gpart add -b 162 -s 60G -t freebsd-ufs da0
gpart add -t freebsd-swap -s 4G da0
gpart add -t freebsd-ufs -s 400G da0
gpart add -t freebsd-ufs -s 57620447037 da0
на загрузке имею
> Invalid backup GPT header
после чего бутится и работает нормально...
что не так?
а что показывается gpart list после загрузки?
ОтветитьУдалитьПри помощи чего сделан da0 на 28Т?
srv3# gpart list
ОтветитьУдалитьGeom name: da0
state: OK
fwheads: 255
fwsectors: 63
last: 58593525726
first: 34
entries: 128
scheme: GPT
Providers:
1. Name: da0p1
Mediasize: 65536 (64K)
Sectorsize: 512
Mode: r0w0e0
rawuuid: 5009d3cb-ffaa-11e0-9a06-00259029f58f
rawtype: 83bd6b9d-7f41-11dc-be0b-001560b84f0f
label: (null)
length: 65536
offset: 17408
type: freebsd-boot
index: 1
end: 161
start: 34
2. Name: da0p2
Mediasize: 64424509440 (60G)
Sectorsize: 512
Mode: r1w1e2
rawuuid: 6edd9317-ffaa-11e0-9a06-00259029f58f
rawtype: 516e7cb6-6ecf-11d6-8ff8-00022d09712b
label: (null)
length: 64424509440
offset: 82944
type: freebsd-ufs
index: 2
end: 125829281
start: 162
3. Name: da0p3
Mediasize: 4294967296 (4.0G)
Sectorsize: 512
Mode: r1w1e1
rawuuid: 86686b15-ffaa-11e0-9a06-00259029f58f
rawtype: 516e7cb5-6ecf-11d6-8ff8-00022d09712b
label: (null)
length: 4294967296
offset: 64424592384
type: freebsd-swap
index: 3
end: 134217889
start: 125829282
4. Name: da0p4
Mediasize: 429496729600 (400G)
Sectorsize: 512
Mode: r1w1e2
rawuuid: cbfdf724-ffaa-11e0-9a06-00259029f58f
rawtype: 516e7cb6-6ecf-11d6-8ff8-00022d09712b
label: (null)
length: 429496729600
offset: 68719559680
type: freebsd-ufs
index: 4
end: 973078689
start: 134217890
5. Name: da0p5
Mediasize: 29501668882944 (27T)
Sectorsize: 512
Mode: r1w1e2
rawuuid: 1db1073f-ffab-11e0-9a06-00259029f58f
rawtype: 516e7cb6-6ecf-11d6-8ff8-00022d09712b
label: (null)
length: 29501668882944
offset: 498216289280
type: freebsd-ufs
index: 5
end: 58593525726
start: 973078690
Consumers:
1. Name: da0
Mediasize: 29999885189120 (27T)
Sectorsize: 512
Mode: r4w4e11
===========
сделано на вполне железном рейде - 3ware 9750, 12 дисков по 3T (драйвер tws c официального сайта)
Раз уж GEOM_PART посчитал что "state: OK", значит заголовок вполне себе корректный.
ОтветитьУдалитьЭто сообщение от gptboot и наиболее вероятная причина в том, что он не может корректно определить размер диска.
Это можно проверить, если в файле sys/boot/i386/common/gpt.c в функции gptread_hdr() добавить в сообщение об ошибке вывод LBA, с которого оно пытается читать. Что-то типа такого:
printf("%s: unable to read %s GPT header from LBA %llu\n", BOOTPROG, which, (unsigned long long)hdrlba);
После этого пересобрать gptboot и переустановить его..
собственно, это у меня уже третий такой случай.
ОтветитьУдалитьвсе три - на 3ware рейдах, 9500, 9650, 9750
к сожалению, все три уже в продакшене, экспериментирвоать не могу.
размеры - от 2.7T до 27T
Может заинтересует. Захотелось перенести систему в лоб с одного винта на другой:
ОтветитьУдалитьada0p1 - freebsd-boot
ada0p2 - freebsd-zfs
dd if=/dev/ada0 of=/dev/ada1 bs=8M
gpart recover ada1
Теперь ada1 вроде как корректный, но zpool не позволяет с ним что-то сделать - идентификаторы gpt одинаковые. Создать пул/добавить - "/dev/ada1p2 is part of active pool", удалить - "no such device in pool"
Проще, быстрее и правильнее было бы подключить второй диск в зеркало, затем по окончанию синхронизации отключить из зеркала первый.
ОтветитьУдалитьЗдравствуйте Андрей!
ОтветитьУдалитьПодскажите пожалуйста, в FreeBSD 10.1-RELEASE-p16 поменялся синтаксис?
# gpart recover ada2
gpart: arg0 'ada2': Invalid argument
После подключения диска к Windows7 через USB адаптор слетела разметка, метка диска, название пула, данные на месте и видны через 16-ти ричный редактор акрониса.
Диск размечался так:
# camcontrol devlist
***
at scbus4 target 0 lun 0 (ada2,pass2)
***
# gpart create -s GPT ada2
ada2 created
# gpart add -l COPY -t freebsd-zfs ada2
ada2p1 added
# gpart show
***
=> 34 5860533101 ada2 GPT (2.7T)
34 6 - free - (3.0K)
40 5860533088 1 freebsd-zfs (2.7T)
5860533128 7 - free - (3.5K)
# zpool create TEST gpt/COPY
# zfs create TEST/TEST_COPY
# zpool list
NAME SIZE ALLOC FREE FRAG EXPANDSZ CAP DEDUP HEALTH ALTROOT
TEST 2,72T 444K 2,72T 0% - 0% 1.00x ONLINE -
Заполнил данными, экспортировал пул, погасил, отключил, подключил к Windows7, посмотрел в диспетчере, отключил, подключил к FREEBSD
# dmesg | grep ada2
ada2 at ahcich5 bus 0 scbus5 target 0 lun 0
ada2: ATA-9 SATA 3.x device
ada2: Serial Number WD-WMC4N0D6WSDS
ada2: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada2: Command Queueing enabled
ada2: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C)
ada2: quirks=0x1<4K>
ada2: Previously was known as ad14
GEOM: ada2: the secondary GPT header is not in the last LBA.
GEOM_PART: integrity check failed (ada2, GPT)
# sysctl kern.geom.part.check_integrity=0
kern.geom.part.check_integrity: 1 -> 0
# gpart status ada2
gpart: No such geom: ada2.
# gpart recover ada2
gpart: arg0 'ada2': Invalid argument
gpart recover работает только если таблица разделов существует в ядре и помечена как CORRUPTED. В вашем случае видимо не так.
УдалитьМожете загрузиться в режиме bootverbose, тогда integrity check напишет что конкретно ему не нравится. Ну и, если вы уверены, что все размеры и смещения, которы приведены тут были действительно такими, то можно просто пересоздать таблицу разделов.
Пересоздал поверх таблицу разделов, ZFS pool оказался на месте.
Удалитьgpart backup "наше всё"
Добрый день, Андрей!
ОтветитьУдалитьПомогите, пожалуйста, решить две проблемы.
Работаю на компе "ASUS Z87-PRO" с прошивкой UEFI "Z87-PRO-ASUS-2103.cap" (2014г)
Первая трабла: Дистрибутивы FreeBSD-9.1, 10.0 .....10.2.
Установка в режимах MBR или GPT.
1. В случае единственного в системе HDD загрузка после уст-ки нормальная.
2. При подключении в систему других дисков (Linux, FreeBSD) загрузка нарушается:
2.1. Зависание на стадии "Root mount waiting for: usbus1"
или "mountroot> waiting for device /dev/ada0p2 ", например.
2.2. В случае просто остановки: "mountroot>" - удается вручную задать "правильный" раздел,
например: "ufs:/dev/ada1p2" и загрузка выполняется нормально.
Вторая трабла: Дистрибутивы FreeBSD-10.0 .....10.2.
Невозможно произвести установку в режиме "Manual".
А именно: не удается создать или отредактировать разделы и пр. из-за отказа клав. и мыши
после выбора этого режима.
В режиме "Auto" (испол. весь диск) установка идет нормально.
На "9-ке" это не наблюдается.
Спасибо.
На мой взгляд это одна и та же проблема. Во время загрузки ядро не успевает дождаться инициализации USB контроллера. Или что-то вроде того. В BIOS'ах бывает настройка про поддержку legacy USB устройств. Кажется она помогает от пропадания клавиатуры. Ещё можно попробовать добавить в loader.conf настройку таймаута ожидания kern.cam.boot_delay (вроде бы в миллисекундах).
УдалитьСпасибо! Буду пробовать.
ОтветитьУдалить