はじめに
現在、Raspberry Piをベースとした、新しい監視カメラシステムを開発中ですが、そこで利用している様々な技術的なトピックをメモ代わりにまとめていきたいと思います。
今回は、Raspberry PiのSDカードをRAMディスク化する方法です。
RAMディスク化
Raspberry Piを使用して、IoTデバイスを開発し、実運用していく為には、突然の電源のOFFなどでも、OSが壊れないようにする必要があります。
また、ディスクとして使用しているSDカードには寿命があり、書き込み回数が多くなると、その寿命が短くなってしまいます。
こうした状況に対応するために、ディスクとして使用しているSDカードをRAMディスク化します。
RAMディスク化とは、構築したSDカード上のディスクイメージを書き込み禁止にして、その上に物理メモリ上に構築した書き込み可能なRAMディスク領域を重ねて、論理的なディスク領域を作成します。
これにより、ディスク領域への書き込みは実メモリ(RAM)上で行われることになり、SDカードへの書き込みが行われなくなり、SDカードの寿命が延びることになります。
さらに、シャットダウンを行わずに、直接電源ケーブルを抜いたとしても、次回起動時には、RAMディスク化する前の正常な状態で起動させることができるようになります。
OverlayFS(Overlay Filesystem)
このRAMディスク化には、OverlayFS(Overlay Filesystem)を使用します。
OverlayFS(オーバーレイファイルシステム)は、Linuxカーネルに統合されているユニオンファイルシステム(Union Filesystem)の一種で、複数のファイルシステムを重ね合わせて1つのように見せる技術です。
Dockerなどで、イメージ領域とコンテナ領域を分けるコア技術としても使用されています。
この機能を使用して、構築したSDカード上のディスクイメージを書き込み禁止にして、その上にtmpfsなどを使用して物理メモリ上に構築した書き込み可能なRAMディスク領域を重ねることで、ディスクのRAM化を実現します。
このRAMディスク化を有効にすると、以後のディスクへの書き込みは実メモリ上に構築されたRAMディスク領域に行われることになります。
対して、実ディスク領域のSDカードは読み取り専用モードになり、読み込み処理しか行われなくなることでSDカードの寿命が延びることになります。(少なくとも書き込み・消去によるセルの劣化は起こりません)
また、突然電源がOFFになったとしても、影響を受けるのは実メモリ上に構築されたRAMディスク領域のみですので、構築した実ディスク領域は影響を受けないため、次回電源ONの際には、問題なく起動できることになります。
ただし、RAMディスク化した後に行った変更は実メモリ上に反映されるため、電源OFFですべて消えてしまい、次回起動時には、RAMディスク化する前の状態に戻って起動されることになります。
そのため、OSのインストールや、必要なアプリのインストールを行い、環境を構築したのちにRAMディスク化する必要がありますし、変更を加える場合は、一度RAMディスク化を解除してから、変更を行う必要があります。
Raspberry PiでのRAMディスク化
ここでは、Raspberry Pi 5でRaspberry Pi OS(64bit)を使用した場合の設定方法を説明します。
Raspberry Pi OSでは、こうしたシステム設定変更の為に、raspi-configという便利なコマンドがあり、今回行うRAMディスク化も、このコマンドで行うことが可能です。
まずは、raspi-configを起動します。
sudo raspi-config
最初のメニュー画面で、「4 Performance Options」を選択します。
「P2 Overlay File System Enable/disable read-only file system」を選択します。
その後、「Would you like the overlay file system to be enabled?」と確認が表示されるので、「Yes」を選択します。
次の段階で、「Would you like the boot partition to be write-protected?」と聞かれます。ブートパーティションを書き込み禁止にするかどうかの設問ですが、ここでは「No」に設定しておきます。(後で変更を加えるので)
終了させると再起動されますので、起動後にディスクの状態がどうなっているかをdfコマンドで確認してみます。
$ df -h
Filesystem 1K-blocks Used Available Use% Mounted on
udev 1671064 0 1671064 0% /dev
tmpfs 388308 1200 387108 1% /run
/dev/mmcblk0p2 246017184 2451148 231058876 2% /media/root-ro
tmpfs-root 1941532 24712 1916820 2% /media/root-rw
overlayroot 1941532 24712 1916820 2% /
tmpfs 1941532 0 1941532 0% /dev/shm
tmpfs 5120 20 5100 1% /run/lock
/dev/mmcblk0p1 522230 65584 456646 13% /boot/firmware
tmpfs 388304 0 388304 0% /run/user/1000
SDカード上に作成された物理パーティションは下記の2つです。
- /dev/mmcblk0p1
- ブート用パーティション(FAT32)
- /boot/firmwareにマウントされる
- /dev/mmcblk0p2
- ルート用パーティション(ext4)
- /(root)にマウントされる
OverlayFSによってRAMディスク化されたのは、ルートの領域になりますので、dfの結果からルートの部分を見てみます。
/dev/mmcblk0p2 246017184 2451148 231058876 2% /media/root-ro
tmpfs-root 1941532 24712 1916820 2% /media/root-rw
overlayroot 1941532 24712 1916820 2% /
SDカード上の物理パーティションの/dev/mmcblk0p2は、/media/root-roにマウントされています。名前からわかるように、ここはro(Read-Only)でマウントされています。
また、tmpfsで実メモリ上に構築された領域が/media/root-rwにマウントされています。こちらはrw(Read-Write)です。
そしてOverlyFSによって、この2つを結合した論理ディスク領域に/(root)がマウントされている状態です。
ちなみに、tmpfsによって構築された領域の容量とOverlayFSによって構築された論理領域の容量が同じことからも分かるように、RAMディスク化した際の領域は、搭載している物理メモリの領域に制限されます。
最後に
これでRaspberry PiのSDカードをRAMディスク化することができました。
ただ、実際に運用していくと、いくつか問題が出てきます。
実際に、私も開発中に以下の問題が出てきました。
- アプリケーションの設定ファイルなど、永続化したい情報の置き場所が欲しい
- Dockerが起動できなくなる
これらの対応方法については、後日記事にしようと思います。
ちなみに、こんな感じのものを開発中です。
このシステムで使用している技術の概要は以下のBookにまとめていますので、ご興味のある方は読んでみてください。
また、近日中にテスターの募集を行う予定ですので、お手伝いしていただける方はよろしくお願いします。
(後日、どこかで募集します。。。)