ミルク色の記録

やったこと、やってみたこと

raspi-configのAdvanced OptionsでOverlay FSを使ってみた

きっかけ

先日、メモリの設定を変えようとraspi-configを起動して、Advanced Optionsを開いたらメニューにOverlay FSが増えていることに気がついた。

f:id:ushiboy:20191215130640p:plain
Advanced Options

説明にEnable/Disable read-only file systemとあるので、これって/パーティションを読み込み専用にするやつじゃね?と思い、素のRaspbian OSイメージをSDカードに焼いて試してみた。

試したイメージはRaspbian Buster Lite 2019-09-26でAPTでパッケージを最新に上げたもの。

Overlay FS の有効化

Overlay FSを選択すると、有効にするか聞かれるので、Yesを選択する。

f:id:ushiboy:20191215131141p:plain

すると、initramfsの生成が行われ、完了メッセージが表示される。

f:id:ushiboy:20191215131318p:plain

次に/bootパーティションを書き込み保護するか聞かれる。Yesを選択した場合は/bootパーティションが読み込み専用になり、Noにした場合/bootパーティションはそのままとなる。

f:id:ushiboy:20191215131426p:plain

とりあえずNoを選択して実行すると、/bootの扱いについて表示される。

f:id:ushiboy:20191215131657p:plain

このあとraspi-configを終了すると再起動を促されるので、OSを再起動してログインし直す。

ログイン後、mount状態を見ると次のようになる。

$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,relatime)
udev on /dev type devtmpfs (rw,nosuid,relatime,size=465128k,nr_inodes=116282,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=94832k,mode=755)
overlay on / type overlay (rw,noatime,lowerdir=/lower,upperdir=/upper/data,workdir=/upper/work)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
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)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=29,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)
mqueue on /dev/mqueue type mqueue (rw,relatime)
sunrpc on /run/rpc_pipefs type rpc_pipefs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
configfs on /sys/kernel/config type configfs (rw,relatime)
/dev/mmcblk0p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=94828k,mode=700,uid=1000,gid=1000)

overlay on / type overlay (rw,noatime,lowerdir=/lower,upperdir=/upper/data,workdir=/upper/work)とあり、/パーティションがoverlayfsで保護されているのがわかる。

この時、/boot/cmdline.txtは次のようになっている。

boot=overlay console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

先頭にboot=overlayが追加されている。また、/boot/config.txtの末尾には次のようにinitramfs initrd.img-4.19.75-v7+-overlayが追加されている。

[all]
#dtoverlay=vc4-fkms-v3d
initramfs initrd.img-4.19.75-v7+-overlay

Overlay FS の無効化

raspi-configのAdvanced OptionsOverlay FSを選択し、disableにすればよい。再起動後にマウントの状態は次のように戻る。

$ mount
/dev/mmcblk0p2 on / type ext4 (rw,noatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=469544k,nr_inodes=117386,mode=755)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,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)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=33,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)
sunrpc on /run/rpc_pipefs type rpc_pipefs (rw,relatime)
mqueue on /dev/mqueue type mqueue (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
configfs on /sys/kernel/config type configfs (rw,relatime)
/dev/mmcblk0p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=94828k,mode=700,uid=1000,gid=1000)

/bootパーティションの書き込み保護

Overlay FSを有効化するときに/bootパーティションの書き込み保護も有効にすると、再起動後にマウント状態は次のようになる。

$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,relatime)
udev on /dev type devtmpfs (rw,nosuid,relatime,size=465128k,nr_inodes=116282,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=94832k,mode=755)
overlay on / type overlay (rw,noatime,lowerdir=/lower,upperdir=/upper/data,workdir=/upper/work)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
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)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
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/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
sunrpc on /run/rpc_pipefs type rpc_pipefs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=35,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)
mqueue on /dev/mqueue type mqueue (rw,relatime)
configfs on /sys/kernel/config type configfs (rw,relatime)
/dev/mmcblk0p1 on /boot type vfat (ro,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=94828k,mode=700,uid=1000,gid=1000)

/dev/mmcblk0p1 on /boot type vfat (ro,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)となっており、/bootパーティションが読み込み専用(ro)になっていることがわかる。

これは/etc/fstabの設定によって行っているようで、/etc/fstabを見ると次のようになっている。

$ cat /etc/fstab 
proc            /proc           proc    defaults          0       0
PARTUUID=6c586e13-01  /boot           vfat    defaults,ro          0       2
PARTUUID=6c586e13-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

PARTUUID=6c586e13-01 /boot vfat defaults,ro 0 2とあり、roが設定されていることがわかる。

ちなみに/bootの書き込み保護も有効にすると、Overlay FSの解除はraspi-configの1度の実行だけでは駄目で、2度行う必要がある。1度目の解除実行時に下のようなメッセージがでる。

f:id:ushiboy:20191215132927p:plain

想像だけど、一度目の解除実行では/bootのマウントを書き込み可で再マウントして、/boot/cmdline.txt/boot/config.txtを修正してOverlay FSを無効化するが、/etc/fstabOverlay FSの解除後でないと変更できないからとかじゃないかと思う。

気になること

initramfsのファイル名をinitrd.img-4.19.75-v7+-overlayという感じで-overlay付きで作っているけど、カーネルバージョンアップデート時の自動的なinitramfsの作り直しに対応できているのかな?というのはちょっと気になったりもする。

まとめ

Raspberry PIでなにも対策せずに動かしているとSDカード壊れるのは昔からの課題だったので、公式にOverlay FSで読み込み専用にできるようになったのは素直に嬉しい。

/は読み込み専用にしつつ特定のディレクトリは書き込み可にしておきたいということで、パーティションを分割する需要は今後も増えそう。