news 2026/9/9 11:12:56

工控单板Linux存储规划与OverlayFS恢复出厂实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
工控单板Linux存储规划与OverlayFS恢复出厂实战

在工控行业里摸爬滚打这几年,接触最多的就是各种单板跑 Linux 的设备:工业 HMI、边缘采集网关、运动控制板,还有一堆叫不上名字的专用终端。这类设备和开发板最大的区别在于,它是要 7x24 小时在现场跑的,而且维护人员的水平参差不齐,现场环境更是恶劣——突然断电、灰尘、震动、高温都是家常便饭。所以这里跑 Linux 不能照搬服务器那一套,也不能照着树莓派的做法来,存储配置、系统升级、故障恢复这套东西,必须从设计之初就严丝合缝地规划好。

这篇主要讲三个核心问题:存储怎么分区才扛得住工控环境、系统怎么升级才安全可回滚、以及如何用 OverlayFS 实现一个真正好用的“恢复出厂”功能。这套组合拳我在多个项目里验证过,从瑞芯微到全志再到几款国产 x86 板子都试过,逻辑是通用的,具体参数我会尽量给全。

1. 工控单板 Linux 的整体设计与存储思路

1.1 工控单板到底特殊在哪里

工控单板和我们平时玩的树莓派、香橙派看着像,实际上设计逻辑完全不一样。开发板强调折腾,工控板强调稳定。客户现场装上去的设备,少则三年多则五年八年不关机,系统崩溃一次可能就是产线停线、数据丢失,代价非常大。

所以在做这类系统时,第一原则就是:默认你已经遇到了最坏的情况。比如客户可能会在系统正在写日志的时候直接断电,可能会拿着 U 盘拷数据把系统文件误删,可能会反复升级失败然后怪你产品不行。我们要做的不是祈祷这些事不发生,而是让系统在遭遇这些事之后还能自己恢复,或者用一个简单的操作就能恢复。

另一个工控场景的特殊之处是网络环境。很多工厂的内网是隔离的,设备根本访问不了外网。这意味着系统更新不能依赖在线软件源,必须走离线升级包。也正因如此,我们的存储规划里通常会为系统备份、升级包缓存预留一部分空间。

1.2 存储介质选型:eMMC 是绝对主流

工控单板的存储介质就那么几类,我把这几年的选型经验整理出来:

存储介质优点缺点工控场景建议
eMMC内置坏块管理、抗震动、寿命较好、价格适中容量相对固定、磨损仍存在首选,系统盘和数据盘都合适
SD/TF 卡容量大、更换方便容易被弹出、接触不良、寿命参差不齐千万别当作系统盘,最多做扩展存储
SATA/NVMe SSD容量大、速度快成本高、体积大、功耗高数据量大的设备可选,但要注意掉电保护
SPI NOR Flash寿命长、启动快、可靠性极高容量太小(通常几 MB 到几十 MB)只放 bootloader 和硬件参数
NAND Flash成本低、容量适中需要软件做坏块管理、有 OOB 区问题老平台还在用,新设计不如直接用 eMMC

从可靠性角度来说,eMMC 赢在封装一体化和内置 FTL(闪存转换层)。它里面有独立的控制器管理逻辑块到物理块的映射、磨损均衡、坏块替换,这些对上层应用是透明的。你写数据时不用关心底层擦写次数,只要关注自己软件的写入量是否合理。

我踩过的坑是 SD 卡做系统盘。某项目为了省成本用了工业级 SD 卡,结果客户现场设备震动大,SD 卡偶尔接触不良,系统直接 I/O 错误崩溃,而且恢复起来很麻烦。后来换 eMMC 方案,再没出过这个问题。

1.3 存储可靠性是恢复出厂的基石

很多人在做“恢复出厂”功能时,脑子里想到的是备份一个系统镜像,出问题再用镜像恢复。这个思路没错,但如果在存储规划阶段没做好,后面全是麻烦。

最基本的逻辑是:恢复出厂要恢复到一个“干净”的状态,那么这个干净状态就必须是物理隔离的、不被日常运行污染的。如果你把根文件系统和用户数据混在一个可写分区里,所谓恢复出厂就只能靠完整重刷整个分区——这样既慢又容易出问题,而且会把不该清的用户数据也抹掉。

所以在我的设计里,系统恢复的关键不是一个“救火”脚本,而是存储布局本身:系统区保持只读,可写数据集中在独立的 data 分区,运行时改动放到 OverlayFS 的上层。这样恢复出厂只需要清理 OverlayFS 的上层目录,秒级完成,而且用户数据可以保留。

2. 存储配置:分区规划与读写控制

2.1 典型工控单板分区规划

以一块 8GB eMMC、跑 Debian/Ubuntu 系统的工控单板为例,我习惯的分区方案是这样的:

分区大小文件系统挂载点读写属性说明
/dev/mmcblk0p1256MBext4/bootro内核、设备树、启动参数
/dev/mmcblk0p22GBext4/ (rootfs)ro(可通过 overlay 变可写)系统根文件系统
/dev/mmcblk0p3512MBext4/datarw应用配置、用户数据、日志缓存
/dev/mmcblk0p4512MBext4/overlayrwOverlayFS 的 upper 与 work 目录
/dev/mmcblk0p5512MBext4/mnt/backuprw出厂备份与升级包暂存区
剩余空间视 eMMC 容量ext4/home 或 /var/lib/dockerrw业务数据扩展区

这个分区表看着简单,但每个分区的读写属性都是刻意设计的。rootfs 默认只读挂载,所有系统文件不会被篡改;/data 保存需要持久化的用户数据,即使恢复出厂也能保留;/overlay 专门给 OverlayFS 当可写层,是“恢复出厂”功能的核心。

分区空间虽然不大,但对工控系统来说完全够用——系统目录几百 MB 就装完了。容量较大的 eMMC(16GB/32GB)可以在后面加一个大分区给业务数据,或者拆成多个逻辑分区给 Docker 用。

2.2 让根文件系统“真的只读”

把 rootfs 挂载为只读,这件事说易行难,很多人改了 /etc/fstab 后发现系统起不来或者一堆服务报错。原因在于,很多应用和系统服务默认就要往 / 里面写东西——/var/log 要写日志、/run 要写运行时文件、/tmp 要放临时文件、/etc 有时要改配置。

我用的方案是“rootfs 只读 + 关键路径 tmpfs 覆盖”。具体做法:

# /etc/fstab 关键部分 /dev/mmcblk0p2 / ext4 defaults,noatime,ro 0 1 tmpfs /tmp tmpfs defaults,size=64M,mode=1777 0 0 tmpfs /var/log tmpfs defaults,size=32M,mode=0755 0 0 tmpfs /var/tmp tmpfs defaults,size=16M,mode=1777 0 0

然后把 /var/log 里的系统日志通过 rsyslog 配置写到 /data/logs 或者一个独立的数据分区。systemd-journald 也要改 Storage 配置,避免它往 /var/log/journal 写东西。

另外,/etc 下面有些运行时配置需要可写,比如 DHCP 申请的 DNS、某些软件的许可证文件。我一个项目里的处理是,把所有“运行时要动态写入 /etc 的文件”统一重定向到 /data/etc 下,用完再通过 bind mount 回填:

mkdir -p /data/etc mount --bind /data/etc /etc/network

这样 rootfs 的只读不会被打破,而业务上需要的“可写”又都能满足。第一次调的时候挺折腾,但调好之后省心太多了。

2.3 日志轮转与写入量控制

工控设备最怕的不是系统文件被改,而是闪存被写坏。eMMC 虽然有磨损均衡,但也是有寿命的,一个严重的日志死循环可以在几个月内干掉一块好好的 eMMC。

处理思路就两条:少写、限速。少写是指日志和临时文件不要落在持久化介质上,用 tmpfs 顶住;限速是必须写持久化的日志时,用 logrotate 按大小和份数轮转,避免无限增长。我常用的配置:

/var/log/app/*.log { daily rotate 14 maxsize 64M compress copytruncate missingok }

还有一个容易忽略的地方:数据库和缓存。如果设备上有 SQLite 或者一些 KV 存储,一定要把库文件放到 /data 而不是 /root 或 /var/lib。SQLite 的 WAL 模式会频繁写盘,对闪存寿命很不友好,如果业务允许,尽量用内存库定时刷盘,或者调大 checkpoint 间隔。

2.4 为什么强调物理分区隔离

我这里说的“物理分区隔离”,是指 rootfs、overlay 上层、用户数据必须放在三个独立分区,而不是同一个分区下的三个目录。原因在于,OverlayFS 的 upper 目录如果和 lower 的底层分区是同一个文件系统,且该文件系统是可写的,那么一旦 rootfs 里有文件被修改,底层的 lower 就被污染了,最终 OverlayFS 的合并视图会非常混乱。

实际做过实验:rootfs 和 overlay 在同一分区时,如果系统服务不小心往 / 下写了一个和 lower 中同名文件,OverlayFS 的 copy-up 逻辑会被绕过,底层文件直接被改掉。等你想做恢复出厂、清空 upper 时,发现底层文件也变了,恢复到的是一个不干净的状态。

分区隔离之后这个问题彻底消失。upper 的改动永远只落在自己的分区里,和 lower 底层互不干扰。

3. 系统升级实操:离线升级与双分区切换

3.1 为什么工控升级必须走离线包

在线升级方便,但工控现场真的不适合。工业网络往往有严格的隔离策略,设备可能连网关都不通;即便能联网,也不能保证目标设备能稳定地从服务器拉取大量数据。

更实际的一点是:工控系统的升级行为需要可审计、可重复、可回滚。我接触过的客户,升级都要求有明确的版本号、升级记录、操作日志,这些在线升级很难给到。

所以我一般采用离线升级包 + 双分区切换的方案。升级包是一个带校验信息的 tar.gz,或者更规范一点,是一个自解压的升级脚本集合,里面包含完整的文件系统镜像、内核、设备树、升级脚本和校验文件。

3.2 双分区(A/B)升级的原理与优势

双分区升级的思路很直白:把 rootfs 分成 A、B 两份,当前运行的是 A,升级时往 B 里写;写完验证无误后,把启动标志切到 B;重启后 U-Boot 从 B 启动。如果 B 启动失败,U-Boot 检测到启动次数异常,自动回滚到 A。

这个方案的优点在于,升级过程对当前运行的系统完全无影响,即使升级写到一半断电,A 系统依然完好;即使 B 系统起来后有问题,也能自动回滚,不会变砖。对工控设备来说,这个“保底”太重要了。

具体到分区规划,就是在前面那个表的基础上再加一个 rootfs_b:

分区大小挂载点说明
/dev/mmcblk0p22GB/ (rootfs_a)当前运行的系统
/dev/mmcblk0p32GB/mnt/rootfs_b备用系统,升级目标

启动槽位的记录我放在 /boot 分区下一个文件里,U-Boot 通过读取这个文件决定从哪个 rootfs 加载。也可以把启动槽位存在 U-Boot 环境变量或 misc 分区,看你的引导链怎么设计方便。

3.3 离线升级脚本的设计与实现

升级脚本是整个升级流程的核心。我的升级包结构长这样:

upgrade_package/ ├── VERSION ├── checksums.md5 ├── rootfs_b.tar.gz ├── kernel.itb ├── u-boot.bin └── upgrade.sh

upgrade.sh 的关键逻辑如下(简化版):

#!/bin/bash set -euo pipefail INACTIVE_ROOT=/dev/mmcblk0p3 MNT_ROOT=/mnt/upgrade_root BOOT_DIR=/boot echo "=== Upgrade script start ===" # 1. 校验升级包完整性 md5sum -c checksums.md5 if [ $? -ne 0 ]; then echo "Checksum failed. Abort." exit 1 fi # 2. 检查备用分区是否可写,先卸载再挂载 umount $MNT_ROOT 2>/dev/null || true mount $INACTIVE_ROOT $MNT_ROOT # 3. 清空目标分区 rm -rf $MNT_ROOT/* # 4. 解压文件系统 tar xzf rootfs_b.tar.gz -C $MNT_ROOT sync # 5. 写入内核/设备树到 boot 分区 cp kernel.itb $BOOT_DIR/kernel_b.itb sync # 6. 写入启动槽位标记 echo "B" > $BOOT_DIR/active_slot sync # 7. 卸载并完成 umount $MNT_ROOT echo "=== Upgrade done, reboot to activate ==="

这里最关键的一步是第 6 步——只有系统文件全部写完后,才修改启动槽位标记。如果第 5 步或者第 6 步之前断电重启,系统还按旧槽位启动,升级失败但原系统不损坏;如果第 6 步之后断电,B 分区已经有了完整系统,启动后进入新版本,本身也没问题。这就是“先写数据、后写标志”的断电保护策略。

3.4 U-Boot 侧的双分区引导与自动回滚

U-Boot 侧的引导逻辑要配合启动槽位标记工作。以最简单的方案为例,U-Boot 环境变量 bootcmd 中做一次检测:

if test -f ${bootpart}/active_slot; then slot=$(cat ${bootpart}/active_slot) else slot=A fi if test "${slot}" = "B"; then setenv rootspec "root=/dev/mmcblk0p3 rootfstype=ext4" else setenv rootspec "root=/dev/mmcblk0p2 rootfstype=ext4" fi

自动回滚的原理也很简单:在 B 系统正常启动且健康检查通过后,在 Linux 里把一个“标记文件”写到 boot 分区,表示这次启动是成功启动;U-Boot 每次启动时检查,如果指定槽位没有成功标记且启动次数达到阈值,就回退到另一个槽位:

# 在系统启动脚本中执行 if [ -f /boot/active_slot ]; then slot=$(cat /boot/active_slot) touch /boot/${slot}_boot_ok # 清理失败计数 setenv -f bootcount 0 fi

U-Boot 中对应逻辑:

if test -f ${bootpart}/B_boot_ok; then setenv slot B elif test ${bootcount} -ge 2; then echo "Boot B failed, rollback to A" setenv slot A setenv bootcount 0 fi

这套机制我在实际项目中跑了一年多,客户那边也有过几次升级失败的情况,基本都是 U-Boot 自动回滚到旧版本解决的,运维同学反馈“体验还可以,重启一下就好了”。

3.5 简化版方案:单分区 + 备份包恢复

如果你的 eMMC 空间紧张,或者产品定位里不太需要反复升级,也可以用简化方案:rootfs 只保留一份,但在 /backup 分区保存一个出厂时的 rootfs 镜像。升级时对当前 rootfs 做覆盖,失败时从备份包恢复。

这个方案的缺点是升级过程会打断业务,而且覆盖写 rootfs 时如果断电会变砖(要么靠备份恢复,要么靠刷机工具救砖),可靠性明显低于双分区。所以我的建议是,只要能承担几百 MB 的空间成本,优先上双分区;空间实在紧张的,再考虑简化版。

4. OverlayFS 恢复出厂:原理与实操

4.1 OverlayFS 到底是个什么东西

OverlayFS 是 Linux 内核自带的一种联合文件系统,作用是“把两个目录叠在一起看”。

这里用一个生活化类比:想象你有一张写满字的纸(lowerdir,只读底层),又拿来一张半透明的纸(upperdir,可写上层)盖在上面。你透过上面那张纸看到的,是两张纸叠加后的效果:下面的字能看见,上面的字也能看见。如果我在上面的纸上写字,不会影响到下面那张纸;如果我把上面那张纸揭开丢掉,换一张新的半透明纸盖上去,看到的又变回最初那一层的内容——这不就是恢复出厂吗。

在内核层面,OverlayFS 有四个关键目录:

目录作用生命周期
lowerdir只读底层,一般是根文件系统永远不变
upperdir可写上层,所有修改都在这里恢复出厂时清空
workdirOverlayFS 元数据工作目录恢复出厂时清空
merged叠加视图,应用实际读取/写入的地方动态生成

当应用修改一个 lowerdir 里的文件时,OverlayFS 会先把该文件“复制”到 upperdir(这叫 copy-up),再在 upperdir 里修改。对应用来说,它感觉不到这个过程,但对系统设计者来说,这个机制简直是为恢复出厂量身定做的。

4.2 用 OverlayFS 做恢复出厂的整体设计

有了前面分区规划的铺垫,OverlayFS 的方案就很清晰了:rootfs 作为 lowerdir 只读挂载,/overlay/upper 作为 upperdir,/overlay/work 作为 workdir,三者叠加后挂载成新的根目录。系统正常运行时的一切写操作,都落在 /overlay/upper 里。

恢复出厂的操作,本质上就是“清空 /overlay 分区下的 upper 和 work 目录,然后重启”。因为 lowerdir 一直没变,清空上层之后看到的系统,就是刚烧录时的样子。

这套方案的优势非常明显:

  • 恢复速度快,即使 2GB 的根文件系统,清空 overlay 也就几十毫秒,加上重启也就几秒钟
  • 永远不需要写整个系统分区,不消耗 eMMC 不必要的寿命
  • 不会出现“恢复过程中断电变砖”的风险,因为只删了可写层,系统层毫发无损
  • 用户数据全在 /data 分区,恢复系统不会误删业务数据

4.3 OverlayFS 挂载的实操配置

要让根文件系统跑在 OverlayFS 上,关键是在系统启动时完成一次重新挂载。我一般不用 initramfs,而是直接在 U-Boot 启动参数里指定 overlay 逻辑,或者在一个早起的 systemd 服务里完成。

直接用 fstab 挂载 OverlayFS 有时会遇到顺序问题,因为你要在根文件系统已经挂载的情况下,把另一个文件系统当 lowerdir 叠上来,这个操作在系统完全启动后再做会非常别扭。所以我的做法是:早期启动脚本(或 initramfs)里完成重挂载。

以 systemd 为例,在系统启动早期加入一个服务:

# /etc/systemd/system/overlay-root.service [Unit] Description=Setup overlay root filesystem DefaultDependencies=no Before=sysinit.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/setup-overlay-root.sh

脚本内容:

#!/bin/bash # setup-overlay-root.sh ROOT_DEVICE=/dev/mmcblk0p2 OVERLAY_DEVICE=/dev/mmcblk0p4 UPPER_DIR=/overlay/upper WORK_DIR=/overlay/work MERGED_DIR=/mnt/root # 等待设备节点就绪 sleep 1 # 挂载 overlay 分区 mount $OVERLAY_DEVICE /overlay # 初始化 upper 和 work 目录 mkdir -p $UPPER_DIR $WORK_DIR $MERGED_DIR # 将当前根文件系统重新绑定挂载到临时目录作为 lower mount --bind / $MERGED_DIR mount --make-private $MERGED_DIR # 用 overlay 重新挂载根目录 mount -t overlay overlay -o lowerdir=$MERGED_DIR,upperdir=$UPPER_DIR,workdir=$WORK_DIR / echo "Overlay root mounted"

这里有几个容易踩的坑,我逐个说明:

第一个坑:mount --bind / $MERGED_DIR这一步必须有。如果你直接把lowerdir=/写到 overlay 挂载参数里,内核会陷入递归循环——overlay 的底层又依赖 overlay。必须先把当前根目录绑定到一个临时挂载点,再用这个临时挂载点当 lowerdir,最后用 overlay 覆盖根目录。

第二个坑:overlay 分区必须先挂载,然后才能初始化 upper/work 目录。我见过有人直接在脚本里mkdir -p /overlay/upper,但 /overlay 目录本身在 rootfs 里,rootfs 还是只读的,创建不了,所以必须先 mount 一个可写分区到 /overlay。

第三个坑:如果 rootfs 本身不是只读挂载,overlay 的 lower 和 upper 都在同一个可写文件系统上,会破坏 OverlayFS 的一致性。所以/etc/fstab里 rootfs 的挂载参数一定要写ro

4.4 恢复出厂的触发方式与脚本

恢复出厂的核心动作是清空 upper 和 work。但要注意:你不能在系统运行、overlay 已经挂载到根目录的时候直接删 upper 目录——因为当前根目录的写入会实时落到 upper,删了又会立刻生成新的文件,而且可能破坏正在运行的文件句柄。

正确做法是:不直接在线清理,而是通过 reboot 配合标志位实现。我在方案里设置了三种触发方式:

方式一:开机按键触发

U-Boot 检测到某个 GPIO 按键被按下,就在启动参数里传一个factory_reset标志。启动脚本里判断到这个标志后,在 overlay 尚未挂载时清空 overlay 分区,然后正常启动系统。

方式二:系统内指令触发

用户或运维人员登录系统后执行factory-reset命令。命令的核心逻辑是把标志写入 /data 或专门的状态分区,然后重启。启动早期脚本检测到标志后执行清理:

#!/bin/bash # /usr/local/bin/factory-reset touch /data/.factory_reset sync reboot

然后启动脚本中:

if [ -f /data/.factory_reset ]; then echo "Factory reset requested..." umount -l /overlay 2>/dev/null || true mkfs.ext4 -q /dev/mmcblk0p4 rm -f /data/.factory_reset sync fi

这里我用 mkfs.ext4 直接格式化 overlay 分区,比一个一个删文件干净利落,也避免了文件系统碎片问题。要注意的是,mkfs 会直接重建文件系统,所以这一步绝不能在对 overlay 分区有挂载时执行,否则内核会报错。所以我把清理动作放在 overlay 尚未挂载的启动早期。

方式三:Web/应用界面触发

通过设备的业务 Web 页面或上位机软件调用一个后端接口,后端只执行上面那个 factory-reset 脚本。这个对客户来说最友好,因为不需要懂 Linux 命令。

4.5 恢复出厂的边界条件与保护

恢复出厂不是万能的,我在设计时明确划分了边界:

  • rootfs 与系统内核损坏:OverlayFS 只保护用户态文件,内核和 bootloader 损坏时,只能靠双分区回滚或串口刷机
  • /data 分区用户数据:默认保留,因为很多工控场景,设备有自己的配置和校准数据,恢复出厂不能把这些丢掉;如果业务确实需要“完整恢复”,可以在 factory-reset 脚本里加一个参数,选择是否同时格式化 /data
  • 硬件故障:eMMC 物理损坏、供电异常、主板问题,软件方案都无能为力

还要提一点:恢复出厂功能要“防呆”。我在脚本里加了一个二次确认机制,比如需要先执行factory-reset --yes --confirm才能触发,避免对面的运维手滑把几十条产线设备全恢复了。

5. 常见问题与排查技巧实录

5.1 故障现象速查表

现象可能原因排查方向
系统正常启动但修改配置后重启丢失overlay 挂载失败或 upper 没生效检查 /etc/fstab、检查启动日志中 overlay mount 的输出
执行恢复出厂后系统还是旧状态upper 目录没清理干净或清理顺序错误确认清理时 overlay 未挂载,确认 mkfs 目标分区正确
升级完成后重启还是旧版本启动槽位标记没写成功检查 active_slot 文件内容,检查 U-Boot 读取逻辑
升级 B 分区后无法启动内核/设备树与 rootfs 不匹配检查 kernel_b.itb 是否写入 boot 分区,检查根参数
系统运行几个月后 eMMC 写满或变慢日志/缓存写入量过大且未限制检查 /var/log 大小、journald 占用、数据库文件位置
OverlayFS 挂载时报 invalid argumentlowerdir 和 upperdir 同分区或 rootfs 未只读检查 fstab 中 ro 参数,检查分区挂载情况
恢复出厂后 /data 也没了格式化了错误的分区检查脚本中 mkfs 的分区编号,加保护性判断

5.2 几个值得记录的踩坑过程

坑一:journald 差点写废 eMMC

我在一个项目上用了默认的 systemd-journald,日志直接写到 /var/log/journal。设备现场跑了一个月后,发现 eMMC 的写入量惊人,一查 journald 默认没有日志大小上限,滚动不够及时。后来我把 /var/log 改成 tmpfs,journald 的 Storage=volatile,同时把需要持久化的应用日志单独用 logrotate 控制,写入量立刻降下来了。

坑二:OverlayFS 和 rootfs 同分区的严重问题

早期为了省分区,我把 overlay 的 upper 目录放在了 rootfs 分区里一个叫 /overlay 的目录下。结果有个系统服务往 /etc 写了个文件,copy-up 正确处理还行,但一旦某个进程直接通过底层分区的路径改文件,整个 overlay 视图就乱了。那时候排查了很久,最后才意识到是 lower 和 upper 物理同盘造成的。这个问题从根上解决,就是分一个独立分区给 overlay。

坑三:双分区升级断电后的“假成功”

升级脚本里,我以前是把“写 active_slot 标记”放在“拷贝系统文件”之后的同一段流程里,但两次 sync 之间没有区分优先级。有一次客户升级写入 rootfs_b 时断电,重启后 U-Boot 识别到 active_slot 还是 A,系统正常工作;可升级记录却显示“已写入新版本”,运维误以为升级完成了。后来我改成升级包安装完成后单独弹一个“需要重启才能完成”的提示,并且 active_slot 的写入状态会校验文件系统完整性后才确认成功。

坑四:恢复出厂时忘了 umount overlay

有一次线上版本故障,现场同事执行恢复出厂,脚本里没有先 umount overlay 就删上层目录,结果系统内核报错、文件系统只读,最后只能断电重启。当时我意识到这个问题的严重性:直接删一个挂载中的 overlay 上层,等于在高速公路上换轮胎。后来脚本里一律先处理挂载状态,再格式化。

5.3 让系统“自己会看病”

最后分享一个我觉得很值的做法:在系统启动早期加一个健康检查脚本,检查几个关键路径是否可写、关键服务是否存活、磁盘剩余空间是否充足。如果连续多次启动失败,自动触发恢复出厂——当然要加保护,比如只有连续 3 次失败才触发,且必须是在/data 之外的系统分区空间足够时才执行。

我还在设备上写了一个小工具syscheck,会在开机时输出一张摘要:rootfs 是否只读、overlay 是否挂载、当前启动槽位、磁盘空间、内核版本、固件版本。这大大减轻了排障时和现场沟通的负担。很多问题,运维只需要把 syscheck 的输出发过来,我就知道是哪一类故障了。

写在后面

这套存储配置、双分区升级加 OverlayFS 恢复出厂的方案,我前前后后在不同项目里改了好几版,踩过的坑比写出来的还多。核心体会就是:工控设备的系统设计,别想着“出事以后能修”,而是要“出事以后不用修,或者最简单操作就能恢复”。把只读、分区隔离、双分区、overlay 这几个机制吃透,从存储规划开始就按这个思路做,后面恢复出厂只是水到渠成的一步。

最后再提一个我在调试时常用的技巧:最终验证 OverlayFS 是否真生效,可以在系统启动后执行df -h /mount | grep overlay,看到根目录挂载类型是 overlay 就说明成功;如果要看某个文件到底落在 upper 还是 lower,用ls -i对比文件 inode 和上下层目录是否一致就行。这个小办法帮我避过不少“以为生效其实没生效”的坑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 11:12:37

深入理解Python递归:调用栈、终止条件与性能优化实战

1. 递归到底是什么:一个"自己调用自己"的函数背后发生了什么1.1 从"查字典"和"套娃"理解递归的定义很多初学Python的朋友在学到递归这一节时,最容易卡住的地方不是"看不懂代码",而是"想不通逻辑…

作者头像 李华
网站建设 2026/9/9 11:10:36

2026年十大高薪行业深度解析:从AI大模型到ESG的赛道选择指南

这两年总有人问我:现在换工作,往哪里跳才能拿到高薪?说实话,每次听到这个问题,我都有点心情复杂。“高薪行业”这四个字,听起来像是一个确定的目标,背后却藏着一堆不确定性。我见过从互联网大厂…

作者头像 李华
网站建设 2026/9/9 11:10:19

MINIMAX-H3本地部署实战:8G显存+LoRA多模态模型跑通指南

这次来看 MINIMAX-H3。如果只看名字,你可能会把它当成 MiniMax 又发布的新模型,但这次更值得关注的点是:它正式适配了 LoRA,并且按“8G 显存 16G 内存”这个中低配目标在推进。对手里只有 8G 级别 N 卡的用户来说,这是…

作者头像 李华
网站建设 2026/9/9 11:08:19

AI会议助手深度测评:声纹识别如何决定会议记录的分水岭

最近这半年,我几乎把市面上主流的AI会议助手都装了一遍,每天不是在开会,就是在开会的路上,手机里的录音文件堆了几十个。本来想着让AI帮我解放双手,结果用了几周发现一个尴尬的问题:记录倒是记得全&#xf…

作者头像 李华
网站建设 2026/9/9 11:07:38

低代码不是拖拽工具,而是业务与技术融合的交付革命

2016年的时候我做过一个内部系统,前后端加测试四个人,整整忙了三个月才上线。到了2025年底,我们团队接了一个体量差不多的需求,两个人在低代码平台上从建模到配置再上线,花了九天。九天里还有两天在等业务部门确认审批…

作者头像 李华
网站建设 2026/9/9 11:06:36

Modbus TCP Master/Slave测试软件实战:从通讯调试到故障排查

简介:Modbus TCP Master/Slave 测试软件是一款面向工业互联网场景的调试工具,主要服务于自动化工程师、PLC 程序员和上位机开发者,用于验证各类 Modbus TCP 设备的通信链路、功能码响应与数据采集逻辑,目标是降低设备联调与排错门…

作者头像 李华