我们可以使用文件系统层次结构标准 (FHS) 文档来帮助查找我们需要的实用程序的名称以及它们在目录结构中的位置。FHS/sbin目录列出了 fsck 和名为 fsck.* 的东西,用于检查文件系统。由于我们使用的是第二扩展 (ext2) 文件系统,因此 fsck.* 就变成了 fsck.ext2。挂载文件系统是使用/bin目录中的 mount 和 umount 命令完成的。但是,找不到自动挂载本地文件系统的脚本名称。在大多数系统中,这种类型的脚本都在/etc目录中,但虽然 FHS 列出了对/etc的要求,但它目前没有对启动脚本提出建议。几个 GNU/Linux 发行版使用/etc/init.d作为保存启动脚本的位置,因此我们将把我们的文件系统挂载脚本放在那里。
在上一章中,我们使用手册页来帮助我们查找源代码。在本章中,我们将使用一个名为 Linux Software Map (LSM) 的工具。LSM 是一个 GNU/Linux 软件数据库,它跟踪包名称、作者、构成包的二进制文件的名称和下载站点等信息。使用 LSM 搜索引擎,我们可以使用命令名称作为关键字来定位软件包。
如果我们搜索 Ibiblio 的 Linux Software Map (LSM),网址为 http://www.ibiblio.org/pub/Linux/,关键字为 "fsck",我们会得到大量的匹配结果。由于我们使用的是第二扩展文件系统,简称 ext2,我们可以使用 "ext2" 作为关键字来细化搜索。向 LSM 搜索引擎提供这两个关键字会找到一个名为 e2fsprogs 的软件包。查看 e2fsprogs 的 LSM 条目,我们发现该软件包包含实用程序 e2fsck、mke2fs、dumpe2fs、fsck 等。我们还发现 e2fsprogs 的 LSM 条目已经有一段时间没有更新了。几乎肯定有更新的版本。另一个查找源代码的好 Internet 资源是 SourceForge,网址为 http://sourceforge.net/。在 SourceForge 搜索引擎中使用关键字 "e2fsprogs" 会找到更新版本的 e2fsprogs。
找到 fsck 是一次非常有趣的冒险,但现在我们可以继续寻找 mount 和 umount。在 LSM 上搜索会得到很多匹配结果,但大多数都指向一个名为 util-linux 的软件包的各种版本。我们所要做的就是滚动并选择最新版本。util-linux 的 LSM 条目列出了很多除了 mount 和 umount 之外的实用程序。我们绝对应该扫描列表,看看 util-linux 的其他命令是否出现在 FHS 对/bin和/sbin.
的要求中。下面是我们到目前为止收集的软件包列表以及与 FHS 匹配的实用程序。
e2fsprogs -- fsck, fsck.ext2 (e2fsck), mkfs.ext2 (mke2fs)
util-linux -- dmesg, getty (agetty), kill, login, mount, swapon, umount
现在我们有了 fsck 和 mount 命令,我们需要想出一个 shell 脚本来自动检查和挂载本地文件系统。一种简单的方法是编写一个简短的两行脚本,它调用 fsck,然后调用 mount。但是,如果文件系统不干净怎么办?系统绝对不应该尝试挂载损坏的文件系统。因此,我们需要设计一种方法来在挂载文件系统之前确定其状态。fsck 的手册页提供了一些关于如何使用返回代码来完成此操作的见解。基本上,如果 fsck 返回代码 0 或 1,则表示文件系统正常,返回代码 2 或更大表示需要某种手动干预。一个简单的 if-then 语句可以评估 fsck 返回代码,以确定是否应挂载文件系统。有关编写 shell 脚本的帮助,我们可以参考 BASH(1) 手册页和 Advanced-BASH-Scripting-Guide。这两个参考资料都可以从 Linux Documentation Project 网站免费获得,网址为 http://www.tldp.org/。
最后要做的是确定是否需要二进制文件以外的其他文件。我们在项目的上一阶段了解了如何使用 ldd 检查库依赖项,我们也将使用它来检查本阶段的实用程序。还有一些其他文件是 fsck 和 mount 需要的,fsck(8) 和 mount(8) 手册页提供了一些关于这些文件的见解。有/etc/fstab,其中列出了设备及其挂载点,/etc/mtab,用于跟踪已挂载的内容,以及许多/dev文件,这些文件代表各种磁盘。我们需要包含所有这些才能使一切正常工作。
该/etc/fstab文件只是一个简单的文本文件,可以使用任何编辑器创建。我们需要为根文件系统和 proc 文件系统添加条目。有关此文件格式的信息可以在 fstab(5) 手册页中找到,或者通过查看任何流行的 GNU/Linux 发行版上的/etc/fstab文件来找到。
该/etc/mtab文件提出了一个独特的挑战,因为它不包含像fstab这样的静态信息。该mtab文件跟踪已挂载的文件系统,因此其内容会不时更改。我们特别感兴趣的是mtab在系统首次启动时、在任何文件系统挂载之前的状态。此时/etc/mtab应该是空的,因此我们需要配置一个启动脚本来创建一个空的/etc/mtab,然后再挂载任何文件系统。但是不可能在/etc目录中创建任何文件,因为/在启动时是只读的。这造成了一个悖论。我们无法创建一个空的mtab,因为/文件系统未挂载为可写,并且在我们创建空的mtab之前,我们不应该挂载任何文件系统。为了避开这个问题,我们需要做以下事情:
重新挂载/为读写,但使用-n选项,以便 mount 不会尝试在/etc/mtab中写入条目,此时它是只读的。
现在文件系统是可写的,创建一个空的/etc/mtab文件。
重新挂载/再次重新挂载为读写,这次使用-f选项,以便将条目写入/etc/mtab,但实际上/不会第二次挂载。