1.パッケージの追加
FUSE マウントのために fuse を追加します。
※ /sbin/mount.fuse を overlay マウント時に使用。
sudo apt-get install -y fuse
システム SD カード(ルート)を読み取り専用で運用しつつ、書き込みが必要なディレクトリは overlayfs と tmpfs で吸収するミニマルな構成。
Systemd による /etc/fstab の処理を利用するため、Raspberry Pi 以外でも使えます。
※ このサイトのサーバーおよびルーターは、ここで紹介する方法でシャットダウンフリー化した Raspberry Pi 2 Model B 上で動作しています。
overlayfs で tmpfs 上に展開。/etc/fstab から上記 overlayfs をマウント。/(ルート)のマウントオプションが ro でない場合は 通常起動(書き込み可能)。前提:swap の無効化、/fsprotect の作成済み。/proc/filesystems に overlay が無い場合は modprobe overlay が必要です。
Raspberry Pi 専用ではなく、他の Linux でも同様の考え方で利用可能です。
FUSE マウントのために fuse を追加します。
※ /sbin/mount.fuse を overlay マウント時に使用。
sudo apt-get install -y fuse
/usr/local/bin/mount_overlay の配置fstab での FUSE マウントで使用するスクリプトを以下の内容で配置します。
#!/bin/sh
DIR="$1"
ROOT_MOUNT=$( awk '$2=="/" { print substr($4,1,2) }' /proc/mounts )
if [ "$ROOT_MOUNT" = "ro" ]; then
if [ -e "${DIR}" ]; then
# tmpfs を /fsprotect にマウント(注1)
/bin/mount -t tmpfs -o size=320m tmpfs ${DIR}
for d in usr lib etc home root var
do
/bin/mkdir ${DIR}/${d}
/bin/mkdir ${DIR}/${d}_rw
OPTS="-o lowerdir=/${d},upperdir=${DIR}/${d},workdir=${DIR}/${d}_rw"
/bin/mount -t overlay ${OPTS} overlay /${d}
done
fi
fi
# /var/log を独立して tmpfs に配置したい場合はここでマウント(注2)
/usr/local/bin/make_log_files
exit 0
注1)tmpfs の容量
容量を指定しない場合、合計 RAM の 半分 が上限となる挙動です。サーバープログラムに影響する場合があったため明示容量(例:320m)を指定しています。※挙動は環境により異なる可能性があります。
注2)ログの tmpfs 化
/var/log を独立して tmpfs にマウントし、必要なディレクトリ/ファイルを作成します(下記 make_log_files 参照)。
/usr/local/bin/make_log_files以下の様なスクリプトを配置し、mount_overlay から呼び出します。
通常起動時でも /var/log を tmpfs にすることで、SDカードにゴミが溜まることを防ぎます。
#!/bin/sh
/bin/mount -t tmpfs tmpfs /var/log
/bin/mkdir -p /var/log/apache2
/bin/chown root.adm /var/log/apache2
/bin/mkdir -p /var/log/samba
/bin/chown root.adm /var/log/samba
/bin/mkdir -p /var/log/sysstat
#/bin/mkdir -p /var/log/apt
#/bin/mkdir -p /var/log/private
#/bin/touch /var/log/lastlog
#/bin/chown root.utmp /var/log/lastlog
/etc/fstab/tmp は予め tmpfs をマウント。mount_overlay を呼び出し、選択ディレクトリを /fsprotect に展開。proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat ro,defaults 0 2
/dev/mmcblk0p2 / ext4 ro,defaults,noatime 0 1
mount_overlay /fsprotect fuse nofail,defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
df 結果(例)ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
/dev/root 7460628 1456788 5667940 21% /
devtmpfs 469544 0 469544 0% /dev
tmpfs 474152 0 474152 0% /dev/shm
tmpfs 474152 35964 438188 8% /run
tmpfs 5120 0 5120 0% /run/lock
tmpfs 474152 0 474152 0% /sys/fs/cgroup
tmpfs 474152 0 474152 0% /tmp
tmpfs 327680 7992 319688 3% /fsprotect
overlay 327680 7992 319688 3% /usr
overlay 327680 7992 319688 3% /lib
overlay 327680 7992 319688 3% /etc
overlay 327680 7992 319688 3% /home
overlay 327680 7992 319688 3% /root
overlay 327680 7992 319688 3% /var
tmpfs 474152 3000 471152 1% /var/log
/dev/mmcblk0p1 258096 39973 218123 16% /boot
tmpfs 94828 0 94828 0% /run/user/1000
プロテクト(読み取り専用)で運用しつつ、次回ブートで通常モードに戻したい/その逆を切り替えたいときに便利です。
パス:/usr/local/bin/noprotect
#!/bin/sh
sudo mount -o rw,remount /
sudo umount -l /etc
sudo sed -i 's/ro,defaults/rw,defaults/g' /etc/fstab
cat /etc/fstab
パス:/usr/local/bin/protect
#!/bin/sh
sudo sed -i 's/rw,defaults/ro,defaults/g' /etc/fstab
cat /etc/fstab
tmpfs は RAM を消費します。メモリの空き容量とプロセスの動作要件を考慮してサイズを決めてください。noprotect で通常モードに戻し、ログ(必要なら一時的に /var/log をディスク配置)を確認。