背景

在以往的 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 分区中(此时处于非标准的顶层状态)。

  1. 使用 USB 启动盘引导,选择 “Try Ubuntu” (试用 Ubuntu) 进入 Live 桌面环境。

  2. 自动进入安装程序界面,按照常规步骤选择。

  3. 在“安装类型”步骤,选择 “Manual installation” (手动安装 / Something else)。

    2026-02-25_134121

  4. 配置分区表 (假设是空盘,需新建分区表):

    2026-02-25_134325

    • p1 (EFI): 512MB - 1GB,格式化为 FAT32,Use as: EFI System Partition(选择启动设备会自动创建 EFI 分区)。 2026-02-25_134358
    • p2 (Swap): (可选) 建议与物理内存大小一致,格式化为 linux-swap
    • p3 (Root): 剩余空间,格式化为 btrfs,挂载点设为 / (根目录)。勾选“格式化此分区”。 2026-02-25_134459
  5. 继续执行安装,等待进度条走完。 2026-02-25_134548

2026-02-25_140242

第二阶段:子卷结构迁移

目的:系统刚刚装好,非常干净。我们要在 Live USB 环境下,将原本位于顶层的系统文件安全、完整地“复制”到标准的 @@home 子卷中。

打开终端 (Terminal),执行以下命令获取管理员权限并确认磁盘分区:

sudo -i
lsblk

2026-02-25_140920

卸载残留挂载点并进行结构迁移:

# 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

2026-02-25_141524

将系统文件同步到子卷:

# 4. 使用 rsync 将顶层系统文件复制到 @ 子卷
# -aAXv 参数极度重要:确保保留所有权限、ACL 和扩展属性
# --exclude 排除刚刚建好的子卷及 home 目录,防止无限循环复制
rsync -aAXv --exclude={'/@','/@home','/home'} /mnt/ /mnt/@/

2026-02-25_141946 2026-02-25_142024

# 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

2026-02-25_142404

第三阶段:配置 fstab 与修复引导 (Chroot)

目的:文件结构已经完美,现在必须修改系统配置,告诉 GRUB 引导器和内核系统已经搬家到了 @ 子卷。

1. 修改 fstab 配置

nano /mnt/@/etc/fstab

找到挂载 //boot/efi 的行:

  1. / 的挂载选项添加 subvol=@ 以及透明压缩 compress=zstd:1
  2. 复制 / 的那一行,把挂载点改为 /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  ...

2026-02-25_142951 (保存:Ctrl+O, 回车, Ctrl+X)

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,可按以下步骤恢复:

  1. 强制重启,在 BIOS/Logo 界面后狂按 Esc 或按住 Shift 调出 GRUB 菜单。
  2. 在菜单中选择 “Ubuntu snapshots"。

  1. 选择最近一次状态正常的快照(按日期排序)。

  1. 系统会以只读模式成功进入桌面。此时打开 Timeshift,选中刚才的快照,点击 “Restore (恢复)"。
  2. 恢复完成后重启电脑,系统即可完美复活。