防止断电时 ext4/Linux 驱动器上的数据损坏

Jon*_*son 11 linux embedded ide corruption

我有一些运行 American Megatrends bios 的嵌入式板,以嵌入式 linux 作为操作系统。我的问题是工业闪存 ide 会在断电时损坏。我将它们格式化为 ext4。每当发生这种情况时,我通常可以使用 fsck 修复闪存,但这在我们的部署中是不可能的。我听说禁用写缓存应该会有所帮助,但我不知道该怎么做。另外,还有什么我应该做的吗?

更多信息

该驱动器是一个 4GB ide 闪存模块。我有一个分区是 ext4。操作系统安装在该分区上,grub 是我的引导加载程序。

fdisk -l 显示 /dev/sda 作为我的闪存模块,/dev/sda1 作为我的主分区。

断电后,我通常无法完全通过启动初始化脚本来实现。

当我在另一台 PC 上安装驱动器时,我运行 fsck /dev/sda1。它总是显示类似的消息

"zero datetime on node 1553 ... fix (y)?"
Run Code Online (Sandbox Code Playgroud)

我修复了它们,它可以正常启动,直到下一次断电。

明天到办公室时,我会贴出 fdisk -l 的实际输出

这就是我对系统如何工作的全部了解。我不是系统专家,我是一名软件工程师,习惯于陷入工作描述之外的困境。我知道如何格式化驱动器、安装引导加载程序、编写软件以及破解操作系统。

这是 dumpe2fs 的输出

#sudo dumpe2fs /dev/sda1
dumpe2fs 1.41.12 (17-May-2010)
Filesystem volume name:   VideoServer
Last mounted on:          /
Filesystem UUID:          9cba62b0-8038-4913-be30-8eb211b23d78
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    (none)
Filesystem state:         not clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              245760
Block count:              977949
Reserved block count:     48896
Free blocks:              158584
Free inodes:              102920
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      239
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Flex block group size:    16
Filesystem created:       Fri Feb  4 15:12:00 2011
Last mount time:          Sun Oct  2 23:48:37 2011
Last write time:          Mon Oct  3 16:34:01 2011
Mount count:              2
Maximum mount count:      26
Last checked:             Tue Oct  4 07:44:50 2011
Check interval:           15552000 (6 months)
Next check after:         Sun Apr  1 07:44:50 2012
Lifetime writes:          21 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Default directory hash:   half_md4
Directory Hash Seed:      249d2b79-1e20-49a3-b324-6cb631294a63
Journal backup:           inode blocks
Run Code Online (Sandbox Code Playgroud)

the*_*bit 6

写入缓存通常与 BIOS 无关,大多数情况下没有用于切换磁盘缓存设置的选项。使用 linux,使用hdparm -W 0应该会有所帮助。

该设置是持久的,因此如果您没有 hdparm 在您的生产系统中使用,您应该能够在不同的系统上禁用磁盘写入缓存并重新插入磁盘。

顺便说一句:我赞同不可写的根文件系统的想法(这样你的系统就可以在一种“恢复模式”下启动并允许远程访问,即使可写文件系统由于某种原因不可挂载)。如果您可以更改硬件设计,请考虑使用mtd 设备而不是具有闪存感知文件系统(如jffs2 )的 IDE/SATA 磁盘。几年来,我们一直将这种组合与多种嵌入式设备(主要是该领域的 VPN 路由器解决方案)结合使用,并取得了良好的效果。

更新:您的问题的根源似乎是您正在运行禁用日志功能的 ext4 文件系统 -列表中has_journal缺少Filesystem features。只需关闭所有服务,使用 来检查是否仍有打开的文件,使用lsof +f -- /重新挂载您的根分区只读mount -o remount,ro /,使用 启用日志tune2fs -O has_journal /dev/sda1并将“有序”日志模式设置为默认挂载选项tune2fs -o journal_data_ordered /dev/sda1- 您将不得不重新-运行 fsck(最好从救援系统)并在此操作后重新挂载 root/reboot。

有了这些设置,即使在突然断电的情况下,元数据也可以保证可以从日志中恢复。实际数据也始终如一地写入磁盘,尽管您可能会在启动时看到断电前几秒钟的数据。如果这是不可接受的,您可以考虑在tune2fs -o journal_data /dev/sda1您的文件系统中使用mount 选项 - 这将包括写入日志中磁盘的所有数据 - 这显然会为您提供更好的数据一致性,但代价是性能损失和更高的磨损水平在您的 SSD 上。


pol*_*ial 5

写缓存建议是一个好的开始,但这听起来像是一个架构设计缺陷。在嵌入式系统上,除非在极少数情况下,内部闪存可能不应 R/W 安装。您确实应该在内存文件系统中完成大部分工作,并根据某些用户命令或定期将更改同步回 RW 闪存。在正常操作期间,嵌入式系统在 rw 模式下使用常规文件系统(如 ext4)确实很少见。如果某些应用程序需要大量存储空间,您应该考虑让您的系统分区不同,并将其设计为数据分区可以作为启动的一部分进行 fsck -y'ed。

如果您需要一些起点,我会看看人们如何设置无盘 Linux 系统:

http://frank.harvard.edu/~coldwell/diskless/

并从那里开始。一般的想法是您的系统二进制文件和数据可以以只读方式安装,因此您的文件系统不会被损坏。但是,您需要能够写入某些区域,因此您通常需要一些东西来存储文件系统 /tmp、/var/tmp。即使某些东西需要可写,您只需创建一个脚本来将分区挂载为 r+w,然后提交更改,然后返回只读。

一个非常好的例子是 Cyclades 硬件,它的嵌入式 linux,每当您进行配置更改时,您都必须执行一个保存脚本,该脚本实际上重新捆绑配置并将它们写出到闪存中。