# 21.5.软件 RAID 设备

一些主板和扩展卡会添加一些简单的硬件，通常只是一个 ROM，使计算机能够从 RAID 阵列启动。启动后，RAID 阵列的访问由计算机的主处理器运行的软件处理。这种“硬件辅助软件 RAID”使 RAID 阵列不依赖于任何特定操作系统，并且在操作系统加载之前就可以使用。

根据使用的硬件，支持多种 RAID 等级。有关完整列表，请参见 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html)。

[graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 需要 **geom\_raid.ko** 内核模块，FreeBSD 9.1 及以后版本的 **GENERIC** 内核中已包含此模块。如果需要，可以使用 `graid load` 手动加载。

## 21.5.1. 创建阵列

软件 RAID 设备通常有一个菜单，可以通过在计算机启动时按下特定的键进入。该菜单可以用来创建和删除 RAID 阵列。也可以直接从命令行使用 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 创建阵列。

`graid label` 用于创建一个新阵列。此示例使用的主板具有 Intel 软件 RAID 芯片组，因此指定了 Intel 元数据格式。新阵列被命名为 **gm0**，它是一个镜像（RAID1），并使用磁盘 **ada0** 和 **ada1**。

> **当心**
>
> 当磁盘被转换为新阵列时，会覆盖其中的一些空间。请首先备份现有数据！

```sh
# graid label Intel gm0 RAID1 ada0 ada1
GEOM_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 created
GEOM_RAID: Intel-a29ea104: Provider raid/r0 for volume gm0 created.
```

状态检查显示新镜像已准备好使用：

```sh
# graid status
   Name   Status  Components
raid/r0  OPTIMAL  ada0 (ACTIVE (ACTIVE))
                  ada1 (ACTIVE (ACTIVE))
```

阵列设备出现在 **/dev/raid/** 中。第一个阵列被命名为 **r0**，如果存在其他阵列，则依次命名为 **r1**、**r2** 等。

这些设备的 BIOS 菜单可以创建带有特殊字符的阵列名称。为了避免特殊字符的问题，阵列被赋予简单的编号名称，如 **r0**。要显示实际的标签（如上面示例中的 **gm0**），可以使用 [sysctl(8)](https://man.freebsd.org/cgi/man.cgi?query=sysctl\&sektion=8\&format=html)：

```sh
# sysctl kern.geom.raid.name_format=1
```

## 21.5.2. 多个卷

某些软件 RAID 设备支持在阵列上创建多个 *卷*。卷的工作方式类似于分区，允许将物理磁盘上的空间拆分并以不同方式使用。例如，Intel 软件 RAID 设备支持两个卷。此示例创建一个 40G 的镜像卷，用于安全存储操作系统，然后创建一个 20G 的 RAID0（条带化）卷，用于快速临时存储：

```sh
# graid label -S 40G Intel gm0 RAID1 ada0 ada1
# graid add -S 20G gm0 RAID0
```

卷作为额外的 **rX** 条目出现在 **/dev/raid/** 中。具有两个卷的阵列将显示 **r0** 和 **r1**。

请参阅 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 了解不同软件 RAID 设备支持的卷数量。

## 21.5.3. 将单个磁盘转换为镜像

在某些特定条件下，可以将现有的单个磁盘转换为 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 阵列，而不需要重新格式化。为了避免在转换过程中丢失数据，现有的磁盘必须满足以下最低要求：

* 磁盘必须使用 MBR 分区方案。使用 GPT 或其他具有元数据位于磁盘末尾的分区方案将被 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 元数据覆盖并损坏。
* 磁盘末尾必须有足够的未分区和未使用的空间来存放 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 元数据。此元数据的大小会有所不同，但最大值为 64M，因此建议至少有该大小的空闲空间。

如果磁盘满足这些要求，首先进行完整备份。然后，使用该磁盘创建一个单盘镜像：

```sh
# graid label Intel gm0 RAID1 ada0 NONE
```

[graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 元数据已写入磁盘末尾的空闲空间。现在可以将第二个磁盘插入到镜像中：

```sh
# graid insert raid/r0 ada1
```

原始磁盘的数据将立即开始复制到第二个磁盘。直到复制完成之前，镜像将处于降级状态。

## 21.5.4. 向阵列中插入新磁盘

可以将磁盘插入阵列，作为替代已故障或缺失的磁盘。如果没有故障或缺失的磁盘，则新磁盘将作为备用磁盘。例如，将新磁盘插入到正常工作的两个磁盘镜像中，将得到一个包含一个备用磁盘的两个磁盘镜像，而不是三个磁盘的镜像。

在示例镜像阵列中，数据立即开始复制到新插入的磁盘。新磁盘上的任何现有信息将被覆盖。

```sh
# graid insert raid/r0 ada1
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 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.
```

## 21.5.5. 从阵列中移除磁盘

可以将单个磁盘从阵列中永久移除，并擦除其元数据：

```sh
# graid remove raid/r0 ada1
GEOM_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.
```

## 21.5.6. 停止阵列

可以停止阵列，而不从磁盘中移除元数据。系统启动时，阵列将被重新启动。

```sh
# graid stop raid/r0
```

## 21.5.7. 检查阵列状态

可以随时检查阵列状态。在上面的示例中，将磁盘添加到镜像中后，数据正在从原始磁盘复制到新磁盘：

```sh
# graid status
   Name    Status  Components
raid/r0  DEGRADED  ada0 (ACTIVE (ACTIVE))
                   ada1 (ACTIVE (REBUILD 28%))
```

某些类型的阵列，如 `RAID0` 或 `CONCAT`，如果磁盘发生故障，可能不会在状态报告中显示。要查看这些部分故障的阵列，可以添加 `-ga` 选项：

```sh
# graid status -ga
          Name  Status  Components
Intel-e2d07d9a  BROKEN  ada6 (ACTIVE (ACTIVE))
```

## 21.5.8. 删除阵列

通过删除阵列中的所有卷来销毁阵列。当最后一个卷被删除时，阵列将停止，且磁盘上的元数据将被移除：

```sh
# graid delete raid/r0
```

## 21.5.9. 删除意外的阵列

磁盘可能意外地包含 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 元数据，这可能是由于之前的使用或制造商测试所致。 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 会检测到这些磁盘并创建一个阵列，从而干扰对单个磁盘的访问。要移除不需要的元数据：

1. 启动系统。在启动菜单中，选择 `2` 进入加载器提示符。输入：

   ```sh
   OK set kern.geom.raid.enable=0
   OK boot
   ```

   系统将以禁用 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 的方式启动。
2. 对受影响的磁盘进行完整备份。
3. 作为解决方法，可以通过在 **/boot/loader.conf** 文件中添加以下内容来禁用 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 阵列检测：

   ```sh
   kern.geom.raid.enable=0
   ```

   要永久删除受影响磁盘上的 [graid(8)](https://man.freebsd.org/cgi/man.cgi?query=graid\&sektion=8\&format=html) 元数据，可以启动 FreeBSD 安装 CD-ROM 或内存棒，并选择 `Shell`。使用 `status` 命令查找阵列的名称，通常是 `raid/r0`：

   ```sh
   # graid status
      Name   Status  Components
   raid/r0  OPTIMAL  ada0 (ACTIVE (ACTIVE))
                     ada1 (ACTIVE (ACTIVE))
   ```

   通过名称删除卷：

   ```sh
   # graid delete raid/r0
   ```

   如果显示了多个卷，针对每个卷重复该过程。在删除最后一个阵列后，卷将被销毁。

   重新启动并验证数据，必要时从备份恢复。删除元数据后，可以移除 **/boot/loader.conf** 中的 `kern.geom.raid.enable=0` 条目。
