1.文件系统断电可靠性问题
“一切皆是文件”,这是Linux生态系统中最常被引用的经验法则之一。这体现了文件以及文件系统可靠性对Linux操作系统的重要性。
提高可靠性最简单的方法就是把文件系统设置为只读状态。即禁止对其中的内容作任何修改。这样,文件系统便不会因写入操作期间发生故障而受损。当然,您也可以不这么做。配置数据、日志文件、临时信息及其他数据需要一个可靠的可写文件系统。
图1:Linux内核中的文件系统
考虑到汽车应用的独特需求,断电时确保系统的可靠性非常重要。汽车嵌入式系统面临两种高风险:意外失电以及意外失电时处理不当导致功能失效。显然,我们都不希望自己的汽车因电池电量不足而被拖到维修门店。
1.1. 背景 — 到底什么是“文件系统”?
对于Linux设置,无论是嵌入式还是桌面设置,文件系统层都是持久性和易失性存储器的核心。如图1所示,当某项应用想与系统中的数据交互时,可通过虚拟文件系统或VFS实现。
VFS层可抽象出底层文件系统实现的差异。事实上,我们在与文件交互时经常会看到向上呈现的现象,例如“/home/user/myfile.txt”。
实际文件系统实现发生在VFS下。它的主要任务是追踪下方介质数据的组织位置和方式。我们可以把它想象成一名库管理员,其通过自己的组织方案存储和检索标注数据。常见的文件系统实现方式包括ext4、btrfs、XFS、F2FS和ZFS。也有很多其他方式。
下层称作块层。它是实际存储硬件的抽象化表现。块设备代表的是存储设备或其中一部分。它看起来像一个大的可随机访问原始数据的连续区域,以块的形式组织起来,每个块通常为512字节或4千字节。这些块通过从0到数百万的块编号访问,具体取决于设备的整体大小。
这种抽象由不同的硬件驱动程序实现。对于有硬件闪存转换层(FTL,经常出现在eMMC、SSD和NVMe存储设备中)的基于闪存的存储,这种驱动程序可能会非常精简。FTL已经完成了大部分抽象工作。适用于其他存储形式的驱动程序则可能比较复杂。
现在,大量不同的文件系统实现表明,它们在速度、可靠性和资源使用情况等性能指标方面存在差异。这说明,对于某个特定的用例,有些驱动程序可能比其他类型更适用,那么该如何挑选合适的驱动程序呢?通常,速度和资源的使用情况很容易测试,但由于现实中存在断电等诸多问题,可靠性则不易测试。这里概述的测试设置可以帮助我们解决这个问题。
1.2 潜在故障模式
因意外断电而受损是可写文件系统的一个常见问题。通常,更改文件会导致文件系统向底层存储介质发出一个或多个写入命令(通过块层)。整个操作过程只有在所有命令全部执行后才能完成。
如果意外断电,磁盘中的数据可能只被部分写入。根据介质的特征,单次操作都可能中断,导致运行状态不一致。
任何这种错误都会以不同的方式体现在文件系统层中。根据中断写入操作的目的和位置,可能会出现数据(文件内容)或元数据损坏(文件名称、文件大小、目录等)。元数据损坏的后果通常更严重。如果元数据受损,可能导致从文件名错误到整个文件系统不可用等各种问题。元数据比较小,更容易通过冗余等方式减轻损害。通常防止数据损坏的措施成本较高,但它可以确保文件系统整体可用,即使存储在某处的单个文件包含虚假数据也是如此。
1.3 现代文件系统使用的缓解策略
如上所述,可利用多种方法减轻或阻止上述损坏。比较常见的三种方法包括日志记录、写时复制(CoW)和日志结构文件系统。
这些方法的选择取决于数据冗余形式。基本上,日志记录会先将所有数据写入占位符区域,然后复制到目标位置。这样,中断后总有一份完整的先前数据或新写入数据,因而可恢复为一致的状态。
写时复制与此类似,其将新数据写入未使用的位置,并标记“被覆盖”的数据。这种方法优于日志记录的地方在于无需回写。它的缺点是经常修改的文件会被碎片化。
日志结构法则将所有内容全部存储到循环缓冲区中。这样可以改善冗余和写入性能,但需定期收集垃圾。备用电池等基于硬件的策略不考虑。
1.4 用例依赖严重程度
第1.2条所述的故障其严重程度取决于使用场景。
如果受损的文件系统是根文件系统,ECU将无法运行,需要更换或至少需由合格人员亲自干预。
如果文件系统用于二次数据记录或不太重要的配置,可考虑使用自动修复策略,将文件系统重新格式化。情况最坏时,可能导致系统恢复出厂设置。这是否可接受需在系统设计阶段确定。
例如,我们可以考虑采用可调节乘坐舱空调和娱乐功能的系统,而非直接启动车辆驾驶辅助的系统。前一种系统的短时功能失效以及某些个人设置失效可能会为我们带来不便,但并不会为车辆驾驶员带来危险。后一种系统则不同。
其他需要考虑的因素包括当前硬件冗余或自动备份。同时,根据文件系统的配置,可在可靠性、速度和闪存磨损之间进行权衡。
2. 系统性文件系统断电抗扰度测试
为收集有关文件系统电源故障可靠性的确凿且可量化的证据,我们进行了确定性和文件系统不可知测试设置。在我们的测试中,文件系统为黑盒。此外,我们了解了下块和上VFS层的概况。
2.1 想法
如上所述,任何断电引起的文件系统损坏都是由于意外中断导致的硬件层写入操作所致。根据闪存硬件规格,我们知道较大规模的写入操作由较小的增量组成,这些增量以原子方式写入,也就是说它们要么完全写入,要么根本不写入[1]–[3]。因此,如果硬件正确实现了原子性,则可以中断写入操作的状态数量将是有限的。
也就是说,我们可以在一系列写入操作期间每一个可能的时间点模拟断电故障。每次中断,测试文件系统都有一次恢复机会。然后,检查是否出现任何故障模式。
2.2 方法论
图2:dm-log-writes测试设置
Linux设备映射器的dm-log-writes软件驱动程序可执行这些测试。它可以在文件系统和块设备层之间记录通过它的每一次写入。所生成的二进制写日志将被写入大容量持久性存储器中,供后续回放。
为生成日志输入,我们使用了Linux测试项目(ltp)中常见的fsstress程序[4]。给定一个随机种子后,fsstress可根据预先设定的概率分布,通过VFS层在文件系统生成一组操作。然后,这些操作会使测试的黑盒文件系统向块层发出写入操作,被dm-log-writes拦截、记录,然后中继到存储块设备中。记录的写入操作路径如上图所示。
dm-log-writes二进制日志的回放能够达到数据块设备在日志记录期间可能经历的所有状态。我们创建的回放实现能够将部分日志条目回放到单个写入块(在多数基于闪存的硬件上均为原子块)的粒度。所生成的块设备快照会呈现存储器在突然断电后可能出现的所有状态。
现在我们来检查所有可能出现的断电状态。每一步我们都会详细检查VFS层,确认文件系统是否仍然可用、一致,且未出现数据或元数据损坏。我们还会执行检查和其他写入操作,搜索“隐藏的”损坏,这些损坏无法被通常的静态文件系统检查工具立即检测出来。
2.3 完整性
我们对上述方法完整性的论证基于前述对一系列文件系统操作期间断电可能导致的所有状态的模拟。相关汽车级存储介质的硬件文档表明,至少可以认为单块写入是原子操作[3]、[5]。因此,如果我们对所有可能实施的原子步骤进行测试,即逐块写入,我们的测试就磁盘数据的可达状态而言就是完整的。
当然,这只是问题的一部分。我们还需要将不同的操作集呈现为VFS层的输入数据。这里,我们提出一个统计论点,即在fsstress上使用不同的种子来确保所有可能的操作以不同的组合运行。
3. 对客户的价值
Elektrobit对相关基于Linux的产品采用这种测试方法来提高可靠性。结果可直接用于在开发期间制定与文件系统有关的设计决策。特定用例产生的问题可尽早发现,尽早解决。
当然,测试不会在产品发布后停止,而将在维护过程中继续进行以免实施回归测试。特别是Linux内核升级时,如果在新的上游代码中引入文件系统漏洞,将会产生额外的保护层。
除此之外,Elektrobit还能根据需要为特殊用例提供定制解决方案。他们能够部署专门的测试设置,包括对在不同硬件、虚拟化或裸机上运行的不同Linux设置上的不同文件系统集进行结果评估。
4. emlix
emlix提供工业级Linux,用于在整个产品生命周期内实现设备、机器和工厂的数字化和安全联网。
20多年来,emlix一直在将系统知识、开源世界的创新和市场知识传输到我们350多家客户的产品中,这些客户遍及汽车、能源工业、自动化技术、医疗技术、安全技术等领域。
作为一家专业的开源软件提供商,我们确保整个流程安全、透明。我们使用的工具和开发标准能够满足工业要求和认证需要。我们为我们的解决方案提供长期维护合同,对产品生命周期和客户投资负责。
参考文献
[1] NVM Express Inc., “NVM Command Set Specification 1.0b.” Dec.18,2021.[Online].Available: https://nvmexpress.org/developers/nvme-specification/
[2] JEDEC, “JESD84-B51 - Embedded Multi-Media Card (e•MMC) Electrical Standard (5.1).”Jul. 2014.
[3] Micron Technology Inc., “TN-FC-27: e-MMC Power Loss Data Integrity.”Dec. 2013.
[4] “Linux Test Project - fsstress.” Silicon Graphics Inc. [Online].Available:
https://github.com/linux-test-project/ltp/tree/master/testcases/kernel/fs/fsstress
[5] Micron Technology Inc., “e.MMC Memory - MTFC8GAM, MTFC16GAP, MTFC32GAP, MTFC64GAP, MTFC128GAP.”Oct. 2018.
关于作者
Andreas Zdziarstek
emlix GmbH
Andreas Zdziarstek是emlix GmbH的一名系统工程师。他主要从事嵌入式Linux软件方面的工作,为汽车领域的用例开发定制解决方案,重点解决问题包括安全性、可靠性和可用性。
Thomas Brinker
emlix GmbH
Thomas Brinker是emlix GmbH的一名高级系统工程师和项目经理。他是汽车、医疗、工业和消费设备领域的安全嵌入式Linux系统架构师,在整个产品生命周期中负责需求工程和设计。
编辑:黄飞
评论
查看更多