Debian WheezyがインストールされているパーティションをRAID1に変更する方法

前回の記事で自宅サーバのバックアップであれこれ悩んでみたが、結論としてはRAID1+定期バックアップという構成に落ち着いた。やはり今からbtrfsを入れるのは腰が重かった。

本構成を実現するにあたり1つ問題となったのが、どうやってDebian WheezyがインストールされているパーティションをRAID1に変更するかであった。RAID1を組んで、RAIDボリュームを認識させた後にOSをインストールするのは容易いが、逆は思いの外難しい。あれこれ調べてみると、日本語の記事ではDebian Etchで実施したという記事は出てくるのだが、いかんせんgrubが古いので参考にならない。結局、以下のサイトを参考にした。

参考
How To Set Up Software RAID1 On A Running System (Incl. GRUB2 Configuration) (Ubuntu 10.04) - Page 2 - Page 2

Setting up RAID on an existing Debian/Ubuntu installation

上記を参考にして実際にやってみた結果を書いてみようと思う。結論を言うと、無事にRAID1のボリュームを認識させることができた。

まず、大きな流れは以下のようになる。

  1. 新規ディスクのパーティションにRAID1をデグレード状態で構築。
  2. grub等を設定し、RAIDデバイスからbootできるようにする。
  3. 作成したRAID1デイバスをmountし、既存のdebianのシステムをまるごとコピーする。
  4. RAIDデバイスからのbootに成功したら、元々Debianが入っていたパーティションをRAID1に参加させる。

grubの設定以外は簡単である。

仮定として、現在Debian Wheezyがインストールされているパーティションは/dev/sda1、RAID1として追加したい新規ディスクのパーティションは/dev/sdb1とする。両者のサイズは予め同じにしておき、パーティションタイプを0xfdにしておく。これはfdiskを使えば簡単にできる。(入力する際には0xは不要。)

root@emperor:~# fdisk /dev/sda

Command (m for help): t
Partition number (1-5): 1
Hex code (type L to list codes): fd  

また、RAIDの構築にはmdadmというツールを使用する。入っていなければインストールしよう。

では、ステップ1について述べる。まずは新規パーティションを使ってRAID1を構築する。RAID1はミラーリングなので、当たり前だがディスクは2つ必要である。しかし、まずはディスク1つの状態でRAID1を構築する。(デグレード状態。)

mdadm --create /dev/md0 --level=1 --raid-devices=2 missing /dev/sdb1 

これで新しく/dev/md0というRAID1のデバイスが作成される。上記コマンドのmissingというところがミソで、これによってディスク1つでRAID1が構築できるようになる。

作成したmd0にファイルシステムを作成するのをお忘れなく。

mkfs.ext4 /dev/md0

では、ステップ2に進もう。最大の難関はgrubであるが、それ以外にもいろいろ設定が必要である。

まず、mdadmの設定ファイルに今作ったmd0の情報を追記する。

mdadm --examine --scan >> /etc/mdadm/mdadm.conf

">>"ではなく">"にしてしまうと死亡するので注意が必要である。

次に、boot時にmd0のボリュームを最初に起こすように設定する。

dpkg-reconfigure mdadm

あれこれ言われるが、allとなっているところを/dev/md/0に置き換えればOKだ。なぜか/dev/md0だとうまくいかないのは謎である。どちらにせよ、/dev/md/0は/dev/md0へのシンボリックリンクになっているので、同じことである。

fstabも変更しておく必要がある。今までは/dev/sda1をルートパーティションとしていたが、今度からは/dev/md0がルートパーティションになる。例として私のfstabの設定を示す。

/dev/md0    /    ext4    errors=remount-ro    0    1

ここでいよいよgrubの設定を行う。正直に言うと、一度失敗してgrub rescueに落ちてしまい、あれやこれやと手を打ってなんとか直したというのが事実なので、ここは何が正しい手順なのか自信がない。とりあえずやってみたことをあれこれ書いていく。

まず、grubのconfig設定を行う。

dpkg-reconfigure grub-pc

grubのインストール先を聞かれるところで、/dev/sdaと/dev/sdbを選択する。/dev/md0を選んではいけないので注意が必要である。

次に、grubの設定ファイルを書いていく。ベースとして/etc/grub.d/40_customをコピーし、/etc/grub.d/09_swraid1_setupというファイルを作成する。*1

作成したファイルを開いて、以下のように記述する。

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-amd64' --class debian --class gnu-linux --class gnu --class os {
        insmod gzio
        insmod mdraid1x
        insmod part_msdos
        insmod raid
        insmod ext2
        set root='(md/0)'
        search --no-floppy --fs-uuid --set=root 9d87ce79-fa38-4fd0-a936-b7dc9ce159cf
        linux   /boot/vmlinuz-3.2.0-4-amd64 root=/dev/md0 ro quiet
        initrd  /boot/initrd.img-3.2.0-4-amd64
}

searchの行が必要かどうかは自信がないが、あれこれ試行錯誤しているうちにつけてみた。最後の番号はmd0のUUIDを記述する。UUIDはblkidコマンドで調べられる。最初のmenuentryやlinux, initrdの項目のカーネルバージョンは、自分の環境に合ったものを設定する必要がある。/boot/grub/grub.cfgの中で"### BEGIN /etc/grub.d/10_linux ###"と書かれているセクションの設定を参考にすると良いだろう。

上記ファイルが設定できたら、以下のコマンドでgrub.cfgファイルを更新する。

update-grub 

grub2の方針なのか知らないが、直接/boot/grub/grub.cfgをいじるということはしないようだ。

initramfsも更新する。

update-initramfs -u

これでgrubの設定はおしまいである。

続いてステップ3に移る。ここは簡単で、md0を適当なところにmountしてルートファイルシステムをまるごとコピーすればよい。

mkdir /mnt/raid
mount /dev/md0 /mnt/raid
rsync -auHx --exclude=/proc/* --exclude=/sys/* --exclude=/tmp/* /* /mnt/raid

状況が気になる人はrsyncに-vを足しても良いだろう。

最後に、これも必要なのかよく分かっていないが、grub-installを実行しておく。

grub-install /dev/sda
grub-install /dev/sdb

さあ、次が最後のステップである。システムをrebootし、起動できるかどうか確かめよう。ちなみに、私の環境だとfd0がないとかなんとかいうエラーが出るようになってしまったが、起動はできている。致命的ではないが、時間ができたら解決したいところだ。

システムが無事に起動できたらdfコマンドを叩いてみよう。以下のような行があれば成功である。

/dev/md0        82504240 30052404  48260816  39% /

ここまで確認できたら、既存の/dev/sda1をmd0に加える。

mdadm /dev/md0 -a /dev/sda1 

/dev/sda1をmd0に追加すると、すぐにミラーリングが始まる。以下のコマンドで進捗が監視できる。

watch -n1 cat /proc/mdstat

無事にミラーリングが完了したら、もう一度以下のコマンドを叩いておく。

update-grub

あとはもう一度rebootして、立ち上がってくるのを祈る。ちなみに私は最初ここでgrub rescueに落ちた(笑)

以上で手順はおしまいだが、grub rescueに落ちるようになってしまった際の復旧のヒントについて書いておくことにする。

まず、一番大切なのは慌てないことである。データは存在しているのだから、grubさえ直せば元通りになる。落ち着いて対処しよう。

次に、CDやUSBメモリなどからOSを立ち上げて復旧作業に入る。ここで私が焦ったポイントが1つある。それは、/dev/sda1や/dev/sdb1はもはやmountできないということである!なぜならRAIDだから。ではどうするかというと、慌てず騒がずmdadmをインストールしよう。そうすれば/dev/md0が見えるはずなので、これを適当なところにmountできる。すると、データは全て無事であることが確認できる。そうなればあとはmountしたところにchrootして設定をやり直せばよいだけの話だ。chrootするときは/procやら/sysやらの扱いに注意して欲しい。以下の記事などを参考にすると良いだろう。

d.hatena.ne.jp

以上で今回の記事はおしまいだ。起動時に謎のエラーメッセージが出るのだけは気に食わないが、RAID1自体は問題なく構築できて大満足であった。ついでにgrub rescueに落ちても動じない鉄の精神が身についた。こういう保守作業を通して人は強くなっていくものなので、また何か面白いことを思いついたらやってみよう。

*1:ファイル名は好きにして良いと思うが、恐らく09というところは変えない方がよい。grubの仕組みをさっぱり理解していないので推測だが、ここの番号が若い順に設定ファイルの優先度が高くなっているような気がする。そして、通常のboot設定の番号が10になっているので、ここでは09としているのだと思う。