FreeBSD 使用手册
上一页 | 第21章 　Vinum 卷管理程序 | 下一页

# 21.9 使用 Vinum 作为根文件系统

如果文件系统使用完全镜像的 Vinum 配置， 有时也会希望根文件系统也作了镜像。 这种配置要比镜像其它文件系统麻烦一些， 因为：

- 根文件系统在引导过程中很早的时候就必须处于可用状态， 因此 Vinum 的基础设施在这一时刻就应该可用了。

- 包含根文件系统的卷， 同时也保存了系统的引导程序和内核， 因此它们必须能够被宿主系统的内建工具 (例如 PC 机的 BIOS) 识别， 而通常是没办法让它们了解 Vinum 的细节的。

下面几节中， 术语 “根卷” 标识包含根文件系统的 Vinum 卷。 把这个卷命名为 `"root"` 可能是个不错的主意， 不过从技术上说， 并不严格地要求这样做。 不过， 接下来的命令例子都使用这个名字。

## 21.9.1 及早启动 Vinum 以适应对根文件系统的要求

有许多关于它的尺度：

- Vinum 必须在启动时可以被内核使用。 因此， 在 第 21.8.1.1 节 中所介绍的方法， 也就无法适应这一任务的需要了。 在接下来的配置中， 也 不能 设置 `start_vinum` 参数。 第一种方法是通过将 Vinum 静态联编到内核中来实现， 这样， 它就在任何时候都可用了， 虽然一般并不需要这样。 另一种方法是通过 `/boot/loader` (第 12.3.3 节) 来尽早加载 vinum 内核模块， 这一操作发生在内核加载之前。 这可以通过将下面的配置：

      geom_vinum_load="YES"

  加入到 `/boot/loader.conf` 文件中来实现。

- 对 Gvinum 而言， 所有的启动过程都是在内核模块加载时自动进行的， 因此上面的操作， 也就是所要进行的全部工作了。

## 21.9.2 让基于 Vinum 的卷在引导时可以访问

因为目前的 FreeBSD 引导程序只有 7.5 KB 的代码， 并且已经承担了从 UFS 文件系统中读取文件 (例如 `/boot/loader`) 的重任， 因此完全没有办法再让它去分析 Vinum 配置数据中的 Vinum 结构， 并找到引导卷本身的信息。 因此， 需要一些技巧来为引导代码提供标准的 `"a"` 分区， 而它则包含了根文件系统。

要让这些得以实现， 根卷需要满足下面的条件：

- 根卷不能是条带卷或 RAID-5 卷。

- 根卷 plex 不能包含连接的子盘。

需要说明的是， 使用多个 plex， 每个 plex 都复制一份根文件系统的副本， 是需要而且是可行的。 然而， 引导过程只能使用这些副本中的一个来引导系统， 直到内核最终自行挂接根文件系统为止。 这些 plex 中的每个子盘， 在这之后会有它们自己的 `"a"` 分区， 以表达每一个可以引导的设备。 每一个 `"a"` 分区， 尽管并不需要和其它包含根卷的 plex 处于各自驱动器的同一位置。 但是， 这样创建 Vinum 卷使得镜像卷相互对称， 从而能够避免了混淆。

为了创建每一个根卷的 `"a"` 分区， 需要完成下面的操作：

1. 使用下面的命令来了解根卷成员子盘的位置 (从设备开始的偏移量) 和尺寸：

       # gvinum l -rv root

   需要注意的是， Vinum 偏移量和尺寸的单位是字节。 它们必须是 512 的整数倍， 才能得到 `bsdlabel` 命令所需的块号。

2. 在每一个根卷成员设备上， 执行命令：

       # bsdlabel -e devname

   这其中， 对于没有 slice (也就是 fdisk) 表的磁盘， `devname` 必须是磁盘的名字 (例如 `da0`)， 或者是 slice 的名字 (例如 `ad0s1`)。

   如果设备上已经有了 `"a"` 分区 (比如说， 包含 Vinum 之前的根文件系统)， 则应改为其它的名字， 以便继续访问 (如果需要的话)， 但它并不会继续用于启动系统。 注意， 活动的分区 (类似正挂接的根文件系统) 不能被改名， 因此， 要完成这项工作， 必须从 “Fixit” 盘启动， 或者分两步操作， 并 (在镜像情形中) 首先操作那些非引导盘。

   然后， 设备上 Vinum 分区的偏移 (如果有的话) 必须加到这个设备上根卷对应的子盘上。 其结果值， 将成为新的 `"a"` 分区的 `"offset"` 值。 这个分区的 `"size"` 值， 可以根据前面的配置计算得出。 `"fstype"` 应该是 `4.2BSD`。 `"fsize"`、 `"bsize"`， 以及 `"cpg"` 值， 则应与文件系统的实际情况匹配， 尽管在配置 Vinum 时并不重要。

   这样， 新的 `"a"` 分区， 将创建并覆盖这一设备上的 Vinum 分区的范围。 注意， `bsdlabel` 只有在 Vinum 分区的 fstype 被标记为 `"vinum"` 时， 才允许这样做。

3. 这就成了！ 所有的 `"a"` 分区现在都已存在， 而且是根卷的一份副本。 强烈建议您再次验证其结果， 方法是：

       # fsck -n /dev/devnamea

务必注意， 所有包含控制信息的文件， 都必须放到 Vinum 卷上的根文件系统。 在启动新的 Vinum 根卷时， 它们可能和实际在用的根文件系统不匹配。 因此， `/etc/fstab` 和 `/boot/loader.conf` 这两个文件需要特别地注意。

在下次重启时， 引导程序需要从新的基于 Vinum 的根文件系统中获取适当的控制信息， 并据此工作。 在内核初始化过程的结尾部分， 在所有的设备都被宣示之后， 如果显示了下面的信息， 则表示配置成功：

    Mounting root from ufs:/dev/gvinum/root

## 21.9.3 基于 Vinum 的根文件系统的配置范例

在 Vinum 根卷配置好之后， `gvinum l -rv root` 的输出可能类似下面的样子：

    ...
    Subdisk root.p0.s0:
            Size:        125829120 bytes (120 MB)
            State: up
            Plex root.p0 at offset 0 (0  B)
            Drive disk0 (/dev/da0h) at offset 135680 (132 kB)

    Subdisk root.p1.s0:
            Size:        125829120 bytes (120 MB)
            State: up
            Plex root.p1 at offset 0 (0  B)
            Drive disk1 (/dev/da1h) at offset 135680 (132 kB)

需要注意的值是 `135680`， 也就是偏移量 (相对于 `/dev/da0h` 分区)。 这相当于 `bsdlabel` 记法中的 265 个 512-字节的磁盘块。 类似地， 根卷的尺寸是 245760 个 512-字节的磁盘块。 `/dev/da1h` 中， 包含了根卷的第二个副本， 采用了同样的配置。

这些设备的 bsdlabel 类似下面的样子：

    ...
    8 partitions:
    #        size   offset    fstype   [fsize bsize bps/cpg]
      a:   245760      281    4.2BSD     2048 16384     0   # (Cyl.    0*- 15*)
      c: 71771688        0    unused        0     0         # (Cyl.    0 - 4467*)
      h: 71771672       16     vinum                        # (Cyl.    0*- 4467*)

可以看到， 伪装的 `"a"` 分区的 `"size"` 参数和前面的一样， 而 `"offset"` 参数则是 Vinum 分区 `"h"`， 以及设备中这一分区 (或 slice) 的偏移量之和。 这是一种典型的配置， 它能够避免在 第 21.9.4.3 节 中介绍的问题。 此外， 我们也看到整个 `"a"` 分区完全处于设备上包含了 Vinum 数据的 `"h"` 分区之中。

注意， 在上面的配置中， 整个设备都是 Vinum 专用的， 而且没有留下 Vinum 之前的根分区， 因为它永久性地成为了新建的 Vinum 配置中的一个子盘。

## 21.9.4 故障排除

如果遇到了问题， 则需要从中恢复的办法。 下面列出了一些常见的缺陷， 及其解决方法。

### 21.9.4.1 系统的引导程序加载了， 但无法启动

如果由于某种原因系统不再继续启动， 引导程序可以在 10-秒 倒计时的时候， 按 space 键来停止。 加载器变量 (例如 `vinum.autostart`) 可以通过使用 `show` 命令来查看， 并使用 `set` 和 `unset` 命令来设置。

如果遇到的问题是由于 Vinum 的内核模块没有列入预加载的列表， 而没有正确加载， 则简单使用 `load geom_vinum` 会有所帮助。

此后， 可以使用 `boot -as` 来继续启动过程。 选项 `-as` 会要求内核询问所挂接的根文件系统 (`-a`)， 并使引导过程在单用户模式停止 (`-s`)， 此时根文件系统是以只读方式挂接的。 这样， 即使只挂接了多 plex 卷中的一个 plex， 也不会引致 plex 之间数据不一致的问题。

当提示输入要挂接的根文件系统时， 可以输入任何一个包含根文件系统的设备。 如果正确地配置了 `/etc/fstab`， 则默认的应该是类似 `ufs:/dev/gvinum/root`。 一般可以使用类似 `ufs:da0d` 这样的设备来代替它， 因为它通常包括了 Vinum 之前的根文件系统。 需要注意的是， 如果在这里输入了 `"a"` 分区， 则它可能表达的实际上是 Vinum 根设备的一个子盘， 而在镜像式配置中， 这只会挂接镜像的根设备中的一个。 如果之后将这个文件系统以读写方式挂接， 则需要从 Vinum 根卷中删去其他的 plex， 否则这些卷中可能会包含不一致的数据。

### 21.9.4.2 只加载了主引导程序

如果 `/boot/loader` 加载失败， 而主引导程序加载正常 (在启动时， 屏幕最左边一列有一个旋转的线)， 则可以尝试在此时中断主引导程序的过程， 方法是按 space 键。 这将在引导的第二阶段暂停， 具体可以参见 第 12.3.2 节。 此时， 可以尝试从另一个分区， 例如原先包含根文件系统， 并不再叫作 `"a"` 的那个分区， 启动。

### 21.9.4.3 无法启动， 引导程序发生 panic

这种情况一般是由于 Vinum 安装过程中破坏了引导程序造成的。 不幸的是， Vinum 目前只在分区开始的地方保留了 4 KB 的空间， 之后就开始写 Vinum 头信息了。 然而， 目前第一阶段和第二阶段的引导程序， 加上 bsdlabel 嵌入的内容则需要 8 KB。 因此， 如果 Vinum 分区从偏移量 0 开始， 而这个 slice 或磁盘能够启动， 则 Vinum 的安装将毁掉引导程序。

类似地， 如果从上述情形中恢复， 例如， 从 “Fixit” 盘启动， 并通过 `bsdlabel -B` 按照 第 12.3.2 节 中介绍的方法来恢复引导程序， 则引导程序会覆盖掉 Vinum 头， 这样 Vinum 也就找不到它的磁盘了。 尽管这并不会真的毁掉 Vinum 的配置数据， 或者 Vinum 卷上的数据， 并且可以通过输入一模一样的 Vinum 配置数据来恢复， 但从这种状况中完全恢复是非常困难的。 要真正解决问题， 必须将整个 Vinum 分区向后移动至少 4 KB， 以便使 Vinum 头和系统的引导程序不再冲突。

上一页 | 起始页 | 下一页
配置 Vinum | 上一级 | 虚拟化

本文档和其它文档可从这里下载：ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题，请先阅读文档，如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.