子卷必须独立挂载才能被快照;对普通目录如/var/www执行btrfs subvolume snapshot会报错“not a btrfs subvolume”,因快照仅支持子卷而非子卷内路径。

子卷必须独立挂载才能被快照
直接对 /var/www 这类普通目录执行 btrfs subvolume snapshot 会报错:ERROR: not a btrfs subvolume。Btrfs 快照操作只接受子卷(subvolume)作为源,而普通目录只是子卷内的路径,不具备快照能力。
所以第一步不是“建快照”,而是把应用数据目录变成子卷:
- 先卸载原挂载点(如
umount /var/www) - 用
btrfs subvolume create /@www在根文件系统上新建子卷(路径需在 Btrfs 挂载点内) - 更新
/etc/fstab,添加类似UUID=xxx /var/www btrfs subvol=@www 0 0的条目 - 重挂载:
mount /var/www,再运行btrfs subvolume list /确认@www出现在输出中且path字段匹配
子卷命名和位置影响 fstab 可靠性
subvol= 参数在 /etc/fstab 中必须使用子卷名(不是路径),且该名字必须是相对于文件系统根的、已存在的子卷名。比如你执行了 btrfs subvolume create /mnt/btrfs/myapp,那 fstab 里就得写 subvol=myapp,而不是 subvol=/mnt/btrfs/myapp 或 subvol=mnt/btrfs/myapp——后者会导致开机挂载失败,系统卡在 emergency mode。
常见踩坑点:
- 子卷名含斜杠(
/)或点(.)会被内核拒绝,创建时会静默失败或报Invalid argument - 子卷路径不在 Btrfs 文件系统根下(例如建在
/home/user/subvol而 /home 是独立分区),btrfs subvolume list /就看不到它 - fstab 中漏写
defaults或其他必要挂载选项(如compress=zstd),可能使子卷虽能挂载但失去压缩等特性
删除子卷前必须确保未挂载且无活跃进程访问
btrfs subvolume delete 不是 rm -rf,它要求目标子卷完全空闲。如果子卷正被挂载(哪怕只是 mount -o subvol=xxx /mnt 临时挂载过),命令会失败并提示:Directory is busy;如果进程正在其下打开文件(如 nginx 正服务 /var/www),也会同样失败。
安全删除流程:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 先查挂载状态:
findmnt -D /path/to/subvol(-D 显示子卷名而非挂载点) - 若已挂载,执行
umount /path/to/subvol - 查占用进程:
lsof +D /path/to/subvol或fuser -v /path/to/subvol,杀掉相关进程 - 最后执行
btrfs subvolume delete /path/to/subvol(注意:路径是挂载点或子卷绝对路径,不是子卷名)
子卷默认 ID 和 set-default 关系容易混淆
每个 Btrfs 文件系统都有一个“默认子卷”(default subvolume),它的 ID 决定系统启动时挂载哪个子卷。这个 ID 不是固定的,也不是子卷创建顺序决定的——它由 btrfs subvolume set-default 显式设置。例如:
btrfs subvolume list / | grep "top level" ID 5 gen 1234 top level 5 path @ ID 256 gen 1235 top level 5 path @www
这里 ID 5 是当前默认子卷(即挂载 / 时实际看到的内容)。如果你想让 @www 成为根目录内容,得运行:
sudo btrfs subvolume set-default 256 /
然后重启生效。误以为“先创建的子卷就是默认”或“改 fstab 就能切默认子卷”是常见误解——fstab 的 subvol= 只影响单次挂载,不改变文件系统级默认 ID。
真正麻烦的是:一旦设错默认子卷,系统可能无法启动(比如设成一个空子卷),此时必须进 live USB,用 btrfs subvolume set-default 5 /mnt 回退,否则只能手动修复 fstab 和子卷关系。










