Btrfs (简体中文)
引自 Btrfs Wiki:
- Btrfs 是一种现代的写时复制(CoW)Linux 文件系统,已经并入内核主线。Btrfs 致力于实现一些高级功能,同时着重于容错性、修复性以及易于管理性。它由多家企业共同开发,以 GNU GPL 协议授权,并欢迎任何人的贡献。
- Btrfs 有一些功能尚不稳定,可参见内核百科的 Btrfs 稳定性状态报告(英文)、Btrfs 足够稳定了吗?(英文) 和 开始使用 Btrfs(英文)。
- 了解当前的 #已知问题。
准备工作
要使用一些用户空间工具的话,需要 安装 基础操作必须的 btrfs-progs 软件包。
如果需要从 Btrfs 文件系统引导(比如说内核和内存盘在一个 Btrfs 的分区上),请检查 启动引导器 是否支持 Btrfs。
创建文件系统
下文展示了如何创建一个新的 Btrfs 文件系统。要将一个 ext3/4 分区转换为 Btrfs,请参考 #从 Ext3/4 转换。要使用无分区的配置,请参考 #无分区 Btrfs 磁盘。
查阅 mkfs.btrfs(8) 以获取更多信息。
单一设备上的文件系统
要在分区 /dev/partition
上创建一个 Btrfs 文件系统,执行:
# mkfs.btrfs -L mylabel /dev/partition
Btrfs 用于元数据的默认节点大小 (nodesize) 为 16KB,而用于数据的默认扇区大小 (sectorsize) 等于页面大小 (page size) 并会自动检测。 要对元数据使用较大的节点大小 (必须为扇区大小的倍数,最大允许 64KB),请通过 -n
开关为 nodesize
指定一个值。如下例所示,使用 32KB 块大小:
# mkfs.btrfs -L mylabel -n 32k /dev/partition
多设备文件系统
多个设备可以用来创建一组 RAID。支持的 RAID 级别有 RAID 0、RAID 1、RAID 10、RAID 5 和 RAID 6。从 5.5 版本内核开始,新增对 RAID1c3
和 RAID1c4
的支持,分别是 3 份冗余和 4 份冗余的 RAID 1。可以使用 -d
和 -m
参数分别为数据和元数据配置 RAID 等级。默认情况下,数据有一份副本(single
),元数据则被镜像(RAID1
)。这就像创建一个 JBOD 配置,多个磁盘会被看做成一个文件系统,但文件不会重复。更多有关如何创建一个 Btrfs RAID 卷的信息请参阅 Btrfs Wiki:在多个设备上使用 Btrfs。
# mkfs.btrfs -d single -m raid1 /dev/part1 /dev/part2 ...
必须在 /etc/mkinitcpio.conf
中加入 udev
钩子或 btrfs
钩子才能在一个池中使用多个 Btrfs 设备。查阅 Mkinitcpio (简体中文)#常用钩子 以获取更多信息。
- 可以稍后再将设备添加到多设备文件系统中。详情请参见 Btrfs wiki 文章。
- 多个设备可以大小各异。但是,如果在 RAID 配置中一个硬盘的大小比其他的都大,那么它多出的空间将不会被使用。
- 有些 引导加载程序 不支持多设备文件系统,比如 Syslinux。
- Btrfs 不会自动从速度最快的设备读取,因此混合使用不同类型的磁盘会导致性能表现不恒定。详情请参阅 Stack Overflow 上的这个回答。
#RAID 小节中有关于维护多设备上的 Btrfs 文件系统的一些建议。
配置文件系统
写时复制 (CoW)
默认情况下 Btrfs 对所有文件使用 写时复制 (CoW)。参阅 Btrfs 系统管理指南相关章节 以获取实现细节以及它的优点和缺点。
停用 CoW
要对某个子卷上的新文件停用写时复制,使用 nodatacow
挂载选项。这只会影响新创建的文件,写时复制仍然会在已存在的文件上生效。nodatacow
参数同样会禁用压缩。参阅 btrfs(5) 以了解细节。
nodatacow
参数挂载某些子卷,而其他的使用 datacow
参数。第一个被挂载子卷的挂载参数将会应用于其他所有子卷。”要单文件或目录禁用写时复制特性,请使用下面的命令:
$ chattr +C [文件/目录的地址(path)]
这会为这个文件的单个引用停用写时复制,如果这个文件不只有一个引用(例如通过 cp --reflink=always
生成或者在文件系统快照中),写时复制依然生效。
$ mv /path/to/dir /path/to/dir_old $ mkdir /path/to/dir $ chattr +C /path/to/dir $ cp -a /path/to/dir_old/* /path/to/dir $ rm -rf /path/to/dir_old
需要保证这个过程中目标文件不会被使用,同时注意下面描述的 mv
或 cp --reflink
并不起作用。
创建轻量副本
默认情况下,使用 cp
复制 Btrfs 文件系统上的文件时,会创建实际副本。要创建引用原始数据的轻量级副本,请使用 reflink 选项:
$ cp --reflink source dest
参阅 cp
的手册页获得关于 --reflink
标志的更多信息。
压缩
Btrfs 支持 透明和自动压缩。这就减小了文件的大小,通过减少文件写入增幅来显著延长闪存介质(flash-baesd media)的寿命 [1][2][3]。在某些特定的场景下(比如单线程、重负荷的文件 I/O))还 提高了性能。尽管在其他的场景下(比如多线程和/或大文件 I/O 高强度 CPU 任务)还是明显影响了性能。通常使用更快的压缩算法,比如 zstd 和 lzo 可以获得更好的性能,这个 性能测试 提供了详细的对比。
承上文,compress=alg
挂载选项可自动考虑为每个文件启用压缩,其中的 alg
处可以选填为 zlib
, lzo
, zstd
, 或者 no
(即不压缩)。由此,Btrfs 将检查压缩数据的第一部分是否能将其缩减。如果能,则会压缩该文件的整个写入;否则不会压缩任何内容。所以,如果数据的第一部分没有被缩减,那么即使数据的其余部分可以大大缩减,写入时也不会被压缩。[4] 这样做是为了防止让磁盘一直等待写入,直到所有要写入的数据传递给 Btrfs 并被压缩后为止。
另外可以改用 compress-force=alg
挂载选项,这会让 Btrfs 跳过对数据第一部分的压缩检查,并尝试对每个文件启用自动压缩。最不济的情况,这会 (稍微) 导致 CPU 占用率无故升高。不过,在多个混合使用系统的经验测试显示,与仅使用 compress=zstd
(其也有 10% 的磁盘压缩率) 相比,使用 compress-force=zstd
可以显著提高约 10% 的磁盘压缩率。
只有在加入挂载选项后创建或修改的文件才会被压缩。
给现存文件启用压缩,可使用 btrfs filesystem defragment -calg
命令,alg
处可选填为 zlib
,lzo
或 zstd
。举例来说,要用 zstd 方式给整个文件系统重新压缩,执行下列命令:
# btrfs filesystem defragment -r -v -czstd /
要在新的 Btrfs 分区上安装 Arch Linux 时就启用压缩功能 (充分利用压缩特性),请在 挂载 文件系统时使用 compress
选项:mount -o compress=zstd /dev/sdxY /mnt/
。在配置过程中,请在 fstab 中把 compress=zstd
添加到根目录文件系统的挂载选项里。
chattr +c
,也可以在不使用 compress
选项的情况下为每个单文件启用压缩属性。对目录执行会使这个目录下新文件自动被压缩。- 如果使用
zstd
参数,使用较旧版本内核或者尚不支持zstd
的 btrfs-progs 的系统可能不能读取或修复您的文件系统。 -
GRUB 在 2.04 版本中引入了对 zstd 的支持。使用此后版本时,请通过手动运行
grub-install
(需添加适用于机器 BIOS/UEFI 设置的选项参数)确保安装在 MBR/ESP 中的引导加载程序已确实升级,因为这些事情不会自动完成。可参阅 FS#63235。
查看压缩类型和压缩比
compsize 软件包能获取一个文件列表 (或一整个 Btrfs 文件系统),并测量出它们使用的压缩类型和其有效压缩比。不过,其给出的未压缩时大小数值不一定能和其他程序 (比如 du
) 给出的数值吻合,因为每一文件所占空间范围都会计数一次,即使文件被链接了多次,即使文件的一部分不再被使用 (但其未被垃圾回收)。 -x
选项可让程序运行保持在单一个文件系统上,这在 compsize -x /
(检查根目录) 之类的情况下很有用,可以避免程序去尝试访问非 Btrfs 子目录从而导致整个程序运行失败。
子卷
"btrfs 子卷不是 (也不能看作) 块设备,一个子卷可以看作 POSIX 文件名字空间.这个名字空间可以通过子卷上层访问,也可以独立挂载."[5]
每个 btrfs 文件系统都有一个 ID 为 5 的顶层子卷。它可以挂载为 /
(默认情况下),或者可以挂载为另一个子卷。子卷可以在文件系统中移动,它们通过其 ID 而不是路径来标识。
参阅下面的链接获得更多信息:
- Btrfs Wiki SysadminGuide#Subvolumes
- Btrfs Wiki Getting started#Basic Filesystem Commands
- Btrfs Wiki Trees
创建子卷
要创建一个子卷:
# btrfs subvolume create /path/to/subvolume
列出子卷列表
要列出当前路径 (path
) 下的子卷和它们的 ID:
# btrfs subvolume list -p path
删除子卷
要删除一个子卷:
# btrfs subvolume delete /path/to/subvolume
自 Linux 4.18 起, 用户可以像移除常规目录一样删除一个子卷 (用 rm -r
, rmdir
命令)。
挂载子卷
可以使用 subvol=/path/to/subvolume
或 subvolid=objectid
挂载标志来安装子卷,就像文件系统分区一样。例如,您可以拥有一个名为 subvol_root
的子卷,并将其挂载为 /
。通过在文件系统的顶层创建各种子卷,然后将它们挂载到适当的挂载点,可以模仿传统的文件系统分区。 因此,可以使用 #快照 轻松地将文件系统(或其一部分)恢复到先前的状态。
/
。参阅 Snapper#Suggested filesystem layout, Btrfs SysadminGuide#Managing Snapshots 和 Btrfs SysadminGuide#Layout 获得子卷应用的示例。
有关 Btrfs 特定的挂载选项的完整列表,请参阅 btrfs(5)。
挂载子卷为根挂载点
要使用一个子卷作为根挂载点,请使用 rootflags=subvol=/path/to/subvolume
—— 一个 内核参数 指定子卷。在 /etc/fstab
中编辑根挂载点并指定挂载选项 subvol=
。或者可以在 /etc/fstab
中用 ID 指定子卷:用 rootflags=subvolid=objectid
作为内核参数并用 subvolid=objectid
作为挂载选项。
改变默认子卷
如果挂载时不指定 subvol=
选项便会挂载默认子卷。要改变默认子卷,执行:
# btrfs subvolume set-default subvolume-id /
subvolume-id 可以通过#列出子卷列表获得。
通过 btrfs subvolume set-default
修改默认子卷将会导致文件系统的最顶层无法访问,除非使用 subvol=/
或者 subvolid=5
挂载参数。[6]
配额
Btrfs中的配额支持是通过使用配额组或 qgroup 在子卷级别实现的:默认情况下,每个子卷都以 0/subvolume_id 的形式分配配额组。 但是,如果需要的话,可以使用任意数字创建配额组。
要使用 Qgroup,你首先需要启用它:
# btrfs quota enable path
从此时开始,新创建的子卷将由这些配额组控制。 为了能够为已创建的子卷启用配额,首先正常启用配额,然后使用它们的 subvolume_id 为每个子卷创建一个配额组,再重新扫描它们:
# btrfs subvolume list path | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup create 0/{} path # btrfs quota rescan path
Btrfs 中的配额组形成树层次结构,其中 Qgroup 附加到子卷。大小限制由每个 Qgroup 独立配置且在并在包含给定子卷的树中达到任何限制时应用。
配额组的限制可以应用于总数据使用,非共享数据使用,压缩数据使用或全部。文件复制和文件删除可能都会影响限制,因为如果删除原始卷的文件并且只剩下一个副本,则另一个 Qgroup 的非共享限制可能会更改。例如,新快照几乎与原始子卷共享所有块,对子卷的新写入将向专用限制提升,一个卷中的公共数据的删除将升高到另一个卷中的专用限制。
要对 Qgroup 应用限制,请使用命令 btrfs qgroup limit
。根据你的使用情况,使用总限制,非共享限制( -e
)或压缩限制( -c
)。
显示文件系统使用中给定路径的使用情况和限制:
# btrfs qgroup show -reF path
提交间隔
将数据写入文件系统的频率由 Btrfs 本身和系统的设置决定。Btrfs 默认设置为 30 秒检查点间隔,新数据将在 30 秒内被提交到文件系统。 这可以通过在 /etc/fstab
增加 commit
挂载参数来修改:
LABEL=arch64 / btrfs defaults,noatime,compress=lzo,commit=120 0 0
系统范围的设置也会影响提交间隔。它们包括 /proc/sys/vm/*
下的文件,这超出了本维基文章的范围,因此不再赘述。 它们的内核文档位于 Documentation/sysctl/vm.txt
。
SSD TRIM
Btrfs 文件系统能够从支持 TRIM 命令的 SSD 驱动器中释放未使用的块。内核从 5.6 版本开始提供了异步丢弃(asynchronous discard)支持,可使用挂载参数 discard=async
启用。已释放的空间范围不会被马上丢弃,它们会被集中起来并在稍后由一个单独的工作线程进行 TRIM,这将能改善提交延迟。
有关启用和使用 TRIM 的更多信息,请参阅 Solid State Drives#TRIM。
使用
交换文件
自 Linux 内核版本 5.0 起 Btrfs 提供 交换文件 支持 [7]。 Swap#建立交换文件 一节中已交代正确初始化交换文件的方法。 Power_management/Suspend_and_hibernate#休眠到 Btrfs 上的交换文件中 一节中则已交代了休眠到交换文件的配置方法。
- 交换文件不可以放在快照子卷上。正确的过程是创建一个新子卷来存放交换文件。
- Btrfs 不支持跨多设备文件系统上的交换文件。参见 Btrfs wiki: Btrfs 支持交换文件吗?(英文) 和 Arch 论坛上的讨论 (英文)。
显示已使用的/空闲空间
像 df
这样的用户空间工具可能不会准确的计算剩余空间 (因为并没有分别计算文件和元数据的使用情况) 。推荐使用 btrfs filesystem usage
来查看使用情况。比如说:
# btrfs filesystem usage /
btrfs filesystem usage
在 RAID5/RAID6
设备上可能无法正常工作。请参阅 [8] 以获取更多信息。
碎片整理
Btrfs 支持通过配置挂载参数 autodefrag
来实现在线的碎片整理,参见 btrfs(5) § MOUNT OPTIONS 。要手动整理你的根目录的话,可以使用:
# btrfs filesystem defragment -r /
使用不带 -r
开关的上述命令将导致仅整理该目录的子卷所拥有的元数据。这允许通过简单地指定路径进行单个文件碎片整理。
对具有 CoW 副本(快照副本或使用cp --reflink
或 bcp 创建的文件)进行碎片整理以及使用带压缩算法的 -c
开关进行碎片整理可能会导致生成两个不相关的文件从而增加磁盘使用量。
RAID
Btrfs 提供对 RAID 一类的 #多设备文件系统的原生支持.参阅 the Btrfs wiki page 获得更多信息. Btrfs 管理员手册 提供了技术背景信息.
检修 (Scrub)
Btrfs Wiki 术语表中写到,Scrub 是一种 "在线文件系统检查工具"。它能读取文件系统中的文件和元数据,并使用校验值和 RAID 存储上的镜像区分并修复损坏的数据。
手动启动
启动一个(后台运行的)包含 /
目录的文件系统在线检查任务:
# btrfs scrub start /
检查该任务的运行状态:
# btrfs scrub status /
通过服务或者定时器启动
btrfs-progs 软件包带有 btrfs-scrub@.timer
系统单元,用来每月运行 scrub 命令。通过添加挂载点的参数来启用它,例如btrfs-scrub@-.timer
(/
) 或者 btrfs-scrub@home.timer
(/home
).
也可以通过启动 btrfs-scrub@.service
来手动运行 scrub (使用同样的挂载点参数),相较 (以 root 用户身份运行) btrfs scrub
,这么做的优点是会记录在 Systemd 日志中。
数据平衡 (Balance)
“Balance 将会通过分配器再次传递文件系统中的所有数据。它主要用于在添加或删除设备时跨设备重新平衡文件系统中的数据。如果设备出现故障,余额将为冗余 RAID 级别重新生成缺失的副本。”[9]。参阅 上游的 FAQ.
在单设备文件系统上,余额对于(临时)减少分配但未使用(元)数据块的数量也是有用的。有时候这对于解决 "filesystem full" 故障 来说也是必须的。
# btrfs balance start / # btrfs balance status /
快照
"快照是和特定子卷共享文件和元数据的特殊子卷, 利用了 btrfs 的写时复制特性." 详见 Btrfs Wiki SysadminGuide#Snapshots.
要创建一个快照:
# btrfs subvolume snapshot source [dest/]name
source
为要创建快照的对象,[dest/]name
为快照安放路径。
加入 -r
参数可以创建一个只读快照. 为只读快照创建一个快照可以获得一个只读快照的可写入版本.
发送和接收
可以通过 send
命令发送一个快照,通常会与 btrfs 中的 receive
组成管道.例如将快照 /root_backup
(也许是/
的备份) 发送到 /backup
:
# btrfs send /root_backup | btrfs receive /backup
只能发送只读快照,上面的命令在将子卷复制到外部设备 (例如备份驱动器) 时会很有用.
也可以只发送两个快照间发生变化的部分,例如如果你已经发送了快照 root_backup
,然后又建立了一个新的只读快照 root_backup_new
,可以这样完成增量发送:
# btrfs send -p /root_backup /root_backup_new | btrfs receive /backup
现在你 /backup
的快照会是 root_backup_new
.
参阅 Btrfs Wiki 上关于增量备份的页面 (英文) 获得更多信息 (例如使用工具自动化这一过程)。
去重
使用写时复制,Btrfs 能够复制文件或整个子卷而无需实际复制数据。但是,无论何时更改文件,都会创建一个新的“真正的”副本。重复数据删除更进一步,通过主动识别共享公共序列的数据块并将它们组合到具有相同写时复制语义的范围内。
专用于 Btrfs 分区去重的工具包括 duperemove,bedupAUR 和 btrfs-dedup。人们可能还希望仅使用基于文件的级别对数据进行重复数据删除,比如 rmlint、jdupesAUR 或者 dduper-gitAUR。有关这些程序的可用功能的概述和其他信息,请参阅 上游 Wiki 条目 (英文)。
此外,Btrfs开发人员正致力于带内(也称为同步或内联)重复数据删除,这意味着在将新数据写入文件系统时完成重复数据删除。目前,它仍然是一个在 out-of-tree 开发的实验。愿意测试新功能的用户可以阅读相关的内核 Wiki 页 (英文)。
已知问题
一些在尝试之前应该知道的限制。
加密
Btrfs 目前还没有内建的加密支持,但未来可能加入此功能。可以在运行mkfs.btrfs
前加密分区,参阅Dm-crypt with LUKS.
(如果已经创建了文件系统,可以使用EncFS或TrueCrypt,但是这样会无法使用 btrfs 的一些功能。)
检查 btrfs 文件系统问题
btrfs check
工具目前有一些已知问题,在继续深入阅读了解之前,您不应该直接运行它, 参见 #检查 Btrfs 文件系统 小节。
提示和技巧
无分区 Btrfs 磁盘
--alloc-start
参数以留出更大空间给 GRUB。Btrfs 能应用到整个设备上,替代 MBR 或 GPT 分区表,但是并不要求一定这么做,最简单的方法是 在一个已存在的分区上创建 Btrfs 文件系统。 如果选择用 Btrfs 替代分区表, 可以用 #子卷 模拟不同的分区。下列是在单个无分区设备上使用 Btrfs 文件系统的限制:
- 不能在同一磁盘上的不同分区上放置其它的 文件系统。
- 如果使用 5.0 之前版本的 Linux 内核,则不能使用 交换区,因为 Btrfs 在 5.0 前不支持 交换文件,并且也无处创建 交换分区。
- 不能使用 UEFI 启动。
运行下面的命令把整个设备的分区表替换成 Btrfs:
# mkfs.btrfs /dev/sdX
如果设备上存在分区表,则需要使用:
# mkfs.btrfs -f /dev/sdX
例如 /dev/sda
而不是 /dev/sda1
。后一种形式会格式化现有的分区而不是替换掉原有的分区表。由于根分区是 Btrfs 文件系统,请确保已将 btrfs
编译进内核, 或者将 btrfs
放入 mkinitcpio.conf#MODULES 中并且 重新生成 initramfs。
像使用普通的 MBR 分区表存储设备一样安装 启动管理器, 参考 Syslinux#Manual install 或 GRUB/Tips and tricks#Install to partition or partitionless disk。 如果你的内核因为 Failed to mount /sysroot.
错误无法启动, 请在 /etc/default/grub
里添加 GRUB_PRELOAD_MODULES="btrfs"
并生成 GRUB 配置文件 (GRUB#Generate the main configuration file)。
从 Ext3/4 转换
brtfs-convert
功能。从安装 CD 启动,然后转化分区:
# btrfs-convert /dev/partition
挂载转换后的分区并修改 /etc/fstab
文件,指定分区类型 (type 为 btrfs,并且 fs_passno[最后一列] 要修改为0,因为 Btrfs 在启动时并不进行磁盘检查)。
还要注意的是分区的 UUID 将有改变,所以使用 UUID (指定分区) 时,请更新 fstab 中相应的条目。 chroot
到系统并重建 GRUB 条目(如果对此过程不熟悉,参考从现有 Linux 系统安装 和 GRUB 中的相应内容)。 如果正在转换根目录,还需要在 chroot 环境中重建初始化内存盘 (mkinitcpio -p linux
)。 如果 GRUB 不能启动 (例如有 'unknown filesystem' 错误),则需要重新安装 (grub-install /dev/partition
) 并重新生成配置文件 (grub-mkconfig -o /boot/grub/grub.cfg
)。
/ext2_saved
还在,就可以进行回滚。请使用 btrfs-convert -r /dev/partition
命令进行回滚,这将会丢弃任何对新转换 Btrfs 文件系统的更改。确认没有问题后,通过删除 ext2_saved
备份子卷完成转换的最后一步。请注意,如果没了它 (备份子卷),你将没办法还原回 ext3/4 文件系统。
# btrfs subvolume delete /ext2_saved
最后通过 Balance 回收空间。
校验和 (Checksum) 硬件加速
CRC32 是英特尔 (Intel) SSE4.2 中的新指令。要验证 Btrfs 校验和是否有硬件加速:
# dmesg | grep crc32c
Btrfs loaded, crc32c=crc32c-intel
如果你看到的是 crc32c=crc32c-generic
,则很有可能是因为您根分区是 Btrfs,并且您须要之后将 crc32c-intel
编译进内核中才能使其正常生效。单纯将 crc32c-intel
放入 mkinitcpio.conf 是 不会 生效的。
损坏恢复
btrfs check
工具有一些已知问题,参见 #检查 Btrfs 文件系统 小节。btrfs-check 不能在一个已挂载的文件系统上工作。为了能够在不从 Live USB 启动的情况下使用 btrfs-check,需要将其添加到初始内存盘:
/etc/mkinitcpio.conf
BINARIES=("/usr/bin/btrfs")
然后 重新生成 initramfs。
之后如果启动时出现问题,则可以使用该实用程序进行修复。
查阅 Btrfs Wiki 的 Btrfsck 页 以获取更多信息。
引导进入快照
要引导进入快照,因为快照可以像子卷那样被挂载,所以请像挂载子卷为根分区那样进行同样的流程 (已交代于#挂载子卷为根挂载点的一段中)。
如果使用 GRUB,则可以在 grub-btrfs 或 grub-btrfs-gitAUR 的帮助下,在重新生成配置文件时使用 Btrfs 快照自动填充启动菜单。
搭配 systemd-nspawn 使用 Btrfs 子卷
可查阅 Systemd-nspawn#Use Btrfs subvolume as container root 和 Systemd-nspawn#Use temporary Btrfs snapshot of container 等文章。
疑难解答
请查阅 Btrfs 常见问答集(英文) 以获得排除一般问题的信息。
GRUB
分区偏移
core.img
嵌入到已分区磁盘上时,可能会发生偏移问题。这意味着可以将 GRUB 的 corg.img
直接嵌入到无分区磁盘 (例如 /dev/sdX
) 上的 Btrfs 存储池中。GRUB 2 可以引导启动 Btrfs 分区,但是因为模块比其它文件系统大,grub-install 生成的 core.img 文件超过了 MBR 与第一个分区之间的空间大小 (63 扇区/31.5KiB)。最新版的 fdisk
和 gdisk
等磁盘工具会通过第一个分区前空出 1-2MiB 的空间来避免此问题。
Missing root
Users experiencing the following: error no such device: root
when booting from a RAID style setup then edit /usr/share/grub/grub-mkconfig_lib and remove both quotes from the line echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
. Regenerate the config for grub and the system should boot without an error.
挂载超时
有时(尤其在大型 RAID1 阵列上)系统启动时会出现挂载超时的现象,并带有如下日志信息:
Jan 25 18:05:12 host systemd[1]: storage.mount: Mounting timed out. Terminating. Jan 25 18:05:46 host systemd[1]: storage.mount: Mount process exited, code=killed, status=15/TERM Jan 25 18:05:46 host systemd[1]: storage.mount: Failed with result 'timeout'. Jan 25 18:05:46 host systemd[1]: Failed to mount /storage. Jan 25 18:05:46 host systemd[1]: Startup finished in 32.943s (firmware) + 3.097s (loader) + 7.247s (kernel)> Jan 25 18:05:46 host kernel: BTRFS error (device sda): open_ctree failed
这可以通过 fstab 中特定的 systemd 挂载选项 x-systemd.mount-timeout
提供系统以更长的超时时间来轻松解决。例如:
/dev/sda /storage btrfs rw,relatime,x-systemd.mount-timeout=5min 0 0
出现 BTRFS: open_ctree failed 错误
截至 2014 年 11 月,一个似乎存在于 systemd 或 mkinitcpio 中的 Bug 可能会导致在 mkinitcpio.conf
中使用 btrfs
钩子(hook)的用户在启动多设备文件系统的 Btrfs 卷时遇到以下错误:
BTRFS: open_ctree failed mount: wrong fs type, bad option, bad superblock on /dev/sdb2, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg|tail or so. You are now being dropped into an emergency shell.
一种解决办法是,从 HOOKS
中将 btrfs
移入 MODULES
中,然后通过 mkinitcpio -p linux
命令重新生成 initramfs 并重新启动。
请查阅 原论坛讨论 和 FS#42884 获得更多的讨论内容和信息。
另外,如果在挂载 RAID 卷组缺少某个卷时,也有可能会发生这个错误。这种情况下,需要把 degraded
加入到 /etc/fstab
中;如果根目录在卷组上,需要同时加入内核参数 rootflags=degraded
。
接上文,截至 2016 年 8 月,针对这一问题,一个可能的解决方案是在 /etc/fstab
中仅靠单个硬盘来挂载阵列,然后让 Btrfs 自动发现并追加其它硬盘。UUID 和 LABEL 等基于组的标识符似乎是导致出现错误的原因。比如说,由“disk1”(磁盘 1) 和“disk2”(磁盘 2)组成的双设备 RAID1 阵列会被分配到一个 UUID。但是请在 /etc/fstab
中只使用 /dev/mapper/disk1
来指定磁盘阵列,而不要使用 UUID。更多解释,参见这个博客文章。
另一个可能的解决方法是在 mkinitcpio.conf 中移除 udev
钩子并替换为 systemd
钩子。此时 btrfs
不应出现在 HOOKS
或 MODULES
列表中。
检查 Btrfs 文件系统
btrfs check
命令工具)仍处在大开发阶段,强烈建议在加上 --repair
参数运行 btrfs check
前先做一个备份,并提前阅读 Btrfsck 文档(英文)。btrfs check 可以检查并修复一个未挂载的 Btrfs 文件系统。但是由于它尚未开发完成,它并不能修复某些错误(即使这些错误没有导致无法挂载的情况发生)。
另请参阅
- 官方网站
- 官方常见问答
- Btrfs 拉取请求(Pull Requests)
- 性能相关
-
杂项
- Funtoo:BTRFS Fun
- Avi Miller presenting Btrfs at SCALE 10x, January 2012.
- Summary of Chris Mason's talk from LFCS 2012
- Btrfs: stop providing a bmap operation to avoid swapfile corruptions 2009-01-21
- Doing Fast Incremental Backups With Btrfs Send and Receive