пятница, 3 февраля 2012 г.

Проблемы при обновлении с FreeBSD 7+ до 9.0

Почти месяц прошёл со дня выхода FreeBSD 9.0 и уже (только сейчас!) появляются первые жалобы о неудачных обновлениях. Я буду говорить в первую очередь о том, что "сломал" я - это добавление проверок корректности метаданных в GEOM класс PART.
Эти проверки были добавлены более полугода назад. Расскажу (оправдаюсь) для чего они нужны. Во-первых, конечно же, что бы уберечь пользователей от потери данных, разного рода паник ядра, которые могут возникнуть когда информация в метаданных таблиц разделов не соответствует действительности. Например, когда границы нескольких разделов пересекаются, т.е. один раздел содержит в себе другой раздел или его часть; когда раздел выходит за физические границы носителя или частично перекрывает служебные данные таблицы разделов.

В общем, это те ситуации когда ядро не может решить что делать. Проверки эти были добавлены в базовый модуль и не зависят от типа таблиц (схем), поэтому касаются всех поддерживаемых таблиц разделов.

В версии FreeBSD 9+ система по-умолчанию отказывается работать с таблицей разделов, в которой будут обнаружены подобные несоответствия. Узнать об этом можно увидев при загрузке сообщение:
 GEOM_PART: integrity check failed (имя_провайдера, имя_схемы)
Если вам интересно, что же там не так, то можно включить режим verbose boot и тогда ядро напишет о всех несоответствиях, найденных в метаданных. Если этот диск не загрузочный, то режим можно включить через sysctl и выполнить retaste для диска, чтобы увидеть в консоли и в логах все сообщения:
# sysctl debug.bootverbose=1
# true > /dev/ada1
Что же делать, если вам непосчастливилось и у вас обнаружилась такая таблица разделов? В качестве временного решения можно отключить эти проверки через sysctl или loader.conf:

# sysctl kern.geom.part.check_integrity=0
Тогда система будет себя вести почти как раньше. Т.е. вы сможете получить доступ к данным, которые у вас были до этого на диске. Но вы не сможете делать изменения в таблице разделов, так как она будет отмечена как повреждённая. Это значит, что, исправить повреждения не удастся без полного уничтожения таблицы разделов. Кстати, запись загрузочного кода то же считается попыткой изменить таблицу разделов.

Теперь о жалобах после обновления. Возникают они обычно от тех пользователей, которые используют gmirror, созданный по методу: на готовой системе захотелось зеркало. Т.е. была система, добавили ещё один диск, переписали последний сектор и сделали зеркало.

А получилось, что раздел, размер которого был во весь диск, фактически уменьшился на 1 сектор, при этом, информация в таблице разделов осталась прежней. Если же в конце диска у вас было свободное пространство, то, скорее всего, никаких проблем при обновлении не будет.

Чтобы исправить эту проблему нужно пересоздать таблицу разделов на зеркале. Сделать это можно следующим образом:
  • удалить один компонент из зеркала и уничтожить таблицу разделов на нём;
  • создать новое зеркало на этом диске и уже на нём создать таблицу разделов;
  • создать разделы и файловые системы, записать загрузочный код, выполнить dump+restore данных со старого зеркала на новое;
  • выполнить необходимые правки в /etc/fstab и /boot/loader.conf (если необходимо);
  • перезагрузиться с нового зеркала, после этого уничтожить старое зеркало, таблицу разделов на нём и подключить диск в новое зеркало.
Пример последовательности команд описан в этом письме. Многие советуют мигрировать с конфигурации, в котрой используется зеркало из целых дисков, на GPT + несколько gmiror для разлных разделов, но мне кажется, что такая схема будет проигрывать по производительности, хотя для некоторых случаев может оказаться приемлимой.

Хочу сразу предупредить, что проверки целостности метаданных уже перенесены в ветку 8-STABLE, и в грядущем 8.3-RELEASE они уже будут присутствовать (который уже не за горами).  По-умолчанию проверки будут отключены, поэтому при обновлении разделы не будут неожиданно теряться. Но чтобы избежать этого в дальнейшем, рекомендую не забывать о правильной последовательности создания зеркала в новых установках системы.

Пользователям netmond хочу сообщить, что в текущей версии было исправлено несколько ошибок. Последнюю версию можно скачать тут.

5 комментариев:

  1. Лалетин Михаил3 февраля 2012 г. в 13:20

    Т.е. метод создания зеркала, описанный в handbook'е неправильный?
    Надо изначально при разбивке диска оставлять хоть каплю места под второй слайс, которого не будет?

    ОтветитьУдалить
  2. Приветствую. Тут возник вопрос по поводу зеркала на дисках: Мы на наших серверах используем схему ad0s1 -> gmirror -> партишены. Т.е. на диске создаётся слайс, он цепляется в зеркало и уже на нём создаются разделы. Такая схема была выбрана во-первых ради простоты (один gmirror вместо отдельного на каждый раздел) и чтобы избежать проблем связанных с различным размером жестких дисков в зеркале (правда не могу вспомнить сейчас, каких именно =)). Судя по всему на gpt она не работает т.к. загрузчик не видит раздел freebsd-ufs внутри freebsd и тупо вылетает в перезагрузку. Ничего не посоветуете, что делать? Забить и поднять gpt поверх gmirror поверх дисков или как?

    ОтветитьУдалить
    Ответы
    1. Загрузочный код gptboot не умеет находить UFS разделы внутри BSD label. Если вы используете GPT и хотите загружаться с UFS, то вам нужно использовать GPT разделы с типом "freebsd-ufs". В принципе, проведя небольшие расчёты можно переделать раздел с типом "freebsd" в несколько разделов "freebsd-ufs". Главное сохранить все смещения и сделать бекап :)

      Удалить
  3. Полезная информация. И в хэндбук сюда http://www.freebsd.org/doc/handbook/geom-mirror.html ее бы неплохо было внести...

    ОтветитьУдалить
  4. По-моему, кто-то уже работает над обновлением этой главы. В списке рассылки freebsd-doc@ были какие-то патчи для review.

    ОтветитьУдалить