Raspberry Pi OS bookworm 使用overlayFS配置只读树莓派系统

媳妇单位管理比较严格,公司电脑上不能瞎安装软件,下班时工位还得断电,突然想到家里还有个派不上用场的树莓派3B+,扔到媳妇单位去帮她同步同步文件,都什么年代了,天天揣个U盘到处跑容易丢数据,也容易丢U盘。于是就有了这篇笔记。手把手地试图教会读者怎么进行配置,略新手向教程,但不排除在过程中使用了新手不太会用的解决办法,所以教不会是有可能滴。

扔到一个我控制不了电源的地方,那么首先就想到,需要把树莓派TF卡配置成只读模式,避免那个只会java的“伪IT从业者”连 sudo poweroff 都不会敲。本文是在树莓派上仅插一张TF卡的情况下,实现挂载单独交换分区/writable,挂载单独可读写分区/swap,/boot/firmware分区和root分区只读挂载。

新版本的 Raspberry OS 使用 raspi-config 工具内的overlayFS选项即可实现 root 分区只读,与旧版本的脚本实现有很大不同,这应该是从bullseye版本就已经变更了,但汉语页面上没找到有相关的帖子,在这里我把自己踩过的坑也顺便记录下来。本文侧重 overlayFS 的配置过程,其他问题会叙述比较潦草。

说个题外话,由于树莓派3B+吃灰太久还是什么原因,原来的电源欠压了,只能再买个新的。
在指令行检查树莓派电源是不是欠压:

vcgencmd get_throttled
: '回显内容可能是:
	throttled=0x50000
或
	throttled=0x0
'

 0x0就是正常,0x50000就是输入电压不足5V,也可能是电源供电电流小。
而 `vcgencmd measure_volts`指令,检测的是树莓派的核心电压,会回显为`volt=1.3000V`,上下有浮动,这个电压异常就会工作异常了,这个电压只能代表电源供电没有太大问题,不代表没有问题。顺便说下,本文所有在Linux上的操作都是在指令行界面,树莓派压根就没装图形界面。

回到overlayFS,先介绍概念,在 OverlayFS 中:
1. Underlay (或 lowerdir):是实际的、通常是只读的底层文件系统。这个部分有些文件可以修改,有些文件完全只读,即使使用工具修改以后,也只是看起来被修改了,实际文件内容其实没变化。重启以后会回到启用overlayFS时的状态。
2. Upperlay (或 upperdir):是用于存放所有修改、新增或删除的文件和目录的可写层。每次重启以后,这里存储的数据完全丢弃,这其实是在内存里,不在TF卡里。
3. Overlay (或 Merged View):是将 Underlay 和 Upperlay 合并后虚拟生成的那个完整的文件系统视图。

本文在描述中,有些时候手懒,把`/boot/firmware`分区简写成了`/boot`分区,旧版 Raspberry Pi OS 或者说旧版 Raspbian,就是树莓派定制的这个 Debian 的曾用名,那时使用的是 /boot 分区,两个分区名字其实指的都是`/boot/firmware`分区。

0、烧录 Raspberry Pi OS

当然可以使用第三方烧录工具比如rufus、DD之类,那样的话,没有显示器开机想连接无线网,进入SSH,还需要使用另一台Linux挂载TF卡,对里面的内容进行修改。

这里介绍使用 Windows 系统烧录TF卡的另一种办法,对2022年以后的树莓派系统写入用户名密码、wifi,开启SSH server的办法。

从树莓派官网上下载  Raspberry Pi Imager 应用程序,可以在图形界面配置要写入的系统,配置登录用户,配置SSH server是否启用,配置wifi名称密码,不需要写入完成以后,再另找 Linux 系统修改 TF 卡。但应注意选择需要写入的系统时,使用“use custom”,选择已下载的映像。如果选择在线镜像,会下载到 C:\Users\<username>\AppData\Local\Raspberry Pi\Imager\cache 路径下,以类似lastdownload.cache 的文件名存储,十分难以清理。
此安装方式操作直观,强烈建议初学者采取这种方式

不管是以哪种方式,所有准备工作完成后把TF卡插进树莓派硬件,加电开机,注意树莓派不是 x86 架构,没有开机自检,没有自检完成“嘀”声提示。

Raspberry Pi OS 在2022年以后发布的版本,系统不再生成旧版系统默认的“pi”用户。在首次启动时,系统会在本地控制台提示用户创建一个新的用户账户,但需要树莓派本地显示器,远程控制台未验证。
这里要注意旧版 Raspberry Pi OS 为 pi 用户配置了很多权限,其配置文件还保留在新版系统里,比如用户组,/etc/group 文件。这个文件造成比较尴尬的问题,如果写入镜像的时候创建的不是pi用户,那么新建用户就没有 sudo 权限,也就不能启用 root 用户,什么权限都没有,简单说就成了没法用的系统。要不然就一定要在写入系统时,手工把不是pi的那个用户加进文件,解决掉 sudo 问题,这依赖于另一个linux系统,还需要是能挂载 TF 卡的 x86 平台 Linux 之类,Windows 读写 ext4 分区需要第三方软件,这类软件一般都收费。

或者就干脆在烧录系统时,直接创建一个 pi 用户,避免无权限的死循环,等进入系统以后再新建其他用户名。

1、预留可读写区域

如果配置整个TF卡只读,则无法记录任何信息到下次重启,一种办法是挂载一个U盘或者移动硬盘作为可读写分区,另一种办法是在TF卡上增加第三个分区,也就是留出一块空间来存储文件,避免整卡只读,什么也存不下。但实现这个思路有一个操作顺序,开启 overlayFS 以后,表面上是可以存文件,实际上写操作全都在Upperlay,并不写入Underlay,重启以后会恢复成Underlay上存储的状态。修改root分区结束位置,最好在新装系统上操作,TF卡烧录系统完成后,使用其他 Linux 系统挂载TF卡,这样树莓派开机,不需要考虑文件碎片问题,没运行过的系统不会有文件碎片。如果计划好了设置TF卡只读,上来第一步可以先预留可读写分区,避免以后麻烦。如果需要设置成整卡只读,这个步骤跳过,但如果需要保留一部分区域可以写入,这个步骤是烧录完系统以后,第一件需要做的事,这件事是烧录完系统,TF卡插入树莓派,加电开机之前要做的事。TF卡尾部创建第三第四分区以后,不能使用 raspi-config 扩展到整个 TF 卡。

!注意 Raspberry Pi OS bookworm 的官方镜像还是使用mbr,不是gpt,只能建立4个主分区,那么在本例中:/boot、root、swap、/writable就已经把4个主分区全都用了,如果还需要更多可读写分区,那我没试验。我也不确定树莓派3B+能不能支持EFI引导方式。

以下动作是在另一台 Linux 电脑上操作,不是在树莓派上操作,烧录完系统不要直接插树莓派硬件开机,在树莓派上做这种动作基本上不会成功,调整分区结束位置之前,空间已经被占用可能写入文件不说,还会提示 `/dev/mmcblk0p2` 分区正在使用。我的另一台Linux是ubuntu 24.04 LTS。

: '这一段使用这种格式的注释,避免提示符和注释符混淆。'
: '切换root用户,避免当前操作的Linux和树莓派OS之间的权限问题,当然全程sudo也
没什么原则性错误,其实是好习惯,只是万一碰上奇奇怪怪的问题不见得顺利。'
$ su -

: '使用fdisk工具查看系统上都有什么。'
# fdisk -l
: '重点是找到TF卡
    Disk /dev/sdc:7.4 GiB,7948206080 字节,15523840 个扇区
    Disk model: Storage Device
    单元:扇区/1*512=512 字节
    扇区大小(逻辑/物理):512 字节 /512 字节
    I/0 大小(最小/最佳):512 字节/512 字节
    磁盘标签类型:dos
    磁盘标识符:0x442e675f

    设备       启动      起点        末尾        扇区  大小 Id 类型
    /dev/sdc1           8192     1056767    1048576  512M  c W95 FAT32(LBA)
    /dev/sdc2        1056768    11698175  106414083  5.1G 83 Linux
'

: '取消TF卡的挂载,调整分区只能在不挂载或者只读挂载情况下进行,有图形界面的Linux
可能会自动挂载它所识别到的东西。/dev/sdc*中的星号,代表这个物理驱动器下所有的分区。'
# umount /dev/sdc*

: '使用parted工具,fdisk工具也可以。'
# parted /dev/sdc

: '进入工具以后会显示以下内容,提示符变成“(parted)”:
    GNU Parted 3.6
    使用 /dev/sdc
    欢迎使用 CNU Parted!输入'help'来查看命令列表。
    (parted)
'
(parted) print free
: '显示当前磁盘使用情况:
    型号: Mass Storage Device(scsi)
    磁盘 /dev/sdc:7948MB
    扇区大小 (逻辑/物理): 512B/512B
    分区表: msdos
    磁盘标志: 

    Number  Start   End     Size    Type     File system  Flags
            32.3kB  4194kB  4162kB           Free Space
     1      4194kB  541MB   537MB   primary  fat32        lba
     2      541MB   5989MB  5448MB  primary  ext4
            5989MB  7948MB  1959MB           Free Space
'

: '照抄上面的结束位置,计算空间起始位置,创建新存储分区,本例256M空间不多,使用FAT32
格式。顺序自己掌握,如果存在今后root分区空间不足,需要舍弃某一个分区,空间并入root分区
的可能时,root分区只能兼并跟自己相邻的分区,当然也可以使用动态卷,并入一个物理上不连续
的空间,不过那个操作太麻烦了。不如parted删除相邻分区,修改分区结束位置来得痛快。'
(parted) mkpart primary fat32 7692MB 7948MB
: '照抄上面的结束位置,计算空间起始位置,创建新swap分区'
(parted) mkpart primary linux-swap 7180MB 7692MB

: '验证修改空间大小'
(parted) print free                                                       
: '
    型号: Mass Storage Device(scsi)
    磁盘 /dev/sdc:7948MB
    扇区大小 (逻辑/物理): 512B/512B
    分区表: msdos
    磁盘标志:

    编号        起始点    结束点    大小        类型        文件系统    标志
               32.3kB    4194k     4162kB                 可用空间
     1         4194kB    541MB     537MB     primary      fat32      lba
     2          541MB    5989MB    5448MB    primary      ext
               5989MB    7180MB    1191MB                 可用空间
     4         7180MB    7692MB    512MB     linux-swap(v1)          交换
     3         7692MB    7948MB    256MB     primary      fat32      lba
'

: '手工扩展 root 分区,调整树莓派系统的root分区大小,结束位置看空闲空间的结束位置,2指
第二分区,尾部位置7948 - 预留空间256 = 7692就是结束位置。linux-swap(v1)这个类型名称解
释见后。'
(parted) resizepart 2 7180MB
: '可能提示没有2K对齐影响性能,出现不出现是跟结束位置这个兆数所对应上的扇区数字有关系。
如果追求2K对齐,可以把结束位置减少1M填写,按本例就是7179MB,不追求就算了,直接分配进去。
    Warning: The resulting partition is not properly aligned for best performance: 14523438s %
    2048s != 0s
    Ignore/Cancel? i
'

: '退出后会提示可能需要修改/etc/fstab,但是TF卡不是在第三系统上使用,不用理会这个提示。'
(parted) quit
: '信息:你可能需要 /etc/fstab。'

: '一定记得修正ext4,如果不修正,ext4会认为是分区结束符位置错了,分区大小会出错,不加-f参
数,resize2fs会认为ext4现在能自圆其说,反馈 "nothing to do." 也不要使用-M参数,指令会要
求用户先使用 e2fsck -f /dev/sdc2 命令修复错误,但是执行e2fsck指令,会反馈新烧录的系统里
有一堆错误,初学者不建议进行修复,e2fsck指令会发现未体现在日志中的潜在问题,但这些非致命错
误不会导致不能开机。'
# sudo resize2fs -f /dev/sdc2

: '既然能进行resize2fs就说明它没挂载,可以不执行,但是如果忘了,就有可能是在挂载状态。'
# sudo umount /dev/sdc*

`linux-swap(v1)` 这个类型名称的解释:交换空间的确存在几个版本,`linux-swap(v1)` 是传统且广泛支持的Swap格式,适用于包括树莓派在内的绝大多数Linux系统。`linux-swap(v2)` 是较新的Swap格式,需内核Linux 5.0及以上支持,但实际应用较少,v2相比v1,支持如元数据校验或加密功能。使用v2,反而增加树莓派系统开销,一个开发板也很难去跑什么关键性企业应用,也不怕什么隐私数据泄露之类的问题,纯学习或者个人使用,v1完全够了。然后TF卡再插入树莓派加电开机,开机以后树莓派不会自动扩展 root 分区到 TF 卡尾部,使用 raspi-config 工具也不能扩展,会反馈 TF 卡尾部有其他分区,反馈不知道该怎么做。
如果忘记在其他 Linux 上修正 ext4 ,开机以后使用树莓派上执行 `resize2fs -f /dev/mmcblk0p2` 是不能操作 root 分区的。注意这时 TF 卡的设备标识已经不是第三系统上的sdc了,基本上是 `/dev/mmcblk0`,记得用`fdisk -l`和`fd -h`检查磁盘空间,如果前面拔卡之前,忘记resize2fs,那么`fdisk -l`和`fd -h`所显示的磁盘空间会有相当大的差距,原因是分区尾部结束符位置虽然变动了,但是ext4有自己的记录,这个记录会认为是分区尾部结束符位置错了,拒绝承认自己有剩下的可用空间。最好进行一次检查,如果忘了呢?

: '这一段使用这种格式的注释,避免提示符和注释符混淆。'
: '这两个指令显示分区空间数字相差不大,比方说一个6.4G,一个6.3G,就是成功了。如果相差1G
以上,那肯定是前面修正ext4失败了。但是不要看错行,不需管目前已占用空间'
$ sudo fdisk -l
: '屏显反馈略过'
$ sudo fd -h
: '屏显反馈略过,自行比较'

: '树莓派上执行parted工具,其实没什么好注释的。'
$ sudo parted /dev/mmcblk0
: '
    GNU Parted 3.5
    Using /dev/mmcblk0
    Welcome to GNU Parted! Type 'help' to view a list of commands.
'
(parted) print free
: '
    Model: SD SL08G (sd/mmc)
    Disk /dev/mmcblk0: 7948MB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags: 

    Number  Start   End     Size     Type     File system  Flags
            32.3kB  4194kB  4162kB            Free Space
     1      4194kB   541MB   537MB   primary  fat32        lba
     2      541MB   7180MB  6639MB   primary  ext4
            7180MB  7180MB   288kB            Free Space
     4      7180MB  7692MB   512MB   primary               swap
     3      7692MB  7948MB   256MB   primary               lba

这个显示剩余了288KB空间没分配出去,原因是指令要求它2K对齐,如果设置分区的时候手工让它2K对齐,
这里也会出现。只有分区结束兆数对应的扇区数不能2K对齐时,有机会要求机器忽略2K对齐。如果第二分
区的结束位置和第三分区的开始位置兆数正好可以2K对齐时,不出现提示,直接产生这种未分配空间,大
小也不会超过1M大小。
序列编号要注意,这里并不是按照从TF卡存储空间最低位到最高位的顺序排序,而是按照创建顺序的排序,
记好自己TF卡上的分区序列号,parted和fisk -l所呈现的序列号是对应的,只不过类型字符有所区别。
'
(parted) quit

到这里,已经具备了不会被overlay只读的第三、四分区,也已经有了基本占用100%的TF卡,还需要做一些工作。

: '这一段以及以后的操作不使用root,都是在普通用户身份操作。'
: '查看TF卡分区情况'
sudo fdisk -l

: '找到Linux swap所在行,也就是第四分区,格式化第四分区'
sudo mkswap /dev/mmcblk0p4

: '格式化第三分区'
sudo mkfs.vfat -F 32 /dev/mmcblk0p3

: '变更 swap ,bookworm 默认是使用 swap 文件而不是分区:'
: '挂载swap分区'
sudo swapon /dev/mmcblk0p4

: '看一下树莓派的swap状态'
sudo swapon --show
: '输出中会体现TYPE是文件还是分区
    NAME            TYPE         SIZE USED PRIO
    /var/swap       file         512M   0B   -2
    /dev/mmcblk0p4  partition    512M   0B   -3
'

: '照抄上面的交换文件,停用掉'
sudo swapoff /var/swap
: '或者使用交换文件的管理软件,关闭交换文件'
sudo dphys-swapfile swapoff

: '停用交换文件的系统服务,如果今后不使用交换文件,stop和disable两个指令不需要敲,直接反安装'
sudo systemctl stop dphys-swapfile
: '禁用交换文件的系统服务,要不下次重启以后,交换文件还会回来'
sudo systemctl disable dphys-swapfile
: '回显执行结果,删除了dphys-swapfile.service文件。
    Synchronizing state of dphys-swapfile.service with SysV service script with /lib/systemd/systemd-sysv-install.
    Executing: /lib/systemd/systemd-sysv-install disable dphys-swapfile
Removed "/etc/systemd/system/multi-user.target.wants/dphys-swapfile.service".
'

: '如果今后不会再使用交换文件,可以移除dphys-swapfile'
sudo dphys-swapfile uninstall
: '删除交换文件'
sudo rm /var/swap


: '检查swap分区UUID'
sudo blkid /dev/mmcblk0p4
: '输出中的PARTUUID复制下来,注意这里的UUID随着每次格式化变化,PARTUUID也同样会变化
    /dev/mmcblk0p4: UUID="7116727c-09d2-44f4-981a-bf77af8b6438" TYPE="swap" PARTUUID="cf16d979-04"
'

: '开机挂载swap分区,如果忘了,树莓派有可能在比较重的计算任务时程序崩溃。'
sudo nano /etc/fstab
: '推荐使用PARTUUID挂载,使用设备名/dev/mmcblk0p4这种不太推荐,万一分区一变化,就有可能没有交换分区了,不过树莓派很难有这么大变化,随意使用吧,文件内增加一行。

PARTUUID=cf16d979-04 none swap sw 0 0

这行内容使用空格或者tab分隔字符随意,格式没那么严格,愿意的话把注释改掉,文件默认内容说是使用交换文件而不是交换分区,现在已经切换成交换分区,原有注释会起到误导作用。
'

愿意的话重启一次,看看fstab文件开机挂载是不是成功,再进行下面的步骤,挂载可读写分区不要着急,后面做充分准备工作,再挂载不迟。

2、升级系统、系统加固

升级软件以及升级EEPROM,创建原有用户pi以外的其他用户,更改SSH端口,更改开机界面一类操作。总是有些服务器运维跟我说什么新版本不一定好用,新版本有新问题。但是我就说一条,新版本可以修复旧版本的BUG,但反之不成立,如果旧版本发布时就已经预见到了新版本将要出现的BUG,并且可以有效预防,那这个软件一定不是地球人写的。

况且你都在看我写的bookworm解决办法了,实在偏爱旧版本可以装个jessie,我印象里至少jessie是可以用脚本启动overlayFS的。

sudo apt-get update && sudo apt-get full-upgrade -y
sudo apt autoremove -y && sudo apt clean
# 树莓派4代以后有EEProm,3代和之前的没有,启动程序固化不可升级。
sudo rpi-eeprom-update -a

升级软件包运气不好会碰上升级动作超时,如果是在内核升级的时候超时,不一定会埋下什么雷。
修复任何依赖关系问题或未完全安装的软件包,不需要带包名称:

sudo apt --fix-broken install

重新配置可能相关的软件包:

sudo dpkg --configure <软件包名>

重新安装当前的内核和 `initramfs-tools`:

sudo apt install --reinstall linux-image-$(uname -r) initramfs-tools

变更SSH端口,安装配置防火墙之类,愿意现在做也可以,安装配置软件包完成以后再做也可以,我就不说了,想做什么,另搜教程。


3、挂载可读写分区

前面说过树莓派pi用户那个sudo权限问题,这里先建立新用户,两个目的:一个是/writable分区挂载需要,另一个是某些软件包的配置文件不一定在什么地方,不见得所有者是root。当然有人会说chown、chmod指令就能搞定,那需要先找到发生问题的文件才能执行,如果你刚是学习Linux的入门选手,别给自己找麻烦,要不就干脆沿用pi用户,要不在这里就开始使用另建立的用户,非要给自己挖坑的另算。

提示一点,如果使用vsftpd之类的软件管理树莓派,注意有些软件的登录uid数值不能小于1000。当然OpenSSH提供一个sftp,需要手动开启,具体就不细说了,想用什么自己搜吧。

# 建立新用户,然后要求输入密码什么的,具体搜索其他教程,建立不建立home文件夹之类指令有区别。
# 但是跟overlayFS没多大关系,这里不展开说。
sudo useradd <username>

# 跟本例相关的是uid、gid,不明白什么意思的话还是搜索其他教程。
id <username>

# 仿照pi用户的用户组,把新用户全加入进去,注意lpadmin组与远程桌面相关,如果没有GUI需要忽略,
# 没有桌面的 Raspberry Pi OS 根本就没有这个组。这些用户组配置在/etc/group文件中。
sudo usermod -a -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,render,netdev,gpio,i2c,spi,lpadmin <username>

测试新建用户可以登录或者说达到你想要配置的目的,禁用pi用户,启用root用户,将新建用户加入“/etc/sudoers.d/***_<username>-nopasswd”之类的操作都可以做,但是我不展开讲,有需要自己搜索其他教程。

: '创建第三分区,也就是开启只读以后,可读写分区的挂载点'
sudo mkdir /writable

: '修改权限,避免之后再建立新用户不可读写问题,当然也可以指定只有特定用户可读写,
umask自行搜索'
sudo chmod -R 777 /writable

: '查看第三分区UUID'
sudo blkid /dev/mmcblk0p3
: '输出中的PARTUUID复制下来,注意每次烧录的系统,UUID可能会一样,但PARTUUID都会
不一样。
/dev/mmcblk0p3: UUID="0F99-E9DC" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="cf16d979-03"
'

: '可以测试一下挂载新分区,df命令就可以看到挂载点。'
sudo mount PARTUUID=cf16d979-03 /writable 
df -h
: '回显输出看自己的输出,我的结果略过。'

: '但此时不要着急填入/etc/fstab文件中,立马重启开机挂载。要先查看树莓派新建用户的id,
一般是1001;如果使用pi用户,要把下面uid和gid换成1000,就可以重启挂载第三分区了。
`noatime`: 禁用更新文件的访问时间,以提高性能和减少写入。
`uid=1001,gid=1001`: 路径虽然已经设置777,但是对于FAT32来说,并没有文件所有者这类信
息,要以一个用户身份读写文件,还需要指定group和user,如果现在还没有新建用户,要先注释
不执行,补完作业再取消注释。或者沿用pi用户的话,这里uid和gid值改成1000。
`umask=0000`: 开放读写权限给所有用户.
`0`: 指示 `dump` 工具不要备份这个文件系统。
`2`: 指示在启动时,这个文件系统应该在根文件系统之后被 `fsck` 检查。
'
sudo nano /etc/fstab
: '
PARTUUID=cf16d979-03  /writable       vfat    defaults,noatime,uid=1001,gid=1001,umask=0000 0 2
'

: '重启以使新分区fstab挂载项生效。'
sudo reboot

然后安装必要软件包,比如:

sudo apt install lftp netcat-openbsd vim dnsutils

有些软件包,vsftpd、webdis、bird之类,如果你没有经验,测试配置过程中会产生很多log文件,配置完成再进行下一步。
看自己需求吧,具体软件配置不说了,跟overlayFS没有必然关系,有需要自行找教程,只说一个ftp不支持IPv6,我使用lftp客户端程序。


4、强制轮转日志

运行 logrotate 命令,并指定强制轮转所有配置的 log 文件:

sudo logrotate -f /etc/logrotate.conf

这一步单列出来,是因为如果在前面配置阶段产生了比较多的日志,那么这些日志会一直在Underlay上,一查看日志,就是当初开启overlay之前那堆东西还在。


5、禁用交换文件(其实是有点多余)

前面已经说了交换分区,多余归多余,稍微带一句,overlayFS会将所有写操作重定向到内存,交换文件根本就没有意义。启用overlayFS时,软件也会禁用交换空间,不管是文件还是分区。不过真正启用overlayFS以后,还是有办法设置一个交换文件出来的,就是配置过程过于酸爽,我就没测试到底,不如交换分区来得痛快。
如果一开始计划树莓派使用并设置了交换分区,此步骤跳过。这里是你考虑开启overlayFS前,到底要不要彻底反安装dphys-swapfile。
查看 swap 状态,bookworm 默认是使用 swap 文件而不是分区,如果没设置交换分区:

sudo swapon --show
: '输出中会体现TYPE是文件还是分区
    NAME      TYPE SIZE USED PRIO
    /var/swap file 512M   0B   -2
'

交换文件以以下指令禁用并删除:

# 关闭交换文件
sudo dphys-swapfile swapoff

# 移除dphys-swapfile,如果今后不会再使用交换文件
sudo dphys-swapfile uninstall
# 否则禁用交换文件服务,以备今后使用
sudo systemctl stop dphys-swapfile && sudo systemctl disable dphys-swapfile

# 删除交换文件
sudo rm /var/swap


6、启用overlayFS

在 raspi-config 工具界面中 Performance Options 项内选择 Overlay File System 之后的界面上确认启用或停用,这时会安装几个软件包,需要保证root分区还有空间安装,大约3M。还会在/boot分区重新生成内核。然后注意 Would you like the boot partition to be write-protected? 配置/boot分区是否只读,回车以后等待重启。
启用Overlay FS之前,三个主分区是读写状态:

$ sudo findmnt -l
TARGET                   SOURCE      FSTYPE   OPTIONS
/sys                     sysfs       sysfs    rw,nosuid,nodev,noexec,relatime
/proc                    proc        proc     rw,relatime
/dev                     udev        devtmpfs rw,nosuid,relatime,size=324088k,nr_inodes=810
/dev/pts                 devpts      devpts   rw,nosuid,noexec,relatime,gid=5,mode=620,ptmx
/run                     tmpfs       tmpfs    rw,nosuid,nodev,noexec,relatime,size=92844k,m
/                        /dev/mmcblk0p2
                                     ext4     rw,noatime
/sys/kernel/security     securityfs  security rw,nosuid,nodev,noexec,relatime
/dev/shm                 tmpfs       tmpfs    rw,nosuid,nodev
/run/lock                tmpfs       tmpfs    rw,nosuid,nodev,noexec,relatime,size=5120k
/sys/fs/cgroup           cgroup2     cgroup2  rw,nosuid,nodev,noexec,relatime,nsdelegate,me
/sys/fs/pstore           pstore      pstore   rw,nosuid,nodev,noexec,relatime
/sys/fs/bpf              bpf         bpf      rw,nosuid,nodev,noexec,relatime,mode=700
/proc/sys/fs/binfmt_misc systemd-1   autofs   rw,relatime,fd=29,pgrp=1,timeout=0,minproto=5
/dev/mqueue              mqueue      mqueue   rw,nosuid,nodev,noexec,relatime
/sys/kernel/debug        debugfs     debugfs  rw,nosuid,nodev,noexec,relatime
/sys/kernel/tracing      tracefs     tracefs  rw,nosuid,nodev,noexec,relatime
/sys/fs/fuse/connections fusectl     fusectl  rw,nosuid,nodev,noexec,relatime
/sys/kernel/config       configfs    configfs rw,nosuid,nodev,noexec,relatime
/run/credentials/systemd-sysusers.service
                         ramfs       ramfs    ro,nosuid,nodev,noexec,relatime,mode=700
/run/credentials/systemd-sysctl.service
                         ramfs       ramfs    ro,nosuid,nodev,noexec,relatime,mode=700
/run/credentials/systemd-tmpfiles-setup-dev.service
                         ramfs       ramfs    ro,nosuid,nodev,noexec,relatime,mode=700
/writable                /dev/mmcblk0p3
                                     vfat     rw,noatime,uid=1001,gid=1001,fmask=0022,dmask
/boot/firmware           /dev/mmcblk0p1
                                     vfat     rw,relatime,fmask=0022,dmask=0022,codepage=43
/run/credentials/systemd-tmpfiles-setup.service
                         ramfs       ramfs    ro,nosuid,nodev,noexec,relatime,mode=700
/proc/sys/fs/binfmt_misc binfmt_misc binfmt_m rw,nosuid,nodev,noexec,relatime
/run/rpc_pipefs          sunrpc      rpc_pipe rw,relatime
/run/user/1000           tmpfs       tmpfs    rw,nosuid,nodev,relatime,size=92840k,nr_inode
/run/user/1000/gvfs      gvfsd-fuse  fuse.gvf rw,nosuid,nodev,relatime,user_id=1000,group_i
/run/user/1000/doc       portal      fuse.por rw,nosuid,nodev,relatime,user_id=1000,group_i
/run/user/1001           tmpfs       tmpfs    rw,nosuid,nodev,relatime,size=92840k,nr_inode

启用overlay以后,前两个主分区变成ro状态:

$ sudo findmnt -l
TARGET                   SOURCE         FSTYPE   OPTIONS
/sys                     sysfs          sysfs    rw,nosuid,nodev,noexec,relatime
/proc                    proc           proc     rw,relatime
/dev                     udev           devtmpfs rw,nosuid,relatime,size=323852k,nr_inodes=
/dev/pts                 devpts         devpts   rw,nosuid,noexec,relatime,gid=5,mode=620,p
/run                     tmpfs          tmpfs    rw,nosuid,nodev,noexec,relatime,size=92844
# 第二分区在这里,ro状态,后面是一个假分区
/media/root-ro           /dev/mmcblk0p2 ext4     ro,relatime
/media/root-rw           tmpfs-root     tmpfs    rw,relatime
/                        overlayroot    overlay  rw,relatime,lowerdir=/media/root-ro,upperd
/sys/kernel/security     securityfs     security rw,nosuid,nodev,noexec,relatime
/dev/shm                 tmpfs          tmpfs    rw,nosuid,nodev
/run/lock                tmpfs          tmpfs    rw,nosuid,nodev,noexec,relatime,size=5120k
/sys/fs/cgroup           cgroup2        cgroup2  rw,nosuid,nodev,noexec,relatime,nsdelegate
/sys/fs/pstore           pstore         pstore   rw,nosuid,nodev,noexec,relatime
/sys/fs/bpf              bpf            bpf      rw,nosuid,nodev,noexec,relatime,mode=700
/proc/sys/fs/binfmt_misc systemd-1      autofs   rw,relatime,fd=29,pgrp=1,timeout=0,minprot
/dev/mqueue              mqueue         mqueue   rw,nosuid,nodev,noexec,relatime
/sys/kernel/debug        debugfs        debugfs  rw,nosuid,nodev,noexec,relatime
/sys/kernel/tracing      tracefs        tracefs  rw,nosuid,nodev,noexec,relatime
/sys/kernel/config       configfs       configfs rw,nosuid,nodev,noexec,relatime
/sys/fs/fuse/connections fusectl        fusectl  rw,nosuid,nodev,noexec,relatime
/run/credentials/systemd-sysusers.service
                         ramfs          ramfs    ro,nosuid,nodev,noexec,relatime,mode=700
/run/credentials/systemd-sysctl.service
                         ramfs          ramfs    ro,nosuid,nodev,noexec,relatime,mode=700
/run/credentials/systemd-tmpfiles-setup-dev.service
                         ramfs          ramfs    ro,nosuid,nodev,noexec,relatime,mode=700
# 第三分区在这里,还是rw状态
/writable                /dev/mmcblk0p3 vfat     rw,noatime,uid=1001,gid=1001,fmask=0022,dm
# 第一分区在这里,ro状态
/boot/firmware           /dev/mmcblk0p1 vfat     ro,relatime,fmask=0022,dmask=0022,codepage
/run/credentials/systemd-tmpfiles-setup.service
                         ramfs          ramfs    ro,nosuid,nodev,noexec,relatime,mode=700
/proc/sys/fs/binfmt_misc binfmt_misc    binfmt_m rw,nosuid,nodev,noexec,relatime
/run/rpc_pipefs          sunrpc         rpc_pipe rw,relatime
/run/user/1000           tmpfs          tmpfs    rw,nosuid,nodev,relatime,size=92840k,nr_in
/run/user/1000/gvfs      gvfsd-fuse     fuse.gvf rw,nosuid,nodev,relatime,user_id=1000,grou
/run/user/1000/doc       portal         fuse.por rw,nosuid,nodev,relatime,user_id=1000,grou
/run/user/1001           tmpfs          tmpfs    rw,nosuid,nodev,relatime,size=92840k,nr_in

不设置任何交换空间的话,开启overlay以后,系统运行速度明显下降,这时树莓派完全依赖内存写入。

然后会发现启用overlay的时候,把交换分区在/etc/fstab文件中注释掉了。

#overlayroot:swap=0#PARTUUID=cf16d979-04 none swap sw 0 0

需要把交换分区的配置,从/boot/firmware移动到root里去。解决办法中的动作,是否可以在启用overlayFS之前做,我并没有进行测试。

解决办法:

 ① 以可读写方式挂载/boot/firmware/,这之后操作的不是overlay,是overlayFS修改过内容的/boot/firmwares,既是也不是underlay。后面解释。

sudo mount -o remount,rw /boot/firmware/

编辑`/boot/firmware/cmdline.txt`文件,内容只有一行,所有参数以空格间隔,内容可能是这样:

overlayroot=tmpfs console=serial0,115200 console=tty1 root=PARTUUID=cf16d979-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=CN

找到`overlayroot=tmpfs`,这个参数是是overlayFS加进来的,删除掉这个,注意跟后面其他参数有空格间隔,可以一并删掉。
这个参数在每次使用raspi-config工具设置/boot/firmware分区只读的时候,都会加进来,所以每次配置完成,重启以后,都会引起树莓派没有swap分区的问题

如果在这里把参数改成`tmpfs:swap=1,recurse=0`,也可以实现挂载swap分区,只是不能单纯靠`raspi-config`工具恢复root分区的可读写状态,需要先把cmdline.txt文件内容恢复成没修改之前,或者删除掉overlayroot参数,再配合`raspi-config`工具恢复root的可读写。
这是在修改underlay的文件,但不要以执行`sudo overlayroot-chroot`的方式修改underlay的文件。如果以`overlayroot-chroot`的方式修改,会提示`/boot/firmware/cmdline.txt`文件不存在,这是root分区的underlay并不包含`/boot/firmware/cmdline.txt`。而`/boot/firmware`,是overlayFS以有别于root镜像的另一个镜像的方式,实现了只读。所以前面说既是也不是underlay。
然后执行` sudo mount -o remount,ro /boot/firmware `把boot以只读方式重新挂载(可选),如果等下修改全部完成就重启树莓派,挂载回只读方式可以跳过。

 ② 使用`overlayroot-chroot`工具,进入root分区的underlay,在进入这个环境时,会有一个提示,并且命令提示符会有变化:

raspberry:~ $ sudo overlayroot-chroot
: '    在进入这个环境时,会有一个提示,并且命令提示符会有变化:
INFO: Chrooting into [/media/root-ro]
root@raspberry:/#
这里具备root权限,但sudo指令失效了
'

根据`/etc/overlayroot.conf`内容说明,创建或编辑`/etc/overlayroot.local.conf`,系统会读取这个文件,不需要在其他文件里,手工引用这个文件。直接在`/etc/overlayroot.conf`设置也会生效,但会被升级覆盖掉配置。

nano /etc/overlayroot.local.conf
: '在文件内加入内容:

overlayroot="tmpfs:swap=1,recurse=0"

'

`tmpfs`指 "Upperlay",它负责实现一个看起来可读写的root分区,其实每次重启都会丢弃这部分修改或新增的内容;
`swap=1`指启用交换空间,默认值是0,禁用交换空间;
`recurse=0`是指仅在root分区上启用overlayFS,不设置其他挂载点只读,默认值是1,含义是将全部分区设置为只读。但是我没搞明白,为什么`/boot/firmware/cmdline.txt`文件中没携带这个参数的情况下,存在一个root分区以外的可读写分区,这种处理方法会让第三分区逃过一劫。
因为/boot/firmware的overlay是另行创建,在fstab可以看到第1个分区的挂载项,跟这个参数没关系。
如果希望配置“overlayroot_cfgdisk”可以自己尝试,默认值是`overlayroot_cfgdisk="disabled"`。这个参数在`/etc/overlayroot.conf`文件内,删掉以后还是在`/etc/overlayroot.local.conf`文件中另行配置。它的作用是把配置文件丢到一个可读写的地方,避免每次重启以后丢掉了Upperlay的数据,导致配置都不能留存。
然后就可以`reboot`重启验证,或者使用`exit`指令退出`overlayroot`,继续使用树莓派。


7、停用overlay

还是使用`raspi-config`工具, Performance Options 项内选择 Overlay File System 选项内选 `<No>`取消,注意提示,/bootf分区不可在启用overlay的时候取消只读,提示/boot分区不可操作,选择`<finish>`的时候提示是否重启。
此时/boot/firmware仍处于只读状态,重启以后再次执行raspi-config,选择 overlay FS 注意不要选启用,先选择root分区不启用,然后再选择/boot不启用,退出选择`<finish>`的时候提示是否重启。
两次重启都完成,就可以恢复/boot/firmware的可读写状态了。

文中有一部分markdown标记,又忘记用markdown编辑器了,懒得删除不影响阅读。

本文是查阅相关配置说明,以及结合AI搜索结果,来源全部是英语页面,如果文中出现对他人文章的侵权,请联系我删除。

This blog is to consult the relevant configuration instructions, as well as combined with AI search results, the source is all English web sites, if there is infringement of other people's articles in this blog, please contact me to delete.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值