Software RAID on Debian Linux

This how-to demonstrates the procedure for converting your current Debian Linux install into a RAID 1 array (mirrored). Although I use Debian for this example, the principles are the same on other Linux distributions. The instructions can also be easily adapted to any level of RAID.

Use your current install or install Debian as you would normally do it. You will need to install enough or the system to allow for custom kernel configuration, i.e. compiling your own kernel. The reason you can’t use the default install’s kernel is because you must have support for the automount filesystem, meaning that the kernel can detect and boot from your RAID partitions, type 0xfd (Linux RAID auto). When I try to add automount support during the install’s kernel setup, it gacks. I didn’t spend any time google’ing around for a way to force it on the install, so if anyone knows a way to get automount into the install’s kernel please let me know and I’ll update this how-to.

Compile your kernel as you would normally do it, with the exception of adding “Multiple Device” support to your kernel configuration for the RAID level(s) you’ll be using (see appendix A). Under the supported file systems, include “Kernel automounter” (see appendix B).
NOTE: RAID and file systems must be compiled into the kernel, NOT as modules!
INSTALL REQUIRED TOOLS:

Now “apt-get install” a few apps that you’ll need for the migration to raid.
Raidtools2 (required)
Reiserfsprogs (required if using reiserfs. You’ll need to format the RAID array with whatever file system you choose.)
VIM (Not required, but very useful.)

Let’s say I have two drives, /dev/hda and /dev/hdc. /dev/hda is partitioned as follows:
Hda1 /boot ext2 200m type 83
Hda2 swap 768m type 82
Hda3 / reiserfs 18g type 83

Now partition /dev/hdc as follows (identical in size but with type FD partitions):

Hdc1 200m type fd
Hdc2 768m type fd
Hdc3 18g type fd
MAKING THE RAID:

Now that you have installed the new kernel and required tools it’s time to get down to brass tacks. What we’ll be doing is making a RAID 1 array with a failed mirror, /dev/hda, and copy all of its data to the RAID array. Then boot from the RAID array and add /dev/hda to the mirror.

Type “swapoff –a” to turn off your swap space. Also edit your /etc/fstab (Appendix F) to reflect your new devices and comment out your swap partition. You’ll also have to switch into single user mode by entering “init 1”.
Next create the /etc/raidtab file by copying the following file (see appendix C), or type “man raidtab > /etc/raidtab” and clean it up in vi. Note that disk 1 (/dev/hda) has been marked as failed.

After you’ve created the /etc/raidtab file, it’s time to make the RAID arrays by using the “mkraid” command. Enter this:

mkraid /dev/md0
mkraid /dev/md1
mkraid /dev/md2

You can check the status of your raid arrays by typing “cat /proc/mdstat”. (see appendix E) Now format them with the file system that you use. I’m using ext2 for /boot and reiserfs for /:

mkfs.ext2 /dev/md0
mkswap /dev/md1
mkfs.reiserfs /dev/md2

You must now copy over your data from /dev/hda to /dev/hdc. To do this mount /dev/md0 to /mnt/boot and /dev/md2 to /mnt/root and copy your files like so:

mkdir /mnt/boot
mkdir /mnt/root
mount /dev/md0 /mnt/boot
mount /dev/md2 /mnt/root
cd /
find . –xdev | cpio –pm /mnt/root (this may take a while)
cd /mnt/root/boot
rm –rf *
cp –Rfa /boot /mnt/boot

Now change the “root=” reference in /etc/lilo.conf to “root=/dev/md2” and run “/sbin/lilo”.

Now reboot to single user mode by typing “-s” after the kernel that you want to use when the lilo screen appears after rebooting.After booting up and logging in, issue the “cat /proc/mdstat” and the “mount” commands to see if all went well. If all is happy, partition /dev/hda identically to /dev/hdc and uncomment the swap partition in /etc/fstab. In the /etc/raidtab file, comment out the failed-drive references and uncomment the raid-disks references. Now add /dev/hda to the array by typing:
raidhotadd /dev/md0 /dev/hda1
raidhotadd /dev/md1 /dev/hda2
raidhotadd /dev/md2 /dev/hda3

Again you can check the status of the arrays by cat’ing /proc/mdstat. It should look something like this while generating the array:

debian:~# cat /proc/mdstat 
Personalities : [raid1] [multipath] 
md1 : active raid1 hdc2[0] hda2[1]
      787072 blocks [2/2] [UU]
      
md2 : active raid1 hda3[2] hdc3[0]
      77152064 blocks [2/1] [U_]
      [>....................]  recovery =  3.7% (2925180/77152064) finish=62.2min speed=19860K/sec
md0 : active raid1 hdc1[0]
      208704 blocks [2/1] [U_]

Lastly, you’ll need to update your /etc/lilo.conf to reflect the changes and to be able to boot from either disk. Change the “boot=” line to “boot=/dev/md0” and add the line “raid-extra-boot=/dev/hda,/dev/hdc” and run “/sbin/lilo”

This should have you up and running. It’ll take a while for your drives to sync, but when it’s finished you’ll have a nice RAID 1 array capable of booting from either disk. You may now want to add a cron job to check the /proc/mdstat for failed disks and let you know about it.

Appendix A Kernel Config, Multiple Devices
  x x [*] Multiple devices driver support (RAID and LVM) 

  x x <*> RAID support 

  x x < > Linear (append) mode 

  x x < > RAID-0 (striping) mode 

  x x <*> RAID-1 (mirroring) mode 

  x x < > RAID-4/RAID-5 mode 

  x x <*> Multipath I/O support 

  x x <*> Logical volume manager (LVM) support 

Appendix B Kernel Config, Automount File System
  x x       [ ] Quota support                                                       
  x x       < > Kernel automounter support                                          
  x x       <*> Kernel automounter version 4 support (also supports v3)             

Appendix C raidtab
# md0 
  raiddev /dev/md0
  raid-level 1
  nr-raid-disks 2
  chunk-size 32 # Has no effect on RAID 1
  persistent-superblock 1
  device /dev/hdc1
  raid-disk 0
  device /dev/hda1
  #raid-disk 1
  failed-disk 1
# md1 
  raiddev /dev/md1
  raid-level 1
  nr-raid-disks 2
  chunk-size 32 # Has no effect on RAID 1
  persistent-superblock 1
  device /dev/hdc2
  raid-disk 0
  device /dev/hda2
  #raid-disk 1
  failed-disk 1
# md2
  raiddev /dev/md2
  raid-level 1
  nr-raid-disks 2
  chunk-size 32 # Has no effect on RAID 1
  persistent-superblock 1
  device /dev/hdc3
  raid-disk 0
  device /dev/hda3
  #raid-disk 1
  failed-disk 1

Appendix D Lilo.conf
lba32
boot=/dev/md0
raid-extra-boot=/dev/hda,/dev/hdc
root=/dev/md2
install=/boot/boot-menu.b
map=/boot/map
delay=20
	prompt
	timeout=100
vga=normal
default=Linux2.4.24

image=/vmlinuz
	label=Linux
	read-only

image=/boot/vmlinuz-2.4.24
	label=Linux2.4.24
	read-only

Appendix E /proc/mdstat
debian:~# cat /proc/mdstat 
Personalities : [raid1] [multipath] 
md1 : active raid1 hdc2[0] hda2[1]
      787072 blocks [2/2] [UU]
      
md2 : active raid1 hdc3[0] hda3[1]
      77152064 blocks [2/2] [UU]
      
md0 : active raid1 hdc1[0] hda1[1]
      208704 blocks [2/2] [UU]
      
unused devices: 

Appendix F /etc/fstab
debian:~# cat /etc/fstab
# /etc/fstab: static file system information.
#
#                        
/dev/md2        /               reiserfs        defaults        0       0
/dev/md1        none            swap    sw                      0       0
proc            /proc           proc    defaults                0       0
/dev/fd0        /floppy         auto    user,noauto             0       0
/dev/cdrom      /cdrom          iso9660 ro,user,noauto          0       0
/dev/md0        /boot   ext2    defaults                        0       2