Create A Software RAID1
by Darrel Johnston (djohnston)
Backup, backup, backup your personal files. Your vacation pictures, family tree history files, the movie of your daughter’s graduation, financial spreadsheets and digital art you created cannot be replaced if they are lost. Unless, of course, you have backups. A backup program can be manually run by the user, but that requires the discipline of the user remembering to run the backup. A backup program can be scheduled to be run automatically. However, that means that any new files written after the last backup can potentially be lost before the next backup is scheduled to be run. Creating the backups takes extra disk space, even if the disk space is part of an internet storage service.
With a RAID1 array setup, there is very little chance that you will ever lose your data. That is because a RAID1 disk array is a mirrored setup. Anything written to one disk or set of disks is also written to the mirrored disk or set of disks. So, although you need at least one extra hard drive to set up the disk array, it is not much different from needing extra disk space to store your program-created backups. The advantage is that the backup files are created almost instantaneously. With a two disk RAID1 setup, if one drive fails, the other one keeps running. Once a replacement drive for the failed one is installed, the still running drive synchronizes all its data to the new blank drive. After synchronization is complete, the two drives begin reading and writing data in tandem again.
Many of today’s motherboards come with RAID capabilities built into the board. And, add-on RAID controllers can be bought for reasonable prices. In reality, though, you do not need a hardware RAID controller in order to enjoy the benefits of a RAID1 setup. You can control the RAID1 entirely with software from the PCLinuxOS repositories. Although there may be a slight performance decrease in using a software driven setup rather than a hardware driven one, the performance loss won’t be very much. All you need are two matched hard drives and the willingness to convert them into a RAID1 array.
What I mean by matched hard drives is that they should be close to equal in capability. They do not have to be exact twins. The potential storage capacity of the RAID1 array is only as large as the smallest drive in the array. And the potential read and write speeds in the array are only as fast as the slowest drive in the array. So, it is important to match the drives as closely as possible. You would not want to use a 300GB drive with a 500GB drive because the total capacity of the RAID1 array would be 300GB. The extra 200GB space on the 500GB drive would not be used. The read and write speeds should be close to the same because the slower drive will cause unneeded wait times for the faster drive.
Before beginning, be sure you have the following packages installed on your system from Synaptic: dmraid, dmraid-events, libdmraid1 and mdadm. The setup in this tutorial assumes that the user will use the RAID1 array as a data storage device, and not as a home directory or root filesystem partition. I set up a software RAID1 using two 10GB hard drives and started by creating sdb1 and sdc1 partitions with fdisk.
Creating the RAID1 array
[root@localhost ~]# fdisk /dev/sdb
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4, default 1): 1
First sector (2048-20971519, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519):
Using default value 20971519
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): fd
Changed system type of partition 1 to fd (Linux raid autodetect)
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
[root@localhost ~]#
[root@localhost ~]# fdisk /dev/sdc
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4, default 1): 1
First sector (2048-20971519, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519):
Using default value 20971519
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): fd
Changed system type of partition 1 to fd (Linux raid autodetect)
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
[root@localhost ~]#
Next, I created the RAID1 array using mdadm, then formatted /dev/md0 with the xfs filesystem.
[root@localhost ~]# mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1
mdadm: array /dev/md0 started.
[root@localhost ~]# mkfs.xfs /dev/md0
meta-data=/dev/md0 isize=256 agcount=4, agsize=655292 blks
= sectsz=512 attr=2, projid32bit=0
data = bsize=4096 blocks=2621168, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@localhost ~]#
Then I checked the results by listing all drives with fdisk.
[root@localhost ~]# fdisk -l
Disk /dev/sda: 8589 MB, 8589934592 bytes
255 heads, 63 sectors/track, 1044 cylinders, total 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sda1 * 63 2088449 1044193+ 82 Linux swap / Solaris
/dev/sda2 2088450 16771859 7341705 83 Linux
Disk /dev/sdb: 10.7 GB, 10737418240 bytes
107 heads, 17 sectors/track, 11529 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sdb1 2048 20971519 10484736 fd Linux raid autodetect
Disk /dev/sdc: 10.7 GB, 10737418240 bytes
107 heads, 17 sectors/track, 11529 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sdc1 2048 20971519 10484736 fd Linux raid autodetect
Disk /dev/md0: 10.7 GB, 10736304128 bytes
2 heads, 4 sectors/track, 2621168 cylinders, total 20969344 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/md0 doesn't contain a valid partition table
[root@localhost ~]#
Notice the invalid partition table for /dev/md0. It doesn’t mean the device is unusable. It simply means fdisk does not know how to deal with a RAID device. Next, I made a mount point for md0, mounted it, checked the space on the drives, then unmounted md0.
[root@localhost ~]# mkdir /mnt/raid1
[root@localhost ~]# mount /dev/md0 /mnt/raid1
[root@localhost ~]# df -H
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 7.4G 2.1G 5.0G 30% /
/dev/md0 11G 34M 11G 1% /mnt/raid1
[root@localhost ~]# umount /mnt/raid1
[root@localhost ~]#
I added one line to my /etc/fstab file:
/dev/md0 /mnt/raid1 xfs defaults 1 2
The mount point for md0 is /mnt/raid1. And sdb1, sdc1 and md0 look like the following:
I changed permissions on /mnt/raid1 to give all users full access.
[root@localhost ~]# chmod 777 -R /mnt/raid1
[root@localhost ~]# ls -l /mnt | grep raid1
drwxrwxrwx 2 root root 4096 Jun 29 03:49 raid1/
[root@localhost ~]#
Just one more step to take. As root, edit the file /etc/mdadm.conf. The entire file is commented, so I just added the line below to the bottom of the file.
ARRAY /dev/md0 devices=/dev/sdb1,/dev/sdc1 level=1 num-devices=2 auto=yes
I created a desktop file on my LXDE desktop that I can click on to access the contents of the RAID1 array. I also created a shortcut to the mountpoint on my home directory by entering in a terminal:
[darrel@localhost ~]$ ln -s /mnt/raid1 ~/RAID1
My desktop and home directory look like this:
The contents of the RAID1 desktop file are:
[Desktop Entry]
Type=Application
Icon=/usr/share/icons/gnome/48x48/devices/drive-harddisk.png
Name=RAID1
Exec=pcmanfm /mnt/raid1
StartupNotify=true
Terminal=false
MimeType=x-directory/normal;inode/directory;
Encoding=UTF-8
X-Desktop-File-Install-Version=0.11
So, we now have a RAID1 array set up. Whatever is written to /dev/sdb1 will also be written to /dev/sdc1. To the system, both drives appear to be one unit, /dev/md0. And /dev/md0 is mounted as /mnt/raid1 and has a volume label of RAID1. But how can we be sure that both drives in the array are working? In a terminal, run the command: cat /proc/mdstat
You will see something similar to the following:
Personalities : [raid1]
md0 : active raid1 sdb1[0] sdc1[1]
10484672 blocks [2/2] [UU]
unused devices: <none>
Replacing a failed drive and rebuilding the array
If you have a degraded RAID1 array, instead of the string [UU] you will see [U_]. If a disk has failed, you will probably find a lot of error messages in the log files /var/log/messages and/or /var/log/syslog. Assuming that the log files show /dev/sdc1 has failed, we must remove and replace it. We will use the mdadm RAID management program for all steps. First, we have to mark /dev/sdc1 as failed.
[root@localhost ~]# mdadm --manage /dev/md0 --fail /dev/sdc1
[root@localhost ~]#
Then we check the RAID1 status. /dev/sdc1 should have an (F) designation.
[root@localhost ~]# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb1[0] sdc1[1](F)
10484672 blocks [2/1] [U_]
unused devices: <none>
[root@localhost ~]#
Next we need to remove /dev/sdc1 from /dev/md0:
[root@localhost ~]# mdadm --manage /dev/md0 --remove /dev/sdc1
mdadm: hot removed /dev/sdc1
[root@localhost ~]#
When we check the RAID1 status again, /dev/sdc1 should not be listed.
[root@localhost ~]# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb1[0]
10484672 blocks [2/1] [U_]
unused devices: <none>
[root@localhost ~]#
Once the failed drive has been logically removed from the software RAID controller, it is time to shut down the computer, physically remove the drive and replace it with another.
[root@localhost ~]# shutdown -h now
After you have replaced the failed hard drive and rebooted the computer, you can easily duplicate the partitioning scheme of the still running drive with just one command:
[root@localhost ~]# sfdisk -d /dev/sdb | sfdisk /dev/sdc
Run fdisk -l as root to check that both drives have the same partitioning. Next we need to add /dev/sdc1 to /dev/md0.
[root@localhost ~]# mdadm --manage /dev/md0 --add /dev/sdc1
mdadm: re-added /dev/sdc1
[root@localhost ~]#
Now the array /dev/md0 will be synchronized. Run cat /proc/mdstat to see when it's finished.
During the synchronization the output will look like this:
[root@localhost ~]# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb1[0] sdc1[1]
10484672 blocks [2/1] [U_]
[=>...................] recovery = 19.9% (2414398/10484672) finish=1.4min speed=126519K/sec
Once the synchronization has completed, the RAID1 array will again look like the following.
[root@localhost ~] cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb1[0] sdc1[1]
10484672 blocks [2/2] [UU]
unused devices: <none>
[root@localhost ~]
xyzabc-placeholder