使用overlayfs打造一個只讀的不怕意外關機的樹莓派Raspberry Pi
樹莓派的本領就不多說了。但是在樹莓派的應用場合,關機的時候還是顯得尷尬,先不說執行 sudo halt 要麼需要ssh上去,要麼需要有鍵盤和顯示器,更不要說,有的場景可能連網路和顯示器都沒有,真正的 headless。 但是如果不執行sudo halt直接關電源,那麼有很大的概率會損壞SD卡上的檔案系統,甚至損壞SD卡。
overlayfs是linux系統下的一種影子檔案系統,它可以把真正的儲存檔案系統作為只讀掛載,而把所有檔案改動都存放在RAM中,關機或者重啟就失效,真正的保護了儲存檔案系統。 下面就說一下我在樹莓派中實施overlayfs的方法,其實很簡單。
我參考了這個帖子中介紹的方法:
https://www.raspberrypi.org/forums/viewtopic.php?t=173063#p1151405
1. 首先,禁用交換空間,畢竟樹莓派裡的交換空間也是佔用RAM(tempfs)的,所以如果使用了overlayfs後,交換空間就顯得沒有意義了。
執行如下3條命令:
sudo dphys-swapfile swapoff
sudo dphys-swapfile uninstall
sudo update-rc.d dphys-swapfile remove
2. 更新系統,保證系統為最新狀態
sudo apt-get update sudo apt-get upgrade
3. 儲存如下指令碼為 overlayRoot.sh
#!/bin/sh # Read-only Root-FS for Raspian using overlayfs # Version 1.0 # # Created 2017 by Pascal Suter @ DALCO AG, Switzerland # to work on Raspian as custom init script # (raspbian does not use an initramfs on boot) # # Modified 2017-Apr-21 by Tony McBeardsley # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. # # # Tested with Raspbian mini, 2017-01-11 # # This script will mount the root filesystem read-only and overlay it with a temporary tempfs # which is read-write mounted. This is done using the overlayFS which is part of the linux kernel # since version 3.18. # when this script is in use, all changes made to anywhere in the root filesystem mount will be lost # upon reboot of the system. The SD card will only be accessed as read-only drive, which significantly # helps to prolong its life and prevent filesystem coruption in environments where the system is usually # not shut down properly # # Install: # copy this script to /sbin/overlayRoot.sh and add "init=/sbin/overlayRoot.sh" to the cmdline.txt # file in the raspbian image's boot partition. # I strongly recommend to disable swapping before using this. it will work with swap but that just does # not make sens as the swap file will be stored in the tempfs which again resides in the ram. # run these commands on the booted raspberry pi BEFORE you set the init=/sbin/overlayRoot.sh boot option: # sudo dphys-swapfile swapoff # sudo dphys-swapfile uninstall # sudo update-rc.d dphys-swapfile remove # # To install software, run upgrades and do other changes to the raspberry setup, simply remove the init= # entry from the cmdline.txt file and reboot, make the changes, add the init= entry and reboot once more. fail(){ echo -e "$1" /bin/bash } # Load overlay module modprobe overlay if [ $? -ne 0 ]; then fail "ERROR: missing overlay kernel module" fi # Mount /proc mount -t proc proc /proc if [ $? -ne 0 ]; then fail "ERROR: could not mount proc" fi # Create a writable fs on /mnt to then create our mountpoints mount -t tmpfs inittemp /mnt if [ $? -ne 0 ]; then fail "ERROR: could not create a temporary filesystem to mount the base filesystems for overlayfs" fi # Mount a tmpfs under /mnt/rw mkdir /mnt/rw mount -t tmpfs root-rw /mnt/rw if [ $? -ne 0 ]; then fail "ERROR: could not create tempfs for upper filesystem" fi # Identify root fs device, PARTUUID, mount options and fs type #rootDev=`blkid -o list | awk '$3 == "/" {print $1}'` # Changed here(point to / ) in case the cmd above doesn't work # By ChenYang 20171122 rootDev=/dev/mmcblk0p2 rootPARTUUID=`awk '$2 == "/" {print $1}' /etc/fstab` rootMountOpt=`awk '$2 == "/" {print $4}' /etc/fstab` rootFsType=`awk '$2 == "/" {print $3}' /etc/fstab` # Mount original root filesystem readonly under /mnt/lower mkdir /mnt/lower mount -t ${rootFsType} -o ${rootMountOpt},ro ${rootDev} /mnt/lower if [ $? -ne 0 ]; then fail "ERROR: could not ro-mount original root partition" fi # Mount the overlay filesystem mkdir /mnt/rw/upper mkdir /mnt/rw/work mkdir /mnt/newroot mount -t overlay -o lowerdir=/mnt/lower,upperdir=/mnt/rw/upper,workdir=/mnt/rw/work overlayfs-root /mnt/newroot if [ $? -ne 0 ]; then fail "ERROR: could not mount overlayFS" fi # Create mountpoints inside the new root filesystem-overlay mkdir /mnt/newroot/ro mkdir /mnt/newroot/rw # Remove root mount from fstab (this is already a non-permanent modification) grep -v "$rootPARTUUID" /mnt/lower/etc/fstab > /mnt/newroot/etc/fstab echo "#the original root mount has been removed by overlayRoot.sh" >> /mnt/newroot/etc/fstab echo "#this is only a temporary modification, the original fstab" >> /mnt/newroot/etc/fstab echo "#stored on the disk can be found in /ro/etc/fstab" >> /mnt/newroot/etc/fstab # Change to the new overlay root cd /mnt/newroot pivot_root . mnt exec chroot . sh -c "$(cat <<END # Move ro and rw mounts to the new root mount --move /mnt/mnt/lower/ /ro if [ $? -ne 0 ]; then echo "ERROR: could not move ro-root into newroot" /bin/bash fi mount --move /mnt/mnt/rw /rw if [ $? -ne 0 ]; then echo "ERROR: could not move tempfs rw mount into newroot" /bin/bash fi # Unmount unneeded mounts so we can unmout the old readonly root umount /mnt/mnt umount /mnt/proc umount /mnt/dev umount /mnt # Continue with regular init exec /sbin/init END )"
注意,我的指令碼和帖子裡面的有些不同,我把
rootDev=`blkid -o list | awk '$3 == "/" {print $1}'`
改成了
rootDev=/dev/mmcblk0p2
不改的話,我這裡overlayRoot.sh會執行失敗
(20180503更新)另外需要注意,如果在Windows下編輯overlayRoot.sh檔案,需要儲存為Unix文字文件格式,即行結束符為單個LF字元,而不是Windows風格的CR+LR兩個字元。否則你可能會看到如下錯誤:
---[ end Kernel panic - not syncing: Requested init /sbin/overlayRoot.sh failed (error -2).
4. 將指令碼拷貝到 /sbin/overlayRoot.sh
sudo cp overlayRoot.sh /sbin/overlayRoot.sh
sudo chmod a+x /sbin/overlayRoot.sh
5. 修改 cmdline.txt 檔案,在行尾加上 "init=/sbin/overlayRoot.sh",如下是我的 /boot/cmdline.txt 檔案的內容
[email protected]:~ $ cat /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=0e82c2e4-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait init=/sbin/overlayRoot.sh
6. 為了保證整個SD卡都是隻讀,將 /boot 分割槽也修改為只讀, 修改 fstab 檔案,把/boot 對應的行改為ro,我的/etc/fstab檔案內容如下
[email protected]:~ $ cat /etc/fstab
proc /proc proc defaults 0 0
PARTUUID=0e82c2e4-01 /boot vfat defaults,ro 0 2
PARTUUID=0e82c2e4-02 / ext4 defaults,noatime 0 1
7. 到這裡 sudo reboot 重啟,重啟後,檔案系統就處於影子系統的保護之下了,所有對於檔案系統的改動,在重啟後都將恢復原狀。 用mount命令可以確認overlayfs的正常工作。
root-rw on /rw type tmpfs (rw,relatime)
/dev/mmcblk0p2 on /ro type ext4 (ro,noatime,data=ordered)
overlayfs-root on / type overlay (rw,relatime,lowerdir=/mnt/lower,upperdir=/mnt/rw/upper,workdir=/mnt/rw/work)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,size=470160k,nr_inodes=117540,mode=755)
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/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/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/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=25,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
sunrpc on /run/rpc_pipefs type rpc_pipefs (rw,relatime)
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=94952k,mode=700,uid=1000,gid=1000)
原來的根檔案系統 /dev/mmcblk0p2 改為掛載在 /ro ,並且是隻讀;/boot 也掛載為只讀;而 / 的 type 變成了overlay。
好了,直接拔電試試看吧。事實上你可以反覆嘗試不正常關機,都不會有問題。
8. 以後如果想禁用overlayfs,可以修改 cmdline.txt 把 "init=/sbin/overlayRoot.sh" 刪掉,重啟即可。 當然修改前要先把 /boot remount 成可寫狀態。
更新系統等操作都需要先禁用overlayfs後再執行。
9. 如果臨時想修改原 /boot 以及根檔案系統的內容可以如下命令remount
要remount /boot為可寫
[email protected]:~ $ sudo mount -o remount,rw /boot
原來的根檔案系統在overlayfs下是掛載在 /ro 的,要remount的話
[email protected]:~ $ sudo mount -o remount,rw /ro
注意,remount檔案系統為可寫後,要重啟和關機需要使用sudo reboot或者sudo halt,不可以強行非正常關機,以免損壞檔案系統。
PS. 網上有人報告,如果在不接顯示器的情況下(即 headless),如上指令碼會執行失敗,但是我不接顯示器時並沒有遇到此問題 。
PS2. 網上有另外一個指令碼,連結如下
https://gist.githubusercontent.com/niun/34c945d70753fc9e2cc7/raw/3d60338cd8d8daf740692f426a5a1ec17839d613/root-ro
使用了 update-initramfs 的方式,我在官方系統中可以使用,但是在修改了核心的系統中,執行失敗。
【20180717後記】
--- 如果開啟了overlay以後,root分割槽的所有變動重啟後都會丟失,如果要儲存資料,可以縮小root分割槽後另外建立一個分割槽,使用FAT32,並mount為rw, sync, flush,用來儲存資料,另外最好使用f2fs分割槽格式,據說f2fs就是針對SD卡之類的儲存優化設計的。當然儲存資料的頻率不要太高,否則異常關機仍有可能會損壞SD卡,就失去使用overlay的意義了。 如果儲存資料的頻率很高,比如log,可以考慮儲存到外接U盤。
--- 也有人把 /boot 掛載為rw並臨時存放資料,我認為那是不可取的,因為 /boot 裡面存放的是啟動設定資訊以及核心等。
--- 網上也有人修改指令碼,(https://github.com/jacobalberty/root-ro),使得可以短路某GPIO後啟動系統就可寫,斷開後啟動就只讀。這是個好主意,有空研究一下。
【20180720更新】 為了方便識別當前系統是不是在overlayfs模式下,我在 .bashrc 的結尾加上如下幾行(當然必須在非overlayfs下修改,否則修改內容不會儲存),這樣如果是在overlayfs模式下,命令提示行的前面會加上“[OVL]”
find_overlay=`mount | grep overlay`
if [ ${#find_overlay} -gt 0 ]; then
PS1="[OVL] $PS1"
fi
歡迎交流
相關推薦
使用overlayfs打造一個只讀的不怕意外關機的樹莓派Raspberry Pi
樹莓派的本領就不多說了。但是在樹莓派的應用場合,關機的時候還是顯得尷尬,先不說執行 sudo halt 要麼需要ssh上去,要麼需要有鍵盤和顯示器,更不要說,有的場景可能連網路和顯示器都沒有,真正的 headless。 但是如果不執行sudo halt直接關電源,那麼有很大的
用樹莓派Raspberry Pi和Micro:bit做一個自拍器
clear microsoft 編程 告訴 pac 文本編程 裝配 -a 按鈕 在這個項目中,我們將使用Python來構建一個由Micro:bit觸發樹莓派Raspberry Pi和相機模塊的自拍器。這是開始使用硬件和簡單文本編程的好方法。 我們將學習: 如何設置Raspb
樹莓派raspberry pi配置
hang 開啟 鍵盤布局設置 jin -i icon ccf ron load (1)國際化語言 樹莓派初裝系統之後,首次啟動會出現“raspi-config”工具,如下圖:(若不是初次啟動,在命令模式下,請輸入 sudo raspi-
樹莓派 Raspberry Pi 啟用 root 登陸賬戶
樹莓派使用指南樹莓派 Raspberry Pi 啟用 root 登陸賬戶樹莓派系統使用的linux是debian系統,所以樹莓派啟用root和debian是相同的。debian裏root賬戶默認沒有密碼,但賬戶鎖定。當需要root權限時,由默認賬戶經由sudo執行,Raspberry pi 系統中的Raspb
樹莓派 Raspberry PI基礎
數字 -c san 波特率 fin block dddddd exp org 樹莓派 Raspberry PI基礎 官網網址:https://www.raspberrypi.org 下載地址:https://www.raspberrypi.org/downloads/ 官方
樹莓派 Raspberry PI之GPIO
document ble lock back ocs 輸入輸出 indent 1.5 res 樹莓派 Raspberry PI之GPIO 樹莓派各版本硬件原理圖:https://www.raspberrypi.org/documentation/hardware/raspb
樹莓派Raspberry Pi實戰之命令列下實現USB儲存裝置自動掛載
簡單介紹實現命令列下USB儲存裝置自動掛載的方法,Linux gnome/kde視窗環境下有移動儲存的管理程式,可以實現自動掛載移動儲存裝置,但是在命令列下 通常需要用mount命令手動掛載USB儲存裝置。 通過給linux下的裝置管理服務udev新增規則配置檔案,可以實現命令列下U
樹莓派(Raspberry Pi 3) - 系統燒錄及系統使用
樹莓派(Raspberry pi)是一塊整合度極高的ARM開發板,不僅包含了HDMI,RCA,CSI,HDMI,GPIO等埠,還支援藍芽以及無線通訊。由於Raspberry Pi幾乎是為Linux而生的一款卡片式微型電腦,所以R
樹莓派(Raspberry Pi 3)的系統燒錄及使用
今天我們將詳細一步一步地講解樹莓派3的燒錄和使用。樹莓派3是整合度很高的較為先進的ARM開發板,功能豐富,我們先來看一下它的結構以及40個GPIO口分別的用處,以免接線的時候搞錯。 APP開發、一元建站、貨運APP、冷練車APP、直播系統、小程式開發,找上海捌
樹莓派 raspberry pi 能象Arduino一樣外接感測器,控制器嗎
答案是YES樹莓派板子上有26只管腳,這些GPIO (general purpose I/O) 包括 SPI, I2C, 串列埠 UART, 3V3 and 5V 電源。國內論壇就有文章“Raspbmc 設定紅外線接收器”介紹如何為樹莓派安裝Raspbmc 作業系統,安裝配置紅
樹莓派Raspberry Pi的嵌入式QT平臺
在樹莓派上設計桌面應用一般情況會依賴於X11環境,如果是Windows平臺,就目前而言,我們也可以選擇Windows 10 IoT環境進行開發。UWP目前也支援在樹莓派2上進行部署。至於常見的Linux X11或者Wayland環境,相比之下比較冗餘,但是QT Emebe
Arduino 與樹莓派 Raspberry Pi 相比各自有什麼優缺點
Arduino 與樹莓派 Raspberry Pi 的差異談不上優缺點,而是他們是兩個完全不同的產品: 1. 產品定位上:Arduino的定位是微控制器,側重IO效能;Raspberry Pi的定位是電腦側重計算效能 2. 運算效能:Arduino以UNO為例是AV
適用於樹莓派Raspberry Pi的嵌入式QT平臺(一) -- 交叉編譯安裝Qt Embedded 5.5
在樹莓派上設計桌面應用一般情況會依賴於X11環境,如果是Windows平臺,就目前而言,我們也可以選擇Windows 10 IoT環境進行開發。UWP目前也支援在樹莓派2上進行部署。至於常見的Linux X11或者Wayland環境,相比之下比較冗餘,但是QT Emebedded直接利用Framebuffer
適用於樹莓派Raspberry Pi的嵌入式QT平臺(二) -- 在Windows下用Qt Creator開發編譯Raspberry Qt 5應用程式
接著上篇 "",我們已經成功在Windows上交叉編譯了Raspberry Pi的嵌入式Qt 5.5。那麼我們就可以開始開發基於Qt 5的應用程式。接下來,我們需要在Windows上搭建必要的Qt開發工具,首當其衝就是官方的Qt Creator,不僅提供了原生的C++編輯器,Qt介面設計器,而且還可以整合現有
適用於樹莓派Raspberry Pi的嵌入式QT平臺(三) -- 交叉編譯 Raspberry Pi 版GDB with Python
上篇講到“在Windows下用Qt Creator開發編譯Raspberry Qt 5應用程式”,由於目前Qt Creator所支援的GDB需要有Python支援,但是目前MinGW中的GDB都是無Python支援的,所以我們需要自己下載GDB程式碼並且編譯成針對Raspberry Pi支援Python的版本
在樹莓派(Raspberry Pi)上Qt5的本地構建
網上有很多關於在Raspberry Pi上構建Qt5的教程,但所有或大部分教程都是使用桌面機器交叉編譯Raspberry Pi的二進位制檔案。如果您交叉編譯,您將無法執行qmake並在Raspberry Pi本身上建立。本教程旨在向您展示如何在Raspberr
樹莓派(raspberry pi) 系統在SD卡上安裝Linux
剛剛拿到一隻Simon同學出借的樹莓派(raspberry pi) ,準備一張4GB的SD卡,準備跑一下Linux。在Windows 7上用 工具寫入img到SD卡上,報錯,失敗。好在俺有Linux vmware虛擬機器,在虛擬機器上搞,執行命令 sudo dd bs=1M
樹莓派(raspberry pi)學習6: 中文支援(中文顯示和中文輸入法)
樹莓派(raspberry pi)的原版是沒有中文支援的,需安裝 startx 後,用 Midori 瀏覽器 可以瀏覽網頁 瀏覽www.baidu.com,一堆亂碼 安裝中文顯示支援 第一步,先為終端進行相關更新:sudo apt-get update 第二步:為
樹莓派(Raspberry Pi 3)
VNC 是一款優秀的遠端控制軟體,在樹莓派、手機、電腦或者平板上安裝VNC,就可以通過這些裝置來遠端控制樹莓派了。 安裝VNC服務 安裝VNC需要使用命令列來完成,如果需要遠端操作安裝VNC,就必須通過SSH登入到命令列介面。在安裝軟體包之前,可以通過執行
在Ubuntu 16.04上為樹莓派(RaspBerry Pi 3)編譯Android 7(Nougat)
1. 環境準備和介紹 本文章的測試環境如下: 軟體環境:VMware Workstation Pro + Ubuntu 16.04 64 bit,虛擬機器的記憶體配置6GB,4個CPU 硬體環境:RaspBerry Pi3 + 16GB SD卡 測試