もし、手の届かない離島に電源ブチ切りラズパイを置くなら、私ならばoverlayもfuseも使いたくない。以下、/sbin/initでの対応を示すが、未完成である。シンボリックリンクを嫌う実装が何かあるようで、いずれ調査して解決する予定である。一方で、chrootは使わず、Stateless CentOS7でのやり方(=tmpfsでbind)で実装できている。下記でも起動はするし、SSHログインもできるが、現時点ではoverlay方式またはtmpfs-bind方式でのご利用を推奨する。
前提:準備①〜③が完了していること。fuseとoverlayは不要。
~# mkdir /tmpfsroot
~# touch /.tmpfsroot
~# dosfslabel /dev/mmcblk0p1 boot
~# e2label /dev/mmcblk0p2 rootfs
/tmpfsrootにユーザランド(rootfs)を構築し、chrootする。リードオンリーで良い領域はシンボリックリンクで対応する。アプリによっては、シンボリックリンクで対応したために正しく機能しないケースがある。/etc/fstab_tmpfsrootは、/tmpfsroot/etc/fstabにコピーされる。
/etc/fstab_tmpfsroot(rw→ro):
# tmpfsroot用の/etc/fstab proc /proc proc defaults 0 0 # 軟弱なFAT領域はroマウント LABEL=boot /boot vfat ro,defaults 0 2 # rootfsを/MicroSDへroマウント LABEL=rootfs /MicroSD ext4 ro,defaults,noatime 0 1 # LABEL=logを刻印したext4メディアにログ保存するならコメントアウト #LABEL=log /var/log ext4 defaults,noatime 0 0
~# rm /sbin/init
Under Construction!
基本動作確認はしているが改善余地があり、後日フォロー予定。
/sbin/init:
#!/bin/sh ## /home, /root, /etcは、総メモリ容量の1/2を超える場合は、事前に調整すること。 ## 特に/homeは要注意。確認方法: cd /; du --max-depth 1 -h ## $DISKは定義しない(rootfsは/boot/cmdline.txtのパラメータでマウントされている)。 ramdisksize=500M # DISK=/tmpfsroot/MicroSD if [ -d /tmpfsroot ] && [ -e /.tmpfsroot ]; then ## /tmpfsrootに主要構成を構築 mount -t tmpfs -o size=${ramdisksize} tmpfs /tmpfsroot ## フォルダ作成 echo "Creating directories..." for d in boot dev media mnt opt proc run sys tmp usr var MicroSD; do mkdir /tmpfsroot/${d} done ## 微調整 chmod 1777 /tmpfsroot/tmp echo > /tmpfsroot/fastboot ## rwエリアをコピー ## *** メモリの1/2容量を超えないこと! *** echo -n "Copying files, directories..." #for d in etc root home srv; do for d in etc root srv; do echo -n ".. " cp -a ${DISK}/${d} /tmpfsroot done # /etc/fstabを調整 [ -e /tmpfsroot/etc/fstab_tmpfsroot ] && mv -f /tmpfsroot/etc/fstab_tmpfsroot /tmpfsroot/etc/fstab ## roエリアをシンボリックリンク for d in bin sbin lib; do ln -s /MicroSD/${d} /tmpfsroot/${d} done ## /usrを処置(/usr/localだけtmpfs) for d in bin games include lib man sbin share src; do ln -s /MicroSD/usr/${d} /tmpfsroot/usr/${d} done cp -a ${DISK}/usr/local /tmpfsroot/usr ## /varの処置:ディスクの/varの構成のみをコピー cd ${DISK}/var for d in `ls -l | awk '$1 ~ /d/ {print $9 }' `; do DIR_NAME=`basename ${d}` if [ ${DIR_NAME} = "lib" ]; then #ln -s /MicroSD/var/lib /tmpfsroot/var/lib mkdir /tmpfsroot/var/lib else find ${DIR_NAME} -type d | cpio -pdm /tmpfsroot/var/ find ${DIR_NAME} -type l | cpio -pdm /tmpfsroot/var/ fi done ## /var/libの処置 cd ${DISK}/var/lib for d in `ls -l | awk '$1 ~ /d/ {print $9 }' `; do DIR_NAME=`basename ${d}` if [ ${DIR_NAME} = "systemd" ] || [ ${DIR_NAME} = "nfs" ]; then # rwフォルダはtmpfsrootにコピー cp -a ${DISK}/var/lib/${DIR_NAME} /tmpfsroot/var/lib/${DIR_NAME} else # 他はSymbolic Linkで対応 ln -s /MicroSD/var/lib/${DIR_NAME} /tmpfsroot/var/lib/${DIR_NAME} fi done cd ## fstabに/var/logの定義があればマウント mount -T /tmpfsroot/etc/fstab /var/log ## switch_root mount -o bind /sys /tmpfsroot/sys mount -o bind /dev /tmpfsroot/dev/ mount -t proc proc /tmpfsroot/proc #mount -o bind / /tmpfsroot/MicroSD cd /tmpfsroot pivot_root . MicroSD exec chroot . /lib/systemd/systemd #exec switch_root /tmpfsroot /lib/systemd/systemd "$@" </tmpfsroot/dev/console >/tmpfsroot/dev/console #exec /usr/lib/klibc/bin/run-init /tmpfsroot /lib/systemd/systemd #exec /usr/lib/klibc/bin/run-init /tmpfsroot /lib/systemd/systemd "$@" </tmpfsroot/dev/console >/tmpfsroot/dev/console #exec chroot /tmpfsroot /lib/systemd/systemd else ## 元のsystemdを起動する exec /lib/systemd/systemd fi echo "Something went badly wrong in the /sbin/init."
~# chmod +x /sbin/init