В началоLinux не для идиотов → Блочные устройства
Gentoo-doc HOME Пред.: Секреты /devВ началоУровень выше: Linux не для идиотовСлед.: Сетевая подсистема

14. Блочные устройства

Любое устройство, подключенное к компьютеру, имеет свое назначение, и блочные устройства в большинстве своем предназначаются для хранения информации. Как организована работа с блочными устройствами в Linux?

Во-первых, следует определиться с типами блочных устройств. Их следует поделить на две категории: к первой отнесем логические (виртуальные) устройства (loop-устройства, software RAID-устройства, устройства Volume Management, поддержка различных таблиц разделов), ко второй категории – физические устройства (SCSI диски и CD-ROM'ы, IDE-диски, USB-storage, RAM-диск).

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

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

Существует множество различных форматов разбиения диска на разделы – например, DOS partition table, BSD disklabels, UnixWare slices и многие другие. Как правило, во всех случаях соответствующая спецификация предусматривает возможность перечисления ограниченного количества разделов путем указания номеров первой и последней дорожек, занимаемых каждым из разделов. Каждый раздел видится как отдельное блочное устройство.

По традиции имена блочных устройств, соответствующих IDE-дискам и созданным на них разделам начинаются с hd и имеют вид /dev/hd<N>[<M>] где N – это буква, зависящая от контроллера и канала IDE, к которому подключено устройство, и режима устройства (master/slave). M – это некоторое число от 1 до 63 (фактически номер раздела на диске). Если число не указано, подразумевается весь диск. SCSI-дискам в /dev присваиваются имена sda, sdb, sdc и т.д. Ниже приводится небольшая таблица соответствия устройств и имен специальных файлов для IDE-дисков:

Контроллер

Канал

Режим

Имя файла

1

1

master

primary master

hda

1

1

slave

primary slave

hdb

1

2

master

secondary master

hdc

1

2

slave

secondary slave

hdd

2

1

master

tertiary master

hde

2

1

slave

tertiary slave

hdf

2

2

master

quaternary master

hdg

2

2

slave

quaternary slave

hdh

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

Особой разновидностью раздела можно назвать расширенный (extended) раздел DOS. Расширенный разделы DOS может быть разбит на произвольное количество вложенных разделов, но в настоящий момент без использования LVM ядро Linux поддерживает до 63 разделов на IDE-диске и до 15 разделов на SCSI-диске. Такое ограничение связано с распределением мажоров и миноров блочных устройств.

Когда используется разбиение диска на разделы с использованием таблицы разделов DOS, следует помнить, что на жестком диске может быть не более 4 первичных разделов. Если администратору нужно, чтобы на жестком диске было более 4 разделов, необходимо объявить один из первичных разделов как расширенный раздел. Первичные разделы при использовании таблицы разделов DOS нумеруются от 1 до 4, логические разделы нумеруются начиная с 5, вне зависимости от количества первичных разделов. Только один из первичных разделов может быть объявлен расширенным.

Рассмотрим вывод команды fdisk, которая обычно используется в Linux для разбиения диска на разделы:

# fdisk /dev/hda -l
         Disk /dev/hda: 6442 MB, 6442450944 bytes
16 heads, 63 sectors/track, 12483 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1         203      102280+  83  Linux
/dev/hda2             204        2032      921816   83  Linux
/dev/hda3            2033        3072      524160   82  Linux swap
/dev/hda4            3073       12483     4743144    f  W95 Ext'd (LBA)
/dev/hda5            3073        4088      512032+  83  Linux
/dev/hda6            4089       12483     4231048+  83  Linux

Как видно, на жестком диске IDE созданы 6 разделов, из них 4 первичных (разделы с номерами от 1 до 4) и два логических раздела с номерами 5 и 6, созданных внутри extended-раздела hda4.

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

Если нет возможности запустить программу fdisk, то для получения данных о разметке блочных устройств на разделы и о состоянии блочных устройств, доступных в настоящий момент, можно использовать некоторые файлы из файловой системы /proc:

$ cat /proc/partitions
major minor  #blocks  name
   3     0   78150744 hda
   3     1    1084356 hda1
   3     2   77063805 hda2
 253     0    1048576 dm-0
 253     1    1048576 dm-1
 253     2   10485760 dm-2
 253     3   10485760 dm-3
 253     4    1048576 dm-4
 253     5   41943040 dm-5
 253     6     360448 dm-6
 253     7     258048 dm-7
 253     8     258048 dm-8
 253     9     258048 dm-9
 253    10      53248 dm-10
   7     0     651884 loop0
   7     1     650198 loop1
   7     2     653336 loop2
   7     3     198962 loop3

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

Интересной особенностью таблицы разделов диска является то, что она не всегда изменяема. Это приводит к тому, что во многих случаях невозможно изменить размер какого-либо раздела или внести какие-либо другие изменения в таблицу разделов без перезагрузки – т.е. системный администратор может делать любые изменения, но они вступят в силу только после перезагрузки системы.

14.1. Распределение мажоров и миноров IDE дисков

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

Всем устройствам, находящимся на одном канале IDE, присвоен один мажор. В настоящий момент ядро Linux выделяет для каждого устройства 64 минора, из которых первый минор зарезервирован для всего диска, и 63 минора остается для идентификации разделов. Таким образом, для IDE-дисков мажор идентифицирует канал, а по минору можно определить номер устройства на канале (режим master/slave) и номер раздела. Более детально это можно увидеть в следующей таблице:

Таблица 1. Распределение номеров устройств для IDE-дисков

Канал Устройство Раздел Major number Minor number Имя в /dev
1 1 Весь диск 3 0 /dev/hda
Раздел 1 1 /dev/hda1
Раздел 2 2 /dev/hda2
Раздел 3 3 /dev/hda3
Раздел 4 4 /dev/hda4
... ... ...
Раздел 63 63 /dev/hda63
2 Весь диск 64 /dev/hdb
Раздел 1 65 /dev/hdb1
Раздел 2 66 /dev/hdb2
Раздел 3 67 /dev/hdb3
... ... ...
Раздел 63 127 /dev/hdb63
2 1 Весь диск 22 0 /dev/hdc
Разделы 1-63 /dev/hdc[1..63]
2 Весь диск 64 /dev/hdd
Разделы 65-127 /dev/hdd[1..63]


По таблице становится видно, что на каждый 64-й минор происходит смена физического диска. Драйвер IDE в текущей версии ядра Linux поддерживает до четырех каналов IDE – т.е. до 8 устройств, по два устройства на канал..

Рекомендации, которую можно дать владельцам компьютеров с интерфейсом IDE: устройства по возможности рекомендуется держать на разных каналах. Если нет свободных каналов, то “быстрые” устройства лучше подключать на один канал, медленные – на другой.

14.2. Распределение мажоров и миноров для SCSI-дисков

Шина SCSI свободна от некоторых недостатков IDE, например количество устройств на одном канале может быть 15 (на самом деле 16, но одним устройством считается сам контроллер), все SCSI устройства работают на своей максимальной скорости, и ограничены только возможностями шины и контроллера – но SCSI-устройства и дороже, и поэтому шина SCSI используется в основном на серверах и рабочих станциях. Для SCSI-дисков ситуация немного меняется – мажоры не привязаны к контроллерам (т.е. один major number может использоваться дисками с разных хост-адаптеров). На каждом SCSI-диске система поддерживает до 16 разделов, а нумерация дисков производится в порядке их подключения по схеме, аналогичной IDE-дискам – но только переход на следующий диск происходит на каждом 16-м миноре (т.е. разделы на SCSI-дисках нумеруются от 1 до 15). Увидеть это можно в следующей таблице и листинге /dev:

Таблица 2. Распределение номеров устройств для SCSI-дисков

Номер диска в порядке подключения Major number Minor number Раздел Имя файла
1 8 0 Весь диск sda
1 Первый первичный sda1
2 Второй первичный sda2
3 Третий первичный sda3
4 Четвертый первичный sda4
5 Первый логический sda5
... ... ...
15 Одиннадцатый логический sda15
2 8 16 Весь диск sdb
17 Первый первичный sdb1
18 Второй первичный sdb2
19 Третий первичный sdb3
20 Четвертый первичный sdb4
21 Первый логический sdb5
... ... ...
31 Одиннадцатый логический sdb15


В текущей версии ядро Linux поддерживает до 4096 SCSI-дисков – и для абсолютного большинства  компьютеров этого должно быть достаточно. Очень важной особенностью SCSI-дисков является то, что мажор устройства, соответствующего физическому диску, не зависит от контроллера. В результате, если у вас есть 3 диска SCSI, то они всегда именуются sda, sdb и sdc, и если вы выключите компьютер и отключите первый диск, то после перезагрузки второй диск (который ранее назывался sdb) станет называться sda, а третий диск (который назывался sdc) станет называться sdb, поэтому при работе со SCSI-устройствами можно использовать devfs (которая позволяет адресовать диски через путь их подключения), либо использовать специализированные средства управления дисковым пространством, которые помечают носители и впоследствии правильно их идентифицируют даже после переименования устройств – например, средства md (software RAID) или LVM. Надо заметить, что в свете удаления devfs из основной ветви ядра, использование LVM стало фактически обязательным на серверах.

14.3. Устройства SATA и переход с IDE на PATA

SATA, «осовремененная» версия интерфейса IDE, по своей структуре приблизилась к подсистеме SCSI. Поэтому в целях унификации подсистемы ввода-вывода в ядре Linux поддержка SATA была реализована через интерфейс SCSI, соответственно SATA-диски и контроллеры видятся ядром (и пользователем) как SCSI-устройства.

В новейших ядрах линейки 2.6 также появилась возможность работы с IDE-дисками через подсистему SCSI., и в новых дистрибутивах, таких как Fedora 7, даже обычные Parallel ATA (они же IDE) диски и контроллеры представляются как SCSI-устройства, что привело к унификации подсистемы дискового ввода-вывода, и теперь все диски и CD/DVD приводы для пользователя представляются как /dev/sdX или /dev/scdX. Драйверы для обычных контроллеров IDE, которые работают по новой схеме, начинаются с префикса pata, например: pata_via – это драйвер IDE-контроллеров с чипсетом VIA, а pata_piix –  это дарйвера для IDE-контроллеров Intel, работающие  через подсистему SCSI.

А говоря проще, это означает следующее – если у вас новый дистрибутив или имеются SATA-диски, вы можете смело работать со всеми дисками как со SCSI-устройствами.

14.4. Logical Volume Manager

Использование таблиц разделов для управления дисковым пространством – достаточно часто используемое решение. К сожалению, оно не свободно от определенных недостатков – например, нет возможности расширить раздел или уменьшить его размер, нет возможности создать один раздела на нескольких дисках и т.д. Решить эту задачу призван LVM (Logical Volume Manager).

LVM работает следующим образом: пользователь может пометить какие-либо блочные устройства как разделы, используемые LVM. Каждое из таких помеченых блочных устройств (их называют физическими томам,и или physical volumes) может быть присоединено к какой либо группе логических томов (logical volume groups). Внутри групп логических томов могут создаваться уже собственно логические тома (logical volumes). Дисковое пространство любого физического тома из некоторой группы может быть выделено любому логическому тому из этой группы. Реализовано это через так называемые “экстенты” (extents) дискового пространства. Физические тома LVM разбиваются на экстенты, после чего из экстентов и составляются логические тома. Именно за счет этого можно динамически менять конфигурацию дискового пространства – экстент может быть удален из одного тома, и добавлен к другому. Каждый объект LVM – будь то логический том, физический том или группа томов, имеет свой уникальный идентификатор.

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

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

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

# fdisk /dev/hdb

            The number of cylinders for this disk is set to 79408.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/hdb: 40.9 GB, 40982151168 bytes
16 heads, 63 sectors/track, 79408 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hdb1               1       79408    40021600+  8e  Linux LVM

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

В приведенном выше выводе fdisk видно, что на IDE-диске primary slave создан один раздел типа LVM (код типа раздела 0x8E). В следующем листинге показан процесс инициализации физического тома и создания группы томов aurora, в которую включается инициализированный командой pvcreate физический том /dev/hdb1:

# pvcreate /dev/hdb1 
  No physical volume label read from /dev/hdb1
  Physical volume "/dev/hdb1" successfully created
# vgcreate aurora /dev/hdb1
  Volume group "aurora" successfully created

Третий фрагмент демонстрирует создание нескольких томов и изменение размеров томов, проделанное с помощью LVM. В этом примере создается логический том размеров в 20GB, затем размер этого тома увеличивается до 30GB, создается еще один логический том, и после этого оба созданных логических тома удаляются.

# lvcreate -L 20G -n ftpdata aurora
  Logical volume "ftpdata" created
# lvscan
  ACTIVE           '/dev/aurora/ftpdata' [20,00 GB] next free (default)
# lvresize -L +10G /dev/aurora/ftpdata 
  Extending logical volume ftpdata to 30,00 GB
  Logical volume ftpdata successfully resized
# lvscan
  ACTIVE           '/dev/aurora/ftpdata' [30,00 GB] next free (default)
# lvcreate -L 8G -n home_dirs aurora
  Logical volume "home_dirs" created
# lvscan
  ACTIVE           '/dev/aurora/ftpdata' [30,00 GB] next free (default)
  ACTIVE           '/dev/aurora/home_dirs' [8,00 GB] next free (default)
# lvremove /dev/aurora/ftpdata 
Do you really want to remove active logical volume "ftpdata"? [y/n]: y
  Logical volume "ftpdata" successfully removed
# lvremove /dev/aurora/home_dirs 
Do you really want to remove active logical volume "home_dirs"? [y/n]: y
  Logical volume "home_dirs" successfully removed

Еще один фрагмент демонстрирует удаление группы томов и очистку физического тома:

# vgremove aurora
  Volume group "aurora" successfully removed
# pvremove /dev/hdb1
  Labels on physical volume "/dev/hdb1" successfully wiped

Каждый логический том LVM имеет свой собственный minor number, а major number для всех томов LVM равен 253. Для доступа к томам LVM можно создавать блочные устройства с помощью команды mknod, а можно воспользоваться возможностями, предоставляемыми утилитой devlabel. Эта утилита создает символьные ссылки и каталоги внутри подкаталога /dev, причем для каждой группы томов в /dev создается каталог с именем этой группы, а логические тома представляются символьными ссылками из этих каталогов на блочные устройства, обслуживаемые драйвером device mapper, и тогда любой том LVM можно адресовать следующим путем: /dev/<имя_группы>/<имя_тома>. На листинге ниже показан пример того, как можно распределить дисковое пространство с помощью LVM:

# ls -la /dev/chimera
lr-xr-xr-x  1 root root 23 Окт  8 13:53 opt -> /dev/mapper/chimera-opt
lr-xr-xr-x  1 root root 24 Окт  8 13:53 swap -> /dev/mapper/chimera-swap
lr-xr-xr-x  1 root root 24 Окт  8 13:53 temp -> /dev/mapper/chimera-temp
lr-xr-xr-x  1 root root 23 Окт  8 13:53 usr -> /dev/mapper/chimera-usr
lr-xr-xr-x  1 root root 23 Окт  8 13:53 var -> /dev/mapper/chimera-var
# lvscan
  ACTIVE          '/dev/chimera/swap' [1,00 GB] next free (default)
  ACTIVE          '/dev/chimera/temp' [1,00 GB] next free (default)
  ACTIVE          '/dev/chimera/usr' [10,00 GB] next free (default)
  ACTIVE          '/dev/chimera/opt' [10,00 GB] next free (default)
  ACTIVE          '/dev/chimera/var' [1,00 GB] next free (default)
# mount | grep chimera
/dev/mapper/chimera-var on /var type ext3 (rw)
/dev/mapper/chimera-temp on /tmp type ext3 (rw)
/dev/mapper/chimera-usr on /usr type ext3 (rw)
/dev/mapper/chimera-opt on /opt type ext3 (rw)

Таким образом, возможности LVM позволяют системному администратору максимально эффективно использовать дисковое пространство, оперативно реагируя на меняющиеся условия эксплуатации. Еще одной интересной возможностью LVM является так называемый multipath I/O. В случае активации соответствующей опции  в ядре device mapper знает о том, что физический том с некоторым UUID может быть доступен через несколько контроллеров, и в случае отказа одного контроллера динамически происходит переключение ввода-вывода на другой. Опытные системные администраторы также оценят такую возможность, как создание снимка (snapshot) логического тома: при создании снимка создается моментальная копия логического тома, которая начинает «жить» независимо от того тома, на основе которого она была создана:

# sync
# lvcreate -s -L 10G -n home_snapshot /dev/chimera/home
# dd if=/dev/chimera/home_snapshot of=/dev/st0
# lvremove /dev/chimera/home_snapshot

В приведенном примере системный администратор вызовом команды sync сбрасывает все закэшированные операции на диск, создает снимок тома home из группы томов chimera, на котором «живет» файловая система /home, и этот снимок называет home_snapshot, при этом на удержание копии измененных данных выделяется 10 гигабайт дискового пространства. Каждый раз, когда будет переписываться какой-либо блок логического тома home, первоначальная версия изменяемого блока будет копироваться в те 10GB дискового пространства, которые мы выделили под снимок тома, и мы можем считать содержимое тома home_snapshot неизменным, и скопировать его на ленту. В процессе чтения, если читаемый блок не изменялся с момента создания снимка, то он читается из исходного тома (home), если же  блок менялся с момента создания снимка, то используется его копия, хранимая в зарезервированном при создании снимка пространстве. После окончания копирования мы удаляем снимок командой lvremove.

14.5. Sotware RAID

Ядро Linux содержит средства для организации software raid (программных RAID-устройств). Эта возможность поддерживается драйвером устройств md. В отличие от device mapper, драйвер md умеет работать в “самостоятельном” режиме, получая конфигурацию из параметров, которые пользователь указал ядру при загрузке системы, что позволяет организовывать загрузку системы с RAID-устройств. Все устройства md имеют мажор 254 и миноры от 0 и до 16383.

В отличие от LVM, основной задачей которого является динамическое распределение дискового пространства (деление разделов на фрагменты и построение из фрагментов новых блочных устройств), задачей подсистемы RAID является построение новых блочных устройств путем объединения существующих.

Каждое из устройств, входящих в создаваемый дисковый массив, может определенным образом помечаться. Впоследствии эти метки (их также называют array superblocks) используются для повторной сборки массива. В частности, например, суперблок массива содержит его уникальный идентификатор, который можно использовать при сборке ранее созданного массива после перезагрузки. Если программный RAID-массив был помечен в процессе создания (т.е. на нем был создан суперблок массива), это дает возможность автоматической сборки массива вне зависимости от того, поменялся или нет порядок следования устройств. Например, такая необходимость может возникнуть в ситуации, когда порядок нумерации блочных устройств изменился – например, один из SCSI-дисков, участвовавших в построении массива, был удален.

Естественно, суперблок не является обязательным – то есть можно создавать массивы без суперблока, но управления ими может быть затруднено вследствие необходимости «руками» контролировать корректность указания устройств при переконфигурации массива.

Из интересных особенностей драйвера md стоит отметить то, что он поддерживает разбиение md-устройств на разделы, при этом минорные номера присваиваются разделам аналогично тому, как они присваиваются разделам на дисках IDE, т.е на каждом RAID-устройстве можно создать до 63 разделов. Определить минор раздела, созданного на RAID-устройстве, можно с помощью вычисления значения следующего выражения: 64 * N + M, где N – это номер массива (номер RAID-устройства) из диапазона 0...255, а M – это номер раздела из диапазона 1...63.

Следует сказать, что по умолчанию в большинстве дистрибутивов специальные файлы для разделов на md-устройствах не создаются, и их необходимо создать вручную командой mknod. В настоящий момент оптимальным, наверное, следует считать комбинирование использования LVM и md, что позволяет достигнуть надежности за счет дублирования данных средствами md, и гибкости распределения дискового пространства за счет возможностей LVM.

Драйвер md хорошо подходит для создания RAID-устройств уровней 0, 1 или 0+1, но не будет являться оптимальным вариантом в случае использования, например RAID уровня 5 (чередование данных по устройствам с вычислением контрольной суммы и кодом исправления ошибок), поскольку это создаст значительную нагрузку на процессор при большом объеме передаваемых данных. Возможно, что в таких случаях стоит подумать о приобретении аппаратного контроллера RAID – например, HP NetRaid (сделан на основе AMI MegaRAID) или Compaq Smart Array (сейчас называется HP Smart Array).

На листинге демонстрируется пример создания, активизации и остановки программных RAID-устройств уровня 0 и уровня 1 средствами драйвера md и системной утилиты mdadm. Утилита mdadm имеет конфигурационный файл /etc/mdadm.conf, но для того, чтобы проделать некоторые тесты и демонстрационные примеры нет необходимости его изменять.

В первом примере будем считать, что на жестком диске hdb создано два раздела, с которыми мы и будем экспериментировать. Для начала необходимо произвести инициализацию md-устройства. Соответственно, для успешной необходимо указать тип RAID-массива, специальный файл md-устройства, которое мы хотим инициализировать, и список блочных устройств, на которых будет располагаться получившийся массив:

# mdadm --create \
>                           /dev/md0 --level=0 \
>                           --raid-devices=2 /dev/hdb1 /dev/hdb2
mdadm: array /dev/md0 started.
# mdadm -Q /dev/md0
/dev/md/d0: 983.25MiB raid0 2 devices, 0 spares.
# mdadm –S /dev/md0
# mdadm --create \
>                           /dev/md0 --level=1 \
>                           --raid-devices=2 /dev/hdb1 /dev/hdb2
mdadm: array /dev/md0 started.
# mdadm -Q /dev/md0
/dev/md0: 491.63MiB raid1 2 devices, 0 spares.
# mdadm –S /dev/md0
# mdadm –assemble /dev/md0 /dev/hdb1 /dev/hdb2
mdadm: /dev/md0 has been started with 2 drives.

Последняя команда демонстрирует активизацию массива путем указания имени md-устройства и нескольких блочных устройств, на которых оно базируется. Все остальные параметры (размеры блоков, разновидность RAID и т.д.) утилита mdadm извлекла из суперблока массива. Как уже отмечалось, суперблок массива содержит еще и уникальный идентификатор массива, что дает возможность проидентифицировать каждое исходное блочное устройство на предмет его принадлежности к какому-либо массиву. Ниже приведен пример вывода утилиты mdadm, демонстрирующий как можно получить некоторые полезные данные о массиве, а строка, содержащая UID массива выделена жирным текстом:

# mdadm -Q -D /dev/md0
/dev/md0:
        Version : 00.90.01
  Creation Time : Fri Oct  8 14:29:21 2004
     Raid Level : raid1
     Array Size : 102336 (99.94 MiB 104.79 MB)
    Device Size : 102336 (99.94 MiB 104.79 MB)
   Raid Devices : 2
  Total Devices : 2
Preferred Minor : 0
    Persistence : Superblock is persistent

    Update Time : Fri Oct  8 14:32:22 2004
          State : clean, no-errors
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

    Number   Major   Minor   RaidDevice State
       0     253       24        0      active sync   /dev/hdb1
       1     253       25        1      active sync   /dev/hdb2
           UUID : 8696ffc0:52547452:ba369881:d1b252d0
         Events : 0.3

Впоследствии этот идентификатор может быть использован в файле конфигурации для утилиты mdadm. В конфигурационном файле /etc/mdadm.conf можно указать список устройств и правила их построения, после чего описанные в нем md-устройства будут автоматически собираться и разбираться без указания списка исходных устройств:

# cat /etc/mdadm.conf
MAILADDR root
ARRAY /dev/md0 UUID=8696ffc0:52547452:ba369881:d1b252d0
DEVICE /dev/hdb*

В листинге видно, что устройство массив md0 имеет указанный идентификатор, а также указано, что для построения массивов могут быть использованы все раделы диска hdb. В этом примере если системный администратор напишет команду mdadm –assemble /dev/md0, то mdadm просканирует все файлы устройств с именами, совпадающими с шаблоном /dev/hdb* и подключит к массиву md0 те из них, на которых будет найдена суперблок массива с тем идентификатором, который указан в параметре ARRAY для устройства /dev/md0.

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

linux md0=0,/dev/hdb1,/dev/hdb2 root=/dev/md0

Данный пример приведен скорее как иллюстративный, поскольку в зависимости от опций, использованных при создании RAID-устройства, на котором расположена корневая файловая система, командная строка ядра может меняться. В современных дистрибутивах при необходимости инициализации md-устройств для загрузки системы, как правило код и утилиты инициализации устройства помещаются в initrd.

Суперблок массива записывается не в начале блочного устройства, а ближе к его середине или концу. Сделано это было для того, чтобы можно было создать RAID-массив с boot-сектором, который сможет быть прочитан не только ядром Linux с драйвером md, но и базовым загрузчиком BIOS, вследствие чего можно объединить в RAID-массив не разделы жестких дисков, а непосредственно физические диски. Тогда загрузчик, установленный в начало RAID-устройства, окажется установленным в начало жесткого диска, после чего можно использовать при загрузке ядра следующую командную строку:

linux md0=d0,/dev/hda,/dev/hdb root=/dev/md_d0p1

Драйвер md также поддерживает возможность задания hotswap-устройств для массивов, т.е. резервных устройств, которые могут быть активизированы в при сбое одного из основных устройств в массиве.

Поддержка устройств software RAID в Linux дает возможность создавать серверы с высокой отказоустойчивостью и быстродействием.

14.6. Device mapper

В ядрах линейки 2.6 появилась еще одна подсистема по некоторым функциям аналогичная подсистеме MD, и называемая device-mapper. Это модульная компонентная подсистема, позволяющая с помощью специальных команд создать одно блочное устройство из нескольких кусков других блочных устройств,  а также определить правила, по которым производится запись на эти «нижележащие» блочные устройства.

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

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

14.7. Host-RAID, или дешевых RAID-контроллеров не бывает

Сегодня даже для дешевых современных материнских плат фирмы-производители часто декларируют «аппаратную поддержку RAID» и у многих пользователей этот факт вызывает недоумение – как же так, мой Linux не умеет работать с RAID?!

На самом деле все проще – задекларированная и разрекламированная поддержка RAID-массивов на материнских платах для офисных и домашних компьютеров – это миф.

Вся поддержка RAID в таких «контроллерах» на самом деле представляют собой просто небольшое расширение в BIOS и без специальных драйверов в 32/64-битных операционных системах такие контроллера не работают, а все функции RAID для них выполняются драйвером. Если в Windows для каждого из таких контроллеров фирма-производитель пишет драйвер, то в Linux ситуация немного иная.

Для реализации возможности работы с такими псевдо-RAID контроллерами (иногда называемыми fake-RAID) была разработана утилита dmraid. При запуске она сканирует жесткие диски в поисках специальных блоков (функционально аналогичных суперблокам уже знакомых нам md-устройств), записываемых такими fake-RAID контроллерами, и если ей удалось распознать формат этого специального блока, то dmraid инструктирует подсистему device-mapper о том, в каком порядке следует считывать блоки с жестких дисков.

После этого device-mapper создает блочное устройство, при записи или чтение данных с которого данные автоматически читаются и пишутся так, как сделал бы это драйвер от производителя материнской платы или контроллера.

Пред.: Секреты /devВ началоУровень выше: Linux не для идиотовСлед.: Сетевая подсистема
В началоLinux не для идиотов → Блочные устройства