我正在使用运行 DietPi OS 的 Raspberry Pi CM4 开发嵌入式应用程序。我希望尽可能减少 MMC 闪存写入次数,以实现最长的使用寿命。在我的安装中,有一些应用程序经常在整个 /var 目录中写入数据(不仅仅是 /var/log 和 /var/tmp 的常见违规者)。 /var 中的这一新数据不是关键任务,因此我想将所有 /var 挂载为一个 overlayfs,然后使用一个关闭脚本来同步对磁盘的更改一次。我的覆盖部分工作正常。这是我的启动脚本:
#!/bin/bash
#Startup script to mount /var as an overlay to minimize eMMC writes
if mount | grep "overlay on /var type overlay"; then
echo Mount Point at /var already exists, exiting.
exit 1
else
if [ ! -d "/var.tmpfs" ]
then
mkdir -p /var.tmpfs
fi
mount -t tmpfs -o rw,nosuid,nodev,noexec,relatime,size=256m,mode=0775 tmpfs /var.tmpfs
mkdir -p /var.tmpfs/upper
mkdir -p /var.tmpfs/work
chown -R root:root /var.tmpfs
chmod -R u=rwX,g=rwX,o=rX /var.tmpfs
if [ ! -d "/tmp/realvar" ]
then
mkdir -p /tmp/realvar
fi
mount --bind /var /tmp/realvar
sudo mount -t overlay -o rw,lowerdir=/tmp/realvar,upperdir=/var.tmpfs/upper,workdir=/var.tmpfs/work overlay /var
fi
exit 0
这会导致对写入 /var 的任何内容的 MMC 写入为零,同时仍然可以使用通过 overlayfs 写入那里的数据。最困难的部分是运作良好。现在我想将上层目录中的更新同步到磁盘,以便在计划的重新启动/关闭事件中幸存下来。我意识到断电事件会导致我失去 upperdir 中的所有数据,但这很好。
同步脚本:
#!/bin/bash
#Shutdown script to sync the contents of the temporary overlay to actual /var on disk
if [ -d "/tmp/realvar" ]
then
rsync -vaz --delete /var/ /tmp/realvar
fi
exit 0
上述大部分内容均归功于 LeonidMew 和 Tobby Fox,来自这个非常相关但较旧的线程:将/var/logs挂载为tmpfs,有时借助overlayfs来保存更改
问题是:rsync 不起作用,我不明白为什么。为了进行测试,我在建立覆盖层后在 /var/lib 中创建了一个文件。然后,我执行 rsync 命令字符串,该字符串似乎按预期执行。我重新启动,我的测试文件消失了。换句话说,upperdir 的内容没有按照我希望的方式写入磁盘。
一个有趣的观察:在 /var/lib 中创建测试文件后,它立即存在于 /var.tmpfs/upper/lib 和 /tmp/realvar/lib 中。我不希望它位于 /tmp/realvar/lib 中,因为这是覆盖层的“较低”目录。不确定这是否相关,但我注意到这是一件奇怪的事情。
我使用下面的命令来确认我的覆盖层实际上正在工作,方法是观察我的所有应用程序读取/写入 /var 覆盖层并确认此命令的结果不会改变:
cat /sys/fs/ext4/mmcblk0p2/lifetime_write_kbytes
由于我的 rsync 功能不起作用,因此 /var 中的所有更改在重新启动后都会丢失。通过 /var 上的覆盖层和我使用 DietPi 进行的极简安装,启动后 MMC 写入为零,但如果我更改 /etc 中的设置或更改 /usr 中的嵌入式应用程序,那么它会立即写入并在重新启动后继续存在。如果我能让 /var 覆盖层的 rsync 工作,那么我将拥有一个完美的(对我来说)嵌入式文件系统配置。
任何想法将不胜感激!