GeekFactory

int128.hatenablog.com

RAID1+LVMにルートファイルシステムを置く

RAID1+LVMのボリューム上にルートファイルシステムを置くには、起動時にRAID1ボリュームとLVMボリュームの両方を認識してやる必要があります。そのためにはinitramfsを使います。

下記の構成を考えます。

物理ボリューム RAIDボリューム タイプ
/dev/sda1 + /dev/sdb1 /dev/md0 ext3 (/boot)
/dev/sda2 + /dev/sdb2 /dev/md1 swap
/dev/sda3 + /dev/sdb3 /dev/md2 Linux LVM

起動時の流れは下記のようになります。

  1. /dev/sda(MBR)からブートストラップを読み込む。
  2. /dev/sda1からブートローダを読み込む。
  3. /dev/sda1からkernelとinitramfsを読み込む。
  4. kernelのブートコードが実行される。
  5. initramfsのスクリプトが実行される。
  6. RAID1ボリュームを認識する。
  7. LVMボリュームを認識する。
  8. ルートファイルシステムをマウントする。
  9. /sbin/initを実行する。

構築

まず、必要なパッケージを準備します。

# mkdir /boot/initramfs
# cd /boot/initramfs
# wget http://svn.coderepos.org/share/platform/linux/initramfs-util/createinitramfs
# ./createinitramfs

content以下に必要なディレクトリを作成します。

# cd /boot/initramfs
# mkdir content/{dev,etc,point,proc,sys}

実行ファイルをコピーします。依存するライブラリも同時にコピーされます。

# cd /boot/initramfs
# ./createinitramfs /bin/busybox /sbin/vgchange /sbin/mdadm
# cd content
# tar xf /usr/share/busybox/busybox-links.tar
# rm linuxrc

(x86_64の場合に必要)
# cd /boot/initramfs
# mv lib/* lib64
# rmdir lib
# ln -s lib64 lib

/boot/initramfs/content/init スクリプトを作成します。

#!/bin/sh
# initramfs script for Linux 2.6 LVM/RAID

echo -e "\x1b[1;32m *\x1b[0m Setting up filesystems"
/bin/mount -t proc none /proc
/bin/mount -t sysfs none /sys
/bin/mount -t tmpfs none /dev
/bin/mount -t tmpfs none /etc
/sbin/mdev -s

echo -e "\x1b[1;32m *\x1b[0m Scanning for raid device(s)"
echo 'DEVICE /dev/sd[abcd][0-3]' > /etc/mdadm.conf
/sbin/mdadm --examine --scan >> /etc/mdadm.conf

for d in `grep -o '/dev/md[0-9]' /etc/mdadm.conf`; do
        echo -e "\x1b[1;32m *\x1b[0m Activating raid device... $d"
        /sbin/mdadm --assemble "$d"
done

echo -e "\x1b[1;32m *\x1b[0m Activating logical volume(s)"
/sbin/vgchange -a y

echo -e "\x1b[1;32m *\x1b[0m Mounting rootfs... $ROOT"
ROOT="`cat /proc/cmdline | sed -ne 's,.*root=\([^ ]*\).*,\1,p'`"
[ -b "$ROOT" ] || exec /bin/ash
/bin/mount -o ro "$ROOT" /point || exec /bin/ash

echo -e "\x1b[1;32m *\x1b[0m Switching rootfs"
/bin/umount /sys /proc /dev /etc
exec /sbin/switch_root /point /sbin/init

exec /bin/ash

最後にinitramfsを作成して完了です。

# cd /boot/initramfs
# ./createinitramfs
# mv initramfs.gz ..