Software RAID 1 (mirroring) mit 2.4.x Kernel auf Debian Basis

Marcus Schopen <marcus dot schopen at uni dash bielefeld dot de>

Stand: 18.06.2002

Wem selbst ein IDE Hardware RAID mit ca. 110 € (z.B. Promise Fasttrack/100 TX2) immer noch zu teuer ist, kann hier auf die kostengünstigere Variante des Software-RAIDs für SCSI und IDE Festplatten zurückgreifen. Das folgende kleine "HOWTO" beschreibt ein bootbares RAID 1 auf einer Debian Woody.


0. Vorüberlegungen

Bevor hier losgelegt wird, sollte man ein Backup auf dritte Medien anfertigen (DAT, CD, Partition Image etc.). Es wird zwar eine Lösung beschrieben, die ohne ein Backup des laufenden Systems auf dritte Medien auskommt, jedoch sollte man keine unnötigen Risiken eingehen.

Das HOWTO lässt sich ohne weiteres auf RAID 5 übertragen. Weiterführende Hinweise befinden sich unter den Links am Ende der Seite.

Die zweiten Festplatte sollte wenn möglich an den zweiten IDE/SCSI-Channel gehängt und als Master gejumpert werden (hier leider nicht der Fall).


1. Partitionierung der Festplatten

Ich gehe davon aus, dass bereits eine Debian woody mit 2.4er Kernel installiert wurde bzw. der Leser mit dem Debian Installationssetup vertraut ist. Wer an dieser Stelle ein neues System aufsetzen möchte, sollte hierfür die 2.4er Boot-Floppys benutzen und schon bei der Installation beide Festplatten identisch partitionieren. Die Installation erfolgt hierbei wie gewohnt auf die erste Festplatte (hda).

Die Mountpoints auf der ersten Festplatte (hda) auf diesem System wie folgt aus:

Mountpoint hda Partition (erste Festplatte)
/ /dev/hda4
/boot /dev/hda1
/usr /dev/hda5
/home /dev/hda6
/var /dev/hda7
/tmp /dev/hda8
/vol /dev/hda9


Entsprechend sollte die zweite Festplatte (hdb) partitioniert werden. Sind beide Festplatten identisch partitioniert (z.B. mit cfdisk), sind auf der zweiten Festplatte (hdb) alle Partition - bis auf die swap - auf den Typ "fd" (= Linux raid autodetect) zu setzen:

Partitionierung hdc

Zu formatieren brauchen wir die zweite Festplatte (hdb) vorerst nicht.

Zusatz: Bei einer Neuinstallation der Debian woody von den 2.4er Kernel Boot-Floppys werden in "/etc/apt/sources.list" fälschlicherweise die Quellen der potato (derzeit stable) übernommen. Solange woody noch nicht stable ist, sind im file "/etc/apt/sources.list" alle "stable"-Einträge durch "woody" zu ersetzen. Danach ist "apt-get update" aufzurufen, um die passenden woody Paket Informationen herunterzuladen.


2. Kernel

Wir benötigen einen eigenen Kernel, da im 2.4.18er Kernel von Debian die RAID Unterstützung nur als Module gebaut wurden. Den Kernel holt man sich am besten direkt von ftp.de.kernel.org und packt ihn unter /usr/src/ ins Verzeichnis "linux" aus.

In das Verzeichnis "/usr/src/linux" wechseln und mit "make menuconfig" den neuen Kernel konfigurieren. Die Konfiguration für ein RAID 1 sollte so aussehen:

RAID Konfiguration 2.4.18 Kernel

Jetzt noch ein schnelles

make dep; make clean; make bzlilo; make modules; make modules_install; lilo

und der neue Kernel sollte fertig sein. Vielleicht einmal den Rechner neu starten, um sicher zu gehen, dass der neue Kernel einwandfrei arbeitet.

Zusatzinfo: Zum Bauen des Kernels müssen mindestens folgende Packete installiert sein: gcc, make, libc6-dev und libncurses5-dev. Etwaige weitere Anhängigkeiten erkennt der Packetmanager automatisch.


3. RAID2-Tools

Wir installieren uns die RAID2 Tools:

apt-get install raidtoos2



4. RAID konfigurieren

Wir legen die Datei /etc/raidtab mit folgendem Inhalt an. Hilfreich ist diese Übersetungstabelle, um nicht ganz den Überblick zwischen RAID und physikalischen Partitionen zu verlieren:

Mountpoint RAID Partition hda Partition (erste Festplatte) hdb Partition (zweite Festplatte)
/ /dev/md0 /dev/hda4 /dev/hdb4
/boot /dev/md1 /dev/hda1 /dev/hdb1
/usr /dev/md2 /dev/hda5 /dev/hdb5
/home /dev/md3 /dev/hda6 /dev/hdb6
/var /dev/md4 /dev/hda7 /dev/hdb7
/tmp /dev/md5 /dev/hda8 /dev/hdb8
/vol /dev/md6 /dev/hda9 /dev/hdb9


Wichtig ist, dass die erste Festplatte(hda) hier noch als "failed-disk" markiert ist!

# example /etc/raidtab
# md0 is the root array
raiddev			/dev/md0
raid-level		1
nr-raid-disks		2
chunk-size		32
# Spare disks for hot reconstruction
nr-spare-disks		0
persistent-superblock	1
device			/dev/hdb4
raid-disk		0
# this is our old disk, mark as failed for now
device			/dev/hda4
failed-disk		1


# md1 is the /boot array
raiddev			/dev/md1
raid-level		1
nr-raid-disks		2
chunk-size		32
# Spare disks for hot reconstruction
nr-spare-disks		0
persistent-superblock	1
device			/dev/hdb1
raid-disk		0
# boot is marked failed as well
device			/dev/hda1
failed-disk		1


# md2 is the /usr array
raiddev			/dev/md2
raid-level		1
nr-raid-disks		2
chunk-size		32
# Spare disks for hot reconstruction
nr-spare-disks		0
persistent-superblock	1
device			/dev/hdb5
raid-disk		0
# boot is marked failed as well
device			/dev/hda5
failed-disk		1


# md3 is the /home array
raiddev			/dev/md3
raid-level		1
nr-raid-disks		2
chunk-size		32
# Spare disks for hot reconstruction
nr-spare-disks		0
persistent-superblock	1
device			/dev/hdb6
raid-disk		0
# boot is marked failed as well
device			/dev/hda6
failed-disk		1


# md4 is the /var array
raiddev			/dev/md4
raid-level		1
nr-raid-disks		2
chunk-size		32
# Spare disks for hot reconstruction
nr-spare-disks		0
persistent-superblock	1
device			/dev/hdb7
raid-disk		0
# boot is marked failed as well
device			/dev/hda7
failed-disk		1


# md5 is the /tmp array
raiddev			/dev/md5
raid-level		1
nr-raid-disks		2
chunk-size		32
# Spare disks for hot reconstruction
nr-spare-disks		0
persistent-superblock	1
device			/dev/hdb8
raid-disk		0
# boot is marked failed as well
device			/dev/hda8
failed-disk		1


# md6 is the /vol array
raiddev			/dev/md6
raid-level		1
nr-raid-disks		2
chunk-size		32
# Spare disks for hot reconstruction
nr-spare-disks		0
persistent-superblock	1
device			/dev/hdb9
raid-disk		0
# boot is marked failed as well
device			/dev/hda9
failed-disk		1

Zusatz: die Swap Partitionen werden nicht im RAID-Array gehalten. Swap Partitionen werden von Haus aus durch den Kernel in einer Art Stripe RAID geführt.


5. RAID einrichten

Wir setzen nun nacheinander die einzelnen RAID Partitionen auf. Die erste Festplatte (hda) wird hier noch nicht beachtet, da wir sie ja als "failed-disk" markiert haben.

bob:~# mkraid /dev/md0
bob:~# mkraid /dev/md1
bob:~# mkraid /dev/md2
bob:~# mkraid /dev/md3
bob:~# mkraid /dev/md4
bob:~# mkraid /dev/md5
bob:~# mkraid /dev/md6


6. RAID formatieren

Wir formatieren die einzelnen RAID Partitionen auf der zweiten Festplatte (hdb) im ext3 oder ext2 Format:

bob:~# mkfs.ext3 /dev/md0
bob:~# mkfs.ext3 /dev/md1
bob:~# mkfs.ext3 /dev/md2
bob:~# mkfs.ext3 /dev/md3
bob:~# mkfs.ext3 /dev/md4
bob:~# mkfs.ext3 /dev/md5
bob:~# mkfs.ext3 /dev/md6

7. System kopieren

Wir kopieren das komplette System von der ersten Festplatte (hda) auf die Festplatte mit dem RAID-System (hdb). Hierzu legen wir uns unter dem /mnt auf  der ersten Festplatte entsprechend den einzelnen Partitionen folgende Verzeichnisse an:

bob:~# mkdir /mnt/root
bob:~# mkdir /mnt/boot
bob:~# mkdir /mnt/usr
bob:~# mkdir /mnt/home
bob:~# mkdir /mnt/var

Jetzt mounten wir die die einzelnen RAID-Partitionen auf diese Verzeichnisse:

bob:~# mount /dev/md0 /mnt/root
bob:~# mount /dev/md1 /mnt/boot
bob:~# mount /dev/md2 /mnt/usr
bob:~# mount /dev/md3 /mnt/home
bob:~# mount /dev/md4 /mnt/var

und kopieren das komplette System bis auf die Verzeichnisse /mnt/, /proc/ und z.B. nfs in die gemounteten Verzeichnisse:

bob:~# cp -a /boot/ /mnt/boot/
bob:~# cp -a /usr/ /mnt/usr/
bob:~# cp -a /home/ /mnt/home/
bob:~# cp -a /var/ /mnt/var/

Nun die / root Partition kopieren:

bob:~# cp -a /bin/ /mnt/root/
bob:~# cp -a /dev/ /mnt/root/
bob:~# cp -a /etc/ /mnt/root/
bob:~# cp -a /initrd/ /mnt/root/
bob:~# cp -a /lib/ /mnt/root/
bob:~# cp -a /opt/ /mnt/root/
bob:~# cp -a /root/ /mnt/root/
bob:~# cp -a /sbin/ /mnt/root/
bob:~# cp -a /vmlinuz* /mnt/root/
bob:~# cp /*.* /mnt/root/

Je nach Struktur müssen ggf. einzelne Verzeichnisse ausgelassen oder hinzugefügt werden, aber das Prinzip sollte hiermit wohl deutlich sein.

Nun sind noch die einzelnen Mount-Points auf der RAID root Partition "/mnt/root/" anzulegen:

bob:~# mkdir /mnt/root/boot
bob:~# mkdir /mnt/root/home
bob:~# mkdir /mnt/root/tmp
bob:~# mkdir /mnt/root/usr
bob:~# mkdir /mnt/root/var
bob:~# mkdir /mnt/root/vol

Zum Schluss nicht das /proc Verzeichnis vergessen:

bob:~# mkdir /mnt/root/proc

Man sollte sich unbedingt vergewissern, dass das System auf der RAID Festplatte (hdb) identisch mit dem der ersten Festplatte (hda) ist. Wurden hier Dateien vergessen, sind sie später nicht mehr wieder herzustellen.


8. File System

Auf der root Partition der RAID Festplatte (hdb) passen wir die "fstab" in "/mnt/root/etc/" wie folgt an:

# /etc/fstab: Tabelle einzubindender Dateisysteme.
#
# <Dateisystem> <Mountpunkt>    <Typ>   <Optionen>                      <dump>  <pass>
/dev/md0        /               ext3    defaults,errors=remount-ro      0       1
/dev/hda2       none            swap    sw                      0       0
/dev/hdb2       none            swap    sw                      0       0
proc            /proc           proc    defaults                        0       0
/dev/fd0        /floppy         auto    defaults,user,noauto            0       0
/dev/cdrom      /cdrom          iso9660 defaults,ro,user,noauto         0       0
/dev/md1        /boot   ext3    defaults                        0       2
/dev/md2        /usr    ext3    defaults                        0       2
/dev/md3        /home   ext3    defaults                        0       2
/dev/md4        /var    ext3    defaults                        0       2
/dev/md5        /tmp    ext3    defaults                        0       2
/dev/md6        /vol    ext3    defaults                        0       2


9. Boot Floppy

Wir erstellen uns eine Boot-Floppy, mit der auf das RAID auf der zweiten Festplatte gebootet werden kann:

dd if=/vmlinuz of=/dev/fd0 bs=2k
rdev /dev/fd0 /dev/md0
rdev -r /dev/fd0 0
rdev -R /dev/fd0 1

und booten das System von dieser Diskette. Vor dem Reboot sollten alle gemounteten md-Devices unter "/mnt" mit "umount" freigegeben werden. Das System sollte nun von den RAID-Partitionen der zweiten Festplatte (hdb) gestartet werden. Mount zeigt uns dies:

bob:~# mount
/dev/md0 on / type ext3 (rw,errors=remount-ro)
proc on /proc type proc (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/md1 on /boot type ext3 (rw)
/dev/md2 on /usr type ext3 (rw)
/dev/md3 on /home type ext3 (rw)
/dev/md4 on /var type ext3 (rw)
/dev/md5 on /tmp type ext3 (rw)
/dev/md6 on /vol type ext3 (rw)

Ist dies nicht der Fall, starten Sie das System ganz normal von hda und überprüfen Sie alle vorherigen Schritte.

Erst wenn Sie sich ganz sicher sind, dass das System auf dem RAID zuverlässig arbeitet, sollten Sie mit dem nächsten Schritt fortfahren und die erste Festplatte (hda) in das bestehende RAID-Array einreihen. Danach sind alle Daten auf Festplatte hda unwiederbringlich verloren. Es existiert nur noch die Kopie auf Festplatte hdb.


10. RAID vervollständigen

Vorab:

Nun hängen wir die erste Festplatte mit "raidhotadd" in das RAID-Array ein:

bob:~# raidhotadd /dev/md0 /dev/hda4
bob:~# raidhotadd /dev/md1 /dev/hda1
bob:~# raidhotadd /dev/md2 /dev/hda5
bob:~# raidhotadd /dev/md3 /dev/hda6
bob:~# raidhotadd /dev/md4 /dev/hda7
bob:~# raidhotadd /dev/md5 /dev/hda8
bob:~# raidhotadd /dev/md6 /dev/hda9

Je nach Größe der einzelnen Partition kann die Synchronisation der beiden Festplatten unterschiedlich lange dauren. Der aktuelle Stand lässt sich mittel "cat /proc/mdstat" ermitteln:

bob:~# cat /proc/mdstat
Personalities : [linear] [raid1] [multipath]
read_ahead 1024 sectors
md1 : active raid1 hda1[1] hdb1[0]
15936 blocks [2/2] [UU]

md2 : active raid1 hda5[1] hdb5[0]
13671168 blocks [2/2] [UU]

md3 : active raid1 hda6[1] hdb6[0]
13671168 blocks [2/2] [UU]

md4 : active raid1 hda7[1] hdb7[0]
9767424 blocks [2/2] [UU]

md5 : active raid1 hda8[1] hdb8[0]
489856 blocks [2/2] [UU]

md6 : active raid1 hda9[2] hdb9[0]
29294400 blocks [2/1] [U_]
[=====>...............] recovery = 25.1% (7364608/29294400) finish=144.4min speed=2528K/sec
md0 : active raid1 hda4[1] hdb4[0]
10747392 blocks [2/2] [UU]

unused devices: <none>

Es ist ratsam, vor einem Reboot die Synchronisation aller Partitionen abzuwarten. Ggf. kann dies einige Stunden dauern.


11. RAID bootbar machen:

Wir erstellen und eine neue lilo conf, um das System direkt vom RAID bootbar zu machen:

# /etc/lilo.conf - mit RAID Support

# Support LBA for large hard disks.
#
lba32

# Overrides the default mapping between harddisk names and the BIOS'
# harddisk order. Use with caution.
disk=/dev/md0
bios=0x80
partition=/dev/md1

# Specifies the boot device.  This is where Lilo installs its boot
# block.  It can be either a partition, or the raw device, in which
# case it installs in the MBR, and will overwrite the current MBR.
#
boot=/dev/hda

# Specifies the device that should be mounted as root. (`/')
#
root=/dev/md0

# Installs the specified file as the new boot sector
# You have the choice between: bmp, compat, menu and text
# Look in /boot/ and in lilo.conf(5) manpage for details
#
install=/boot/boot-menu.b

# Specifies the location of the map file
#
map=/boot/map

# Specifies the number of deciseconds (0.1 seconds) LILO should
# wait before booting the first image.
#
delay=20


# Specifies the VGA text mode at boot time. (normal, extended, ask, <mode>)
#
vga=normal

# Boot up Linux by default.
#
default=Linux

image=/vmlinuz
	label=Linux
	read-only

image=/vmlinuz.old
	label=LinuxOLD
	read-only
	optional

und schreiben diese mit

bob:~# lilo -C /etc/lilo.conf 

in den Masterboot Record der hda Festplatte. 

Wer möchte, kann auch noch eine lilo.conf für die hdb Festplatte erstellen, so dass bei einem Ausfall von hda direkt von hdb gebootet werden kann. Hierzu legen wir für hdb eine eigene lilo.conf.hdb an und passen die Zeile "boot=/dev/hda" nach "boot=/dev/hdb" an. Ein

bob:~# lilo -C /etc/lilo.conf.hdb

schreibt die Bootinformationen in den MBR von hdb. Es erscheint eine Warnung »/dev/hdb is not on the first disk«, aber das soll uns nicht stören, denn im Backup-Fall wird diese Festplatte ja zur ersten Festplatte im System. Dafür muss sie natürlich noch an den ersten (E)IDE Kanal gehängt werden!

In der Regel reicht es bei einem Ausfall von hda aber aus, von der oben erstellten Bootdiskette von hdb zu booten.

 

12. Wer's testen will

Wir fahren den Rechner herunter, trennen die erste Festplatte (hda) ab, hängen die zweite Festplatte (hdb) an den ersten IDE-Channel  und starten den Rechner erneut. Es sollte nun von hdb (jetzt hda) gebootet werden. Ist dies nicht der Fall, verwendet man einfach die erstellte Startdiskette. Wir fahren den Rechner erneut herunter, hängen die erste Festplatte (hda) wieder an, starten den Rechner und hängen nach erfolgreichem Reboot die hda Partitionen per Hand mit "raidhotadd" wieder in das RAID-Array ein.

 

13. Was ist los mit Bob?

Das System kommt überhaupt nicht mehr mit dem Software-RAID hoch. Hilfe, was tun?

In diesem Fall besteht immer noch die Möglichkeit, mit der Debian Rescue Disk ein Notfall-Linux von Diskette zu booten. Dort lässt man sich mit ALT-F2 auf eine shell abwerfen und mountet die root Partition einer der beiden RAID-Festplatten (hda4 oder hdb4) mit  "mount /dev/hda4 /mnt". 
   Auf der gemounteten Partition ersetzt man in der Datei "fstab" unter "/mnt/etc/" alle md-Devices durch entsprechende hda- oder hdb-Devices (siehe Tabelle oben). Danach von der eigenen, oben erstellten Bootdiskette das System booten und am lilo Prompt "linux root=/dev/hda4" eingeben. Das System sollte nun von Festplatte hda oder hdc ohne RAID hochkommen.

 

14. Zusatz

Die Geschwindigkeit der Festplatten lässt sich häufig mit "hdparm" erheblich steigern:

bob:~# apt-get install hdparm

vorher:

bob:~# hdparm -Tt /dev/hda
Timing buffer-cache reads: 128 MB in 0.46 seconds =278.26 MB/sec
Timing buffered disk reads: 64 MB in 17.25 seconds = 3.71 MB/sec

optimiert:

bob:~# hdparm -Tt /dev/hda
Timing buffer-cache reads: 128 MB in 0.46 seconds =278.26 MB/sec
Timing buffered disk reads: 64 MB in 2.54 seconds = 25.20 MB/sec

Eine detailierte Beschreibung zu hdparm findet sich hier.

 

15. Links


Änderungen und freundliche Kritik an: marcus dot schopen at uni dash bielefeld dot de

Have fun!