EFIなマシンにソフトRAID1でDebianをインストール

概要

(U)EFIなマシンがよく分かっていない。 が、時代の流れ的に(U)EFIなマシンにLinuxをインストールする必要が出てきた。 この記事では、よく分かっていない(U)EFIなマシンにソフトRAIDを組みながらインストールするという無謀なことをやる。 最近のソフトRAIDはRAID0,1くらいなら十分に実用になると聞いたので、ハードウェアのRAIDコントローラは導入せずにソフトウェアでRAID1を組むことにした。

ちなみに、この記事はインストール完了後から書いているので、この通りにやって動くかどうかは分からん。 トラブル発生時に自分で何とかできそうな人だけにオススメする。

ディスクの準備

当然ながら同じ容量(同じ型番が良いらしい。理由は知らん)のディスクを2台用意しないことには始まらない。

今回は以下のように4台のディスクを用意した。

  • 500GB x 2台: システムのメインとして使用する
  • 3TB x 2台: ユーザデータ格納用として使用する

インストール

全ディスクをマシンに刺して、ディスクのパーティション設定時以外は普通にインストールすればいい。 各ディスクは同じパーティション構成にしておく。 自分の場合はこんな感じにした。

ディスク パーティション サイズ マウントポイント タイプ
500GB (1) /dev/sda1 100M   EFI system
/dev/sda2 200M /boot ext4
/dev/sda5 メモリと同じだけ   swap
/dev/sda6 残り全部 / ext4
500GB (2) /dev/sdb1 100M   EFI system
/dev/sdb2 200M /boot2 ext4
/dev/sdb5 メモリと同じだけ   swap
/dev/sdb6 残り全部   ext4
3TB (1) /dev/sdc1 全部   ext4
3TB (2) /dev/sdd1 全部   ext4

パーティション設定画面にRAIDを設定する部分があるので、ここでRAIDを設定する。 EFIをRAIDに設定することはできないし、 /boot に関しては grub-install のときに悲惨な目に遭うとのことなので、自分で冗長化しておくことにした。

/dev/sda6/dev/sdb6/dev/md0 を、/dev/sdc1/dev/sdd1/dev/md1 をRAID1として設定する。

スワップに関しては、別々のディスクにパーティションを設けていればRAID0とほぼ同じ効果を出すことができるのでRAIDの設定をしなくて良い。

あとは /dev/md0/ に、 /dev/md1/home などにマウントしてインストールを続行すればOK。

スワップを平等に使う

デフォルトの設定ではスワップが平等に使われないかもしれない。 スワップの状態は /proc/swaps で確認できる。 以下のように優先度( Priority )が同じであれば平等に使われることとなる。

% cat /proc/swaps
Filename                                Type            Size    Used    Priority
/dev/sdb5                               partition       15624188        0       1
/dev/sda5                               partition       15624188        0       1

もしPriorityが異なる場合には、 /etc/fstabpri オプションを使って優先度を指定する。

UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx none           swap      sw,pri=1      0   0
UUID=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy none           swap      sw,pri=1      0   0

/bootとEFIシステムパーティションの冗長化

まずは /boot を冗長化する。 冗長化と言っても、壊れたときにデータを復元できるようにバックアップを取っているだけなので、故障時には復旧作業が必要になる。

冗長化用のパーティションは /boot2 としてマウントしてあるはずなので、ここに丸ごとコピーすればOK。 ただし、 /boot/efi は別のパーティションなので除外する。 マウントするためにディレクトリは作成しておく。

% sudo rsync --exclude "efi/" -avrz -e cp /boot/ /boot2/
% sudo mkdir /boot2/efi

EFIシステムパーティションに関してはgrubをインストールすることで同じ内容のパーティションを作成できるが、念のためまったく同じ状態にしておく。 後でgrubを使って上書きするので、この作業は必要ないかもしれない。

% sudo dd if=/dev/sda1 of=/dev/sdb1

このままではUUIDまで同じになってしまうので、UUIDを書き換える。 EFIシステムパーティションはvfatでフォーマットされているのだが、vfatのUUIDを書き換える方法が分からんのでddで無理矢理書き換える。

バイナリエディタが必要になるのでbviを導入する。

% sudo apt-get install bvi

パーティションの先頭部分を書き出して、UUIDを変更してから書き戻す。 0x43から4 byteがUUID。リトルエンディアン。 他のディスクとUUIDが異なればいいので、普通は1 byte書き換えれば十分。 各パーティションのUUIDは ls -l /dev/disk/by-uuid で確認できるので、これを見ると参考になるかも。 ただし dd コマンド使用後は /dev/sda1/dev/sdb1 のUUIDが同じものになっていまっているため、この部分だけはうまく表示できない場合がある。

% sudo dd if=/dev/sdb1 of=/tmp/blk bs=512 count=1
% sudo bvi /tmp/blk

これをディスクに書き戻す。

% sudo dd if=/tmp/blk of=/dev/sdb1 bs=512 count=1

/etc/fstab も変更しておく。 /dev/sdb1 はマウントされてないと思われるので、 /dev/sda1 の行をコピーしてUUIDとマウント先を書き換えればOK。

UUID=xxxx-xxxx  /boot2/efi       vfat    umask=0077      0       1

UUIDを書き換えたので、念のため再起動しておく。 /etc/fstab を書き換えたので /boot2/efi がマウントされるはず。

あとはrootになって以下のような感じでgrubをインストールすればOK。 efivars モジュールがロードされていればEFIブートマネージャ(?)にも登録される。 すなわち、BIOSでブート順を指定するところに現れるようになる。

% sudo grub-install --target=x86_64-efi --efi-directory=/boot2/efi --bootloader-id="debian (sub)" --recheck

EFIブートマネージャへの登録状況は、オプションなしで efibootmgr を実行すれば確認できる。

% sudo efibootmgr
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0001,0000,0003,0006,000B
Boot0000* debian
Boot0001* debian (sub)
Boot0003* UEFI: Built-in EFI Shell
Boot0006* CD/DVD Drive
Boot000B* Hard Drive

efivars モジュールがロードされていなければ、以下のようにしてEFIブートマネージャに登録する。 オプション類はmanを参照のこと。

% sudo efibootmgr -c -g -d /dev/sdb -p 1 -L "debian (sub)" -l '\EFI\debian\grubx64.efi'