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/