Особенности построение Soft-RAID-1 в Linux c установленным udev, используя mdadm

Опубликовано ivul - пт, 11.03.2005 - 10:58

Введение

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

udev и mdadm

Как уже было сказано, построить RAID согласно различным описаниям и How-To я не смог. Дело в том, что на моем сервере я планировал поднять несколько RAID-массивов. Для каждого массива должен быть файл устройства /dev/mdN (где N – номер устройства), и если соответствующего файла нет, его нужно создать:

mknod /dev/md0 b 9 0
mknod /dev/md1 b 9 1
...
mknod /dev/mdN b 9 N

И все бы хорошо, но после перезагрузки созданные файлы /dev/mdN бесследно исчезают. Все, кроме /dev/md0. Соответственно RAID-массивы не запускаются, ссылаясь на отсутствие файлов устройств.
Виноват в исчезновении файлов udev.
Что такое udev? Вольный перевод соответствующего определения с man-страницы в man (8) udev, это - поддержка настраиваемого динамического именования устройств в Linux.
В отличие от devfs, udev - не новая поддерживаемая ядром файловая система, пусть и виртуальная, а обычная пользовательская программа. Более того, при ее использовании необходимость в поддержке devfs как будто бы отпадает вообще.
Правда, для своего функционирования udev нуждается в еще одной виртуальной файловой системе - sysfs, но ее поддержка в ядрах серии 2.6.X осуществляется автоматически (а сама эта файловая система монтируется по умолчанию в каталог /sys), основываясь на информации из которой, udev и присваивает имена всяческим устройствам.
В отличие от raidtools, на котором и строятся RAID-массивы во всех руководствах, mdadm, заявленный в тех же руководствах просто как более удобная и простая альтернатива raidtools, умеет автоматически создавать файлы /dev/mdN, если они отсутствуют.

Построение RAID1 с помощью mdadm

Имеется 4 SCSI жестких диска, ОС Linux Mandrake 10.1, ядро 2.6.8.1-12mdk, mdadm-1.7.0-3mdk, udev-030-24.1.101mdk.
Требуется построить RAID-массивы 1 уровня (т.е. зеркала) из дисков /dev/sda и /dev/sdb, /dev/sdc и /dev/sdd.
Система установлена на следующие разделы:

/dev/sda1 /boot
/dev/sda5 swap
/dev/sda6 /
/dev/sdc1 /home

Хочу отметить, что /boot я вынес на отдельный раздел, т.к. пытаясь создать точку монтирования “/” на RAID-массиве во время установки системы, я получил сообщение о том, что для этого необходим раздел “/boot”. Практика показала, что это совсем не обязательно, но переразбивать диски заново было уже не охота.

Чтобы автоматически загружался модуль поддержки RAID-массива 1 уровня, в файл modprobe.preload нужно добавить строчку

raid1

С помощью программы fdisk нужно создать диски /dev/sdb1=/dev/sda1, /dev/sdb5=/dev/sda5, /dev/sdb6=/dev/sda6, /dev/sdd1=/dev/sdc1 и задать тип для всех дисков “fd” (Linux raid autodetect). Т.к. диски sda1, sda5, sda6 и sdc1 уже смонтированы, изменения вступят в силу после перезагрузки, по-этому перезагружаемся.
Пусть устройство /dev/md будет соответствовать разделу /home, /dev/md2 – swap.
Сразу после установки системы уже присутствует файл /dev/md0. Нужных нам /dev/md1 и /dev/md2 нет. Их придется создать.

mknod /dev/md1 b 9 1
mknod /dev/md2 b 9 2

Создаем RAID-массивы.

mdadm –create /dev/md1 –level=1 –chunk=64 –raid-devices=2 /dev/sdc1 /dev/sdd1
mdadm –create /dev/md2 –level=1 –chunk=64 –raid-devices=2 /dev/sda5 /dev/sdb5

Перед тем, как создать RAID-массив, mdadm выдаст краткую информацию о добавляемых дисках и запрос на подтверждение. Говорим “y”.
Т.к. диски /dev/sdc1 и /dev/sda5 заняты, они не будут добавлены в RAID-массивы.

Теперь RAID-массивы надо активировать.

mdadm /dev/md1 –run
mdadm /dev/md2 –run

Проверить состояние RAID-массивов можно командой

cat /proc/mdstat

 

Personalities : [raid1]
md1 : active raid1 sdb5[0]
1020032 blocks [2/1] [_U]

md0 : active raid1 sdd1[1]
17936448 blocks [2/1] [_U]

unused devices:

Обратите внимание, что индексы устройств md начинаются с 0, а не с 1. В этом нет ничего страшного, но вносит определенную путаницу. Эта ситуация исправится, когда будет создан массив md0 или если сразу создавать массивы по порядку с 0 индекса.

Создаем файловые системы.

mkfs -t ext3 /dev/md1
mkswap /dev/md2

Создадим какалог /mnt/md, в который будем временно монтировать RAID-диски.

mkdir /mnt/md

Монтируем в /mnt/md диск /dev/md1

mount /dev/md1 /mnt/md

Копируем в /mnt/md содержимое /home

cp -a /home/* /mnt/md

Теперь надо подкорректировать файлы lilo.conf и fstab.

У меня в lilo.conf параметры, относящиеся к загружаемому ядру, изначально выглядели так:

image=/boot/vmlinuz-2.6.8.1-12mdksmp
label="2681-12smp"
root=/dev/sda6
initrd=/boot/initrd-2.6.8.1-12mdksmp.img
append="acpi=ht resume=/dev/sda5"
read-only

Меняем значение параметра append:

append="acpi=ht resume=/dev/md2"

В fstab меняю

/dev/sdc1 /home ext3 defaults 1 2 на /dev/md1 /home ext3 defaults 1 2
/dev/sda5 swap swap defaults 0 0 на /dev/md2 swap swap defaults 0 0

Теперь самое главное.
Чтобы после перезагрузки присутствовали файлы /dev/md1 и /dev/md2, они должны быть описаны в /etc/mdadm.conf следующим образом:

DEVICE partitions
# /home
ARRAY /dev/md1 level=raid1 num-devices=2 devices=/dev/sdc1,/dev/sdd1 auto=md
# swap
ARRAY /dev/md2 level=raid1 num-devices=2 devices=/dev/sdb5,/dev/sda5 auto=md

Параметр auto=md отвечает за то, чтобы файл /dev/mdN был автоматически создан, если он отсутствует.
Теперь можно перезагрузиться.
После перезагрузки добавляем недостающие диски в RAID-массивы

mdadm /dev/md1 –add /dev/sdc1
mdadm /dev/md2 –add /dev/sda5

После этих команд начнется синхронизация дисков.

Personalities : [raid1]

 

md0 : active raid1 sda6[2] sdb6[0]
17936448 blocks [2/1] [U_]
[>....................] recovery = 3.6% (81792/17936448) finish=11.4min speed=10838K/sec

md1 : active raid1 sda1[2] sdb1[0]
1020032 blocks [2/1] [U_]
resync=DELAYED
unused devices:

Если не предполагается размещение на RAID корневого раздела и загрузка с RAID, на этом можно и остановиться.

Загрузка с RAID

Внесем дополнения в файл /etc/mdadm.conf. Теперь он выглядит так:

DEVICE partitions
# /boot
ARRAY /dev/md0 level=raid1 num-devices=2 devices=/dev/sdb1,/dev/sda1 auto=md
# /home
ARRAY /dev/md1 level=raid1 num-devices=2 devices=/dev/sdc1,/dev/sdd1 auto=md
# swap
ARRAY /dev/md2 level=raid1 num-devices=2 devices=/dev/sdb5,/dev/sda5 auto=md
# /
ARRAY /dev/md3 level=raid1 num-devices=2 devices=/dev/sdb6,/dev/sda6 auto=md

И перезагрузимся.
Делается это для того, чтобы автоматически создать недостающие файлы /dev/md0 и /dev/md3 и привести в соответствие системные индексы RAID-дисков, отображаемые в /proc/mdstat.
RAID-массивы /dev/md0 и /dev/md3 необходимо пересоздать и активировать.

mdadm –create /dev/md0 –level=1 –chunk=64 –raid-devices=2 /dev/sdф1 /dev/sdи1
mdadm –create /dev/md3 –level=1 –chunk=64 –raid-devices=2 /dev/sda6 /dev/sdb6

 

mdadm /dev/md0 –run
mdadm /dev/md3 --run

Создаем файловые системы

mkfs -t ext3 /dev/md0
mkfs -t ext3 /dev/md3

Монтируем /dev/md3 в /mnt/md и копируем в него содержимое корневого раздела

mount /dev/md3 /mnt/md
cd /
find . -xdev | cpio -pm /mnt/md

Обратите внимание, что папка /mnt/md/dev осталась пустой. Из-за этого указанная в руководствах команда

chroot /mnt/md lilo

выполнена не будет, ссылаясь на отсутствие файлов дисков.

Выполняем

makedev /mnt/md/dev

Монтируем /dev/md0

chroot /mnt/md mount /dev/md0 /boot

Копируем содержимое папки /boot

cp -a /boot/* /mnt/md/boot

Теперь необходимо подготовить ядро.
Копируем файл initrd-2.6.8.1-12mdk.img в папку /mnt

cp /boot/initrd-2.6.8.1-12mdk.img /mnt

Переименовываем в initrd-2.6.8.1-12mdk.img.gz и распаковываем

gzip -d initrd-2.6.8.1-12mdk.img.gz

Создаем дополнительную папку /mnt/1

mkdir /mnt/1

и монтируем в нее ядро

mount -o loop /mnt/initrd-2.6.8.1-12mdk.img /mnt/1

Копируем файлы /dev/md0, /dev/md1, /dev/md2, /dev/md3 в папку /mnt/1/dev

cp /dev/md0 /mnt/1/dev
cp /dev/md1 /mnt/1/dev
cp /dev/md2 /mnt/1/dev
cp /dev/md3 /mnt/1/dev

Копируем файл /lib/modules/2.6.8.1-12mdk/kernel/drivers/md/raid1.ko.gz в папку /mnt/1/lib
cp /lib/modules/2.6.8.1-12mdk/kernel/drivers/md/raid1.ko.gz /mnt/1/lib
и распаковываем его

gzip -d /mnt/1/lib/raid1.ko.gz

Подправим файл /mnt/1/linuxrc. В него нужно добавить загрузку модуля /lib/raid1.ko и автозапуск RAID-массивов. Автозапуск RAID обязательно должен быть прописан после строки “mountdev size=1M,mode=0755” и перез запуском udev. Во всех других случаях возникает “Kernel panic...”.
После внесенных изменений linuxrc выглядит так:

#!/bin/nash
echo "Loading scsi_mod.ko module"
insmod /lib/scsi_mod.ko
echo "Loading aic7xxx.ko module"
insmod /lib/aic7xxx.ko
echo "Loading sd_mod.ko module"
insmod /lib/sd_mod.ko
echo "Loading jbd.ko module"
insmod /lib/jbd.ko
echo "Loading ext3.ko module"
insmod /lib/ext3.ko
echo "Loading raid1.ko module"
insmod /lib/raid1.ko
echo Mounting /proc filesystem
mount -t proc /proc /proc
echo Mounting sysfs
mount -t sysfs none /sys
echo Creating device files
mountdev size=1M,mode=0755
echo “MY RAID AUTORUN”
raidautorun /dev/md0
raidautorun /dev/md1
raidautorun /dev/md2
raidautorun /dev/md3
echo starting udev
udevstart
echo -n /sbin/hotplug > /proc/sys/kernel/hotplug
echo Creating root device
mkrootdev /dev/root
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
echo 0x0100 > /proc/sys/kernel/real-root-dev
pivot_root /sysroot /sysroot/initrd
umount /initrd/sys
umount /initrd/proc
echo Initrd finished

Размонтируем папку /mnt/1, запакуем файл initrd-2.6.8.1-12mdk.img и скопируем его в /mnt/md/boot

cd /mnt
umount /mnt/1
gzip initrd-2.6.8.1-12mdk.img
mv initrd-2.6.8.1-12mdk.img.gz initrd-2.6.8.1-12mdk.raid1.img
cp initrd-2.6.8.1-12mdk.raid1.img /mnt/md/boot

Внесем изменения в lilo.conf и fstab

fstab:

/dev/md3 / ext3 defaults 1 1
/dev/md0 /boot ext3 defaults 1 2
/dev/md1 /home ext3 defaults 1 2
/dev/hda /mnt/cdrom auto user,iocharset=koi8-u,noauto,ro 0 0
/dev/fd0 /mnt/floppy auto umask=0,user,codepage=866,iocharset=koi8-u,noauto,sync 0 0
none /proc proc defaults 0 0
/dev/md2 swap swap defaults 0 0

lilo.conf

default="2681-12smp-raid1"
boot=/dev/md0
map=/boot/map
install=menu
keytable=/boot/ru4.klt
raid-extra-boot=mbr
disk=/dev/sdb
bios=0x80
prompt
nowarn
timeout=100
message=/boot/message
menu-scheme=wb:bw:wb:bw
...
image=/boot/vmlinuz-2.6.8.1-12mdk
label="2681-12-raid1"
root=/dev/md3
initrd=/boot/initrd-2.6.8.1-12mdk.raid1.img
append="acpi=ht resume=/dev/md2"
read-only

Выполним команду

chroot /mnt/md lilo

Перезагружаемся.
Перед загрузкой системы в BIOS SCSI-контроллера нужно выбрать загрузку со второго (/dev/sdb) диска.

Добавляем диски в RAID-массивы.

mdadm /dev/md0 –add /dev/sda1
mdadm /dev/md3 –add /dev/sda6

Результат команды cat /proc/mdstat будет примерно таким:

Personalities : [raid1]
md2 : active raid1 sdb5[0] sda5[1]
1020032 blocks [2/2] [UU]

 

md3 : active raid1 sda6[2] sdb6[0]
7751232 blocks [2/1] [U_]
[>....................] recovery = 3.6% (281792/7751232) finish=11.4min speed=10838K/sec
md1 : active raid1 sdd1[1] sdc1[0]
17936448 blocks [2/2] [UU]

md0 : active raid1 sda1[2] sdb1[0]
152512 blocks [2/1] [U_]
resync=DELAYED
unused devices:

Когда синхронизация закончиться, таким:

Personalities : [raid1]
md2 : active raid1 sdb5[0] sda5[1]
1020032 blocks [2/2] [UU]

 

md3 : active raid1 sda6[1] sdb6[0]
7751232 blocks [2/2] [UU]

md1 : active raid1 sdd1[1] sdc1[0]
17936448 blocks [2/2] [UU]

md0 : active raid1 sda1[1] sdb1[0]
152512 blocks [2/2] [UU]

unused devices:

Не лишним будет еще раз выполнить команду lilo, чтобы записать изменения в mbr диска /dev/sda.
На этом все. Можно оставить загрузку со второго (/dev/sdb) диска, можно вернуться к загрузке с первого (/dev/sda).

Заключение

Мое описание построения RAID-массива 1 уровня не претендует на полное. Просто по mdadm я не нашел руководства (или How-To) на русском языке и всю информацию по настройкам и параметрам запуска брал из соответствующих man. Изменения в файле linuxrc, касающиеся автозапуска md-устройств, вообще определил простым перебором. Раза с 7-го нашел правильный вариант.
Если в описании найдете неточности и ошибки, сообщите мне.
Дополнения – приветствуются.

 

Ссылки по теме

http://www.opennet.ru/base/sys/root_soft_raid.txt.html
http://www.opennet.ru/opennews/art.shtml?num=1844
http://www.opennet.ru/docs/HOWTO-RU/Software-RAID-HOWTO.html