系统管理指南:设备和文件系统

fsck 命令检查和尝试修复的内容

本节介绍文件系统正常运行时发生的情况、可能会出现的问题、fsck 命令(检查和修复实用程序)可查找的问题,以及此命令如何更正它找到的不一致性问题。

为什么可能出现 UFS 文件系统的不一致性问题

在每个工作日中,可能会创建、修改和删除数百个文件。每次修改文件时,操作系统都会执行一系列文件系统更新。如果这些更新被可靠地写入磁盘,便会产生一致的文件系统。

用户程序执行更改文件系统的操作(例如写入操作)时,会先将要写入的数据复制到内核中的核心缓冲区。通常,以异步方式处理磁盘更新。尽管在写入系统调用返回很长时间之后才会写入数据,但是允许用户进程继续执行。这样,在任何给定时间,由于文件系统驻留在磁盘上,因此它将滞后于核心信息所表示的文件系统状态。

当缓冲区需要用于其他用途时,或者内核自动运行 fsflush 守护进程(时间间隔为 30 秒)时,将更新磁盘信息以反映核心信息。 如果在未写出核心信息的情况下停止系统,则磁盘上的文件系统可能会处于不一致状态。

文件系统可能由于以下几种原因出现不一致性问题。最常见的原因是操作错误和硬件故障。

异常关机可能会导致此类问题,例如未正确关闭系统,或者未采用正确的方式使已挂载的文件系统脱机。为防止异常关机,在关闭系统、从驱动器中物理移除磁盘组或使磁盘脱机之前,必须将文件系统的当前状态写入磁盘(即“进行同步”)。

不一致性问题也可能是由硬件缺陷或者磁盘或控制器固件的问题导致的。在磁盘驱动器上,块随时都可能会损坏。此外,磁盘控制器可能无法正常工作。

接受一致性检查的 UFS 组件

本节介绍 fsck 命令将针对以下 UFS 文件系统组件执行的各种一致性检查:超级块、柱面组块、inode、间接块和数据块。

有关 UFS 文件系统结构的信息,请参见UFS 文件系统的柱面组结构

超级块检查

超级块存储摘要信息,它是 UFS 文件系统中最常损坏的组件。对文件系统 inode 或数据块进行的每个更改也会修改超级块。如果 CPU 暂停工作且最后一个命令不是 sync 命令,则几乎可以肯定超级块会被损坏。

将根据以下内容检查超级块是否存在不一致性问题:

文件系统大小和 Inode 列表大小检查

文件系统大小必须大于超级块和 inode 列表所用的块数。inode 数必须小于文件系统所允许的最大数。一个 inode 表示一个文件的所有信息。对于 fsck 命令,文件系统大小和布局信息是最关键的信息。无法实际检查这些大小,因为它们是在创建文件系统时静态确定的。但是,fsck 命令可以检查这些大小是否在合理的范围内。所有其他文件系统检查都要求这些大小正确。如果 fsck 命令检测到主超级块的静态参数已损坏,则会要求操作员指定备用超级块的位置。

有关 UFS 文件系统结构的更多信息,请参见UFS 文件系统的柱面组结构

空闲块检查

空闲块存储在柱面组块图中。fsck 命令检查标记为空闲的所有块是否未被任何文件请求。将所有块统计在内后,fsck 命令将检查空闲块数与 inode 所请求的块数之和是否等于文件系统中的总块数。如果块图出现任何错误,则 fsck 命令将重新构建它们,不考虑已分配的块。

超级块中的摘要信息包括文件系统中空闲块总数的计数。fsck 命令将此计数与它在文件系统中找到的空闲块数进行比较。如果这两个计数不一致,则 fsck 命令会将超级块中的计数替换为实际的空闲块计数。

空闲 Inode 检查

超级块中的摘要信息包含文件系统中空闲 inode 的计数。fsck 命令将此计数与它在文件系统中找到的空闲 inode 数进行比较。如果这两个计数不一致,则 fsck 命令会将超级块中的计数替换为实际的空闲 inode 计数。

Inode

将按顺序从 inode 2 开始检查 inode 列表(Inode 0 和 inode 1 是保留的)。将根据以下内容检查每个 inode 是否存在不一致性问题:

Inode 的格式和类型

每个 inode 都包含模式字,用于说明 inode 的类型和状态。Inode 可以是以下九种类型之一:

Inode 可能处于以下三种状态之一:

创建文件系统时,会保留固定数目的 inode。但是,仅在需要这些 inode 时才分配它们。已分配 inode 是指向文件的 inode。未分配 inode 不指向文件,因此它应该为空。部分分配状态表示 inode 未正确格式化。例如,如果因硬件故障而将错误数据写入 inode 列表,则 inode 将变为此状态。fsck 命令可以执行的唯一更正操作是清除 inode。

链接计数检查

每个 inode 都包含与其链接的目录项数的计数。fsck 命令通过从根 (/) 目录开始检查整个目录结构并计算每个 inode 的实际链接计数,验证每个 inode 的链接计数。

存储在 inode 中的链接计数和由 fsck 命令确定的实际链接计数之间的差异可能是以下三种类型之一:

重复块检查

每个 inode 都包含由 inode 请求的所有块的列表或指向列表的指针(间接块)。由于间接块由 inode 拥有,因此间接块的不一致性问题会直接影响拥有间接块的 inode。

fsck 命令将 inode 请求的每个块编号与已分配块的列表进行比较。如果另一个 inode 已请求某个块编号,则将该块编号放置在重复块列表中。否则,会将已分配块的列表更新为包括该块编号。

如果发现重复块,则 fsck 命令再次遍历 inode 列表,以查找请求每个重复块的其他 inode。fsck 命令不能肯定哪个 inode 出现错误。因此,fsck 命令会提示您选择应保留和应清除的 inode。请注意,inode 中的大量重复块可能是由于未将间接块写入文件系统而导致的。

坏块编号检查

fsck 命令检查 inode 请求的每个块编号,以确定其值是否大于文件系统中第一个数据块的值并小于最后一个数据块的值。如果块编号超出了此范围,则认为它是坏块编号。

inode 中的坏块编号可能是由于未将间接块写入文件系统而导致的。fsck 命令会提示您清除 inode。

Inode 大小检查

每个 inode 都包含它所引用的数据块数的计数。实际数据块的数目等于已分配数据块与间接块的和。fsck 命令计算数据块数,并将该块计数与 inode 请求的块数进行比较。如果 inode 包含的计数不正确,则 fsck 命令会提示您修复它。

每个 inode 都包含一个 64 位大小的字段。此字段说明与 inode 关联的文件中的字符数(数据字节)。粗略检查 inode 的大小字段是否一致时,会使用大小字段中所示的字符数,以计算应与 inode 关联的块数,然后将该块数与 inode 请求的实际块数进行比较。

间接块

间接块由 inode 拥有。因此,间接块的不一致性问题会影响拥有它的 inode。可以检查的不一致性问题如下:

对直接块也执行以上列出的一致性检查。

数据块

inode 可以直接或间接引用三种数据块。引用的所有块必须属于同一种类。这三种类型的数据块如下:

纯文本数据块包含存储在文件中的信息。符号链接数据块包含存储在符号链接中的路径名。目录数据块包含目录项。fsck 命令只能检查目录数据块的有效性。

通过 inode 的 mode 字段中的项,可以将目录与常规文件区分开。与目录关联的数据块包含目录项。检查目录数据块是否存在一致性问题涉及以下内容:

未分配目录检查

如果目录数据块中的 inode 编号指向未分配的 inode,则 fsck 命令删除该目录项。如果修改并写出包含新目录项的数据块,但未写出 inode,则可能出现此情况。如果突然关闭 CPU,则可能出现此情况。

错误 Inode 编号检查

如果目录项 inode 编号超出了 inode 列表的范围,则 fsck 命令删除该目录项。将错误数据写入目录数据块时,可能出现此情况。

错误 “.” 和 “..” 项检查

.” 的目录 inode 编号项必须是目录数据块中的第一项。目录 inode 编号必须引用自身。即,其值必须等于目录数据块的 inode 编号。

..” 的目录 inode 编号项必须是目录数据块中的第二项。目录的 inode 编号值必须等于父目录的 inode 编号或它自己的 inode 编号(如果该目录是根 (/) 目录)。

如果 “.” 和 “..” 的目录 inode 编号不正确,则 fsck 命令将它们替换为正确值。如果有多个硬链接指向一个目录,则将找到的第一个硬链接视为 “..” 应指向的实际父级。在这种情况下,fsck 命令建议您删除其他名称。

断开的目录

fsck 命令检查文件系统的常规连通性。如果找到未链接到文件系统的目录,则 fsck 命令将该目录链接到文件系统的 lost+found 目录。当 inode 已写入文件系统,但是对应的目录数据块未写入时,可能出现此情况。

常规数据块

与常规文件关联的数据块包含文件的内容。fsck 命令不会尝试检查常规文件的数据块内容的有效性。

fsck 摘要消息

以交互方式运行 fsck 命令且成功完成时,将显示与以下内容类似的消息:


# fsck /dev/rdsk/c0t0d0s7

** /dev/rdsk/c0t0d0s7

** Last Mounted on /export/home

** Phase 1 - Check Blocks and Sizes

** Phase 2 - Check Pathnames

** Phase 3 - Check Connectivity

** Phase 4 - Check Reference Counts

** Phase 5 - Check Cyl groups

2 files, 9 used, 2833540 free (20 frags, 354190 blocks, 0.0% fragmentation)

# 

# fsck /dev/rdsk/c0t0d0s7

** /dev/rdsk/c0t0d0s7

** Last Mounted on /export/home

** Phase 1 - Check Blocks and Sizes

** Phase 2 - Check Pathnames

** Phase 3a - Check Connectivity

** Phase 3b - Verify Shadows/ACLs

** Phase 4 - Check Reference Counts

** Phase 5 - Check Cylinder Groups 

2 files, 9 used, 2833540 free (20 frags, 354190 blocks, 0.0% fragmentation)

# 

fsck 输出的最后一行说明有关文件系统的以下信息:

# files

正在使用的 inode 数

# used

正在使用的段数

# free

未使用的段数

# frags

未使用的非块段数

# blocks

未使用的完整块数

% fragmentation

段百分比,其中:空闲段数 x 100/文件系统中的总段数

有关段的信息,请参见段大小