I have a firewall running OpenBSD 3.7 installed on a SATA disk known to the system as wd0. An identical disk, wd1, is available and not being used. For added data security, I would like to mirror the content of wd0 to wd1 without re-installing or taking the box offline for more than a couple of minutes. After searching the net for HOWTO’s and information I finaly found a NetBSD guide, that helped me in the right direction. The missing pieces was found in the raidctl manpage. Below are the steps that I have taken to achive my goal. You should be able to use my instructions on your own system by changing device names and/or create labels according to your own needs. If you decide to use this guide, please make sure you have backed up all data. Proceed at your own risk!
Modify the Kernel Compile and reboot a new kernel with RAIDframe enabled:
option RAID_AUTOCONFIG # RAID Autoconfiguration pseudo-device raid 4 # RAIDframe disk driver
Initialize the second disk with fdisk This is only needed on i386 systems:
$ fdisk -i wd1
Setup disklabels With the disklabel -E wd1 command, you can add appropriate labels. I have added the following:
a: for complete minimal installation, 2G b: for swap, 512M c: unused e: for RAID rootfs, 2G f: for RAID swap, 2G g: for usr,home,etc, the rest
Remember to set FS type to RAID for e,f & g (FS type: [4.2BSD] RAID)! If you fail to do this, the system won’t find the raid devices.
Copy OpenBSD to wd1a It is not possible to load the kernel from a RAID device, so we have to make a small partition with a full OpenBSD installation and your RAIDframe aware kernel. Maybe it’s possible to skip this and load the kernel from a floppy or something… i don’t know.
Create filesystem on wd1a and mount:
$ newfs /dev/wd1a $ mount /dev/wd1a /mnt
Copy required data to wd1a (I have /, /var & /usr as seperate mounts)
dump -0 -f - / | (cd /mnt && restore -x -f -) dump -0 -f - /var | (cd /mnt/var && restore -x -f -) dump -0 -f - /usr | (cd /mnt/usr && restore -x -f -)
Modify /mnt/etc/fstab to look like:
[root@firewall ~] $ cat /mnt/etc/fstab /dev/wd1a / ffs rw 1 1
Umount wd1a:
$ umount /mnt
wd1a should contain a working copy of your OpenBSD installation including your new kernel with RAID support build in.
Create RAID configuration :
The disk /dev/wd9 is non-existing and is used as a dummy for wd0 during setup. Remember to create the device node for wd9:
$ cd /dev && sh MAKEDEV wd9
Create RAID configuration for raid0: (Read the raidctl man page for more details on the syntax.)
$ cat < raid0.conf
Create RAID configuration for raid1:
$ cat > raid1.conf <
Create RAID configuration for raid2:
$ cat > raid2.conf <
Create the RAID devices (use -c if re-creating):
$ raidctl -C raid0.conf raid0 $ raidctl -C raid1.conf raid1 $ raidctl -C raid2.conf raid2
Initialize the component labels each with a unique serial:
$ raidctl -I 200509290 raid0 $ raidctl -I 200509291 raid1 $ raidctl -I 200509292 raid2
Initialize the RAID with verbose output:
$ raidctl -iv raid0 $ raidctl -iv raid1 $ raidctl -iv raid2
Setup RAID disklabels
Setup a label on raid0 for the root filesystem:
$ disklabel -E raid0 a: for /, all available space
Setup a label on raid1 for swap:
$ disklabel -E raid1 b: for swap, all available space
Setup labels on raid2 for the other mountpoints:
$ disklabel -E raid2
I have created the following labels:
- e: for /tmp, 2G
- f: for /var, 8G
- g: for /usr, 4G
- h: for /usr/local, 8G
- i: for /usr/obj, 4G
- j: for /usr/ports, 4G
- k: for /usr/src, 4G
- l: for /home, rest of the disk
This is properly overkill, but I like to seperate things and my box is equipped with two 200Gb drives and i won’t need the space for anything.
Create filesystems and populate
So far so good. Now we need to create the filesystems with newfs and copy data from wd0 to the raid devices:
Create and copy to raid0a (/ -> /mnt)
$ newfs raid0a $ mount /dev/raid0a /mnt $ dump -0 -f - / | (cd /mnt && restore -x -f -)
Create and copy to raid2e (/tmp -> /mnt/tmp)
$ newfs raid2e $ mount /dev/raid2e /mnt/tmp $ dump -0 -f - /tmp | (cd /mnt/tmp && restore -x -f -)
Create and copy to raid2f (/var -> /mnt/var)
$ newfs raid2f $ mount /dev/raid2f /mnt/var $ dump -0 -f - /var | (cd /mnt/var && restore -x -f -)
Create and copy to raid2g (/usr -> /mnt/usr)
$ newfs raid2g $ mount /dev/raid2g /mnt/usr $ dump -0 -f - /usr | (cd /mnt/usr && restore -x -f -)
Create and copy to raid2h (/usr/local -> /mnt/usr/local)
$ newfs raid2h $ mount /dev/raid2h /mnt/usr/local $ dump -0 -f - /usr/local | (cd /mnt/usr/local && restore -x -f -) $ umount /mnt/usr/local
Create and copy to raid2i (/usr/obj -> /mnt/usr/obj)
$ newfs raid2i $ mount /dev/raid2i /mnt/usr/obj $ dump -0 -f - /usr/obj | (cd /mnt/usr/obj && restore -x -f -) $ umount /mnt/usr/obj
Create and copy to raid2j (/usr/ports -> /mnt/usr/ports)
$ newfs raid2j $ mount /dev/raid2j /mnt/usr/ports $ dump -0 -f - /usr/ports | (cd /mnt/usr/ports && restore -x -f -) $ umount /mnt/usr/ports
Create and copy to raid2k (/usr/src -> /mnt/usr/src)
$ newfs raid2k $ mount /dev/raid2k /mnt/usr/src $ dump -0 -f - /usr/src | (cd /mnt/usr/src && restore -x -f -) $ umount /mnt/usr/src
Create and copy to raid2l (/home -> /mnt/home)
$ newfs raid2l $ mount /dev/raid2l /mnt/home $ dump -0 -f - /home | (cd /mnt/home && restore -x -f -) $ umount /mnt/home
Modify fstab, unmount and make bootable
$ cat /mnt/etc/fstab /dev/raid0a / ffs rw 1 1 /dev/raid1b none swap sw 0 0 /dev/raid2l /home ffs rw,nodev,nosuid,softdep 1 2 /dev/raid2e /tmp ffs rw,nodev,nosuid,softdep 1 2 /dev/raid2g /usr ffs rw,nodev,softdep 1 2 /dev/raid2h /usr/local ffs rw,nodev,softdep 1 2 /dev/raid2i /usr/obj ffs rw,nodev,nosuid,softdep 1 2 /dev/raid2j /usr/ports ffs rw,nodev,nosuid,softdep 1 2 /dev/raid2k /usr/src ffs rw,nodev,nosuid,softdep 1 2 /dev/raid2f /var ffs rw,nodev,nosuid,softdep 1 2
Unmount /mnt/var, /mnt/usr, /mnt/tmp & /mnt
$ umount /mnt/var $ umount /mnt/usr $ umount /mnt/tmp $ umount /mnt
Make second disk bootable
$ mount /dev/wd1a /mnt $ chroot /mnt /usr/mdec/installboot -n /boot /usr/mdec/biosboot wd1 $ umount /mnt
The NetBSD guide wrote something about parity errors when rebooting without unmounting the swapfs. I have added the following to my /etc/rc.shutdown file just in case:
swapoff=YES # Unconfigure swap to avoid parity errors if [ "X${swapoff}" != X"NO" ]; then echo "Unmounting swap on raid1" swapctl -d /dev/raid1b fi
Make RAID autoconfigurable & reboot
Make the RAID’s autoconfigurable with the root filesystem on raid0:
$ raidctl -A root raid0 $ raidctl -A yes raid1 $ raidctl -A yes raid2
Reboot your system and remember to boot wd1 !
$ shutdown -r now
When the OpenBSD boot loader appears, type: boot wd1a:/bsd
During boot you should see something like
Kernelized RAIDframe activated raid0 (root): (RAID Level 1) total number of sectors is 4194176 (2047 MB) as root raid1 (root): (RAID Level 1) total number of sectors is 4194176 (2047 MB) raid2 (root): (RAID Level 1) total number of sectors is 226476160 (110584 MB)
Add your primary disk
Relabel wd0 with same layout as wd1
$ disklabel wd1 > disklabel.wd1 $ sed -e 's/wd1/wd0/g' disklabel.wd1 > disklabel.wd0 $ disklabel -R -r wd0 disklabel.wd0
Add hotspares (wd0), remove dummy devices & reconstruct raid (one at a time is preferred). Check recontruction with raidctl -s raid.
Add hotspare, remove dummy & recontruct raid0:
$ raidctl -a /dev/wd0e raid0 $ raidctl -F component0 raid0 $ raidctl -S raid0
Add hotspare, remove dummy & recontruct raid1:
$ raidctl -a /dev/wd0f raid1 $ raidctl -F component0 raid1 $ raidctl -S raid1
Add hotspare, remove dummy & recontruct raid2:
$ raidctl -a /dev/wd0g raid2 $ raidctl -F component0 raid2 $ raidctl -S raid2
When all raids have been rebuild, it’s time to rebuild the parity:
$ raidctl -P raid0 $ raidctl -P raid1 $ raidctl -P raid2
Check the parity with raidctl -p raid’. Only when Parity Status: clean you’re safe.
NOTE: remember installboot on wd0!
Final Words
I hope my information was of any use. It took me a full day to figure out :)
Please contact me if you find any errors or know a better/easier way to accomplish this.