作者:PAWEL DAWIDEK
译者:ykla 【】为译者注
ZFS 文件系统进入 FreeBSD 操作系统的故事是一段对编程的热情、对技术的热爱,以及是一个引导我做出最有价值贡献于 FreeBSD 项目的旅程。那是在 2005 年的夏天。虽然我不太擅长记日期,但我还记得我第一次接触 ZFS 的情境:当时我和朋友们在波兰的马祖里地区,这里有 2000 多个美丽的湖泊。我的其中一位朋友当时在波兰的一个电信公司工作,他们使用了大量来自 Sun Microsystems 的硬件和 Solaris 操作系统。他带来了一份 Sun 发来的通知的打印副本,其中描述了一个新的文件系统,它经过了一段时间的开发,即将作为 OpenSolaris 的一部分发布。但在继续讲述这个故事之前,让我们回到过去,来了解一些背景信息...
我对编程一见钟情。那时我 12 岁,我的表亲向我介绍了 C-64 上的 BASIC 编程语言。
爱情初见!
我对编程一见钟情。那时我 12 岁,我的表弟 Tomek 向我介绍了 C-64 上的 BASIC 编程语言。我被迷住了。我感觉自己像一个年轻的上帝:你拿起这个无生命的硬件,创建一个程序,然后看着它活了起来!这太酷了;我无法想象还有什么比这更棒的事情了。因此,我从未对电子游戏感兴趣。那时,我在波兰一个小镇长大,并不容易找到对编程感兴趣的人,所以我基本上是独自一人(除非是在测试 Tomek 的耐心极限)。
当我转向 Amiga 500 【即 Amiga 家用电脑的第一款低端版本】后,我终于找到了一些来自演示场景的朋友,我们通过邮件用 3.5 英寸软盘交换我的作品。等待并不是一件好事,但我没有抱怨。当我的下一台计算机——Amiga 1200 开始显得老旧时,很明显是时候继续前进了。我知道微软的 Windows 不适合我。我尝试过 Linux,但还不是很满意。最后,一个朋友向我介绍了 FreeBSD。他的安装非常简单,我再也不能要求比这更好的体验了。哈!如果你对最后一句话没有感到不安,那么显然你还没有享受过使用 sysinstall 【现在为 bsdinstall】的“乐趣”。不,安装并不是一件轻松的事情——我尝试了多次才终于享受到了我的第一个 FreeBSD 系统。我认为 sysinstall 一定就像海军海豹突击队的地狱周那样,让强者从弱者中分离出来,使真正的黑客在那里锻造!而我成功了!我设定了下一个目标和梦想,不仅要成为一个能够安装 FreeBSD 的黑客,还要成为一个内核黑客和 FreeBSD 的贡献者。
在 2003 年,我正式加入 FreeBSD 项目,成为了 src 提交者,实现了自己的目标。是的,我为此举办了派对来庆祝。自从我加入以来,我在系统的许多领域工作过,但主要是与 GEOM 框架相关。在 FreeBSD 中,GEOM 框架位于磁盘驱动程序和文件系统之间,允许插件实现各种转换,比如镜像、RAID、块级加密等。我真的很喜欢 GEOM 的设计,并且喜欢与之一起工作,所以我在存储栈的至少这一部分有相当的经验。至于文件系统,我知道必须远离 VFS,因为它是内核中最复杂的部分之一。
可悲的是,UFS 自 FreeBSD 成立以来就一直是默认文件系统。实际上,UFS 比 FreeBSD 本身还要古老。UFS2 在 FreeBSD 5.0 中被引入,解决了 UFS1 的一些问题,但仍然存在一些重要的问题没有解决。主要问题是在系统崩溃或停电后进行 fsck 所需的时间。随着磁盘越来越大,fsck 可能需要花费几个小时才能完成。解决这个问题的方法显而易见——我们需要将日志记录添加到 UFS 中,或者将其他带有日志记录功能的文件系统移植到 FreeBSD。说起来容易做起来难。在 Linux 中,有很多文件系统可供选择,很多人试图将它们移植到 FreeBSD,但出于某种奇怪的原因,这些移植从未完成,因此我们最终得到了没有日志记录功能的 extfs,只读的 ReiserFS 和只读的 XFS。甚至还有一个来自 Mac OS X 的可读写的 HFS+ 移植,但是,当然,没有日志记录功能,并且我还记得至少有一次试图给 UFS 添加日志记录的失败尝试。这是怎么回事?UNIX 之神是否背弃了我们?
让我们回到我在马祖里亚的度假时刻。我的朋友开始阅读 ZFS 的公告,而我的眼睛和嘴巴越张越大:池化存储——你可以创建任意多的文件系统,它们将共享可用空间。无限快照,创建起来不费时间。无限克隆。内建压缩。端到端数据验证。自动修复受损数据。事务性写时复制模型——始终保持一致——永远不需要进行 fsck(文件系统检查)。这是怎么回事?这怎么可能?这不仅仅是改进,而是文件系统的彻底革命。我记得我曾梦想过这个完美的结合:最好的文件系统运行在最好的操作系统上……那将会是多么令人惊奇啊?
几个月后,ZFS 正式发布了,它不仅在开源社区中引起轰动,而且在整个存储行业都掀起了风暴。有些人讨厌它,大多数人喜欢它,还有一些人害怕它,但没有人忽视它。有人称它为文件系统的终极之选,有人称它为狂热的分层违规【"狂热的分层违规"是对 ZFS 的一种负面评价,意指在设计中使用了过多的分层或复杂的架构。通常情况下,过多的分层和复杂的设计会增加代码的复杂性和难以理解性,可能导致维护和调试变得困难。在软件开发中,应该尽量保持简洁和清晰的设计,避免过多的分层和复杂性,以提高代码的可维护性和可读性。】。然而,它从未被称为又一个普通的文件系统。几乎每个操作系统都想要 ZFS:Linux 用户空间 port 在 FUSE 下启动,DragonFlyBSD 【该系统至今仍未支持 ZFS】宣布即将移植 ZFS,而苹果也开始将 ZFS 移植到 Mac OS X。ZFS 很快将无处不在,只是不在我们所钟爱的 FreeBSD 中...
为了撰写这篇文章,我不得不分析很多当时的 IRC 日志。让我印象最深的是关于 ZFS 本身有多少怀疑态度:太复杂了,层次太多了,只是个样子货,设计缺陷很快就会被发现,等着瞧第一个灾难故事的发生吧,它永远不会被移植到社区开发的操作系统,这只是炒作,太可笑了。我想人们习惯了一个道理,如果某事看起来太美好了,往往就是真的太美好了【即太好的东西常常是假的】。幸运的是,爱是盲目的,我当时并没有注意到这一点。
在 ZFS 发布后等待了 10 个月,我却没有看到有人开始工作,于是我想我不妨一试。虽然我对 VFS 层几乎一无所知,很可能很快就会失败,但谁能阻止我尝试呢?至少,我能学到一些新东西。我的移植工作始于 2006 年 8 月 12 日。为了不让人们抱太高的希望,我创建的 perforce 【软件存储库】分支的描述是“This is not a ZFS port!”(这不是 ZFS 的移植!)。我最初的估计是用六个月的时间完成一个只读的原型。
我必须承认,虽然 ZFS 不是我创建的,但在 ZFS 上的工作是我职业生涯中最吸引人的项目。我喜欢努力工作,我喜欢工作到很晚。我喜欢全神贯注于项目,而且我有幸参与了许多令人惊叹的项目。多年来,我是 FreeBSD 中最有成效的提交者之一,同时还在发展自己的业务。但没有其他项目能让我连续工作 48 个小时,几乎没有休息,只在这 48 个小时之间短暂地打个盹。我现在告诉你的事情听起来可能对我来说都有些不可思议,但它确实发生过,我向你保证 :)
在处理大型项目时,我仍然希望尽快运行某些内容,然后逐步实现缺失的部分。第一步是移植用户空间组件,如 libzpool、ztest 和 zdb。这基本上还好。下一个挑战是编译和加载 ZFS 内核模块。当你尝试加载一个带有缺失符号的内核模块时,FreeBSD 内核链接器会报告第一个缺失的符号并返回错误。我有太多的缺失符号,以至于我不得不修改链接器以一次报告它们所有的错误。对它们的逐个修复花费了太多时间。五天后,我第一次加载了 zfs.ko。理论上,FreeBSD 内核和 ZFS 代码之间有四个主要的接触点:
在堆栈的底部,我们需要教会 ZFS 如何与 FreeBSD 的块设备通信,这意味着将 ZFS 连接到 GEOM(在 GEOM 术语中是创建一个仅消费的 GEOM 类)。由于我对 GEOM 有经验,这个部分很简单。
在堆栈的顶部,我们需要将 ZFS 连接到 FreeBSD 的 VFS,因此需要移植 ZPL 层。
同样,在堆栈的顶部,ZFS 存储可以通过 ZVOL访问,因为 ZVOLs 是块设备,所以这还涉及到 GEOM,但这次是提供者 -only 的 GEOM 类。
最后一个组件是 /dev/zfs 设备,它由用户空间的 ZFS 工具(zfs(8)和 zpool(8))与 ZFS 内核模块进行通信。
将 ZPL 层移植并将 ZFS 连接到 FreeBSD 的 VFS 当然是最困难的部分。在 FreeBSD 上的第一次内核挂载发生在 2006 年 8 月 19 日,也就是一个星期后。经过十昼夜的工作,我已经准备好了一个读写原型。我可以创建池、创建文件系统并挂载它们,创建行为非常稳定的 ZVOL,创建文件和目录,列出它们,以及更改权限和所有权。我最初估计的六个月的只读原型时间表明,“有点”偏离了。尽管还有大量工作要做,但来自社区的鼓励给了我继续和完成项目所需的动力。在 2007 年,ZFS 在 FreeBSD 7.0 中以实验状态正式发布,在 FreeBSD 8.0(2009 年)中宣布为生产就绪状态。
在我工作之前宣布的其他移植都没有实现,所以我猜要打破诅咒,你只需要努力工作足够就行 :)
老实说,如果不是 ZFS 的创建者在早期阶段做出的一个非常重要的决定,要在十天内实现一个工作的读写原型是不可能的。他们希望大部分代码能够在用户空间中编译,以便轻松进行测试和调试。这对我的移植工作是巨大的帮助,因为大部分代码已经非常易于移植。
当我参与大型项目时,我仍然喜欢尽快拥有可以运行的东西,然后逐步实现缺失的部分。
这是一段令人惊叹的旅程,我希望每位软件开发者都能有类似的经历。在撰写这篇文章时,我想要感谢一些人。首先,我想感谢 Jeff Bonwick、Matt Ahrens 以及 Sun 的整个 ZFS 团队,感谢他们创造了这一革命性的技术,并始终支持我的工作。还要感谢 Alexander Kabaev,在 VFS 方面给予我的所有耐心和帮助。感谢 Robert Watson,是他鼓励了我,并一直是我仰望的榜样。感谢 Kris Kennaway,作为无情的早期测试人员,我们不是无缘无故地称他为 BugMagnet。感谢 Martin Matuska,他在时机成熟时接手并负责 ZFS 的维护。最后但同样重要的是,我要感谢整个 FreeBSD 社区——没有什么比感受到自己的工作得到认可并提供真正价值的更令人满足的事情。
自 ZFS 最初发布以来的 20 年里发生了很多事情:NetApp 对 Sun 发起了法律战,Apple 终止了 ZFS 移植,许可证问题阻止了 ZFS 成为 Linux 内核的本地组件,Sun Microsystems 不再存在,新的管理者停止了 ZFS 的开发。然而,这一伟大的技术仍然存在,项目在 OpenZFS 旗帜下继续进行。愿 OpenZFS 永存!愿 FreeBSD 永存!
PAWEL DAWIDEK 是 Fudo Security 的联合创始人兼首席技术官,这是一家专注于构建安全远程访问产品的安全供应商。他还参与了 FreeBSD 操作系统的开发,在安全和存储相关的项目上工作,比如 GELI 磁盘加密、Capsicum 能力和沙箱框架、jail 容器、ZFS 和各种 GEOM 类。Pawel 在技术之余的爱好是练习巴西柔术。