пятница, 10 декабря 2010 г.

GEOM: практические знания. Часть 1.

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

Начнём с определений. Что такое GEOM класс? Классом он называется в связи с похожестью на классы в Си++. Т.е. это некоторая структура, содержащая в себе методы-функции которые реализуют возможности этого класса. Набор методов стандартный для всех классов. Грубо говоря, разработка какого-то нового класса - это новая реализация этих методов.

GEOM класс может иметь объекты (а может и не иметь). Если проводить аналогии с классами Си++, то это переменные этого класса. Например, есть GEOM класс MIRROR, он предоставляет возможность создавать зеркала. Когда вы загружаете модуль ядра, либо он у вас вкомпилирован туда, то ядро "знает" о существовании такого класса. Но когда вы создаёте зеркало, вы создаёте объект этого класса.

Каждый объект geom может иметь "провайдера" (provider), даже несколько. Провайдер, это в общем-то то, ради чего GEOM и придуман. Они предоставляют пользователю услугу реализуемую GEOM классом. Тот же GEOM класс MIRROR предоставляет нам провайдера, например mirror/gm0, работая с которым мы получаем "услугу", реализующую программное зеркало.

Другим важным понятием является консьюмер (consumer). Консьюмер - это то, через что geom объект получает доступ к провайдерам других объектов geom. Пример: у вас есть два жестких диска. Кстати говоря, драйверы дисков создают geom объекты класса DISK. Вы можете выполнить команду "geom DISK list", чтобы просмотреть информацию об объектах класса DISK:

 > geom DISK list
Geom name: ada0
Providers:
1. Name: ada0
   Mediasize: 41110142976 (38G)
   Sectorsize: 512
   Mode: r0w0e0
   fwsectors: 63
   fwheads: 16

Geom name: ada1
Providers:
1. Name: ada1
   Mediasize: 163928604672 (153G)
   Sectorsize: 512
   Mode: r2w2e5
   fwsectors: 63
   fwheads: 16
Как видно, у меня тут два диска ada0 и ada1. Они у меня разные да и заняты данными, так что портить для демонстрации я их не буду. Создам два идентичных объекта класса MD:

# mdconfig -s 100m
md0
# mdconfig -s 100m
md1
# geom MD list
Geom name: md0
Providers:
1. Name: md0
   Mediasize: 104857600 (100M)
   Sectorsize: 512
   Mode: r0w0e0
   type: swap
   length: 104857600
   fwsectors: 0
   fwheads: 0
   unit: 0

Geom name: md1
Providers:
1. Name: md1
   Mediasize: 104857600 (100M)
   Sectorsize: 512
   Mode: r0w0e0
   type: swap
   length: 104857600
   fwsectors: 0
   fwheads: 0
   unit: 1
Как видно из вывода команд, у нас есть два объекта md0 и md1, у каждого из них по одному провайдеру, соответственно md0 и md1. Теперь, при создании geom объекта класса MIRROR его консьюмеры подключатся к провайдерам объектов md0 и md1, и будет создан провайдер mirror/gm0:

# gmirror label gm0 md0 md1
# geom MIRROR list
Geom name: gm0
State: COMPLETE
Components: 2
Balance: load
Slice: 4096
Flags: NONE
GenID: 0
SyncID: 1
ID: 7231867
Providers:
1. Name: mirror/gm0
   Mediasize: 104857088 (100M)
   Sectorsize: 512
   Mode: r0w0e0
Consumers:
1. Name: md0   Mediasize: 104857600 (100M)
   Sectorsize: 512
   Mode: r1w1e1
   State: ACTIVE
   Priority: 0
   Flags: NONE
   GenID: 0
   SyncID: 1
   ID: 2647920667
2. Name: md1
   Mediasize: 104857600 (100M)
   Sectorsize: 512
   Mode: r1w1e1
   State: ACTIVE
   Priority: 1
   Flags: NONE
   GenID: 0
   SyncID: 1
   ID: 4248479672
Думаю этого должно быть достаточно для понимания, если недостаточно, попробуйте прочитать ещё раз :)

Глядя на вывод команды geom <КЛАСС> list можно увидеть много полезной информации, для каждого класса "полезность" определил разработчик, поэтому у каких-то классов больше, у других - меньше, у третьих вообще ничего нет...

Я бы хотел обратить внимание на строку содержащую слово "Mode:" и набор букв с цифрами. Она есть у всех провайдеров и консьюмеров и показывает режим доступа, который осуществляется по отношению к ним на данный момент. В первом выводе "geom MD list" режим доступа к провайдерам отображается как "r0w0e0". Это означает, что никто не пытается с них читать (r = 0), никто не пытается на них записывать (w = 0) и никто не пытается получить эксклюзивный доступ к ним (e = 0).

Эти счётчики служат не только для отображения информации о текущем состоянии провайдеров и консьюмеров. Они так же являются ограничителями доступа. Например, если кто-то уже получил эксклюзивный доступ к провайдеру, то любой другой желающий получить доступ к нему будет "обрадован" сообщением об ошибке EPERM - "Operation not permitted". Наверное, многие из вас сталкивались с этим сообщением при попытке записать загрузочный код на провайдер, который содержит смонтированные разделы. Именно эта "защита от прострела ноги" отключается переменной "kern.geom.debugflags=16".

Если выполнить команду "geom MD list" сейчас, после создания зеркала на них, то мы увидим, что у провайдеров изменился режим:

# geom MD list
Geom name: md0
Providers:
1. Name: md0
   Mediasize: 104857600 (100M)
   Sectorsize: 512
   Mode: r1w1e1
   type: swap
   length: 104857600
   fwsectors: 0
   fwheads: 0
   unit: 0

Geom name: md1
Providers:
1. Name: md1
   Mediasize: 104857600 (100M)
   Sectorsize: 512
   Mode: r1w1e1
   type: swap
   length: 104857600
   fwsectors: 0
   fwheads: 0
   unit: 1
Это постарались консьюмеры объекта mirror/gm0. Т.е. теперь, эти провайдеры защищены от случайной записи с вашей стороны, а значит и объект mirror/gm0 не будет неприятно удивлён испорченными данными. Поэтому использование "kern.geom.debugflags=16" является плохой практикой.

... Продолжение следует ...

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

  1. Немного оффтоп, но хочется спросить.
    1. а почему в RSS отдаётся не полный пост, это так задумано, или так вышло? очень бы хотелось полный.
    2. ну и чтоб два раза не вставать, так ли необходима качпа, по моему от неё больше хлопот реальным пользователям чем ботам ;)

    ОтветитьУдалить
  2. и вдогонку, если не сложно то там в профиле есть настройки, что бы коментирование происходило прямо в теле статьи, а то эти отдельные окна, как то не сильно удобны, да и 21-й век всё таки уже на дворе :)

    ОтветитьУдалить
  3. По 2-му и 3-му пункту сделал, а по первому, считаю, что так правильнее :)

    ОтветитьУдалить
  4. Ну хозяин барин конечно, просто зачастую в ридере удобнее читать, и когда материал туда не полный отдаётся часто просто проматывается.

    ОтветитьУдалить
  5. Спасибо за статью! Наконец адекватное представление появилось об этих классах....

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