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

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

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

更多信息

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

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

断电后,我通常无法完全完成启动初始化脚本。

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

"zero datetime on node 1553 ... fix (y)?"

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

明天到办公室时,我会发布 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

答案1

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

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

顺便说一句:我支持非可写根文件系统的想法(这样您的系统就可以在某种“恢复模式”下启动,即使可写文件系统由于某种原因无法挂载,也可以允许远程访问)。如果您可以更改硬件设计,请考虑使用mtd 设备而不是像具有闪存感知文件系统的 IDE/SATA 磁盘jffs2. 几年来,我们一直将这种组合与多种嵌入式设备(主要是现场的 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(最好从救援系统运行)并重新挂载根分区/重新启动。

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

答案2

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

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

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

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

一个很好的例子就是 Cyclades 硬件及其嵌入式 Linux,每当您进行配置更改时,您都必须执行一个保存脚本,该脚本实际上会重新捆绑配置并将其写入闪存。

相关内容