Создание устройств mdadm при загрузке

Здравствуйте! Вопрос такой: как заставить mdadm создавать рейд при старте системы? Предыстория: имелся один диск с тремя разделами: swap, / и /var. Требуется раздел /var зеркалировать. Поставил второй диск, сделал рейд, указал в fstab монтировать этот рейд (/dev/md0 /var ext4 defaults 0 0). Монтирования не происходит, так как не создаётся устройство /dev/md0. После загрузки руками создаётся прекрасно (хотя бы командой mdadm --assemble --scan).

rcmdadm start
insserv mdadm

Спасибо, но это не помогло (кстати, служба называется mdadmd).
Судя по логу, происходит СНАЧАЛА монтирование файловых систем, где mount ругается на отсутствие устройства md0. А потом уже стартует служба mdadmd. Кроме того, всё равно после загрузки смотрим в /proc/mdstat и видим пустоту. Куда ещё копать?

Вот содержимое /etc/mdadm.conf, если надо:
DEVICE /dev/sda3 /dev/sdb3
ARRAY /dev/md/0 level=raid1 num-devices=2 metadata=0.90 UUID=9f5e54a4:d86e93ed:e6c11aab:f0854536
devices=/dev/sda3,/dev/sdb3

В общем, получилось :slight_smile: Спасибо людям с IRC-канала #opensuse.ru. По их же просьбе описываю весь процесс здесь.
Итак, дано:

  • OpenSUSE 11.2
  • Один НЖМД SATA c двумя разделами: swap и /.

Требуется:

  • сделать программный RAID1, НЕ ПЕРЕУСТАНАВЛИВАЯ систему.

Первое, что я попытался сделать, это создать RAID из всего диска. Но быстро понял, что это слишком сложно и, самое главное, не нужно. Дело в том, что требуется зеркалировать лишь важные пользовательские данные, а систему (или, тем более, swap) зеркалировать не нужно. Поэтому я определился, где лежат важные для меня данные (скажем - в /var) и начал плясать от этого.

Итак, поэтапно.
0) Установил второй жёсткий диск такого же размера, как и первый.

  1. Для начала я решил создать на первом диске (sda) раздел, в который перенесу все данные /var и который буду впоследствии монтировать отдельно и зеркалировать. Так как система рабочая, туда смонтирован корень, т.е. менять файловую таблицу на лету не получится, пришлось воспользоваться утилитой gparted. Я поступил просто: взял Live-дистрибутив Ubuntu, в состав которого входит gparted, и с его помощью откусил кусок от раздела / на sda. Получился раздел sda3.
  2. В новом разделе я создал файловую систему ext4:
    mke2fs -t ext4 /dev/sda3
  3. Смонтировал этот раздел и скопировал туда содержимое /var:
    a) mount /dev/sda3 /mnt
    b) cp -dRx /var/* /mnt
  4. Затем, отключив будущий раздел /var (umount /mnt), я запустил fdisk и пометил этот раздел как находящийся в составле Linux RAID. Для этого в fdisk надо выбрать команду t (тип раздела) и поставить шестнадцатеричный код fd.
  5. Теперь потребовалось создать разделы на втором диске (sdb). Разметку я решил сделать такую же, как на первом, для чего воспользовался командой
    sfdisk -d /dev/sda | sfdisk /dev/sdb/
    Эта команда копирует таблицу разделов с одного диска на другой. При желании, разумеется, можно на втором диске создать таблицу разделов вручную тем же fdisk’ом:)
  6. Следующий этап - создание файловых систем на втором диске. Делаем:
    mke2fs -t ext4 /dev/sdb2
    mke2fs -t ext4 /dev/sdb3
  7. Теперь информацию копируем с 1-го на 2-й диск. Разумеется, этого можно и не делать, но я решил, что, хотя зеркалироваться постоянно будет только раздел /var, копия системы будет на обоих дисках. Опишу вкратце:
    a) Монтируем раздел, где будет копия системы, в /mnt (mount /dev/sdb2 /mnt) и копируем туда корень (cp -dRxf / /mnt)
    b) То же самое проделываем с /dev/sdb3 (который, напоминаю, будет входить в состав зеркала. Хотя этого можно и не делать - при синхронизации зеркала вся информация всё равно будет скопирована).
  8. Наконец, самое главное: создание рейда. Прежде всего, нужно установить программу для этого. Я выбрал mdadm. Чтобы установить его в OpenSUSE, надо набрать:
    zypper in mdadm
  9. Теперь - создаём рейд. Пользовался я вот этой инструкцией:
    Программный RAID в Linux - Xgu.ru](http://xgu.ru/wiki/raid).
    Напишу вкратце, подробнее см. ссылку.
    8a) mdadm --create --verbose /dev/md0 --level=1 --raid-devices=2 /dev/sda3 /dev/sdb3
    Рейд готов. Проверяем этот факт:
    cat /proc/mdstat
    На выходе должны быть сведения о созданном рейде, а также о его текущем состоянии.
  10. Следующим пунктом автор той статьи рекомендует создавать файловую систему на устройстве /dev/md0 - нашем рейде. Но я убедился, что ранее существовавшая там система прекрасно работает, только надо дождаться синхронизации, состояние которой видно в выводе предыдущей команды. Поэтому следующее, что я делаю - создаю конфигурационный файл. Он назвается /etc/mdadm.conf. Как проще передать кучу сведений, необходимых для идентификации рейда, в этот файл? А командой mdadm c нужными параметрами. Вот как сделал я:
    a) echo “DEVICE /dev/sda3 /dev/sdb3” > /etc/mdadm.conf
    b) mdadm --detail --scan --verbose >> /etc/mdadm.conf
    В итоге у меня получилось вот что:

DEVICE /dev/sda3 /dev/sdb3
ARRAY /dev/md/0 level=raid1 num-devices=2 metadata=0.90 UUID=9f5e54a4:d86e93ed:e6c11aab:f0854536 devices=/dev/sda3,/dev/sdb3

Насчёт слеша перед 0 ничего не могу сказать: действительно, создаётся устройство /dev/md/0, но также создаётся и /dev/md0, и оба монтируются.
10) Теперь начинаются подводные камни. Наш замечательный рейд готов, но после ребута он исчезнет :slight_smile: Мы можем собрать его снова командой
mdadm --assemble --scan
Но нам надо, чтобы он собирался сам. Пoэтому запускаем и добавляем в автозапуск демон mdadmd:
rcmdadmd start
insserv mdadmd
11) И ещё один подводный камень: нужно пересобрать initrd с поддержкой RAID. Для этого пишем:
mkinitrd -f md
12) Наконец, предпоследний шаг - монтирование нашей файловой системы на старте. Я отредактировал fstab, добавив в конец такую строку:
/dev/md0 /var ext4 defaults 0 0
13) Ещё некоторые косметические доделки.
Я изменил в fstab соотвествующие строки, относящиеся к монтированию свопа и корневой файловой системы, чтобы они ссылались на диск не по его UUID, а по названию устройства: sda. Дело в том, что, если у нас отвалится диск sda, мы можем отключить его, спокойно загрузиться с диска, который раньше назывался sdb, а теперь, будучи единственным, будет называться sda, и работать. Также для этого необходимо прописать загрузчик GRUB в бутсектор обоих дисков. Как это правильно делать, ищите сами - я пока толком не разобрался :slight_smile: Вроде примерно так (команды подряд):


grub
root (hd1,1)
setup
quit

ИЛи так:


[root@myhost]# grub
grub> device (hd0) /dev/sdb # Set (hd0) to be the 2nd drive for subsequent commands
grub> root (hd0,0) # Root device (with /boot/grub) is 1st partition of 2nd drive
grub> setup (hd0) # Write the MBR on the 2nd drive
grub> quit

Но не уверен в правильности этого рецепта.
И, естественно, надо скопировать на второй диск файлы /etc/fstab и /etc/mdadm.conf, а также /boot/inirtd.img. В общем, чтобы ничего не забыть, можно ещё раз всю рутовую ФС скопировать.

Ну вот, теперь можно перезагружаться и проверять.

Полезная статья, спасибо.

Насчёт слеша перед 0 ничего не могу сказать: действительно, создаётся устройство /dev/md/0
Это ссылка на /dev/md0. Я бы исправил на целевое устройство.

(или, тем более, swap) зеркалировать не нужно
В таких случаях лучше создать второй swap-раздел с таким же приоритетом и прописать его в fstab.

Ага, так и сделал уже. Я пытался отредактировать предыдущее сообщение, но, к сожалению, тут есть дурацкое ограничение на редактирование: разрешено в течении десяти минут только :frowning:
Насчёт GRUB:
root (hd0,1)
setup (hd0)
setup (hd1)
После этого стало нормально работать в случае отключения любого из дисков, только надо из /boot/grub/menu.lst убрать определение root по UUID, надо туда тоже, как и в fstab, прописать /dev/sda2. Потому что любой диск становится sda, если он единственный. Если не прав, поправьте, но у меня так работает. Однако, нарвался ещё на одну странную вещь: у меня почему-то в корневом разделе на диске sdb владелец и группа ВСЕХ файлов исключительно рут (root:root). Возможно, это связано с тем, что я сдуру копировал корневой раздел запущенной системы? В общем, рекомендую делать это самое копирование теми же командами, но загрузившись с внешнего носителя.

От блин! Мне тут помогли разобраться с копированием… Я почему-то думал, что права сохраняются! Оказывается, нет :slight_smile:
Т.е. копируем так: cp -pdRx /source /destination.

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

ЗЫ: Извиняюсь за то, что “инструкция” получилась сумбурной и неточной. К сожалению, как я тут уже писал, отредактировать старый пост я не могу. Позже выложу где-нибудь полную инструкцию со всеми изменениями/дополнениями и добавлю сюда ссылку (надеюсь, модераторы сочтут такую ссылку приемлемой).