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

вторник, 1 июля 2014 г.

Реализация disklabel64 для FreeBSD

В этом посте я хочу рассказать о не так давно добавленной поддержке disklabel64 в GEOM_PART. Эта "таблица разделов" используется в DragonFlyBSD. На сколько я могу судить по коду, используется она там по-умолчанию. Я не являюсь пользователем DragonFlyBSD, но не смотря на это, я подписан на их рассылку для разработчиков, в которую посылаются commit messages. Так как это всё же форк FreeBSD, то их кодовая база пока ещё довольно близка к FreeBSD и там бывают интересные коммиты.
disklabel64 является неким гибридом GPT и disklabel, используемой во всех BSD. Число 64 в названии намекает на то, что все смещения и размеры внутри метаданных являются 64-битными, в отличие от disklabel, где они были 32-битными. Ещё одно важное отличие - в 64-битной версии все смещения указаны в байтах, а не в секторах. Это, при соблюдении некоторых условий, должно позволить disklabel64 оставаться работоспособной при изменении размера сектора. Например, когда у вас есть диск, где размер сектора можно переключить перемычкой. Если создать disklabel64 на диске, у которого размер сектора 512 байт, а потом через некоторое время переключить его на 4096 байт, то для пользователя ничего не изменится. А в GPT такой трюк не получится. Полезность этого функционала конечно довольно сомнительна, но она заложена в дизайн.
По-умолчанию disklabel64 может иметь 16 разделов, но резервирует место для 32. Они так же как в disklabel именуются буквами латиницы. Но для совместимости со старым софтом, раздел 'с' недоступен для пользователя. Если кто-то не помнит, то раньше в disklabel этот раздел адресовал весь диск или раздел, на котором находится disklabel. В disklabel64 пользователь не может обратиться к области метаданных через разделы. Т.е. метаданные защищены от "самоуничтожения". В disklabel если вы специально не позаботились и не создали раздел 'a' со смещением относительно начала диска, то у вас имеется возможность уничтожить метаданные выполнив запись на раздел.
Сами разделы обзавелись UUID'ами. Каждый раздел имеет свой уникальный UUID. Тип раздела может быть указан двумя способами - так же как в disklabel при помощи 8-битного числа, либо как в GPT при помощи UUID. Сама disklabel64 тоже имеет UUID, а так же 64 байта для символьной метки. Т.е. при желании можно добавить соответствующую поддержку в geom_label и использовать эти UUID'ы как метки.
Место для загрузочного кода резервируется между метаданными и началом доступного пользователю места для создания разделов. По-умолчанию это 32 кбайта.
В метаданные заложена возможность наличия резервной копии, но пока что она нигде не реализована.

Если у вас установлена DragonFlyBSD, то теперь у вас есть возможность обратиться к её разделам. Если конечно вы используете UFS :)

пятница, 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 хочу сообщить, что в текущей версии было исправлено несколько ошибок. Последнюю версию можно скачать тут.

четверг, 29 апреля 2010 г.

sade - редактор диска, часть 5.

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

Я же выделил код и объявления структур и функций для работы с устройствами, партициями и файловыми системами в отдельную группу файлов. Позже оформлю их в виде библиотеки. Написал код для получения информации о файловых системах и сохранения его в список, которой используется внутри редактора файловых систем. Сделал базовую реализацию редактора, пока что он отображает список партиций имеющих тип freebsd-swap и freebsd-ufs:
На список команд не обращайте внимание, это copy-paste из редактора партиций. В принципе, кроме того что видно в списке сейчас, информационная структура хранит ещё данные о том смонтирована ли файловая система и опции монтирования из /etc/fstab.
Сделал так же проверку на наличие меток glabel, под которыми данное устройство может быть смонтировано или записано в fstab. Правда пока эта проверка достаточно формальная, потому как перебрать все возможные метки какие могут быть - достаточно нетривиальная задача.

Дальше буду думать, какие команды добавить в этот редактор и потихоньку их реализовывать.
Ещё надо что-то придумать с механизмом commit/undo для этого редактора. Небольшой набросок механизма ведения истории действий с возможностью отката и сохранения я сделал, но ясной картины как я буду его использовать пока нет.

пятница, 23 апреля 2010 г.

gpart resize - лёд тронулся.

Ну вот, переодическое "капанье на мозг" :-) дало первые результаты. Marcel закоммитил мой патч, добавляющий поддержку изменения размера провайдеров внутри схемы. Константин Белоусов (kib@) посоветовал не забыть через некоторое время напомнить ему сделать MFC. Думаю недельки через 3-4 можно будет начинать "напоминать" :-)

А пока, отправил ему письмо с благодарностью и ссылками на следующие два патча :-)

gpart recover - восстановление таблицы GPT

Когда я писал патч для изменения размеров партиций, я пытался решить свою задачу, что, в принципе, мне удалось. Тут в списке рассылки freebsd-geom@ появился человек, заинтересованный в изменении размера носителя, на котором находится схема GPT. У него используется RAID контроллер, который позволяет наращивать дисковое пространство, что-то вроде `zpool attach`. Вставил ещё диск, подключил его к рейду и вот - у тебя уже больше свободного места. Проблема только в том, что GPT хранит две копии метаданных - в начале диска и в конце.
Соответственно, после увеличения размера носителя, вторая копия будет находится уже не в конце и система при подключении этой GPT схемы выдаст в лог такие строчки:
GEOM: md0: the secondary GPT table is corrupt or invalid.
GEOM: md0: using the primary only -- recovery suggested.
Но, на данный момент, штатной возможности восстановить метаданные нет. Она есть в планах на wiki.freebsd.org. И я уже спрашивал Марселя о том, что он думает на этот счёт, но ответа не получил. Поэтому немного почитав код реализации схемы GPT, сделал набросок патча, который помимо восстановления метаданных позволяет выполнять такую "махинацию" с изменением размера носителя. Патч и пример использования можно посмотреть тут.

четверг, 22 апреля 2010 г.

sade - редактор диска, часть 4

После небольшого перерыва решил продолжить эпопею с sade.

От marcel@ по прежнему тишина, поэтому думаю придётся отказаться от использования geom_part.so в пользу libgeom. В связи с этим предстоит частичное дублирование кода из geom_part.so у себя. В основном это будет код записи загрузочного кода и автоподбора параметров. Но зато стандартно и без лишних костылей...

После непродолжительных обсуждений в IRC и некоторого обдумывания придумал, как примерно будет выглядеть интерфейс для работы с ZFS и создания файловых систем. К тому же решил, что будет полезной возможность создания RAID при помощи GEOM классов. Поэтому добавил главное меню, в котором пока 3 пункта:
[Image]
Пока что работает только второй, но дело сдвинулось с мёртвой точки.

По моей логике работа с sade будет выглядеть примерно так:
  1. Сначала пользователь может зайти в раздел RAID (если ему нужно это) и там выбрать устройства, которые он планирует объединить в RAID. Причём кроме обычных gmirror и gstripe думаю туда же добавить и возможность создания ZFS пула из нескольких устройств (т.е. mirror, raidz, raidz2). Возможно стоит туда же втиснуть возможность конфигурирования gjournal, geli,... Но про последние пока не думал, да и не использовал я их по сути.
  2. После создания конфигурации для RAID, либо сразу, если она не нужна, пользователь заходит во второй пункт. Тут уже открывается список устройств, из которых можно выбрать только одно (единовременно) и дальше типовой функционал gpart. Создание схемы, добавление партиций на неё и запись загрузочного кода. Сюда же входит создание разметки BSD. Для ZFS будет отдельный редактор, больше похожий на редактор файловых систем. Он будет открываться при выборе ZFS пула из списка устройств. Или когда пользователь выберет в списке возможных схем "создание ZFS пула".

    Вообще, работу с ZFS думаю реализовать по аналогии с партициями. Создание пула соответствует созданию схемы, а создание датасетов - созданию партиций. Т.е. например, когда в редакторе партиций нажать Enter на партиции с типом freebsd-zfs, то будет предложено создать пул на ней (если конечно там его ещё нет), после чего откроется редактор ZFS, в котором можно создавать датасеты.
  3. После создания партиций пользователь должен будет выйти в главное меню и выбрать третий пункт. Это будет тоже отдельный редактор, над созданием которого сейчас я начинаю работать. Это будет список, пока я планирую выводить 4 столбика:
    имя_провайдера<--->тип_ФС<--->Размер<--->Точка монтирования

    В список поддерживаемых ФС пока планирую включить: ufs, zfs, swap. Ещё там может отображаться "empty" и "unknown". "empty" для свежесозданных партиций, а "unknown" для случая когда нет прав для того чтобы определить тип ФС или ещё чего-то непредвиденного.
Вот как-то так..

воскресенье, 11 апреля 2010 г.

sade - редактор диска, часть 3

По совету Константина (kib@) опубликовал RFC в списках рассылки freebsd-current@ и freebsd-geom@ на тему переписывания sade(8). Как оказалось я не единственный, кто этим занимается, но другим, пока что, показать совсем нечего. Поэтому решил продолжать сам.

Закончил все функции редактора и нашёл ещё один "полубаг" в реализации схемы APM. Класс не находит метаданные схемы APM, если после её создания не было создано ниодной партиции. Но в общем-то это не так страшно.

Из плюсов этого RFC было то, что ответил Marcel. Написал что он очень занят, но патчи нужно всётаки коммитить, попросил переслать всё, что я ему посылал до этого. Переслал. Опять тишина...

Исправил баг в схеме MBR, который вызывал панику при отмене удаления схемы. Модифицировал подобным же образом все схемы, которые могут зависеть от геометрии провайдера. Ответа пока тоже нет...

Выложил всё, что накодил для sade вместе со скриншотами. Если кто желает, можете потестить, только осторожно, механизмы вызова паники я вроде бы описывал ранее.

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

По загрузочному коду довольно много неясности вносит наличие множества различных вариантов и отсутсвие опыта использования большинства из них :)
Для разных схем есть различные реализации загрузочного кода, из которых сам я пробовал только mbr и boot0 для MBR схемы, и gptzfsboot с pmbr для схемы GPT. А ведь есть ещё и другие схемы, которые используются на аппартных архитектурах, которые я вообще не видел, таких как PC98 и APM. Наверное, сделаю только то, что сам пробовал, а дальше уж видно будет.

По файловым системам тоже пока вопросов больше чем ответов. По сути, FreeBSD работает только с двумя файловыми системами - UFS и ZFS. С ZFS отдельная история, так как она не обычная файловая система, а ещё и в некоторой степени LVM. Поэтому, думаю что стоит начать с реализации только UFS. Дальше опять вопросы - где должен быть реализован функционал создания файловых систем? Внутри редактора партиций или же в отдельном редакторе? С точки зрения моей логики, вроде бы удобнее создать файловую систему сразу после создания партиции. Но опять же, куда в редакторе размещать все элементы интерфейса? Где отображать точку монтирования, опции для newfs и т.п.?

Короче, работы ещё полно...

среда, 7 апреля 2010 г.

sade - редактор диска, часть 2

Фреймворк для создания "нестандартных" диалогов практически готов, по крайней мере он почти обеспечивает мои текущие нужды. Называется он "customdlg". Появилось пара мыслей по его улучшению, но это пока можно отложить на будущее. Как говорится - нет предела совершенству :).

После фреймворка я продолжил реализацию оставшихся функций редактора партиций. На данный момент уже работают:
  • Create Slice - создание партиций;
  • Delete Slice - удаление партиций; когда все партиции удалены эта же команда предлагает уничтожить текущую схему (gpart destroy);
  • Undo All Changes - отмена несохранённых изменений (gpart undo);
  • Write Changs - сохранение изменений на провайдер (gpart commit);
  • Set Active - установка аттрибута активной партиции для схем MBR и PC98 (gpart set -a active);
  • Inspect Slices - откытие субредактора партиций для схемы BSD, т.е. если имеется партиция с типом "freebsd" то нажав на ней Enter открывается тот же редактор партиций (если необходимо, с предложением создать схему BSD на провайдере) но слегка ограниченный.
В принципе, нереализованными остались только команды "Change Type" и "Set Label", которые я решил объединить в один диалог. Но это дело получаса работы. И тогда можно будет анонсировать куда-нибудь в freebsd-hackers@ или freebsd-geom@, посмотреть что люди думают, может какие-то предложения будут дельные.

Да, ещё.  В процессе реализации функционала и тестирования было обнаружено два бага в реализации класса PART. Первый заключается в том, что созданную схему "BSD" и "VTOC8" нельзя отменить при помощи команды "gpart undo". Эту проблему я решил, осталось дождаться, что ответит мэйнтейнер gpart. Ну и второй - он уже более неприятен. После создания схемы MBR без разделов, попытке удалить её и отменить удаление, в модуле geom_part_mbr происходит деление на ноль и паника. Покопавшись немного простого решения не нашёл, пока открыл PR. Если Marcel до завтра не ответит, буду пытаться решать сам.

четверг, 1 апреля 2010 г.

sade - редактор диска

После изучения GEOM класса PART и беглого просмотра кода редактирования слайсов в sysinstall и "отпочковавшегося"  от него sade, захотелось научить их делать это "правильно" :)

Но чем дальше я читал код sade и думал как бы его лучше изменить, тем всё грустнее мне казалась эта перспектива. Поэтому я начал с малого, набросал код функций для типовых операций, проводимых с диском. Сначала это были функции получения списка устройств, пригодных для разметки, и получения таблицы партиций на устройстве. Эти действия легко реализуются при помощи libgeom. Попутно изучал более подробно код sade и пробовал различные примеры по использованию libdialog и ncurses.

Когда встала задача написания функций редактирования таблиц партиций, то мне показалось целесообразным использовать уже написанный код библиотеки geom_part, которая используется утилитой gpart(8). Всё бы ничего, но как оказалось, библиотека не предназначена для этого. Т.е. в рамках приложения gpart(8) она это вполне успешно делает, но вот из своего приложения её использовать нельзя, так как библиотека обрабатывает ошибки при помощи вызовов err(3) и abort(3). Пришлось отучить её от этого, после чего получилось использовать её код.

В своих же функциях мне просто осталось правильно сформировать запрос, заполнив нужные параметры, и вызвать функцию из библиотеки geom_part.

Очень полезной оказалась и встроенная поддержка отложенных операций в классе PART, т.е. из своего приложения можно выполнять различные действия с таблицей партиций, а при необходимости можно сделать откат, либо сохранить все изменения на диск.

Далее я принялся за интерфейс пользователя. По-началу дело шло неплохо. Вот так к примеру выглядит окно выбора устройств:
Приятным бонусом от использования libgeom стало появление в списке устройств различных GEOM провайдеров. Вообще, полный список поддерживаемых устройств выглядит так:
        {"DISK",        "disk device"},
        {"MD",          "memory backed virtual disk"},
        {"ZFS::ZVOL",   "ZFS volume"},
        {"MIRROR",      "GEOM based mirror (RAID1)"},
        {"STRIPE",      "GEOM based stripe (RAID0)"},
        {"RAID3",       "GEOM based RAID3 array"},
        {"CONCAT",      "GEOM based concatenated disk"},
        {"ELI",         "GEOM based encrypted disk"},
        {"JOURNAL",     "GEOM based journalled disk"},
        {"MULTIPATH",   "GEOM based disk with multiple path"},
Список редактируется легко, так что добавить новое, либо что-то убрать из него не составить труда.
После выбора устройства по логике должен открываться редактор партиций, за основу я взял существующий в sysinstall и sade, но слегка изменил и улучшил его. Вот так он выглядит:
Пока что он ничего полезного не делает, кроме отображения списка партиций и навигации по нему. В дополнение к этому я сделал ещё один диалог, который открывается при выборе устройства, на котором ещё нет таблиц партиций:
После выбора типа таблицы она создаётся на носителе и открывается редактор партиций.

Вот. Это пока то, что удалось реализовать без особых сложностей. Теперь встала задача добавления новых диалогов. Как оказалось библиотека libdialog предоставляет довольно скудные возможности для создания диалогов, отличающихся от стандартных. А те что предоставляет, выглядят как-то "топорно". Поэтому... Пишу вот сейчас некий "фреймворк" для создания нестандартных диалогов. Вот таким, к примеру, планируется диалог добавления нового слайса:
БОльшая часть "фреймворка" уже написана. Осталось немного и можно будет продолжить реализовывать функции редактора партиций. Ну и ещё остались пока нерешённые вопросы:
1. Что делать с ZFS?
2. Как создавать файловые системы, надо ли их монтировать, надо ли их в fstab прописывать и т.п.

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

gpart: изменение размера раздела

Доделал поддержку изменения размера разделов для GEOM класса PART. На данный момент идеи "что бы туда ещё добавить" закончились, поэтому решил выложить патчи.

Немного о цели патчей. Были у меня несколько машин, на которые я уже давно для тестов ставил FreeBSD с ZFS. Они полностью установлены на ZFS, но было оставлено свободное пространство "на всякий случай". Там используется GPT "схема" со "стандартной" разбивкой на три партиции: freebsd-boot, freebsd-swap и freebsd-zfs. Свободное место было оставлено в конце диска. И вот, в один прекрасный момент захотелось использовать свободное место. Но создавать отдельную партицию не хотелось после успешных экспериментов по расширению пула ZFS.

После постановки задачи "как это сделать" очевидных решений найдено не было. Первое, что пришло на ум - поправить в таблице GPT размер партиции. Решил попробовать, подампил таблицу в файлы, поизучал формат... Решил посмотреть, что там в коде реализации. Оказалось, что "заготовка" базового метода resize уже имелась в коде класса. Только она ничего не делала, а возвращала ошибку ENOSYS.

Я связался с автором класса PART - Marcel Moolenaar. Обсудил с ним что и как лучше реализовать. После чего взялся за эксперименты. Что в итоге получилось, можно увидеть здесь. Ход работы можно проследить в perforce.

Если в кратце, то в начале пришлось заново вспомнить изучить для чего в дереве кода ядра используются файлы с расширением "*.m". Они применяются для создания подобия ООП в коде ядра. Как я уже упоминал ранее, структура класса PART интересна своей модульностью. Сам класс имеет базовые методы работы с партициями, а все детали реализации описываются в отдельных модулях схем. Так вот, в .m файлах описан программный "интерфейс" подобных модулей. Эти файлы обрабатываются awk скриптом во время компиляции ядра и генерируются файлы .c и .h.

Грубо говоря, благодаря им и создаётся иллюзия ООП. Хотя на мой взгляд всё довольно условно :) Итак, реализовав базовый алгоритм изменения размера в ядре и добавив новую команду в утилиту управления gpart, я добавил поддержку в GPT схему. Потестировал на md(4) дисках - вроде работает и даже не паникует :)
Решил попробовать на рабочей системе, попробовал - размер изменился, перезагрузился - пул "подхватил" свободное пространство и я счастлив :)

После этого добавил поддержку в оставшиеся схемы, немного потестировал на том же md(4) и вроде всё. Да, только в EBR не стал добавлять, там как-то не всё гладко в реализации.

Пример использования:
# gpart show md0
=>    34  409533  md0  GPT  (200M)
      34  204800    1  freebsd-zfs  (100M)
  204834  204733       - free -  (100M)

# gpart resize -s 150m -i 1 md0
md0p1 resized
# gpart show md0
=>    34  409533  md0  GPT  (200M)
      34  307200    1  freebsd-zfs  (150M)
  307234  102333       - free -  (50M)

# gpart resize -i 1 md0
md0p1 resized
# gpart show md0
=>    34  409533  md0  GPT  (200M)
      34  409533    1  freebsd-zfs  (200M)

У команды resize есть два параметра "-i index" и "-s size". Указание индекса обязательно, а вот размер может быть вычислен автоматически. Изменяться может только смещение конца партиции, смещение начала всегда остаётся неизменным.

И ещё важное замечание - изменяются только метаданные таблицы разделов, изменение размеров файловой системы нужно производить сторонними методами, например growfs для UFS. ZFS сама видит увеличение. Уменьшение разделов не запрещено и работает, но что на это скажет файловая система раздела - мне, честно говоря, не очень хочется узнавать :)

четверг, 18 марта 2010 г.

Использование gpart

Утилита gpart служит для управления GEOM классом PART. На самом деле это хардлинк на утилиту geom(8), которая является универсальной утилитой управления для многих GEOM классов.

Как я уже упоминал в предыдущей заметке, класс PART служит для работы с таблицами партиций и предоставляет доступ к провайдерам этих партиций. С появлением этой утилиты можно уже забыть такие утилиты как fdisk и bsdlabel, они морально устарели. Большинство их действий можно выполнять при помощи утилиты gpart. Нужно только понять и запомнить основные понятия - схема и партиция. Прежде чем создавать партиции, необходимо выбрать тип таблицы - схему. Например, для привычной разметки с использованием MBR необходимо выполнить команду 'gpart create' с указанием имени схемы в опции "-s mbr":
# gpart create -f x -s mbr md0
md0 created
# gpart show md0
=>     17  1023978  md0  MBR  (500M)
       17  1023978       - free -  (500M)

# gpart commit md0
Опция "-f x" указывает классу не вносить изменения на провайдер носителя сразу. Т.е. если вы не уверены в своих действиях, вы можете с каждой командой указывать эту опцию и после того как будете уверены, выполнить команду `gpart commit`, либо отменить изменения командой `gpart undo`. Не имеет значения, какой флаг вы укажете после опции "-f", т. к. класс отслеживает только наличие опции и её отличие от значения, принятого по-умолчанию. Если не указывать опцию "-f", то её значение по-умолчанию будет установлено в "-f C", что приведёт к автоматическому выполнению команды `gpart commit`.

Таблица MBR может содержать максимум 4 записи, т.е. не более 4 партиций. После того как схема создана можно создавать партиции при помощи команды `gpart add`. Каждая партиция обладает несколькими обязательными свойствами - смещение начала, смещение конца, индекс в таблице и тип партиции. А так же одно дополнительное свойство, которым обладают партиции некоторых схем - символьная метка.  Все эти параметры видны пользователю, за исключением смещения конца. Смещение заменяется на вычисляемый из него размер.
К тому же, для создания партиции при помощи утилиты gpart нужен только один обязательный параметр - это тип партиции, остальные параметры могут быть вычеслены автоматически.

Тип партиции может быть задан символьным именем либо специальным номером, в зависимости от используемой схемы. Поддерживаемые символьные имена можно увидеть в мануале gpart(8). При необходимости задать какой-то специфический для схемы тип партиции, он указывается после знака восклицания. Например, для схемы MBR тип партиции FreeBSD представлен номером 165, который можно указать как "-t !165" (не забываем экранировать знак восклицания, если выполняем команду из shell - "\!165"), либо символьным именем "-t freebsd".

Размер и смещение начала партиции по-умолчанию задаются в блоках, размер которых обычно соответствует размеру физического сектора, т.е. 512 байт. Для того чтобы не вычислять количество блоков, эти параметры можно указывать с суффиксом размера: b, k, m, g, t, p, e - т.е. от байт до экзабайт. Но есть одна особенность реализации - парсер при разборе этих параметров ещё не знает какой размер сектора имеет носитель, поэтому если он отличается от 512 байт, то лучше указывать размер в секторах, иначе размер будет вычислен неправильно.  Размер партиции указывается после опции "-s", а смещение начала - после "-b". При опускании любого из этих параметров они выбираются автоматически: смещение начала - на первый доступный блок, размер - на максимально возможный из доступного свободного пространства.

Вычисление индекса партиции обычно можно оставить утилите gpart. Только если вам не нужна какая-нибудь особенная конфигурация, например, чтобы система устанавливалась на ad0s3 нужно указать параметр "-i 3".

Итак, схема создана, создадим партицию:
# gpart add -s 400m -t freebsd md0
md0s1 added
# gpart show md0
=>     17  1023978  md0  MBR  (500M)
       17   819196    1  freebsd  (400M)
   819213   204782       - free -  (100M)

Как видно, партиция была создана с типом "freebsd" и размером в 400 Мбайт, индекс и смещение начала были выбраны автоматически.

Теперь на созданной партиции можно сделать дополнительную разметку для BSD схемы:
# gpart create -s bsd md0s1
md0s1 created
# gpart show md0
=>     17  1023978  md0  MBR  (500M)
       17   819196    1  freebsd  (400M)
   819213   204782       - free -  (100M)

# gpart show md0s1
=>     0  819196  md0s1  BSD  (400M)
       0  819196         - free -  (400M)

Теперь добавим партиции, только вместо bsdlabel используем тот же gpart:
# gpart add -s 100m -t freebsd-ufs md0s1
md0s1a added
# gpart add -s 100m -t freebsd-swap md0s1
md0s1b added
# gpart add -t freebsd-ufs md0s1
md0s1d added
# gpart show md0s1
=>     0  819196  md0s1  BSD  (400M)
       0  204800      1  freebsd-ufs  (100M)
  204800  204800      2  freebsd-swap  (100M)
  409600  409596      4  freebsd-ufs  (200M)

Всё достаточно легко и просто. Для записи загрузочного кода можно использовать всю ту же утилиту. Для этого предназначена команда `gpart bootcode`. Например, аналогом команды `bsdlabel -B` будет:
# gpart bootcode -b /boot/boot md0s1
md0s1 has bootcode
Аналогично можно записать загрузочный код для схемы MBR:
# gpart bootcode -b /boot/mbr md0
md0 has bootcode
Если же необходимо установить менеджер загрузки, то нужно всего лишь выбрать другой образ загрузочного кода - /boot/boot0. Так же, не стоит забывать, что у схемы MBR есть аттрибут активного раздела, чтобы его установить нужно использовать команду `gpart set`:
# gpart set -a active -i 1 md0
md0s1 has active set
# gpart show md0
=>     17  1023978  md0  MBR  (500M)
       17   819196    1  freebsd  [active]  (400M)
   819213   204782       - free -  (100M)

В принципе, этого набора команд достаточно для работы. Если иметь понятие, что и для чего нужно сделать - то сложностей в использовании вообще не вижу. Даже если такая необходимость возникает нечасто, все команды утилиты gpart имеют описание:
# gpart 
usage: gpart add [-b start] [-s size] -t type [-i index] [-l label] [-f flags] geom
       gpart bootcode [-b bootcode] [-p partcode] [-i index] [-f flags] geom
       gpart commit geom
       gpart create -s scheme [-n entries] [-f flags] provider
       gpart delete -i index [-f flags] geom
       gpart destroy [-f flags] geom
       gpart modify -i index [-l label] [-t type] [-f flags] geom
       gpart set -a attrib -i index [-f flags] geom
       gpart show [-lr] [geom ...]
       gpart undo geom
       gpart unset -a attrib -i index [-f flags] geom
       gpart help
       gpart list [name ...]
       gpart status [-s] [name ...]
       gpart load [-v]
       gpart unload [-v]

среда, 10 марта 2010 г.

Немного о GEOM классе PART

В 7-ую версию FreeBSD был добавлен GEOM класс PART, который заменил собой несколько классов, реализующих поддержку таблиц партиций, таких как BSD, MBR, PC98.

Не слишком углубляясь в технические подробности реализации назначение класса PART можно представить в виде некоторого модульного механизма ядра для управления различными таблицами партиций.

Каждый пользователь FreeBSD в той или иной мере знаком как минимум с двумя типами таблиц партиций - это MBR и BSD, а в последнее время, стал пользоваться популярностью ещё один тип - GPT. В терминологии класса PART эти типы таблиц представлены "схемами". А модульность реализации позволяет включать поддержку различных схем в виде отдельных модулей ядра. Для этого реализация класса включает в себя инфраструктуру с базовыми действиями схожими для различных типов таблиц партиций. А реализация особенностей каждой из "схем" содержится в отдельных модулях, которые благодаря интерфейсу kobj(9) подключаются в базовую инфраструктуру класса.

Когда подсистема GEOM инициализирует класс PART, базовая инфраструктура класса выполняет "пробу" для каждой зарегистрированной схемы. Т.е. класс выполняет поиск метаданных схемы на носителях. Так, например, схема MBR реализует поддержку таблицы основных разделов, содержащейся в главной загрузочной записи MBR. Если "схема" обнаружит свои метаданные на носителе, она создаёт "провайдеры", через которые осуществляется доступ к партициям. Для пользователя партиции этой схемы выглядят как <имя_провайдера>s%d, где %d - номер индекса партиции в таблице. Т.е. привычные всем имена типа ad0s1 можно разделить на имя провайдера носителя ad0 и имя партиции s1, где 1 - это номер партиции в таблице.

Схема BSD реализует поддержку bsd-разделов. Это те, которые раньше создавались утилитой bsdlabel (или ещё раньше disklabel). Имена партиций этой схемы именуются латинскими буквами, например, ad0s1a. Здесь ad0 - имя провайдера носителя, s1 - имя провайдера схемы MBR, т.е. на диске ad0 была создана схема MBR и уже на первой партиции этой схемы была создана схема BSD c партицией, определяемой именем "a".

Схема GPT реализует поддержку GUID таблицы разделов. Имена партиций при использовании этой схемы формируются в зависимости от типа. Тип задаётся при создании партиции, о нём я расскажу чуть позже. Но в общем, имя может быть либо "p%d" либо "s%d", где %d - номер индекса в таблице. Обычно это "p", имя "s" используется только для типа партиции "freebsd", обозначающего, что на данной партиции будет использоваться BSD схема.

Ещё одна знакомая схема - EBR. Она используется для разметки партиций внутри расширенных разделов. И осталось ещё три неупомянутых схемы, поддержка которых реализована на сегодняшний день в классе PART: APM используемая в Apple Mac, PC98 используемая в NEC PC-9801, и VTOC8 используемая  на Sun'овских UltraSPARC.

Это краткое описание я решил написать после нескольких часов, проведённых за изучением исходного кода этого класса. И в целом, его реализация мне понравилась. Можно сказать, что она довольно красива и в духе всей подсистемы GEOM.