第 20 章。存储

20.1. 概述

本章涵盖了在 FreeBSD 中使用磁盘和存储介质。 这包括 SCSI 和 IDE 磁盘、CD 和 DVD 介质、内存支持磁盘和 USB 存储设备。

阅读完本章后,您将了解

  • 如何将额外的硬盘添加到 FreeBSD 系统。

  • 如何在 FreeBSD 上扩展磁盘分区的大小。

  • 如何配置 FreeBSD 以使用 USB 存储设备。

  • 如何在 FreeBSD 系统上使用 CD 和 DVD 介质。

  • 如何使用 FreeBSD 下提供的备份程序。

  • 如何设置内存磁盘。

  • 什么是文件系统快照以及如何有效地使用它们。

  • 如何使用配额限制磁盘空间使用量。

  • 如何加密磁盘和交换以保护它们免受攻击者攻击。

  • 如何配置高可用性存储网络。

阅读本章之前,您应该

20.2. 添加磁盘

本节介绍如何在当前只有一块驱动器的机器上添加一块新的 SATA 磁盘。 首先,关闭计算机并按照计算机、控制器和驱动器制造商的说明将驱动器安装到计算机中。 重新启动系统并成为 root 用户。

检查 /var/run/dmesg.boot 以确保找到了新磁盘。 在此示例中,新添加的 SATA 驱动器将显示为 ada1

在此示例中,将在新磁盘上创建一个单一大型分区。 与较旧且不太通用的 MBR 方案相比,将优先使用 GPT 分区方案。

如果要添加的磁盘不是空白的,可以使用 gpart delete 删除旧的分区信息。 有关详细信息,请参阅 gpart(8)

创建分区方案,然后添加单个分区。 为了提高具有更大硬件块大小的新型磁盘的性能,分区与一个兆字节边界对齐

# gpart create -s GPT ada1
# gpart add -t freebsd-ufs -a 1M ada1

根据使用情况,可能需要多个较小的分区。 有关创建小于整个磁盘的分区选项,请参阅 gpart(8)

可以使用 gpart show 查看磁盘分区信息

% gpart show ada1
=>        34  1465146988  ada1  GPT  (699G)
          34        2014        - free -  (1.0M)
        2048  1465143296     1  freebsd-ufs  (699G)
  1465145344        1678        - free -  (839K)

在新的磁盘上的新分区中创建一个文件系统

# newfs -U /dev/ada1p1

创建一个空目录作为 挂载点,一个在原始磁盘文件系统中挂载新磁盘的位置

# mkdir /newdisk

最后,在 /etc/fstab 中添加一个条目,以便新磁盘在启动时自动挂载

/dev/ada1p1	/newdisk	ufs	rw	2	2

可以手动挂载新磁盘,无需重新启动系统

# mount /newdisk

20.3. 调整大小和扩展磁盘

磁盘的容量可以增加,而无需对已存在的数据进行任何更改。 这在虚拟机中很常见,当虚拟磁盘变得太小时会扩大。 有时将磁盘映像写入 USB 记忆棒,但没有使用全部容量。 在这里,我们描述了如何调整磁盘内容的大小或 扩展 以利用增加的容量。

通过检查 /var/run/dmesg.boot 确定要调整大小的磁盘的设备名称。 在此示例中,系统中只有一块 SATA 磁盘,因此驱动器将显示为 ada0

列出磁盘上的分区以查看当前配置

# gpart show ada0
=>      34  83886013  ada0  GPT  (48G) [CORRUPT]
        34       128     1  freebsd-boot  (64k)
       162  79691648     2  freebsd-ufs  (38G)
  79691810   4194236     3  freebsd-swap  (2G)
  83886046         1        - free -  (512B)

如果磁盘使用 GPT 分区方案格式化,它可能会显示为“损坏”,因为 GPT 备份分区表不再位于驱动器的末尾。 使用 gpart 修复备份分区表

# gpart recover ada0
ada0 recovered

现在,磁盘上的额外空间可用于新分区,或者可以扩展现有分区

# gpart show ada0
=>       34  102399933  ada0  GPT  (48G)
         34        128     1  freebsd-boot  (64k)
        162   79691648     2  freebsd-ufs  (38G)
   79691810    4194236     3  freebsd-swap  (2G)
   83886046   18513921        - free -  (8.8G)

分区只能调整大小到连续的可用空间。 在这里,磁盘上的最后一个分区是交换分区,但需要调整大小的是第二个分区。 交换分区只包含临时数据,因此可以安全地卸载、删除,然后在调整第二个分区的大小后重新创建第三个分区。

禁用交换分区

# swapoff /dev/ada0p3

从磁盘 ada0 中删除第三个分区(由 -i 标志指定)。

# gpart delete -i 3 ada0
ada0p3 deleted
# gpart show ada0
=>       34  102399933  ada0  GPT  (48G)
         34        128     1  freebsd-boot  (64k)
        162   79691648     2  freebsd-ufs  (38G)
   79691810   22708157        - free -  (10G)

在修改已挂载文件系统的分区表时存在数据丢失的风险。 最好是在从实时 CD-ROM 或 USB 设备运行时对未挂载的文件系统执行以下步骤。 但是,如果绝对必要,可以在禁用 GEOM 安全功能后调整挂载的文件系统的大小

# sysctl kern.geom.debugflags=16

调整分区大小,留出空间重新创建所需大小的交换分区。 要调整大小的分区使用 -i 指定,所需的新大小使用 -s 指定。 可选地,使用 -a 控制分区的对齐方式。 这只会修改分区的尺寸。 分区中的文件系统将在单独的步骤中扩展。

# gpart resize -i 2 -s 47G -a 4k ada0
ada0p2 resized
# gpart show ada0
=>       34  102399933  ada0  GPT  (48G)
         34        128     1  freebsd-boot  (64k)
        162   98566144     2  freebsd-ufs  (47G)
   98566306    3833661        - free -  (1.8G)

重新创建交换分区并激活它。 如果没有使用 -s 指定大小,则使用所有剩余空间

# gpart add -t freebsd-swap -a 4k ada0
ada0p3 added
# gpart show ada0
=>       34  102399933  ada0  GPT  (48G)
         34        128     1  freebsd-boot  (64k)
        162   98566144     2  freebsd-ufs  (47G)
   98566306    3833661     3  freebsd-swap  (1.8G)
# swapon /dev/ada0p3

扩展 UFS 文件系统以使用调整大小的分区的新容量

# growfs /dev/ada0p2
Device is mounted read-write; resizing will result in temporary write suspension for /.
It's strongly recommended to make a backup before growing the file system.
OK to grow file system on /dev/ada0p2, mounted on /, from 38GB to 47GB? [Yes/No] Yes
super-block backups (for fsck -b #) at:
 80781312, 82063552, 83345792, 84628032, 85910272, 87192512, 88474752,
 89756992, 91039232, 92321472, 93603712, 94885952, 96168192, 97450432

如果文件系统是 ZFS,则通过使用 -e 运行 online 子命令来触发调整大小

# zpool online -e zroot /dev/ada0p2

分区及其上的文件系统现在都已调整大小,以使用新可用磁盘空间。

20.4. USB 存储设备

许多外部存储解决方案(如硬盘驱动器、USB 拇指驱动器和 CD 和 DVD 刻录机)使用通用串行总线 (USB)。 FreeBSD 提供对 USB 1.x、2.0 和 3.0 设备的支持。

USB 3.0 支持与某些硬件不兼容,包括 Haswell (Lynx point) 芯片组。 如果 FreeBSD 启动时显示 failed with error 19 消息,请在系统 BIOS 中禁用 xHCI/USB3。

对 USB 存储设备的支持已内置到 GENERIC 内核中。 对于自定义内核,请确保内核配置文件中存在以下行

device scbus	# SCSI bus (required for ATA/SCSI)
device da	# Direct Access (disks)
device pass	# Passthrough device (direct ATA/SCSI access)
device uhci	# provides USB 1.x support
device ohci	# provides USB 1.x support
device ehci	# provides USB 2.0 support
device xhci	# provides USB 3.0 support
device usb	# USB Bus (required)
device umass	# Disks/Mass storage - Requires scbus and da
device cd	# needed for CD and DVD burners

FreeBSD 使用 umass(4) 驱动程序,该驱动程序使用 SCSI 子系统来访问 USB 存储设备。 由于任何 USB 设备都将被系统视为 SCSI 设备,因此如果 USB 设备是 CD 或 DVD 刻录机,请 不要 在自定义内核配置文件中包含 device atapicam

本节的其余部分演示了如何验证 FreeBSD 是否识别 USB 存储设备以及如何配置设备以便可以使用它。

20.4.1. 设备配置

要测试 USB 配置,请插入 USB 设备。 使用 dmesg 确认驱动器出现在系统消息缓冲区中。 它应该类似于:

umass0: <STECH Simple Drive, class 0/0, rev 2.00/1.04, addr 3> on usbus0
umass0:  SCSI over Bulk-Only; quirks = 0x0100
umass0:4:0:-1: Attached to scbus4
da0 at umass-sim0 bus 0 scbus4 target 0 lun 0
da0: <STECH Simple Drive 1.04> Fixed Direct Access SCSI-4 device
da0: Serial Number WD-WXE508CAN263
da0: 40.000MB/s transfers
da0: 152627MB (312581808 512 byte sectors: 255H 63S/T 19457C)
da0: quirks=0x2<NO_6_BYTE>

品牌、设备节点 (da0)、速度和尺寸将根据设备的不同而有所不同。

由于 USB 设备被视为 SCSI 设备,因此可以使用 camcontrol 列出连接到系统的 USB 存储设备

# camcontrol devlist
<STECH Simple Drive 1.04>          at scbus4 target 0 lun 0 (pass3,da0)

或者,可以使用 usbconfig 列出设备。 有关此命令的更多信息,请参阅 usbconfig(8)

# usbconfig
ugen0.3: <Simple Drive STECH> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (2mA)

如果设备尚未格式化,请参阅 添加磁盘 以了解有关如何在 USB 驱动器上格式化和创建分区的说明。 如果驱动器附带文件系统,则可以使用 “挂载和卸载文件系统” 中的说明由 root 用户挂载。

允许不受信任的用户挂载任意介质(通过启用 vfs.usermount,如下所述)从安全角度来看不应被视为安全。 大多数文件系统并非旨在防范恶意设备。

要使设备可由普通用户挂载,一种解决方案是使用 pw(8) 使设备的所有用户成为 operator 组的成员。 接下来,确保 operator 能够读取和写入设备,方法是在 /etc/devfs.rules 中添加以下行

[localrules=5]
add path 'da*' mode 0660 group operator

如果系统中还安装了内部 SCSI 磁盘,请更改第二行如下

add path 'da[3-9]*' mode 0660 group operator

这将排除前三个 SCSI 磁盘 (da0da2) 属于 operator 组。 将 3 替换为内部 SCSI 磁盘的数量。 有关此文件的更多信息,请参阅 devfs.rules(5)

接下来,在 /etc/rc.conf 中启用规则集

devfs_system_ruleset="localrules"

然后,通过在 /etc/sysctl.conf 中添加以下行来指示系统允许普通用户挂载文件系统

vfs.usermount=1

由于这只有在下次重启后才会生效,因此请使用 sysctl 立即设置此变量

# sysctl vfs.usermount=1
vfs.usermount: 0 -> 1

最后一步是创建一个目录,用于挂载文件系统。 此目录需要由要挂载文件系统的用户拥有。 一种方法是让 root 创建一个由该用户拥有的子目录,例如 /mnt/username。 在以下示例中,请将 username 替换为用户的登录名,将 usergroup 替换为用户的首要组

# mkdir /mnt/username
# chown username:usergroup /mnt/username

假设插入了 USB 拇指驱动器,并且出现了设备 /dev/da0s1。 如果设备使用 FAT 文件系统格式化,则用户可以使用以下命令挂载它

% mount -t msdosfs -o -m=644,-M=755 /dev/da0s1 /mnt/username

在拔下设备之前,必须先卸载它

% umount /mnt/username

移除设备后,系统消息缓冲区将显示类似于以下内容的消息

umass0: at uhub3, port 2, addr 3 (disconnected)
da0 at umass-sim0 bus 0 scbus4 target 0 lun 0
da0: <STECH Simple Drive 1.04> s/n WD-WXE508CAN263          detached
(da0:umass-sim0:0:0:0): Periph destroyed

20.4.2. 自动挂载可移动介质

通过在 /etc/auto_master 中取消注释此行,可以自动挂载 USB 设备

/media		-media		-nosuid

然后将这些行添加到 /etc/devd.conf

notify 100 {
	match "system" "GEOM";
	match "subsystem" "DEV";
	action "/usr/sbin/automount -c";
};

如果 autofs(5)devd(8) 正在运行,请重新加载配置

# service automount restart
# service devd restart

通过将此行添加到 /etc/rc.conf,可以将 autofs(5) 设置为在启动时启动

autofs_enable="YES"

autofs(5) 需要 devd(8) 启用,默认情况下它是启用的。

立即启动服务,使用

# service automount start
# service automountd start
# service autounmountd start
# service devd start

每个可以自动挂载的文件系统在 /media/ 中显示为一个目录。目录以文件系统标签命名。如果标签丢失,则目录以设备节点命名。

文件系统在第一次访问时被透明地挂载,并在一段时间不活动后被卸载。自动挂载的驱动器也可以手动卸载

# automount -fu

此机制通常用于内存卡和 USB 存储棒。它可以与任何块设备一起使用,包括光驱或 iSCSI LUN。

20.5. 创建和使用 CD 介质

光盘 (CD) 介质提供了一些特性,将它们与传统磁盘区分开来。它们的设计使它们可以连续读取,而无需延迟以在磁道之间移动磁头。虽然 CD 介质确实有磁道,但这些磁道指的是要连续读取的数据部分,而不是磁盘的物理属性。ISO 9660 文件系统旨在处理这些差异。

FreeBSD Ports Collection 提供了几种实用程序,用于刻录和复制音频和数据 CD。本章演示了几个命令行实用程序的使用。对于具有图形界面的 CD 刻录软件,请考虑安装 sysutils/xcdroastsysutils/k3b 软件包或端口。

20.5.1. 支持的设备

GENERIC 内核提供对 SCSI、USB 和 ATAPICD 阅读器和刻录器的支持。如果使用自定义内核,则内核配置文件中需要存在的选项因设备类型而异。

对于 SCSI 刻录机,请确保以下选项存在

device scbus	# SCSI bus (required for ATA/SCSI)
device da	# Direct Access (disks)
device pass	# Passthrough device (direct ATA/SCSI access)
device cd	# needed for CD and DVD burners

对于 USB 刻录机,请确保以下选项存在

device scbus	# SCSI bus (required for ATA/SCSI)
device da	# Direct Access (disks)
device pass	# Passthrough device (direct ATA/SCSI access)
device cd	# needed for CD and DVD burners
device uhci	# provides USB 1.x support
device ohci	# provides USB 1.x support
device ehci	# provides USB 2.0 support
device xhci	# provides USB 3.0 support
device usb	# USB Bus (required)
device umass	# Disks/Mass storage - Requires scbus and da

对于 ATAPI 刻录机,请确保以下选项存在

device ata	# Legacy ATA/SATA controllers
device scbus	# SCSI bus (required for ATA/SCSI)
device pass	# Passthrough device (direct ATA/SCSI access)
device cd	# needed for CD and DVD burners

在 10.x 之前的 FreeBSD 版本中,如果刻录机是 ATAPI 设备,则还需要在内核配置文件中添加此行

device atapicam

或者,可以通过将以下行添加到 /boot/loader.conf 来在启动时加载此驱动程序

atapicam_load="YES"

这将需要重新启动系统,因为此驱动程序只能在启动时加载。

要验证 FreeBSD 是否识别了设备,请运行 dmesg 并查找设备的条目。在 10.x 之前的系统中,输出第一行的设备名称将是 acd0 而不是 cd0

% dmesg | grep cd
cd0 at ahcich1 bus 0 scbus1 target 0 lun 0
cd0: <HL-DT-ST DVDRAM GU70N LT20> Removable CD-ROM SCSI-0 device
cd0: Serial Number M3OD3S34152
cd0: 150.000MB/s transfers (SATA 1.x, UDMA6, ATAPI 12bytes, PIO 8192bytes)
cd0: Attempt to query device size failed: NOT READY, Medium not present - tray closed

20.5.2. 刻录 CD

在 FreeBSD 中,可以使用 cdrecord 刻录 CD。此命令与 sysutils/cdrtools 软件包或端口一起安装。

虽然 cdrecord 有很多选项,但基本用法很简单。指定要刻录的 ISO 文件的名称,以及如果系统有多个刻录机设备,则指定要使用的设备的名称

# cdrecord dev=device imagefile.iso

要确定刻录机的设备名称,请使用 -scanbus,它可能会产生类似以下结果

# cdrecord -scanbus
ProDVD-ProBD-Clone 3.00 (amd64-unknown-freebsd10.0) Copyright (C) 1995-2010 Jörg Schilling
Using libscg version 'schily-0.9'
scsibus0:
        0,0,0     0) 'SEAGATE ' 'ST39236LW       ' '0004' Disk
        0,1,0     1) 'SEAGATE ' 'ST39173W        ' '5958' Disk
        0,2,0     2) *
        0,3,0     3) 'iomega  ' 'jaz 1GB         ' 'J.86' Removable Disk
        0,4,0     4) 'NEC     ' 'CD-ROM DRIVE:466' '1.26' Removable CD-ROM
        0,5,0     5) *
        0,6,0     6) *
        0,7,0     7) *
scsibus1:
        1,0,0   100) *
        1,1,0   101) *
        1,2,0   102) *
        1,3,0   103) *
        1,4,0   104) *
        1,5,0   105) 'YAMAHA  ' 'CRW4260         ' '1.0q' Removable CD-ROM
        1,6,0   106) 'ARTEC   ' 'AM12S           ' '1.06' Scanner
        1,7,0   107) *

找到 CD 刻录机的条目,并将用逗号分隔的三个数字作为 dev 的值。在本例中,雅马哈刻录机设备是 1,5,0,因此指定该设备的适当输入是 dev=1,5,0。有关指定此值的其它方法以及有关写入音频轨道和控制写入速度的信息,请参阅 cdrecord 的手册页。

或者,运行以下命令以获取刻录机的设备地址

# camcontrol devlist
<MATSHITA CDRW/DVD UJDA740 1.00>   at scbus1 target 0 lun 0 (cd0,pass0)

使用 scbustargetlun 的数值。在本例中,1,0,0 是要使用的设备名称。

20.5.3. 将数据写入 ISO 文件系统

为了生成数据 CD,在将构成 CD 上磁道的数据文件刻录到 CD 之前,必须先准备这些文件。在 FreeBSD 中,sysutils/cdrtools 安装了 mkisofs,它可以用来生成 ISO 9660 文件系统,它是 UNIX® 文件系统中目录树的映像。最简单的用法是指定要创建的 ISO 文件的名称以及要放入 ISO 9660 文件系统的文件的路径

# mkisofs -o imagefile.iso /path/to/tree

此命令将指定的路径中的文件名映射到符合标准 ISO 9660 文件系统限制的名称,并将排除不符合 ISO 文件系统标准的文件。

许多选项可用于克服标准强加的限制。特别是,-R 启用了 UNIX® 系统常见的 Rock Ridge 扩展,而 -J 启用了 Microsoft® 系统使用的 Joliet 扩展。

对于仅在 FreeBSD 系统上使用的 CD,可以使用 -U 来禁用所有文件名限制。当与 -R 一起使用时,它会生成一个与指定 FreeBSD 树完全相同的文件系统映像,即使它违反了 ISO 9660 标准。

最后,通用选项是 -b。它用于指定引导映像的位置,用于生成“El Torito”可引导 CD。此选项接受一个参数,该参数是 CD 上正在写入的树顶部的引导映像的路径。默认情况下,mkisofs 在“软盘仿真”模式下创建 ISO 映像,因此需要引导映像的大小正好为 1200、1440 或 2880 KB。一些引导加载程序(如 FreeBSD 分发介质使用的引导加载程序)不使用仿真模式。在这种情况下,应使用 -no-emul-boot。因此,如果 /tmp/myboot 包含一个可引导的 FreeBSD 系统,其引导映像在 /tmp/myboot/boot/cdboot 中,则此命令将生成 /tmp/bootable.iso

# mkisofs -R -no-emul-boot -b boot/cdboot -o /tmp/bootable.iso /tmp/myboot

生成的 ISO 映像可以用以下命令作为内存磁盘挂载

# mdconfig -a -t vnode -f /tmp/bootable.iso -u 0
# mount -t cd9660 /dev/md0 /mnt

然后可以验证 /mnt/tmp/myboot 是否相同。

mkisofs 有许多其他选项可用于微调其行为。有关详细信息,请参阅 mkisofs(8)

可以使用 dd 将数据 CD 复制到一个映像文件,该文件在功能上等效于使用 mkisofs 创建的映像文件。为此,请使用设备名称作为输入文件,并使用要创建的 ISO 的名称作为输出文件

# dd if=/dev/cd0 of=file.iso bs=2048

生成的映像文件可以像在 刻录 CD 中描述的那样刻录到 CD 上。

20.5.4. 使用数据 CD

将 ISO 刻录到 CD 后,可以通过指定文件系统类型、包含 CD 的设备的名称以及现有的挂载点来挂载它

# mount -t cd9660 /dev/cd0 /mnt

由于 mount 假设文件系统是 ufs 类型,因此如果在挂载数据 CD 时未包含 -t cd9660,将出现“不正确的超级块”错误。

虽然任何数据 CD 都可以用这种方式挂载,但具有某些 ISO 9660 扩展的磁盘可能表现怪异。例如,Joliet 磁盘将所有文件名存储为双字节 Unicode 字符。如果一些非英语字符显示为问号,请使用 -C 指定本地字符集。有关更多信息,请参阅 mount_cd9660(8)

为了使用 -C 来进行这种字符转换,内核需要加载 cd9660_iconv.ko 模块。这可以通过将以下行添加到 loader.conf

cd9660_iconv_load="YES"

然后重新启动机器,或者通过使用 kldload 直接加载模块来完成。

有时,在尝试挂载数据 CD 时,会显示“设备未配置”。这通常意味着 CD 驱动器未检测到托盘中的磁盘,或者驱动器在总线上不可见。CD 驱动器可能需要几秒钟才能检测到介质,所以请耐心等待。

有时,SCSICD 驱动器可能会被错过,因为它没有足够的时间来响应总线复位。要解决此问题,可以创建一个自定义内核,它会增加默认的 SCSI 延迟。将以下选项添加到自定义内核配置文件中,并使用 “构建和安装自定义内核” 中的说明重新构建内核

options SCSI_DELAY=15000

这会告诉 SCSI 总线在启动期间暂停 15 秒,以使 CD 驱动器有尽可能多的机会来响应总线复位。

可以直接将文件刻录到 CD 上,而无需创建 ISO 9660 文件系统。这被称为刻录原始数据 CD,有些人出于备份目的这样做。

此类磁盘无法像普通数据 CD 一样挂载。为了检索刻录到此类 CD 上的数据,必须从原始设备节点读取数据。例如,以下命令将提取位于第二个 CD 设备上的压缩 tar 文件到当前工作目录

# tar xzvf /dev/cd1

为了挂载数据 CD,必须使用 mkisofs 编写数据。

20.5.5. 复制音频 CD

要复制音频 CD,请从 CD 中提取音频数据到一系列文件中,然后将这些文件写入空白 CD。

复制音频 CD 描述了如何复制和刻录音频 CD。如果 FreeBSD 版本小于 10.0 且设备是 ATAPI,则必须首先使用 支持的设备 中的说明加载 atapicam 模块。

步骤:复制音频 CD
  1. 软件包或端口 sysutils/cdrtools 安装了 cdda2wav。此命令可用于提取所有音频轨道,并将每个轨道写入当前工作目录中的单独 WAV 文件。

    % cdda2wav -vall -B -Owav

    如果系统中只有一个 CD 设备,则不需要指定设备名称。请参考 cdda2wav 手册页了解如何指定设备,以及有关此命令的其他可用选项的更多信息。

  2. 使用 cdrecord 编写 .wav 文件。

    % cdrecord -v dev=2,0 -dao -useinfo  *.wav

    确保 2,0 设置正确,如 刻录 CD 中所述。

20.6. 创建和使用 DVD 介质

与 CD 相比,DVD 是下一代光学存储技术。DVD 比任何 CD 都能存储更多数据,并且是视频发布的标准。

可为可刻录 DVD 定义五种物理可刻录格式。

  • DVD-R:这是第一种可用的 DVD 可刻录格式。DVD-R 标准由 DVD 论坛 定义。此格式是写一次。

  • DVD-RW:这是 DVD-R 标准的可重写版本。DVD-RW 可以重写大约 1000 次。

  • DVD-RAM:这是一种可重写格式,可以看作是可移动硬盘。但是,这种介质与大多数 DVD-ROM 驱动器和 DVD-Video 播放器不兼容,因为只有少数 DVD 刻录机支持 DVD-RAM 格式。有关 DVD-RAM 使用的更多信息,请参考 使用 DVD-RAM

  • DVD+RW:这是一种由 DVD+RW 联盟 定义的可重写格式。DVD+RW 可以重写大约 1000 次。

  • DVD+R:此格式是 DVD+RW 格式的写一次变体。

单层可刻录 DVD 可以存储高达 4,700,000,000 字节的数据,实际上是 4.38 GB 或 4485 MB,因为 1 千字节是 1024 字节。

必须区分物理介质和应用程序。例如,DVD-Video 是一种特定的文件布局,可以写入任何可刻录 DVD 物理介质,如 DVD-R、DVD+R 或 DVD-RW。在选择介质类型之前,请确保刻录机和 DVD-Video 播放器都与所考虑的介质兼容。

20.6.1. 配置

要执行 DVD 刻录,请使用 growisofs(1)。此命令是 sysutils/dvd+rw-tools 实用程序的一部分,支持所有 DVD 介质类型。

这些工具使用 SCSI 子系统访问设备,因此必须加载 ATAPI/CAM 支持 或将其静态编译到内核中。如果刻录机使用 USB 接口,则不需要此支持。有关 USB 设备配置的更多详细信息,请参考 USB 存储设备

还必须为 ATAPI 设备启用 DMA 访问,方法是在 /boot/loader.conf 中添加以下行

hw.ata.atapi_dma="1"

在尝试使用 dvd+rw-tools 之前,请查阅 硬件兼容性说明

对于图形用户界面,请考虑使用 sysutils/k3b,它为 growisofs(1) 和许多其他刻录工具提供了用户友好的界面。

20.6.2. 刻录数据 DVD

由于 growisofs(1)mkisofs 的前端,它将调用 mkisofs(8) 来创建文件系统布局并在 DVD 上执行写入。这意味着在刻录过程之前不需要创建数据的映像。

要将 /path/to/data 中的数据刻录到 DVD+R 或 DVD-R,请使用以下命令

# growisofs -dvd-compat -Z /dev/cd0 -J -R /path/to/data

在此示例中,-J -R 被传递给 mkisofs(8) 以创建具有 Joliet 和 Rock Ridge 扩展的 ISO 9660 文件系统。有关更多详细信息,请参考 mkisofs(8)

对于初始会话录制,-Z 用于单会话和多会话。将 /dev/cd0 替换为 DVD 设备的名称。使用 -dvd-compat 表示磁盘将被关闭,并且录制将不可追加。这也应该提供与 DVD-ROM 驱动器更好的介质兼容性。

要刻录预先制作的映像,例如 imagefile.iso,请使用

# growisofs -dvd-compat -Z /dev/cd0=imagefile.iso

写入速度应根据所使用的介质和驱动器自动检测和设置。要强制写入速度,请使用 -speed=。有关示例用法,请参考 growisofs(1)

为了支持大于 4.38GB 的工作文件,必须通过将 -udf -iso-level 3 传递给 mkisofs(8) 以及所有相关程序(如 growisofs(1))来创建 UDF/ISO-9660 混合文件系统。仅在创建 ISO 映像文件或将文件直接写入磁盘时才需要此操作。由于以这种方式创建的磁盘必须使用 mount_udf(8) 作为 UDF 文件系统挂载,因此它只能在支持 UDF 的操作系统上使用。否则,它看起来像包含损坏的文件。

要创建此类型的 ISO 文件

% mkisofs -R -J -udf -iso-level 3 -o imagefile.iso /path/to/data

要将文件直接刻录到磁盘

# growisofs -dvd-compat -udf -iso-level 3 -Z /dev/cd0 -J -R /path/to/data

当 ISO 映像已经包含大型文件时,growisofs(1) 不需要任何其他选项即可将该映像刻录到磁盘上。

请务必使用 sysutils/cdrtools 的最新版本,其中包含 mkisofs(8),因为较旧的版本可能不支持大型文件。如果最新版本不起作用,请安装 sysutils/cdrtools-devel 并阅读其 mkisofs(8)

20.6.3. 刻录 DVD-Video

DVD-Video 是基于 ISO 9660 和微 UDF (M-UDF) 规范的特定文件布局。由于 DVD-Video 呈现特定的数据结构层次结构,因此需要特定的程序(如 multimedia/dvdauthor)来制作 DVD。

如果 DVD-Video 文件系统的映像已经存在,则可以像刻录任何其他映像一样刻录它。如果使用 dvdauthor 制作 DVD,并且结果在 /path/to/video 中,则应使用以下命令来刻录 DVD-Video

# growisofs -Z /dev/cd0 -dvd-video /path/to/video

-dvd-video 被传递给 mkisofs(8) 以指示它创建 DVD-Video 文件系统布局。此选项意味着 -dvd-compat growisofs(1) 选项。

20.6.4. 使用 DVD+RW

与 CD-RW 不同,原始 DVD+RW 需要在首次使用之前进行格式化。建议在适当的时候让 growisofs(1) 自动处理此操作。但是,可以使用 dvd+rw-format 来格式化 DVD+RW

# dvd+rw-format /dev/cd0

只执行此操作一次,并记住只有原始 DVD+RW 介质需要格式化。格式化后,DVD+RW 可以像往常一样刻录。

要刻录全新的文件系统,而不仅仅是将一些数据追加到 DVD+RW 上,则无需先清空介质。相反,请像这样覆盖之前的录制

# growisofs -Z /dev/cd0 -J -R /path/to/newdata

DVD+RW 格式支持将数据追加到之前的录制。此操作包括将新会话合并到现有会话中,因为它不被视为多会话写入。 growisofs(1)扩展介质上存在的 ISO 9660 文件系统。

例如,要将数据追加到 DVD+RW,请使用以下内容

# growisofs -M /dev/cd0 -J -R /path/to/nextdata

在后续写入期间,应使用与刻录初始会话时相同的 mkisofs(8) 选项。

使用 -dvd-compat 以获得与 DVD-ROM 驱动器更好的介质兼容性。当使用 DVD+RW 时,此选项不会阻止添加数据。

要清空介质,请使用

# growisofs -Z /dev/cd0=/dev/zero

20.6.5. 使用 DVD-RW

DVD-RW 接受两种磁盘格式:增量顺序和限制覆盖。默认情况下,DVD-RW 磁盘采用顺序格式。

原始 DVD-RW 可以直接写入而无需格式化。但是,顺序格式的非原始 DVD-RW 需要在写入新初始会话之前进行清空。

要清空顺序模式下的 DVD-RW

# dvd+rw-format -blank=full /dev/cd0

使用 -blank=full 进行完整清空将在大约 1 倍速介质上花费大约一小时。如果 DVD-RW 将在一次刻录 (DAO) 模式下录制,则可以使用 -blank 进行快速清空。要以 DAO 模式刻录 DVD-RW,请使用以下命令

# growisofs -use-the-force-luke=dao -Z /dev/cd0=imagefile.iso

由于 growisofs(1) 会自动尝试检测快速清空的介质并启动 DAO 写入,因此 -use-the-force-luke=dao 不应需要。

相反,应该将任何 DVD-RW 都使用限制覆盖模式,因为这种格式比默认的增量顺序更灵活。

要将数据写入顺序 DVD-RW,请使用与其他 DVD 格式相同的说明

# growisofs -Z /dev/cd0 -J -R /path/to/data

要将一些数据追加到之前的录制,请在 growisofs(1) 中使用 -M。但是,如果将数据追加到增量顺序模式下的 DVD-RW,则将在磁盘上创建一个新会话,结果将是多会话磁盘。

限制覆盖格式的 DVD-RW 在新初始会话之前无需清空。相反,使用 -Z 覆盖磁盘。也可以使用 -M 扩展磁盘上已写入的现有 ISO 9660 文件系统。结果将是一个单会话 DVD。

要将 DVD-RW 设置为限制覆盖格式,必须使用以下命令

# dvd+rw-format /dev/cd0

要更改回顺序格式,请使用

# dvd+rw-format -blank=full /dev/cd0

20.6.6. 多会话

很少有 DVD-ROM 驱动器支持多会话 DVD,并且大多数情况下只读取第一个会话。顺序格式的 DVD+R、DVD-R 和 DVD-RW 可以接受多个会话。DVD+RW 和 DVD-RW 限制覆盖格式不存在多会话的概念。

在 DVD+R、DVD-R 或 DVD-RW 上以顺序格式进行初始非封闭会话后,使用以下命令将为光盘添加一个新会话。

# growisofs -M /dev/cd0 -J -R /path/to/nextdata

在 DVD+RW 或 DVD-RW 上以受限覆盖模式使用此命令将追加数据,同时将新会话合并到现有会话。结果将是单会话光盘。使用此方法在对这些类型的介质进行初始写入后添加数据。

由于在每个会话之间会使用介质上的部分空间来标记会话的结束和开始,因此应添加大量数据的会话以优化介质空间。DVD+R 的会话数限制为 154 个,DVD-R 约为 2000 个,DVD+R 双层为 127 个。

20.6.7. 更多信息

要获取有关 DVD 的更多信息,请在指定驱动器中插入光盘时使用 dvd+rw-mediainfo /dev/cd0 命令。

有关 dvd+rw-tools 的更多信息,请参阅 growisofs(1)dvd+rw-tools 网站cdwrite 邮件列表 档案。

创建与使用 dvd+rw-tools 相关的故障报告时,请始终包含 dvd+rw-mediainfo 的输出。

20.6.8. 使用 DVD-RAM

DVD-RAM 录像机可以使用 SCSI 或 ATAPI 接口。对于 ATAPI 设备,必须通过将以下行添加到 /boot/loader.conf 来启用 DMA 访问

hw.ata.atapi_dma="1"

DVD-RAM 可以看作是可移动硬盘驱动器。与任何其他硬盘驱动器一样,DVD-RAM 必须先格式化才能使用。在此示例中,整个磁盘空间将使用标准 UFS2 文件系统格式化

# dd if=/dev/zero of=/dev/acd0 bs=2k count=1
# bsdlabel -Bw acd0
# newfs /dev/acd0

DVD 设备 acd0 必须根据配置进行更改。

格式化 DVD-RAM 后,可以将其作为普通硬盘驱动器挂载

# mount /dev/acd0 /mnt

挂载后,DVD-RAM 将可读写。

20.7. 创建和使用软盘

本节介绍如何在 FreeBSD 中格式化 3.5 英寸软盘。

步骤:格式化软盘的步骤

软盘需要在使用之前进行低级格式化。这通常由供应商完成,但格式化是检查介质完整性的好方法。要在 FreeBSD 上对软盘进行低级格式化,请使用 fdformat(1)。使用此实用程序时,请注意任何错误消息,因为这些消息可以帮助确定磁盘是好是坏。

  1. 要格式化软盘,请将新 3.5 英寸软盘插入第一个软盘驱动器,并发出以下命令

    # /usr/sbin/fdformat -f 1440 /dev/fd0
  2. 低级格式化磁盘后,创建磁盘标签,因为系统需要它来确定磁盘的大小和几何形状。支持的几何形状值列在 /etc/disktab 中。

    要写入磁盘标签,请使用 bsdlabel(8)

    # /sbin/bsdlabel -B -w /dev/fd0 fd1440
  3. 现在,软盘已准备好使用文件系统进行高级格式化。软盘的文件系统可以是 UFS 或 FAT,其中 FAT 通常是软盘的更好选择。

    要使用 FAT 格式化软盘,请发出以下命令

    # /sbin/newfs_msdos /dev/fd0

现在,磁盘已准备好使用。要使用软盘,请使用 mount_msdosfs(8) 挂载它。您还可以从 Ports Collection 中安装和使用 emulators/mtools

20.8. 使用 NTFS 磁盘

本节介绍如何在 FreeBSD 中挂载 NTFS 磁盘。

NTFS(新技术文件系统)是由 Microsoft® 开发的一种专有日志文件系统。多年来,它一直是 Microsoft Windows® 的默认文件系统。FreeBSD 可以使用 FUSE 文件系统挂载 NTFS 卷。这些文件系统是作为用户空间程序实现的,它们通过一个定义明确的接口与 fusefs(5) 内核模块交互。

步骤:挂载 NTFS 磁盘的步骤

  1. 在使用 FUSE 文件系统之前,我们需要加载 fusefs(5) 内核模块

    # kldload fusefs

    使用 sysrc(8) 在启动时加载模块

    # sysrc kld_list+=fusefs
  2. 从软件包中安装实际的 NTFS 文件系统,如示例所示(参见 使用 pkg 进行二进制软件包管理)或从端口中安装(参见 使用 Ports Collection

    # pkg install fusefs-ntfs
  3. 最后,我们需要创建一个目录,用于挂载文件系统

    # mkdir /mnt/usb
  4. 假设插入了 USB 磁盘。可以使用 gpart(8) 查看磁盘分区信息

    # gpart show da0
    =>	  63  1953525105  da0 MBR   (932G)
    	  63  1953525105    1 ntfs  (932G)
  5. 我们可以使用以下命令挂载磁盘

    # ntfs-3g /dev/da0s1 /mnt/usb/

    现在,磁盘已准备好使用。

  6. 此外,可以在 /etc/fstab 中添加一个条目

    /dev/da0s1  /mnt/usb	ntfs mountprog=/usr/local/bin/ntfs-3g,noauto,rw  0 0

    现在,可以使用以下命令挂载磁盘

    # mount /mnt/usb
  7. 可以使用以下命令卸载磁盘

    # umount /mnt/usb/

20.9. 备份基础

实施备份计划对于从磁盘故障、意外文件删除、随机文件损坏或机器完全损坏(包括现场备份的损坏)中恢复至关重要。

备份类型和时间表将有所不同,具体取决于数据的的重要性、文件恢复所需的粒度以及可接受的停机时间。一些可能的备份技术包括

  • 整个系统的存档,备份到永久的异地媒体。这提供了针对上述所有问题的保护,但恢复速度慢且不方便,尤其是对于非特权用户。

  • 文件系统快照,这对于恢复已删除的文件或文件的先前版本很有用。

  • 整个文件系统或磁盘的副本,使用计划的 net/rsync 与网络上的另一个系统同步。

  • 硬件或软件 RAID,这可以最大限度地减少或避免磁盘故障时的停机时间。

通常,会使用多种备份技术。例如,您可以创建一个时间表来自动执行每周的完整系统备份,将其存储在异地,并使用每小时的 ZFS 快照来补充此备份。此外,您可以在进行文件编辑或删除之前手动备份各个目录或文件。

本节介绍了一些可用于在 FreeBSD 系统上创建和管理备份的实用程序。

20.9.1. 文件系统备份

用于备份文件系统的传统 UNIX® 程序是 dump(8)(用于创建备份)和 restore(8)(用于恢复备份)。这些实用程序在磁盘块级别工作,低于文件系统创建的文件、链接和目录的抽象。与其他备份软件不同,dump 会备份整个文件系统,并且无法仅备份文件系统的一部分或跨越多个文件系统的目录树。dump 不会写入文件和目录,而是写入构成文件和目录的原始数据块。

如果在根目录上使用 dump,它将不会备份 /home/usr 或许多其他目录,因为这些目录通常是其他文件系统的挂载点或指向这些文件系统的符号链接。

当用于恢复数据时,restore 默认情况下会将临时文件存储在 /tmp/ 中。当使用具有较小 /tmp 的恢复磁盘时,请将 TMPDIR 设置为具有更多可用空间的目录,以便恢复成功。

当使用 dump 时,请注意,它保留了一些早期的怪癖,这些怪癖来自 AT&T UNIX® 的第 6 版(大约在 1975 年)。默认参数假设备份到 9 轨磁带,而不是其他类型的媒体或当今可用的高密度磁带。这些默认值必须在命令行中覆盖。

可以将文件系统通过网络备份到另一台系统或连接到另一台计算机的磁带驱动器。虽然可以使用 rdump(8)rrestore(8) 实用程序来实现此目的,但它们不被认为是安全的。

相反,您可以通过 SSH 连接更安全地使用 dumprestore。此示例创建 /usr 的完整压缩备份,并将备份文件通过 SSH 连接发送到指定的主机。

示例 1. 使用 SSH dump
# /sbin/dump -0uan -f - /usr | gzip -2 | ssh -c blowfish \
          [email protected] dd of=/mybigfiles/dump-usr-l0.gz

此示例设置 RSH 以便通过 SSH 连接将备份写入远程系统上的磁带驱动器

示例 2. 使用 SSH 和设置的 RSH 进行 dump
# env RSH=/usr/bin/ssh /sbin/dump -0uan -f [email protected]:/dev/sa0 /usr

使用 Z 文件系统 (ZFS) 的系统可以使用 zfs(8) 来创建快照,以及 发送和接收 它们到/来自远程系统。

20.9.2. 目录备份

有几个内置的实用程序可用于根据需要备份和恢复指定的文件和目录。

备份目录中所有文件的不错选择是 tar(1)。此实用程序可追溯到 AT&T UNIX® 的第 6 版,默认情况下假设递归备份到本地磁带设备。可以使用开关来指定备份文件的名称。

此示例创建当前目录的压缩备份,并将其保存到 /tmp/mybackup.tgz。创建备份文件时,请确保备份未保存到正在备份的同一目录。如有疑问,请恢复到临时目录或指定备份中要恢复的文件的名称。

示例 3. 使用 tar 备份当前目录
# tar czvf /tmp/mybackup.tgz .

要恢复整个备份,请 cd 到要恢复到的目录,并指定备份的名称。请注意,这将覆盖恢复目录中任何较新的文件版本。如有疑问,请恢复到临时目录或指定备份中要恢复的文件的名称。

示例 4. 使用 tar 恢复当前目录
# tar xzvf /tmp/mybackup.tgz

有数十个可用的开关,这些开关在 tar(1) 中有描述。此实用程序还支持使用排除模式来指定备份指定目录或从备份恢复文件时不应包含哪些文件。

要使用指定的文件和目录列表创建备份,cpio(1) 是一个不错的选择。与 tar 不同,cpio 不知道如何遍历目录树,必须提供要备份的文件列表。

例如,可以使用 lsfind 创建文件列表。此示例创建当前目录的递归列表,然后将其管道传输到 cpio 以创建名为 /tmp/mybackup.cpio 的输出备份文件。

示例 5. 使用 lscpio 递归备份当前目录
# ls -R | cpio -ovF /tmp/mybackup.cpio

一个试图桥接 tarcpio 提供的功能的备份实用程序是 pax(1)。多年来,tarcpio 的各种版本变得略有不兼容。POSIX® 创建了 pax,它试图读取和写入许多不同的 cpiotar 格式,以及它自己的新格式。

与前面示例等效的 pax 将是

示例 6. 使用 pax 备份当前目录
# pax -wf /tmp/mybackup.pax .

20.9.3. 使用数据磁带进行备份

虽然磁带技术一直在不断发展,但现代备份系统往往将异地备份与本地可移动介质相结合。FreeBSD 支持任何使用 SCSI 的磁带驱动器,例如 LTO 或 DAT。对 SATA 和 USB 磁带驱动器的支持有限。

对于 SCSI 磁带设备,FreeBSD 使用 sa(4) 驱动程序以及 /dev/sa0/dev/nsa0/dev/esa0 设备。物理设备名称为 /dev/sa0。当使用 /dev/nsa0 时,备份应用程序不会在写入文件后倒带磁带,这允许将多个文件写入磁带。使用 /dev/esa0 会在设备关闭后弹出磁带。

在 FreeBSD 中,mt 用于控制磁带驱动器的操作,例如在磁带上搜索文件或向磁带写入磁带控制标记。例如,可以通过在写入新文件之前跳过前三个文件来保留磁带上的前三个文件。

# mt -f /dev/nsa0 fsf 3

此实用程序支持许多操作。有关详细信息,请参考 mt(1)

要使用 tar 将单个文件写入磁带,请指定磁带设备的名称和要备份的文件。

# tar cvf /dev/sa0 file

要从磁带上的 tar 存档中恢复文件到当前目录

# tar xvf /dev/sa0

要备份 UFS 文件系统,请使用 dump。此示例备份 /usr,在完成后不倒带磁带。

# dump -0aL -b64 -f /dev/nsa0 /usr

要从磁带上的 dump 文件中交互式恢复文件到当前目录

# restore -i -f /dev/nsa0

20.9.4. 第三方备份实用程序

FreeBSD Ports Collection 提供了许多第三方实用程序,可用于安排备份创建、简化磁带备份,并使备份更轻松、更方便。这些应用程序中的许多是基于客户端/服务器的,可用于自动备份单个系统或网络中的所有计算机。

流行的实用程序包括

20.9.5. 紧急恢复

除了定期备份之外,还建议在紧急准备计划中执行以下步骤。

创建以下命令输出的打印副本

  • gpart show

  • more /etc/fstab

  • pkg prime-list

  • dmesg

将此打印输出和安装介质的副本存储在安全位置。如果需要紧急恢复,请启动安装介质并选择 Live CD 访问救援 shell。此救援模式可用于查看系统当前状态,如果需要,可用于重新格式化磁盘并从备份中恢复数据。

接下来,测试救援 shell 和备份。记下该过程。将这些笔记与介质、打印输出和备份一起存储。这些笔记可能会防止在执行紧急恢复的压力下意外破坏备份。

为了增加安全性,请将最新备份存储在与计算机和磁盘驱动器物理隔离的位置,距离要远得多。

20.10. 内存磁盘

除了物理磁盘之外,FreeBSD 还支持创建和使用内存磁盘。内存磁盘的一种可能的用途是在不首先将其刻录到 CD 或 DVD 然后挂载 CD/DVD 介质的情况下访问 ISO 文件系统的内容。

在 FreeBSD 中,md(4) 驱动程序用于提供对内存磁盘的支持。GENERIC 内核包含此驱动程序。当使用自定义内核配置文件时,请确保它包含以下行

device md

20.10.1. 挂载和卸载现有映像

要挂载现有文件系统映像,请使用 mdconfig 指定 ISO 文件的名称和一个空闲的单元号。然后,引用该单元号将其挂载到现有的挂载点上。挂载后,ISO 中的文件将出现在挂载点中。此示例将 diskimage.iso 附加到内存设备 /dev/md0,然后将该内存设备挂载到 /mnt

# mdconfig -f diskimage.iso -u 0
# mount -t cd9660 /dev/md0 /mnt

请注意,-t cd9660 用于挂载 ISO 格式。如果未使用 -u 指定单元号,mdconfig 将自动分配一个未使用的内存设备并输出分配的单元的名称,例如 md4。有关此命令及其选项的更多详细信息,请参考 mdconfig(8)

当不再使用内存磁盘时,应将其资源释放回系统。首先,卸载文件系统,然后使用 mdconfig 将磁盘从系统中分离并释放其资源。继续此示例

# umount /mnt
# mdconfig -d -u 0

要确定是否有任何内存磁盘仍然附加到系统,请键入 mdconfig -l

20.10.2. 创建文件或内存支持的内存磁盘

FreeBSD 还支持内存磁盘,其中要使用的存储空间是从硬盘或内存区域分配的。第一种方法通常称为文件支持的文件系统,第二种方法称为内存支持的文件系统。这两种类型都可以使用 mdconfig 创建。

要创建一个新的内存支持的文件系统,请指定 swap 类型以及要创建的内存磁盘的大小。然后,使用文件系统格式化内存磁盘,并像往常一样挂载。此示例在单元 1 上创建一个 5M 内存磁盘。然后,使用 UFS 文件系统格式化该内存磁盘,然后再将其挂载。

# mdconfig -a -t swap -s 5m -u 1
# newfs -U md1
/dev/md1: 5.0MB (10240 sectors) block size 16384, fragment size 2048
        using 4 cylinder groups of 1.27MB, 81 blks, 192 inodes.
        with soft updates
super-block backups (for fsck -b #) at:
 160, 2752, 5344, 7936
# mount /dev/md1 /mnt
# df /mnt
Filesystem 1K-blocks Used Avail Capacity  Mounted on
/dev/md1        4718    4  4338     0%    /mnt

要创建一个新的文件支持的内存磁盘,首先分配一个要使用的磁盘区域。此示例创建一个名为 newimage 的空 5MB 文件

# dd if=/dev/zero of=newimage bs=1k count=5k
5120+0 records in
5120+0 records out

接下来,将该文件附加到内存磁盘,标记内存磁盘并使用 UFS 文件系统对其进行格式化,挂载内存磁盘,并验证文件支持的磁盘的大小。

# mdconfig -f newimage -u 0
# bsdlabel -w md0 auto
# newfs -U md0a
/dev/md0a: 5.0MB (10224 sectors) block size 16384, fragment size 2048
        using 4 cylinder groups of 1.25MB, 80 blks, 192 inodes.
super-block backups (for fsck -b #) at:
 160, 2720, 5280, 7840
# mount /dev/md0a /mnt
# df /mnt
Filesystem 1K-blocks Used Avail Capacity  Mounted on
/dev/md0a       4710    4  4330     0%    /mnt

使用 mdconfig 创建文件或内存支持的文件系统需要几个命令。FreeBSD 还附带 mdmfs,它会自动配置内存磁盘,使用 UFS 文件系统对其进行格式化,并将其挂载。例如,在使用 dd 创建 newimage 后,此一个命令相当于运行上面显示的 bsdlabelnewfsmount 命令。

# mdmfs -F newimage -s 5m md0 /mnt

要改为使用 mdmfs 创建一个新的基于内存的内存磁盘,请使用此一个命令

# mdmfs -s 5m md1 /mnt

如果未指定单元号,mdmfs 将自动选择一个未使用的内存设备。有关 mdmfs 的更多详细信息,请参考 mdmfs(8)

20.11. 文件系统快照

FreeBSD 与 软更新 结合提供了文件系统快照功能。

UFS 快照允许用户创建指定文件系统的映像,并将它们视为文件。如果您使用的是 Z 文件系统 (ZFS),请参考 管理快照,了解如何使用快照。

快照文件必须在执行操作的文件系统中创建,并且每个文件系统最多可以创建 20 个快照。活动快照记录在超级块中,因此它们在卸载和重新挂载操作以及系统重新引导后仍然存在。当不再需要快照时,可以使用 rm(1) 删除它。虽然可以按任何顺序删除快照,但所有已用空间可能不会被获取,因为另一个快照可能会声明一些已释放的块。

不可更改的 snapshot 文件标志在最初创建快照文件后由 mksnap_ffs(8) 设置。unlink(1) 对快照文件做了一个例外,因为它允许删除它们。

快照是使用 mount(8) 创建的。要将 /var 的快照放置在文件 /var/snapshot/snap 中,请使用以下命令

# mount -u -o snapshot /var/snapshot/snap /var

或者,使用 mksnap_ffs(8) 来创建快照。

# mksnap_ffs /var /var/snapshot/snap

可以在文件系统上找到快照文件,例如 /var,可以使用 find(1)

# find /var -flags snapshot

创建快照后,它有几个用途。

  • 一些管理员会将快照文件用于备份目的,因为快照可以传输到 CD 或磁带。

  • 文件系统完整性检查器 fsck(8) 可以运行在快照上。假设文件系统在挂载时是干净的,这应该始终提供干净且不变的结果。

  • 在快照上运行 dump(8) 将生成一个与文件系统和快照时间戳一致的转储文件。 dump(8) 还可以使用 -L 在一条命令中创建快照、创建转储映像,然后删除快照。

  • 快照可以作为文件系统的冻结映像进行挂载。要 mount(8) 快照 /var/snapshot/snap 运行

    # mdconfig -a -t vnode -o readonly -f /var/snapshot/snap -u 4
    # mount -r /dev/md4 /mnt

现在可以通过 /mnt 访问冻结的 /var。最初,一切将处于创建快照时的相同状态。唯一的例外是,任何早期快照将显示为零长度文件。要卸载快照,请使用

# umount /mnt
# mdconfig -d -u 4

有关 softupdates 和文件系统快照的更多信息,包括技术论文,请访问 Marshall Kirk McKusick 的网站 http://www.mckusick.com/

20.12. 磁盘配额

磁盘配额可用于限制用户或组成员在每个文件系统基础上分配的磁盘空间量或文件数量。这可以防止一个用户或一组用户占用所有可用的磁盘空间。

本节介绍如何为 UFS 文件系统配置磁盘配额。要在 ZFS 文件系统上配置配额,请参阅 数据集、用户和组配额

20.12.1. 启用磁盘配额

要确定 FreeBSD 内核是否提供对磁盘配额的支持

% sysctl kern.features.ufs_quota
kern.features.ufs_quota: 1

在本例中,1 表示配额支持。如果该值为 0,请将以下行添加到自定义内核配置文件中,并使用 配置 FreeBSD 内核 中的说明重新构建内核。

options QUOTA

接下来,在 /etc/rc.conf 中启用磁盘配额。

quota_enable="YES"

通常,在启动时,每个文件系统的配额完整性将由 quotacheck(8) 检查。该程序确保配额数据库中的数据正确反映文件系统上的数据。这是一个耗时的过程,会显着影响系统启动所需的时间。要跳过此步骤,请将此变量添加到 /etc/rc.conf

check_quotas="NO"

最后,编辑 /etc/fstab 以在每个文件系统基础上启用磁盘配额。要在文件系统上启用每个用户配额,请将 userquota 添加到文件系统 /etc/fstab 条目中的选项字段以启用配额。例如

/dev/da1s2g   /home    ufs rw,userquota 1 2

要启用组配额,请使用 groupquota。要启用用户和组配额,请用逗号分隔选项。

/dev/da1s2g    /home    ufs rw,userquota,groupquota 1 2

默认情况下,配额文件存储在文件系统的根目录中,分别为 quota.userquota.group。有关更多信息,请参阅 fstab(5)。不建议为配额文件指定其他位置。

配置完成后,重新启动系统,/etc/rc 将自动运行相应的命令以创建在 /etc/fstab 中启用的所有配额的初始配额文件。

在正常操作过程中,无需手动运行 quotacheck(8)quotaon(8)quotaoff(8)。但是,应该阅读这些手册页以熟悉其操作。

20.12.2. 设置配额限制

要验证配额是否已启用,请运行

# quota -v

每个启用了配额的文件系统都应该有一个磁盘使用情况和当前配额限制的单行摘要。

系统现在可以使用 edquota 为其分配配额限制。

有几种选项可用于强制执行对用户或组可分配的磁盘空间量以及他们可以创建的文件数量的限制。分配可以基于磁盘空间(块配额)、文件数量(inode 配额)或两者的组合进行限制。每个限制进一步细分为两个类别:硬限制和软限制。

硬限制不得超过。一旦用户达到硬限制,该用户就无法在该文件系统上进行进一步的分配。例如,如果用户在文件系统上的硬限制为 500 千字节,并且当前使用量为 490 千字节,则该用户只能再分配 10 千字节。尝试再分配 11 千字节将失败。

软限制可以在有限的时间内(称为宽限期)内超过,默认情况下为一周。如果用户超过其限制的时间超过宽限期,则软限制将变为硬限制,并且不允许进一步分配。当用户降至软限制以下时,宽限期将重置。

在以下示例中,正在编辑 test 帐户的配额。当调用 edquota 时,将打开由 EDITOR 指定的编辑器以编辑配额限制。默认编辑器设置为 vi。

# edquota -u test
Quotas for user test:
/usr: kbytes in use: 65, limits (soft = 50, hard = 75)
        inodes in use: 7, limits (soft = 50, hard = 60)
/usr/var: kbytes in use: 0, limits (soft = 50, hard = 75)
        inodes in use: 0, limits (soft = 50, hard = 60)

每个启用了配额的文件系统通常有两行。一行代表块限制,另一行代表 inode 限制。更改该值以修改配额限制。例如,要将 /usr 上的块限制提高到软限制为 500 和硬限制为 600,请按如下方式更改该行中的值

/usr: kbytes in use: 65, limits (soft = 500, hard = 600)

退出编辑器后,新的配额限制将生效。

有时需要为一系列用户设置配额限制。这可以通过首先将所需配额限制分配给用户来实现。然后,使用 -p 将该配额复制到指定的用户 ID(UID)范围内。以下命令将为 UID 10,00019,999 复制这些配额限制

# edquota -p test 10000-19999

有关更多信息,请参阅 edquota(8)

20.12.3. 检查配额限制和磁盘使用情况

要检查单个用户或组配额和磁盘使用情况,请使用 quota(1)。用户只能查看自己的配额以及他们所属组的配额。只有超级用户才能查看所有用户和组配额。要获得启用了配额的文件系统的所有配额和磁盘使用情况的摘要,请使用 repquota(8)

通常,用户未在其中使用任何磁盘空间的文件系统不会显示在 quota 的输出中,即使用户为该文件系统分配了配额限制。使用 -v 来显示这些文件系统。以下是对具有两个文件系统配额限制的用户 quota -v 的示例输出。

Disk quotas for user test (uid 1002):
     Filesystem  usage    quota   limit   grace   files   quota   limit   grace
           /usr      65*     50      75   5days       7      50      60
       /usr/var       0      50      75               0      50      60

在本例中,用户当前在 /usr 上超过 50 千字节的软限制 15 千字节,并且还有 5 天的宽限期。星号 * 表示用户当前已超过配额限制。

20.12.4. NFS 上的配额

配额由 NFS 服务器上的配额子系统强制执行。 rpc.rquotad(8) 守护进程使 NFS 客户端上的 quota 能够获得配额信息,从而允许这些机器上的用户查看其配额统计信息。

在 NFS 服务器上,通过从 /etc/inetd.conf 中的该行中删除 # 来启用 rpc.rquotad

rquotad/1      dgram rpc/udp wait root /usr/libexec/rpc.rquotad rpc.rquotad

然后,重新启动 inetd

# service inetd restart

20.13. 加密磁盘分区

FreeBSD 提供了出色的在线保护措施,以防止未经授权的数据访问。文件权限和 强制访问控制 (MAC) 有助于防止未经授权的用户在操作系统处于活动状态且计算机已通电时访问数据。但是,如果攻击者对计算机有物理访问权,并且可以将计算机的硬盘驱动器移至另一个系统以复制和分析数据,则操作系统强制执行的权限就无关紧要了。

无论攻击者如何获得硬盘驱动器或已关闭的计算机,FreeBSD 中内置的基于 GEOM 的加密子系统都能够保护计算机文件系统上的数据,以防即使是拥有大量资源的动机很强的攻击者。与加密单个文件的加密方法不同,内置的 gbdegeli 实用程序可用于透明地加密整个文件系统。没有明文会接触到硬盘驱动器的磁头。

本章演示如何在 FreeBSD 上创建加密文件系统。它首先使用 gbde 演示该过程,然后使用 geli 演示相同的示例。

20.13.1. 使用 gbde 进行磁盘加密

gbde(4) 功能的目标是为攻击者访问存储设备的内容提供 formidable 挑战。但是,如果计算机在运行时被入侵,并且存储设备处于活动连接状态,或者攻击者可以访问有效的密码短语,则它不会对存储设备的内容提供任何保护。因此,在系统运行时提供物理安全并保护加密机制使用的密码短语非常重要。

此功能提供了多个屏障来保护存储在每个磁盘扇区中的数据。它使用 128 位 AES 在 CBC 模式下加密磁盘扇区的内容。磁盘上的每个扇区都使用不同的 AES 密钥进行加密。有关加密设计的更多信息(包括如何从用户提供的密码短语派生扇区密钥),请参阅 gbde(4)

FreeBSD 为 gbde 提供了一个内核模块,可以使用以下命令加载它

# kldload geom_bde

如果使用自定义内核配置文件,请确保它包含以下行

options GEOM_BDE

以下示例演示了将新的硬盘驱动器添加到将保存单个加密分区的系统中,该分区将作为 /private 进行挂载。

步骤:使用 gbde 加密分区
  1. 添加新的硬盘驱动器

    按照 添加磁盘 中的说明将新驱动器安装到系统中。在本例中,新的硬盘驱动器分区已添加为 /dev/ad4s1c,而 /dev/ad0s1* 代表现有的标准 FreeBSD 分区。

    # ls /dev/ad*
    /dev/ad0        /dev/ad0s1b     /dev/ad0s1e     /dev/ad4s1
    /dev/ad0s1      /dev/ad0s1c     /dev/ad0s1f     /dev/ad4s1c
    /dev/ad0s1a     /dev/ad0s1d     /dev/ad4
  2. 创建目录以保存 gbde 锁定文件

    # mkdir /etc/gbde

    gbde 锁定文件包含 gbde 访问加密分区所需的信息。如果没有访问锁定文件,gbde 将无法解密加密分区中包含的数据,除非进行大量的 manual 干预,而该操作不受软件支持。每个加密分区使用一个单独的锁定文件。

  3. 初始化 gbde 分区

    gbde 分区必须先初始化才能使用。此初始化只需要执行一次。此命令将打开默认编辑器,以便在模板中设置各种配置选项。要与 UFS 文件系统一起使用,请将 sector_size 设置为 2048

    # gbde init /dev/ad4s1c -i -L /etc/gbde/ad4s1c.lock
    #
    # Sector size is the smallest unit of data which can be read or written.
    # Making it too small decreases performance and decreases available space.
    # Making it too large may prevent filesystems from working.  512 is the
    # minimum and always safe.  For UFS, use the fragment size
    #
    sector_size	=	2048
    [...]

    保存编辑后,系统将两次要求用户输入用于保护数据的密码短语。两次输入的密码短语必须相同。gbde 保护数据的能力完全取决于密码短语的质量。有关如何选择易于记忆的安全密码短语的技巧,请参阅http://world.std.com/~reinhold/diceware.htm.

    此初始化操作为 gbde 分区创建了一个锁定文件。在本例中,它存储为/etc/gbde/ad4s1c.lock。锁定文件必须以“.lock”结尾才能被/etc/rc.d/gbde 启动脚本正确检测。

    锁定文件必须与任何加密分区的內容一起备份。如果没有锁定文件,合法所有者将无法访问加密分区上的数据。

  4. 将加密分区附加到内核

    # gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c.lock

    此命令将提示输入在加密分区初始化期间选择的密码短语。新的加密设备将出现在/dev 中,名为/dev/device_name.bde

    # ls /dev/ad*
    /dev/ad0        /dev/ad0s1b     /dev/ad0s1e     /dev/ad4s1
    /dev/ad0s1      /dev/ad0s1c     /dev/ad0s1f     /dev/ad4s1c
    /dev/ad0s1a     /dev/ad0s1d     /dev/ad4        /dev/ad4s1c.bde
  5. 在加密设备上创建文件系统

    将加密设备附加到内核后,可以在设备上创建文件系统。此示例使用启用了软更新的 UFS 文件系统。请确保指定具有*.bde 扩展名的分区。

    # newfs -U /dev/ad4s1c.bde
  6. 挂载加密分区

    创建一个挂载点并挂载加密文件系统

    # mkdir /private
    # mount /dev/ad4s1c.bde /private
  7. 验证加密文件系统是否可用

    加密文件系统现在应该可见并可以使用。

    % df -H
    Filesystem        Size   Used  Avail Capacity  Mounted on
    /dev/ad0s1a      1037M    72M   883M     8%    /
    /devfs            1.0K   1.0K     0B   100%    /dev
    /dev/ad0s1f       8.1G    55K   7.5G     0%    /home
    /dev/ad0s1e      1037M   1.1M   953M     0%    /tmp
    /dev/ad0s1d       6.1G   1.9G   3.7G    35%    /usr
    /dev/ad4s1c.bde   150G   4.1K   138G     0%    /private

每次启动后,所有加密文件系统都必须手动重新附加到内核,检查错误并挂载,然后才能使用文件系统。要配置这些步骤,请将以下行添加到/etc/rc.conf

gbde_autoattach_all="YES"
gbde_devices="ad4s1c"
gbde_lockdir="/etc/gbde"

这需要在启动时在控制台中输入密码短语。输入正确的密码短语后,加密分区将自动挂载。rc.conf(5) 中列出了其他 gbde 启动选项。

sysinstall 与 gbde 加密设备不兼容。所有*.bde 设备必须在启动 sysinstall 之前从内核中分离,否则它将在其初始设备探测期间崩溃。要分离示例中使用的加密设备,请使用以下命令

# gbde detach /dev/ad4s1c

20.13.2. 使用 geli 进行磁盘加密

可以使用 geli 获得另一种加密 GEOM 类。此控制实用程序添加了一些功能,并使用不同的方案执行加密工作。它提供了以下功能

  • 利用crypto(9) 框架,并在可用时自动使用加密硬件。

  • 支持多种加密算法,例如 AES-XTS、AES-CBC 和 Camellia-CBCAES。

  • 允许加密根分区。用于访问加密根分区的密码短语将在系统启动期间请求。

  • 允许使用两个独立密钥。

  • 它速度很快,因为它执行简单的扇区到扇区加密。

  • 允许备份和恢复主密钥。如果用户破坏了其密钥,仍然可以通过从备份中恢复密钥来访问数据。

  • 允许磁盘使用随机的一次性密钥附加,这对于交换分区和临时文件系统很有用。

更多功能和使用示例可以在geli(8) 中找到。

以下示例说明如何生成一个密钥文件,该文件将用作挂载在/private 下的加密提供程序的主密钥的一部分。密钥文件将提供一些用于加密主密钥的随机数据。主密钥也将受到密码短语的保护。提供程序的扇区大小将为 4kB。该示例描述了如何附加到 geli 提供程序,在其上创建文件系统,挂载它,使用它,最后如何分离它。

过程:使用 geli 加密分区
  1. 加载 geli 支持

    geli 的支持可作为可加载的内核模块使用。要配置系统在启动时自动加载模块,请将以下行添加到/boot/loader.conf

    geom_eli_load="YES"

    要立即加载内核模块

    # kldload geom_eli

    对于自定义内核,请确保内核配置文件包含以下行

    options GEOM_ELI
    device crypto
  2. 生成主密钥

    以下命令生成一个主密钥,所有数据都将使用该密钥加密。此密钥永远无法更改。与其直接使用它,不如用一个或多个用户密钥对其进行加密。用户密钥由可选的文件/root/da2.key 中的随机字节组合和/或密码短语组成。在本例中,密钥文件的数据源是/dev/random。此命令还将提供程序(/dev/da2.eli)的扇区大小配置为 4kB,以提高性能

    # dd if=/dev/random of=/root/da2.key bs=64 count=1
    # geli init -K /root/da2.key -s 4096 /dev/da2
    Enter new passphrase:
    Reenter new passphrase:

    使用密码短语和密钥文件都不是必需的,因为两种保护主密钥的方法都可以独立使用。

    如果密钥文件被指定为“-”,则将使用标准输入。例如,此命令生成三个密钥文件

    # cat keyfile1 keyfile2 keyfile3 | geli init -K - /dev/da2
  3. 使用生成的密钥附加提供程序

    要附加提供程序,请指定密钥文件、磁盘名称和密码短语

    # geli attach -k /root/da2.key /dev/da2
    Enter passphrase:

    这将创建一个带有.eli 扩展名的新设备

    # ls /dev/da2*
    /dev/da2  /dev/da2.eli
  4. 创建新的文件系统

    接下来,使用 UFS 文件系统格式化设备并将其挂载到现有挂载点

    # dd if=/dev/random of=/dev/da2.eli bs=1m
    # newfs /dev/da2.eli
    # mount /dev/da2.eli /private

    加密文件系统现在应该可以使用。

    # df -H
    Filesystem     Size   Used  Avail Capacity  Mounted on
    /dev/ad0s1a    248M    89M   139M    38%    /
    /devfs         1.0K   1.0K     0B   100%    /dev
    /dev/ad0s1f    7.7G   2.3G   4.9G    32%    /usr
    /dev/ad0s1d    989M   1.5M   909M     0%    /tmp
    /dev/ad0s1e    3.9G   1.3G   2.3G    35%    /var
    /dev/da2.eli   150G   4.1K   138G     0%    /private

完成对加密分区的操作后,不再需要/private 分区,最好通过卸载和分离 geli 加密分区来将其放入冷存储

# umount /private
# geli detach da2.eli

提供了一个rc.d 脚本,用于简化启动时 geli 加密设备的挂载。对于本示例,请将以下行添加到/etc/rc.conf

geli_devices="da2"
geli_da2_flags="-k /root/da2.key"

这将/dev/da2 配置为 geli 提供程序,其主密钥为/root/da2.key。系统将在系统关闭之前自动将提供程序与内核分离。在启动过程中,脚本将在附加提供程序之前提示输入密码短语。在密码提示之前和之后可能会显示其他内核消息。如果启动过程似乎停滞,请仔细查看其他消息中的密码提示。输入正确的密码短语后,将附加提供程序。然后挂载文件系统,通常通过/etc/fstab 中的条目进行挂载。有关如何配置在启动时挂载的文件系统的说明,请参阅“挂载和卸载文件系统”

20.14. 加密交换

与磁盘分区加密一样,交换空间加密用于保护敏感信息。考虑一个处理密码的应用程序。只要这些密码保留在物理内存中,它们就不会写入磁盘,并且将在重新启动后清除。但是,如果 FreeBSD 开始将内存页交换出去以释放空间,密码可能会以未加密的形式写入磁盘。加密交换空间可以解决这种情况。

本节演示如何使用gbde(8)geli(8) 加密来配置加密的交换分区。假设/dev/ada0s1b 是交换分区。

20.14.1. 配置加密交换

交换分区默认情况下不加密,并且应在继续之前清除任何敏感数据。要使用随机垃圾覆盖当前交换分区,请执行以下命令

# dd if=/dev/random of=/dev/ada0s1b bs=1m

要使用gbde(8) 加密交换分区,请在/etc/fstab 中的交换行中添加 .bde 后缀

# Device		Mountpoint	FStype	Options		Dump	Pass#
/dev/ada0s1b.bde	none		swap	sw		0	0

要改为使用geli(8) 加密交换分区,请使用 .eli 后缀

# Device		Mountpoint	FStype	Options		Dump	Pass#
/dev/ada0s1b.eli	none		swap	sw		0	0

默认情况下,geli(8) 使用 AES 算法,密钥长度为 128 位。通常,默认设置就足够了。如果需要,可以在/etc/fstab 中的 options 字段中更改这些默认设置。可能的标志是

aalgo

用于确保加密数据未被篡改的数据完整性验证算法。有关支持的算法列表,请参阅geli(8)

ealgo

用于保护数据的加密算法。有关支持的算法列表,请参阅geli(8)

keylen

用于加密算法的密钥长度。有关每种加密算法支持的密钥长度,请参阅geli(8)

sectorsize

在加密之前将数据拆分为块的大小。更大的扇区大小会提高性能,但会增加存储开销。建议的大小为 4096 字节。

此示例使用 AES-XTS 算法、128 位密钥长度和 4 千字节扇区大小来配置加密的交换分区

# Device		Mountpoint	FStype	Options				Dump	Pass#
/dev/ada0s1b.eli	none		swap	sw,ealgo=AES-XTS,keylen=128,sectorsize=4096	0	0

20.14.2. 加密交换验证

系统重新启动后,可以使用 swapinfo 验证加密交换的正常运行。

如果使用的是gbde(8)

% swapinfo
Device          1K-blocks     Used    Avail Capacity
/dev/ada0s1b.bde   542720        0   542720     0

如果使用的是geli(8)

% swapinfo
Device          1K-blocks     Used    Avail Capacity
/dev/ada0s1b.eli   542720        0   542720     0

20.15. 高可用性存储 (HAST)

高可用性是严肃商业应用中的主要要求之一,高可用性存储是此类环境中的关键组件。在 FreeBSD 中,高可用性存储 (HAST) 框架允许通过 TCP/IP 网络连接的多个物理分离的机器透明地存储相同数据。HAST 可以理解为基于网络的 RAID1(镜像),类似于 GNU/Linux® 平台中使用的 DRBD® 存储系统。结合 FreeBSD 的其他高可用性功能,如 CARP,HAST 使构建对硬件故障具有抵抗力的高可用性存储集群成为可能。

以下是 HAST 的主要功能

  • 可用于屏蔽本地硬盘上的 I/O 错误。

  • 文件系统无关,因为它适用于 FreeBSD 支持的任何文件系统。

  • 高效且快速的重新同步,因为只同步节点停机期间修改的块。

  • 可以在已部署的环境中使用以添加额外的冗余。

  • 与 CARP、Heartbeat 或其他工具一起,它可以用来构建一个健壮且持久的存储系统。

阅读完本节后,您将了解

  • HAST 是什么,它是如何工作的,以及它提供了哪些功能。

  • 如何在 FreeBSD 上设置和使用 HAST。

  • 如何集成 CARP 和 devd(8) 以构建健壮的存储系统。

在阅读本节之前,您应该

HAST 项目由 FreeBSD 基金会赞助,并得到 http://www.omc.net/http://www.transip.nl/ 的支持。

20.15.1. HAST 操作

HAST 在两台物理机器之间提供同步块级复制:节点和节点。这两台机器一起被称为一个集群。

由于 HAST 在主从配置中工作,因此它只允许集群节点中的一个在任何给定时间处于活动状态。主节点,也称为活动节点,是处理对 HAST 管理设备的所有 I/O 请求的节点。从节点会自动从主节点同步。

HAST 系统的物理组件是主节点上的本地磁盘和远程从节点上的磁盘。

HAST 在块级别同步运行,这对文件系统和应用程序是透明的。HAST 在 /dev/hast/ 中提供常规 GEOM 提供程序,供其他工具或应用程序使用。使用 HAST 提供的设备与原始磁盘或分区之间没有区别。

每个写入、删除或刷新操作都会通过 TCP/IP 发送到本地磁盘和远程磁盘。每个读取操作都从本地磁盘提供,除非本地磁盘未更新或发生 I/O 错误。在这种情况下,读取操作将发送到从节点。

HAST 试图提供快速的故障恢复。为此,在节点停机后减少同步时间非常重要。为了提供快速同步,HAST 管理着磁盘上的脏扩展位图,并且只在常规同步期间同步这些扩展位图,初始同步除外。

有很多方法可以处理同步。HAST 实现了几种复制模式来处理不同的同步方法

  • memsync:此模式在本地写入操作完成以及远程节点确认数据到达后,但在实际存储数据之前,将写入操作报告为已完成。远程节点上的数据将在发送确认后直接存储。此模式旨在降低延迟,但仍然提供良好的可靠性。此模式是默认模式。

  • fullsync:此模式在本地写入和远程写入都完成时将写入操作报告为已完成。这是最安全且最慢的复制模式。

  • async:此模式在本地写入完成后将写入操作报告为已完成。这是最快且最危险的复制模式。它只应在复制到延迟过高而无法使用其他模式的远程节点时使用。

20.15.2. HAST 配置

HAST 框架由以下几个组件组成

  • 提供数据同步的 hastd(8) 守护程序。当此守护程序启动时,它会自动加载 geom_gate.ko

  • 用户空间管理实用程序,hastctl(8)

  • The hast.conf(5) 配置文件。此文件必须在启动 hastd 之前存在。

希望将 GEOM_GATE 支持静态构建到内核中的用户应该将此行添加到自定义内核配置文件中,然后使用 配置 FreeBSD 内核 中的说明重新构建内核

options	GEOM_GATE

以下示例描述了如何使用 HAST 配置两个节点以进行主从操作,以在两者之间复制数据。这些节点将被称为 hasta,IP 地址为 172.16.0.1,以及 hastb,IP 地址为 172.16.0.2。这两个节点都将拥有一个用于 HAST 操作的相同大小的专用硬盘 /dev/ad6。HAST 池,有时也称为资源或 /dev/hast/ 中的 GEOM 提供程序,将被称为 test

HAST 的配置是使用 /etc/hast.conf 完成的。此文件应在两个节点上相同。最简单的配置是

resource test {
	on hasta {
		local /dev/ad6
		remote 172.16.0.2
	}
	on hastb {
		local /dev/ad6
		remote 172.16.0.1
	}
}

有关更高级的配置,请参考 hast.conf(5)

如果主机可解析且在 /etc/hosts 或本地 DNS 中定义,则也可以在 remote 语句中使用主机名。

配置存在于两个节点上后,就可以创建 HAST 池。在两个节点上运行以下命令,将初始元数据存储到本地磁盘并启动 hastd(8)

# hastctl create test
# service hastd onestart

无法在现有文件系统上使用 GEOM 提供程序,也无法将现有存储转换为 HAST 管理的池。此过程需要在提供程序上存储一些元数据,现有提供程序上将没有足够的可用空间。

HAST 节点的 primarysecondary 角色由管理员或像 Heartbeat 这样的软件使用 hastctl(8) 选择。在主节点 hasta 上,发出以下命令

# hastctl role primary test

在从节点 hastb 上运行以下命令

# hastctl role secondary test

通过在每个节点上运行 hastctl 来验证结果

# hastctl status test

检查输出中的 status 行。如果它显示 degraded,则配置文件存在问题。它应该在每个节点上显示 complete,这意味着节点之间的同步已开始。当 hastctl status 报告 0 字节的 dirty 扩展时,同步完成。

下一步是在 GEOM 提供程序上创建文件系统并将其挂载。这必须在 primary 节点上完成。创建文件系统可能需要几分钟,具体取决于硬盘的大小。此示例在 /dev/hast/test 上创建了一个 UFS 文件系统

# newfs -U /dev/hast/test
# mkdir /hast/test
# mount /dev/hast/test /hast/test

HAST 框架配置正确后,最后一步是确保在系统启动期间自动启动 HAST。将此行添加到 /etc/rc.conf

hastd_enable="YES"

20.15.2.1. 故障转移配置

此示例的目标是构建一个健壮的存储系统,该系统能够抵抗任何给定节点的故障。如果主节点发生故障,从节点将无缝接管,检查并挂载文件系统,并继续工作,不会丢失任何数据。

为了完成此任务,公共地址冗余协议 (CARP) 用于在 IP 层提供自动故障转移。CARP 允许同一网络段上的多个主机共享一个 IP 地址。根据 “公共地址冗余协议 (CARP)” 中提供的文档,在集群的两个节点上设置 CARP。在此示例中,每个节点都将拥有自己的管理 IP 地址和一个共享 IP 地址 172.16.0.254。集群的主 HAST 节点必须为主 CARP 节点。

上一节中创建的 HAST 池现在已准备好导出到网络上的其他主机。这可以通过使用共享 IP 地址 172.16.0.254 通过 NFS 或 Samba 导出来实现。唯一尚未解决的问题是在主节点发生故障时自动故障转移。

在 CARP 接口启动或停止的情况下,FreeBSD 操作系统会生成一个 devd(8) 事件,从而可以监视 CARP 接口的状态变化。CARP 接口上的状态变化表示某个节点发生故障或重新上线。这些状态变化事件使运行脚本成为可能,该脚本将自动处理 HAST 故障转移。

为了捕获 CARP 接口上的状态变化,在每个节点上将此配置添加到 /etc/devd.conf 中,同时用 <vhid> 替换虚拟主机 ID,用 <ifname> 替换关联的接口名称

notify 30 {
	match "system" "CARP";
	match "subsystem" "<vhid>@<ifname>";
	match "type" "MASTER";
	action "/usr/local/sbin/carp-hast-switch primary";
};

notify 30 {
	match "system" "CARP";
	match "subsystem" "<vhid>@<ifname>";
	match "type" "BACKUP";
	action "/usr/local/sbin/carp-hast-switch secondary";
};

在两个节点上重新启动 devd(8) 以使新配置生效

# service devd restart

当指定的接口状态通过启动或停止而发生变化时,系统会生成通知,允许 devd(8) 子系统运行指定的自动故障转移脚本,/usr/local/sbin/carp-hast-switch。有关此配置的进一步说明,请参考 devd.conf(5)

以下是一个自动故障转移脚本的示例

#!/bin/sh

# Original script by Freddie Cash <[email protected]>
# Modified by Michael W. Lucas <[email protected]>
# and Viktor Petersson <[email protected]>

# The names of the HAST resources, as listed in /etc/hast.conf
resources="test"

# delay in mounting HAST resource after becoming primary
# make your best guess
delay=3

# logging
log="local0.debug"
name="carp-hast"

# end of user configurable stuff

case "$1" in
	primary)
		logger -p $log -t $name "Switching to primary provider for ${resources}."
		sleep ${delay}

		# Wait for any "hastd secondary" processes to stop
		for disk in ${resources}; do
			while $( pgrep -lf "hastd: ${disk} \(secondary\)" > /dev/null 2>&1 ); do
				sleep 1
			done

			# Switch role for each disk
			hastctl role primary ${disk}
			if [ $? -ne 0 ]; then
				logger -p $log -t $name "Unable to change role to primary for resource ${disk}."
				exit 1
			fi
		done

		# Wait for the /dev/hast/* devices to appear
		for disk in ${resources}; do
			for I in $( jot 60 ); do
				[ -c "/dev/hast/${disk}" ] && break
				sleep 0.5
			done

			if [ ! -c "/dev/hast/${disk}" ]; then
				logger -p $log -t $name "GEOM provider /dev/hast/${disk} did not appear."
				exit 1
			fi
		done

		logger -p $log -t $name "Role for HAST resources ${resources} switched to primary."

		logger -p $log -t $name "Mounting disks."
		for disk in ${resources}; do
			mkdir -p /hast/${disk}
			fsck -p -y -t ufs /dev/hast/${disk}
			mount /dev/hast/${disk} /hast/${disk}
		done

	;;

	secondary)
		logger -p $log -t $name "Switching to secondary provider for ${resources}."

		# Switch roles for the HAST resources
		for disk in ${resources}; do
			if ! mount | grep -q "^/dev/hast/${disk} on "
			then
			else
				umount -f /hast/${disk}
			fi
			sleep $delay
			hastctl role secondary ${disk} 2>&1
			if [ $? -ne 0 ]; then
				logger -p $log -t $name "Unable to switch role to secondary for resource ${disk}."
				exit 1
			fi
			logger -p $log -t $name "Role switched to secondary for resource ${disk}."
		done
	;;
esac

简而言之,当节点成为主节点时,脚本将执行以下操作

  • 将 HAST 池提升为主节点,位于其他节点上。

  • 检查 HAST 池下的文件系统。

  • 挂载池。

当节点成为从节点时

  • 卸载 HAST 池。

  • 将 HAST 池降级为从节点。

这只是一个作为概念验证的示例脚本。它没有处理所有可能的情况,可以以任何方式扩展或更改,例如,启动或停止所需的 services。

对于此示例,使用了标准 UFS 文件系统。为了减少恢复所需的时间,可以使用支持日志的 UFS 或 ZFS 文件系统。

除了在本地使用高可用性存储之外,还可以通过 NFSiSCSIsshfs(1) 或 ports 中的程序(例如,net/samba419)将其共享到网络上的其他计算机。

更多详细的信息和额外的示例可以在http://wiki.FreeBSD.org/HAST找到。

20.15.3. 故障排除

HAST 通常应该能正常工作。但是,就像任何其他软件产品一样,有时它可能无法按预期工作。问题的来源可能不同,但经验法则是确保集群节点之间的时间同步。

在对HAST进行故障排除时,应该通过启动hastd时使用-d来提高hastd(8)的调试级别。此参数可以多次指定以进一步提高调试级别。还可以考虑使用-F,它将hastd在前台启动。

20.15.3.1. 从脑裂状态恢复

脑裂发生在集群节点无法相互通信,并且都配置为主节点时。这是一种危险状态,因为它允许两个节点对数据进行不兼容的更改。此问题必须由系统管理员手动纠正。

管理员必须决定哪个节点具有更重要的更改,或者手动执行合并。然后,让HAST对数据损坏的节点执行完全同步。为此,请在需要重新同步的节点上执行以下命令

# hastctl role init test
# hastctl create test
# hastctl role secondary test

最后修改时间:2024年9月24日,由 Wolfram Schneider修改