baek_hyang / Furina & Rafale
440 words
2 minutes
BTRFS 踩坑:根目录下的子卷

BTRFS 踩坑:根目录下的子卷
TL; DR: 不能假设你的 /
是文件系统的「根目录」,可能是任何东西的挂载点,例如 BTRFS 子卷 /@
.
事件的起因是我们希望给 /srv
目录一个单独的子卷,以便增量备份。
btrfs subvolume create /@srv
但是,在我们尝试挂载新创建的子卷时,会得到如下错误:
# mount -o subvol=@srv /dev/nvme0n1p2 /srvmount: /srv: fsconfig() failed: 没有那个文件或目录. dmesg(1) may have more information after failed mount system call.
这看似很奇怪,因为如果我们尝试列出子卷:
# btrfs subvolume list /ID 256 gen 85363 top level 5 path @ID 257 gen 85363 top level 5 path @homeID 258 gen 85363 top level 5 path @logID 259 gen 85170 top level 5 path @pkgID 260 gen 68985 top level 5 path @.snapshotsID 261 gen 13 top level 256 path var/lib/portablesID 262 gen 13 top level 256 path var/lib/machinesID 271 gen 85142 top level 5 path @srv
会发现同样的操作可以成功挂载类似的子卷(如 @home
),却无法挂载我们的 @srv
.
问题的原因在于,此时我们系统的根目录 /
并不是 BTRFS 文件系统的根目录 /
, 而是其下的子卷 @
的挂载点(这是 Arch Linux 默认安装下的行为)。
# mount -t btrfs /dev/nvme0n1p2 /tmp/rootfs# ls /tmp/rootfs'@'/ '@home'/ '@log'/ '@pkg'/ '@.snapshots'/# ls /tmp/rootfs/@ bin@ dev/ '@foo'/ lib@ logs/ opt/ root/ sbin@ sys/ usr/ boot/ etc/ home/ lib64@ mnt/ proc/ run/ srv/ tmp/ var/
因此,在我们创建子卷 /@srv
时,看似在「根目录」/
下创建的子卷,实际上位于 /@/@srv
. 这也是我们无法通过 @srv
访问的原因。
# btrfs subvolume show /@srv | head -n 2@/@srv Name: @srv
为解决这个问题,可以将 BTRFS 挂载到其它挂载点后再操作:
mount -t btrfs /dev/nvme0n1p2 /tmp/rootfsbtrfs subvolume create /tmp/rootfs/@srv
或使用 @/@srv
而非 @srv
引用这个子卷。
BTRFS 踩坑:根目录下的子卷
https://misaka10987.github.io/posts/migrate/btrfs-subvol-under-root/