ReadOnlyなrootfsをaufsでマウントしReadWrite可能なFSに見せかける
-
Author: uncho
Linuxをインストールしたルートファイルシステムをリードオンリーでマウントし一切ファイルに変更を加えず、しかも再起動すれば変更した設定をクリアできる。。そんな環境を作ることになりました。条件として、ファイルに変更をしなくても通常のサーバと同様に設定変更できるようにする必要がある為、aufsを使いルートファイルシステムをマウントすることによって実現させてみたいと思います。
なお、ここではルートファイルシステムをNFSで提供する環境を前提で書いていますので必要によって各自の環境で読み替えて下さい。aufsについてはこちらを参照下さい。
実施環境:
- OS:CentOS5.4
- Kernel Ver:2.6.31.6
1. aufsが使えるカーネルを構築する
aufsを利用する為にはカーネルがaufsをサポートしている必要がある為、aufsが適用されたカーネルを構築する必要があります。構築手順についてはこちらを参照下さい。
2. initrdの作成
rootfsが’/’にマウントされる前に、先にaufsで/sysrootをマウントする必要がある為、必要な処理をinitrdに組み込む必要があります。まず、変更を加えるinitrdを生成し必要な処理を書き込む準備をします。なお、ここではrootfsをNFSでマウントすることを前提で書いており、「–with」でNICのドライバを指定、「–root*」でNFSマウントに必要なパラメータをして指定しています。環境に合わせて変更して下さい。
cd /tmp/
mkinitrd --with=pcnet32 --with=mii --rootopts=ro,nolock,rsize=1024,wsize=1024 --net-dev=eth0 --rootdev=192.168.110.250:/export/NFSroots/CentOS54-DISKLESS --rootfs=nfs initrd-2.6.31.6.img 2.6.31.6
3. initrdファイルの展開
生成したinitrdファイルの実体は、gzip+cpioですのでそれらを使って展開させ、必要な処理を組み込み改造できるようにします。
gzip -cd initrd-2.6.31.6.img > initrd
mkdir workrd
cd workrd/
cpio -i --file=../initrd
4. 処理に必要なコマンドをinitrdへコピー
initrdの/binには必要最低限のコマンドしか用意されていないので、必要なコマンドをコピーして組み込みます。必要なコマンドとは、ここではbashとbusyboxですので、これらを展開したinitrdにコピーします。
cp /bin/bash bin/.
cp /busybox bin/.
ldd /bin/bash # lddコマンドでbashに必要なライブラリを確認します。
cp /lib/libtermcap.so.2 lib/.
cp /lib/libdl.so.2 lib/.
cp /lib/libc.so.6 lib/.
cp /lib/ld-linux.so.2 lib/.
コピーが終わったらbusyboxで使うコマンドのリンクを作成します。
cd bin/
ln -s busybox ln
ln -s busybox mkdir
ln -s busybox mount
cd ..
5. initスクリプトの修正
initrdにあるinitスクリプトはnashのスクリプトになっています。このスクリプトにこの後に作る処理スクリプトのファイル名を記述します。また私の環境では、initスクリプトでnetnameがあるとNICの初期化がうまくいかず、NFSがマウントできなかったので削除しました。
vi init
echo Mounting root filesystem.
mount /sysroot
echo Start Special Script. # この行を追加
aufs.sh # この行を追加
echo Setting up other filesystems.
setuproot
6. aufsマウント処理スクリプトの作成
aufsマウントする処理をするシェルスクリプトをbin配下に作成します。
vi bin/aufs.sh
#!/bin/bash
/bin/mkdir /rw
/bin/mkdir /ro
/bin/mount -t tmpfs aufs-tmpfs /rw
/bin/mount --move /sysroot /ro
/bin/mount -t aufs -o br:/rw:/ro=ro aufs /sysroot
/bin/mount --move /rw /sysroot/rw
/bin/mount --move /ro /sysroot/ro
exit 0
chmod 755 bin/aufs.sh
シェルスクリプトが行っている処理を説明すると、/rwと/roディレクトリを作成し、RAMディスクを/rwにマウントします。その後すでにReadOnlyでマウントされているrootfsをmountコマンドの–move オプションで/roへ移動させます。この時点でRAMディスクの/rwとReadOnlyのrootfsの/roが揃ったので、これらをaufsで纏めて/sysrootにマウントし直します。これで完成なのですが、ブートの途中で/sysrootが/にマウントされる事で、/rwと/roが見られなくなってしまうため、/rwと/roをブート後も参照出来るように、mount –moveコマンドで/sysroot/rw,/sysroot/roへ移動させます。(/sysroot/rw,/sysroot/roは事前にReadOnly側のFS上に作って置く必要があります)
7. initrdの再アーカイブ化と/boot配下へのコピー
修正したinitrdをcpio+gzipでアーカイブし直します。ここでは直接/bootのinitrdを置き換えていますが、必要によってgrub.conf等を修正して下さい。
find . -print | cpio -o --file=../initrd_new --format=newc
cd ..
gzip -c9 initrd_new > initrd-2.6.31.6.img
mv /boot/initrd-2.6.31.6.img /boot/initrd-2.6.31.6.img.org
mv initrd-2.6.31.6.img /boot/.
これで一通り完成です。記憶をたどりながら書いたので多少抜けがあるかもしれません。