最近遇到一个情况,需要把一块SSD从FreeBSD机器上拆下来,然后读取里面的数据。刚好这块硬盘的文件系统是ZFS.(当然一大部分用FreeBSD的人都是因为它有ZFS,对吧?)众所周知,macOS原生支持的文件系统只有HFS+、APFS、exFAT、FAT32和NTFS(只读),我们需要一点额外的功夫来读写ZFS硬盘。
尽管ZFS从名字上看是和NTFS、ext4一样的文件系统,不过其抽象层次已经超越了简单理解上的「文件系统」层面,提供了快照(Snapshot)和冗余阵列(RAID-Z)这样的功能。因此除了系统VFS API之外,ZFS还需要若干自带工具(比如 zfs
和 zpool
命令)才能良好工作。好在ZFS诞生于Solaris,在FreeBSD上发展,而我们熟悉的macOS属于正统UNIX,也是FreeBSD的近亲。将ZFS移植到macOS(以前叫OS X)的项目已经存续许久1。
首先,因为目前的macOS已经在安全性上做了许多限制,我们需要在系统设置里降低安全性要求。如果你的电脑是Intel芯片的Mac,此步不需要操作。如果是Apple Silicon的Mac,请关闭电脑,然后长按电源键,直到显示「正在载入启动选项」松开,选择操作系统所在的硬盘和输入密码,并在实用工具里的「启动安全性实用工具」中,将「安全策略」设置为「降低安全性」,并且勾选「允许用户管理来自被认可开发者的内核扩展」。确认设置后重新启动。这一步的原因是苹果考虑在未来的macOS中禁用内核扩展功能(kext),所以现在将其默认设置为弃用2。
然后我们去OpenZFS on OS X项目网站下载最新的release 2.1.0. 最近OpenZFS的网站遇到了问题无法打开,可以去Web Archive的Wayback Machine打开OpenZFS on OS X官网,或者在这里下载安装包(Big Sur及以上系统:Intel3和Apple Silicon4)。打开pkg文件,一步步安装完成后,打开系统设置,在隐私设置的「完全使用磁盘」项内启用 zpool
支持。如果系统是Ventura,还需要在系统设置「通用-登录项目」允许Joergen Lundman和Justin Johnson两项的后台运行。保险起见,安装设置完成后重启电脑。
现在我们已经有了使用ZFS的软件条件,可以挂载ZFS存储池了。
# 假设你的ZFS Pool名称为默认的zroot,否则按情况修改
mkdir $HOME/mount_zfs
# ZFS可以智能地检测到这不是它此前运行的系统,所以需要 -f 选项
# 如果不加 -R,ZFS会将硬盘挂载到系统根目录 /,当然会失败
sudo zpool import -f zroot -R $HOME/mount_zfs
# 前一步已经挂载上了部分内容,要挂载诸如 /usr/local 等目录,需要更多操作
sudo zfs mount zroot/ROOT/default
现在就可以在 $HOME/mount_zfs
目录查看硬盘的内容了,也可以通过 df -h
确认各分区的挂载情况。正常情况下,Finder里也会列出大量挂载位置。
操作完成后,记得取消挂载ZFS存储池。
sudo zfs unmount zroot/ROOT/default
sudo zpool export zroot
参考资料
- 导入ZFS存储池
- 挂载ZFS文件系统
- How to mount external ZFS file system without clobbering/altering current or external filesystem
- zfs-macOS-2.1.0 release
- 在搭载 Apple 芯片的 Mac 上更改启动磁盘的安全性设置
注释
1 其实多年前一直有传言曰Mac OS X会使用ZFS取代HFS+作为默认文件系统,尤其考虑到苹果已经将同样来自Solaris的DTrace移植到Mac平台作为系统工具一部分(现在Xcode的Instruments即依赖DTrace),但最后苹果否决了这个计划,然后在2017年发布了APFS。放弃ZFS的具体原因不得而知,也许是版权考虑,也许是ZFS的确不适合当时苹果即将发布的移动设备。
2 未来用什么技术代替内核扩展尚未可知。一个适宜在用户态挂载任意文件系统的做法是新的用于网盘软件的FileProvider API,不过它的路径被严格限制。在苹果对Mac OS X Server还有野心的年代,内核扩展曾经还是苹果的主推功能,令人唏嘘。
3 MD5 = 80bee1c01362372ea3a803fdac56bfaa
4 MD5 = 1a72698d035d05d777c44e4cc734a952