嵌入式 Linux 的防损坏 SD 卡文件系统?

SF.*_*SF. 40 linux filesystems embedded failure-resistance

最近,我们的客户遇到了一个相当不愉快的情况 - 用于显示遥感数据的基于 Raspberry Pi 的“信息亭”(没有什么比显示来自数据收集服务器的自更新网页的信息亭模式浏览器更花哨的了)由于以下原因无法启动文件系统损坏。Ext4,需要手动fsck,系统将成为明天重要演示的一部分,立即需要服务。当然,我们不能要求客户在晚上关闭系统时很好地关闭系统;该系统必须简单地承受这种虐待。

我想在未来避免这种情况,并且我想将操作系统移动到一个可以防止这种情况的文件系统。有很多用于 MTD 设备的文件系统,让它们在 SD 卡(标准块设备)上运行需要一些严重的跳跃。还有一些其他文件系统(日志等)具有良好的抗腐败能力。我仍然需要看到他们的优缺点的一些合理比较。

Linux 中可用的哪个文件系统将在意外电源故障时提供最佳的抗破坏性,并且不需要跳过像yaffs2这样不可能的箍来安装到 SD。

磨损平衡是一个优点,但不是必需的——SD 卡通常有自己的机制,如果不够完美,尽管系统应该是“对闪存温和的”(像 NTFS 这样的系统可以在一个月内杀死 SD 卡)。

loc*_*eed 20

RAID1模式下的BTRFS将在单个 SD 卡上提供最佳的抗损坏能力,并每个预定义的时间段内自动运行清理

好处:

  1. 保留对文件系统进行 RW 的能力
  2. 现代的、功能齐全的文件系统,具有非常有用的 RPi 选项,例如透明压缩和快照
  3. 设计时考虑到了闪存(除其他外)

这是如何做到的:

我在 ArchARM linux 上运行我的 RaspberryPi,我的卡在 SD 读卡器中,所以相应地修改这些指令以用于其他发行版和 /dev 接口。

这是一个示例分区布局:

/dev/mmcblk0p1: fat32 boot partition
/dev/mmcblk0p2: to be used as btrfs partition
/dev/mmcblk0p3: to be used as btrfs partition (mirrored with the above)
/dev/mmcblk0p4 (optional): swap
Run Code Online (Sandbox Code Playgroud)

要将 btrfs 放入 RAID1,您可以像这样创建文件系统:

mkfs.btrfs -m raid1 -d raid1 /dev/mmcblk0p2 /dev/mmcblk0p3
Run Code Online (Sandbox Code Playgroud)

然后,您rsync -aAXv可以使用以前备份的系统。

要让它从 raid1 中的 BTRFS 启动,您需要修改 initramfs。因此,当您的系统仍在旧文件系统上运行时,您需要执行以下操作。

Raspberry 通常不使用 mkinitcpio,因此您必须安装它。然后,您需要将“btrfs”添加到 mkinitcpio.conf 中的 MODULES 数组并使用以下命令重新创建 initramfs

mkinitcpio -g /boot/initrd -k YOUR_KERNEL_VERSION
Run Code Online (Sandbox Code Playgroud)

要知道键入什么而不是 YOUR_KERNEL_VERSION,请运行

ls /lib/modules
Run Code Online (Sandbox Code Playgroud)

如果您更新内核,则必须在重新启动之前重新创建 initramfs。

然后,您需要修改 RPi 的启动文件。

在cmdline.txt中,你需要有

root=/dev/mmcblk0p2 initrd=0x01f00000 rootfstype=btrfs
Run Code Online (Sandbox Code Playgroud)

并在 config.txt 中,您需要添加

initramfs initrd 0x01f00000
Run Code Online (Sandbox Code Playgroud)

完成所有这些并成功启动到 btrfs RAID1 系统后,剩下的唯一事情就是使用 systemd 计时器(首选)或 cron (dcron) 设置定期清理(每 3-7 天),如下所示:

btrfs scrub start /
Run Code Online (Sandbox Code Playgroud)

如果发现任何损坏,它将在您的文件系统上运行,比较所有文件的校验和并修复它们(替换为正确的副本)。

BTRFS RAID1、单一介质和 Raspberry Pi 的组合使这个非常神秘的东西。把所有的部分放在一起需要一些时间和工作,但它就是这样。

  • @@@ 更新:@@@ 截至目前,可以尝试使用 dup-mode 而不是 RAID1:“mkfs.btrfs --data dup --metadata dup”,但我不能 100% 确定它与 RAID1 一样有弹性在单个驱动器上。 (2认同)

小智 10

我会采用另一种方式,只使用只读文件系统。在 sdcard 上使用读写根文件系统时,我的树莓派从来没有足够稳定。您可以仅通过内核 cmdline (ro) 引导您的根,也可以使用带有搭载的 initramfs 包括您的完整系统。

两者都可以使用我自制的构建系统 OpenADK 创建。( http://www.openadk.org )


MDM*_*313 8

闪存比磁存储更受欢迎,原因有很多,但对于这个应用程序,我会说主要是因为没有移动部件。话虽如此,我不认为存在“防腐败”文件系统,但有一些强大的文件系统(ext4 就是其中之一),以及一些有助于减轻腐败的策略。

内存盘

如果RPI的图像不会变化,这听起来像没有,如果没有将尝试(或者应该尝试)写入磁盘,然后尝试使用创建为一个根文件系统解压到内存中。这里的想法是你在启动时有一个压缩的根文件系统,它被解压到 RAM 中。所有更改都发生在 RAM 磁盘上,因此对 SD 卡的有效写入为零,仅在启动时读取。这应该会减少对驱动器的读/写操作,从而延长其使用寿命。这类似于从 CD 引导 linux时所做的事情,并且是linux 引导时首先发生的事情之一。


zmo*_*zmo 7

好吧,您在这里遇到的问题是使用诸如 ext* 之类的“现代”文件系统可能会磨损您的 SD 卡;根据我的经验,发生在一年内,或者如果你采取更高的水平,则在明年。

问题在于现代文件系统总是在移动块以防止数据碎片化。这在旋转磁盘上是一件好事,您希望在将所有数据加载到缓存时对其进行整理。缺点是它正在执行更多无法缓存的写入,因为在没有太多 I/O 发生时正在处理整理。

当您处理大量日志记录时也会发生这种情况,您在调试嵌入式设备时可能想要这样做。日志写入是最糟糕的写入类型,因为它有很多定期发生的微​​小写入,这会产生大量碎片。

正如您所说,您的系统也在处理传感器的数据,您很可能将它们存储在闪存中。它们和日志数据一样糟糕。

我遇到了你遇到的同样问题,这是我的结论。我试图寻找以“更强大”的方式出售的 SD 卡,即能够处理比其他卡更多的写入,但我发现市场上没有专注于这一点的基准,与 SSD 上的基准不同。由于它们都只关注速度,因此无法知道每个内存块的写入次数以及 SDCard 中使用的技术。

不过,我注意到“工业”级sandisks 的使用寿命更长。这并不奇怪,当你付出更多时,你得到更多。

但最后,在启用密集日志记录的情况下,我发现没有一个 SD 卡的使用寿命超过几年,一年是死亡人数最多的一年。

我想出的解决方案是@BigHomie 和@wbx 的解决方案:使用只读 extX 文件系统(因为不再需要日志记录,您甚至可以回退到旧的 ext2)。如果您想在会话中保留日志或写入临时文件,您始终可以使用 RAMDISK。

仅存在有助于使用只读部分中的数据填充 ramdisk 的教程和脚本,以便您可以为会话编辑它们。

注意:我的经验是在 Beaglebone 上使用 Angstrom Linux,其中包括 20 个传感器设备的试运行。该系统的日志记录非常冗长,使用 systemd 的日志系统。