FreeBSD 中文社区翻译文章存档
FreeBSD 中文社区
  • FreeBSD 网络文章集锦
  • 2025 年
    • BSD 许可证一览
    • FreeBSD 上的 ZFS 日志压缩
    • 为 FreeBSD 发声:FOSDEM 2025 参会报告
    • zfs 速查手册
    • FreeBSD 开发计划
    • 谁在使用 FreeBSD(基金会官方版本)
    • FreeBSD 特色开发项目
    • 如何将基于 Electron 的应用程序移植到 FreeBSD
    • FreeBSD:原始操作系统发行版的火炬传承者
    • 浏览 FreeBSD 新的季度和两年一次发布计划
    • FreeBSD 日专访 BSD 守护神 Beastie
  • 2024 年 11 月
    • 苹果的开源基石:macOS 和 iOS 背后的 BSD 传统
    • 在动荡的开源世界中保持稳定:FreeBSD 的持久稳定性
    • 为什么你应该使用 FreeBSD
    • FreeBSD 13.4: 新特性及其发展历程
    • Quantum Leap Research 和 FreeBSD 基金会将投资 75 万美元以改善笔记本电脑支持和用户体验
    • 主权科技基金将投资 68.64 万欧元用于 FreeBSD 基础设施现代化
  • 2024 年 7 月
    • BSD 老将:Michael J. Karels 逝世,享年 68 岁
    • 讣告——Michael "Mike" John Karels
    • 配置自己的 VPN——基于 OpenBSD、Wireguard、IPv6 和广告拦截
    • 如何在 FreeBSD 中指定 CPU 类型
    • 使用 BIOS 引导和 UEFI 引导的 GPT 分区的区别和制作方法
    • 通过替换 ZFS 镜像池中的磁盘来扩容
    • 通过将 ZFS 池构建为镜像结构,消除异常数据的影响
    • ZFS 池破坏实验
    • FreeBSD ports 开发技术研究
    • FreeBSD pkg 命令概述
    • portsnap 被淘汰了,本应由 git 代替,但结果我发现自己用的是 got
    • ccache 在构建 FreeBSD 的 buildworld 时的效率
    • 关于对 FreeBSD 发布计划和生命周期的修订
  • 2023 年 12 月
    • FreeBSD 新手?来参与社区吧
    • 介绍来 FreeBSD 的学生
    • EuroBSDCon 2023 旅行报告——Bojan Novković
    • 什么是开发播客?FreeBSD 项目的演变
    • EuroBSDCon 2023 旅行报告——Mark Johnston
    • TalkDev:探索开源的未来
    • 为什么选择 FreeBSD?Metify 展示迁移到 FreeBSD 如何对两个新产品进行增强
    • FreeBSD 基金会宣布通过 SSDF 认证
    • 2023 年全球开放大会报告
    • FreeBSD v14:恪守类 Unix 操作系统传统,提升安全性与性能
  • 2023 年 9 月
    • 认识 2023 年参与 FreeBSD 谷歌编程之夏项目的学生:Soobin Rho
    • 认识 2023 年参与 FreeBSD 谷歌编程之夏项目的学生:Aymeric Wibo
    • FreeBSD 企业工作组首次会议总结
    • 认识 2023 年 FreeBSD 谷歌编程之夏的学生:Sudhanshu Mohan Kashyap
    • 认识 2023 年夏季滑铁卢大学合作学生:Naman Sood
    • FreeBSD 基金会 2023 年暑期实习生:Jake Freeland
    • 第二次企业工作组会议回顾
    • OpenBSD 与 FreeBSD:有何不同,哪个更好?
  • 2023 年 9 月以前
    • 在 FreeBSD 的 jail 中安装 NextCloud
    • 参与宣传:2023 年 5 月的 FreeBSD 开发者峰会和 BSDCan
    • 恭喜 FreeBSD 迎来 30 周年!为什么开源项目 FreeBSD 能够持续存在
    • 庆祝 FreeBSD 成立 30 周年:许可证
    • 聚集在开放领域工作的公益和慈善基金会
    • 在 Linode 上安装 pfSense
    • 在 FreeBSD 的 jail 中安装 NextCloud
    • 将 FreeBSD 上的 Ansible 主机和客户机都安装在 Jail 中
    • FreeBSD 简介 | BSD.pw 研讨会
    • 如何在 FreeBSD 上安装 Python
    • 升级到 FreeBSD 13.2 的十大理由
    • 采访 FreeBSD 基金会执行董事 Deb Goodkin
    • 我们使用开源的 FreeBSD 作为企业操作系统的 5 个原因
    • 关于 BSD 与 Linux 的典型讨论
    • OpenBSD 太棒了
    • systemd 背后的真正动机
    • systemd 在任何地方都不安全
    • 为什么你应该将所有东西从 Linux 迁移到 BSD
    • 如何在 FreeBSD 上设置一个简单且实际工作的 WireGuard 服务器
    • 选择 FreeBSD 而非 GNU/Linux 的技术性原因
    • GPL 之殇
    • FreeBSD 与研究社区
    • 在 OpenBSD 和 FreeBSD 之间选择的区别
    • FreeBSD 是一个令人惊叹的操作系统
    • 留意日期:2023 年 11 月的自由软件组织厂商峰会
    • JENNY 日常使用的系统:FreeBSD 13.2
    • FreeBSD Ports 中的 OPTIONS 功能介绍——使用 OPTIONS_SET/OPTIONS_UNSET/NO_DIALOG 进行操作和实践
    • FreeBSD Bhyve 上的 PCI 直通
    • 2023 年 FreebBSD 谷歌编程之夏学生介绍:Raghav Sharma
    • 2023 年 7 月软件开发项目进展报道
    • 用于研究的 FreeBSD:CHERI/Morello
    • 在 FreeBSD Jail 中使用 OpenRC 启动并运行 Devuan GNU+Linux 系统
由 GitBook 提供支持

FreeBSD 中文社区

在本页
  • 引言
  • 为实验磁盘创建分区
  • 创建 ZFS 池
  • 写入虚拟数据
  • 故意破坏数据以制造不一致
  • 检查是否损坏
  • 修复损坏部分并确认

这有帮助吗?

在GitHub上编辑
导出为 PDF
  1. 2024 年 7 月

ZFS 池破坏实验

上一页通过将 ZFS 池构建为镜像结构,消除异常数据的影响下一页FreeBSD ports 开发技术研究

最后更新于11天前

这有帮助吗?

  • 原文:

  • 作者:みんみん

  • 最后更新于 2022-12-08

引言

ZFS 文件系统本身就内置了校验和机制,在读取数据时会实时检查校验和与数据的完整性,确保数据没有损坏。

执行命令 zpool scrub 后,会读取所有已写入的数据部分并与校验和进行一致性检查。如果在 scrub 过程中发现了错误,在具有冗余结构(如镜像或 RAID-Z 等)的情况下,错误会被自动修复。

在这里,我们将实验性地修改 ZFS 管理范围外的数据,故意制造校验和不一致的情况,以引发数据错误。

本实验在 FreeBSD 上进行,但如果是在 Ubuntu 等 Linux 系统上的 ZFS,虽然分区创建和磁盘设备名称可能会有所不同,但 ZFS 操作的命令是相同的。

为实验磁盘创建分区

首先,创建实验用的 ZFS 池。我们将在 USB 磁盘 da1 上进行实验。

准备一块带 GPT 标签的磁盘。

$ gpart create -s gpt da1

创建一个 4GB 的分区。

$ gpart add -t freebsd-zfs -a 4k -s 4g -l ttt da1

检查创建的分区。

$ gpart show da1
=>       40  312581728  da1  GPT  (149G)
         40    8388608    1  freebsd-zfs  (4.0G)
    8388648  304193120       - free -  (145G)

$ gpart show -l da1
=>       40  312581728  da1  GPT  (149G)
         40    8388608    1  ttt  (4.0G)
    8388648  304193120       - free -  (145G)

创建 ZFS 池

通常情况下,为了节省磁盘空间,当创建 ZFS 池时会使用 -O compression=lz4 等选项启用压缩功能,但本次实验为了写入零数据而没有启用压缩选项。因为启用压缩后,数据压缩会导致数据大小无法被实际写入。

$ zpool create -O atime=off ztest gpt/ttt

检查创建的 ZFS 池。

$ zpool status ztest
  pool: ztest
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        ztest       ONLINE       0     0     0
          gpt/ttt   ONLINE       0     0     0

errors: No known data errors

写入虚拟数据

Scrub 只会检查已经写入的数据部分的完整性。为了破坏已写入的数据,我们将首先创建一个内容为零的文件。

进入 ZFS 池内的目录。

$ cd /ztest

使用 dd 命令从 /dev/zero 读取虚拟数据(即零数据)并填充整个池。

$ dd if=/dev/zero of=dummy bs=4m
dd: dummy: No space left on device
928+0 records in
927+1 records out
3891134464 bytes transferred in 157.300331 secs (24736976 bytes/sec)
$

可以看到,池已被填满。此处我们显式使用 -b 选项以便查看块数。

$ df -b /ztest
Filesystem 512-blocks    Used Avail Capacity  Mounted on
ztest         7601024 7601024     0   100%    /ztest

故意破坏数据以制造不一致

池已填满后,我们将故意制造 ZFS 校验和错误。由于通过 ZFS 进行的修改无法破坏数据,我们将从 ZFS 管理外部向磁盘写入垃圾数据。

首先导出池。

$ zpool export ztest

接着在相关分区的适当位置写入一个块的垃圾数据。

$ dd if=/dev/random of=/dev/gpt/ttt count=1 oseek=4000000
1+0 records in
1+0 records out
512 bytes transferred in 0.382043 secs (1340 bytes/sec)
$

检查是否损坏

导入池并尝试读取之前创建的文件

$ zpool import ztest
$ cat /ztest/dummy > /dev/null
cat: /ztest/dummy: Input/output error
$

如上所示,发生了错误。池的状态如下,乍一看似乎没有错误。

$ zpool status ztest
  pool: ztest
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        ztest       ONLINE       0     0     0
          gpt/ttt   ONLINE       0     0     0

errors: No known data errors
$

尝试执行 scrub。

$ zpool scrub ztest
$ zpool status ztest
  pool: ztest
 state: ONLINE
  scan: scrub in progress since Mon Aug 29 18:17:33 2022
        3.62G scanned at 412M/s, 550M issued at 61.1M/s, 3.62G total
        0B repaired, 14.81% done, 00:00:51 to go
config:

        NAME        STATE     READ WRITE CKSUM
        ztest       ONLINE       0     0     0
          gpt/ttt   ONLINE       0     0     0

errors: No known data errors
$ 

等待 scrub 完成后,使用 status 进行确认。

$ zpool status ztest
  pool: ztest
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A
  scan: scrub repaired 0B in 00:01:05 with 1 errors on Mon Aug 29 18:18:32 2022
config:

        NAME        STATE     READ WRITE CKSUM
        ztest       ONLINE       0     0     0
          gpt/ttt   ONLINE       0     0     2

errors: 1 data errors, use '-v' for a list
$

可以看到,CKSUM 发生了错误。实际损坏的文件可以通过选项 -v 进行确认。

$ zpool status -v ztest
  pool: ztest
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A
  scan: scrub repaired 0B in 00:01:05 with 1 errors on Mon Aug 29 18:18:32 2022
config:

        NAME        STATE     READ WRITE CKSUM
        ztest       ONLINE       0     0     0
          gpt/ttt   ONLINE       0     0     2

errors: Permanent errors have been detected in the following files:

        /ztest/dummy
$

重新读取 /ztest/dummy 时,错误依旧存在。

$ cat /ztest/dummy > /dev/null
cat: /ztest/dummy: Input/output error
$

修复损坏部分并确认

接下来,通过重新写 0 来恢复损坏的部分。

$ zpool export ztest
$ dd if=/dev/zero of=/dev/gpt/ttt count=1 oseek=4000000
1+0 records in
1+0 records out
512 bytes transferred in 0.382715 secs (1338 bytes/sec)
$

这应该已经将数据恢复到原状态,再次尝试读取。

$ zpool import ztest
$ cat /ztest/dummy > /dev/null
$

如上所示,读取成功且没有错误。虽然 zpool status 中的错误信息依然存在,但 CKSUM 的错误计数已经变为 0。

$ zpool status ztest
  pool: ztest
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A
  scan: scrub repaired 0B in 00:01:05 with 1 errors on Mon Aug 29 18:18:32 2022
config:

        NAME        STATE     READ WRITE CKSUM
        ztest       ONLINE       0     0     0
          gpt/ttt   ONLINE       0     0     0

errors: 1 data errors, use '-v' for a list
$

重新执行 scrub

$ zpool scrub ztest

scrub 完成后,检查池的状态。

$ zpool status ztest
  pool: ztest
 state: ONLINE
  scan: scrub repaired 0B in 00:01:05 with 0 errors on Mon Aug 29 18:34:27 2022
config:

        NAME        STATE     READ WRITE CKSUM
        ztest       ONLINE       0     0     0
          gpt/ttt   ONLINE       0     0     0

errors: No known data errors
$

如上所示,错误已消失。

ZFS プールを壊してみた