2014年2月13日木曜日

ramdisk(/dev/ram0)を使ってカーネルビルド時間を短縮

CentOS 6 のカーネルを若干カスタマイズして、再ビルドして使っている環境があるのですが、ビルド時間を多少短縮したいのと、SSD の消耗を軽減したく、ramdisk を使ってみました。

以下、自分向けのメモですが、どなたかの参考まで。

まず、ビルドに利用しているマシンは、メモリ 16G 積んでます。
カーネルをビルドするには、だいたい 10G は空きディスクが必要なので、ramdisk のサイズを 10G にするため、grub.conf にブートパラメータを追加します。
    ... ramdisk_size=10240000
再起動したら、ramdisk にメモリを割り付けてしまうため、ゼロ埋め処理します。
# shred -z -n 0 /dev/ram0
これは、dd if=/dev/zero of=/dev/ram0 bs=1M としても、いいですが。。

あとは、mkfs してマウントします。
# mkfs -t ext4 /dev/ram0
# mkdir /mnt_ram0
# mount /dev/ram0 /mnt_ram0
そんで、~/rpmbuild の内容を ram0 へコピーします。
# cd ~/rpmbuild
# tar cf - . | (cd /mnt_ram0 ; tar xf -)
最後に、ram0 を ~/rpmbuild へ再マウントします。
# umount /mnt_ram0
# mount /dev/ram0 ~/rpmbuild
これで、カーネル再ビルドの前準備完了です。

実際、やってみたところ、わたしの環境では、ビルド時間が2分程度(全体の処理時間の11%)短縮できました。

ちなみに、最初は zram を使おうとしたのですが、再ビルドしたいのは 32bit 版カーネルであり、ビルド環境も 32bit 版であるため、メモリ限界(ちゃんと調べてないですが、おそらく lowmem の限界)で、うまく行きませんでした。ramdisk のほうは、highmem を使えるようで、問題ありませんでした。

16G メモリって、なかなか使いこなせてない(余りがち)ですが、ちょっとばかり有効活用できたような気もしました。

2014-02-15追記
最初に zram を使おうと思った流れで、ramdisk + ext4 を使いましたが、他に tmpfs もあるので、そちらも試してみました。
CentOS 6 では、デフォルトで /dev/shm に tmpfs がマウントされますが、サイズが少し不足するので拡張します。あと、カーネルビルドの性質上、多数のファイルを作成するので、inode 数も拡張します。
# mount -o remount,size=10240M,nr_inodes=300000 /dev/shm
                        ※64bit版をビルドする場合は足りないようです。12800M なら成功 (2019-03-20追記)
inode 数も拡張しないと、ビルドが失敗します。このとき、容量不足と勘違いしそうなメッセージ(No space left on device)が出て、紛らわしいです。

あとは、次のように bind マウントして利用しました。
# mkdir /dev/shm/rpmbuild
# cd ~/rpmbuild
# tar cf - . | (cd /dev/shm/rpmbuild ; tar xf -)
# mount --bind /dev/shm/rpmbuild ~/rpmbuild
ビルド時間は、ramdisk を利用した場合と変わりませんでしたし、tmpfs を使うほうが手軽かと思います。マシンを再起動しなくても、メモリ解放できますし。
ただ、メモリの空き状況によっては、tmpfs の中身がスワップアウトされることがあるので、その点だけ頭の片隅に置いておいたほうがよいかと。

2014-08-30追記
その後、月1回程度(CentOS 6 の errata カーネルが出る度)のペースで、tmpfs を使う方法を使ってカーネルリビルド(ちなみに HZ=250 設定と nonpae 化)していますが、ビルド時間短縮と SSD 負担軽減に役立っていると思います。先日、うっかり、tmpfs を使わずにビルドしたところ、SSD に負荷がかかり、SSD を見失った(高熱のため?)こともあり、tmpfs 役立つなあ と思いました。

2019-03-20追記
32bit版カスタムカーネルを作るのに tmpfs を使い続けてきて問題ありませんでしたが、64bit版を作る用事があり、やってみたところ tmpfs のサイズ指定 10240M では空き容量不足となり、 12800M 指定したらビルドできました。一般的に64bitオブジェクト(.o や実行バイナリ)は、32bitオブジェクトよりサイズが大きいから、っということなのでしょう。自明と思うので、具体的にサイズ確認まではしませんでしたが。
もしも、この書き込みを見て参考にする人はご注意ください。

0 件のコメント:

コメントを投稿

人気ブログランキングへ にほんブログ村 IT技術ブログへ