我有一个简单的更新程序 bash 脚本,它通过删除事件旧文件并将新文件从存档复制到正在运行的嵌入式目标根文件系统来替换文件。这样,脚本可以更新系统文件以及更新程序脚本本身。
mount -o remount,rw /dev/rootfs /
最近,我通过使用 R/W 访问 ( ) 重新挂载、执行其更新业务并使用 R/O 访问 ( mount -o remount,ro /dev/rootfs /
)重新挂载来扩展脚本来处理只读文件系统。
但这种方法失败了。通常,脚本在第一次运行时(使用 R/O 访问权限重新安装时)失败,或者在第二次运行(使用 R/W 访问权限重新安装时)失败。这是一条代表性的错误消息:
root@device:~# mount -o remount,rw /dev/rootfs /
EXT3-fs (mmcblk0p2): warning: couldn't remount RDWR because of unprocessed orphan inode list. Please umount/remount instead.
mount: mounting /dev/rootfs on / failed: Invalid argument
经过一些研究(例如https://stackoverflow.com/questions/7834667/self-deleting-bash-script),我意识到问题在于如何从文件系统中删除打开的文件的机制。即,在调用时仅取消链接到文件 inode 的链接,而当所有使用该文件的程序关闭该文件时,该 inode 表示的文件实际上被删除。因此,当我重新挂载回 R/O 模式时,到 inode 的链接消失了,而 inode 本身却没有消失,从而导致文件系统损坏,从而导致列出的错误。这个结论正确吗?
现在,我感兴趣的是如何正确解决这个问题。我认为避免重新安装回 R/O 模式并重新启动系统是可以的,对吗?但有没有更好的解决方案,允许重新挂载回 R/O 模式并避免系统重启?
请注意,解决方案应该与文件系统类型无关。具体来说,我在 ext3/ext4 和 ubifs 上运行。
编辑:我正在寻找一个通用的解决方案,它不需要重新启动单个服务(即了解系统)。重新启动系统实际上并不是问题,只是将系统返回到运行更新脚本之前的相同状态听起来是正确的,即如果文件系统在执行之前是 R/O,则可能应该是 R /O 之后也是如此。但也许这样的前提是无效的。