从 Arch Linux 迁移到 CachyOS:Btrfs 快照修复与内核升级实战

记录一次从 Arch Linux 迁移到 CachyOS 的完整过程:诊断并修复 snapper 事务快照与启动快照、导入 CachyOS 仓库与 GPG 密钥、安装 znver4 优化内核、处理 DKMS 驱动重建,以及迁移后的配置清理与软件包管理策略。

背景

我的系统运行在 Btrfs 文件系统上,使用 snapper 管理快照。快照体系原本有三层:timeline 自动快照、pacman 事务前后快照(pre/post)、以及手动启动快照(boot)。其中 timeline 一直正常,但事务快照和启动快照在近期某个操作后被破坏,pacman 安装软件时会触发 Python traceback。

同时,系统使用的是标准 Arch Linux 内核(linux 包),而 CPU(AMD Ryzen,-march=znver4)完全支持 x86-64-v4 指令集。CachyOS 提供了针对 v3/v4/znver4 优化编译的软件包和内核,这些包利用了更现代的 CPU 指令扩展,理论上能带来可感知的性能提升。

系统环境

组件 版本/配置
文件系统 Btrfs,单设备 /dev/nvme0n1p3,1.82 TiB
子卷布局 @ (/), @home (/home), @root, @log, @pkg, @tmp, @cache, @srv
快照工具 snapper,双配置:@@home
启动管理器 GRUB + grub-btrfs(快照自动检测)
原内核 linux 6.x(Arch 标准包)
原 pacman 旧版(不支持扩展架构匹配)
CPU 指令集 x86-64-v4, znver4
GPU 驱动 nvidia-open-dkms 595.71.05

快照体系分析

当前配置

snapper 有两个独立配置,分别管理根子卷和家目录子卷的快照:

配置  │ 子卷
──────┼──────
@     │ /
@home │ /home

两者的配置几乎完全对称,核心参数如下:

参数 @ @home 说明
TIMELINE_CREATE yes yes 定时自动快照
TIMELINE_LIMIT_HOURLY 10 10 保留最近 10 个小时快照
TIMELINE_LIMIT_DAILY 10 10 保留最近 10 个日快照
TIMELINE_LIMIT_MONTHLY 10 10 保留最近 10 个月快照
TIMELINE_LIMIT_YEARLY 10 10 保留最近 10 个年快照
TIMELINE_LIMIT_WEEKLY 0 0 不保留周快照
TIMELINE_LIMIT_QUARTERLY 0 0 不保留季度快照
NUMBER_LIMIT 50 50 编号快照上限
NUMBER_LIMIT_IMPORTANT 10 10 重要快照上限
FREE_LIMIT 0.2 0.2 空闲空间低于 20% 时清理
SPACE_LIMIT 0.5 0.5 快照占用超过 50% 时清理
NUMBER_MIN_AGE 3600 3600 快照至少保留 1 小时
TIMELINE_MIN_AGE 3600 3600 timeline 快照间隔至少 1 小时

快照历史

snapper list 看,最早的快照是 2025 年 11 月 22 日(系统初始安装),之后每月一个保留点(NUMBER_CLEANUP 策略导致),近期快照密集——5 月 7 日到 5 月 10 日从 #1941 增长到 #1953,且在 5 月 10 日当天产生了大量 pre/post 事务快照。这是由于 TIMELINE_LIMIT_HOURLY=10 配合 NUMBER_LIMIT=50 产生的正常行为。

Btrfs 子卷结构

ID   path
256  <FS_TREE>/@          (根子卷)
257  <FS_TREE>/@home      (家目录)
258  <FS_TREE>/@root
259  <FS_TREE>/@log
260  <FS_TREE>/@pkg
261  <FS_TREE>/@tmp
262  <FS_TREE>/@cache
263  <FS_TREE>/@srv
268  @/.snapshots           (根快照目录)
267  @home/.snapshots       (home 快照目录)

每个快照编号在 @/.snapshots/{N}/snapshot@home/.snapshots/{N}/snapshot 下各有一个对应的 btrfs 子卷,编号一一对应,说明 snapper 每次同时对两个配置做快照。

事务快照修复

问题诊断

执行 paru -S helix 时,pacman 事务前钩子触发 snapper pre snapshot,但 Python 脚本直接 traceback 退出。关键错误来自 /etc/pacman.d/hooks/ 下的 snapper hook 文件,调用 snapper 时传入了不存在的配置名或错误的子卷路径。

修复步骤

  1. 检查 /etc/snapper/configs/ 下的配置文件名是否与 hook 中引用的名称一致。
  2. 确认 /etc/pacman.d/hooks/ 中 snapper 相关 hook 的正确性——Arch 的 snapper 包提供的 hook 使用 snapper create -c <config> 格式。
  3. 验证后重新触发事务,snapper 正常创建了 pre/post 快照(#1957 / #1958)。

修复后,每次 pacman 事务都会自动创建一对 pre/post 快照:

#1962 | pre  | pacman -S pacman
#1963 | post | pacman
#1964 | pre  | pacman -S linux-cachyos linux-cachyos-headers
#1965 | post | linux-cachyos linux-cachyos-headers

启动快照修复

启动快照依赖 grub-btrfs 在生成 GRUB 配置时自动发现快照并创建菜单项。问题排查过程:

  1. 确认 /boot/grub/grub.cfg 中存在 submenu "Snapshots" 区块
  2. 检查 grub-btrfs 服务是否正常运行
  3. 重新运行 sudo grub-mkconfig -o /boot/grub/grub.cfg

修复后 GRUB 正确显示了 36 个快照入口,从最早的 2025-11-22 到最新的 2026-05-10,每个快照条目包含时间戳、描述和 pre/post 标签,可通过 GRUB 菜单直接启动到任意历史快照状态。

CachyOS 迁移

CPU 指令集验证

在迁移前确认硬件兼容性:

# 查看动态链接器支持的指令集级别
/lib/ld-linux-x86-64.so.2 --help | grep supported
# 输出: x86-64-v4 (supported, searched)
#       x86-64-v3 (supported, searched)
#       x86-64-v2 (supported, searched)

# 查看 GCC 检测的原生微架构
gcc -march=native -Q --help=target 2>&1 | grep -Po "^\s+-march=\s+\K(\w+)$"
# 输出: znver4

这意味着可以同时使用 cachyos-v4cachyos-znver4 仓库的优化包。

GPG 密钥导入

CachyOS 仓库需要导入签名公钥。直接运行 cachyos-repo.sh --install 失败——脚本内使用的 keyserver 在中国大陆无法访问:

gpg: keyserver receive failed: End of file

解决方法:使用 Ubuntu 的 keyserver 手动导入:

sudo pacman-key --keyserver hkps://keyserver.ubuntu.com --recv-keys F3B607488DB35A47
sudo pacman-key --lsign-key F3B607488DB35A47

但重新运行安装脚本仍然失败,因为脚本内部写死了自己的 keyserver 逻辑。最终绕过方案:直接安装 cachyos-keyring 等包,跳过脚本:

sudo pacman -U https://mirror.cachyos.org/repo/x86_64/cachyos/cachyos-keyring-20240331-1-any.pkg.tar.zst
# 随后自动拉入 cachyos-mirrorlist 等依赖

安装 keyring 后,pacman 会自动信任 CachyOS 软件包的签名。

仓库配置

安装完成后 /etc/pacman.conf 被添加了以下仓库,顺序反映优先级:

[cachyos-znver4]         # znver4 优化包,最高优先级
Include = /etc/pacman.d/cachyos-v4-mirrorlist

[cachyos-core-znver4]    # znver4 优化的 core 替代
Include = /etc/pacman.d/cachyos-v4-mirrorlist

[cachyos-extra-znver4]   # znver4 优化的 extra 替代
Include = /etc/pacman.d/cachyos-v4-mirrorlist

[cachyos]                # 通用 CachyOS 包(非架构相关)
Include = /etc/pacman.d/cachyos-mirrorlist

[core]                   # Arch 官方 core
[extra]                  # Arch 官方 extra
[multilib]               # Arch 官方 multilib
[archlinuxcn]            # 中文社区仓库(USTC/BFSU 镜像)

架构匹配问题

首次尝试安装 linux-cachyos 时报错:

错误:无法准备事务处理 (无效的软件包架构)
:: 软件包 linux-cachyos-7.0.5-2-x86_64_v3 未包含一个有效的架构

原因:CachyOS 内核包标记为 x86_64_v3 架构,而旧版 pacman 只认识 x86_64any。Arch 的新版 pacman(7.1 系列)才支持扩展架构名。

解决:先升级 pacman,再安装 CachyOS 内核:

sudo pacman -S pacman           # 升级到 7.1.0.r9.g54d9411-3
sudo pacman -S linux-cachyos linux-cachyos-headers

内核安装与 DKMS

CachyOS 内核安装过程:

  1. 下载 linux-cachyos(153 MiB)和 linux-cachyos-headers(62 MiB)
  2. 事务前钩子创建 pre 快照 #1964
  3. 安装内核和头文件
  4. 事务后钩子触发 DKMS 重建:
==> dkms install --no-depmod nvidia/595.71.05 -k 7.0.5-2-cachyos
==> depmod 7.0.5-2-cachyos
  1. initcpio 重建:
==> Building image from preset: /etc/mkinitcpio.d/linux-cachyos.preset: default
  -> -k /boot/vmlinuz-linux-cachyos -g /boot/initramfs-linux-cachyos.img
  1. GRUB 配置更新,自动检测到全部 36 个快照并添加子菜单
  2. 创建 post 快照 #1965

启动验证

重启后确认:

uname -r                    # 7.0.5-2-cachyos
dkms status                 # nvidia/595.71.05, 7.0.5-2-cachyos: installed
lsmod | grep nvidia         # nvidia_drm, nvidia_uvm, nvidia_modeset 均已加载

迁移后清理

pacman 警告分析

运行 pacman -Syyu 后出现多个"本地版本比仓库版本更新"的警告:

包名 本地版本 仓库版本 来源
firefox 150.0.2-1 150.0.1-1.1 cachyos-extra-znver4
mkinitcpio 41-3 41-2 cachyos
nvidia-open-dkms 595.71.05-2 595.71.05-1 cachyos-znver4
nvidia-utils 595.71.05-2 595.71.05-1 cachyos-znver4
paru 2.1.0-5 2.1.0-2 cachyos
sqlite 3.53.1-1 3.53.0-2 cachyos-znver4

这些警告是正常的——Arch 主线仓库(core/extra)和 AUR 的更新节奏通常比 CachyOS 仓库快。CachyOS 对包的重新编译需要时间。这不会导致降级,pacman 会保留本地更新版本。

AUR 与 CachyOS 仓库的优先级

CachyOS 仓库排在 core/extra 之前,因此同名的 CachyOS 优化包会优先被安装。但 AUR 包(如 paru、nvidia-open-dkms)走的是不同的安装路径:

  • AUR helper(paru/yay)安装的包在 pacman -Qm 中显示为"外来包"
  • CachyOS 仓库的包在 pacman -Qn 中显示为"本地包"
  • 两者不会直接冲突,但版本号可能交错

如果想强制使用 CachyOS 仓库版本(当 AUR 版本出现问题时):

# 先卸载 AUR 版本
sudo pacman -R <package>
# 再从仓库安装
sudo pacman -S <package>

代理配置清理

系统使用 sing-box 透明代理,端口为 7897(非标准 7890)。排查后确认 /etc/pacman.conf 中没有残留的 XferCommand 代理配置——透明代理在 TPROXY 层工作,无需应用层配置。

pacnew 合并

pacman 升级时产生了 /etc/pacman.conf.pacnew,直接用新版覆盖并手工合并 CachyOS 仓库配置和中文社区仓库配置。

CachyOS 工具包

迁移后可选的 CachyOS 特色工具:

包名 用途
cachyos-settings 系统级优化配置(sysctl, udev 规则等)
cachyos-rate-mirrors 自动测速并选择最快镜像
cachyos-ananicy-rules Ananicy 进程优先级规则集
cachyos-zsh-config Zsh 配置优化
bpftune 自动内核参数调优
scx-scheds sched-ext 调度器集合

这些包并非必须安装,按需选用即可。scx-scheds 已被标记为 linux-cachyos 的可选依赖。

总结

整个迁移过程的核心难点不在 CachyOS 本身,而在于前后依赖链的协调:

  1. snapper hook 修复是前置条件——事务快照工作后才有安全网
  2. GPG 密钥导入需要绕过 keyserver 网络问题
  3. pacman 版本决定了能否识别扩展架构包
  4. DKMS 自动重建让内核切换后 Nvidia 驱动无缝衔接

最终状态:系统运行在 linux-cachyos 7.0.5-2,使用的 znver4 优化包,Btrfs 快照体系三层(timeline / 事务 / 启动)全部正常工作。

Interaction

读完之后

分享海报
Interaction

评论区