RaspberryPi2 の SD カードを aufs と fsprotect で保護する

RaspberryPi2 で SD カードのヘタリ防止と意図しない電源断対策のため、aufs と fsprotect を導入します。
Web 上にいくつか記事がありますが、少し内容が古かったりするので、まとめ直してみました。
OS は raspbian を使っています。

## ビルド環境の構築

RaspberryPi 上でビルドすると時間がかかるので、性能の良いマシン上の Ubuntu でクロスビルドすることにします。

```
# apt-get update
# apt-get upgrade  # お好みで
# apt-get install lib32ncurses5 lib32z1 libncurses5-dev gcc-arm-linux-gnueabi make libncurses5-dev git vim bc
```

## aufs パッチをあてる
aufs はパッチとして提供されていますので、これをあてていきます。

まずソースコードとパッチ、ビルドツールを入手します。

```
% git clone https://github.com/raspberrypi/tools.git
% git clone https://github.com/raspberrypi/linux.git
% cd linux
% git checkout rpi-4.1.y  # バージョンはお好みで。手元の raspbian のバージョンに近いものが安心
% git clone https://github.com/sfjro/aufs4-standalone.git
% cd aufs4-standalone/
% git checkout aufs4.1.13+  # kernel のバージョンに合わせる
```

パッチをあてましょう。aufs4-standalone/README に手順があります。ファイルが変わっているかもしれないのでこちらを確認するのが確実です。

```
% patch -p1 < aufs4-standalone/aufs4-kbuild.patch
% patch -p1 < aufs4-standalone/aufs4-base.patch
% patch -p1 < aufs4-standalone/aufs4-mmap.patch

% cd aufs4-standalone
% cp -rp fs/ ..
% cp -rp Documentation/ ..
% cp -irp include/uapi/linux/aufs_type.h ../include/uapi/linux/
% cd ..
```

## ビルド

パッチがあったらビルドしていきます。
まず kernel config を作りましょう。
動作中の raspbian の /proc/config.gz を取ってくるとしている記事もありますが、バージョンが違う場合はそのままでは使えないので、特にカスタマイズしていなければ defconfig を使うのが楽です。

```
% RPICC=/root/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-

% ARCH=arm CROSS_COMPILE=$RPICC make bcm2709_defconfig
% ARCH=arm CROSS_COMPILE=$RPICC make menuconfig
>>> File systems > Miscellaneous filesystems > Aufs を 有効 (*) にする
```

uname 等で判別しやすいように kernel の version を変更しておきます。

```
% vim Makefile
>>> EXTRAVERSION = -aufs (名前はお好みで) 
```

ビルドします。

```
% ARCH=arm CROSS_COMPILE=$RPICC make zImage modules dtbs
```

## Raspberry Pi に適用する

ビルドしたバイナリを tar で固め、Raspberry Pi にコピーします。

```
% ARCH=arm CROSS_COMPILE=$RPICC make INSTALL_MOD_PATH=./tmp modules_install

% mkdir tmp/overlays
% ./scripts/mkknlimg arch/arm/boot/zImage tmp/kernel7.img
% cp arch/arm/boot/dts/*.dtb tmp/
% cp arch/arm/boot/dts/overlays/*.dtb* tmp/overlays/

% tar zcvf tmp.tar.gz ./tmp
% scp tmp.tar.gz pi@IP_ADDRESS:~
```

以降は RaspberryPi 上で作業します。

```
rpi% tar zxf tmp.tar.gz
rpi% cd tmp

rpi# cp kernel7.img /boot/kernel7.img
rpi# cp -r lib /
rpi# chown -R root:root /lib/modules
rpi# cp *dtb /boot
rpi# cp -r overlays/ /boot

rpi# reboot
```

## aufs の有効化

ここまでで上手くいっていれば、以下のようになるはずです

```
rpi% uname -r
4.1.18-aufs-v7+
```

aufs は initramfs を使うようなので、これを作ります

```
rpi# update-initramfs -c -k `uname -r`
rpi# vim /boot/config.txt
>> 「initramfs initrd.img-4.1.18-aufs-v7+」 を追記
```

initramfs の行は `=` ではなく、スベースがデリミタなことに注意。

## fsprotect の有効化

```
rpi# apt-get install fsprotect

rpi# vim /boot/cmdline.txt
>>> dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=ye
s rootwait fsprotect
>>> (最後の "fsprotect" を追記)

rpi# reboot
```

## 確認

再起動後、以下のように / が none でマウントされていれば OK。
試しに `touch /hoge; reboot` とかやってみると、ファイルが消えているはずです。

```
rpi% df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev               10240       0     10240   0% /dev
tmpfs             189596    4628    184968   3% /run
/dev/mmcblk0p2   7512304 3865976   3286380  55% /fsprotect/system
none              524288    2012    522276   1% /fsprotect/tmp
none              524288    2012    522276   1% /
tmpfs             473988       0    473988   0% /dev/shm
tmpfs               5120       4      5116   1% /run/lock
tmpfs             473988       0    473988   0% /sys/fs/cgroup
/dev/mmcblk0p1     61384   31160     30224  51% /boot
tmpfs              94800       0     94800   0% /run/user/1000
```


## 参考にしたドキュメント
- http://qiita.com/haisaihiroki/items/251d9340dc12c5c03102
- http://d.hatena.ne.jp/ayokoyama/20140605/p1
- http://nokute.hatenablog.com/entry/2015/07/08/235005
- http://karaage.hatenadiary.jp/entry/2015/10/07/073000