Ключевые слова:raid, disk, fs, linux, (найти похожие документы)
From: bk_man
Newsgroups: http://www.linux-os.ru/
Date: Mon, 22 Aug 2004 18:21:07 +0000 (UTC)
Subject: Конвертация обычной установки Linux в Software-ROOT-RAID1
Оригинал: http://www.linux-os.ru/Members/bk_man/Articles/linux_installation_plain2raid1
В документе рассматривается пример конвертации Linux-системы,
установленной на один жесткий диск в Software-ROOT-RAID1
Предисловие
-----------
Важные данные всегда должны резервироваться - в противном случае это
неважные данные, т.к. они могут быть потеряны. К сожалению, в сервере
не всегда бывает доступен аппаратный RAID-контроллер или же он не
поддерживается текущим ядром. Вместе с тем, RAID не является заменой
резервированию данных, об этом тоже нужно помнить и своевременно
делать резервные копии на другой сервер.
Рассматриваемый случай
----------------------
Я рассматриваю здесь RAID1, но это может работать также для других
случаев (я этого не проверял). Я проделывал все нижеописанные
процедуры на сервере RX-300 производства Fujitsu-Siemens.
Диски были одинакового размера из стандартной поставки сервера, режим
HostRAID в SCSI-контроллере был отключен. Все операции производились
на дистрибутиве ALT Linux Compact версии 2.3, который был обновлен до
репозитария Sisyphus по состоянию на 20040517.
Необходимый инструментарий
--------------------------
Для выполнения поставленной задачи нам потребуется следующий софт:
* установленные пакеты raidtools и mkinitrd
* Ремонтный загрузочный компакт-диск (флешка, ...) с установленными
raidtools и способный определить ваше железо (Knoppix 3.4 не смог
определить и подключить контроллер Adaptec AIC-7902W и поэтому
оказался не у дел). Я использую SystemRescueCD (http://www.sysresccd.org)
на основе дистрибутива Gentoo Linux.
Алгоритм работы
---------------
Пусть на /dev/sda есть два раздела:
$ sudo fdisk /dev/sda
Command (m for help): p
Disk /dev/sda: 73.5 GB, 73508513792 bytes
255 heads, 63 sectors/track, 8936 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 1 63 506016 82 Linux swap
/dev/sda2 * 64 8936 71272372+ 83 Linux
Убеждаемся, что необходимые пакеты установлены:
$ rpm -q mkinitrd raidtools
mkinitrd-2.9.1-alt1
raidtools-0.90-ipl11mdk
Пусть swap-раздел у нас будет на /dev/md0, а корневая файловая система
на /dev/md1.
Загружаемся с ремонтного комплекта, монтируем в нём корневую файловую
систему:
# mkdir /mnt/disk
# mount -t ext3 /dev/sda2 /mnt/disk
Переходим в неё:
# chroot /mnt/disk
Создаём файл /etc/raidtab следующего содержания:
raiddev /dev/md0
raid-level 1
chunk-size 64k
persistent-superblock 1
nr-raid-disks 2
nr-spare-disks 0
device /dev/sda1
raid-disk 0
device /dev/sdb1
raid-disk 1
failed-disk 1
raiddev /dev/md1
raid-level 1
chunk-size 64k
persistent-superblock 1
nr-raid-disks 2
nr-spare-disks 0
device /dev/sda2
raid-disk 0
device /dev/sdb2
raid-disk 1
failed-disk 1
Изменяем в файле /etc/fstab устройства с /dev/sd? на /dev/md? :
/dev/md0 swap swap defaults 0 0
/dev/md1 / ext3 defaults 1 1
devpts /dev/pts devpts gid=5,mode=0620 0 0
proc /proc proc gid=19 0 0
/dev/cdrom /mnt/cdrom auto user,iocharset=koi8-r,noauto,ro,exec 0 0
/dev/floppy /mnt/floppy auto user,iocharset=koi8-r,quiet,sync,codepage=866,noauto,umask=0,exec 0 0
Изменяем тип разделов на устройстве /dev/sda на fd для того, чтобы
ядро при старте могло определить массив:
# fdisk /dev/sda
Command (m for help): p
Disk /dev/sda: 73.5 GB, 73508513792 bytes
255 heads, 63 sectors/track, 8936 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 1 63 506016 82 Linux raid autodetect
/dev/sda2 * 64 8936 71272372+ 83 Linux raid autodetect
Обновляем initrd.img для нашего ядра. Я делал это без ремонтного
набора, подсовывая на время работы команды mkinitrd файлы /etc/raidtab
и /etc/fstab с будущей конфигурацией RAID'а (потом их достаточно
переименовать, например в .old, чтобы эти файлы "не замечали"
initscripts и не делали ненужных вещей):
# mkinitrd -v /boot/initrd-raid1.img `uname -r`
mkinitrd: Generating module dependencies...
mkinitrd: ...done.
mkinitrd: Using modules:
/lib/modules/2.4.26-std-smp-alt1/kernel/drivers/scsi/scsi_mod.o
/lib/modules/2.4.26-std-smp-alt1/kernel/drivers/scsi/sd_mod.o
/lib/modules/2.4.26-std-smp-alt1/kernel/drivers/scsi/aic7xxx/aic79xx.o
/lib/modules/2.4.26-std-smp-alt1/kernel/drivers/md/raid1.o
/lib/modules/2.4.26-std-smp-alt1/kernel/fs/jbd/jbd.o
/lib/modules/2.4.26-std-smp-alt1/kernel/fs/ext3/ext3.o
Contents of linuxrc:
#!/bin/sh
/bin/insmod -f /lib/modules/2.4.26-std-smp-alt1/kernel/drivers/scsi/scsi_mod.o
/bin/insmod -f /lib/modules/2.4.26-std-smp-alt1/kernel/drivers/scsi/sd_mod.o
/bin/insmod -f
/lib/modules/2.4.26-std-smp-alt1/kernel/drivers/scsi/aic7xxx/aic79xx.o
/bin/insmod -f /lib/modules/2.4.26-std-smp-alt1/kernel/drivers/md/raid1.o
/bin/insmod -f /lib/modules/2.4.26-std-smp-alt1/kernel/fs/jbd/jbd.o
/bin/insmod -f /lib/modules/2.4.26-std-smp-alt1/kernel/fs/ext3/ext3.o
/bin/raidautorun /safedev/md255
mkinitrd: Inode count: 55
mkinitrd: Image size: 892K
mkinitrd: Created image from tree: /root/tmp/initrd.dmjMQg4478/tree --> /root/tmp/initrd.dmjMQg4478/img
mkinitrd: Created romfs image file
mkinitrd: Installed ramdisk into /boot/initrd-raid1.img
open /dev/fb0: No such device
Ramdisk size: 268K
Необходимо проверить, что последней строкой в скрипте linuxrc является
/bin/raidautorun /safedev/md255, которая запускает массив. Без неё у
вас будет возникать ошибка
Kernel panic : VFS : Unable to mount root fs on 09:01.
Далее необходимо исправить конфигурацию LILO в файле /etc/lilo.conf :
boot=/dev/md1
raid-extra-boot=mbr-only
И для всех используемых ядер изменить параметр изменить корневую
файловую систему и вписать сделанный на предыдущем шаге initrd :
image=/boot/vmlinuz-2.4.26-std-smp-alt1
label=2426-raid1
root=/dev/md1
read-only
optional
vga=normal
initrd=/boot/initrd-raid1.img
Далее следует сгенерировать и запустить наш массив (делать это нужно,
загрузившись с ремонтного набора):
# mkraid /dev/md0
# mkraid /dev/md1
Состояние массива можно наблюдать в файле /proc/mdstat. Там будет
отображаться информация о том, что массив работает в degraded mode.
Обновляем загрузчик:
# /sbin/lilo -v
Warning: using BIOS device code 0x80 for RAID boot blocks
Added 2426-raid1 *
The Master boot record of /dev/sda has been updated.
Перезагружаемся. Массив работает сейчас с одного диска, поэтому мы
должны подключить второй. Если диск не был подключен к серверу и
оборудование позволяет подключать SCSI-устройства "на лету", то
физически подключаем диск к серверу (при этом в syslog отображается
информация об этом: scsi0: Someone reset channel A). Для того, чтобы
устройство стало видно операционной системе, проделаем следующую
операцию:
# echo "scsi add-single-device 0 0 1 0" > /proc/scsi/scsi
где 1 - Id устройства на SCSI-шине. В документации к моему серверу
указано, что SCSI Id соотнесены со слотами для подключения жестких
дисков на постоянной основе и приведена схема какому гнезду какой
номер соответствует, поэтому советую вам обратиться к документации
сервера для уточнения данного вопроса.
После добавления устройства таким образом в syslog записывается
информация о имени устройства в операционной системе:
Apr 12 14:42:57 alm kernel: scsi singledevice 0 0 1 0
Apr 12 14:42:57 alm kernel: blk: queue d6521618, I/O limit 4095Mb (mask 0xffffffff)
Apr 12 14:42:57 alm kernel: Vendor: FUJITSU Model: MAP3735NC Rev: 5207
Apr 12 14:42:57 alm kernel: Type: Direct-Access ANSI SCSI revision: 03
Apr 12 14:42:57 alm kernel: blk: queue e128ce18, I/O limit 4095Mb (mask 0xffffffff)
Apr 12 14:42:57 alm kernel: scsi0:A:0:0: Tagged Queuing enabled. Depth 253
Apr 12 14:42:57 alm kernel: scsi0:A:1:0: Tagged Queuing enabled. Depth 253
Apr 12 14:42:57 alm kernel: Attached scsi disk sdb at scsi0, channel 0, id 1, lun 0
Apr 12 14:43:06 alm kernel: (scsi0:A:1): 320.000MB/s transfers (160.000MHz DT|IU|QAS, 16bit)
Apr 12 14:43:06 alm kernel: SCSI device sdb: 143571316 512-byte hdwr sectors(73509 MB)
Apr 12 14:43:06 alm kernel: sdb: unknown partition table
Строка Attached scsi disk sdb at scsi0, channel 0, id 1, lun 0
сообщает нам о том, что подключенный диск будет виден как /dev/sdb, а
строка sdb: unknown partition table сообщает о том, что скорее всего
был добавлен ни разу не использованный диск. Самое время разбить его
также, как и /dev/sda :
# sfdisk -d /dev/sda > /tmp/sda.out
# sfdisk /dev/sdb < /tmp/sda.out
Диск переразбит, самое время подключить его к массиву:
# raidhotadd /dev/md0 /dev/sdb1
# raidhotadd /dev/md1 /dev/sdb2
Диск подключен и процесс восстановления массива должен автоматически
запуститься. Наблюдать за ним можно при помощи вот такой нехитрой
команды:
# watch -n 5 cat /proc/mdstat
Проверяем, что тип разделов на /dev/sdb установлен в fd :
# fdisk /dev/sdb
Command (m for help): p
Disk /dev/sdb: 73.5 GB, 73508513792 bytes
255 heads, 63 sectors/track, 8936 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sdb1 1 63 506016 fd Linux raid autodetect
/dev/sdb2 * 64 8936 71272372+ fd Linux raid autodetect
После окончания восстановления (а можно и во время) осталось обновить
загрузчик на добавленном диске:
# /sbin/lilo -v
Warning: using BIOS device code 0x80 for RAID boot blocks
Added 2426-raid1 *
The Master boot record of /dev/sda has been updated.
Warning: /dev/sdb is not on the first disk
The Master boot record of /dev/sdb has been updated.
Напоследок осталось подправить файл /etc/raidtab - удалить из него
строки failed-disk 1. Не забывайте про данный файл. Он используется в
стартовых скриптах для запуска/останова устройств /dev/md?, поэтому
важно иметь содержимое этого файла в соответствии с вашей текущей
конфигурацией массива.
Готово!
Добавление и удаление дисков из работающего массива
---------------------------------------------------
Так случается, что диски иногда отказывают. :-(
Для начала необходимо отключить сбойный диск из массива (пусть это
будет /dev/sda для примера):
# raidsetfaulty /dev/md0 /dev/sda1
# raidsetfaulty /dev/md1 /dev/sda2
# raidhotremove /dev/md0 /dev/sda1
# raidhotremove /dev/md1 /dev/sda2
После этого необходимо отключить диск от операционной системы, для
чего необходимо выяснить его параметры на шине SCSI. Ядра ALT Linux
(начиная с 2.4.22) собираются со специальным патчем, который позволяет
это сделать:
$ cat /proc/scsi/scsi_sd
sda: scsi00(0,0,0)
sdb: scsi00(0,1,0)
Если у вас нет /proc/scsi/scsi_sd, то нужно обратиться к документации
сервера для выяснения какому слоту какой SCSI Id соответствует. Обычно
ядро нумерует устройства по порядку. Это значит, что если у вас есть
диски 0 0 0 0 и 0 0 3 0, то первый диск получит имя /dev/sda, а второй
- /dev/sdb - несмотря на то, что Id у него 3 а не 1.
Удаляем устройство:
# echo "scsi remove-single-device 0 0 0 0" > /proc/scsi/scsi
После этого диск можно смело вытаскивать физически из сервера. Если в
массиве были резервные (spare) диски, то после выдачи команд
raidsetfaulty и raidhotremove автоматически начнется восстановление на
один из них. Если резервных дисков не было, то массив продолжит
работать в degraded mode.
Создано: bk_man <http://www.linux-os.ru/Members/bk_man>
Последнее изменение: 2004-05-21 03:22
На raid superblock уходит некоторое количество блоков, поэтому /dev/md* (RAID1) будет чуть меньше блочных устройств, из которых он сделан. Если это не было учтено при mkfs, то придётся поправлять по ходу дела -- посмотрев в /proc/mdstat размер в блоках результирующих устройств, сказать:
e2fsck -f /dev/md0
resize2fs /dev/md0 767072 (пример для 3Gb блоками по 4k, который тут оказался)
10. convert existing filesystem to RAID 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# The idea is to create a degraded RAID 1 on the second partition, move
# data, then hot add the first. This seems safer to me than simply to
# force-add a superblock to the existing filesystem.
#
# Assume /dev/sda1 holds the data (and let's assume it's mounted on
# /home) and /dev/sdb1 is empty and of the same size...
#
mdadm --create /dev/md0 -l1 -n2 /dev/sdb1 missing
mkfs -t <type> /dev/md0
mount /dev/md0 /mnt
tar -cf- -C /home . | tar -xf- -C /mnt -p
# consider verifying the data
umount /home
umount /mnt
mount /dev/md0 /home # also change /etc/fstab
mdadm --add /dev/md0 /dev/sda1