第二十一章 GEOM:模块化磁盘转换框架21.1. 简介21.2. RAID0——Striping步骤:创建未格式化ATA磁盘条带21.3. RAID1——Mirroring21.3.1. 元数据问题21.3.2. 使用两个新磁盘创建镜像21.3.3. 使用现有驱动器创建镜像21.3.4. 故障排除21.3.5. 从磁盘故障中恢复21.4. RAID3-具有专用奇偶校验的字节级条带化21.4.1. 创建专用RAID3阵列21.5. 软件RAID设备21.5.1. 创建一个阵列21.5.2. 多卷21.5.3. 将单个驱动器转换为镜像21.5.4. 将新驱动器插入阵列21.5.5. 从阵列中删除驱动器21.5.6. 停止阵列21.5.7. 检查阵列状态21.5.8. 删除阵列21.5.9. 删除意外阵列21.76. GEOM Gate 网络21.7. 标记磁盘设备21.7.1. 标签类型和示例21.8. 通过GEOM记录UFS
在FreeBSD中,GEOM框架允许通过使用提供者或 /dev 中的磁盘设备来访问和控制类,如主引导记录和BSD标签。通过支持各种软件RAID配置,GEOM透明地提供了对操作系统和操作系统实用程序的访问。
本章介绍FreeBSD中GEOM框架下磁盘的使用。这包括使用该框架进行配置的主要RAID控制实用程序。本章不是RAID配置的权威指南,只讨论了GEOM支持的RAID分类。
阅读本章后,你会知道:
• GEOM提供哪种类型的RAID支持。 • 如何使用基本实用程序配置、维护和操作各种RAID级别。 • 如何通过GEOM镜像、条带化、加密和远程连接磁盘设备。 • 如何对连接到GEOM框架的磁盘进行故障排除。
在阅读本章之前,您应该:
• 了解FreeBSD如何处理磁盘设备(【20. 存储】)。 • 知道如何配置和安装新内核(【10. 配置FreeBSD内核】)。
striping——条带化将多个磁盘驱动器组合到一个卷中。条带化可以通过使用硬件RAID控制器来执行。GEOM磁盘子系统为磁盘条带化(也称为RAID0)提供软件支持,无需RAID磁盘控制器。
在RAID0中,数据被分割成块,这些块被写入阵列中的所有驱动器。如下图所示,RAID0可以同时向阵列中的四个磁盘中的每一个写入64k,而不必等待系统将256k写入一个磁盘,从而提供卓越的I/O性能。通过使用多个磁盘控制器,可以进一步增强这种性能。

RAID0条带中的每个磁盘必须具有相同的大小,因为I/O请求是交错的,可以并行读取或写入多个磁盘。
xxxxxxxxxxRAID0不提供任何冗余。这意味着,如果阵列中的一个磁盘发生故障,磁盘上的所有数据都会丢失。如果数据很重要,请实施备份策略,定期将备份保存到远程系统或设备。使用商品磁盘在FreeBSD系统上创建基于GEOM的RAID0软件的过程如下。创建条带后,请参阅 gstripe(8) 以获取有关如何控制现有条带的更多信息。
加载geom_stripe.ko模块:
xxxxxxxxxx# kldload geom_stripe确保存在合适的挂载点。如果此卷将成为根分区,则暂时使用另一个挂载点,如 /mnt 。
确定将被条带化的磁盘的设备名称,并创建新的条带设备。例如,要将设备名为 /dev/ad2 和 /dev/ad3 的两个未使用和未分区的ATA磁盘条带化:
xxxxxxxxxx# gstripe label -v st0 /dev/ad2 /dev/ad3Metadata value stored on /dev/ad2.Metadata value stored on /dev/ad3.Done.在新卷上编写一个标准标签,也称为分区表,并安装默认引导代码:
xxxxxxxxxx# bsdlabel -wB /dev/stripe/st0除了st0之外,此过程还应在 /dev/stripe 中创建另外两个设备。其中包括 st0a 和 st0c 。此时,可以使用 newfs 在st0a上创建UFS文件系统:
xxxxxxxxxx# newfs -U /dev/stripe/st0a许多数字将在屏幕上滑动,几秒钟后,该过程将完成。卷已创建并准备装载。
要手动挂载创建的磁盘条带,请执行以下操作:
xxxxxxxxxx# mount /dev/stripe/st0a /mnt要在引导过程中自动挂载此条带文件系统,请将卷信息放置在 /etc/fstab 中。在这个例子中,创建了一个名为 stripe 的永久挂载点:
xxxxxxxxxx# mkdir /stripe# echo "/dev/stripe/st0a /stripe ufs rw 2 2" \ >> /etc/fstabgeom_stripe.ko 模块也必须在系统初始化期间自动加载,方法是在 /boot/loader.conf 中添加一行:
xxxxxxxxxx# echo 'geom_stripe_load="YES"' >> /boot/loader.confRAID1或镜像是将相同数据写入多个磁盘驱动器的技术。镜像通常用于防止因驱动器故障导致的数据丢失。镜像中的每个驱动器都包含一个相同的数据副本。当单个驱动器发生故障时,镜像将继续工作,从仍在运行的驱动器提供数据。计算机继续运行,管理员有时间在不中断用户的情况下更换故障驱动器。
这些例子说明了两种常见情况。第一种方法是用两个新驱动器创建镜像,并将其用作现有单个驱动器的替代品。第二个示例在单个新驱动器上创建镜像,将旧驱动器的数据复制到镜像中,然后将旧驱动器插入镜像中。虽然这个过程稍微复杂一些,但它只需要一个新驱动器。
传统上,镜像中的两个驱动器在型号和容量上是相同的,但gmerror(8)并不要求如此。使用不同驱动器创建的镜像的容量将等于镜像中最小驱动器的容量。较大驱动器上的额外空间将无法使用。稍后插入镜像的驱动器的容量必须至少与镜像中已有的最小驱动器一样大。
x此处显示的镜像过程是非破坏性的,但与任何主要的磁盘操作一样,请先进行完整备份。虽然 dump(8) 在这些过程中用于复制文件系统,但它不适用于具有软更新日志记录的文件系统。有关检测和禁用软更新日志记录的信息,请参阅 tunefs(8)。许多磁盘系统在每个磁盘的末尾存储元数据。在将磁盘重新用于镜像之前,应擦除旧元数据。大多数问题是由两种特定类型的剩余元数据引起的:GPT分区表和来自以前镜像的旧元数据。
GPT元数据可以用 gpart(8) 擦除。此示例从磁盘 ada8 中擦除主GPT分区表和备份GPT分区表格:
xxxxxxxxxx# gpart destroy -F ada8可以从活动镜像中删除磁盘,并使用 gmerror(8) 一步擦除元数据。这里,示例盘 ada8 从活动镜像 gm4 中移除:
xxxxxxxxxx# gmirror remove gm4 ada8如果镜像未运行,但旧的镜像元数据仍在磁盘上,请使用 gmerror clear 将其删除:
xxxxxxxxxx# gmirror clear ada8gmerror(8) 在磁盘末尾存储一个元数据块。由于GPT分区方案也在磁盘末尾存储元数据,因此不建议使用 gmerror(8) 镜像整个GPT磁盘。这里使用MBR分区是因为它只在磁盘的开头存储分区表,并且不与镜像元数据冲突。
在这个例子中,FreeBSD已经安装在单个磁盘 ada0 上。两个新磁盘 ada1 和 ada2 已连接到系统。将在这两个磁盘上创建一个新镜像,并用于替换旧的单个磁盘。
geom_mirror.ko 内核模块必须内置到内核中,或者在启动或运行时加载。现在手动加载内核模块:
xxxxxxxxxx# gmirror load使用两个新驱动器创建镜像:
xxxxxxxxxx# gmirror label -v gm0 /dev/ada1 /dev/ada2gm0 是分配给新镜像的用户选择的设备名称。镜像启动后,此设备名称将显示在 /dev/mirror/ 中。
现在可以使用 gpart(8) 在镜像上创建MBR和bsdlabel分区表。此示例使用传统的文件系统布局,分区为 /、swap 、/var/tmp 和 /usr 。一个/和一个交换分区也可以工作。
镜像上的分区大小不必与现有磁盘上的分区相同,但它们必须足够大,以容纳 ada0 上已有的所有数据。
xxxxxxxxxx# gpart create -s MBR mirror/gm0# gpart add -t freebsd -a 4k mirror/gm0# gpart show mirror/gm0=> 63 156301423 mirror/gm0 MBR (74G) 63 63 - free - (31k) 126 156301299 1 freebsd (74G) 156301425 61 - free - (30k)xxxxxxxxxx# gpart create -s BSD mirror/gm0s1# gpart add -t freebsd-ufs -a 4k -s 2g mirror/gm0s1# gpart add -t freebsd-swap -a 4k -s 4g mirror/gm0s1# gpart add -t freebsd-ufs -a 4k -s 2g mirror/gm0s1# gpart add -t freebsd-ufs -a 4k -s 1g mirror/gm0s1# gpart add -t freebsd-ufs -a 4k mirror/gm0s1# gpart show mirror/gm0s1=> 0 156301299 mirror/gm0s1 BSD (74G) 0 2 - free - (1.0k) 2 4194304 1 freebsd-ufs (2.0G) 4194306 8388608 2 freebsd-swap (4.0G) 12582914 4194304 4 freebsd-ufs (2.0G) 16777218 2097152 5 freebsd-ufs (1.0G) 18874370 137426928 6 freebsd-ufs (65G) 156301298 1 - free - (512B)通过在MBR和bsdlabel中安装引导代码并设置活动切片,使镜像可引导:
xxxxxxxxxx# gpart bootcode -b /boot/mbr mirror/gm0# gpart set -a active -i 1 mirror/gm0# gpart bootcode -b /boot/boot mirror/gm0s1格式化新镜像上的文件系统,启用软更新。
xxxxxxxxxx# newfs -U /dev/mirror/gm0s1a# newfs -U /dev/mirror/gm0s1d# newfs -U /dev/mirror/gm0s1e# newfs -U /dev/mirror/gm0s1f现在,可以使用 dump(8) 和 restore(8) 将原始ada0磁盘中的文件系统复制到镜像上。
xxxxxxxxxx# mount /dev/mirror/gm0s1a /mnt# dump -C16 -b64 -0aL -f - / | (cd /mnt && restore -rf -)# mount /dev/mirror/gm0s1d /mnt/var# mount /dev/mirror/gm0s1e /mnt/tmp# mount /dev/mirror/gm0s1f /mnt/usr# dump -C16 -b64 -0aL -f - /var | (cd /mnt/var && restore -rf -)# dump -C16 -b64 -0aL -f - /tmp | (cd /mnt/tmp && restore -rf -)# dump -C16 -b64 -0aL -f - /usr | (cd /mnt/usr && restore -rf -)编辑 /mnt/etc/fstab 以指向新的镜像文件系统:
xxxxxxxxxx# Device Mountpoint FStype Options Dump Pass#/dev/mirror/gm0s1a / ufs rw 1 1/dev/mirror/gm0s1b none swap sw 0 0/dev/mirror/gm0s1d /var ufs rw 2 2/dev/mirror/gm0s1e /tmp ufs rw 2 2/dev/mirror/gm0s1f /usr ufs rw 2 2如果 geom_mirror.ko 内核模块尚未内置到内核中,则编辑 /mnt/boot/loader.conf 以在引导时加载该模块:
xxxxxxxxxxgeom_mirror_load="YES"重新启动系统以测试新镜像,并验证是否已复制所有数据。BIOS将镜像视为两个单独的驱动器,而不是镜像。由于驱动器是相同的,因此选择哪个启动并不重要。
如果启动时出现问题,请参阅【21.3.4. 故障排除】。关闭电源并断开原始ada0磁盘的连接,可以将其作为离线备份保存。
在使用中,镜像的行为将与原始的单驱动器一样。
在这个例子中,FreeBSD已经安装在单个磁盘ada0上。新磁盘ada1已连接到系统。将在新磁盘上创建一个单磁盘镜像,将现有系统复制到该镜像上,然后将旧磁盘插入镜像中。需要这个稍微复杂的过程,因为 gmerror 需要在每个磁盘的末尾放置一个512字节的元数据块,而现有的ada0通常已经分配了所有的空间。
加载 geom_mirror.ko 内核模块:
xxxxxxxxxx# gmirror load使用 diskinfo 检查原始磁盘的介质大小:
xxxxxxxxxx# diskinfo -v ada0 | head -n3/dev/ada0 512 # sectorsize 1000204821504 # mediasize in bytes (931G)在新磁盘上创建镜像。为了确保镜像容量不大于原始ada0驱动器,使用 gnop(8) 创建相同大小的假驱动器。此驱动器不存储任何数据,仅用于限制镜像的大小。当 gmerror(8) 创建镜像时,即使新的ada1驱动器有更多空间,它也会将容量限制为 gzero.nop 的大小。请注意,第二行中的1000204821504等于ada0的媒体大小,如上面的 diskinfo 所示。
xxxxxxxxxx# geom zero load# gnop create -s 1000204821504 gzero# gmirror label -v gm0 gzero.nop ada1# gmirror forget gm0由于 gzero.nop 不存储任何数据,镜像不会将其视为已连接。镜像被告知 "forget"(忘记)未连接的组件,删除对 gzero.nop 的引用。结果是一个只包含单个磁盘ada1的镜像设备。
创建 gm0 后,查看ada0上的分区表。此输出来自1 TB驱动器。如果驱动器末尾有一些未分配的空间,则可以将内容直接从ada0复制到新镜像。
但是,如果输出显示磁盘上的所有空间都已分配,如以下列表所示,则磁盘末尾的512字节镜像元数据没有可用空间。
xxxxxxxxxx# gpart show ada0=> 63 1953525105 ada0 MBR (931G) 63 1953525105 1 freebsd [active] (931G)在这种情况下,必须编辑分区表,以将 mirror/gm0 上的容量减少一个扇区。稍后将解释该过程。
无论哪种情况,都应首先使用 gpart backup 和 gpart restore 复制主磁盘上的分区表。
xxxxxxxxxx# gpart backup ada0 > table.ada0# gpart backup ada0s1 > table.ada0s1这些命令创建两个文件,table.ada0 和 table.ada0s1 。此示例来自1 TB驱动器:
xxxxxxxxxx# cat table.ada0MBR 41 freebsd 63 1953525105 [active]xxxxxxxxxx# cat table.ada0s1BSD 81 freebsd-ufs 0 41943042 freebsd-swap 4194304 335544324 freebsd-ufs 37748736 503316485 freebsd-ufs 88080384 419430406 freebsd-ufs 130023424 8388608007 freebsd-ufs 968884224 984640881如果磁盘末尾没有显示可用空间,则切片和最后一个分区的大小都必须减少一个扇区。编辑这两个文件,将切片和最后一个分区的大小都减小一个。这些是每个列表中的最后一个数字。
xxxxxxxxxx# cat table.ada0MBR 41 freebsd 63 1953525104 [active]xxxxxxxxxx# cat table.ada0s1BSD 81 freebsd-ufs 0 41943042 freebsd-swap 4194304 335544324 freebsd-ufs 37748736 503316485 freebsd-ufs 88080384 419430406 freebsd-ufs 130023424 8388608007 freebsd-ufs 968884224 984640880如果磁盘末尾至少有一个扇区未分配,则可以使用这两个文件而无需修改。
现在将分区表还原到 mirror/gm0 中:
xxxxxxxxxx# gpart restore mirror/gm0 < table.ada0# gpart restore mirror/gm0s1 < table.ada0s1使用 gpart show 检查分区表。此示例中,gm0s1a 用于 / ,gm0s1d 用于 /var ,gm0s1e 用于 /usr, gm0s1f 用于 /data1 ,gm0s1g 用于 /data2 。
xxxxxxxxxx# gpart show mirror/gm0=> 63 1953525104 mirror/gm0 MBR (931G) 63 1953525042 1 freebsd [active] (931G)1953525105 62 - free - (31k)# gpart show mirror/gm0s1=> 0 1953525042 mirror/gm0s1 BSD (931G) 0 2097152 1 freebsd-ufs (1.0G) 2097152 16777216 2 freebsd-swap (8.0G) 18874368 41943040 4 freebsd-ufs (20G) 60817408 20971520 5 freebsd-ufs (10G) 81788928 629145600 6 freebsd-ufs (300G) 710934528 1242590514 7 freebsd-ufs (592G) 1953525042 63 - free - (31k)切片和最后一个分区在磁盘末尾都必须至少有一个空闲块。
在这些新分区上创建文件系统。分区数量将根据原始磁盘ada0而变化。
xxxxxxxxxx# newfs -U /dev/mirror/gm0s1a# newfs -U /dev/mirror/gm0s1d# newfs -U /dev/mirror/gm0s1e# newfs -U /dev/mirror/gm0s1f# newfs -U /dev/mirror/gm0s1g通过在MBR和bsdlabel中安装引导代码并设置活动切片,使镜像可引导:
xxxxxxxxxx# gpart bootcode -b /boot/mbr mirror/gm0# gpart set -a active -i 1 mirror/gm0# gpart bootcode -b /boot/boot mirror/gm0s1调整 /etc/fstab 以使用镜像上的新分区。首先将此文件复制到 /etc/fstab.orig 进行备份。
xxxxxxxxxx# cp /etc/fstab /etc/fstab.orig编辑 /etc/fstab ,将 /dev/ada0 替换为 mirror/gm0 。
xxxxxxxxxx# Device Mountpoint FStype Options Dump Pass#/dev/mirror/gm0s1a / ufs rw 1 1/dev/mirror/gm0s1b none swap sw 0 0/dev/mirror/gm0s1d /var ufs rw 2 2/dev/mirror/gm0s1e /usr ufs rw 2 2/dev/mirror/gm0s1f /data1 ufs rw 2 2/dev/mirror/gm0s1g /data2 ufs rw 2 2如果 geom_mirror.ko 内核模块尚未内置到内核中,请编辑 /boot/loader.conf 在引导时加载它:
xxxxxxxxxxgeom_mirror_load="YES"现在,可以使用 dump(8) 和 restore(8) 将原始磁盘中的文件系统复制到镜像上。使用 dump -L 转储的每个文件系统将首先创建一个快照,这可能需要一些时间。
xxxxxxxxxx# mount /dev/mirror/gm0s1a /mnt# dump -C16 -b64 -0aL -f - / | (cd /mnt && restore -rf -)# mount /dev/mirror/gm0s1d /mnt/var# mount /dev/mirror/gm0s1e /mnt/usr# mount /dev/mirror/gm0s1f /mnt/data1# mount /dev/mirror/gm0s1g /mnt/data2# dump -C16 -b64 -0aL -f - /usr | (cd /mnt/usr && restore -rf -)# dump -C16 -b64 -0aL -f - /var | (cd /mnt/var && restore -rf -)# dump -C16 -b64 -0aL -f - /data1 | (cd /mnt/data1 && restore -rf -)# dump -C16 -b64 -0aL -f - /data2 | (cd /mnt/data2 && restore -rf -)重新启动系统,从ada1启动。如果一切正常,系统将从 mirror/gm0 启动,该文件现在包含与ada0以前相同的数据。如果启动时出现问题,请参阅故障排除。
此时,镜像仍然仅由单个ada1磁盘组成。
从 mirror/gm0 成功启动后,最后一步是将ada0插入镜像。
xxxxxxxxxx当ada0插入镜像时,其先前的内容将被镜像中的数据覆盖。在将ada0添加到镜像之前,请确保镜像/gm0的内容与ada0相同。如果之前由dump(8)和restore(8)复制的内容与ada0上的内容不同,请还原/etc/fstab以在ada0上挂载文件系统,重新启动,然后重新启动整个过程。xxxxxxxxxx# gmirror insert gm0 ada0GEOM_MIRROR: Device gm0: rebuilding provider ada0两个磁盘之间的同步将立即开始。使用 gmerror 状态查看进度。
xxxxxxxxxx# gmirror status Name Status Componentsmirror/gm0 DEGRADED ada1 (ACTIVE) ada0 (SYNCHRONIZING, 64%)稍后,同步将完成。
xxxxxxxxxxGEOM_MIRROR: Device gm0: rebuilding provider ada0 finished.# gmirror status Name Status Componentsmirror/gm0 COMPLETE ada1 (ACTIVE) ada0 (ACTIVE)mirror/gm0 现在由两个磁盘 ada0 和 ada1 组成,内容会自动相互同步。在使用中, mirror/gm0 的行为将与原始的单驱动器一样。
如果系统不再启动,可能需要更改BIOS设置,以便从新的镜像驱动器之一启动。任一镜像驱动器都可以用于启动,因为它们包含相同的数据。
如果引导停止并显示此消息,则镜像设备有问题:
xxxxxxxxxxMounting from ufs:/dev/mirror/gm0s1a failed with error 19.Loader variables: vfs.root.mountfrom=ufs:/dev/mirror/gm0s1a vfs.root.mountfrom.options=rw Manual root filesystem specification: <fstype>:<device> [options] Mount <device> using filesystem <fstype> and with the specified (optional) option list. e.g. ufs:/dev/da0s1a zfs:tank cd9660:/dev/acd0 ro (which is equivalent to: mount -t cd9660 -o ro /dev/acd0 /)? List valid disk boot devices. Yield 1 second (for background tasks)<empty line> Abort manual inputmountroot>忘记在 /boot/loader.conf 中加载 geom_mirror.ko 模块可能会导致此问题。要修复它,请从FreeBSD安装介质启动,并在第一个提示下选择Shell。然后加载镜像模块并安装镜像设备:
xxxxxxxxxx# gmirror load# mount /dev/mirror/gm0s1a /mnt编辑 /mnt/boot/loader.conf ,添加一行以加载镜像模块:
xxxxxxxxxxgeom_mirror_load="YES"保存文件并重新启动。
导致 error 19 的其他问题需要更多的努力来解决。虽然系统应该从ada0启动,但如果 /etc/fstab 不正确,将出现另一个选择shell的提示。在引导加载程序提示下输入 ufs:/dev/ada0s1a ,然后按 Enter 键。撤消 /etc/fstab 中的编辑,然后从原始磁盘(ada0)而不是镜像挂载文件系统。重新启动系统,然后重试该过程。
xxxxxxxxxxEnter full pathname of shell or RETURN for /bin/sh:# cp /etc/fstab.orig /etc/fstab# reboot磁盘镜像的好处是,单个磁盘可以发生故障,而不会导致镜像丢失任何数据。在上面的示例中,如果ada0发生故障,镜像将继续工作,从剩余的工作驱动器ada1提供数据。
要更换故障驱动器,请关闭系统,并用容量相同或更大的新驱动器物理更换故障驱动器。制造商在以GB为单位对驱动器进行评级时使用了一些任意值,唯一真正确定的方法是比较 diskinfo -v 显示的扇区总数。容量大于镜像的驱动器可以工作,尽管新驱动器上的额外空间不会被使用。
计算机重新通电后,镜像将以“降级”模式运行,只有一个驱动器。镜像被告知忘记当前未连接的驱动器:
xxxxxxxxxx# gmirror forget gm0应使用元数据问题中的说明从替换磁盘中清除任何旧元数据。然后将替换磁盘(本例中为ada4)插入镜像:
xxxxxxxxxx# gmirror insert gm0 /dev/ada4当新驱动器插入镜像时,重新同步开始。将镜像数据复制到新驱动器的过程可能需要一段时间。在复制过程中,镜像的性能将大大降低,因此最好在计算机需求较低时插入新驱动器。
可以使用 gmirror status 监视进度,该状态显示正在同步的驱动器和完成百分比。在重新同步过程中,状态将变为 DEGRADED ,当过程完成时,状态将更改为 COMPLETE 。
RAID3是一种使用专用奇偶校验磁盘将多个磁盘驱动器组合到单个卷中的方法。在RAID3系统中,数据被分割成多个字节,这些字节被写入阵列中的所有驱动器,除了一个充当专用奇偶校验磁盘的磁盘。这意味着从RAID3实现中读取的磁盘可以访问阵列中的所有磁盘。使用多个磁盘控制器可以提高性能。RAID3阵列提供1个驱动器的容错能力,同时提供阵列中所有驱动器总容量的1-1/n倍的容量,其中n是阵列中硬盘驱动器的数量。这种配置最适合存储较大大小的数据,如多媒体文件。
构建RAID3阵列至少需要3个物理硬盘。每个磁盘的大小必须相同,因为I/O请求是交错的,可以并行读取或写入多个磁盘。此外,由于RAID3的性质,驱动器的数量必须等于3、5、9、17等,或2^n+1。
本节演示如何在FreeBSD系统上创建软件RAID3。
xxxxxxxxxx虽然理论上可以在FreeBSD上从RAID3阵列启动,但这种配置并不常见,也不建议使用。在FreeBSD中,对RAID3的支持是由 graid3(8) GEOM类实现的。在FreeBSD上创建专用RAID3阵列需要以下步骤。
首先,通过发出以下命令之一加载 geom_raid3.ko 内核模块:
xxxxxxxxxx# graid3 load或:
xxxxxxxxxx# kldload geom_raid3确保存在合适的挂载点。此命令创建一个新目录用作挂载点:
xxxxxxxxxx# mkdir /multimedia确定将添加到阵列中的磁盘的设备名称,并创建新的RAID3设备。列出的最后一个设备将充当专用奇偶校验盘。此示例使用三个未分区的ATA驱动器:ada1和ada2用于数据,ada3用于奇偶校验。
xxxxxxxxxx# graid3 label -v gr0 /dev/ada1 /dev/ada2 /dev/ada3Metadata value stored on /dev/ada1.Metadata value stored on /dev/ada2.Metadata value stored on /dev/ada3.Done.对新创建的gr0设备进行分区,并在其上放置UFS文件系统:
xxxxxxxxxx# gpart create -s GPT /dev/raid3/gr0# gpart add -t freebsd-ufs /dev/raid3/gr0# newfs -j /dev/raid3/gr0p1许多数字会在屏幕上滑动,过一段时间,这个过程就会完成。卷已创建并准备装载:
xxxxxxxxxx# mount /dev/raid3/gr0p1 /multimedia/RAID3阵列现在可以使用了。
需要额外的配置才能在系统重新启动时保留此设置。
必须先加载 geom_raid3.ko 模块,然后才能安装阵列。要在系统初始化期间自动加载内核模块,请在 /boot/loader.conf 中添加以下行:
xxxxxxxxxxgeom_raid3_load="YES"必须将以下卷信息添加到 /etc/fstab 中,以便在系统启动过程中自动挂载阵列的文件系统:
xxxxxxxxxx/dev/raid3/gr0p1 /multimedia ufs rw 2 2一些主板和扩展卡添加了一些简单的硬件,通常只是一个ROM,允许计算机从RAID阵列启动。启动后,对RAID阵列的访问由计算机主处理器上运行的软件处理。这种 "hardware-assisted software RAID"(硬件辅助软件RAID)提供了不依赖于任何特定操作系统的RAID阵列,即使在加载操作系统之前也能正常工作。
根据使用的硬件,支持多种级别的RAID。请参阅 graid(8) 以获取完整列表。
graid(8) 需要 geom_raid.ko 内核模块,该模块从FreeBSD 9.1开始包含在GENERIC内核中。如果需要,可以使用 graid load 手动装载。
软件RAID设备通常有一个菜单,可以在计算机启动时按特殊键进入。该菜单可用于创建和删除RAID阵列。graid(8) 还可以直接从命令行创建数组。
graid label 用于创建新数组。此示例中使用的主板具有Intel软件RAID芯片组,因此指定了Intel元数据格式。新阵列的标签为 gm0 ,它是一个镜像(RAID1),并使用驱动器ada0和ada1。
xxxxxxxxxx当驱动器被创建为新阵列时,驱动器上的一些空间将被覆盖。先备份现有数据!xxxxxxxxxx# graid label Intel gm0 RAID1 ada0 ada1GEOM_RAID: Intel-a29ea104: Array Intel-a29ea104 created.GEOM_RAID: Intel-a29ea104: Disk ada0 state changed from NONE to ACTIVE.GEOM_RAID: Intel-a29ea104: Subdisk gm0:0-ada0 state changed from NONE to ACTIVE.GEOM_RAID: Intel-a29ea104: Disk ada1 state changed from NONE to ACTIVE.GEOM_RAID: Intel-a29ea104: Subdisk gm0:1-ada1 state changed from NONE to ACTIVE.GEOM_RAID: Intel-a29ea104: Array started.GEOM_RAID: Intel-a29ea104: Volume gm0 state changed from STARTING to OPTIMAL.Intel-a29ea104 createdGEOM_RAID: Intel-a29ea104: Provider raid/r0 for volume gm0 created.状态检查显示新镜像已准备好使用:
xxxxxxxxxx# graid status Name Status Components raid/r0 OPTIMAL ada0 (ACTIVE (ACTIVE)) ada1 (ACTIVE (ACTIVE))阵列设备出现在 /dev/raid/ 中。第一个数组称为 r0 。其他数组(如果存在)将是 r1 、r2 等。
其中一些设备上的BIOS菜单可以创建名称中带有特殊字符的阵列。为了避免这些特殊字符的问题,数组被赋予了简单的编号名称,如 r0 。要显示实际标签,如上例中的 gm0 ,请使用 sysctl(8) :
xxxxxxxxxx# sysctl kern.geom.raid.name_format=1某些软件RAID设备支持阵列上的多个 volume (卷)。卷的工作方式类似于分区,允许物理驱动器上的空间被拆分并以不同的方式使用。例如,Intel软件RAID设备支持两个卷。此示例创建了一个40G镜像用于安全存储操作系统,然后创建了一个子20G RAID0(条带)卷用于快速临时存储:
xxxxxxxxxx# graid label -S 40G Intel gm0 RAID1 ada0 ada1# graid add -S 20G gm0 RAID0卷在 /dev/raid/ 中显示为额外的rX条目。具有两个卷的数组将显示 r0 和 r1 。
有关不同软件RAID设备支持的卷数,请参阅 graid(8) 。
在某些特定条件下,可以将现有的单个驱动器转换为 graid(8) 阵列,而无需重新格式化。为了避免转换过程中的数据丢失,现有驱动器必须满足以下最低要求:
graid(8) 元数据覆盖和损坏。graid(8) 元数据。此元数据的大小各不相同,但最大的元数据占用64M,因此建议至少有这么多可用空间。如果驱动器满足这些要求,请首先进行完整备份。然后使用该驱动器创建一个单驱动器镜像:
xxxxxxxxxx# graid label Intel gm0 RAID1 ada0 NONEgraid(8) 元数据被写入驱动器末尾未使用的空间。现在可以将第二个驱动器插入镜像:
xxxxxxxxxx# graid insert raid/r0 ada1原始驱动器中的数据将立即开始复制到第二个驱动器。镜像将在降级状态下运行,直到复制完成。
驱动器可以插入阵列中,作为故障或丢失驱动器的替代品。如果没有出现故障或丢失的驱动器,则新驱动器将成为备用驱动器。例如,将新驱动器插入工作的双驱动器镜像会导致双驱动器镜像带有一个备用驱动器,而不是三驱动器镜像。
在示例镜像阵列中,数据立即开始复制到新插入的驱动器。新驱动器上的任何现有信息都将被覆盖。
xxxxxxxxxx# graid insert raid/r0 ada1GEOM_RAID: Intel-a29ea104: Disk ada1 state changed from NONE to ACTIVE.GEOM_RAID: Intel-a29ea104: Subdisk gm0:1-ada1 state changed from NONE to NEW.GEOM_RAID: Intel-a29ea104: Subdisk gm0:1-ada1 state changed from NEW to REBUILD.GEOM_RAID: Intel-a29ea104: Subdisk gm0:1-ada1 rebuild start at 0.可以从阵列中永久删除单个驱动器,并擦除其元数据:
xxxxxxxxxx# graid remove raid/r0 ada1GEOM_RAID: Intel-a29ea104: Disk ada1 state changed from ACTIVE to OFFLINE.GEOM_RAID: Intel-a29ea104: Subdisk gm0:1-[unknown] state changed from ACTIVE to NONE.GEOM_RAID: Intel-a29ea104: Volume gm0 state changed from OPTIMAL to DEGRADED.可以停止阵列,而无需从驱动器中删除元数据。系统启动后,阵列将重新启动。
xxxxxxxxxx# graid stop raid/r0可以随时检查阵列状态。在上述示例中将驱动器添加到镜像后,数据将从原始驱动器复制到新驱动器:
xxxxxxxxxx# graid status Name Status Components raid/r0 DEGRADED ada0 (ACTIVE (ACTIVE)) ada1 (ACTIVE (REBUILD 28%))如果磁盘发生故障,某些类型的阵列(如 RAID0 或 CONCAT )可能不会显示在状态报告中。要查看这些部分失败的数组,请添加 -ga :
xxxxxxxxxx# graid status -ga Name Status ComponentsIntel-e2d07d9a BROKEN ada6 (ACTIVE (ACTIVE))通过从数组中删除所有卷来销毁数组。删除最后一个卷后,阵列将停止,元数据将从驱动器中删除:
xxxxxxxxxx# graid delete raid/r0驱动器可能意外地(unexpectedly)包含来自以前使用或制造商测试的 graid(8) 元数据。graid(8) 将检测这些驱动器并创建一个阵列,干扰对单个驱动器的访问。要删除不需要的元数据,请执行以下操作:
启动系统。在引导菜单中,选择 2 作为加载器提示。输入:
xxxxxxxxxxOK set kern.geom.raid.enable=0OK boot系统将在禁用 graid(8) 的情况下启动。
备份受影响驱动器上的所有数据。
作为一种解决方法,可以通过添加以下内容到 /boot/loader.conf 来禁用 graid(8) 阵列检测
xxxxxxxxxxkern.geom.raid.enable=0要从受影响的驱动器中永久删除 graid(8) 元数据,请启动FreeBSD安装CD-ROM或记忆棒,然后选择 Shell 。使用 status 查找阵列的名称,通常为 raid/r0 :
xxxxxxxxxx# graid status Name Status Components raid/r0 OPTIMAL ada0 (ACTIVE (ACTIVE)) ada1 (ACTIVE (ACTIVE))按名称删除卷:
xxxxxxxxxx# graid delete raid/r0如果显示了多个卷,请对每个卷重复该过程。删除最后一个阵列后,卷将被销毁。
重新启动并验证数据,必要时从备份中还原。删除元数据后,也可以删除 /boot/loader.conf 中的 kern.geom.raid.enable=0 条目。
GEOM提供了一种简单的机制,通过使用GEOM Gate网络守护进程 ggated 提供对磁盘、CD和文件系统等设备的远程访问。带有该设备的系统运行服务器守护进程,该守护进程处理客户端使用 ggatec 发出的请求。设备不应包含任何敏感数据,因为客户端和服务器之间的连接未加密。
与网络文件系统(NFS)中讨论的NFS类似,ggated 是使用导出文件配置的。此文件指定允许哪些系统访问导出的资源以及提供的访问级别。例如,要让客户端 192.168.1.5 对第一个SCSI磁盘上的第四个切片进行读写访问,请使用以下行创建 /etc/gg.exports :
xxxxxxxxxx192.168.1.5 RW /dev/da0s4d导出设备之前,请确保当前未安装该设备。然后,开始 ggated :
xxxxxxxxxx# ggated有几个选项可用于指定备用侦听端口或更改导出文件的默认位置。详见 ggated(8) 。
要访问客户端计算机上的导出设备,首先使用 ggatec 指定服务器的IP地址和导出设备的设备名称。如果成功,此命令将显示要装载的 ggate 设备名称。将指定的设备名称装载到空闲装载点上。此示例连接到 192.168.1.1 上的 /dev/da0s4d 分区,然后在 /mnt 上挂载 /dev/ggate0 :
xxxxxxxxxx# ggatec create -o rw 192.168.1.1 /dev/da0s4dggate0# mount /dev/ggate0 /mnt现在可以通过客户端上的 /mnt 访问服务器上的设备。有关 ggatec 的更多详细信息和一些使用示例,请参阅 ggatec(8) 。
xxxxxxxxxx如果设备当前装载在服务器或网络上的任何其他客户端上,则装载将失败。如果需要同时访问网络资源,请改用NFS。当不再需要该设备时,使用 umount 卸载它,以便其他客户端可以使用该资源。
在系统初始化期间,FreeBSD内核会在找到设备时创建设备节点。这种探测设备的方法引发了一些问题。例如,如果通过USB添加新的磁盘设备怎么办?闪存设备可能会被赋予设备名称 da0 ,而原始 da0 可能会被转换为 da1 。如果文件系统列在 /etc/fstab 中,这将导致挂载文件系统的问题,这也可能阻止系统启动。
一种解决方案是按顺序链接SCSI设备,这样添加到SCSI卡的新设备将获得未使用的设备编号。但是,可能取代主SCSI磁盘的USB设备呢?这是因为USB设备通常在SCSI卡之前被探测。一种解决方案是仅在系统启动后插入这些设备。另一种方法是只使用一个ATA驱动器,永远不要在 /etc/fstab 中列出SCSI设备。
更好的解决方案是使用 glabel 标记磁盘设备,并使用 /etc/fstab 中的标签。由于 glabel 将标签存储在给定提供者的最后一个扇区中,因此标签在重新启动后将保持持久。通过将此标签用作设备,无论通过哪个设备节点访问文件系统,都可以始终挂载文件系统。
xxxxxxxxxxglabel可以创建瞬时和永久标签。只有永久标签在重新启动时是一致的。有关标签之间差异的更多信息,请参阅glabel(8)。永久标签可以是通用标签或文件系统标签。永久文件系统标签可以使用 tunefs(8) 或 newfs(8) 创建。这些类型的标签在 /dev 的子目录中创建,并将根据文件系统类型命名。例如,UFS2文件系统标签将在 /dev/ufs 中创建。通用永久标签可以用 glabel 标签创建。这些不是特定于文件系统的,将在 /dev/label 中创建。
临时标签将在下次重新启动时销毁。这些标签是在 /dev/label 中创建的,适合实验。可以使用 glabel create 创建临时标签。
要为UFS2文件系统创建永久标签而不销毁任何数据,请发出以下命令:
xxxxxxxxxx# tunefs -L home /dev/da3现在,/dev/ufs 中应该存在一个标签,可以将其添加到 /etc/fstab 中:
xxxxxxxxxx/dev/ufs/home /home ufs rw 2 2xxxxxxxxxx在尝试运行tunefs时,不得挂载文件系统。现在可以挂载文件系统:
xxxxxxxxxx# mount /home从这一点开始,只要在引导时使用 /boot/loader.conf 加载 geom_label.ko 内核模块,或者存在 GEOM_LABEL 内核选项,设备节点就可以更改,而不会对系统产生任何不良影响。
文件系统也可以通过在 newfs 中使用 -L 标志来创建默认标签。有关更多信息,请参阅 newfs(8) 。
以下命令可用于销毁标签:
xxxxxxxxxx# glabel destroy home以下示例显示了如何标记启动磁盘的分区。
示例32. 在引导磁盘上标记分区
通过在引导磁盘上永久标记分区,即使磁盘被移动到另一个控制器或转移到不同的系统,系统也应该能够继续正常引导。对于此示例,假设使用单个ATA磁盘,该磁盘当前被系统识别为ad0。还假设使用标准的FreeBSD分区方案,包括/、/var,/usr 和 /tmp ,以及交换分区。
重新启动系统,在 loader(8) 提示下,按 4 启动到单用户模式。然后输入以下命令:
xxxxxxxxxx# glabel label rootfs /dev/ad0s1aGEOM_LABEL: Label for provider /dev/ad0s1a is label/rootfs# glabel label var /dev/ad0s1dGEOM_LABEL: Label for provider /dev/ad0s1d is label/var# glabel label usr /dev/ad0s1fGEOM_LABEL: Label for provider /dev/ad0s1f is label/usr# glabel label tmp /dev/ad0s1eGEOM_LABEL: Label for provider /dev/ad0s1e is label/tmp# glabel label swap /dev/ad0s1bGEOM_LABEL: Label for provider /dev/ad0s1b is label/swap# exit系统将继续进行多用户引导。引导完成后,编辑 /etc/fstab 并将常规设备名称替换为各自的标签。最后的 /etc/fstab 看起来像这样:
xxxxxxxxxx# 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现在可以重新启动系统。如果一切顺利,它将正常出现, mount 将显示:
xxxxxxxxxx# 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) 类支持基于唯一文件系统id ufsid 的UFS文件系统标签类型。这些标签可以在 /dev/ufsid 中找到,并在系统启动时自动创建。可以使用 ufsid 标签通过 /etc/fstab 挂载分区。使用 glabel status 接收文件系统及其相应 ufsid 标签的列表:
xxxxxxxxxx% glabel status Name Status Componentsufsid/486b6fc38d330916 N/A ad4s1dufsid/486b6fc16926168e N/A ad4s1f在上面的例子中,ad4s1d 表示 /var ,而 ad4s1f 表示 /usr 。使用所示的 ufsid 值,这些分区现在可以在 /etc/fstab 中挂载以下条目:
xxxxxxxxxx/dev/ufsid/486b6fc38d330916 /var ufs rw 2 2/dev/ufsid/486b6fc16926168e /usr ufs rw 2 2任何带有 ufsid 标签的分区都可以通过这种方式挂载,无需手动创建永久标签,同时仍然可以享受独立于设备名称挂载的好处。
FreeBSD支持UFS文件系统上的期刊。该实现是通过GEOM子系统提供的,并使用 gjournal 进行配置。与其他文件系统日志实现不同, gjournal 方法是基于块的,不是作为文件系统的一部分实现的。这是GEOM的延伸。
日志记录在元数据和文件写入提交到磁盘之前,存储文件系统事务的日志,例如构成完整磁盘写入操作的更改。稍后可以重放此事务日志以重做文件系统事务,从而防止文件系统不一致。
这种方法提供了另一种机制来防止数据丢失和文件系统的不一致。与跟踪和强制元数据更新的软更新和创建文件系统映像的快照不同,日志是专门为此任务存储在磁盘空间中的。为了获得更好的性能,日志可以存储在另一个磁盘上。在此配置中,日志提供程序或存储设备应列在设备后面,以便在上启用日志记录。
GENERIC内核为 gjournal 提供支持。要在启动时自动加载 geom_journal.ko 内核模块,请在 /boot/loader.conf 中添加以下行:
xxxxxxxxxxgeom_journal_load="YES"如果使用自定义内核,请确保内核配置文件中有以下行:
xxxxxxxxxxoptions GEOM_JOURNAL加载模块后,可以使用以下步骤在新的文件系统上创建日志。在这个例子中,da4是一个新的SCSI磁盘:
xxxxxxxxxx# gjournal load# gjournal label /dev/da4这将加载模块并在 /dev/da4 上创建 /dev/da4.journal 设备节点。
现在可以在日志设备上创建UFS文件系统,然后将其挂载到现有的挂载点上:
xxxxxxxxxx# newfs -O 2 -J /dev/da4.journal# mount /dev/da4.journal /mntxxxxxxxxxx对于多个切片,将为每个单独的切片创建一个日志。例如,如果ad4s1和ad4s2都是切片,那么gjournal将创建ad4s1.journal和ad4s2.journal。也可以通过使用 tunefs 在当前文件系统上启用日志记录。但是,在尝试更改现有文件系统之前,请务必进行备份。在大多数情况下,如果 gjournal 无法创建日志,它将失败,但这并不能防止因误用 tunefs 而导致的数据丢失。有关这些命令的更多信息,请参阅 gjournal(8) 和 tunefs(8) 。
可以记录FreeBSD系统的引导磁盘。有关详细说明,请参阅“在台式PC上实现UFS日志”一文。