背景
在以往的 Ubuntu 版本中,如果在安装时手动将根分区格式化为 BTRFS,旧版安装程序(Ubiquity)会自动为我们创建 @(用于根目录)和 @home(用于家目录)这两个标准的子卷(Subvolume)。这种标准的子卷结构是著名系统备份工具 Timeshift 能够开启 BTRFS 模式(秒级快照)的强制前提。
然而,Ubuntu 24.04 启用了全新的系统安装器。这个新安装器在处理 BTRFS 时存在一个极大的局限性:它不支持直接生成标准的 BTRFS 子卷布局。
如果你在新安装器中直接选择“手动分区”并将根目录挂载为 BTRFS,它会把整个系统直接“铺平”安装在 BTRFS 的**顶层(Top Level, ID 5)**上,而不会创建任何子卷。
致命后果:安装完成后,由于缺少 @ 子卷,Timeshift 的 BTRFS 快照模式无法正常工作,导致无法体验 BTRFS 最核心的“时光机回滚”功能。
本教程的目的,就是通过“先正常安装 -> 在 Live USB 中把系统搬进子卷 -> 手动修复 fstab 与引导”的方案,规避 Ubuntu 24.04 安装器的缺陷。
方案简介
本指南旨在物理机上部署一套具备企业级数据安全特性的 Ubuntu 桌面系统。 核心特性包括:
- BTRFS 文件系统:利用写时复制 (CoW) 特性保护数据。
- 子卷结构 (
@/@home):标准的 Ubuntu BTRFS 布局,完美兼容 Timeshift。 - 透明压缩 (ZSTD):大幅提升 SSD 寿命和 I/O 性能。
- 秒级快照 (Timeshift):无论系统如何损坏,均可瞬间回滚。
- GRUB 快照启动:在开机引导菜单直接选择历史快照进入系统。
准备工作
- Ubuntu 24.04 LTS 安装镜像 (USB 启动盘)。
- 目标物理机(建议备份好重要数据,安装过程将清空硬盘)。
注意:本指南使用虚拟机演示,设备名为
/dev/vda。如果是 SATA 硬盘,通常为/dev/sda,NVMe 硬盘通常为/dev/nvme0n1,请根据实际情况调整。
第一阶段:基础系统安装
目的:先让 Ubuntu 安装程序把系统装进 BTRFS 分区中(此时处于非标准的顶层状态)。
-
使用 USB 启动盘引导,选择 “Try Ubuntu” (试用 Ubuntu) 进入 Live 桌面环境。
-
自动进入安装程序界面,按照常规步骤选择。
-
在“安装类型”步骤,选择 “Manual installation” (手动安装 / Something else)。
-
配置分区表 (假设是空盘,需新建分区表):
- p1 (EFI): 512MB - 1GB,格式化为 FAT32,Use as:
EFI System Partition(选择启动设备会自动创建 EFI 分区)。
- p2 (Swap): (可选) 建议与物理内存大小一致,格式化为
linux-swap。 - p3 (Root): 剩余空间,格式化为
btrfs,挂载点设为/(根目录)。勾选“格式化此分区”。
- p1 (EFI): 512MB - 1GB,格式化为 FAT32,Use as:
-
继续执行安装,等待进度条走完。
第二阶段:子卷结构迁移
目的:系统刚刚装好,非常干净。我们要在 Live USB 环境下,将原本位于顶层的系统文件安全、完整地“复制”到标准的 @ 和 @home 子卷中。
打开终端 (Terminal),执行以下命令获取管理员权限并确认磁盘分区:
sudo -i
lsblk
卸载残留挂载点并进行结构迁移:
# 1. 卸载安装程序残留的挂载点 (⚠️ 非常重要)
# 刚安装完时,系统通常被安装程序挂载在 /target 目录下,包括 EFI 分区。
# 为了防止接下来的清理工作误删 EFI 引导文件,必须先彻底卸载它们:
umount -R /target
# 2. 干净地挂载 BTRFS 根分区到 /mnt (请根据 lsblk 的结果替换设备名)
# 物理机可能是 /dev/nvme0n1p3,虚拟机可能是 /dev/vda3
mount /dev/vda3 /mnt
# 3. 创建标准的 Ubuntu 子卷
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
将系统文件同步到子卷:
# 4. 使用 rsync 将顶层系统文件复制到 @ 子卷
# -aAXv 参数极度重要:确保保留所有权限、ACL 和扩展属性
# --exclude 排除刚刚建好的子卷及 home 目录,防止无限循环复制
rsync -aAXv --exclude={'/@','/@home','/home'} /mnt/ /mnt/@/
# 5. 将原本家目录下的内容复制入 @home 子卷
rsync -aAXv /mnt/home/ /mnt/@home/
# 6. 清理顶层的旧文件 (⚠️ 危险操作:请仔细核对,只保留 @ 和 @home 目录)
cd /mnt
# 开启 bash 的扩展通配符功能,以便使用“排除法”删除
shopt -s extglob
# 删除除了 @ 和 @home 以外的所有文件和文件夹
# (因为前面已经安全卸载了 /target,此处不会误删真实 EFI 分区)
rm -rf !(@|@home)
# 再次列出目录确认,此时应该只有 @ 和 @home 两个项目
ls -a
第三阶段:配置 fstab 与修复引导 (Chroot)
目的:文件结构已经完美,现在必须修改系统配置,告诉 GRUB 引导器和内核系统已经搬家到了 @ 子卷。
1. 修改 fstab 配置
nano /mnt/@/etc/fstab
找到挂载 / 和 /boot/efi 的行:
- 为
/的挂载选项添加subvol=@以及透明压缩compress=zstd:1。 - 复制
/的那一行,把挂载点改为/home,选项改为subvol=@home,compress=zstd:1。
修改后的 fstab 大致如下:
# 根目录
UUID=... / btrfs defaults,subvol=@,compress=zstd:1 0 1
# 家目录 (需手动添加)
UUID=... /home btrfs defaults,subvol=@home,compress=zstd:1 0 2
# EFI 分区 (保留原样不动)
UUID=... /boot/efi vfat ...
2. 挂载虚拟文件系统并进入 Chroot
为了重新生成引导,必须“伪装”进入刚装好的系统:
# 先卸载刚才的顶层挂载
umount -R /mnt
# 直接挂载 @ 子卷到 /mnt
mount -o subvol=@ /dev/vda3 /mnt
# 挂载 EFI 分区 (非常重要,假设是 p1,虚拟机为 /dev/vda1)
mount /dev/vda1 /mnt/boot/efi
# 挂载必要的系统接口目录
mount --bind /dev /mnt/dev
mount --bind /dev/pts /mnt/dev/pts
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
mount --bind /run /mnt/run
# (如果是 UEFI 启动,通常还需要挂载 efivars,防止 grub-install 报错找不到 EFI 变量)
mount --bind /sys/firmware/efi/efivars /mnt/sys/firmware/efi/efivars
# 进入系统
chroot /mnt
3. 更新并重装 GRUB
在 chroot 环境中执行以下命令修复引导:
# 将 grub 重新安装到物理硬盘 (注意:这里是整个磁盘如 nvme0n1 或 vda,不带分区号)
grub-install /dev/vda
# 更新 grub 菜单 (它会自动识别 rootflags=subvol=@)
update-grub
如果输出 Installation finished. No error reported. 说明完美成功。
4. 退出并重启
exit
umount -R /mnt
reboot
第四阶段:部署时光机 (Timeshift & GRUB)
1. 验证是否成功
打开终端,输入:
sudo btrfs subvolume list /
如果输出包含 path @ 和 path @home,恭喜你,迁移完美成功!
2. 安装并配置 Timeshift
sudo apt update
sudo apt install timeshift -y
打开 Timeshift 并按照引导进行配置,选择 BTRFS 快照模式。
3. 安装 GRUB 启动菜单集成
安装 grub-btrfs 后,允许你在开机 GRUB 菜单中直接选择历史快照启动。
# 安装依赖
sudo apt install git make inotify-tools -y
# 下载并安装 grub-btrfs
cd ~
git clone https://github.com/Antynea/grub-btrfs.git
cd grub-btrfs
sudo make install
为守护进程添加 Timeshift 兼容配置:
(通过创建 systemd override 文件,安全覆盖默认的 /.snapshots 监控路径)
sudo mkdir -p /etc/systemd/system/grub-btrfsd.service.d
echo -e "[Service]\nExecStart=\nExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto" | sudo tee /etc/systemd/system/grub-btrfsd.service.d/override.conf
4. 修复 Ubuntu UUID 读取问题
问题描述:grub-btrfs 的探测脚本使用 awk 提取 UUID 时使用了 \s 正则表达式。但 Ubuntu 默认使用的是轻量级的 mawk 工具,不支持 \s 语法,导致提取失败并提示 UUID of the root subvolume is not available。
解决办法:修改脚本,将正则表达式替换为通用的兼容写法。
编辑探测脚本:
sudo nano /etc/grub.d/41_snapshots-btrfs
使用 Ctrl+W 搜索 ^\s*UUID 定位到代码。将代码中的 /^\s*UUID/ 替换为 /^[ \t]*UUID/。修改后如下所示:
root_uuid_subvolume="$(btrfs subvolume show / 2>/dev/null | \
awk -F':' '/^[ \t]*UUID/ {gsub(/^[ \t]+/, "", $2); print $2}')"
重新加载配置并启用后台监控服务:
sudo systemctl daemon-reload
sudo systemctl enable --now grub-btrfsd
第五阶段:灾难恢复指南
如果系统因误操作或更新导致黑屏、卡 Logo,可按以下步骤恢复:
- 强制重启,在 BIOS/Logo 界面后狂按
Esc或按住Shift调出 GRUB 菜单。 - 在菜单中选择 “Ubuntu snapshots"。
- 选择最近一次状态正常的快照(按日期排序)。
- 系统会以只读模式成功进入桌面。此时打开 Timeshift,选中刚才的快照,点击 “Restore (恢复)"。
- 恢复完成后重启电脑,系统即可完美复活。
评论