我有一个在嵌入式Linux设备上运行的应用程序,不时会对软件进行更改,有时也会对根文件系统甚至已安装的内核进行更改。
在当前的更新系统中,只删除旧应用程序目录的内容,并在其上复制新文件。当对根文件系统进行更改时,新文件将作为更新的一部分传递,并简单地复制到旧文件上。
现在,目前的方法存在一些问题,我正在寻找改善这种情况的方法:
要求是:
dd
即可?我绝对需要一些方法来对根文件系统进行版本控制。这必须以某种方式完成,我可以从中计算某种diff
,它可以用来更新目标设备的rootfs。
我已经查看了Subversion,因为我们将它用于源代码,但这不适合Linux根文件系统(文件权限,特殊文件等)。
我现在已经创建了一些shell脚本,可以给我一些类似于svn diff
的内容,但我真的想知道是否已经存在一个可行的,经过测试的解决方案。
使用这样的diff
我想升级只会变成一个包含基于已知根文件系统状态的增量更新的包。
您对此有何看法和想法?你会如何实现这样的系统?我更喜欢一种可以在不太长的时间内实施的简单解决方案。
答案 0 :(得分:31)
我相信你在这个问题上看错了 - 任何非原子的更新(例如dd文件系统映像,替换目录中的文件)都会被设计破坏 - 如果电源在更新过程中断电,系统是砖块,对于嵌入式系统,电源可以在升级过程中熄灭。
我写了一篇关于如何在嵌入式Linux系统上正确升级/更新的白皮书[1]。它在OLS上发布。你可以在这里找到论文:https://www.kernel.org/doc/ols/2005/ols2005v1-pages-21-36.pdf
[1] Ben-Yossef,Gilad。 “构建与Murphy兼容的嵌入式Linux系统。” Linux Symposium 。 2005。
答案 1 :(得分:9)
我绝对同意更新必须是原子的 - 我最近开始了一个开源项目,其目标是为本地和远程更新提供安全,灵活的软件管理方式。我知道我的答案很晚,但它可能会帮助你完成下一个项目。
您可以在github.com/sbabic/swupdate
找到“swupdate”(项目名称)的来源。
斯特凡诺
答案 2 :(得分:2)
原子性对嵌入式设备至关重要,其中一个原因是功率损耗;但可能还有其他像硬件/网络问题。
原子性可能有点误解;这是我在更新程序中使用的定义:
使用双A / B分区布局进行全图更新是实现此目的的最简单且最经过验证的方法。
对于嵌入式Linux,您可能需要更新多个软件组件以及可供选择的不同设计;有一篇关于此的新文章:https://mender.io/resources/Software%20Updates.pdf
文件已移至:https://mender.io/resources/guides-and-whitepapers/_resources/Software%2520Updates.pdf
如果您正在使用Yocto项目,您可能会对Mender.io感兴趣 - 我正在开发的开源项目。它由客户端和服务器组成,目标是使更新程序更快更容易地集成到现有环境中;无需重新设计太多或花时间在自定义/本地编码上。它还允许您使用服务器集中管理更新。
答案 3 :(得分:2)
目前,有相当多的开源嵌入式Linux更新工具在不断增长,每个工具都有不同的重点。
另一个值得一提的是RAUC,它专注于处理目标上已签名更新包的安全和原子安装,同时在您适应应用程序和环境方面非常灵活。资料来源于GitHub:https://github.com/rauc/rauc
一般来说,您可以在Yocto Project Wiki页面上找到有关系统更新的当前更新解决方案的概述和比较:
答案 4 :(得分:0)
您可以记录更新并将更新闪存分成两个插槽。电源故障始终会使您返回当前正在执行的插槽。最后一步是修改日记帐值。非原子,没有办法让它变砖。即使它在写日记标志的那一刻失败了。没有原子更新这样的东西。永远。在我的生活中从未见过它。 Iphone,adroid,我的网络交换机 - 它们都不是原子的。如果您没有足够的空间来进行这种设计,那么请修改设计。