21.7.为磁盘设备添加卷标 ======================= 在系统初始化过程中,FreeBSD 内核会在发现设备时创建设备节点。这种探测设备的方法引起了一些问题。例如,如果一个新的磁盘设备是通过 USB 添加的呢?很可能一个闪存设备会被赋予 **da0** 的设备名,而原来的 **da0** 则被转移到 **da1**\ 。如果文件系统被列在 **/etc/fstab** 中,这将导致文件系统的挂载问题,也可能导致系统无法启动。 一个解决方案是按 SCSI 设备的链接拓扑进行命名,这样添加到 SCSI 卡上的新设备就会被发放未使用的设备号。但是,USB 设备可能会取代主 SCSI 磁盘呢?发生这种情况是因为 USB 设备通常在 SCSI 卡之前被探测到。一种解决办法是只在系统启动后插入这些设备。另一个方法是只使用单一的 ATA 驱动器,并且从不在 **/etc/fstab** 中列出 SCSI 设备。 一个更好的解决方案是使用 ``glabel`` 来标记磁盘设备,并在 **/etc/fstab** 中使用这些标签。由于 ``glabel`` 将标签存储在给定 provider 的最后一个扇区中,标签将在重启时保持不变。通过使用这个标签作为设备,文件系统可以始终被挂载,无论它是通过什么设备节点被访问的。 **注意** ``glabel`` 可以创建临时性和永久性的标签。只有永久标签在重启时是不变的。请参考 `glabel(8) `__ 了解更多关于标签之间区别的信息。 21.7.1.标签类型和例子 --------------------- 永久标签可以是一个通用标签或一个文件系统标签。永久文件系统标签可以用 `tunefs(8) `__ 或 `newfs(8) `__ 创建。这些类型的标签被创建在 **/dev** 的一个子目录下,并将根据文件系统的类型来命名。例如,UFS2 文件系统的标签将在 **/dev/ufs** 中创建。通用的永久标签可以用 ``glabel label`` 创建。这些标签不针对文件系统,将被创建在 **/dev/label** 中。 临时标签在下次重启时被销毁。这些标签是在 **/dev/label** 中创建的,适合于实验。可以使用 ``glabel create`` 来创建一个临时标签。 要为 UFS2 文件系统创建一个永久标签而不破坏任何数据,请执行以下命令: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # tunefs -L home /dev/da3 现在 **/dev/ufs** 中应该有一个标签,可以添加到 **/etc/fstab** 中: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session /dev/ufs/home /home ufs rw 2 2 .. **注意** 在运行 ``tunefs`` 时,禁止挂载文件系统。 现在可以挂载文件系统了: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # mount /home 从这时起,只要在启动时用 **/boot/loader.conf** 加载 **geom_label.ko** 内核模块,或者存在内核选项 ``GEOM_LABEL``\ ,设备节点就可以改变而不会对系统产生任何不良影响。 文件系统也可以通过使用 ``newfs`` 的 ``-L`` 参数来创建一个默认的标签。更多信息请参考 `newfs(8) `__\ 。 可以用下面的命令来销毁标签: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # glabel destroy home 下面的例子显示了如何给启动盘的分区贴标签。 **例 41.给启动盘上的分区贴标签** 通过对启动盘上的分区进行永久标记,系统应该能够继续正常启动,即使磁盘被移到另一个控制器上或者被转移到不同的系统。在这个例子中,假设使用的是一个 ATA 磁盘,目前系统识别为 **ad0**\ 。还假设使用了标准的 FreeBSD 分区方案,包括 **/** 、 **/var** 、 **/usr** 和 **/tmp**\ ,以及一个交换分区。 重新启动系统,在 `loader(8) `__ 提示下,按 ``4`` 键启动到单用户模式。然后输入以下命令: .. code:: shell-session # glabel label rootfs /dev/ad0s1a GEOM_LABEL: Label for provider /dev/ad0s1a is label/rootfs # glabel label var /dev/ad0s1d GEOM_LABEL: Label for provider /dev/ad0s1d is label/var # glabel label usr /dev/ad0s1f GEOM_LABEL: Label for provider /dev/ad0s1f is label/usr # glabel label tmp /dev/ad0s1e GEOM_LABEL: Label for provider /dev/ad0s1e is label/tmp # glabel label swap /dev/ad0s1b GEOM_LABEL: Label for provider /dev/ad0s1b is label/swap # exit 系统将继续以多用户启动。启动完成后,编辑 **/etc/fstab**\ ,用各自的标签替换传统的设备名称。最后的 **/etc/fstab** 将看起来像这样: .. code:: shell-session # Device Mountpoint FStype Options Dump Pass# /dev/label/swap none swap sw 0 0 /dev/label/rootfs / ufs rw 1 1 /dev/label/tmp /tmp ufs rw 2 2 /dev/label/usr /usr ufs rw 2 2 /dev/label/var /var ufs rw 2 2 现在可以重新启动系统了。如果一切顺利,它将正常出现,并显示挂载: .. code:: shell-session # mount /dev/label/rootfs on / (ufs, local) devfs on /dev (devfs, local) /dev/label/tmp on /tmp (ufs, local, soft-updates) /dev/label/usr on /usr (ufs, local, soft-updates) /dev/label/var on /var (ufs, local, soft-updates) `glabel(8) `__ 类支持 UFS 文件系统的标签类型,基于唯一的文件系统标识 ``ufsid``\ 。这些标签可以在 **/dev/ufsid** 中找到,并在系统启动时自动创建。\ **/etc/fstab** 可以使用 ``ufsid`` 标签来挂载分区。使用 ``glabel status`` 来接收文件系统和它们相应的 ``ufsid`` 标签的列表: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session % glabel status Name Status Components ufsid/486b6fc38d330916 N/A ad4s1d ufsid/486b6fc16926168e N/A ad4s1f 在上述例子中,\ **ad4s1d** 代表 **/var**\ ,而 **ad4s1f** 代表 **/usr**\ 。使用所示的 ``ufsid`` 值,现在可以用 **/etc/fstab** 中的以下条目来挂载这些分区: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session /dev/ufsid/486b6fc38d330916 /var ufs rw 2 2 /dev/ufsid/486b6fc16926168e /usr ufs rw 2 2 任何带有 ``ufsid`` 标签的分区都可以用这种方式挂载,不需要手动创建永久标签,同时还可以享受设备名称独立挂载的好处。