Показаны сообщения с ярлыком LDM. Показать все сообщения
Показаны сообщения с ярлыком LDM. Показать все сообщения

понедельник, 2 апреля 2012 г.

Проблемы в работе zfsloader во FreeBSD

Сначала небольшой оффтопик - поддержка LDM уже включена во FreeBSD 10-CURRENT и в ближайшие пару недель будет перенесена в STABLE. В отличие от первоначальных патчей, текущая реализация умеет работать с дисками, размеченными GPT. А в остальном всё осталось примерно так же.

Теперь о теме сообщения. Возможно некоторые из вас замечали, что при загрузке FreeBSD c ZFS в качестве корневой файловой системы, наблюдается некоторая задержка между идентификацией дисков и началом загрузки ядра. Эта задержка в ряде случаев (например, большое количество дисков; много разделов; система в гостевой виртуальной машине) может составлять довольно ощутимое время.

Потратив некоторое время на изучение кода в каталоге sys/boot, могу сделать вывод, что работа нашего загрузчика zfsloader далеко не оптимальна. И корни этой проблемы растут с давних времён.

Во-первых, на данный момент из-за "ограниченности vs. универсальности" интерфейса libstand(3) нет никакой возможности определить количество найденных дисков из кода инициализации ZFS. Поэтому ZFS просто последовательно пробует открыть каждый диск поддерживаемый загрузчиком, а это 32 штуки (от "disk0:" до "disk31:").

Во-вторых, опять же, нет никакой возможности из кода инициализации ZFS узнать тип таблицы разделов и количество разделов в ней, чтобы проверить наличие ZFS на этих разделах. Поэтому выполняется простой перебор всех возможных разделов из диапазона от 1 до 128, например, выполняется попытка откыть "disk0p1:", если не удалось, то делается попытка открыть "disk0s1:" и т.д. до 128.

В-третьих, из-за привязанности к интерфейсу libstand(3), код работы с дисковыми устройствами выполняет чтение таблицы разделов, её проверку и т.д. на каждый вызов open(2). Т.е. когда код инициализации ZFS открывает "disk0:", затем открывает каждый его раздел. Все эти действия приводят к повторному чтению таблицы разделов.

Это частично компенсируется наличием уровня блочного кэша (да, даже у загрузчика он есть). Но размер его всего 16 кБайт, поэтому промахи имеют место быть, особенно для случая с GPT, когда таблица разделов занимает от 34 секторов.

В-четвёртых, для случая с GPT не проверяется ни контрольная сумма, ни резервная таблица с заголовком. Т.е. возможен вариант, когда у второй ступени загрузочного кода gptzfsboot и zfsloader будут разные представления о таблицах разделов.

В итоге, я написал вот такой вот патч, который решает часть проблем, но всё же далеко не идеален. Хотя, судя по отзывам увеличивает скорость инициализации загрузчика на порядок.

В идеале же хочется выделить логику работы с таблицами разделов (а он встречается в sys/boot не один и не два раза) в отдельные файлы с необходимым интерфейсом, не зависящим от libstand(3). Но пока работа в этом направлении идёт неспешно.

понедельник, 12 марта 2012 г.

FreeBSD и динамические диски Windows

Некоторое время назад в IRC обсуждалась тема невозможности доступа из FreeBSD к динамическим томам Windows, которые так же известны как тома LDM (Logical Disk Manager). Задача показалась мне интересной и вполне решаемой. В итоге, после проведения "обзора технической литераторы" и известных реализаций, оказалось, что формат метаданных не такой уж и тривиальный. К тому же, нет ниодной официальной публикации этого формата. Единственной информацией, похожей на документацию были описания от уже умершего проекта linux-ntfs. Реализация с открытым кодом тоже была одна, от того же проекта. Эта же реализация сейчас находится и в ядре linux. Ещё нашлась утилита от Марка Руссиновича, выводящая информацию о LDM и пара его публикация на эту тему.

По своим возможностям LDM напоминает LVM в linux. В качестве таблицы разделов LDM может предоставить порядка 2000 томов (нигде не нашёл точной информации, поэтому оценка дана изходя из размеров). Кроме функции таблицы разделов LDM может реализовывать RAID0, RAID1, RAID5, объединения из нескольких дисков, а также различные комбинации из перечисленного. Microsoft лицензировала LDM у Veritas, но по возможностям продукт Veritas более функциональный и изначально был доступен для UNIX. Ходят слухи, что у Microsoft и Veritas были какие-то судебные разбирательства из-за LDM. Но суть не в этом...

Метаданные LDM обладают некоторой избыточностью для отказоустойчивости. Во-первых, внутри группы дисков LDM хранит свои метаданные на каждом диске. Во-вторых, внутри самих метаданных некоторые структуры дублируются, а так же имеется журнал транзакций изменений внутри базы LDM. Для пользователей FreeBSD диск с LDM обычно выглядит как диск с MBR на котором имеются разделы с типом "ms-ldm-data" или его цифровой эквивалент "!66". Но, LDM может работать и с дисками, размеченными GPT. На них кроме раздела "ms-ldm-data" присутствует ещё раздел с типом "ms-ldm-metadata". Метаданные занимают 1 Мегабайт в конце диска. Кроме того, у дисков с MBR имеется ещё дополнительный заголовок в 6-ом секторе, по этому заголовку можно найти расположение основных метаданных. Как показала практика, находиться они могут не в самом конце диска.

Углубляться в строение я не буду, если интересно - можно почитать по ссылкам выше. Хотя, практические эксперименты выявили несколько несоответствий описания с реальностью.

В итоге, теперь чтобы получить доступ к разделам на LDM из FreeBSD можно воспользоваться написанным мною модулем geom_part_ldm. Модуль умеет находить и парсить базу LDM, и на основе прочитанной информации создавать разделы. Поддерживаются только простые тома, а так же зеркальные тома при установке переменной kern.geom.part.ldm.show_mirrors=1. Для реализации span/stripe/raid5 желающие вполне могут воспользоваться услугами класса GEOM_RAID :)

Если у кого-то возникнут проблемы с этим модулем, пишите. Есть желание включить его в head/, если никто не будет против.