Jeff's Blog

Arch 滚挂恢复实录:Btrfs 子卷、Timeshift 快照与 GRUB 修复

又双叒叕滚挂了?

在一个没睡醒的早上,我随意地让 agent 帮我做点事情,遇到一些报错,考虑到系统很久没有升级,可能是依赖太旧了,便开始升级系统,但升级失败了。

因为空间问题,分配给 Arch 的空间太少了,只给了 60G,然后又开启了 Timeshift 的自动备份,所以很快存储空间就都占满了,删点东西腾出一点空间,继续升级,结果重启的时候,就挂了。

准备与救援环境建立

下载最新的 Arch 安装镜像,放到 U 盘里面,U 盘里装了 Ventoy,只要把镜像放进去,就可以了,很方便。

开机后,选择从 U 盘启动,选择要用的镜像,选 Boot in normal mode,进入到 Arch 的安装镜像里面,然后选 Arch Linux install medium (x86_64, UEFI),就进入到 Arch Linux Live 环境了。

连接网络

由于电脑没有网口,选择用无线网络,如果是有线网络,插网线就行了。

无线网络:需要使用 iwctl 工具连接。

  1. 输入 iwctl 进入交互界面。

  2. 输入 device list 找到你的无线网卡名称(比如 wlan0)。

  3. 输入 station wlan0 scan 扫描 Wi-Fi(将 wlan0 换成你的网卡名)。

  4. 输入 station wlan0 get-networks 列出所有Wi-Fi。

  5. 输入 station wlan0 connect "你的 Wi-Fi 名称",然后根据提示输入密码。

  6. 输入 exit 退出 iwctl。

  7. 再次用 ping baidu.com 测试网络是否连通。

踩坑与排错:Btrfs 子卷与快照的“层级”

关于查看分区,以及 Btrfs 相关的一些命令有:

  1. 查看分区的命令

lsblk -f

  1. 查看Btrfs里面有什么子卷的命令

mount /dev/nvme0n1p6 /mnt        #先挂载上顶层卷

btrfs subvolume list /mnt

这次最大的坑是:Btrfs 恢复时,删 Timeshift 快照需要挂载顶层卷,而重装内核、生成 GRUB 需要挂载 @ 子卷和 EFI 分区。我第一次没挂 EFI,导致内核装到了子卷里;又因为快照占满空间pacman 一直报 No space left on device。正确顺序见下一节

完整的修复流程

删完快照、腾出空间后,重新挂载根子卷 @ 才能进入 chroot 修复系统,而不是停留在顶层卷上。

在 Live 环境重新生成 GRUB 时,按以下步骤操作:

  1. 正常挂载并 chroot

mount -o subvol=@ /dev/nvme0n1p6 /mnt

mount /dev/nvme0n1p1 /mnt/boot    # EFI 分区

mount --bind /dev /mnt/dev

mount --bind /proc /mnt/proc

mount --bind /sys /mnt/sys

arch-chroot /mnt

  1. 重新安装内核、升级系统。(需要先联网)

pacman -S linux

pacman -Syu

  1. 如果空间不足,先退出并删快照。

如果 pacman 报 No space left on device,先退出 chroot:


exit

umount -R /mnt

挂顶层卷删快照:


mount /dev/nvme0n1p6 /mnt

btrfs subvolume delete /mnt/timeshift-btrfs/snapshots/2025-01-15/@

umount /mnt

删完后重新挂回子卷和 EFI,再进 chroot:


mount -o subvol=@ /dev/nvme0n1p6 /mnt

mount /dev/nvme0n1p1 /mnt/boot

mount --bind /dev /mnt/dev

mount --bind /proc /mnt/proc

mount --bind /sys /mnt/sys

arch-chroot /mnt

  1. 重新安装内核、升级系统。(需要先联网)

pacman -S linux

pacman -Syu

  1. 重新生成 GRUB 配置

检查 os-prober(因为是双系统,要生成grub菜单的时候,要同时生成 Windos 的启动选项)如果没装 os-prober,先安装:


pacman -S os-prober

确认 /etc/default/grub 中有下面这行中双引号之间的部分,如果没有就追加进去:


echo "GRUB_DISABLE_OS_PROBER=false" >> /etc/default/grub

重新生成 GRUB 配置:


grub-mkconfig -o /boot/grub/grub.cfg

执行后,输出里应该能看到类似 Found Windows Boot Manager on ... 的字样,说明 Windows 被成功识别了。

  1. 检查 /boot/grub/grub.cfg 里是否有 Windows 菜单项

grep -i windows /boot/grub/grub.cfg

如果有输出,说明已经加上了。

  1. 退出并重启

exit

umount -R /mnt

reboot


总结

这次恢复大概就是:从 U 盘启动 Live 系统,先挂载 Btrfs 顶层卷,删除 Timeshift 快照腾出空间;再卸载顶层卷,重新挂载 @ 子卷和 EFI 分区,重装内核、升级系统,最后重新生成 GRUB 引导。

平时很少关注这些底层细节,但真出问题时,还是得回到它们身上。AI 能帮上忙,但前提是自己要核对基本概念和实际磁盘布局,不然很容易把简单问题搞复杂。