ラズベリーパイをおいしく料理してみる(7)-SDカードをReadOnly化する

前回までで、RAMディスク上で動作する状態にすることが出来ました。
今回は、さらにSDカードを書き込み不可でも動作するように、つまり、完全にRAM上で動作するように設定を変更したいと思います。

追記)この後に記載したやり方ではどうやら ”pi3以降では動作しない” 様ですのでご注意を!

なぜ、「SDカードを書き込み不可(=Readonly化)しようと思ったのか」についてですが、それは、「シャットダウンコマンドを実行することなく、安全に電源をOFF出来るようにしたいから」です。
ラズベリーパイの存在意義からも、今後、組み込み向けのプラットフォームとして使う事を考えた場合、「外部からログインしてシャットダウンコマンドを投入してもらう事が前提」というのはナンセンスな気がします。

「使う人」の立場では「PCではない機械」ですから、電源ON/OFFで問題なく使えてあたりまえなほうがいいのは自明の理でしょう。

でも、このままでは「いきなり電源OFF」で運用した場合には書き込み途中のファイル(=破損ファイル)が出来てしまうという可能性があり、「次回の起動時にどうなるか(正常に動作するか)は運任せ。」という状態かな….と。

これではあまりにも無責任なので、突然の停電時への対策も踏まえ、「電源OFFで終了されたとしても問題ないようにしたい」というのは当然の要望ではないか…となるわけです。

 

さてさてどうしたものか…と、数日考えてみたところで思いつきました。

ちょうど、前回まででRAMディスク上で動作するようになっているのですか ら、この状態からさらに一歩進めて、たとえば、起動時にRAMディスク上に全てを展開してそこで動作させるとかで、実際のメディア(SDカード)への書き出しは完全をブロックしてしまい、かつ、その状態でもシステムが動作してくれるのであれば、たとえ電源断で破損ファイルが出来たとしても、次回起動時にはきれいさっぱり忘れられて元に戻るのだから破損ファイルが出来ることでのトラブルは絶対発生しないはずです。

ついで、SDカードへの書き込み回数制限についても気にせずに済むようになるので一石二鳥。(頭の中では)

きっと、Linux系OSなのだから、設定で何とかなるんじゃないかな…と(勝手に)思って調べてみたところ…うん。何とかなりそう。さすがLinux君。

 

念のため手順についていろいろ調べた結果をまとめたら、早速トライしてみましょう。

参考にしたのはおもにこのサイトです。大変お世話になりました。

(念のため書きますが、これから実施する設定では、CUIでの運用しか考慮していないので、GUI環境が動作するかについては未確認なのでその点はご了承ください。)

っと、前置きはココまで。実際に設定変更していきましょう!

 


1.SDカードをReadOnly化する方法について

SDカード自体をReadOnly(書き込み不可)にして、かつ、正常動作させる方法については、おおむね

・aufs(AnotherUnionFS)を組み込んだカーネル再構築し、その後、fsprotectパッケージを適用(インストール)する
・unionfs-fuseパッケージを適用(インストール)する

の2つが、情報も多く、実績もある様です。

調べた範囲では、1つ目の方法では、カーネルの再構築に「とてつもなく時間がかかる」ようです。(8時間くらいかかると書いてあるところもあるようなので)
これではちょっと試してみる…というわけにもいかないので、2個目のほうを先に試してみたのですが、結果的にも良好だったことから、自分は2つ目の方法でいこうと思います。

 

2.パッケージの導入(unionfs-fuseパッケージの導入)

以降の手順で unionfs-fuseパッケージを導入できました。 参考にしたのは こちら のWebサイトです。感謝。

まずは、以下のコマンドでパッケージを導入して適用します。

$ sudo apt-get install unionfs-fuse

 

3.スクリプトのコピー

今回適用したパッケージでは、コマンドにてReadOnlyモードの設定と解除できるということなのですが、その際に使用するスクリプトをカスタマイズする為にコピーします。

$ sudo cp /usr/share/doc/unionfs-fuse/examples/S01a-unionfs-fuse-live-cd.sh /etc/init.d/a-unionfs-fuse-live-cd

$ sudo cp /usr/share/doc/unionfs-fuse/examples/rc.local.omit-pid.sh /usr/local/sbin/a-unionfs-fuse-omit-pid.sh

無事コピーできたら次へ。

 

3.スクリプトの編集

次はスクリプト(a-unionfs-fuse-live-cd)自体を編集します。

対象設定ファイル : /etc/init.d/a-unionfs-fuse-live-cd

 

(1)”BEGIN INIT INFO”記述の追加

先頭のほう(”#!/bin/sh”のうしろ)に ”BEGIN INIT INFO”記述を追加します。

$ sudo vi /etc/init.d/a-unionfs-fuse-live-cd

#!/bin/sh

### BEGIN INIT INFO                                 <- 追加
# Provides: a-unionfs-fuse-live-cd <- 追加
# Required-Start: mountall-bootclean <- 追加
# Required-Stop: <- 追加
# Default-Start: S <- 追加
# Default-Stop: <- 追加
# X-Start-Before: procps udev-mtab urandom <- 追加
# Short-Description: UnionFS mode <- 追加
# Descrition: Shutdown process will not be required <- 追加
### END INIT INFO <- 追加

# Copyright: Bernd Schubert <bernd.schubert@fastmail.fm>

(以下略)

 

(2)”UBIN=…” 以降への追記

以下のように、”UBIN=…” 以降に設定記述を追記する。

対象設定ファイル : /etc/init.d/a-unionfs-fuse-live-cd

$ sudo vi /etc/init.d/a-unionfs-fuse-live-cd

 :
(中略)

UBIN=/usr/bin/unionfs-fuse

cd /boot <- 追加
file=noprotect <- 追加
if [ -e ${file} ]; then <- 追加
<TAB>echo “${file} exists” <- 追加
<TAB>exit 0 <- 追加
fi <- 追加

mount -o remount,ro /dev/mmcblk0p1 /boot <- 追加

mount -t proc proc /proc
mount -t tmpfs tmpfs /tmp

 :
(以下略)

(3))末尾の “pivot_root . oldroot”以降への追記

以下のように、末尾の “pivot_root . oldroot”以降へ追記する。

対象設定ファイル : /etc/init.d/a-unionfs-fuse-live-cd

$ sudo vi /etc/init.d/a-unionfs-fuse-live-cd

(前略)

pivot_root . oldroot
mount -o remount,ro /dev/root /oldroot <- 追加
for d in dev run run/lock sys run/shm dev/pts boot <- 追加
do <- 追
mount –bind /oldroot/$d /$d <- 追加
done <- 追加

init q

 

(4)末尾の”init q” 以降への追記

以下のように、末尾の “init q”以降へ追記する。

対象設定ファイル : /etc/init.d/a-unionfs-fuse-live-cd

$ sudo vi /etc/init.d/a-unionfs-fuse-live-cd

 :
(前略)
init q /usr/local/sbin/a-unionfs-fuse-omit-pid.sh <- 追加    exit 0 <- 追加

4.initスクリプトの有効化

以下の手順でスクリプトを有効化します。

$ sudo update-rc.d a-unionfs-fuse-live-cd defaults

 

5.モード切替スクリプトの設置

以下の手順でモード切替スクリプトを作製します。(先頭のvi起動行を除く内容のファイルを作成すること)

(1)noprotect スクリプト作製

以下の手順で、noprotect(readonly化解除)スクリプトを作成する。

$ sudo vi /usr/local/bin/noprotect    

#!/bin/sh

mount -o rw,remount /boot
cd /boot
if [ -e “protect” ]; then
<TAB>rm /boot/protect
fi

if [ -e “noprotect” ]; then
<TAB>echo “noprotect mode”
else
<TAB>touch /boot/noprotect
<TAB>echo “noprotect mode”
fi

mount -o ro,remount /boot

(2)protect スクリプト作製

以下の手順で、protect(readonly化)スクリプトを作成する。

$ sudo vi /usr/local/bin/protect   

#!/bin/sh

mount -o rw,remount /boot
cd /boot
if [ -e “noprotect” ]; then
<TAB>rm /boot/noprotect
fi

if [ -e “protect” ]; then
<TAB>echo “protect mode”
else
<TAB>touch /boot/protect
<TAB>echo “protect mode”
fi

mount -o ro,remount /boot

(3)chmod実行

$ sudo chmod a+x /usr/local/bin/noprotect
$ sudo chmod a+x /usr/local/bin/protect
以上で設定作業は終了です。

6.使用方法

以下のコマンドラインにて、モード変更を行うことができるようになっているはずです。

(1)通常(ReadWrite)モードに切り替える場合

$ sudo noprotect

(2)ReadOnlyモードに切り替える

$ sudo protect

全ての設定がうまく行っていれば、Readonlyモードで新規作成したテキストファイルやログファイルが、「電源ON/OFF後の再起動後には消えている」もしくは「元の内容に戻っていること」が確認できるはずです。

確認できたら今回の改造は無事終了です。
お疲れ様でした。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です