PINE64にunionfs-fuseでRead-Onlyな環境を作る

Raspberry Piと同じように[PINE64](https://www.pine64.com/)はSDカードを起動及び保存用のストレージとして利用します。
家庭内サーバーとして利用する場合にはSDカードの寿命が気になります。
今回はSDカードを延命させるため、Raspberry Pi等で行われているunionfs-fuseを用いたRead-Only化を実施してみました。

# 事前準備
+ [公式Wiki](http://wiki.pine64.org/)を参考にDebianまたはUbuntuを導入

以下の作業はUbuntu環境で確認しています。

# unionfs-fuseをインストール
```lang:
# apt-get install unionfs-fuse
```

# /etc/fstabを編集
更新前

```lang:/etc/fstab
# <file system>	<dir>	<type>	<options>							<dump>	<pass>
/dev/mmcblk0p1	/boot	vfat	defaults							0		2
/dev/mmcblk0p2	/		ext4	defaults,noatime					0		1
```
更新後

```lang:/etc/fstab
# <file system>	<dir>	<type>	<options>							<dump>	<pass>
/dev/mmcblk0p1	/boot	vfat	ro,defaults							0		2
/dev/mmcblk0p2	/		ext4	ro,defaults,noatime					0		1
mount_unionfs	/etc	fuse	defaults							0		0
mount_unionfs	/var	fuse	defaults							0		0
tmpfs			/tmp	tmpfs	defaults,size=64m,noatime,mode=1777	0		0
```

# マウント用スクリプト作成
```lang:/usr/local/bin/mount_unionfs
#!/bin/sh
DIR=$1
ROOT_MOUNT=$(awk '$2=="/" {print substr($4,1,2)}' < /etc/fstab)
if [ $ROOT_MOUNT = "rw" ]
then
  /bin/mount --bind ${DIR}_org ${DIR}
else
  /bin/mount -t tmpfs ramdisk ${DIR}_rw
  /usr/bin/unionfs-fuse -o cow,allow_other,suid,dev,nonempty ${DIR}_rw=RW:${DIR}_org=RO ${DIR}
fi
```

実行権限設定

```lang:  
# chmod +x /usr/local/bin/mount_unionfs
```
# ディレクトリ準備
```lang:
# cp -a /etc /etc_org
# cp -a /var /var_org
# mkdir /etc_rw
# mkdir /var_rw
```

# 書き込み/更新用スクリプト作成
```lang:/usr/local/bin/rwmount
mount -o remount,rw /
mount -o remount,rw /boot
fusermount -u -z /var
fusermount -u -z /etc
```
```lang:/usr/local/bin/cporg
cp -a /etc/* /etc_org
cp -a /var/* /var_org
sync
```
実行権限設定

```lang:  
# chmod +x /usr/local/bin/rwmount
# chmod +x /usr/local/bin/cporg
```
# 再起動
```lang:  
# reboot
```
# Read-Onlyの確認
```lang:  
# mount
/dev/mmcblk0p2 on / type ext4 (ro,noatime,stripe=1024,data=ordered)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,size=984988k,nr_inodes=246247,mode=755)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
mqueue on /dev/mqueue type mqueue (rw,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,noatime,size=65536k)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
configfs on /sys/kernel/config type configfs (rw,relatime)
ramdisk on /etc_rw type tmpfs (rw,relatime)
ramdisk on /var_rw type tmpfs (rw,relatime)
unionfs-fuse on /var type fuse.unionfs-fuse (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
unionfs-fuse on /etc type fuse.unionfs-fuse (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
/dev/mmcblk0p1 on /boot type vfat (ro,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
tmpfs on /run/user/108 type tmpfs (rw,nosuid,nodev,relatime,size=203708k,mode=700,uid=108,gid=114)
gvfsd-fuse on /run/user/108/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=108,group_id=114)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=203708k,mode=700,uid=1000,gid=1000)
```

# 書き込みモードへの変更し、更新を実施する手順
```lang:  
# rwmount
# -- 書き込み作業 --
# cporg
# reboot
```

# 最後に
買ったは良いが使い方がイメージ出来ていなかったPINE64を家庭内サーバーとして使用するためにRead-Only環境を準備してみました。
まだ理解できていない部分があり、余計なことをしているかもしれませんので、こうしたら良いよ！等のツッコミをお待ちしております。
Raspberry Piも同様の手順でRead-Only環境を準備可能ですので参考にどうぞ。

# 参考
+ [BeagleBone (Green) で Read-only な環境を作る](http://qiita.com/pinebright/items/aa98c214f4e80bfdd4c2)
+ [pi3g Blog - Make Raspbian System Read-Only](http://blog.pi3g.com/2014/04/make-raspbian-system-read-only/)
+ [Raspberry Pi でRAMディスクを使う](http://www.pc-links.com/blog/raspberrypi/ramdisk/)